diff --git a/.deadcode-out b/.deadcode-out index 61c5bcb055..f9bee43043 100644 --- a/.deadcode-out +++ b/.deadcode-out @@ -27,15 +27,13 @@ forgejo.org/models/db TruncateBeans InTransaction DumpTables + GetTableNames forgejo.org/models/dbfs file.renameTo Create Rename -forgejo.org/models/forgefed - GetFederationHost - forgejo.org/models/forgejo/semver GetVersion SetVersionString @@ -67,7 +65,6 @@ forgejo.org/models/user DeleteUserSetting GetFederatedUser GetFederatedUserByUserID - UpdateFederatedUser GetFollowersForUser AddFollower RemoveFollower @@ -248,6 +245,9 @@ forgejo.org/routers/web/org forgejo.org/services/context GetPrivateContext +forgejo.org/services/federation + Init + forgejo.org/services/repository IsErrForkAlreadyExist diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 28fa9e4555..3f250e5682 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -6,7 +6,7 @@ "ghcr.io/devcontainers/features/node:1": { "version": "22" }, - "ghcr.io/devcontainers/features/git-lfs:1.2.4": {}, + "ghcr.io/devcontainers/features/git-lfs:1.2.5": {}, "ghcr.io/warrenbuckley/codespace-features/sqlite:1": {} }, "customizations": { diff --git a/.forgejo/workflows/renovate.yml b/.forgejo/workflows/renovate.yml index 729cba3723..d3eac5357a 100644 --- a/.forgejo/workflows/renovate.yml +++ b/.forgejo/workflows/renovate.yml @@ -28,7 +28,7 @@ jobs: runs-on: docker container: - image: data.forgejo.org/renovate/renovate:41.17.2 + image: data.forgejo.org/renovate/renovate:41.23.2 steps: - name: Load renovate repo cache diff --git a/.golangci.yml b/.golangci.yml index 532132838d..6679a1850e 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -79,6 +79,10 @@ linters: - name: unreachable-code - name: var-declaration - name: var-naming + arguments: + - [] + - [] + - - skip-package-name-checks: true - name: redefines-builtin-id disabled: true staticcheck: diff --git a/Makefile b/Makefile index db4ec2fbd5..c09e0180eb 100644 --- a/Makefile +++ b/Makefile @@ -39,7 +39,7 @@ XGO_VERSION := go-1.21.x AIR_PACKAGE ?= github.com/air-verse/air@v1 # renovate: datasource=go EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/v3/cmd/editorconfig-checker@v3.3.0 # renovate: datasource=go GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@v0.8.0 # renovate: datasource=go -GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.1.6 # renovate: datasource=go +GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.2.1 # renovate: datasource=go GXZ_PACKAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.11 # renovate: datasource=go SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.31.0 # renovate: datasource=go XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest @@ -47,7 +47,7 @@ GO_LICENSES_PACKAGE ?= github.com/google/go-licenses@v1.6.0 # renovate: datasour GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1 # renovate: datasource=go DEADCODE_PACKAGE ?= golang.org/x/tools/cmd/deadcode@v0.34.0 # renovate: datasource=go GOMOCK_PACKAGE ?= go.uber.org/mock/mockgen@v0.5.2 # renovate: datasource=go -RENOVATE_NPM_PACKAGE ?= renovate@41.17.2 # renovate: datasource=docker packageName=data.forgejo.org/renovate/renovate +RENOVATE_NPM_PACKAGE ?= renovate@41.23.2 # renovate: datasource=docker packageName=data.forgejo.org/renovate/renovate # https://github.com/disposable-email-domains/disposable-email-domains/commits/main/ DISPOSABLE_EMAILS_SHA ?= 0c27e671231d27cf66370034d7f6818037416989 # renovate: ... diff --git a/cmd/admin_auth.go b/cmd/admin_auth.go index cb95b3b3c8..91b344b1e9 100644 --- a/cmd/admin_auth.go +++ b/cmd/admin_auth.go @@ -17,6 +17,15 @@ import ( "github.com/urfave/cli/v3" ) +type ( + authService struct { + initDB func(ctx context.Context) error + createAuthSource func(context.Context, *auth_model.Source) error + updateAuthSource func(context.Context, *auth_model.Source) error + getAuthSourceByID func(ctx context.Context, id int64) (*auth_model.Source, error) + } +) + func microcmdAuthDelete() *cli.Command { return &cli.Command{ Name: "delete", @@ -60,6 +69,16 @@ func microcmdAuthList() *cli.Command { } } +// newAuthService creates a service with default functions. +func newAuthService() *authService { + return &authService{ + initDB: initDB, + createAuthSource: auth_model.CreateSource, + updateAuthSource: auth_model.UpdateSource, + getAuthSourceByID: auth_model.GetSourceByID, + } +} + func runListAuth(ctx context.Context, c *cli.Command) error { ctx, cancel := installSignals(ctx) defer cancel() diff --git a/cmd/admin_auth_ldap.go b/cmd/admin_auth_ldap.go index 997d6b3a16..9af6c331d3 100644 --- a/cmd/admin_auth_ldap.go +++ b/cmd/admin_auth_ldap.go @@ -14,15 +14,6 @@ import ( "github.com/urfave/cli/v3" ) -type ( - authService struct { - initDB func(ctx context.Context) error - createAuthSource func(context.Context, *auth.Source) error - updateAuthSource func(context.Context, *auth.Source) error - getAuthSourceByID func(ctx context.Context, id int64) (*auth.Source, error) - } -) - func commonLdapCLIFlags() []cli.Flag { return []cli.Flag{ &cli.StringFlag{ @@ -184,16 +175,6 @@ func microcmdAuthUpdateLdapSimpleAuth() *cli.Command { } } -// newAuthService creates a service with default functions. -func newAuthService() *authService { - return &authService{ - initDB: initDB, - createAuthSource: auth.CreateSource, - updateAuthSource: auth.UpdateSource, - getAuthSourceByID: auth.GetSourceByID, - } -} - // parseAuthSource assigns values on authSource according to command line flags. func parseAuthSource(c *cli.Command, authSource *auth.Source) { if c.IsSet("name") { diff --git a/cmd/admin_auth_oauth.go b/cmd/admin_auth_oauth.go index abdcd5d48a..8a756480cd 100644 --- a/cmd/admin_auth_oauth.go +++ b/cmd/admin_auth_oauth.go @@ -86,6 +86,11 @@ func oauthCLIFlags() []cli.Flag { Value: nil, Usage: "Scopes to request when to authenticate against this OAuth2 source", }, + &cli.StringFlag{ + Name: "attribute-ssh-public-key", + Value: "", + Usage: "Claim name providing SSH public keys for this source", + }, &cli.StringFlag{ Name: "required-claim-name", Value: "", @@ -127,7 +132,7 @@ func microcmdAuthAddOauth() *cli.Command { return &cli.Command{ Name: "add-oauth", Usage: "Add new Oauth authentication source", - Action: runAddOauth, + Action: newAuthService().addOauth, Flags: oauthCLIFlags(), } } @@ -136,7 +141,7 @@ func microcmdAuthUpdateOauth() *cli.Command { return &cli.Command{ Name: "update-oauth", Usage: "Update existing Oauth authentication source", - Action: runUpdateOauth, + Action: newAuthService().updateOauth, Flags: append(oauthCLIFlags()[:1], append([]cli.Flag{idFlag()}, oauthCLIFlags()[1:]...)...), } } @@ -163,6 +168,7 @@ func parseOAuth2Config(_ context.Context, c *cli.Command) *oauth2.Source { IconURL: c.String("icon-url"), SkipLocalTwoFA: c.Bool("skip-local-2fa"), Scopes: c.StringSlice("scopes"), + AttributeSSHPublicKey: c.String("attribute-ssh-public-key"), RequiredClaimName: c.String("required-claim-name"), RequiredClaimValue: c.String("required-claim-value"), GroupClaimName: c.String("group-claim-name"), @@ -173,11 +179,11 @@ func parseOAuth2Config(_ context.Context, c *cli.Command) *oauth2.Source { } } -func runAddOauth(ctx context.Context, c *cli.Command) error { +func (a *authService) addOauth(ctx context.Context, c *cli.Command) error { ctx, cancel := installSignals(ctx) defer cancel() - if err := initDB(ctx); err != nil { + if err := a.initDB(ctx); err != nil { return err } @@ -189,7 +195,7 @@ func runAddOauth(ctx context.Context, c *cli.Command) error { } } - return auth_model.CreateSource(ctx, &auth_model.Source{ + return a.createAuthSource(ctx, &auth_model.Source{ Type: auth_model.OAuth2, Name: c.String("name"), IsActive: true, @@ -197,7 +203,7 @@ func runAddOauth(ctx context.Context, c *cli.Command) error { }) } -func runUpdateOauth(ctx context.Context, c *cli.Command) error { +func (a *authService) updateOauth(ctx context.Context, c *cli.Command) error { if !c.IsSet("id") { return errors.New("--id flag is missing") } @@ -205,11 +211,11 @@ func runUpdateOauth(ctx context.Context, c *cli.Command) error { ctx, cancel := installSignals(ctx) defer cancel() - if err := initDB(ctx); err != nil { + if err := a.initDB(ctx); err != nil { return err } - source, err := auth_model.GetSourceByID(ctx, c.Int64("id")) + source, err := a.getAuthSourceByID(ctx, c.Int64("id")) if err != nil { return err } @@ -244,6 +250,10 @@ func runUpdateOauth(ctx context.Context, c *cli.Command) error { oAuth2Config.Scopes = c.StringSlice("scopes") } + if c.IsSet("attribute-ssh-public-key") { + oAuth2Config.AttributeSSHPublicKey = c.String("attribute-ssh-public-key") + } + if c.IsSet("required-claim-name") { oAuth2Config.RequiredClaimName = c.String("required-claim-name") } @@ -300,5 +310,5 @@ func runUpdateOauth(ctx context.Context, c *cli.Command) error { oAuth2Config.CustomURLMapping = customURLMapping source.Cfg = oAuth2Config - return auth_model.UpdateSource(ctx, source) + return a.updateAuthSource(ctx, source) } diff --git a/cmd/admin_auth_oauth_test.go b/cmd/admin_auth_oauth_test.go new file mode 100644 index 0000000000..ea5442e62d --- /dev/null +++ b/cmd/admin_auth_oauth_test.go @@ -0,0 +1,704 @@ +// Copyright 2025 The Forgejo Authors. All rights reserved. +// SPDX-License-Identifier: GPL-3.0-or-later + +package cmd + +import ( + "context" + "testing" + + "forgejo.org/models/auth" + "forgejo.org/modules/test" + "forgejo.org/services/auth/source/oauth2" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/urfave/cli/v3" +) + +func TestAddOauth(t *testing.T) { + // Mock cli functions to do not exit on error + defer test.MockVariableValue(&cli.OsExiter, func(code int) {})() + + // Test cases + cases := []struct { + args []string + source *auth.Source + errMsg string + }{ + // case 0 + { + args: []string{ + "oauth-test", + "--name", "oauth2 (via openidConnect) source full", + "--provider", "openidConnect", + "--key", "client id", + "--secret", "client secret", + "--auto-discover-url", "https://example.com/.well-known/openid-configuration", + "--use-custom-urls", "", + "--custom-tenant-id", "tenant id", + "--custom-auth-url", "https://example.com/auth", + "--custom-token-url", "https://example.com/token", + "--custom-profile-url", "https://example.com/profile", + "--custom-email-url", "https://example.com/email", + "--icon-url", "https://example.com/icon.svg", + "--skip-local-2fa", + "--scopes", "address", + "--scopes", "email", + "--scopes", "phone", + "--scopes", "profile", + "--attribute-ssh-public-key", "ssh_public_key", + "--required-claim-name", "can_access", + "--required-claim-value", "yes", + "--group-claim-name", "groups", + "--admin-group", "admin", + "--restricted-group", "restricted", + "--group-team-map", `{"org_a_team_1": {"organization-a": ["Team 1"]}, "org_a_all_teams": {"organization-a": ["Team 1", "Team 2", "Team 3"]}}`, + "--group-team-map-removal", + }, + source: &auth.Source{ + Type: auth.OAuth2, + Name: "oauth2 (via openidConnect) source full", + IsActive: true, + Cfg: &oauth2.Source{ + Provider: "openidConnect", + ClientID: "client id", + ClientSecret: "client secret", + OpenIDConnectAutoDiscoveryURL: "https://example.com/.well-known/openid-configuration", + CustomURLMapping: &oauth2.CustomURLMapping{ + AuthURL: "https://example.com/auth", + TokenURL: "https://example.com/token", + ProfileURL: "https://example.com/profile", + EmailURL: "https://example.com/email", + Tenant: "tenant id", + }, + IconURL: "https://example.com/icon.svg", + Scopes: []string{"address", "email", "phone", "profile"}, + AttributeSSHPublicKey: "ssh_public_key", + RequiredClaimName: "can_access", + RequiredClaimValue: "yes", + GroupClaimName: "groups", + AdminGroup: "admin", + GroupTeamMap: `{"org_a_team_1": {"organization-a": ["Team 1"]}, "org_a_all_teams": {"organization-a": ["Team 1", "Team 2", "Team 3"]}}`, + GroupTeamMapRemoval: true, + RestrictedGroup: "restricted", + SkipLocalTwoFA: true, + }, + }, + }, + // case 1 + { + args: []string{ + "oauth-test", + "--name", "oauth2 (via openidConnect) source min", + "--provider", "openidConnect", + "--auto-discover-url", "https://example.com/.well-known/openid-configuration", + }, + source: &auth.Source{ + Type: auth.OAuth2, + Name: "oauth2 (via openidConnect) source min", + IsActive: true, + Cfg: &oauth2.Source{ + Provider: "openidConnect", + OpenIDConnectAutoDiscoveryURL: "https://example.com/.well-known/openid-configuration", + Scopes: []string{}, + }, + }, + }, + // case 2 + { + args: []string{ + "oauth-test", + "--name", "oauth2 (via openidConnect) source `--use-custom-urls` required for `--custom-*` flags", + "--custom-tenant-id", "tenant id", + "--custom-auth-url", "https://example.com/auth", + "--custom-token-url", "https://example.com/token", + "--custom-profile-url", "https://example.com/profile", + "--custom-email-url", "https://example.com/email", + }, + source: &auth.Source{ + Type: auth.OAuth2, + Name: "oauth2 (via openidConnect) source `--use-custom-urls` required for `--custom-*` flags", + IsActive: true, + Cfg: &oauth2.Source{ + Scopes: []string{}, + }, + }, + }, + // case 3 + { + args: []string{ + "oauth-test", + "--name", "oauth2 (via openidConnect) source `--scopes` aggregates multiple uses", + "--provider", "openidConnect", + "--auto-discover-url", "https://example.com/.well-known/openid-configuration", + "--scopes", "address", + "--scopes", "email", + "--scopes", "phone", + "--scopes", "profile", + }, + source: &auth.Source{ + Type: auth.OAuth2, + Name: "oauth2 (via openidConnect) source `--scopes` aggregates multiple uses", + IsActive: true, + Cfg: &oauth2.Source{ + Provider: "openidConnect", + OpenIDConnectAutoDiscoveryURL: "https://example.com/.well-known/openid-configuration", + Scopes: []string{"address", "email", "phone", "profile"}, + }, + }, + }, + // case 4 + { + args: []string{ + "oauth-test", + "--name", "oauth2 (via openidConnect) source `--scopes` supports commas as separators", + "--provider", "openidConnect", + "--auto-discover-url", "https://example.com/.well-known/openid-configuration", + "--scopes", "address,email,phone,profile", + }, + source: &auth.Source{ + Type: auth.OAuth2, + Name: "oauth2 (via openidConnect) source `--scopes` supports commas as separators", + IsActive: true, + Cfg: &oauth2.Source{ + Provider: "openidConnect", + OpenIDConnectAutoDiscoveryURL: "https://example.com/.well-known/openid-configuration", + Scopes: []string{"address", "email", "phone", "profile"}, + }, + }, + }, + // case 5 + { + args: []string{ + "oauth-test", + "--name", "oauth2 (via openidConnect) source", + "--provider", "openidConnect", + }, + errMsg: "invalid Auto Discovery URL: (this must be a valid URL starting with http:// or https://)", + }, + // case 6 + { + args: []string{ + "oauth-test", + "--name", "oauth2 (via openidConnect) source", + "--provider", "openidConnect", + "--auto-discover-url", "example.com", + }, + errMsg: "invalid Auto Discovery URL: example.com (this must be a valid URL starting with http:// or https://)", + }, + } + + for n, c := range cases { + // Mock functions. + var createdAuthSource *auth.Source + service := &authService{ + initDB: func(context.Context) error { + return nil + }, + createAuthSource: func(ctx context.Context, authSource *auth.Source) error { + createdAuthSource = authSource + return nil + }, + updateAuthSource: func(ctx context.Context, authSource *auth.Source) error { + assert.FailNow(t, "should not call updateAuthSource", "case: %d", n) + return nil + }, + getAuthSourceByID: func(ctx context.Context, id int64) (*auth.Source, error) { + assert.FailNow(t, "should not call getAuthSourceByID", "case: %d", n) + return nil, nil + }, + } + + // Create a copy of command to test + app := cli.Command{} + app.Flags = microcmdAuthAddOauth().Flags + app.Action = service.addOauth + + // Run it + err := app.Run(t.Context(), c.args) + if c.errMsg != "" { + assert.EqualError(t, err, c.errMsg, "case %d: error should match", n) + } else { + require.NoError(t, err, "case %d: should have no errors", n) + assert.Equal(t, c.source, createdAuthSource, "case %d: wrong authSource", n) + } + } +} + +func TestUpdateOauth(t *testing.T) { + // Mock cli functions to do not exit on error + defer test.MockVariableValue(&cli.OsExiter, func(code int) {})() + + // Test cases + cases := []struct { + args []string + id int64 + existingAuthSource *auth.Source + authSource *auth.Source + errMsg string + }{ + // case 0 + { + args: []string{ + "oauth-test", + "--id", "23", + "--name", "oauth2 (via openidConnect) source full", + "--provider", "openidConnect", + "--key", "client id", + "--secret", "client secret", + "--auto-discover-url", "https://example.com/.well-known/openid-configuration", + "--use-custom-urls", "", + "--custom-tenant-id", "tenant id", + "--custom-auth-url", "https://example.com/auth", + "--custom-token-url", "https://example.com/token", + "--custom-profile-url", "https://example.com/profile", + "--custom-email-url", "https://example.com/email", + "--icon-url", "https://example.com/icon.svg", + "--skip-local-2fa", + "--scopes", "address", + "--scopes", "email", + "--scopes", "phone", + "--scopes", "profile", + "--attribute-ssh-public-key", "ssh_public_key", + "--required-claim-name", "can_access", + "--required-claim-value", "yes", + "--group-claim-name", "groups", + "--admin-group", "admin", + "--restricted-group", "restricted", + "--group-team-map", `{"org_a_team_1": {"organization-a": ["Team 1"]}, "org_a_all_teams": {"organization-a": ["Team 1", "Team 2", "Team 3"]}}`, + "--group-team-map-removal", + }, + id: 23, + existingAuthSource: &auth.Source{ + Type: auth.OAuth2, + Cfg: &oauth2.Source{}, + }, + authSource: &auth.Source{ + Type: auth.OAuth2, + Name: "oauth2 (via openidConnect) source full", + Cfg: &oauth2.Source{ + Provider: "openidConnect", + ClientID: "client id", + ClientSecret: "client secret", + OpenIDConnectAutoDiscoveryURL: "https://example.com/.well-known/openid-configuration", + CustomURLMapping: &oauth2.CustomURLMapping{ + AuthURL: "https://example.com/auth", + TokenURL: "https://example.com/token", + ProfileURL: "https://example.com/profile", + EmailURL: "https://example.com/email", + Tenant: "tenant id", + }, + IconURL: "https://example.com/icon.svg", + Scopes: []string{"address", "email", "phone", "profile"}, + AttributeSSHPublicKey: "ssh_public_key", + RequiredClaimName: "can_access", + RequiredClaimValue: "yes", + GroupClaimName: "groups", + AdminGroup: "admin", + GroupTeamMap: `{"org_a_team_1": {"organization-a": ["Team 1"]}, "org_a_all_teams": {"organization-a": ["Team 1", "Team 2", "Team 3"]}}`, + GroupTeamMapRemoval: true, + RestrictedGroup: "restricted", + // `--skip-local-2fa` is currently ignored. + // SkipLocalTwoFA: true, + }, + }, + }, + // case 1 + { + args: []string{ + "oauth-test", + "--id", "1", + }, + authSource: &auth.Source{ + Type: auth.OAuth2, + Cfg: &oauth2.Source{ + CustomURLMapping: &oauth2.CustomURLMapping{}, + }, + }, + }, + // case 2 + { + args: []string{ + "oauth-test", + "--id", "1", + "--name", "oauth2 (via openidConnect) source full", + }, + authSource: &auth.Source{ + Type: auth.OAuth2, + Name: "oauth2 (via openidConnect) source full", + Cfg: &oauth2.Source{ + CustomURLMapping: &oauth2.CustomURLMapping{}, + }, + }, + }, + // case 3 + { + args: []string{ + "oauth-test", + "--id", "1", + "--provider", "openidConnect", + }, + authSource: &auth.Source{ + Type: auth.OAuth2, + Cfg: &oauth2.Source{ + Provider: "openidConnect", + CustomURLMapping: &oauth2.CustomURLMapping{}, + }, + }, + }, + // case 4 + { + args: []string{ + "oauth-test", + "--id", "1", + "--key", "client id", + }, + authSource: &auth.Source{ + Type: auth.OAuth2, + Cfg: &oauth2.Source{ + ClientID: "client id", + CustomURLMapping: &oauth2.CustomURLMapping{}, + }, + }, + }, + // case 5 + { + args: []string{ + "oauth-test", + "--id", "1", + "--secret", "client secret", + }, + authSource: &auth.Source{ + Type: auth.OAuth2, + Cfg: &oauth2.Source{ + ClientSecret: "client secret", + CustomURLMapping: &oauth2.CustomURLMapping{}, + }, + }, + }, + // case 6 + { + args: []string{ + "oauth-test", + "--id", "1", + "--auto-discover-url", "https://example.com/.well-known/openid-configuration", + }, + authSource: &auth.Source{ + Type: auth.OAuth2, + Cfg: &oauth2.Source{ + OpenIDConnectAutoDiscoveryURL: "https://example.com/.well-known/openid-configuration", + CustomURLMapping: &oauth2.CustomURLMapping{}, + }, + }, + }, + // case 7 + { + args: []string{ + "oauth-test", + "--id", "1", + "--use-custom-urls", "", + "--custom-tenant-id", "tenant id", + "--custom-auth-url", "https://example.com/auth", + "--custom-token-url", "https://example.com/token", + "--custom-profile-url", "https://example.com/profile", + "--custom-email-url", "https://example.com/email", + }, + authSource: &auth.Source{ + Type: auth.OAuth2, + Cfg: &oauth2.Source{ + CustomURLMapping: &oauth2.CustomURLMapping{ + AuthURL: "https://example.com/auth", + TokenURL: "https://example.com/token", + ProfileURL: "https://example.com/profile", + EmailURL: "https://example.com/email", + Tenant: "tenant id", + }, + }, + }, + }, + // case 8 + { + args: []string{ + "oauth-test", + "--id", "1", + "--name", "oauth2 (via openidConnect) source `--use-custom-urls` required for `--custom-*` flags", + "--custom-tenant-id", "tenant id", + "--custom-auth-url", "https://example.com/auth", + "--custom-token-url", "https://example.com/token", + "--custom-profile-url", "https://example.com/profile", + "--custom-email-url", "https://example.com/email", + }, + authSource: &auth.Source{ + Type: auth.OAuth2, + Name: "oauth2 (via openidConnect) source `--use-custom-urls` required for `--custom-*` flags", + Cfg: &oauth2.Source{ + CustomURLMapping: &oauth2.CustomURLMapping{}, + }, + }, + }, + // case 9 + { + args: []string{ + "oauth-test", + "--id", "1", + "--icon-url", "https://example.com/icon.svg", + }, + authSource: &auth.Source{ + Type: auth.OAuth2, + Cfg: &oauth2.Source{ + CustomURLMapping: &oauth2.CustomURLMapping{}, + IconURL: "https://example.com/icon.svg", + }, + }, + }, + // case 10 + { + args: []string{ + "oauth-test", + "--id", "1", + "--name", "oauth2 (via openidConnect) source `--skip-local-2fa` is currently ignored", + "--skip-local-2fa", + }, + authSource: &auth.Source{ + Type: auth.OAuth2, + Name: "oauth2 (via openidConnect) source `--skip-local-2fa` is currently ignored", + Cfg: &oauth2.Source{ + CustomURLMapping: &oauth2.CustomURLMapping{}, + // `--skip-local-2fa` is currently ignored. + // SkipLocalTwoFA: true, + }, + }, + }, + // case 11 + { + args: []string{ + "oauth-test", + "--id", "1", + "--name", "oauth2 (via openidConnect) source `--scopes` aggregates multiple uses", + "--scopes", "address", + "--scopes", "email", + "--scopes", "phone", + "--scopes", "profile", + }, + authSource: &auth.Source{ + Type: auth.OAuth2, + Name: "oauth2 (via openidConnect) source `--scopes` aggregates multiple uses", + Cfg: &oauth2.Source{ + CustomURLMapping: &oauth2.CustomURLMapping{}, + Scopes: []string{"address", "email", "phone", "profile"}, + }, + }, + }, + // case 12 + { + args: []string{ + "oauth-test", + "--id", "1", + "--name", "oauth2 (via openidConnect) source `--scopes` supports commas as separators", + "--scopes", "address,email,phone,profile", + }, + authSource: &auth.Source{ + Type: auth.OAuth2, + Name: "oauth2 (via openidConnect) source `--scopes` supports commas as separators", + Cfg: &oauth2.Source{ + CustomURLMapping: &oauth2.CustomURLMapping{}, + Scopes: []string{"address", "email", "phone", "profile"}, + }, + }, + }, + // case 13 + { + args: []string{ + "oauth-test", + "--id", "1", + "--attribute-ssh-public-key", "ssh_public_key", + }, + authSource: &auth.Source{ + Type: auth.OAuth2, + Cfg: &oauth2.Source{ + CustomURLMapping: &oauth2.CustomURLMapping{}, + AttributeSSHPublicKey: "ssh_public_key", + }, + }, + }, + // case 14 + { + args: []string{ + "oauth-test", + "--id", "1", + "--required-claim-name", "can_access", + }, + authSource: &auth.Source{ + Type: auth.OAuth2, + Cfg: &oauth2.Source{ + CustomURLMapping: &oauth2.CustomURLMapping{}, + RequiredClaimName: "can_access", + }, + }, + }, + // case 15 + { + args: []string{ + "oauth-test", + "--id", "1", + "--required-claim-value", "yes", + }, + authSource: &auth.Source{ + Type: auth.OAuth2, + Cfg: &oauth2.Source{ + CustomURLMapping: &oauth2.CustomURLMapping{}, + RequiredClaimValue: "yes", + }, + }, + }, + // case 16 + { + args: []string{ + "oauth-test", + "--id", "1", + "--group-claim-name", "groups", + }, + authSource: &auth.Source{ + Type: auth.OAuth2, + Cfg: &oauth2.Source{ + CustomURLMapping: &oauth2.CustomURLMapping{}, + GroupClaimName: "groups", + }, + }, + }, + // case 17 + { + args: []string{ + "oauth-test", + "--id", "1", + "--admin-group", "admin", + }, + authSource: &auth.Source{ + Type: auth.OAuth2, + Cfg: &oauth2.Source{ + CustomURLMapping: &oauth2.CustomURLMapping{}, + AdminGroup: "admin", + }, + }, + }, + // case 18 + { + args: []string{ + "oauth-test", + "--id", "1", + "--restricted-group", "restricted", + }, + authSource: &auth.Source{ + Type: auth.OAuth2, + Cfg: &oauth2.Source{ + CustomURLMapping: &oauth2.CustomURLMapping{}, + RestrictedGroup: "restricted", + }, + }, + }, + // case 19 + { + args: []string{ + "oauth-test", + "--id", "1", + "--group-team-map", `{"org_a_team_1": {"organization-a": ["Team 1"]}, "org_a_all_teams": {"organization-a": ["Team 1", "Team 2", "Team 3"]}}`, + }, + authSource: &auth.Source{ + Type: auth.OAuth2, + Cfg: &oauth2.Source{ + CustomURLMapping: &oauth2.CustomURLMapping{}, + GroupTeamMap: `{"org_a_team_1": {"organization-a": ["Team 1"]}, "org_a_all_teams": {"organization-a": ["Team 1", "Team 2", "Team 3"]}}`, + }, + }, + }, + // case 20 + { + args: []string{ + "oauth-test", + "--id", "1", + "--group-team-map-removal", + }, + authSource: &auth.Source{ + Type: auth.OAuth2, + Cfg: &oauth2.Source{ + CustomURLMapping: &oauth2.CustomURLMapping{}, + GroupTeamMapRemoval: true, + }, + }, + }, + // case 21 + { + args: []string{ + "oauth-test", + "--id", "23", + "--group-team-map-removal=false", + }, + id: 23, + existingAuthSource: &auth.Source{ + Type: auth.OAuth2, + Cfg: &oauth2.Source{ + GroupTeamMapRemoval: true, + }, + }, + authSource: &auth.Source{ + Type: auth.OAuth2, + Cfg: &oauth2.Source{ + CustomURLMapping: &oauth2.CustomURLMapping{}, + GroupTeamMapRemoval: false, + }, + }, + }, + // case 22 + { + args: []string{ + "oauth-test", + }, + errMsg: "--id flag is missing", + }, + } + + for n, c := range cases { + // Mock functions. + var updatedAuthSource *auth.Source + service := &authService{ + initDB: func(context.Context) error { + return nil + }, + createAuthSource: func(ctx context.Context, authSource *auth.Source) error { + assert.FailNow(t, "should not call createAuthSource", "case: %d", n) + return nil + }, + updateAuthSource: func(ctx context.Context, authSource *auth.Source) error { + updatedAuthSource = authSource + return nil + }, + getAuthSourceByID: func(ctx context.Context, id int64) (*auth.Source, error) { + if c.id != 0 { + assert.Equal(t, c.id, id, "case %d: wrong id", n) + } + if c.existingAuthSource != nil { + return c.existingAuthSource, nil + } + return &auth.Source{ + Type: auth.OAuth2, + Cfg: &oauth2.Source{}, + }, nil + }, + } + + // Create a copy of command to test + app := cli.Command{} + app.Flags = microcmdAuthUpdateOauth().Flags + app.Action = service.updateOauth + + // Run it + err := app.Run(t.Context(), c.args) + if c.errMsg != "" { + assert.EqualError(t, err, c.errMsg, "case %d: error should match", n) + } else { + 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/manager_logging.go b/cmd/manager_logging.go index c543afe872..c18bfa919b 100644 --- a/cmd/manager_logging.go +++ b/cmd/manager_logging.go @@ -44,6 +44,11 @@ func defaultLoggingFlags() []cli.Flag { Aliases: []string{"e"}, Usage: "Matching expression for the logger", }, + &cli.StringFlag{ + Name: "exclusion", + Aliases: []string{"x"}, + Usage: "Exclusion for the logger", + }, &cli.StringFlag{ Name: "prefix", Aliases: []string{"p"}, @@ -286,6 +291,9 @@ func commonAddLogger(ctx context.Context, c *cli.Command, mode string, vals map[ if len(c.String("expression")) > 0 { vals["expression"] = c.String("expression") } + if len(c.String("exclusion")) > 0 { + vals["exclusion"] = c.String("exclusion") + } if len(c.String("prefix")) > 0 { vals["prefix"] = c.String("prefix") } diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 1b8d4c6697..71598663b2 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -631,6 +631,7 @@ LEVEL = Info ;LEVEL= ;FLAGS = stdflags or journald ;EXPRESSION = +;EXCLUSION = ;PREFIX = ;COLORIZE = false ;; @@ -1767,6 +1768,9 @@ LEVEL = Info ;; Use PASSWD = `your password` for quoting if you use special characters in the password. ;PASSWD = ;; +;; Alternative location to specify mailer password. You cannot specify both this and PASSWD, and must pick one +;PASSWD_URI = file:/etc/forgejo/mailer_passwd +;; ;; Send mails only in plain text, without HTML alternative ;SEND_AS_PLAIN_TEXT = false ;; @@ -1819,6 +1823,9 @@ LEVEL = Info ;; Password of the receiving account ;PASSWORD = ;; +;; Alternative location to specify password of the receiving account. You cannot specify both this and PASSWORD, and must pick one +;PASSWORD_URI = file:/etc/forgejo/email_incoming_password +;; ;; Whether the IMAP server uses TLS. ;USE_TLS = false ;; diff --git a/go.mod b/go.mod index 33ad5dbc67..139095099b 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module forgejo.org go 1.24 -toolchain go1.24.4 +toolchain go1.24.5 require ( code.forgejo.org/f3/gof3/v3 v3.11.0 @@ -24,7 +24,7 @@ require ( github.com/ProtonMail/go-crypto v1.3.0 github.com/PuerkitoBio/goquery v1.10.3 github.com/SaveTheRbtz/zstd-seekable-format-go/pkg v0.7.2 - github.com/alecthomas/chroma/v2 v2.18.0 + github.com/alecthomas/chroma/v2 v2.19.0 github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb github.com/blevesearch/bleve/v2 v2.5.2 github.com/buildkite/terminal-to-html/v3 v3.16.8 @@ -42,21 +42,21 @@ require ( 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.2.2 - github.com/go-chi/cors v1.2.1 + github.com/go-chi/cors v1.2.2 github.com/go-co-op/gocron v1.37.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-openapi/spec v0.21.0 github.com/go-sql-driver/mysql v1.9.3 - github.com/go-webauthn/webauthn v0.13.0 + github.com/go-webauthn/webauthn v0.13.1 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.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-20250317173921-a4b03ec1a45e + github.com/google/pprof v0.0.0-20250630185457-6e76a2b096b5 github.com/google/uuid v1.6.0 github.com/gorilla/feeds v1.2.0 github.com/gorilla/sessions v1.4.0 @@ -99,13 +99,13 @@ require ( github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc gitlab.com/gitlab-org/api/client-go v0.130.1 go.uber.org/mock v0.5.2 - golang.org/x/crypto v0.39.0 + golang.org/x/crypto v0.40.0 golang.org/x/image v0.27.0 - golang.org/x/net v0.41.0 + golang.org/x/net v0.42.0 golang.org/x/oauth2 v0.30.0 - golang.org/x/sync v0.15.0 - golang.org/x/sys v0.33.0 - golang.org/x/text v0.26.0 + golang.org/x/sync v0.16.0 + golang.org/x/sys v0.34.0 + golang.org/x/text v0.27.0 google.golang.org/protobuf v1.36.4 gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df gopkg.in/ini.v1 v1.67.0 @@ -170,7 +170,7 @@ require ( github.com/go-openapi/jsonpointer v0.21.1 // indirect github.com/go-openapi/jsonreference v0.21.0 // indirect github.com/go-openapi/swag v0.23.1 // indirect - github.com/go-webauthn/x v0.1.21 // indirect + github.com/go-webauthn/x v0.1.22 // indirect github.com/goccy/go-json v0.10.5 // indirect github.com/golang-jwt/jwt/v4 v4.5.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect @@ -244,7 +244,7 @@ require ( replace github.com/hashicorp/go-version => github.com/6543/go-version v1.3.1 -replace github.com/nektos/act => code.forgejo.org/forgejo/act v1.28.0 +replace github.com/nektos/act => code.forgejo.org/forgejo/act v1.29.0 replace github.com/mholt/archiver/v3 => code.forgejo.org/forgejo/archiver/v3 v3.5.1 diff --git a/go.sum b/go.sum index 45497a1b49..3c906b45c6 100644 --- a/go.sum +++ b/go.sum @@ -4,8 +4,8 @@ code.forgejo.org/f3/gof3/v3 v3.11.0 h1:f/xToKwqTgxG6PYxvewywjDQyCcyHEEJ6sZqUitFs code.forgejo.org/f3/gof3/v3 v3.11.0/go.mod h1:4FaRUNSQGBiD1M0DuB0yNv+Z2wMtlOeckgygHSSq4KQ= 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.28.0 h1:96njNC7C1YNyjWq5OWvLZMF/nw0PMthzIA8Nwbnn7jo= -code.forgejo.org/forgejo/act v1.28.0/go.mod h1:dFuiwAmD5vyrzecysHB2kL/GM3wRpoVPl+WdbCTC8Bs= +code.forgejo.org/forgejo/act v1.29.0 h1:CPiI0LRPU0f6gUdQj1ZVax0ySc8CfegY4hiRsymdZU0= +code.forgejo.org/forgejo/act v1.29.0/go.mod h1:RPqtuaI2FkC1SVOaYCRODo5jIfoMTBVgEOOP3Sdiuh4= 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-rpmutils v1.0.0 h1:RZGGeKt70p/WaIEL97pyT6uiiEIoN8/aLmS5Z6WmX0M= @@ -62,8 +62,8 @@ github.com/SaveTheRbtz/zstd-seekable-format-go/pkg v0.7.2/go.mod h1:JitQWJ8JuV4Y 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.18.0 h1:6h53Q4hW83SuF+jcsp7CVhLsMozzvQvO8HBbKQW+gn4= -github.com/alecthomas/chroma/v2 v2.18.0/go.mod h1:RVX6AvYm4VfYe/zsk7mjHueLDZor3aWCNE14TFlepBk= +github.com/alecthomas/chroma/v2 v2.19.0 h1:Im+SLRgT8maArxv81mULDWN8oKxkzboH07CHesxElq4= +github.com/alecthomas/chroma/v2 v2.19.0/go.mod h1:RVX6AvYm4VfYe/zsk7mjHueLDZor3aWCNE14TFlepBk= 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= @@ -215,8 +215,8 @@ github.com/go-asn1-ber/asn1-ber v1.5.5/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkPro github.com/go-chi/chi/v5 v5.0.1/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-chi/chi/v5 v5.2.2 h1:CMwsvRVTbXVytCk1Wd72Zy1LAsAh9GxMmSNWLHCG618= github.com/go-chi/chi/v5 v5.2.2/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops= -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-chi/cors v1.2.2 h1:Jmey33TE+b+rB7fT8MUy1u0I4L+NARQlK6LhzKPSyQE= +github.com/go-chi/cors v1.2.2/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.9.2 h1:giOQAtCgBX08kosrX818DCQJTCNtKwoPBGu0qb6nKTY= @@ -250,10 +250,10 @@ github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI6 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.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= -github.com/go-webauthn/webauthn v0.13.0 h1:cJIL1/1l+22UekVhipziAaSgESJxokYkowUqAIsWs0Y= -github.com/go-webauthn/webauthn v0.13.0/go.mod h1:Oy9o2o79dbLKRPZWWgRIOdtBGAhKnDIaBp2PFkICRHs= -github.com/go-webauthn/x v0.1.21 h1:nFbckQxudvHEJn2uy1VEi713MeSpApoAv9eRqsb9AdQ= -github.com/go-webauthn/x v0.1.21/go.mod h1:sEYohtg1zL4An1TXIUIQ5csdmoO+WO0R4R2pGKaHYKA= +github.com/go-webauthn/webauthn v0.13.1 h1:Q3/GLXsckVJUPE+BGR6ex26yRIiZ/X2ITaMeSkOftuc= +github.com/go-webauthn/webauthn v0.13.1/go.mod h1:HeaBromTjgMg1sHZOzyjEiqcrk4Og7mxafDTWDepaXI= +github.com/go-webauthn/x v0.1.22 h1:rHilV/rYXawarI0uA3uZ5nhLb30Ex8RgbVAsOSt/57o= +github.com/go-webauthn/x v0.1.22/go.mod h1:+iV9BF4OsvLYzETdc0lmQO2webTos10oH6QydSoWxDM= 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= @@ -307,8 +307,8 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ 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-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs= -github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= +github.com/google/pprof v0.0.0-20250630185457-6e76a2b096b5 h1:xhMrHhTJ6zxu3gA4enFM9MLn9AY7613teCdFnlUVbSQ= +github.com/google/pprof v0.0.0-20250630185457-6e76a2b096b5/go.mod h1:5hDyRhoBCxViHszMt12TnOpEI4VVi+U8Gm9iphldiMA= 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= @@ -585,8 +585,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY 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.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM= -golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= +golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= +golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= 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.27.0 h1:C8gA4oWU/tKkdCfYT6T2u4faJu3MeNS5O8UPWlPF61w= @@ -614,8 +614,8 @@ 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.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw= -golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA= +golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= +golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -627,8 +627,8 @@ 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.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8= -golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.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= @@ -654,8 +654,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= -golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= +golang.org/x/sys v0.34.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= @@ -665,8 +665,8 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= 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.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg= -golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ= +golang.org/x/term v0.33.0 h1:NuFncQrRcaRvVmgRkvM3j/F00gWIAlcmlB8ACEKmGIg= +golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -677,8 +677,8 @@ 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.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.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= -golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= +golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= +golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/models/actions/run.go b/models/actions/run.go index 55def805ed..69592120e9 100644 --- a/models/actions/run.go +++ b/models/actions/run.go @@ -284,16 +284,10 @@ func GetLatestRun(ctx context.Context, repoID int64) (*ActionRun, error) { return &run, nil } -// GetRunBefore returns the last run that completed a given timestamp (not inclusive). -func GetRunBefore(ctx context.Context, repoID int64, timestamp timeutil.TimeStamp) (*ActionRun, error) { - var run ActionRun - has, err := db.GetEngine(ctx).Where("repo_id=? AND stopped IS NOT NULL AND stoppedmalicious /'?&" + description: "Malicious label ' " + color: '#000000' + exclusive: true + num_issues: 0 + num_closed_issues: 0 + archived_unix: 0 + +- + id: 12 + repo_id: 3 + org_id: 0 + name: 'archived label<>' + color: '#000000' + exclusive: false + num_issues: 0 + num_closed_issues: 0 + archived_unix: 2991092130 diff --git a/models/fixtures/login_source.yml b/models/fixtures/login_source.yml deleted file mode 100644 index ca780a73aa..0000000000 --- a/models/fixtures/login_source.yml +++ /dev/null @@ -1 +0,0 @@ -[] # empty diff --git a/models/fixtures/protected_branch.yml b/models/fixtures/protected_branch.yml deleted file mode 100644 index ca780a73aa..0000000000 --- a/models/fixtures/protected_branch.yml +++ /dev/null @@ -1 +0,0 @@ -[] # empty diff --git a/models/fixtures/pull_auto_merge.yml b/models/fixtures/pull_auto_merge.yml deleted file mode 100644 index ca780a73aa..0000000000 --- a/models/fixtures/pull_auto_merge.yml +++ /dev/null @@ -1 +0,0 @@ -[] # empty diff --git a/models/fixtures/push_mirror.yml b/models/fixtures/push_mirror.yml deleted file mode 100644 index ca780a73aa..0000000000 --- a/models/fixtures/push_mirror.yml +++ /dev/null @@ -1 +0,0 @@ -[] # empty diff --git a/models/fixtures/repo_archiver.yml b/models/fixtures/repo_archiver.yml deleted file mode 100644 index ca780a73aa..0000000000 --- a/models/fixtures/repo_archiver.yml +++ /dev/null @@ -1 +0,0 @@ -[] # empty diff --git a/models/fixtures/repo_indexer_status.yml b/models/fixtures/repo_indexer_status.yml deleted file mode 100644 index ca780a73aa..0000000000 --- a/models/fixtures/repo_indexer_status.yml +++ /dev/null @@ -1 +0,0 @@ -[] # empty diff --git a/models/fixtures/secret.yml b/models/fixtures/secret.yml deleted file mode 100644 index ca780a73aa..0000000000 --- a/models/fixtures/secret.yml +++ /dev/null @@ -1 +0,0 @@ -[] # empty diff --git a/models/forgejo_migrations/main_test.go b/models/forgejo_migrations/main_test.go index 031fe8090d..2246e327f0 100644 --- a/models/forgejo_migrations/main_test.go +++ b/models/forgejo_migrations/main_test.go @@ -1,7 +1,7 @@ // Copyright 2023 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT -package forgejo_migrations //nolint:revive +package forgejo_migrations import ( "testing" diff --git a/models/forgejo_migrations/migrate.go b/models/forgejo_migrations/migrate.go index 737350b019..fcea69d23f 100644 --- a/models/forgejo_migrations/migrate.go +++ b/models/forgejo_migrations/migrate.go @@ -1,7 +1,7 @@ // Copyright 2023 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT -package forgejo_migrations //nolint:revive +package forgejo_migrations import ( "context" @@ -108,7 +108,9 @@ var migrations = []*Migration{ // v33 -> v34 NewMigration("Add `notify-email` column to `action_run` table", AddNotifyEmailToActionRun), // v34 -> v35 - NewMigration("Add index to `stopped` column in `action_run` table", AddIndexToActionRunStopped), + NewMigration("Noop because of https://codeberg.org/forgejo/forgejo/issues/8373", NoopAddIndexToActionRunStopped), + // v35 -> v36 + NewMigration("Fix wiki unit default permission", FixWikiUnitDefaultPermission), } // GetCurrentDBVersion returns the current Forgejo database version. diff --git a/models/forgejo_migrations/migrate_test.go b/models/forgejo_migrations/migrate_test.go index 20653929a3..9d16c9fe1c 100644 --- a/models/forgejo_migrations/migrate_test.go +++ b/models/forgejo_migrations/migrate_test.go @@ -1,7 +1,7 @@ // Copyright 2023 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT -package forgejo_migrations //nolint:revive +package forgejo_migrations import ( "testing" diff --git a/models/forgejo_migrations/v13.go b/models/forgejo_migrations/v13.go index 614f68249d..ba4183885e 100644 --- a/models/forgejo_migrations/v13.go +++ b/models/forgejo_migrations/v13.go @@ -1,7 +1,7 @@ // Copyright 2024 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT -package forgejo_migrations //nolint:revive +package forgejo_migrations import "xorm.io/xorm" diff --git a/models/forgejo_migrations/v14.go b/models/forgejo_migrations/v14.go index 53f1ef2223..65b857d343 100644 --- a/models/forgejo_migrations/v14.go +++ b/models/forgejo_migrations/v14.go @@ -1,7 +1,7 @@ // Copyright 2024 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT -package forgejo_migrations //nolint:revive +package forgejo_migrations import ( "forgejo.org/models/migrations/base" diff --git a/models/forgejo_migrations/v15.go b/models/forgejo_migrations/v15.go index 5e5588dd05..a63199ab19 100644 --- a/models/forgejo_migrations/v15.go +++ b/models/forgejo_migrations/v15.go @@ -1,7 +1,7 @@ // Copyright 2024 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT -package forgejo_migrations //nolint:revive +package forgejo_migrations import ( "time" diff --git a/models/forgejo_migrations/v16.go b/models/forgejo_migrations/v16.go index f80bfc5268..a7d4d5d590 100644 --- a/models/forgejo_migrations/v16.go +++ b/models/forgejo_migrations/v16.go @@ -1,7 +1,7 @@ // Copyright 2024 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT -package forgejo_migrations //nolint:revive +package forgejo_migrations import "xorm.io/xorm" diff --git a/models/forgejo_migrations/v17.go b/models/forgejo_migrations/v17.go index d6e2983d00..8ef6f2c681 100644 --- a/models/forgejo_migrations/v17.go +++ b/models/forgejo_migrations/v17.go @@ -1,7 +1,7 @@ // Copyright 2024 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT -package forgejo_migrations //nolint:revive +package forgejo_migrations import "xorm.io/xorm" diff --git a/models/forgejo_migrations/v18.go b/models/forgejo_migrations/v18.go index e6c1493f0e..e39b0cbf10 100644 --- a/models/forgejo_migrations/v18.go +++ b/models/forgejo_migrations/v18.go @@ -1,7 +1,7 @@ // Copyright 2024 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT -package forgejo_migrations //nolint:revive +package forgejo_migrations import "xorm.io/xorm" diff --git a/models/forgejo_migrations/v19.go b/models/forgejo_migrations/v19.go index 69b7746eb1..43d279dcb0 100644 --- a/models/forgejo_migrations/v19.go +++ b/models/forgejo_migrations/v19.go @@ -1,7 +1,7 @@ // Copyright 2024 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT -package forgejo_migrations //nolint:revive +package forgejo_migrations import "xorm.io/xorm" diff --git a/models/forgejo_migrations/v1_20/v1.go b/models/forgejo_migrations/v1_20/v1.go index 72beaf23de..f0cb125557 100644 --- a/models/forgejo_migrations/v1_20/v1.go +++ b/models/forgejo_migrations/v1_20/v1.go @@ -1,7 +1,7 @@ // Copyright 2023 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT -package forgejo_v1_20 //nolint:revive +package forgejo_v1_20 import ( "forgejo.org/modules/timeutil" diff --git a/models/forgejo_migrations/v1_20/v2.go b/models/forgejo_migrations/v1_20/v2.go index 39f3b58924..3f79ac3801 100644 --- a/models/forgejo_migrations/v1_20/v2.go +++ b/models/forgejo_migrations/v1_20/v2.go @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -package forgejo_v1_20 //nolint:revive +package forgejo_v1_20 import ( "xorm.io/xorm" diff --git a/models/forgejo_migrations/v1_20/v3.go b/models/forgejo_migrations/v1_20/v3.go index cce227e6eb..49530df556 100644 --- a/models/forgejo_migrations/v1_20/v3.go +++ b/models/forgejo_migrations/v1_20/v3.go @@ -1,7 +1,7 @@ // Copyright 2023 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT -package forgejo_v1_20 //nolint:revive +package forgejo_v1_20 import ( "forgejo.org/modules/timeutil" diff --git a/models/forgejo_migrations/v1_22/main_test.go b/models/forgejo_migrations/v1_22/main_test.go index 03c4c5272c..d6a5bdacee 100644 --- a/models/forgejo_migrations/v1_22/main_test.go +++ b/models/forgejo_migrations/v1_22/main_test.go @@ -1,7 +1,7 @@ // Copyright 2024 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 import ( "testing" diff --git a/models/forgejo_migrations/v1_22/v10.go b/models/forgejo_migrations/v1_22/v10.go index 819800ae71..cf45abdd24 100644 --- a/models/forgejo_migrations/v1_22/v10.go +++ b/models/forgejo_migrations/v1_22/v10.go @@ -1,7 +1,7 @@ // Copyright 2024 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 import ( "xorm.io/xorm" diff --git a/models/forgejo_migrations/v1_22/v11.go b/models/forgejo_migrations/v1_22/v11.go index 17bb592379..f0f92bd04c 100644 --- a/models/forgejo_migrations/v1_22/v11.go +++ b/models/forgejo_migrations/v1_22/v11.go @@ -1,7 +1,7 @@ // Copyright 2024 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 import ( "forgejo.org/modules/timeutil" diff --git a/models/forgejo_migrations/v1_22/v12.go b/models/forgejo_migrations/v1_22/v12.go index 6822524705..51354bd3c2 100644 --- a/models/forgejo_migrations/v1_22/v12.go +++ b/models/forgejo_migrations/v1_22/v12.go @@ -1,7 +1,7 @@ // Copyright 2024 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 import "xorm.io/xorm" diff --git a/models/forgejo_migrations/v1_22/v4.go b/models/forgejo_migrations/v1_22/v4.go index f1195f5f66..499d377bb4 100644 --- a/models/forgejo_migrations/v1_22/v4.go +++ b/models/forgejo_migrations/v1_22/v4.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 import ( "xorm.io/xorm" diff --git a/models/forgejo_migrations/v1_22/v5.go b/models/forgejo_migrations/v1_22/v5.go index 55f9fe1338..1671d3eed2 100644 --- a/models/forgejo_migrations/v1_22/v5.go +++ b/models/forgejo_migrations/v1_22/v5.go @@ -1,7 +1,7 @@ // Copyright 2024 The Forgejo Authors c/o Codeberg e.V.. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 import ( "xorm.io/xorm" diff --git a/models/forgejo_migrations/v1_22/v6.go b/models/forgejo_migrations/v1_22/v6.go index 1a4874872c..072f8e6a15 100644 --- a/models/forgejo_migrations/v1_22/v6.go +++ b/models/forgejo_migrations/v1_22/v6.go @@ -1,7 +1,7 @@ // Copyright 2024 The Forgejo Authors c/o Codeberg e.V.. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 import ( "xorm.io/xorm" diff --git a/models/forgejo_migrations/v1_22/v7.go b/models/forgejo_migrations/v1_22/v7.go index b42dd1af67..e7f6eb412b 100644 --- a/models/forgejo_migrations/v1_22/v7.go +++ b/models/forgejo_migrations/v1_22/v7.go @@ -1,7 +1,7 @@ // Copyright 2024 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 import ( "xorm.io/xorm" diff --git a/models/forgejo_migrations/v1_22/v8.go b/models/forgejo_migrations/v1_22/v8.go index 2d3c0c594b..f23b00d2ad 100644 --- a/models/forgejo_migrations/v1_22/v8.go +++ b/models/forgejo_migrations/v1_22/v8.go @@ -1,7 +1,7 @@ // Copyright 2024 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 import ( "strings" diff --git a/models/forgejo_migrations/v1_22/v8_test.go b/models/forgejo_migrations/v1_22/v8_test.go index baaba7290f..5117dd2dfb 100644 --- a/models/forgejo_migrations/v1_22/v8_test.go +++ b/models/forgejo_migrations/v1_22/v8_test.go @@ -1,7 +1,7 @@ // Copyright 2024 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 import ( "testing" diff --git a/models/forgejo_migrations/v1_22/v9.go b/models/forgejo_migrations/v1_22/v9.go index 34c2844c39..e3cdea97f2 100644 --- a/models/forgejo_migrations/v1_22/v9.go +++ b/models/forgejo_migrations/v1_22/v9.go @@ -1,7 +1,7 @@ // Copyright 2024 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 import "xorm.io/xorm" diff --git a/models/forgejo_migrations/v20.go b/models/forgejo_migrations/v20.go index 8ca9e91f73..91c7b8e911 100644 --- a/models/forgejo_migrations/v20.go +++ b/models/forgejo_migrations/v20.go @@ -1,7 +1,7 @@ // Copyright 2024 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT -package forgejo_migrations //nolint:revive +package forgejo_migrations import "xorm.io/xorm" diff --git a/models/forgejo_migrations/v21.go b/models/forgejo_migrations/v21.go index 53f141b2ab..61d7950c5a 100644 --- a/models/forgejo_migrations/v21.go +++ b/models/forgejo_migrations/v21.go @@ -1,7 +1,7 @@ // Copyright 2024 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT -package forgejo_migrations //nolint:revive +package forgejo_migrations import "xorm.io/xorm" diff --git a/models/forgejo_migrations/v22.go b/models/forgejo_migrations/v22.go index eeb738799c..8078591da6 100644 --- a/models/forgejo_migrations/v22.go +++ b/models/forgejo_migrations/v22.go @@ -1,7 +1,7 @@ // Copyright 2024 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT -package forgejo_migrations //nolint:revive +package forgejo_migrations import "xorm.io/xorm" diff --git a/models/forgejo_migrations/v23.go b/models/forgejo_migrations/v23.go index 20a916a716..a79a4f3d6e 100644 --- a/models/forgejo_migrations/v23.go +++ b/models/forgejo_migrations/v23.go @@ -1,7 +1,7 @@ // Copyright 2024 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT -package forgejo_migrations //nolint:revive +package forgejo_migrations import "xorm.io/xorm" diff --git a/models/forgejo_migrations/v24.go b/models/forgejo_migrations/v24.go index ebfb5fc1c4..084a57e1ce 100644 --- a/models/forgejo_migrations/v24.go +++ b/models/forgejo_migrations/v24.go @@ -1,7 +1,7 @@ // Copyright 2024 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT -package forgejo_migrations //nolint:revive +package forgejo_migrations import "xorm.io/xorm" diff --git a/models/forgejo_migrations/v25.go b/models/forgejo_migrations/v25.go index 8e3032a40c..56cde499a3 100644 --- a/models/forgejo_migrations/v25.go +++ b/models/forgejo_migrations/v25.go @@ -1,7 +1,7 @@ // Copyright 2024 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT -package forgejo_migrations //nolint:revive +package forgejo_migrations import ( "context" diff --git a/models/forgejo_migrations/v25_test.go b/models/forgejo_migrations/v25_test.go index e7402fd021..68e71da012 100644 --- a/models/forgejo_migrations/v25_test.go +++ b/models/forgejo_migrations/v25_test.go @@ -1,7 +1,7 @@ // Copyright 2024 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT -package forgejo_migrations //nolint:revive +package forgejo_migrations import ( "testing" diff --git a/models/forgejo_migrations/v26.go b/models/forgejo_migrations/v26.go index 3292d93ffd..a0c47799c2 100644 --- a/models/forgejo_migrations/v26.go +++ b/models/forgejo_migrations/v26.go @@ -1,7 +1,7 @@ // Copyright 2024 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT -package forgejo_migrations //nolint:revive +package forgejo_migrations import "xorm.io/xorm" diff --git a/models/forgejo_migrations/v27.go b/models/forgejo_migrations/v27.go index 2efa3485a8..9cfbc64370 100644 --- a/models/forgejo_migrations/v27.go +++ b/models/forgejo_migrations/v27.go @@ -1,7 +1,7 @@ // Copyright 2024 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: GPL-3.0-or-later -package forgejo_migrations //nolint:revive +package forgejo_migrations import ( "forgejo.org/modules/timeutil" diff --git a/models/forgejo_migrations/v28.go b/models/forgejo_migrations/v28.go index cba888d2ec..19f0dcd862 100644 --- a/models/forgejo_migrations/v28.go +++ b/models/forgejo_migrations/v28.go @@ -1,7 +1,7 @@ // Copyright 2024 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT -package forgejo_migrations //nolint:revive +package forgejo_migrations import "xorm.io/xorm" diff --git a/models/forgejo_migrations/v29.go b/models/forgejo_migrations/v29.go index d0c2f723ae..92eb05e8b3 100644 --- a/models/forgejo_migrations/v29.go +++ b/models/forgejo_migrations/v29.go @@ -1,7 +1,7 @@ // Copyright 2025 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT -package forgejo_migrations //nolint:revive +package forgejo_migrations import ( "database/sql" diff --git a/models/forgejo_migrations/v30.go b/models/forgejo_migrations/v30.go index 6c41a55316..05a1dff898 100644 --- a/models/forgejo_migrations/v30.go +++ b/models/forgejo_migrations/v30.go @@ -1,7 +1,7 @@ // Copyright 2025 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT -package forgejo_migrations //nolint:revive +package forgejo_migrations import ( "time" diff --git a/models/forgejo_migrations/v30_test.go b/models/forgejo_migrations/v30_test.go index f826dab815..152fddeb47 100644 --- a/models/forgejo_migrations/v30_test.go +++ b/models/forgejo_migrations/v30_test.go @@ -1,7 +1,7 @@ // Copyright 2025 The Forgejo Authors. // SPDX-License-Identifier: GPL-3.0-or-later -package forgejo_migrations //nolint:revive +package forgejo_migrations import ( "testing" diff --git a/models/forgejo_migrations/v31.go b/models/forgejo_migrations/v31.go index fdcab21b1a..23397c7c13 100644 --- a/models/forgejo_migrations/v31.go +++ b/models/forgejo_migrations/v31.go @@ -1,7 +1,7 @@ // Copyright 2025 The Forgejo Authors. // SPDX-License-Identifier: GPL-3.0-or-later -package forgejo_migrations //nolint:revive +package forgejo_migrations import ( "xorm.io/xorm" diff --git a/models/forgejo_migrations/v31_test.go b/models/forgejo_migrations/v31_test.go index 5b4aac2a60..6d1690aae0 100644 --- a/models/forgejo_migrations/v31_test.go +++ b/models/forgejo_migrations/v31_test.go @@ -1,7 +1,7 @@ // Copyright 2025 The Forgejo Authors. // SPDX-License-Identifier: GPL-3.0-or-later -package forgejo_migrations //nolint:revive +package forgejo_migrations import ( "testing" diff --git a/models/forgejo_migrations/v32.go b/models/forgejo_migrations/v32.go index bed335ab6b..81b22c585c 100644 --- a/models/forgejo_migrations/v32.go +++ b/models/forgejo_migrations/v32.go @@ -1,7 +1,7 @@ // Copyright 2025 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: GPL-3.0-or-later -package forgejo_migrations //nolint:revive +package forgejo_migrations import ( "encoding/xml" diff --git a/models/forgejo_migrations/v32_test.go b/models/forgejo_migrations/v32_test.go index cd33de2608..24cda891bc 100644 --- a/models/forgejo_migrations/v32_test.go +++ b/models/forgejo_migrations/v32_test.go @@ -1,7 +1,7 @@ // Copyright 2025 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: GPL-3.0-or-later -package forgejo_migrations //nolint:revive +package forgejo_migrations import ( "bytes" diff --git a/models/forgejo_migrations/v33.go b/models/forgejo_migrations/v33.go index 272035fc23..b9ea8efe47 100644 --- a/models/forgejo_migrations/v33.go +++ b/models/forgejo_migrations/v33.go @@ -1,7 +1,7 @@ // Copyright 2025 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT -package forgejo_migrations //nolint:revive +package forgejo_migrations import ( "fmt" diff --git a/models/forgejo_migrations/v33_test.go b/models/forgejo_migrations/v33_test.go index 664c704bbc..1d3298da15 100644 --- a/models/forgejo_migrations/v33_test.go +++ b/models/forgejo_migrations/v33_test.go @@ -1,7 +1,7 @@ // Copyright 2025 The Forgejo Authors. // SPDX-License-Identifier: GPL-3.0-or-later -package forgejo_migrations //nolint:revive +package forgejo_migrations import ( "testing" diff --git a/models/forgejo_migrations/v34.go b/models/forgejo_migrations/v34.go index 9e958b934f..d193d799e7 100644 --- a/models/forgejo_migrations/v34.go +++ b/models/forgejo_migrations/v34.go @@ -1,7 +1,7 @@ // Copyright 2025 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: GPL-3.0-or-later -package forgejo_migrations //nolint:revive +package forgejo_migrations import "xorm.io/xorm" diff --git a/models/forgejo_migrations/v35.go b/models/forgejo_migrations/v35.go index 0fb3b43e2c..9b389fcc12 100644 --- a/models/forgejo_migrations/v35.go +++ b/models/forgejo_migrations/v35.go @@ -1,19 +1,13 @@ // Copyright 2025 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: GPL-3.0-or-later -package forgejo_migrations //nolint:revive +package forgejo_migrations import ( - "forgejo.org/modules/timeutil" - "xorm.io/xorm" ) -func AddIndexToActionRunStopped(x *xorm.Engine) error { - type ActionRun struct { - ID int64 - Stopped timeutil.TimeStamp `xorm:"index"` - } - - return x.Sync(&ActionRun{}) +// see https://codeberg.org/forgejo/forgejo/issues/8373 +func NoopAddIndexToActionRunStopped(x *xorm.Engine) error { + return nil } diff --git a/models/forgejo_migrations/v36.go b/models/forgejo_migrations/v36.go new file mode 100644 index 0000000000..1a798147cf --- /dev/null +++ b/models/forgejo_migrations/v36.go @@ -0,0 +1,55 @@ +// Copyright 2025 The Forgejo Authors. All rights reserved. +// SPDX-License-Identifier: GPL-3.0-or-later + +package forgejo_migrations + +import ( + "xorm.io/xorm" +) + +func FixWikiUnitDefaultPermission(x *xorm.Engine) error { + // Type is Unit's Type + type Type int + + // Enumerate all the unit types + const ( + TypeInvalid Type = iota // 0 invalid + TypeCode // 1 code + TypeIssues // 2 issues + TypePullRequests // 3 PRs + TypeReleases // 4 Releases + TypeWiki // 5 Wiki + TypeExternalWiki // 6 ExternalWiki + TypeExternalTracker // 7 ExternalTracker + TypeProjects // 8 Projects + TypePackages // 9 Packages + TypeActions // 10 Actions + ) + + // RepoUnitAccessMode specifies the users access mode to a repo unit + type UnitAccessMode int + + const ( + // UnitAccessModeUnset - no unit mode set + UnitAccessModeUnset UnitAccessMode = iota // 0 + // UnitAccessModeNone no access + UnitAccessModeNone // 1 + // UnitAccessModeRead read access + UnitAccessModeRead // 2 + // UnitAccessModeWrite write access + UnitAccessModeWrite // 3 + ) + _ = UnitAccessModeNone + _ = UnitAccessModeWrite + + type RepoUnit struct { + DefaultPermissions UnitAccessMode `xorm:"NOT NULL DEFAULT 0"` + } + _, err := x.Where("type = ?", TypeWiki). + Where("default_permissions = ?", UnitAccessModeRead). + Cols("default_permissions"). + Update(RepoUnit{ + DefaultPermissions: UnitAccessModeUnset, + }) + return err +} diff --git a/models/migrations/test/tests.go b/models/migrations/test/tests.go index c1f0caf19b..6be3b3c2fc 100644 --- a/models/migrations/test/tests.go +++ b/models/migrations/test/tests.go @@ -95,7 +95,8 @@ func PrepareTestEnv(t *testing.T, skip int, syncModels ...any) (*xorm.Engine, fu t.Logf("initializing fixtures from: %s", fixturesDir) if err := unittest.InitFixtures( unittest.FixturesOptions{ - Dir: fixturesDir, + Dir: fixturesDir, + SkipCleanRegistedModels: true, }, x); err != nil { t.Errorf("error whilst initializing fixtures from %s: %v", fixturesDir, err) return x, deferFn diff --git a/models/migrations/v1_10/v100.go b/models/migrations/v1_10/v100.go index 5d2fd8e244..1742bea296 100644 --- a/models/migrations/v1_10/v100.go +++ b/models/migrations/v1_10/v100.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_10 //nolint +package v1_10 import ( "net/url" diff --git a/models/migrations/v1_10/v101.go b/models/migrations/v1_10/v101.go index f023a2a0e7..6c8dfe2486 100644 --- a/models/migrations/v1_10/v101.go +++ b/models/migrations/v1_10/v101.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_10 //nolint +package v1_10 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_10/v88.go b/models/migrations/v1_10/v88.go index 7e86ac364f..eb8e81c19e 100644 --- a/models/migrations/v1_10/v88.go +++ b/models/migrations/v1_10/v88.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_10 //nolint +package v1_10 import ( "crypto/sha1" diff --git a/models/migrations/v1_10/v89.go b/models/migrations/v1_10/v89.go index d5f27ffdc6..0df2a6e17b 100644 --- a/models/migrations/v1_10/v89.go +++ b/models/migrations/v1_10/v89.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_10 //nolint +package v1_10 import "xorm.io/xorm" diff --git a/models/migrations/v1_10/v90.go b/models/migrations/v1_10/v90.go index 295d4b1c1b..5521a97e32 100644 --- a/models/migrations/v1_10/v90.go +++ b/models/migrations/v1_10/v90.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_10 //nolint +package v1_10 import "xorm.io/xorm" diff --git a/models/migrations/v1_10/v91.go b/models/migrations/v1_10/v91.go index 48cac2de70..08db6c2742 100644 --- a/models/migrations/v1_10/v91.go +++ b/models/migrations/v1_10/v91.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_10 //nolint +package v1_10 import "xorm.io/xorm" diff --git a/models/migrations/v1_10/v92.go b/models/migrations/v1_10/v92.go index 9080108594..b6c04a9234 100644 --- a/models/migrations/v1_10/v92.go +++ b/models/migrations/v1_10/v92.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_10 //nolint +package v1_10 import ( "xorm.io/builder" diff --git a/models/migrations/v1_10/v93.go b/models/migrations/v1_10/v93.go index ee59a8db39..c131be9a8d 100644 --- a/models/migrations/v1_10/v93.go +++ b/models/migrations/v1_10/v93.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_10 //nolint +package v1_10 import "xorm.io/xorm" diff --git a/models/migrations/v1_10/v94.go b/models/migrations/v1_10/v94.go index c131af162b..13b7d7b303 100644 --- a/models/migrations/v1_10/v94.go +++ b/models/migrations/v1_10/v94.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_10 //nolint +package v1_10 import "xorm.io/xorm" diff --git a/models/migrations/v1_10/v95.go b/models/migrations/v1_10/v95.go index 3b1f67fd9c..86b52026bf 100644 --- a/models/migrations/v1_10/v95.go +++ b/models/migrations/v1_10/v95.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_10 //nolint +package v1_10 import "xorm.io/xorm" diff --git a/models/migrations/v1_10/v96.go b/models/migrations/v1_10/v96.go index 3bfb770f24..bcbd618b49 100644 --- a/models/migrations/v1_10/v96.go +++ b/models/migrations/v1_10/v96.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_10 //nolint +package v1_10 import ( "path/filepath" diff --git a/models/migrations/v1_10/v97.go b/models/migrations/v1_10/v97.go index dee45b32e3..5872bb63e5 100644 --- a/models/migrations/v1_10/v97.go +++ b/models/migrations/v1_10/v97.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_10 //nolint +package v1_10 import "xorm.io/xorm" diff --git a/models/migrations/v1_10/v98.go b/models/migrations/v1_10/v98.go index bdd9aed089..d21c326459 100644 --- a/models/migrations/v1_10/v98.go +++ b/models/migrations/v1_10/v98.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_10 //nolint +package v1_10 import "xorm.io/xorm" diff --git a/models/migrations/v1_10/v99.go b/models/migrations/v1_10/v99.go index 7f287b77aa..addae66be9 100644 --- a/models/migrations/v1_10/v99.go +++ b/models/migrations/v1_10/v99.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_10 //nolint +package v1_10 import ( "forgejo.org/modules/timeutil" diff --git a/models/migrations/v1_11/v102.go b/models/migrations/v1_11/v102.go index a585d9c423..15f0c83c36 100644 --- a/models/migrations/v1_11/v102.go +++ b/models/migrations/v1_11/v102.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_11 //nolint +package v1_11 import ( "forgejo.org/models/migrations/base" diff --git a/models/migrations/v1_11/v103.go b/models/migrations/v1_11/v103.go index 53527dac58..a515710160 100644 --- a/models/migrations/v1_11/v103.go +++ b/models/migrations/v1_11/v103.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_11 //nolint +package v1_11 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_11/v104.go b/models/migrations/v1_11/v104.go index af3578ca4a..7461f0cda3 100644 --- a/models/migrations/v1_11/v104.go +++ b/models/migrations/v1_11/v104.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_11 //nolint +package v1_11 import ( "forgejo.org/models/migrations/base" diff --git a/models/migrations/v1_11/v105.go b/models/migrations/v1_11/v105.go index b91340c30a..d86973a0f6 100644 --- a/models/migrations/v1_11/v105.go +++ b/models/migrations/v1_11/v105.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_11 //nolint +package v1_11 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_11/v106.go b/models/migrations/v1_11/v106.go index ecb11cdd1e..edffe18683 100644 --- a/models/migrations/v1_11/v106.go +++ b/models/migrations/v1_11/v106.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_11 //nolint +package v1_11 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_11/v107.go b/models/migrations/v1_11/v107.go index f0bfe5862c..a158e3bb50 100644 --- a/models/migrations/v1_11/v107.go +++ b/models/migrations/v1_11/v107.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_11 //nolint +package v1_11 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_11/v108.go b/models/migrations/v1_11/v108.go index a85096234d..8f14504ceb 100644 --- a/models/migrations/v1_11/v108.go +++ b/models/migrations/v1_11/v108.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_11 //nolint +package v1_11 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_11/v109.go b/models/migrations/v1_11/v109.go index ea565ccda3..f7616aec7b 100644 --- a/models/migrations/v1_11/v109.go +++ b/models/migrations/v1_11/v109.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_11 //nolint +package v1_11 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_11/v110.go b/models/migrations/v1_11/v110.go index fce9be847e..e94a738f67 100644 --- a/models/migrations/v1_11/v110.go +++ b/models/migrations/v1_11/v110.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_11 //nolint +package v1_11 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_11/v111.go b/models/migrations/v1_11/v111.go index cc3dc0d545..6f531e4858 100644 --- a/models/migrations/v1_11/v111.go +++ b/models/migrations/v1_11/v111.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_11 //nolint +package v1_11 import ( "fmt" diff --git a/models/migrations/v1_11/v112.go b/models/migrations/v1_11/v112.go index 6112ab51a5..22054e6f68 100644 --- a/models/migrations/v1_11/v112.go +++ b/models/migrations/v1_11/v112.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_11 //nolint +package v1_11 import ( "fmt" diff --git a/models/migrations/v1_11/v113.go b/models/migrations/v1_11/v113.go index dea344a44f..a4d54f66fb 100644 --- a/models/migrations/v1_11/v113.go +++ b/models/migrations/v1_11/v113.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_11 //nolint +package v1_11 import ( "fmt" diff --git a/models/migrations/v1_11/v114.go b/models/migrations/v1_11/v114.go index 95adcee989..9467a8a90c 100644 --- a/models/migrations/v1_11/v114.go +++ b/models/migrations/v1_11/v114.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_11 //nolint +package v1_11 import ( "net/url" diff --git a/models/migrations/v1_11/v115.go b/models/migrations/v1_11/v115.go index 3d4b41017b..65094df93d 100644 --- a/models/migrations/v1_11/v115.go +++ b/models/migrations/v1_11/v115.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_11 //nolint +package v1_11 import ( "crypto/md5" diff --git a/models/migrations/v1_11/v116.go b/models/migrations/v1_11/v116.go index 85aa76c1e0..729fbad18b 100644 --- a/models/migrations/v1_11/v116.go +++ b/models/migrations/v1_11/v116.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_11 //nolint +package v1_11 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_12/v117.go b/models/migrations/v1_12/v117.go index 8eadcdef2b..73b58ca34b 100644 --- a/models/migrations/v1_12/v117.go +++ b/models/migrations/v1_12/v117.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_12 //nolint +package v1_12 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_12/v118.go b/models/migrations/v1_12/v118.go index eb022dc5e4..e8b4249743 100644 --- a/models/migrations/v1_12/v118.go +++ b/models/migrations/v1_12/v118.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_12 //nolint +package v1_12 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_12/v119.go b/models/migrations/v1_12/v119.go index 60bfe6a57d..b4bf29a935 100644 --- a/models/migrations/v1_12/v119.go +++ b/models/migrations/v1_12/v119.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_12 //nolint +package v1_12 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_12/v120.go b/models/migrations/v1_12/v120.go index 3f7ed8d373..14d515f5a7 100644 --- a/models/migrations/v1_12/v120.go +++ b/models/migrations/v1_12/v120.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_12 //nolint +package v1_12 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_12/v121.go b/models/migrations/v1_12/v121.go index 175ec9164d..a28ae4e1c9 100644 --- a/models/migrations/v1_12/v121.go +++ b/models/migrations/v1_12/v121.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_12 //nolint +package v1_12 import "xorm.io/xorm" diff --git a/models/migrations/v1_12/v122.go b/models/migrations/v1_12/v122.go index 6e31d863a1..bc1b175f6a 100644 --- a/models/migrations/v1_12/v122.go +++ b/models/migrations/v1_12/v122.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_12 //nolint +package v1_12 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_12/v123.go b/models/migrations/v1_12/v123.go index b0c3af07a3..52b10bb850 100644 --- a/models/migrations/v1_12/v123.go +++ b/models/migrations/v1_12/v123.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_12 //nolint +package v1_12 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_12/v124.go b/models/migrations/v1_12/v124.go index d2ba03ffe0..9a93f436d4 100644 --- a/models/migrations/v1_12/v124.go +++ b/models/migrations/v1_12/v124.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_12 //nolint +package v1_12 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_12/v125.go b/models/migrations/v1_12/v125.go index ec4ffaab25..7f582ecff5 100644 --- a/models/migrations/v1_12/v125.go +++ b/models/migrations/v1_12/v125.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_12 //nolint +package v1_12 import ( "fmt" diff --git a/models/migrations/v1_12/v126.go b/models/migrations/v1_12/v126.go index ca9ec3aa3f..64fd7f7478 100644 --- a/models/migrations/v1_12/v126.go +++ b/models/migrations/v1_12/v126.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_12 //nolint +package v1_12 import ( "xorm.io/builder" diff --git a/models/migrations/v1_12/v127.go b/models/migrations/v1_12/v127.go index 11a4042973..f686fa617c 100644 --- a/models/migrations/v1_12/v127.go +++ b/models/migrations/v1_12/v127.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_12 //nolint +package v1_12 import ( "fmt" diff --git a/models/migrations/v1_12/v128.go b/models/migrations/v1_12/v128.go index 6d7307f470..8fca974616 100644 --- a/models/migrations/v1_12/v128.go +++ b/models/migrations/v1_12/v128.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_12 //nolint +package v1_12 import ( "fmt" diff --git a/models/migrations/v1_12/v129.go b/models/migrations/v1_12/v129.go index cf228242b9..3e4d3aca68 100644 --- a/models/migrations/v1_12/v129.go +++ b/models/migrations/v1_12/v129.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_12 //nolint +package v1_12 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_12/v130.go b/models/migrations/v1_12/v130.go index bfa856796a..383ef47492 100644 --- a/models/migrations/v1_12/v130.go +++ b/models/migrations/v1_12/v130.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_12 //nolint +package v1_12 import ( "forgejo.org/modules/json" diff --git a/models/migrations/v1_12/v131.go b/models/migrations/v1_12/v131.go index 5184bc3590..1266c2f185 100644 --- a/models/migrations/v1_12/v131.go +++ b/models/migrations/v1_12/v131.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_12 //nolint +package v1_12 import ( "fmt" diff --git a/models/migrations/v1_12/v132.go b/models/migrations/v1_12/v132.go index 3b2b28f7ab..8b1ae6db93 100644 --- a/models/migrations/v1_12/v132.go +++ b/models/migrations/v1_12/v132.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_12 //nolint +package v1_12 import ( "fmt" diff --git a/models/migrations/v1_12/v133.go b/models/migrations/v1_12/v133.go index c9087fc8c1..69e20597d8 100644 --- a/models/migrations/v1_12/v133.go +++ b/models/migrations/v1_12/v133.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_12 //nolint +package v1_12 import "xorm.io/xorm" diff --git a/models/migrations/v1_12/v134.go b/models/migrations/v1_12/v134.go index bba996fd40..1fabdcae96 100644 --- a/models/migrations/v1_12/v134.go +++ b/models/migrations/v1_12/v134.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_12 //nolint +package v1_12 import ( "fmt" diff --git a/models/migrations/v1_12/v135.go b/models/migrations/v1_12/v135.go index 8898011df5..5df0ad7fc4 100644 --- a/models/migrations/v1_12/v135.go +++ b/models/migrations/v1_12/v135.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_12 //nolint +package v1_12 import ( "fmt" diff --git a/models/migrations/v1_12/v136.go b/models/migrations/v1_12/v136.go index e2557ae002..7d246a82be 100644 --- a/models/migrations/v1_12/v136.go +++ b/models/migrations/v1_12/v136.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_12 //nolint +package v1_12 import ( "fmt" diff --git a/models/migrations/v1_12/v137.go b/models/migrations/v1_12/v137.go index 0d86b72010..9d38483488 100644 --- a/models/migrations/v1_12/v137.go +++ b/models/migrations/v1_12/v137.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_12 //nolint +package v1_12 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_12/v138.go b/models/migrations/v1_12/v138.go index 8c8d353f40..4485adeb2d 100644 --- a/models/migrations/v1_12/v138.go +++ b/models/migrations/v1_12/v138.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_12 //nolint +package v1_12 import ( "fmt" diff --git a/models/migrations/v1_12/v139.go b/models/migrations/v1_12/v139.go index cd7963524e..51e57b984a 100644 --- a/models/migrations/v1_12/v139.go +++ b/models/migrations/v1_12/v139.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_12 //nolint +package v1_12 import ( "forgejo.org/modules/setting" diff --git a/models/migrations/v1_13/v140.go b/models/migrations/v1_13/v140.go index d74f808e9f..5bb612c098 100644 --- a/models/migrations/v1_13/v140.go +++ b/models/migrations/v1_13/v140.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_13 //nolint +package v1_13 import ( "fmt" diff --git a/models/migrations/v1_13/v141.go b/models/migrations/v1_13/v141.go index ae211e0e44..b54bc1727c 100644 --- a/models/migrations/v1_13/v141.go +++ b/models/migrations/v1_13/v141.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_13 //nolint +package v1_13 import ( "fmt" diff --git a/models/migrations/v1_13/v142.go b/models/migrations/v1_13/v142.go index 7490e0f3b4..8939f6f2f8 100644 --- a/models/migrations/v1_13/v142.go +++ b/models/migrations/v1_13/v142.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_13 //nolint +package v1_13 import ( "forgejo.org/modules/log" diff --git a/models/migrations/v1_13/v143.go b/models/migrations/v1_13/v143.go index 1f9120e2ba..6a8da8b06d 100644 --- a/models/migrations/v1_13/v143.go +++ b/models/migrations/v1_13/v143.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_13 //nolint +package v1_13 import ( "forgejo.org/modules/log" diff --git a/models/migrations/v1_13/v144.go b/models/migrations/v1_13/v144.go index 7e801eab8a..f138338514 100644 --- a/models/migrations/v1_13/v144.go +++ b/models/migrations/v1_13/v144.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_13 //nolint +package v1_13 import ( "forgejo.org/modules/log" diff --git a/models/migrations/v1_13/v145.go b/models/migrations/v1_13/v145.go index a01f577ed1..f7d3895c84 100644 --- a/models/migrations/v1_13/v145.go +++ b/models/migrations/v1_13/v145.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_13 //nolint +package v1_13 import ( "fmt" diff --git a/models/migrations/v1_13/v146.go b/models/migrations/v1_13/v146.go index a1b54ee3aa..e6a476a288 100644 --- a/models/migrations/v1_13/v146.go +++ b/models/migrations/v1_13/v146.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_13 //nolint +package v1_13 import ( "forgejo.org/modules/timeutil" diff --git a/models/migrations/v1_13/v147.go b/models/migrations/v1_13/v147.go index cc57504c74..831ef5842a 100644 --- a/models/migrations/v1_13/v147.go +++ b/models/migrations/v1_13/v147.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_13 //nolint +package v1_13 import ( "forgejo.org/modules/timeutil" diff --git a/models/migrations/v1_13/v148.go b/models/migrations/v1_13/v148.go index 7bb8ab700b..d276db3d61 100644 --- a/models/migrations/v1_13/v148.go +++ b/models/migrations/v1_13/v148.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_13 //nolint +package v1_13 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_13/v149.go b/models/migrations/v1_13/v149.go index 3a0c5909d5..c1bfe8b09e 100644 --- a/models/migrations/v1_13/v149.go +++ b/models/migrations/v1_13/v149.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_13 //nolint +package v1_13 import ( "fmt" diff --git a/models/migrations/v1_13/v150.go b/models/migrations/v1_13/v150.go index be14fd130c..471a531024 100644 --- a/models/migrations/v1_13/v150.go +++ b/models/migrations/v1_13/v150.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_13 //nolint +package v1_13 import ( "forgejo.org/models/migrations/base" diff --git a/models/migrations/v1_13/v151.go b/models/migrations/v1_13/v151.go index ff584fff67..691b86062d 100644 --- a/models/migrations/v1_13/v151.go +++ b/models/migrations/v1_13/v151.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_13 //nolint +package v1_13 import ( "context" diff --git a/models/migrations/v1_13/v152.go b/models/migrations/v1_13/v152.go index 502c82a40d..648e26446f 100644 --- a/models/migrations/v1_13/v152.go +++ b/models/migrations/v1_13/v152.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_13 //nolint +package v1_13 import "xorm.io/xorm" diff --git a/models/migrations/v1_13/v153.go b/models/migrations/v1_13/v153.go index 0b2dd3eb62..e5462fc162 100644 --- a/models/migrations/v1_13/v153.go +++ b/models/migrations/v1_13/v153.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_13 //nolint +package v1_13 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_13/v154.go b/models/migrations/v1_13/v154.go index cf31190781..89dc7821b2 100644 --- a/models/migrations/v1_13/v154.go +++ b/models/migrations/v1_13/v154.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_13 //nolint +package v1_13 import ( "forgejo.org/modules/timeutil" diff --git a/models/migrations/v1_14/main_test.go b/models/migrations/v1_14/main_test.go index c01faedc35..57cf995be1 100644 --- a/models/migrations/v1_14/main_test.go +++ b/models/migrations/v1_14/main_test.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_14 //nolint +package v1_14 import ( "testing" diff --git a/models/migrations/v1_14/v155.go b/models/migrations/v1_14/v155.go index e814f59938..505a9ae033 100644 --- a/models/migrations/v1_14/v155.go +++ b/models/migrations/v1_14/v155.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_14 //nolint +package v1_14 import ( "fmt" diff --git a/models/migrations/v1_14/v156.go b/models/migrations/v1_14/v156.go index b6dc91a054..7bbd9f4c85 100644 --- a/models/migrations/v1_14/v156.go +++ b/models/migrations/v1_14/v156.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_14 //nolint +package v1_14 import ( "fmt" diff --git a/models/migrations/v1_14/v157.go b/models/migrations/v1_14/v157.go index 7187278d29..ba69f71130 100644 --- a/models/migrations/v1_14/v157.go +++ b/models/migrations/v1_14/v157.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_14 //nolint +package v1_14 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_14/v158.go b/models/migrations/v1_14/v158.go index 3fa27cfecd..2ab3c8a1f0 100644 --- a/models/migrations/v1_14/v158.go +++ b/models/migrations/v1_14/v158.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_14 //nolint +package v1_14 import ( "errors" diff --git a/models/migrations/v1_14/v159.go b/models/migrations/v1_14/v159.go index fdd7e12449..4e921ea1c6 100644 --- a/models/migrations/v1_14/v159.go +++ b/models/migrations/v1_14/v159.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_14 //nolint +package v1_14 import ( "forgejo.org/models/migrations/base" diff --git a/models/migrations/v1_14/v160.go b/models/migrations/v1_14/v160.go index 4dea91b514..73f3798954 100644 --- a/models/migrations/v1_14/v160.go +++ b/models/migrations/v1_14/v160.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_14 //nolint +package v1_14 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_14/v161.go b/models/migrations/v1_14/v161.go index 6e904cfab6..9c850ad0c2 100644 --- a/models/migrations/v1_14/v161.go +++ b/models/migrations/v1_14/v161.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_14 //nolint +package v1_14 import ( "context" diff --git a/models/migrations/v1_14/v162.go b/models/migrations/v1_14/v162.go index 5d6d7c2e3f..ead63f16f4 100644 --- a/models/migrations/v1_14/v162.go +++ b/models/migrations/v1_14/v162.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_14 //nolint +package v1_14 import ( "forgejo.org/models/migrations/base" diff --git a/models/migrations/v1_14/v163.go b/models/migrations/v1_14/v163.go index 60fc98c0a4..06ac36cbc7 100644 --- a/models/migrations/v1_14/v163.go +++ b/models/migrations/v1_14/v163.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_14 //nolint +package v1_14 import ( "forgejo.org/models/migrations/base" diff --git a/models/migrations/v1_14/v164.go b/models/migrations/v1_14/v164.go index 54f6951427..d2fd9b8464 100644 --- a/models/migrations/v1_14/v164.go +++ b/models/migrations/v1_14/v164.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_14 //nolint +package v1_14 import ( "fmt" diff --git a/models/migrations/v1_14/v165.go b/models/migrations/v1_14/v165.go index 9315e44197..90fd2b1e46 100644 --- a/models/migrations/v1_14/v165.go +++ b/models/migrations/v1_14/v165.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_14 //nolint +package v1_14 import ( "forgejo.org/models/migrations/base" diff --git a/models/migrations/v1_14/v166.go b/models/migrations/v1_14/v166.go index e5731582fd..4c106bd7da 100644 --- a/models/migrations/v1_14/v166.go +++ b/models/migrations/v1_14/v166.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_14 //nolint +package v1_14 import ( "crypto/sha256" diff --git a/models/migrations/v1_14/v167.go b/models/migrations/v1_14/v167.go index 9d416f6a32..d77bbc401e 100644 --- a/models/migrations/v1_14/v167.go +++ b/models/migrations/v1_14/v167.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_14 //nolint +package v1_14 import ( "fmt" diff --git a/models/migrations/v1_14/v168.go b/models/migrations/v1_14/v168.go index a30a8859f7..aa93eec19b 100644 --- a/models/migrations/v1_14/v168.go +++ b/models/migrations/v1_14/v168.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_14 //nolint +package v1_14 import "xorm.io/xorm" diff --git a/models/migrations/v1_14/v169.go b/models/migrations/v1_14/v169.go index 5b81bb58b1..4f9df0d96f 100644 --- a/models/migrations/v1_14/v169.go +++ b/models/migrations/v1_14/v169.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_14 //nolint +package v1_14 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_14/v170.go b/models/migrations/v1_14/v170.go index 7b6498a3e9..a2ff4623e1 100644 --- a/models/migrations/v1_14/v170.go +++ b/models/migrations/v1_14/v170.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_14 //nolint +package v1_14 import ( "fmt" diff --git a/models/migrations/v1_14/v171.go b/models/migrations/v1_14/v171.go index 51a35a02ad..7b200e960a 100644 --- a/models/migrations/v1_14/v171.go +++ b/models/migrations/v1_14/v171.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_14 //nolint +package v1_14 import ( "fmt" diff --git a/models/migrations/v1_14/v172.go b/models/migrations/v1_14/v172.go index d49b70f5ad..c410d393f1 100644 --- a/models/migrations/v1_14/v172.go +++ b/models/migrations/v1_14/v172.go @@ -1,7 +1,7 @@ // Copyright 2020 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_14 //nolint +package v1_14 import ( "forgejo.org/modules/timeutil" diff --git a/models/migrations/v1_14/v173.go b/models/migrations/v1_14/v173.go index 2d9eee9197..7752fbe966 100644 --- a/models/migrations/v1_14/v173.go +++ b/models/migrations/v1_14/v173.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_14 //nolint +package v1_14 import ( "fmt" diff --git a/models/migrations/v1_14/v174.go b/models/migrations/v1_14/v174.go index c839e15db8..4049e43070 100644 --- a/models/migrations/v1_14/v174.go +++ b/models/migrations/v1_14/v174.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_14 //nolint +package v1_14 import ( "fmt" diff --git a/models/migrations/v1_14/v175.go b/models/migrations/v1_14/v175.go index 3cda5772a0..49fa17d046 100644 --- a/models/migrations/v1_14/v175.go +++ b/models/migrations/v1_14/v175.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_14 //nolint +package v1_14 import ( "fmt" diff --git a/models/migrations/v1_14/v176.go b/models/migrations/v1_14/v176.go index 1ed49f75fa..ef5dce9a02 100644 --- a/models/migrations/v1_14/v176.go +++ b/models/migrations/v1_14/v176.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_14 //nolint +package v1_14 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_14/v176_test.go b/models/migrations/v1_14/v176_test.go index d88ff207e7..d56b3e0470 100644 --- a/models/migrations/v1_14/v176_test.go +++ b/models/migrations/v1_14/v176_test.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_14 //nolint +package v1_14 import ( "testing" diff --git a/models/migrations/v1_14/v177.go b/models/migrations/v1_14/v177.go index 6e1838f369..96676bf8d9 100644 --- a/models/migrations/v1_14/v177.go +++ b/models/migrations/v1_14/v177.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_14 //nolint +package v1_14 import ( "fmt" diff --git a/models/migrations/v1_14/v177_test.go b/models/migrations/v1_14/v177_test.go index bffc6f92e3..0e0a67fd33 100644 --- a/models/migrations/v1_14/v177_test.go +++ b/models/migrations/v1_14/v177_test.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_14 //nolint +package v1_14 import ( "testing" diff --git a/models/migrations/v1_15/main_test.go b/models/migrations/v1_15/main_test.go index 6c04d3f5ee..4cf6d6f695 100644 --- a/models/migrations/v1_15/main_test.go +++ b/models/migrations/v1_15/main_test.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_15 //nolint +package v1_15 import ( "testing" diff --git a/models/migrations/v1_15/v178.go b/models/migrations/v1_15/v178.go index 6d236eb049..ca3a5c262e 100644 --- a/models/migrations/v1_15/v178.go +++ b/models/migrations/v1_15/v178.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_15 //nolint +package v1_15 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_15/v179.go b/models/migrations/v1_15/v179.go index b990583303..ce514cc4a9 100644 --- a/models/migrations/v1_15/v179.go +++ b/models/migrations/v1_15/v179.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_15 //nolint +package v1_15 import ( "forgejo.org/models/migrations/base" diff --git a/models/migrations/v1_15/v180.go b/models/migrations/v1_15/v180.go index 02fbd57cdb..0b68c3ceb7 100644 --- a/models/migrations/v1_15/v180.go +++ b/models/migrations/v1_15/v180.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_15 //nolint +package v1_15 import ( "forgejo.org/modules/json" diff --git a/models/migrations/v1_15/v181.go b/models/migrations/v1_15/v181.go index 2185ed0213..fb1d3d7a75 100644 --- a/models/migrations/v1_15/v181.go +++ b/models/migrations/v1_15/v181.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_15 //nolint +package v1_15 import ( "strings" diff --git a/models/migrations/v1_15/v181_test.go b/models/migrations/v1_15/v181_test.go index 4154e0b1e9..8196f751e5 100644 --- a/models/migrations/v1_15/v181_test.go +++ b/models/migrations/v1_15/v181_test.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_15 //nolint +package v1_15 import ( "strings" diff --git a/models/migrations/v1_15/v182.go b/models/migrations/v1_15/v182.go index 9ca500c0f9..f53ff11df9 100644 --- a/models/migrations/v1_15/v182.go +++ b/models/migrations/v1_15/v182.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_15 //nolint +package v1_15 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_15/v182_test.go b/models/migrations/v1_15/v182_test.go index 6865cafac4..2baf90d06a 100644 --- a/models/migrations/v1_15/v182_test.go +++ b/models/migrations/v1_15/v182_test.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_15 //nolint +package v1_15 import ( "testing" diff --git a/models/migrations/v1_15/v183.go b/models/migrations/v1_15/v183.go index aaad64c220..5684e35699 100644 --- a/models/migrations/v1_15/v183.go +++ b/models/migrations/v1_15/v183.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_15 //nolint +package v1_15 import ( "fmt" diff --git a/models/migrations/v1_15/v184.go b/models/migrations/v1_15/v184.go index 41b64d4743..fbe0dcd780 100644 --- a/models/migrations/v1_15/v184.go +++ b/models/migrations/v1_15/v184.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_15 //nolint +package v1_15 import ( "context" diff --git a/models/migrations/v1_15/v185.go b/models/migrations/v1_15/v185.go index e5878ec193..60af59edca 100644 --- a/models/migrations/v1_15/v185.go +++ b/models/migrations/v1_15/v185.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_15 //nolint +package v1_15 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_15/v186.go b/models/migrations/v1_15/v186.go index ad75822de5..55d3199335 100644 --- a/models/migrations/v1_15/v186.go +++ b/models/migrations/v1_15/v186.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_15 //nolint +package v1_15 import ( "forgejo.org/modules/timeutil" diff --git a/models/migrations/v1_15/v187.go b/models/migrations/v1_15/v187.go index b573fc52ef..fabef14779 100644 --- a/models/migrations/v1_15/v187.go +++ b/models/migrations/v1_15/v187.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_15 //nolint +package v1_15 import ( "forgejo.org/models/migrations/base" diff --git a/models/migrations/v1_15/v188.go b/models/migrations/v1_15/v188.go index 71e45cab0e..4494e6ff05 100644 --- a/models/migrations/v1_15/v188.go +++ b/models/migrations/v1_15/v188.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_15 //nolint +package v1_15 import "xorm.io/xorm" diff --git a/models/migrations/v1_16/main_test.go b/models/migrations/v1_16/main_test.go index 6f891f3e94..8c0a043be6 100644 --- a/models/migrations/v1_16/main_test.go +++ b/models/migrations/v1_16/main_test.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_16 //nolint +package v1_16 import ( "testing" diff --git a/models/migrations/v1_16/v189.go b/models/migrations/v1_16/v189.go index 1ee72d9c39..19bfcb2423 100644 --- a/models/migrations/v1_16/v189.go +++ b/models/migrations/v1_16/v189.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_16 //nolint +package v1_16 import ( "encoding/binary" diff --git a/models/migrations/v1_16/v189_test.go b/models/migrations/v1_16/v189_test.go index 90b721d5f1..9d74462a92 100644 --- a/models/migrations/v1_16/v189_test.go +++ b/models/migrations/v1_16/v189_test.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_16 //nolint +package v1_16 import ( "testing" diff --git a/models/migrations/v1_16/v190.go b/models/migrations/v1_16/v190.go index 5953802849..1eb6b6ddb4 100644 --- a/models/migrations/v1_16/v190.go +++ b/models/migrations/v1_16/v190.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_16 //nolint +package v1_16 import ( "fmt" diff --git a/models/migrations/v1_16/v191.go b/models/migrations/v1_16/v191.go index 567f88d6d1..427476b70b 100644 --- a/models/migrations/v1_16/v191.go +++ b/models/migrations/v1_16/v191.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_16 //nolint +package v1_16 import ( "forgejo.org/modules/setting" diff --git a/models/migrations/v1_16/v192.go b/models/migrations/v1_16/v192.go index 731b9fb43a..31e8c36346 100644 --- a/models/migrations/v1_16/v192.go +++ b/models/migrations/v1_16/v192.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_16 //nolint +package v1_16 import ( "forgejo.org/models/migrations/base" diff --git a/models/migrations/v1_16/v193.go b/models/migrations/v1_16/v193.go index 8d3ce7a558..a5af2de380 100644 --- a/models/migrations/v1_16/v193.go +++ b/models/migrations/v1_16/v193.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_16 //nolint +package v1_16 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_16/v193_test.go b/models/migrations/v1_16/v193_test.go index 8260acf32d..bf8d8a7dc6 100644 --- a/models/migrations/v1_16/v193_test.go +++ b/models/migrations/v1_16/v193_test.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_16 //nolint +package v1_16 import ( "testing" diff --git a/models/migrations/v1_16/v194.go b/models/migrations/v1_16/v194.go index 6aa13c50cf..2e4ed8340e 100644 --- a/models/migrations/v1_16/v194.go +++ b/models/migrations/v1_16/v194.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_16 //nolint +package v1_16 import ( "fmt" diff --git a/models/migrations/v1_16/v195.go b/models/migrations/v1_16/v195.go index 6d7e94141e..4fd42b7bd2 100644 --- a/models/migrations/v1_16/v195.go +++ b/models/migrations/v1_16/v195.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_16 //nolint +package v1_16 import ( "fmt" diff --git a/models/migrations/v1_16/v195_test.go b/models/migrations/v1_16/v195_test.go index 71234a6fb3..1fc7b51f3c 100644 --- a/models/migrations/v1_16/v195_test.go +++ b/models/migrations/v1_16/v195_test.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_16 //nolint +package v1_16 import ( "testing" diff --git a/models/migrations/v1_16/v196.go b/models/migrations/v1_16/v196.go index 7cbafc61e5..6c9caa100f 100644 --- a/models/migrations/v1_16/v196.go +++ b/models/migrations/v1_16/v196.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_16 //nolint +package v1_16 import ( "fmt" diff --git a/models/migrations/v1_16/v197.go b/models/migrations/v1_16/v197.go index 97888b2847..862bdfdcbd 100644 --- a/models/migrations/v1_16/v197.go +++ b/models/migrations/v1_16/v197.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_16 //nolint +package v1_16 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_16/v198.go b/models/migrations/v1_16/v198.go index 8b3c73addc..5d3043eb46 100644 --- a/models/migrations/v1_16/v198.go +++ b/models/migrations/v1_16/v198.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_16 //nolint +package v1_16 import ( "fmt" diff --git a/models/migrations/v1_16/v199.go b/models/migrations/v1_16/v199.go index 6adcf890af..4020352f2b 100644 --- a/models/migrations/v1_16/v199.go +++ b/models/migrations/v1_16/v199.go @@ -1,6 +1,6 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_16 //nolint +package v1_16 // We used to use a table `remote_version` to store information for updater, now we use `AppState`, so this migration task is a no-op now. diff --git a/models/migrations/v1_16/v200.go b/models/migrations/v1_16/v200.go index c08c20e51d..de57fad8fe 100644 --- a/models/migrations/v1_16/v200.go +++ b/models/migrations/v1_16/v200.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_16 //nolint +package v1_16 import ( "fmt" diff --git a/models/migrations/v1_16/v201.go b/models/migrations/v1_16/v201.go index 35e0c9f2fb..2c43698b0c 100644 --- a/models/migrations/v1_16/v201.go +++ b/models/migrations/v1_16/v201.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_16 //nolint +package v1_16 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_16/v202.go b/models/migrations/v1_16/v202.go index 6ba36152f1..d8c8fdcadc 100644 --- a/models/migrations/v1_16/v202.go +++ b/models/migrations/v1_16/v202.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_16 //nolint +package v1_16 import ( "fmt" diff --git a/models/migrations/v1_16/v203.go b/models/migrations/v1_16/v203.go index e8e6b52453..c3241cba57 100644 --- a/models/migrations/v1_16/v203.go +++ b/models/migrations/v1_16/v203.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_16 //nolint +package v1_16 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_16/v204.go b/models/migrations/v1_16/v204.go index ece03e1305..4d375307e7 100644 --- a/models/migrations/v1_16/v204.go +++ b/models/migrations/v1_16/v204.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_16 //nolint +package v1_16 import "xorm.io/xorm" diff --git a/models/migrations/v1_16/v205.go b/models/migrations/v1_16/v205.go index a064b9830d..cb452dfd7f 100644 --- a/models/migrations/v1_16/v205.go +++ b/models/migrations/v1_16/v205.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_16 //nolint +package v1_16 import ( "forgejo.org/models/migrations/base" diff --git a/models/migrations/v1_16/v206.go b/models/migrations/v1_16/v206.go index 581a7d76e9..01a9c386eb 100644 --- a/models/migrations/v1_16/v206.go +++ b/models/migrations/v1_16/v206.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_16 //nolint +package v1_16 import ( "fmt" diff --git a/models/migrations/v1_16/v207.go b/models/migrations/v1_16/v207.go index 91208f066c..19126ead1f 100644 --- a/models/migrations/v1_16/v207.go +++ b/models/migrations/v1_16/v207.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_16 //nolint +package v1_16 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_16/v208.go b/models/migrations/v1_16/v208.go index 1a11ef096a..fb643324f4 100644 --- a/models/migrations/v1_16/v208.go +++ b/models/migrations/v1_16/v208.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_16 //nolint +package v1_16 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_16/v209.go b/models/migrations/v1_16/v209.go index be3100e02a..230838647b 100644 --- a/models/migrations/v1_16/v209.go +++ b/models/migrations/v1_16/v209.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_16 //nolint +package v1_16 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_16/v210.go b/models/migrations/v1_16/v210.go index 375a008e18..f48ab11db6 100644 --- a/models/migrations/v1_16/v210.go +++ b/models/migrations/v1_16/v210.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_16 //nolint +package v1_16 import ( "crypto/ecdh" diff --git a/models/migrations/v1_16/v210_test.go b/models/migrations/v1_16/v210_test.go index f6423a5821..8454920aa0 100644 --- a/models/migrations/v1_16/v210_test.go +++ b/models/migrations/v1_16/v210_test.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_16 //nolint +package v1_16 import ( "encoding/hex" diff --git a/models/migrations/v1_17/main_test.go b/models/migrations/v1_17/main_test.go index 0a8e05ab5f..166860b3b1 100644 --- a/models/migrations/v1_17/main_test.go +++ b/models/migrations/v1_17/main_test.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_17 //nolint +package v1_17 import ( "testing" diff --git a/models/migrations/v1_17/v211.go b/models/migrations/v1_17/v211.go index 9b72c8610b..517cf19388 100644 --- a/models/migrations/v1_17/v211.go +++ b/models/migrations/v1_17/v211.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_17 //nolint +package v1_17 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_17/v212.go b/models/migrations/v1_17/v212.go index 2337adcc80..23868c0bb2 100644 --- a/models/migrations/v1_17/v212.go +++ b/models/migrations/v1_17/v212.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_17 //nolint +package v1_17 import ( "forgejo.org/modules/timeutil" diff --git a/models/migrations/v1_17/v213.go b/models/migrations/v1_17/v213.go index bb3f466e52..b2bbdf7279 100644 --- a/models/migrations/v1_17/v213.go +++ b/models/migrations/v1_17/v213.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_17 //nolint +package v1_17 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_17/v214.go b/models/migrations/v1_17/v214.go index 2268164919..1925324f0f 100644 --- a/models/migrations/v1_17/v214.go +++ b/models/migrations/v1_17/v214.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_17 //nolint +package v1_17 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_17/v215.go b/models/migrations/v1_17/v215.go index 5aae798562..431103c98e 100644 --- a/models/migrations/v1_17/v215.go +++ b/models/migrations/v1_17/v215.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_17 //nolint +package v1_17 import ( "forgejo.org/models/pull" diff --git a/models/migrations/v1_17/v216.go b/models/migrations/v1_17/v216.go index 268f472a42..37aeacb6fc 100644 --- a/models/migrations/v1_17/v216.go +++ b/models/migrations/v1_17/v216.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_17 //nolint +package v1_17 // This migration added non-ideal indices to the action table which on larger datasets slowed things down // it has been superseded by v218.go diff --git a/models/migrations/v1_17/v217.go b/models/migrations/v1_17/v217.go index 5f096d4824..fef48b7a5b 100644 --- a/models/migrations/v1_17/v217.go +++ b/models/migrations/v1_17/v217.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_17 //nolint +package v1_17 import ( "forgejo.org/modules/setting" diff --git a/models/migrations/v1_17/v218.go b/models/migrations/v1_17/v218.go index 5e3dcd0841..412d124286 100644 --- a/models/migrations/v1_17/v218.go +++ b/models/migrations/v1_17/v218.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_17 //nolint +package v1_17 import ( "forgejo.org/modules/setting" diff --git a/models/migrations/v1_17/v219.go b/models/migrations/v1_17/v219.go index e90656090f..7ca6a26be6 100644 --- a/models/migrations/v1_17/v219.go +++ b/models/migrations/v1_17/v219.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_17 //nolint +package v1_17 import ( "time" diff --git a/models/migrations/v1_17/v220.go b/models/migrations/v1_17/v220.go index 61bbf19725..4e010e5b76 100644 --- a/models/migrations/v1_17/v220.go +++ b/models/migrations/v1_17/v220.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_17 //nolint +package v1_17 import ( packages_model "forgejo.org/models/packages" diff --git a/models/migrations/v1_17/v221.go b/models/migrations/v1_17/v221.go index 84e9a238af..3ef34e3f06 100644 --- a/models/migrations/v1_17/v221.go +++ b/models/migrations/v1_17/v221.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_17 //nolint +package v1_17 import ( "encoding/base32" diff --git a/models/migrations/v1_17/v221_test.go b/models/migrations/v1_17/v221_test.go index 02607d6b32..a9c47136b2 100644 --- a/models/migrations/v1_17/v221_test.go +++ b/models/migrations/v1_17/v221_test.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_17 //nolint +package v1_17 import ( "encoding/base32" diff --git a/models/migrations/v1_17/v222.go b/models/migrations/v1_17/v222.go index ae910cbcb6..873769881e 100644 --- a/models/migrations/v1_17/v222.go +++ b/models/migrations/v1_17/v222.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_17 //nolint +package v1_17 import ( "context" diff --git a/models/migrations/v1_17/v223.go b/models/migrations/v1_17/v223.go index 7d92dcf5ae..4f5d34d841 100644 --- a/models/migrations/v1_17/v223.go +++ b/models/migrations/v1_17/v223.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_17 //nolint +package v1_17 import ( "context" diff --git a/models/migrations/v1_18/main_test.go b/models/migrations/v1_18/main_test.go index 33f5c51222..0c20934cea 100644 --- a/models/migrations/v1_18/main_test.go +++ b/models/migrations/v1_18/main_test.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_18 //nolint +package v1_18 import ( "testing" diff --git a/models/migrations/v1_18/v224.go b/models/migrations/v1_18/v224.go index f3d522b91a..6dc12020ea 100644 --- a/models/migrations/v1_18/v224.go +++ b/models/migrations/v1_18/v224.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_18 //nolint +package v1_18 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_18/v225.go b/models/migrations/v1_18/v225.go index 86bcb1323d..266eccfff8 100644 --- a/models/migrations/v1_18/v225.go +++ b/models/migrations/v1_18/v225.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_18 //nolint +package v1_18 import ( "forgejo.org/modules/setting" diff --git a/models/migrations/v1_18/v226.go b/models/migrations/v1_18/v226.go index f87e24b11d..8ed9761476 100644 --- a/models/migrations/v1_18/v226.go +++ b/models/migrations/v1_18/v226.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_18 //nolint +package v1_18 import ( "xorm.io/builder" diff --git a/models/migrations/v1_18/v227.go b/models/migrations/v1_18/v227.go index b6250fb76c..d39a010159 100644 --- a/models/migrations/v1_18/v227.go +++ b/models/migrations/v1_18/v227.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_18 //nolint +package v1_18 import ( "forgejo.org/modules/timeutil" diff --git a/models/migrations/v1_18/v228.go b/models/migrations/v1_18/v228.go index 1161c8a4c9..3f5b69734d 100644 --- a/models/migrations/v1_18/v228.go +++ b/models/migrations/v1_18/v228.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_18 //nolint +package v1_18 import ( "forgejo.org/modules/timeutil" diff --git a/models/migrations/v1_18/v229.go b/models/migrations/v1_18/v229.go index f96dde9840..00d794725f 100644 --- a/models/migrations/v1_18/v229.go +++ b/models/migrations/v1_18/v229.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_18 //nolint +package v1_18 import ( "fmt" diff --git a/models/migrations/v1_18/v229_test.go b/models/migrations/v1_18/v229_test.go index ac5e726a79..903a60c851 100644 --- a/models/migrations/v1_18/v229_test.go +++ b/models/migrations/v1_18/v229_test.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_18 //nolint +package v1_18 import ( "testing" diff --git a/models/migrations/v1_18/v230.go b/models/migrations/v1_18/v230.go index ea5b4d02e1..078fce7643 100644 --- a/models/migrations/v1_18/v230.go +++ b/models/migrations/v1_18/v230.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_18 //nolint +package v1_18 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_18/v230_test.go b/models/migrations/v1_18/v230_test.go index 7dd6675673..da31b0dc9b 100644 --- a/models/migrations/v1_18/v230_test.go +++ b/models/migrations/v1_18/v230_test.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_18 //nolint +package v1_18 import ( "testing" diff --git a/models/migrations/v1_19/main_test.go b/models/migrations/v1_19/main_test.go index 7c56926f4c..9d1c3a57ea 100644 --- a/models/migrations/v1_19/main_test.go +++ b/models/migrations/v1_19/main_test.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_19 //nolint +package v1_19 import ( "testing" diff --git a/models/migrations/v1_19/v231.go b/models/migrations/v1_19/v231.go index 79e46132f0..8ef1e4e743 100644 --- a/models/migrations/v1_19/v231.go +++ b/models/migrations/v1_19/v231.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_19 //nolint +package v1_19 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_19/v232.go b/models/migrations/v1_19/v232.go index 7fb4a5ac8d..2aab2cf830 100644 --- a/models/migrations/v1_19/v232.go +++ b/models/migrations/v1_19/v232.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_19 //nolint +package v1_19 import ( "forgejo.org/modules/setting" diff --git a/models/migrations/v1_19/v233.go b/models/migrations/v1_19/v233.go index 191afd4868..e62e8a9356 100644 --- a/models/migrations/v1_19/v233.go +++ b/models/migrations/v1_19/v233.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_19 //nolint +package v1_19 import ( "fmt" diff --git a/models/migrations/v1_19/v233_test.go b/models/migrations/v1_19/v233_test.go index 4dc35d1e27..3d5eac9887 100644 --- a/models/migrations/v1_19/v233_test.go +++ b/models/migrations/v1_19/v233_test.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_19 //nolint +package v1_19 import ( "testing" diff --git a/models/migrations/v1_19/v234.go b/models/migrations/v1_19/v234.go index c610a423dd..e00b1cc2b6 100644 --- a/models/migrations/v1_19/v234.go +++ b/models/migrations/v1_19/v234.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_19 //nolint +package v1_19 import ( "forgejo.org/modules/timeutil" diff --git a/models/migrations/v1_19/v235.go b/models/migrations/v1_19/v235.go index 3715de3920..297d90f65a 100644 --- a/models/migrations/v1_19/v235.go +++ b/models/migrations/v1_19/v235.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_19 //nolint +package v1_19 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_19/v236.go b/models/migrations/v1_19/v236.go index fa01a6ab80..c453f95e04 100644 --- a/models/migrations/v1_19/v236.go +++ b/models/migrations/v1_19/v236.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_19 //nolint +package v1_19 import ( "forgejo.org/modules/timeutil" diff --git a/models/migrations/v1_19/v237.go b/models/migrations/v1_19/v237.go index b23c765aa5..cf30226ccd 100644 --- a/models/migrations/v1_19/v237.go +++ b/models/migrations/v1_19/v237.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_19 //nolint +package v1_19 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_19/v238.go b/models/migrations/v1_19/v238.go index 7c912a8341..b257315319 100644 --- a/models/migrations/v1_19/v238.go +++ b/models/migrations/v1_19/v238.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_19 //nolint +package v1_19 import ( "forgejo.org/modules/timeutil" diff --git a/models/migrations/v1_19/v239.go b/models/migrations/v1_19/v239.go index 10076f2401..8f4a65be95 100644 --- a/models/migrations/v1_19/v239.go +++ b/models/migrations/v1_19/v239.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_19 //nolint +package v1_19 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_19/v240.go b/models/migrations/v1_19/v240.go index 4ca5becede..c49ce2f49a 100644 --- a/models/migrations/v1_19/v240.go +++ b/models/migrations/v1_19/v240.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_19 //nolint +package v1_19 import ( "forgejo.org/models/db" diff --git a/models/migrations/v1_19/v241.go b/models/migrations/v1_19/v241.go index a617d6fd2f..e35801a057 100644 --- a/models/migrations/v1_19/v241.go +++ b/models/migrations/v1_19/v241.go @@ -1,7 +1,7 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_19 //nolint +package v1_19 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_19/v242.go b/models/migrations/v1_19/v242.go index bbf227ef77..87ca9cf214 100644 --- a/models/migrations/v1_19/v242.go +++ b/models/migrations/v1_19/v242.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_19 //nolint +package v1_19 import ( "forgejo.org/modules/setting" diff --git a/models/migrations/v1_19/v243.go b/models/migrations/v1_19/v243.go index 55bbfafb2f..9c3f372594 100644 --- a/models/migrations/v1_19/v243.go +++ b/models/migrations/v1_19/v243.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_19 //nolint +package v1_19 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_20/main_test.go b/models/migrations/v1_20/main_test.go index f870dca429..ee5eec5ef6 100644 --- a/models/migrations/v1_20/main_test.go +++ b/models/migrations/v1_20/main_test.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_20 //nolint +package v1_20 import ( "testing" diff --git a/models/migrations/v1_20/v244.go b/models/migrations/v1_20/v244.go index 977566ad7d..76cdccaca5 100644 --- a/models/migrations/v1_20/v244.go +++ b/models/migrations/v1_20/v244.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_20 //nolint +package v1_20 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_20/v245.go b/models/migrations/v1_20/v245.go index 7e6585388b..5e034568c4 100644 --- a/models/migrations/v1_20/v245.go +++ b/models/migrations/v1_20/v245.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_20 //nolint +package v1_20 import ( "context" diff --git a/models/migrations/v1_20/v246.go b/models/migrations/v1_20/v246.go index e6340ef079..22bf723404 100644 --- a/models/migrations/v1_20/v246.go +++ b/models/migrations/v1_20/v246.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_20 //nolint +package v1_20 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_20/v247.go b/models/migrations/v1_20/v247.go index 9ed810a623..056699d744 100644 --- a/models/migrations/v1_20/v247.go +++ b/models/migrations/v1_20/v247.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_20 //nolint +package v1_20 import ( "forgejo.org/modules/log" diff --git a/models/migrations/v1_20/v248.go b/models/migrations/v1_20/v248.go index 40555210e7..4f2091e4bc 100644 --- a/models/migrations/v1_20/v248.go +++ b/models/migrations/v1_20/v248.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_20 //nolint +package v1_20 import "xorm.io/xorm" diff --git a/models/migrations/v1_20/v249.go b/models/migrations/v1_20/v249.go index d2b096bf58..0aebb2a343 100644 --- a/models/migrations/v1_20/v249.go +++ b/models/migrations/v1_20/v249.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_20 //nolint +package v1_20 import ( "forgejo.org/modules/timeutil" diff --git a/models/migrations/v1_20/v250.go b/models/migrations/v1_20/v250.go index cfcde2fc9b..e12223691f 100644 --- a/models/migrations/v1_20/v250.go +++ b/models/migrations/v1_20/v250.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_20 //nolint +package v1_20 import ( "strings" diff --git a/models/migrations/v1_20/v251.go b/models/migrations/v1_20/v251.go index c8665ba7eb..7d2d259df6 100644 --- a/models/migrations/v1_20/v251.go +++ b/models/migrations/v1_20/v251.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_20 //nolint +package v1_20 import ( "forgejo.org/modules/log" diff --git a/models/migrations/v1_20/v252.go b/models/migrations/v1_20/v252.go index bb85c78309..435cce7ebe 100644 --- a/models/migrations/v1_20/v252.go +++ b/models/migrations/v1_20/v252.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_20 //nolint +package v1_20 import ( "forgejo.org/modules/log" diff --git a/models/migrations/v1_20/v253.go b/models/migrations/v1_20/v253.go index 5f4057e9d9..73354fd485 100644 --- a/models/migrations/v1_20/v253.go +++ b/models/migrations/v1_20/v253.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_20 //nolint +package v1_20 import ( "forgejo.org/modules/log" diff --git a/models/migrations/v1_20/v254.go b/models/migrations/v1_20/v254.go index 1e26979a5b..9cdbfb3916 100644 --- a/models/migrations/v1_20/v254.go +++ b/models/migrations/v1_20/v254.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_20 //nolint +package v1_20 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_20/v255.go b/models/migrations/v1_20/v255.go index 49b0ecf220..baa3c4b6d8 100644 --- a/models/migrations/v1_20/v255.go +++ b/models/migrations/v1_20/v255.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_20 //nolint +package v1_20 import ( "forgejo.org/modules/timeutil" diff --git a/models/migrations/v1_20/v256.go b/models/migrations/v1_20/v256.go index 822153b93e..7b84c1e154 100644 --- a/models/migrations/v1_20/v256.go +++ b/models/migrations/v1_20/v256.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_20 //nolint +package v1_20 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_20/v257.go b/models/migrations/v1_20/v257.go index 70f229d73f..8045909dba 100644 --- a/models/migrations/v1_20/v257.go +++ b/models/migrations/v1_20/v257.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_20 //nolint +package v1_20 import ( "forgejo.org/modules/timeutil" diff --git a/models/migrations/v1_20/v258.go b/models/migrations/v1_20/v258.go index 47174ce805..1d3faffdae 100644 --- a/models/migrations/v1_20/v258.go +++ b/models/migrations/v1_20/v258.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_20 //nolint +package v1_20 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_20/v259.go b/models/migrations/v1_20/v259.go index f10b94fa9c..9b2b68263e 100644 --- a/models/migrations/v1_20/v259.go +++ b/models/migrations/v1_20/v259.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_20 //nolint +package v1_20 import ( "fmt" diff --git a/models/migrations/v1_20/v259_test.go b/models/migrations/v1_20/v259_test.go index 32e4aa3050..b41b6c7995 100644 --- a/models/migrations/v1_20/v259_test.go +++ b/models/migrations/v1_20/v259_test.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_20 //nolint +package v1_20 import ( "sort" diff --git a/models/migrations/v1_21/main_test.go b/models/migrations/v1_21/main_test.go index 7104887afb..3f10a39a94 100644 --- a/models/migrations/v1_21/main_test.go +++ b/models/migrations/v1_21/main_test.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_21 //nolint +package v1_21 import ( "testing" diff --git a/models/migrations/v1_21/v260.go b/models/migrations/v1_21/v260.go index 245f3011ab..b73b53bd61 100644 --- a/models/migrations/v1_21/v260.go +++ b/models/migrations/v1_21/v260.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_21 //nolint +package v1_21 import ( "forgejo.org/models/migrations/base" diff --git a/models/migrations/v1_21/v261.go b/models/migrations/v1_21/v261.go index 743bef152d..83a4927704 100644 --- a/models/migrations/v1_21/v261.go +++ b/models/migrations/v1_21/v261.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_21 //nolint +package v1_21 import ( "forgejo.org/modules/timeutil" diff --git a/models/migrations/v1_21/v262.go b/models/migrations/v1_21/v262.go index 23e900572a..6e88e29b9d 100644 --- a/models/migrations/v1_21/v262.go +++ b/models/migrations/v1_21/v262.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_21 //nolint +package v1_21 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_21/v263.go b/models/migrations/v1_21/v263.go index 2c7cbadf0d..55c418bde0 100644 --- a/models/migrations/v1_21/v263.go +++ b/models/migrations/v1_21/v263.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_21 //nolint +package v1_21 import ( "fmt" diff --git a/models/migrations/v1_21/v264.go b/models/migrations/v1_21/v264.go index 5615600072..acd2c9bb48 100644 --- a/models/migrations/v1_21/v264.go +++ b/models/migrations/v1_21/v264.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_21 //nolint +package v1_21 import ( "context" diff --git a/models/migrations/v1_21/v265.go b/models/migrations/v1_21/v265.go index 800eb95f72..b6892acc27 100644 --- a/models/migrations/v1_21/v265.go +++ b/models/migrations/v1_21/v265.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_21 //nolint +package v1_21 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_21/v266.go b/models/migrations/v1_21/v266.go index 79a5f5e14c..440549e868 100644 --- a/models/migrations/v1_21/v266.go +++ b/models/migrations/v1_21/v266.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_21 //nolint +package v1_21 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_21/v267.go b/models/migrations/v1_21/v267.go index f94696a22b..13992d8776 100644 --- a/models/migrations/v1_21/v267.go +++ b/models/migrations/v1_21/v267.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_21 //nolint +package v1_21 import ( "forgejo.org/modules/timeutil" diff --git a/models/migrations/v1_21/v268.go b/models/migrations/v1_21/v268.go index 332793ff07..b677d2383e 100644 --- a/models/migrations/v1_21/v268.go +++ b/models/migrations/v1_21/v268.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_21 //nolint +package v1_21 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_21/v269.go b/models/migrations/v1_21/v269.go index 475ec02380..042040927d 100644 --- a/models/migrations/v1_21/v269.go +++ b/models/migrations/v1_21/v269.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_21 //nolint +package v1_21 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_21/v270.go b/models/migrations/v1_21/v270.go index b9cc84d3ac..ab7c5660ba 100644 --- a/models/migrations/v1_21/v270.go +++ b/models/migrations/v1_21/v270.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_21 //nolint +package v1_21 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_21/v271.go b/models/migrations/v1_21/v271.go index f45c113c1f..e3ce2d4b74 100644 --- a/models/migrations/v1_21/v271.go +++ b/models/migrations/v1_21/v271.go @@ -1,7 +1,8 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_21 //nolint +package v1_21 + import ( "forgejo.org/modules/timeutil" diff --git a/models/migrations/v1_21/v272.go b/models/migrations/v1_21/v272.go index a729c49f1b..14c1e0c4b0 100644 --- a/models/migrations/v1_21/v272.go +++ b/models/migrations/v1_21/v272.go @@ -1,7 +1,8 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_21 //nolint +package v1_21 + import ( "xorm.io/xorm" ) diff --git a/models/migrations/v1_21/v273.go b/models/migrations/v1_21/v273.go index 1ec6ade566..d6ec80d3d5 100644 --- a/models/migrations/v1_21/v273.go +++ b/models/migrations/v1_21/v273.go @@ -1,7 +1,8 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_21 //nolint +package v1_21 + import ( "forgejo.org/modules/timeutil" diff --git a/models/migrations/v1_21/v274.go b/models/migrations/v1_21/v274.go index b74e5fed51..a1211d1fdd 100644 --- a/models/migrations/v1_21/v274.go +++ b/models/migrations/v1_21/v274.go @@ -1,7 +1,8 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_21 //nolint +package v1_21 + import ( "time" diff --git a/models/migrations/v1_21/v275.go b/models/migrations/v1_21/v275.go index 78804a59d6..2bfe5c72fa 100644 --- a/models/migrations/v1_21/v275.go +++ b/models/migrations/v1_21/v275.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_21 //nolint +package v1_21 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_21/v276.go b/models/migrations/v1_21/v276.go index 0830c3bd92..3b0bc23da7 100644 --- a/models/migrations/v1_21/v276.go +++ b/models/migrations/v1_21/v276.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_21 //nolint +package v1_21 import ( repo_model "forgejo.org/models/repo" diff --git a/models/migrations/v1_21/v277.go b/models/migrations/v1_21/v277.go index 12529160b7..0c102eddde 100644 --- a/models/migrations/v1_21/v277.go +++ b/models/migrations/v1_21/v277.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_21 //nolint +package v1_21 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_21/v278.go b/models/migrations/v1_21/v278.go index d6a462d1e7..846f228678 100644 --- a/models/migrations/v1_21/v278.go +++ b/models/migrations/v1_21/v278.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_21 //nolint +package v1_21 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_21/v279.go b/models/migrations/v1_21/v279.go index 2abd1bbe84..beb39effe1 100644 --- a/models/migrations/v1_21/v279.go +++ b/models/migrations/v1_21/v279.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_21 //nolint +package v1_21 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_22/main_test.go b/models/migrations/v1_22/main_test.go index dc991b78fe..7b05993e09 100644 --- a/models/migrations/v1_22/main_test.go +++ b/models/migrations/v1_22/main_test.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 import ( "testing" diff --git a/models/migrations/v1_22/v280.go b/models/migrations/v1_22/v280.go index a8ee4a3bf7..2271cb6089 100644 --- a/models/migrations/v1_22/v280.go +++ b/models/migrations/v1_22/v280.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_22/v281.go b/models/migrations/v1_22/v281.go index 5271c786be..2eeca9be82 100644 --- a/models/migrations/v1_22/v281.go +++ b/models/migrations/v1_22/v281.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 import ( "forgejo.org/modules/timeutil" diff --git a/models/migrations/v1_22/v282.go b/models/migrations/v1_22/v282.go index baad9e0916..eed64c30f7 100644 --- a/models/migrations/v1_22/v282.go +++ b/models/migrations/v1_22/v282.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_22/v283.go b/models/migrations/v1_22/v283.go index 86946d1c39..33a2513069 100644 --- a/models/migrations/v1_22/v283.go +++ b/models/migrations/v1_22/v283.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_22/v283_test.go b/models/migrations/v1_22/v283_test.go index d8e147a131..652d96ac16 100644 --- a/models/migrations/v1_22/v283_test.go +++ b/models/migrations/v1_22/v283_test.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 import ( "testing" diff --git a/models/migrations/v1_22/v284.go b/models/migrations/v1_22/v284.go index 2b95078980..31b38f6aed 100644 --- a/models/migrations/v1_22/v284.go +++ b/models/migrations/v1_22/v284.go @@ -1,7 +1,8 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 + import ( "xorm.io/xorm" ) diff --git a/models/migrations/v1_22/v285.go b/models/migrations/v1_22/v285.go index a55cc17c04..fed89f670e 100644 --- a/models/migrations/v1_22/v285.go +++ b/models/migrations/v1_22/v285.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 import ( "time" diff --git a/models/migrations/v1_22/v286.go b/models/migrations/v1_22/v286.go index d0489e7aeb..05247bb436 100644 --- a/models/migrations/v1_22/v286.go +++ b/models/migrations/v1_22/v286.go @@ -1,6 +1,6 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 import ( "fmt" diff --git a/models/migrations/v1_22/v286_test.go b/models/migrations/v1_22/v286_test.go index c63deef495..5bb3334df2 100644 --- a/models/migrations/v1_22/v286_test.go +++ b/models/migrations/v1_22/v286_test.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 import ( "testing" diff --git a/models/migrations/v1_22/v287.go b/models/migrations/v1_22/v287.go index c8b1593286..5fd901f9de 100644 --- a/models/migrations/v1_22/v287.go +++ b/models/migrations/v1_22/v287.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_22/v288.go b/models/migrations/v1_22/v288.go index 44e4991851..78be3b6ef2 100644 --- a/models/migrations/v1_22/v288.go +++ b/models/migrations/v1_22/v288.go @@ -1,7 +1,7 @@ // Copyright 2024 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 import ( "forgejo.org/modules/timeutil" diff --git a/models/migrations/v1_22/v289.go b/models/migrations/v1_22/v289.go index b9941aadd9..78689a4ffa 100644 --- a/models/migrations/v1_22/v289.go +++ b/models/migrations/v1_22/v289.go @@ -1,7 +1,7 @@ // Copyright 2024 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 import "xorm.io/xorm" diff --git a/models/migrations/v1_22/v290.go b/models/migrations/v1_22/v290.go index 594e417644..ebafab6567 100644 --- a/models/migrations/v1_22/v290.go +++ b/models/migrations/v1_22/v290.go @@ -1,7 +1,7 @@ // Copyright 2024 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 import ( "forgejo.org/modules/timeutil" diff --git a/models/migrations/v1_22/v290_test.go b/models/migrations/v1_22/v290_test.go index 569d77bc16..a1907cf4d6 100644 --- a/models/migrations/v1_22/v290_test.go +++ b/models/migrations/v1_22/v290_test.go @@ -1,7 +1,7 @@ // Copyright 2024 The Forgejo Authors c/o Codeberg e.V.. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 import ( "strconv" diff --git a/models/migrations/v1_22/v291.go b/models/migrations/v1_22/v291.go index 74726fae96..823a644a95 100644 --- a/models/migrations/v1_22/v291.go +++ b/models/migrations/v1_22/v291.go @@ -1,7 +1,7 @@ // Copyright 2024 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 import "xorm.io/xorm" diff --git a/models/migrations/v1_22/v292.go b/models/migrations/v1_22/v292.go index beca556aee..440f48ce80 100644 --- a/models/migrations/v1_22/v292.go +++ b/models/migrations/v1_22/v292.go @@ -1,7 +1,7 @@ // Copyright 2024 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 // NOTE: noop the original migration has bug which some projects will be skip, so // these projects will have no default board. diff --git a/models/migrations/v1_22/v293.go b/models/migrations/v1_22/v293.go index 9f38c3db56..e9c9746b26 100644 --- a/models/migrations/v1_22/v293.go +++ b/models/migrations/v1_22/v293.go @@ -1,7 +1,7 @@ // Copyright 2024 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 import ( "forgejo.org/modules/setting" diff --git a/models/migrations/v1_22/v293_test.go b/models/migrations/v1_22/v293_test.go index 444146737d..6b1931b761 100644 --- a/models/migrations/v1_22/v293_test.go +++ b/models/migrations/v1_22/v293_test.go @@ -1,7 +1,7 @@ // Copyright 2024 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 import ( "testing" diff --git a/models/migrations/v1_22/v294.go b/models/migrations/v1_22/v294.go index 314b4519f1..6c52372306 100644 --- a/models/migrations/v1_22/v294.go +++ b/models/migrations/v1_22/v294.go @@ -1,7 +1,7 @@ // Copyright 2024 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_22/v294_test.go b/models/migrations/v1_22/v294_test.go index ef7b67ca5b..e87a4bc85f 100644 --- a/models/migrations/v1_22/v294_test.go +++ b/models/migrations/v1_22/v294_test.go @@ -1,7 +1,7 @@ // Copyright 2024 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 import ( "slices" @@ -45,7 +45,8 @@ func Test_AddUniqueIndexForProjectIssue(t *testing.T) { for _, index := range tables[0].Indexes { if index.Type == schemas.UniqueType { found = true - slices.Equal(index.Cols, []string{"project_id", "issue_id"}) + slices.Sort(index.Cols) + assert.Equal(t, []string{"issue_id", "project_id"}, index.Cols) break } } diff --git a/models/migrations/v1_22/v295.go b/models/migrations/v1_22/v295.go index 17bdadb4ad..319b1a399b 100644 --- a/models/migrations/v1_22/v295.go +++ b/models/migrations/v1_22/v295.go @@ -1,7 +1,7 @@ // Copyright 2024 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 import "xorm.io/xorm" diff --git a/models/migrations/v1_22/v296.go b/models/migrations/v1_22/v296.go index 1ecacab95f..75350f9f65 100644 --- a/models/migrations/v1_22/v296.go +++ b/models/migrations/v1_22/v296.go @@ -1,7 +1,7 @@ // Copyright 2024 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 import "xorm.io/xorm" diff --git a/models/migrations/v1_22/v298.go b/models/migrations/v1_22/v298.go index b9f3b95ade..7700173a00 100644 --- a/models/migrations/v1_22/v298.go +++ b/models/migrations/v1_22/v298.go @@ -1,7 +1,7 @@ // Copyright 2024 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_22 //nolint +package v1_22 import "xorm.io/xorm" diff --git a/models/migrations/v1_23/main_test.go b/models/migrations/v1_23/main_test.go index 0fd90a4a67..5fb4fec999 100644 --- a/models/migrations/v1_23/main_test.go +++ b/models/migrations/v1_23/main_test.go @@ -1,7 +1,7 @@ // Copyright 2024 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_23 //nolint +package v1_23 import ( "testing" diff --git a/models/migrations/v1_23/v299.go b/models/migrations/v1_23/v299.go index f6db960c3b..73ce19c875 100644 --- a/models/migrations/v1_23/v299.go +++ b/models/migrations/v1_23/v299.go @@ -1,7 +1,7 @@ // Copyright 2024 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_23 //nolint +package v1_23 import "xorm.io/xorm" diff --git a/models/migrations/v1_23/v300.go b/models/migrations/v1_23/v300.go index f1f1cccdbf..404d8dbea8 100644 --- a/models/migrations/v1_23/v300.go +++ b/models/migrations/v1_23/v300.go @@ -1,7 +1,7 @@ // Copyright 2024 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_23 //nolint +package v1_23 import "xorm.io/xorm" diff --git a/models/migrations/v1_23/v301.go b/models/migrations/v1_23/v301.go index b7797f6c6b..f2a4d8c559 100644 --- a/models/migrations/v1_23/v301.go +++ b/models/migrations/v1_23/v301.go @@ -1,7 +1,7 @@ // Copyright 2024 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_23 //nolint +package v1_23 import "xorm.io/xorm" diff --git a/models/migrations/v1_23/v302.go b/models/migrations/v1_23/v302.go index c8ed786d63..1b056993bd 100644 --- a/models/migrations/v1_23/v302.go +++ b/models/migrations/v1_23/v302.go @@ -1,7 +1,7 @@ // Copyright 2024 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_23 //nolint +package v1_23 import ( "forgejo.org/modules/timeutil" diff --git a/models/migrations/v1_23/v303.go b/models/migrations/v1_23/v303.go index fae0131bdd..03197d2857 100644 --- a/models/migrations/v1_23/v303.go +++ b/models/migrations/v1_23/v303.go @@ -1,7 +1,7 @@ // Copyright 2025 The Forgejo Authors. // SPDX-License-Identifier: GPL-3.0-or-later -package v1_23 //nolint +package v1_23 import ( "forgejo.org/models/migrations/base" diff --git a/models/migrations/v1_23/v303_test.go b/models/migrations/v1_23/v303_test.go index f105d11830..f2c764bae3 100644 --- a/models/migrations/v1_23/v303_test.go +++ b/models/migrations/v1_23/v303_test.go @@ -1,7 +1,7 @@ // Copyright 2025 The Forgejo Authors. // SPDX-License-Identifier: GPL-3.0-or-later -package v1_23 //nolint +package v1_23 import ( "testing" diff --git a/models/migrations/v1_6/v70.go b/models/migrations/v1_6/v70.go index ec6bd09bb5..eb669f57b6 100644 --- a/models/migrations/v1_6/v70.go +++ b/models/migrations/v1_6/v70.go @@ -1,7 +1,7 @@ // Copyright 2018 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_6 //nolint +package v1_6 import ( "fmt" diff --git a/models/migrations/v1_6/v71.go b/models/migrations/v1_6/v71.go index 3706ad4406..42fe8cd1ba 100644 --- a/models/migrations/v1_6/v71.go +++ b/models/migrations/v1_6/v71.go @@ -1,7 +1,7 @@ // Copyright 2018 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_6 //nolint +package v1_6 import ( "fmt" diff --git a/models/migrations/v1_6/v72.go b/models/migrations/v1_6/v72.go index 4df2a0f6e9..7cd2331376 100644 --- a/models/migrations/v1_6/v72.go +++ b/models/migrations/v1_6/v72.go @@ -1,7 +1,7 @@ // Copyright 2018 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_6 //nolint +package v1_6 import ( "fmt" diff --git a/models/migrations/v1_7/v73.go b/models/migrations/v1_7/v73.go index b5a748aae3..e0b7a28537 100644 --- a/models/migrations/v1_7/v73.go +++ b/models/migrations/v1_7/v73.go @@ -1,7 +1,7 @@ // Copyright 2018 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_7 //nolint +package v1_7 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_7/v74.go b/models/migrations/v1_7/v74.go index f0567e3c9b..376be37a24 100644 --- a/models/migrations/v1_7/v74.go +++ b/models/migrations/v1_7/v74.go @@ -1,7 +1,7 @@ // Copyright 2018 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_7 //nolint +package v1_7 import "xorm.io/xorm" diff --git a/models/migrations/v1_7/v75.go b/models/migrations/v1_7/v75.go index fa7430970c..ef11575466 100644 --- a/models/migrations/v1_7/v75.go +++ b/models/migrations/v1_7/v75.go @@ -1,7 +1,7 @@ // Copyright 2018 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_7 //nolint +package v1_7 import ( "xorm.io/builder" diff --git a/models/migrations/v1_8/v76.go b/models/migrations/v1_8/v76.go index 61ad006a47..8d47280b41 100644 --- a/models/migrations/v1_8/v76.go +++ b/models/migrations/v1_8/v76.go @@ -1,7 +1,7 @@ // Copyright 2018 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_8 //nolint +package v1_8 import ( "fmt" diff --git a/models/migrations/v1_8/v77.go b/models/migrations/v1_8/v77.go index 8b19993924..4fe5ebe635 100644 --- a/models/migrations/v1_8/v77.go +++ b/models/migrations/v1_8/v77.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_8 //nolint +package v1_8 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_8/v78.go b/models/migrations/v1_8/v78.go index 8102b19335..840fc20d96 100644 --- a/models/migrations/v1_8/v78.go +++ b/models/migrations/v1_8/v78.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_8 //nolint +package v1_8 import ( "forgejo.org/models/migrations/base" diff --git a/models/migrations/v1_8/v79.go b/models/migrations/v1_8/v79.go index f7d2d68f96..c8e0db531f 100644 --- a/models/migrations/v1_8/v79.go +++ b/models/migrations/v1_8/v79.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_8 //nolint +package v1_8 import ( "forgejo.org/modules/setting" diff --git a/models/migrations/v1_8/v80.go b/models/migrations/v1_8/v80.go index cebbbead28..6f9df47a93 100644 --- a/models/migrations/v1_8/v80.go +++ b/models/migrations/v1_8/v80.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_8 //nolint +package v1_8 import "xorm.io/xorm" diff --git a/models/migrations/v1_8/v81.go b/models/migrations/v1_8/v81.go index 734fc24641..8152a47ad7 100644 --- a/models/migrations/v1_8/v81.go +++ b/models/migrations/v1_8/v81.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_8 //nolint +package v1_8 import ( "fmt" diff --git a/models/migrations/v1_9/v82.go b/models/migrations/v1_9/v82.go index 78a90bdde9..235c73c504 100644 --- a/models/migrations/v1_9/v82.go +++ b/models/migrations/v1_9/v82.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_9 //nolint +package v1_9 import ( "fmt" diff --git a/models/migrations/v1_9/v83.go b/models/migrations/v1_9/v83.go index fa24a92d28..9640564a44 100644 --- a/models/migrations/v1_9/v83.go +++ b/models/migrations/v1_9/v83.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_9 //nolint +package v1_9 import ( "forgejo.org/modules/timeutil" diff --git a/models/migrations/v1_9/v84.go b/models/migrations/v1_9/v84.go index c7155fe9cf..423915ae57 100644 --- a/models/migrations/v1_9/v84.go +++ b/models/migrations/v1_9/v84.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_9 //nolint +package v1_9 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_9/v85.go b/models/migrations/v1_9/v85.go index d8e9d91840..9d5adc82dd 100644 --- a/models/migrations/v1_9/v85.go +++ b/models/migrations/v1_9/v85.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_9 //nolint +package v1_9 import ( "fmt" diff --git a/models/migrations/v1_9/v86.go b/models/migrations/v1_9/v86.go index cf2725d158..9464ff0cf6 100644 --- a/models/migrations/v1_9/v86.go +++ b/models/migrations/v1_9/v86.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_9 //nolint +package v1_9 import ( "xorm.io/xorm" diff --git a/models/migrations/v1_9/v87.go b/models/migrations/v1_9/v87.go index fa01b6e5e3..81a4ebf80d 100644 --- a/models/migrations/v1_9/v87.go +++ b/models/migrations/v1_9/v87.go @@ -1,7 +1,7 @@ // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package v1_9 //nolint +package v1_9 import ( "xorm.io/xorm" diff --git a/models/packages/package.go b/models/packages/package.go index bdd1c74cad..c06dcf5eb3 100644 --- a/models/packages/package.go +++ b/models/packages/package.go @@ -125,7 +125,7 @@ func (pt Type) Name() string { case TypeRpm: return "RPM" case TypeAlt: - return "Alt" + return "ALT" case TypeRubyGems: return "RubyGems" case TypeSwift: diff --git a/models/repo/repo_unit.go b/models/repo/repo_unit.go index c11ad70627..e50f79e945 100644 --- a/models/repo/repo_unit.go +++ b/models/repo/repo_unit.go @@ -41,27 +41,30 @@ func (err ErrUnitTypeNotExist) Unwrap() error { } // RepoUnitAccessMode specifies the users access mode to a repo unit +// Only UnitAccessModeWrite is used by the wiki, to mark it as instance-writable type UnitAccessMode int const ( // UnitAccessModeUnset - no unit mode set UnitAccessModeUnset UnitAccessMode = iota // 0 + // UnitAccessModeNone no access - UnitAccessModeNone // 1 + // UnitAccessModeNone UnitAccessMode = 1 // UnitAccessModeRead read access - UnitAccessModeRead // 2 + // UnitAccessModeRead UnitAccessMode = 2 + // UnitAccessModeWrite write access - UnitAccessModeWrite // 3 + UnitAccessModeWrite UnitAccessMode = 3 ) func (mode UnitAccessMode) ToAccessMode(modeIfUnset perm.AccessMode) perm.AccessMode { switch mode { case UnitAccessModeUnset: return modeIfUnset - case UnitAccessModeNone: - return perm.AccessModeNone - case UnitAccessModeRead: - return perm.AccessModeRead + // case UnitAccessModeNone: + // return perm.AccessModeNone + // case UnitAccessModeRead: + // return perm.AccessModeRead case UnitAccessModeWrite: return perm.AccessModeWrite default: diff --git a/models/repo/repo_unit_test.go b/models/repo/repo_unit_test.go index a1964519bd..3d6d408fcb 100644 --- a/models/repo/repo_unit_test.go +++ b/models/repo/repo_unit_test.go @@ -34,8 +34,8 @@ func TestActionsConfig(t *testing.T) { } func TestRepoUnitAccessMode(t *testing.T) { - assert.Equal(t, perm.AccessModeNone, UnitAccessModeNone.ToAccessMode(perm.AccessModeAdmin)) - assert.Equal(t, perm.AccessModeRead, UnitAccessModeRead.ToAccessMode(perm.AccessModeAdmin)) + // 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)) } diff --git a/models/unittest/fixture_loader.go b/models/unittest/fixture_loader.go index 67ef1b28df..dda5c48d35 100644 --- a/models/unittest/fixture_loader.go +++ b/models/unittest/fixture_loader.go @@ -12,6 +12,8 @@ import ( "path/filepath" "strings" + "forgejo.org/modules/container" + "gopkg.in/yaml.v3" ) @@ -32,13 +34,15 @@ type loader struct { fixtureFiles []*fixtureFile } -func newFixtureLoader(db *sql.DB, dialect string, fixturePaths []string) (*loader, error) { +func newFixtureLoader(db *sql.DB, dialect string, fixturePaths []string, allTableNames container.Set[string]) (*loader, error) { l := &loader{ db: db, dialect: dialect, fixtureFiles: []*fixtureFile{}, } + tablesWithoutFixture := allTableNames + // Load fixtures for _, fixturePath := range fixturePaths { stat, err := os.Stat(fixturePath) @@ -60,6 +64,7 @@ func newFixtureLoader(db *sql.DB, dialect string, fixturePaths []string) (*loade return nil, err } l.fixtureFiles = append(l.fixtureFiles, fixtureFile) + tablesWithoutFixture.Remove(fixtureFile.name) } } } else { @@ -71,6 +76,14 @@ func newFixtureLoader(db *sql.DB, dialect string, fixturePaths []string) (*loade } } + // Even though these tables have no fixtures, they can still be used and ensure + // they are cleaned. + for table := range tablesWithoutFixture.Seq() { + l.fixtureFiles = append(l.fixtureFiles, &fixtureFile{ + name: table, + }) + } + return l, nil } @@ -178,13 +191,13 @@ func (l *loader) Load() error { }() // Clean the table and re-insert the fixtures. - tableDeleted := map[string]struct{}{} + tableDeleted := make(container.Set[string]) for _, fixture := range l.fixtureFiles { - if _, ok := tableDeleted[fixture.name]; !ok { + if !tableDeleted.Contains(fixture.name) { 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{}{} + tableDeleted.Add(fixture.name) } for _, insertSQL := range fixture.insertSQLs { diff --git a/models/unittest/fixtures.go b/models/unittest/fixtures.go index 6dc5c8412d..829cc16466 100644 --- a/models/unittest/fixtures.go +++ b/models/unittest/fixtures.go @@ -7,10 +7,12 @@ package unittest import ( "fmt" "path/filepath" + "sync" "time" "forgejo.org/models/db" "forgejo.org/modules/auth/password/hash" + "forgejo.org/modules/container" "forgejo.org/modules/setting" "xorm.io/xorm" @@ -44,6 +46,8 @@ func OverrideFixtures(dir string) func() { } } +var allTableNames = sync.OnceValue(db.GetTableNames) + // InitFixtures initialize test fixtures for a test database func InitFixtures(opts FixturesOptions, engine ...*xorm.Engine) (err error) { e, err := GetXORMEngine(engine...) @@ -75,7 +79,12 @@ func InitFixtures(opts FixturesOptions, engine ...*xorm.Engine) (err error) { panic("Unsupported RDBMS for test") } - fixturesLoader, err = newFixtureLoader(e.DB().DB, dialect, fixturePaths) + var allTables container.Set[string] + if !opts.SkipCleanRegistedModels { + allTables = allTableNames().Clone() + } + + fixturesLoader, err = newFixtureLoader(e.DB().DB, dialect, fixturePaths, allTables) if err != nil { return err } diff --git a/models/unittest/testdb.go b/models/unittest/testdb.go index d34c9e9a0a..29ec82c55f 100644 --- a/models/unittest/testdb.go +++ b/models/unittest/testdb.go @@ -217,6 +217,10 @@ type FixturesOptions struct { Files []string Dirs []string Base string + // By default all registered models are cleaned, even if they do not have + // fixture. Enabling this will skip that and only models with fixtures are + // considered. + SkipCleanRegistedModels bool } // CreateTestEngine creates a memory database and loads the fixture data from fixturesDir diff --git a/models/user/activitypub.go b/models/user/activitypub.go index 816fd8a098..aabf2336fc 100644 --- a/models/user/activitypub.go +++ b/models/user/activitypub.go @@ -19,7 +19,7 @@ func (u *User) APActorID() string { return fmt.Sprintf("%sapi/v1/activitypub/user-id/%s", setting.AppURL, url.PathEscape(fmt.Sprintf("%d", u.ID))) } -// APActorKeyID returns the ID of the user's public key -func (u *User) APActorKeyID() string { +// KeyID returns the ID of the user's public key +func (u *User) KeyID() string { return u.APActorID() + "#main-key" } diff --git a/models/user/email_address_test.go b/models/user/email_address_test.go index 1801f57a23..85f5b16c65 100644 --- a/models/user/email_address_test.go +++ b/models/user/email_address_test.go @@ -181,3 +181,20 @@ func TestDeletePrimaryEmailAddressOfUser(t *testing.T) { assert.True(t, user_model.IsErrEmailAddressNotExist(err)) assert.Nil(t, email) } + +func TestActivateUserEmail(t *testing.T) { + defer unittest.OverrideFixtures("models/fixtures/TestActivateUserEmail")() + require.NoError(t, unittest.PrepareTestDatabase()) + + t.Run("Activate email", func(t *testing.T) { + require.NoError(t, user_model.ActivateUserEmail(t.Context(), 1001, "AnotherTestUserWithUpperCaseEmail@otto.splvs.net", true)) + + unittest.AssertExistsAndLoadBean(t, &user_model.EmailAddress{UID: 1001}, "is_activated = true") + }) + + t.Run("Deactivate email", func(t *testing.T) { + require.NoError(t, user_model.ActivateUserEmail(t.Context(), 1001, "AnotherTestUserWithUpperCaseEmail@otto.splvs.net", false)) + + unittest.AssertExistsAndLoadBean(t, &user_model.EmailAddress{UID: 1001}, "is_activated = false") + }) +} diff --git a/models/user/user.go b/models/user/user.go index eedd1db80e..b124572bb6 100644 --- a/models/user/user.go +++ b/models/user/user.go @@ -182,11 +182,11 @@ func (u *User) BeforeUpdate() { u.MaxRepoCreation = -1 } - // Organization does not need email - u.Email = strings.ToLower(u.Email) + // Ensure AvatarEmail is set for non-organization users, because organization + // are not required to have a email set. if !u.IsOrganization() { if len(u.AvatarEmail) == 0 { - u.AvatarEmail = u.Email + u.AvatarEmail = strings.ToLower(u.Email) } } diff --git a/models/user/user_repository.go b/models/user/user_repository.go index 3f24efb1fb..85f44f1598 100644 --- a/models/user/user_repository.go +++ b/models/user/user_repository.go @@ -57,14 +57,6 @@ func CreateFederatedUser(ctx context.Context, user *User, federatedUser *Federat return committer.Commit() } -func (federatedUser *FederatedUser) UpdateFederatedUser(ctx context.Context) error { - if _, err := validation.IsValid(federatedUser); err != nil { - return err - } - _, err := db.GetEngine(ctx).ID(federatedUser.ID).Cols("inbox_path").Update(federatedUser) - return err -} - func FindFederatedUser(ctx context.Context, externalID string, federationHostID int64) (*User, *FederatedUser, error) { federatedUser := new(FederatedUser) user := new(User) @@ -219,7 +211,6 @@ func RemoveFollower(ctx context.Context, followedUser *User, followingUser *Fede return err } -// TODO: We should unify Activity-pub-following and classical following (see models/user/follow.go) func IsFollowingAp(ctx context.Context, followedUser *User, followingUser *FederatedUser) (bool, error) { if res, err := validation.IsValid(followedUser); !res { return false, err diff --git a/models/user/user_test.go b/models/user/user_test.go index fd9d05653f..f9a3aa6075 100644 --- a/models/user/user_test.go +++ b/models/user/user_test.go @@ -150,7 +150,7 @@ func TestAPActorID_APActorID(t *testing.T) { func TestKeyID(t *testing.T) { user := user_model.User{ID: 1} - url := user.APActorKeyID() + url := user.KeyID() expected := "https://try.gitea.io/api/v1/activitypub/user-id/1#main-key" assert.Equal(t, expected, url) } diff --git a/modules/activitypub/client.go b/modules/activitypub/client.go index d015fb7bec..fb6fa8b543 100644 --- a/modules/activitypub/client.go +++ b/modules/activitypub/client.go @@ -89,6 +89,7 @@ func NewClientFactory() (c *ClientFactory, err error) { type APClientFactory interface { WithKeys(ctx context.Context, user *user_model.User, pubID string) (APClient, error) + WithKeysDirect(ctx context.Context, privateKey, pubID string) (APClient, error) } // Client struct @@ -103,12 +104,8 @@ type Client struct { } // 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 - } - privPem, _ := pem.Decode([]byte(priv)) +func (cf *ClientFactory) WithKeysDirect(ctx context.Context, privateKey, pubID string) (APClient, error) { + privPem, _ := pem.Decode([]byte(privateKey)) privParsed, err := x509.ParsePKCS1PrivateKey(privPem.Bytes) if err != nil { return nil, err @@ -126,6 +123,14 @@ func (cf *ClientFactory) WithKeys(ctx context.Context, user *user_model.User, pu return &c, nil } +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 + } + return cf.WithKeysDirect(ctx, priv, pubID) +} + // NewRequest function func (c *Client) newRequest(method string, b []byte, to string) (req *http.Request, err error) { buf := bytes.NewBuffer(b) @@ -149,12 +154,14 @@ func (c *Client) Post(b []byte, to string) (resp *http.Response, err error) { 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 + if c.pubID != "" { + 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) @@ -167,12 +174,15 @@ func (c *Client) Get(to string) (resp *http.Response, err error) { 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 + + if c.pubID != "" { + 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) diff --git a/modules/container/set.go b/modules/container/set.go index 70f837bc66..d3719dc552 100644 --- a/modules/container/set.go +++ b/modules/container/set.go @@ -74,3 +74,8 @@ func (s Set[T]) Values() []T { func (s Set[T]) Seq() iter.Seq[T] { return maps.Keys(s) } + +// Clone returns a identical shallow copy of this set. +func (s Set[T]) Clone() Set[T] { + return maps.Clone(s) +} diff --git a/modules/container/set_test.go b/modules/container/set_test.go index af5e9126ab..44e4847f6b 100644 --- a/modules/container/set_test.go +++ b/modules/container/set_test.go @@ -47,4 +47,11 @@ func TestSet(t *testing.T) { assert.False(t, s.IsSubset([]string{"key1"})) assert.True(t, s.IsSubset([]string{})) + + t.Run("Clone", func(t *testing.T) { + clonedSet := s.Clone() + clonedSet.Remove("key6") + assert.False(t, clonedSet.Contains("key6")) + assert.True(t, s.Contains("key6")) + }) } diff --git a/modules/git/blob.go b/modules/git/blob.go index 14ca2b1445..4eef5f0e2a 100644 --- a/modules/git/blob.go +++ b/modules/git/blob.go @@ -220,7 +220,7 @@ func (b *Blob) GuessContentType() (typesniffer.SniffedType, error) { } defer r.Close() - return typesniffer.DetectContentTypeFromReader(r) + return typesniffer.DetectContentTypeFromReader(r, b.Name()) } // GetBlob finds the blob object in the repository. diff --git a/modules/git/pushoptions/pushoptions.go b/modules/git/pushoptions/pushoptions.go index 9709a8be79..e96ba0a339 100644 --- a/modules/git/pushoptions/pushoptions.go +++ b/modules/git/pushoptions/pushoptions.go @@ -4,6 +4,7 @@ package pushoptions import ( + "encoding/base64" "fmt" "os" "strconv" @@ -109,5 +110,22 @@ func (o gitPushOptions) GetBool(key Key, def bool) bool { func (o gitPushOptions) GetString(key Key) (string, bool) { val, ok := o[string(key)] - return val, ok + if !ok { + return "", false + } + + // If the value is prefixed with `{base64}` then everything after that is very + // likely to be encoded via base64. + base64Value, found := strings.CutPrefix(val, "{base64}") + if !found { + return val, true + } + + value, err := base64.StdEncoding.DecodeString(base64Value) + if err != nil { + // Not valid base64? Return the original value. + return val, true + } + + return string(value), true } diff --git a/modules/git/pushoptions/pushoptions_test.go b/modules/git/pushoptions/pushoptions_test.go index 1cb36d9d1e..d7c50649d0 100644 --- a/modules/git/pushoptions/pushoptions_test.go +++ b/modules/git/pushoptions/pushoptions_test.go @@ -4,6 +4,7 @@ package pushoptions import ( + "encoding/base64" "fmt" "testing" @@ -92,6 +93,23 @@ func TestParse(t *testing.T) { assert.False(t, options.Parse("unknown=value")) assert.True(t, options.Empty()) }) + + t.Run("Base64 values", func(t *testing.T) { + options := New() + + description := `I contain +a +line` + assert.True(t, options.Parse(fmt.Sprintf("%s={base64}%s", AgitDescription, base64.StdEncoding.EncodeToString([]byte(description))))) + val, ok := options.GetString(AgitDescription) + assert.True(t, ok) + assert.Equal(t, description, val) + + assert.True(t, options.Parse(fmt.Sprintf("%s={base64}fooled you", AgitTitle))) + val, ok = options.GetString(AgitTitle) + assert.True(t, ok) + assert.Equal(t, "{base64}fooled you", val) + }) } func TestReadEnv(t *testing.T) { diff --git a/modules/git/repo_blame.go b/modules/git/repo_blame.go index 139cdd7be9..d812354af5 100644 --- a/modules/git/repo_blame.go +++ b/modules/git/repo_blame.go @@ -4,20 +4,46 @@ package git import ( + "errors" "fmt" + "regexp" +) + +var ( + ErrBlameFileDoesNotExist = errors.New("the blamed file does not exist") + ErrBlameFileNotEnoughLines = errors.New("the blamed file has not enough lines") + + notEnoughLinesRe = regexp.MustCompile(`^fatal: file .+ has only \d+ lines?\n$`) ) // LineBlame returns the latest commit at the given line -func (repo *Repository) LineBlame(revision, path, file string, line uint) (*Commit, error) { - res, _, err := NewCommand(repo.Ctx, "blame"). +func (repo *Repository) LineBlame(revision, file string, line uint64) (*Commit, error) { + res, _, gitErr := NewCommand(repo.Ctx, "blame"). AddOptionFormat("-L %d,%d", line, line). AddOptionValues("-p", revision). - AddDashesAndList(file).RunStdString(&RunOpts{Dir: path}) + AddDashesAndList(file).RunStdString(&RunOpts{Dir: repo.Path}) + if gitErr != nil { + stdErr := gitErr.Stderr() + + if stdErr == fmt.Sprintf("fatal: no such path %s in %s\n", file, revision) { + return nil, ErrBlameFileDoesNotExist + } + if notEnoughLinesRe.MatchString(stdErr) { + return nil, ErrBlameFileNotEnoughLines + } + + return nil, gitErr + } + + objectFormat, err := repo.GetObjectFormat() if err != nil { return nil, err } - if len(res) < 40 { - return nil, fmt.Errorf("invalid result of blame: %s", res) + + objectIDLen := objectFormat.FullLength() + if len(res) < objectIDLen { + return nil, fmt.Errorf("output of blame is invalid, cannot contain commit ID: %s", res) } - return repo.GetCommit(res[:40]) + + return repo.GetCommit(res[:objectIDLen]) } diff --git a/modules/git/repo_blame_test.go b/modules/git/repo_blame_test.go new file mode 100644 index 0000000000..126b95386d --- /dev/null +++ b/modules/git/repo_blame_test.go @@ -0,0 +1,52 @@ +// Copyright 2025 The Forgejo Authors. All rights reserved. +// SPDX-License-Identifier: GPL-3.0-or-later + +package git + +import ( + "path/filepath" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestLineBlame(t *testing.T) { + t.Run("SHA1", func(t *testing.T) { + repo, err := OpenRepository(t.Context(), filepath.Join(testReposDir, "repo1_bare")) + require.NoError(t, err) + defer repo.Close() + + commit, err := repo.LineBlame("HEAD", "foo/link_short", 1) + require.NoError(t, err) + assert.Equal(t, "37991dec2c8e592043f47155ce4808d4580f9123", commit.ID.String()) + + commit, err = repo.LineBlame("HEAD", "foo/link_short", 512) + require.ErrorIs(t, err, ErrBlameFileNotEnoughLines) + assert.Nil(t, commit) + + commit, err = repo.LineBlame("HEAD", "non-existent/path", 512) + require.ErrorIs(t, err, ErrBlameFileDoesNotExist) + assert.Nil(t, commit) + }) + + t.Run("SHA256", func(t *testing.T) { + skipIfSHA256NotSupported(t) + + repo, err := OpenRepository(t.Context(), filepath.Join(testReposDir, "repo1_bare_sha256")) + require.NoError(t, err) + defer repo.Close() + + commit, err := repo.LineBlame("HEAD", "foo/link_short", 1) + require.NoError(t, err) + assert.Equal(t, "6aae864a3d1d0d6a5be0cc64028c1e7021e2632b031fd8eb82afc5a283d1c3d1", commit.ID.String()) + + commit, err = repo.LineBlame("HEAD", "foo/link_short", 512) + require.ErrorIs(t, err, ErrBlameFileNotEnoughLines) + assert.Nil(t, commit) + + commit, err = repo.LineBlame("HEAD", "non-existent/path", 512) + require.ErrorIs(t, err, ErrBlameFileDoesNotExist) + assert.Nil(t, commit) + }) +} diff --git a/modules/git/repo_branch.go b/modules/git/repo_branch.go index 3a9aa3e4e6..1e38bf2946 100644 --- a/modules/git/repo_branch.go +++ b/modules/git/repo_branch.go @@ -19,15 +19,9 @@ import ( // BranchPrefix base dir of the branch information file store on git const BranchPrefix = "refs/heads/" -// IsReferenceExist returns true if given reference exists in the repository. -func IsReferenceExist(ctx context.Context, repoPath, name string) bool { - _, _, err := NewCommand(ctx, "show-ref", "--verify").AddDashesAndList(name).RunStdString(&RunOpts{Dir: repoPath}) - return err == nil -} - // IsBranchExist returns true if given branch exists in the repository. func IsBranchExist(ctx context.Context, repoPath, name string) bool { - return IsReferenceExist(ctx, repoPath, BranchPrefix+name) + return NewCommand(ctx, "show-ref", "--verify", "--quiet").AddDashesAndList(BranchPrefix+name).Run(&RunOpts{Dir: repoPath}) == nil } // Branch represents a Git branch. diff --git a/modules/git/repo_branch_test.go b/modules/git/repo_branch_test.go index 1e0fea7cd4..e61ea6f5d7 100644 --- a/modules/git/repo_branch_test.go +++ b/modules/git/repo_branch_test.go @@ -1,4 +1,5 @@ // Copyright 2018 The Gitea Authors. All rights reserved. +// Copyright 2025 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT package git @@ -195,3 +196,17 @@ func TestRepository_IsReferenceExist(t *testing.T) { }) } } + +func TestIsBranchExist(t *testing.T) { + repo1Path := filepath.Join(testReposDir, "repo1_bare") + + assert.True(t, IsBranchExist(t.Context(), repo1Path, "branch1")) + assert.True(t, IsBranchExist(t.Context(), repo1Path, "branch2")) + assert.True(t, IsBranchExist(t.Context(), repo1Path, "master")) + + assert.False(t, IsBranchExist(t.Context(), repo1Path, "HEAD")) + assert.False(t, IsBranchExist(t.Context(), repo1Path, "153f451b9ee7fa1da317ab17a127e9fd9d384310")) + assert.False(t, IsBranchExist(t.Context(), repo1Path, "153f451b9ee7fa1da317ab17a127e9fd9d384310")) + assert.False(t, IsBranchExist(t.Context(), repo1Path, "signed-tag")) + assert.False(t, IsBranchExist(t.Context(), repo1Path, "test")) +} diff --git a/modules/httplib/serve.go b/modules/httplib/serve.go index c5f0658d4e..d385ac21c9 100644 --- a/modules/httplib/serve.go +++ b/modules/httplib/serve.go @@ -99,7 +99,7 @@ func setServeHeadersByFile(r *http.Request, w http.ResponseWriter, filePath stri Filename: path.Base(filePath), } - sniffedType := typesniffer.DetectContentType(mineBuf) + sniffedType := typesniffer.DetectContentType(mineBuf, opts.Filename) // the "render" parameter came from year 2016: 638dd24c, it doesn't have clear meaning, so I think it could be removed later isPlain := sniffedType.IsText() || r.FormValue("render") != "" diff --git a/modules/indexer/code/bleve/bleve.go b/modules/indexer/code/bleve/bleve.go index c53b7a2e6d..4c8b5f2a86 100644 --- a/modules/indexer/code/bleve/bleve.go +++ b/modules/indexer/code/bleve/bleve.go @@ -177,7 +177,7 @@ func (b *Indexer) addUpdate(ctx context.Context, batchWriter git.WriteCloserErro fileContents, err := io.ReadAll(io.LimitReader(batchReader, size)) if err != nil { return err - } else if !typesniffer.DetectContentType(fileContents).IsText() { + } else if !typesniffer.DetectContentType(fileContents, update.Filename).IsText() { // FIXME: UTF-16 files will probably fail here // Even if the file is not recognized as a "text file", we could still put its name into the indexers to make the filename become searchable, while leave the content to empty. fileContents = nil diff --git a/modules/indexer/code/elasticsearch/elasticsearch.go b/modules/indexer/code/elasticsearch/elasticsearch.go index 3903d77fe0..9b11f56fb7 100644 --- a/modules/indexer/code/elasticsearch/elasticsearch.go +++ b/modules/indexer/code/elasticsearch/elasticsearch.go @@ -144,7 +144,7 @@ func (b *Indexer) addUpdate(ctx context.Context, batchWriter git.WriteCloserErro fileContents, err := io.ReadAll(io.LimitReader(batchReader, size)) if err != nil { return nil, err - } else if !typesniffer.DetectContentType(fileContents).IsText() { + } else if !typesniffer.DetectContentType(fileContents, update.Filename).IsText() { // FIXME: UTF-16 files will probably fail here return nil, nil } diff --git a/modules/indexer/issues/bleve/bleve.go b/modules/indexer/issues/bleve/bleve.go index 8549ba8dfc..cb98f722c5 100644 --- a/modules/indexer/issues/bleve/bleve.go +++ b/modules/indexer/issues/bleve/bleve.go @@ -156,11 +156,12 @@ func (b *Indexer) Delete(_ context.Context, ids ...int64) error { func (b *Indexer) Search(ctx context.Context, options *internal.SearchOptions) (*internal.SearchResult, error) { var queries []query.Query - if options.Keyword != "" { - tokens, err := options.Tokens() - if err != nil { - return nil, err - } + tokens, err := options.Tokens() + if err != nil { + return nil, err + } + + if len(tokens) > 0 { q := bleve.NewBooleanQuery() for _, token := range tokens { innerQ := bleve.NewDisjunctionQuery( diff --git a/modules/indexer/issues/elasticsearch/elasticsearch.go b/modules/indexer/issues/elasticsearch/elasticsearch.go index d632a22b2a..311e92730e 100644 --- a/modules/indexer/issues/elasticsearch/elasticsearch.go +++ b/modules/indexer/issues/elasticsearch/elasticsearch.go @@ -149,12 +149,13 @@ func (b *Indexer) Delete(ctx context.Context, ids ...int64) error { func (b *Indexer) Search(ctx context.Context, options *internal.SearchOptions) (*internal.SearchResult, error) { query := elastic.NewBoolQuery() - if options.Keyword != "" { + tokens, err := options.Tokens() + if err != nil { + return nil, err + } + + if len(tokens) > 0 { q := elastic.NewBoolQuery() - tokens, err := options.Tokens() - if err != nil { - return nil, err - } for _, token := range tokens { innerQ := elastic.NewMultiMatchQuery(token.Term, "content", "comments").FieldWithBoost("title", 2.0).TieBreaker(0.5) if token.Fuzzy { diff --git a/modules/indexer/issues/internal/qstring.go b/modules/indexer/issues/internal/qstring.go index 6b60b4c5f6..348f7a564b 100644 --- a/modules/indexer/issues/internal/qstring.go +++ b/modules/indexer/issues/internal/qstring.go @@ -45,12 +45,9 @@ func (t *Tokenizer) next() (tk Token, err error) { // 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 + if r, _, err = t.in.ReadRune(); err != nil || r != ' ' { + break } - break } if err != nil { return tk, err @@ -107,11 +104,17 @@ nextEnd: // Tokenize the keyword func (o *SearchOptions) Tokens() (tokens []Token, err error) { + if o.Keyword == "" { + return nil, nil + } + 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 token.Term != "" { + tokens = append(tokens, token) + } } if err != nil && err != io.EOF { return nil, err diff --git a/modules/indexer/issues/internal/qstring_test.go b/modules/indexer/issues/internal/qstring_test.go index 835491707c..eb4bdb306f 100644 --- a/modules/indexer/issues/internal/qstring_test.go +++ b/modules/indexer/issues/internal/qstring_test.go @@ -41,6 +41,36 @@ var testOpts = []testIssueQueryStringOpt{ }, }, }, + { + 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: BoolOptShould, + }, + { + Term: "World", + Fuzzy: true, + Kind: BoolOptShould, + }, + }, + }, { Keyword: "+Hello +World", Results: []Token{ @@ -156,6 +186,68 @@ var testOpts = []testIssueQueryStringOpt{ }, }, }, + { + Keyword: "\\", + Results: nil, + }, + { + Keyword: "\"", + Results: nil, + }, + { + Keyword: "Hello \\", + Results: []Token{ + { + Term: "Hello", + Fuzzy: true, + Kind: BoolOptShould, + }, + }, + }, + { + Keyword: "\"\"", + Results: nil, + }, + { + Keyword: "\" World \"", + Results: []Token{ + { + Term: " World ", + Fuzzy: false, + Kind: BoolOptShould, + }, + }, + }, + { + Keyword: "\"\" World \"\"", + Results: []Token{ + { + Term: "World", + Fuzzy: true, + Kind: BoolOptShould, + }, + }, + }, + { + Keyword: "Best \"Hello World\" Ever", + Results: []Token{ + { + Term: "Best", + Fuzzy: true, + Kind: BoolOptShould, + }, + { + Term: "Hello World", + Fuzzy: false, + Kind: BoolOptShould, + }, + { + Term: "Ever", + Fuzzy: true, + Kind: BoolOptShould, + }, + }, + }, } func TestIssueQueryString(t *testing.T) { diff --git a/modules/indexer/issues/internal/tests/tests.go b/modules/indexer/issues/internal/tests/tests.go index b63957ff84..46014994a0 100644 --- a/modules/indexer/issues/internal/tests/tests.go +++ b/modules/indexer/issues/internal/tests/tests.go @@ -87,14 +87,44 @@ func TestIndexer(t *testing.T, indexer internal.Indexer) { } } +func allResults(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { + assert.Len(t, result.Hits, len(data)) + assert.Equal(t, len(data), int(result.Total)) +} + var cases = []*testIndexerCase{ { Name: "default", SearchOptions: &internal.SearchOptions{}, - Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { - assert.Len(t, result.Hits, len(data)) - assert.Equal(t, len(data), int(result.Total)) + Expected: allResults, + }, + { + Name: "empty keyword", + SearchOptions: &internal.SearchOptions{ + Keyword: "", }, + Expected: allResults, + }, + { + Name: "whitespace keyword", + SearchOptions: &internal.SearchOptions{ + Keyword: " ", + }, + Expected: allResults, + }, + { + Name: "dangling slash in keyword", + SearchOptions: &internal.SearchOptions{ + Keyword: "\\", + }, + Expected: allResults, + }, + { + Name: "dangling quote in keyword", + SearchOptions: &internal.SearchOptions{ + Keyword: "\"", + }, + Expected: allResults, }, { Name: "empty", diff --git a/modules/log/event_writer.go b/modules/log/event_writer.go index 4b77e488de..32b5b582c5 100644 --- a/modules/log/event_writer.go +++ b/modules/log/event_writer.go @@ -26,6 +26,7 @@ type WriterMode struct { Flags Flags Expression string + Exclusion string StacktraceLevel Level diff --git a/modules/log/event_writer_base.go b/modules/log/event_writer_base.go index 9189ca4e90..4de2b953c7 100644 --- a/modules/log/event_writer_base.go +++ b/modules/log/event_writer_base.go @@ -68,6 +68,14 @@ func (b *EventWriterBaseImpl) Run(ctx context.Context) { } } + var exclusionRegexp *regexp.Regexp + if b.Mode.Exclusion != "" { + var err error + if exclusionRegexp, err = regexp.Compile(b.Mode.Exclusion); err != nil { + FallbackErrorf("unable to compile exclusion %q for writer %q: %v", b.Mode.Exclusion, b.Name, err) + } + } + handlePaused := func() { if pause := b.GetPauseChan(); pause != nil { select { @@ -95,6 +103,13 @@ func (b *EventWriterBaseImpl) Run(ctx context.Context) { continue } } + if exclusionRegexp != nil { + fileLineCaller := fmt.Sprintf("%s:%d:%s", event.Origin.Filename, event.Origin.Line, event.Origin.Caller) + matched := exclusionRegexp.MatchString(fileLineCaller) || exclusionRegexp.MatchString(event.Origin.MsgSimpleText) + if matched { + continue + } + } var err error switch msg := event.Msg.(type) { diff --git a/modules/log/event_writer_buffer_test.go b/modules/log/event_writer_buffer_test.go index ba9455ba69..d1e37c3673 100644 --- a/modules/log/event_writer_buffer_test.go +++ b/modules/log/event_writer_buffer_test.go @@ -31,3 +31,49 @@ func TestBufferLogger(t *testing.T) { logger.Close() assert.Contains(t, bufferWriter.Buffer.String(), expected) } + +func TestBufferLoggerWithExclusion(t *testing.T) { + prefix := "ExclusionPrefix " + level := log.INFO + message := "something" + + bufferWriter := log.NewEventWriterBuffer("test-buffer", log.WriterMode{ + Level: level, + Prefix: prefix, + Exclusion: message, + }) + + logger := log.NewLoggerWithWriters(t.Context(), "test", bufferWriter) + + logger.SendLogEvent(&log.Event{ + Level: log.INFO, + MsgSimpleText: message, + }) + logger.Close() + assert.NotContains(t, bufferWriter.Buffer.String(), message) +} + +func TestBufferLoggerWithExpressionAndExclusion(t *testing.T) { + prefix := "BothPrefix " + level := log.INFO + expression := ".*foo.*" + exclusion := ".*bar.*" + + bufferWriter := log.NewEventWriterBuffer("test-buffer", log.WriterMode{ + Level: level, + Prefix: prefix, + Expression: expression, + Exclusion: exclusion, + }) + + logger := log.NewLoggerWithWriters(t.Context(), "test", bufferWriter) + + logger.SendLogEvent(&log.Event{Level: log.INFO, MsgSimpleText: "foo expression"}) + logger.SendLogEvent(&log.Event{Level: log.INFO, MsgSimpleText: "bar exclusion"}) + logger.SendLogEvent(&log.Event{Level: log.INFO, MsgSimpleText: "foo bar both"}) + logger.SendLogEvent(&log.Event{Level: log.INFO, MsgSimpleText: "none"}) + logger.Close() + + assert.Contains(t, bufferWriter.Buffer.String(), "foo expression") + assert.NotContains(t, bufferWriter.Buffer.String(), "bar") +} diff --git a/modules/log/logger_test.go b/modules/log/logger_test.go index 6d6ceb69d7..99045b0f4f 100644 --- a/modules/log/logger_test.go +++ b/modules/log/logger_test.go @@ -143,3 +143,19 @@ func TestLoggerExpressionFilter(t *testing.T) { assert.Equal(t, []string{"foo\n", "foo bar\n", "by filename\n"}, w1.GetLogs()) } + +func TestLoggerExclusionFilter(t *testing.T) { + logger := NewLoggerWithWriters(t.Context(), "test") + + w1 := newDummyWriter("dummy-1", DEBUG, 0) + w1.Mode.Exclusion = "foo.*" + logger.AddWriters(w1) + + logger.Info("foo") + logger.Info("bar") + logger.Info("foo bar") + logger.SendLogEvent(&Event{Level: INFO, Filename: "foo.go", MsgSimpleText: "by filename"}) + logger.Close() + + assert.Equal(t, []string{"bar\n"}, w1.GetLogs()) +} diff --git a/modules/markup/markdown/goldmark.go b/modules/markup/markdown/goldmark.go index d229afa8e3..67d81488fd 100644 --- a/modules/markup/markdown/goldmark.go +++ b/modules/markup/markdown/goldmark.go @@ -9,6 +9,7 @@ import ( "strings" "forgejo.org/modules/markup" + markdownutil "forgejo.org/modules/markup/markdown/util" "forgejo.org/modules/setting" "github.com/yuin/goldmark/ast" @@ -35,8 +36,8 @@ func (g *ASTTransformer) applyElementDir(n ast.Node) { func (g *ASTTransformer) Transform(node *ast.Document, reader text.Reader, pc parser.Context) { firstChild := node.FirstChild() tocMode := "" - ctx := pc.Get(renderContextKey).(*markup.RenderContext) - rc := pc.Get(renderConfigKey).(*RenderConfig) + ctx := pc.Get(markdownutil.RenderContextKey).(*markup.RenderContext) + rc := pc.Get(markdownutil.RenderConfigKey).(*RenderConfig) tocList := make([]markup.Header, 0, 20) if rc.yamlNode != nil { diff --git a/modules/markup/markdown/markdown.go b/modules/markup/markdown/markdown.go index e811d29994..2b19e0f1c9 100644 --- a/modules/markup/markdown/markdown.go +++ b/modules/markup/markdown/markdown.go @@ -16,6 +16,7 @@ import ( "forgejo.org/modules/markup/common" "forgejo.org/modules/markup/markdown/callout" "forgejo.org/modules/markup/markdown/math" + markdownutil "forgejo.org/modules/markup/markdown/util" "forgejo.org/modules/setting" giteautil "forgejo.org/modules/util" @@ -34,11 +35,6 @@ var ( specMarkdownOnce sync.Once ) -var ( - renderContextKey = parser.NewContextKey() - renderConfigKey = parser.NewContextKey() -) - type limitWriter struct { w io.Writer sum int64 @@ -64,7 +60,7 @@ func (l *limitWriter) Write(data []byte) (int, error) { // newParserContext creates a parser.Context with the render context set func newParserContext(ctx *markup.RenderContext) parser.Context { pc := parser.NewContext(parser.WithIDs(newPrefixedIDs())) - pc.Set(renderContextKey, ctx) + pc.Set(markdownutil.RenderContextKey, ctx) return pc } @@ -192,7 +188,7 @@ func actualRender(ctx *markup.RenderContext, input io.Reader, output io.Writer) } rc.metaLength = metaLength - pc.Set(renderConfigKey, rc) + pc.Set(markdownutil.RenderConfigKey, rc) if err := converter.Convert(buf, lw, parser.WithContext(pc)); err != nil { log.Error("Unable to render: %v", err) diff --git a/modules/markup/markdown/markdown_test.go b/modules/markup/markdown/markdown_test.go index f7955115e0..c854861031 100644 --- a/modules/markup/markdown/markdown_test.go +++ b/modules/markup/markdown/markdown_test.go @@ -561,6 +561,14 @@ func TestMathBlock(t *testing.T) { "test $$a$$", `

test a

` + nl, }, + { + `\[ +[\triangle ABC] = \sqrt{s(s-a)(s-b)(s-c)} +\]`, + `

[
+[\triangle ABC] = \sqrt{s(s-a)(s-b)(s-c)}
+]

` + nl, + }, } for _, test := range testcases { @@ -568,6 +576,32 @@ func TestMathBlock(t *testing.T) { 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) } + + t.Run("Wiki context", func(t *testing.T) { + testcases := []struct { + testcase string + expected string + }{ + { + "$a$", + `

a

` + nl, + }, + { + `\[ +[\triangle ABC] = \sqrt{s(s-a)(s-b)(s-c)} +\]`, + `

+[\triangle ABC] = \sqrt{s(s-a)(s-b)(s-c)}
+
` + nl, + }, + } + + for _, test := range testcases { + res, err := markdown.RenderString(&markup.RenderContext{Ctx: git.DefaultContext, IsWiki: true}, 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) + } + }) } func TestFootnote(t *testing.T) { diff --git a/modules/markup/markdown/math/block_parser.go b/modules/markup/markdown/math/block_parser.go index 527df84975..b0fe1d588a 100644 --- a/modules/markup/markdown/math/block_parser.go +++ b/modules/markup/markdown/math/block_parser.go @@ -6,6 +6,9 @@ package math import ( "bytes" + "forgejo.org/modules/markup" + markdownutil "forgejo.org/modules/markup/markdown/util" + "github.com/yuin/goldmark/ast" "github.com/yuin/goldmark/parser" "github.com/yuin/goldmark/text" @@ -61,6 +64,13 @@ func (b *blockParser) Open(parent ast.Node, reader text.Reader, pc parser.Contex return node, parser.Close | parser.NoChildren } + ctx := pc.Get(markdownutil.RenderContextKey).(*markup.RenderContext) + if ctx.IsWiki { + reader.Advance(segment.Len() - 1) + segment.Start += 2 + node.Lines().Append(segment) + return node, parser.NoChildren + } return nil, parser.NoChildren } diff --git a/modules/markup/markdown/util/text.go b/modules/markup/markdown/util/text.go index 8a42e5835b..db6e432e79 100644 --- a/modules/markup/markdown/util/text.go +++ b/modules/markup/markdown/util/text.go @@ -7,6 +7,7 @@ import ( "bytes" "github.com/yuin/goldmark/ast" + "github.com/yuin/goldmark/parser" ) func textOfChildren(n ast.Node, src []byte, b *bytes.Buffer) { @@ -24,3 +25,8 @@ func Text(n ast.Node, src []byte) []byte { textOfChildren(n, src, &b) return b.Bytes() } + +var ( + RenderContextKey = parser.NewContextKey() + RenderConfigKey = parser.NewContextKey() +) diff --git a/modules/packages/rpm/metadata.go b/modules/packages/rpm/metadata.go index 4af9af620f..503b7b1a24 100644 --- a/modules/packages/rpm/metadata.go +++ b/modules/packages/rpm/metadata.go @@ -232,9 +232,10 @@ func getEntries(h *rpmutils.RpmHeader, namesTag, versionsTag, flagsTag int, repo case "alt": for i := range names { e := &Entry{ + Name: names[i], AltFlags: uint32(flags[i]), + Version: versions[i], } - e.Version = versions[i] entries = append(entries, e) } } diff --git a/modules/setting/incoming_email.go b/modules/setting/incoming_email.go index e592220de6..a890a4a328 100644 --- a/modules/setting/incoming_email.go +++ b/modules/setting/incoming_email.go @@ -44,9 +44,14 @@ func loadIncomingEmailFrom(rootCfg ConfigProvider) { if sec.HasKey("USER") && !sec.HasKey("USERNAME") { IncomingEmail.Username = sec.Key("USER").String() } + if sec.HasKey("PASSWD") && !sec.HasKey("PASSWORD") { - IncomingEmail.Password = sec.Key("PASSWD").String() + sec.Key("PASSWORD").SetValue(sec.Key("PASSWD").String()) } + if sec.HasKey("PASSWD_URI") && !sec.HasKey("PASSWORD_URI") { + sec.Key("PASSWORD_URI").SetValue(sec.Key("PASSWD_URI").String()) + } + IncomingEmail.Password = loadSecret(sec, "PASSWORD_URI", "PASSWORD") // Infer Port if not set if IncomingEmail.Port == 0 { diff --git a/modules/setting/incoming_email_test.go b/modules/setting/incoming_email_test.go index 6d181cae3c..4ea740bafd 100644 --- a/modules/setting/incoming_email_test.go +++ b/modules/setting/incoming_email_test.go @@ -4,6 +4,8 @@ package setting import ( + "os" + "path/filepath" "testing" "github.com/stretchr/testify/assert" @@ -35,6 +37,22 @@ func Test_loadIncomingEmailFrom(t *testing.T) { assert.Equal(t, "y0u'll n3v3r gUess th1S!!1", IncomingEmail.Password) }) + t.Run("Secrets", func(t *testing.T) { + uri := filepath.Join(t.TempDir(), "email_incoming_password") + + if err := os.WriteFile(uri, []byte("th1S gUess n3v3r y0u'll!!1"), 0o644); err != nil { + t.Fatal(err) + } + + cfg, sec := makeBaseConfig() + sec.NewKey("PASSWORD_URI", "file:"+uri) + + IncomingEmail.Password = "" + loadIncomingEmailFrom(cfg) + + assert.Equal(t, "th1S gUess n3v3r y0u'll!!1", IncomingEmail.Password) + }) + t.Run("Port settings", func(t *testing.T) { t.Run("no port, no tls", func(t *testing.T) { defer resetIncomingEmailPort()() diff --git a/modules/setting/log.go b/modules/setting/log.go index 0747ac4dac..6d069d0e9c 100644 --- a/modules/setting/log.go +++ b/modules/setting/log.go @@ -133,6 +133,7 @@ func loadLogModeByName(rootCfg ConfigProvider, loggerName, modeName string) (wri writerMode.StacktraceLevel = log.LevelFromString(ConfigInheritedKeyString(sec, "STACKTRACE_LEVEL", Log.StacktraceLogLevel.String())) writerMode.Prefix = ConfigInheritedKeyString(sec, "PREFIX") writerMode.Expression = ConfigInheritedKeyString(sec, "EXPRESSION") + writerMode.Exclusion = ConfigInheritedKeyString(sec, "EXCLUSION") // flags are updated and set below switch writerType { diff --git a/modules/setting/log_test.go b/modules/setting/log_test.go index eda6dc36af..223bd68285 100644 --- a/modules/setting/log_test.go +++ b/modules/setting/log_test.go @@ -44,6 +44,7 @@ func TestLogConfigDefault(t *testing.T) { "BufferLen": 10000, "Colorize": false, "Expression": "", + "Exclusion": "", "Flags": "stdflags", "Level": "info", "Prefix": "", @@ -83,6 +84,7 @@ logger.xorm.MODE = "BufferLen": 10000, "Colorize": false, "Expression": "", + "Exclusion": "", "Flags": "stdflags", "Level": "info", "Prefix": "", @@ -121,6 +123,7 @@ MODE = console "BufferLen": 10000, "Colorize": false, "Expression": "", + "Exclusion": "", "Flags": "stdflags", "Level": "info", "Prefix": "", @@ -168,6 +171,7 @@ ACCESS = file "BufferLen": 10000, "Colorize": false, "Expression": "", + "Exclusion": "", "Flags": "stdflags", "Level": "info", "Prefix": "", @@ -191,6 +195,7 @@ ACCESS = file "BufferLen": 10000, "Colorize": false, "Expression": "", + "Exclusion": "", "Flags": "none", "Level": "info", "Prefix": "", @@ -257,6 +262,7 @@ STDERR = true "BufferLen": 10000, "Colorize": false, "Expression": "", + "Exclusion": "", "Flags": "stdflags", "Level": "warn", "Prefix": "", @@ -270,6 +276,7 @@ STDERR = true "BufferLen": 10000, "Colorize": false, "Expression": "", + "Exclusion": "", "Flags": "stdflags", "Level": "error", "Prefix": "", @@ -287,6 +294,7 @@ STDERR = true "BufferLen": 10000, "Colorize": false, "Expression": "", + "Exclusion": "", "Flags": "none", "Level": "warn", "Prefix": "", @@ -323,6 +331,7 @@ MODE = file LEVEL = error STACKTRACE_LEVEL = fatal EXPRESSION = filter +EXCLUSION = not FLAGS = medfile PREFIX = "[Prefix] " FILE_NAME = file-xxx.log @@ -341,6 +350,7 @@ COMPRESSION_LEVEL = 4 "BufferLen": 10, "Colorize": false, "Expression": "", + "Exclusion": "", "Flags": "stdflags", "Level": "info", "Prefix": "", @@ -360,6 +370,7 @@ COMPRESSION_LEVEL = 4 "BufferLen": 10, "Colorize": false, "Expression": "filter", + "Exclusion": "not", "Flags": "medfile", "Level": "error", "Prefix": "[Prefix] ", diff --git a/modules/setting/mailer.go b/modules/setting/mailer.go index 9c004c6ce0..b43484a90f 100644 --- a/modules/setting/mailer.go +++ b/modules/setting/mailer.go @@ -147,6 +147,10 @@ func loadMailerFrom(rootCfg ConfigProvider) { if sec.HasKey("PASSWORD") && !sec.HasKey("PASSWD") { sec.Key("PASSWD").SetValue(sec.Key("PASSWORD").String()) } + if sec.HasKey("PASSWORD_URI") && !sec.HasKey("PASSWD_URI") { + sec.Key("PASSWD_URI").SetValue(sec.Key("PASSWORD_URI").String()) + } + sec.Key("PASSWD").SetValue(loadSecret(sec, "PASSWD_URI", "PASSWD")) // Set default values & validate sec.Key("NAME").MustString(AppName) diff --git a/modules/setting/mailer_test.go b/modules/setting/mailer_test.go index 4523cc91dd..47eaf3ffbb 100644 --- a/modules/setting/mailer_test.go +++ b/modules/setting/mailer_test.go @@ -4,6 +4,8 @@ package setting import ( + "os" + "path/filepath" "testing" "github.com/stretchr/testify/assert" @@ -52,6 +54,24 @@ func Test_loadMailerFrom(t *testing.T) { assert.Equal(t, "y0u'll n3v3r gUess th1S!!1", MailService.Passwd) }) + t.Run("Secrets", func(t *testing.T) { + uri := filepath.Join(t.TempDir(), "mailer_passwd") + + if err := os.WriteFile(uri, []byte("th1S gUess n3v3r y0u'll!!1"), 0o644); err != nil { + t.Fatal(err) + } + + cfg, _ := NewConfigProviderFromData("") + sec := cfg.Section("mailer") + sec.NewKey("ENABLED", "true") + sec.NewKey("PASSWD_URI", "file:"+uri) + + MailService.Passwd = "" + loadMailerFrom(cfg) + + assert.Equal(t, "th1S gUess n3v3r y0u'll!!1", MailService.Passwd) + }) + t.Run("sendmail argument sanitization", func(t *testing.T) { cfg, _ := NewConfigProviderFromData("") sec := cfg.Section("mailer") diff --git a/modules/structs/activitypub.go b/modules/structs/activitypub.go index 117eb0bed2..0cc257ff95 100644 --- a/modules/structs/activitypub.go +++ b/modules/structs/activitypub.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 structs @@ -7,3 +8,15 @@ package structs type ActivityPub struct { Context string `json:"@context"` } + +type APRemoteFollowOption struct { + Target string `json:"target"` +} + +type APPersonFollowItem struct { + ActorID string `json:"actor_id"` + Note string `json:"note"` + + OriginalURL string `json:"original_url"` + OriginalItem string `json:"original_item"` +} diff --git a/modules/structs/attachment.go b/modules/structs/attachment.go index 0a3d4140c2..746f618cf0 100644 --- a/modules/structs/attachment.go +++ b/modules/structs/attachment.go @@ -22,6 +22,12 @@ type Attachment struct { Type string `json:"type"` } +// WebAttachment the generic attachment with mime type +type WebAttachment struct { + *Attachment + MimeType string `json:"mime_type"` +} + // EditAttachmentOptions options for editing attachments // swagger:model type EditAttachmentOptions struct { diff --git a/modules/templates/helper.go b/modules/templates/helper.go index 02b175e6f6..42b4bad83c 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -188,6 +188,7 @@ func NewFuncMap() template.FuncMap { "RenderMarkdownToHtml": RenderMarkdownToHtml, "RenderLabel": RenderLabel, "RenderLabels": RenderLabels, + "RenderUser": RenderUser, "RenderReviewRequest": RenderReviewRequest, // ----------------------------------------------------------------- diff --git a/modules/templates/util_render.go b/modules/templates/util_render.go index a4d7a82eea..48f4eb04a3 100644 --- a/modules/templates/util_render.go +++ b/modules/templates/util_render.go @@ -7,6 +7,7 @@ import ( "context" "encoding/hex" "fmt" + "html" "html/template" "math" "net/url" @@ -15,6 +16,7 @@ import ( "unicode" issues_model "forgejo.org/models/issues" + user_model "forgejo.org/models/user" "forgejo.org/modules/emoji" "forgejo.org/modules/log" "forgejo.org/modules/markup" @@ -26,7 +28,7 @@ import ( // RenderCommitMessage renders commit message with XSS-safe and special links. func RenderCommitMessage(ctx context.Context, msg string, metas map[string]string) template.HTML { - cleanMsg := template.HTMLEscapeString(msg) + cleanMsg := html.EscapeString(msg) // we can safely assume that it will not return any error, since there // shouldn't be any special HTML. fullMessage, err := markup.RenderCommitMessage(&markup.RenderContext{ @@ -63,7 +65,7 @@ func RenderCommitMessageLinkSubject(ctx context.Context, msg, urlDefault string, Ctx: ctx, DefaultLink: urlDefault, Metas: metas, - }, template.HTMLEscapeString(msgLine)) + }, html.EscapeString(msgLine)) if err != nil { log.Error("RenderCommitMessageSubject: %v", err) return template.HTML("") @@ -88,7 +90,7 @@ func RenderCommitBody(ctx context.Context, msg string, metas map[string]string) renderedMessage, err := markup.RenderCommitMessage(&markup.RenderContext{ Ctx: ctx, Metas: metas, - }, template.HTMLEscapeString(msgLine)) + }, html.EscapeString(msgLine)) if err != nil { log.Error("RenderCommitMessage: %v", err) return "" @@ -122,7 +124,7 @@ func RenderIssueTitle(ctx context.Context, text string, metas map[string]string) renderedText, err := markup.RenderIssueTitle(&markup.RenderContext{ Ctx: ctx, Metas: metas, - }, template.HTMLEscapeString(text)) + }, html.EscapeString(text)) if err != nil { log.Error("RenderIssueTitle: %v", err) return template.HTML("") @@ -132,7 +134,7 @@ func RenderIssueTitle(ctx context.Context, text string, metas map[string]string) // RenderRefIssueTitle renders referenced issue/pull title with defined post processors func RenderRefIssueTitle(ctx context.Context, text string) template.HTML { - renderedText, err := markup.RenderRefIssueTitle(&markup.RenderContext{Ctx: ctx}, template.HTMLEscapeString(text)) + renderedText, err := markup.RenderRefIssueTitle(&markup.RenderContext{Ctx: ctx}, html.EscapeString(text)) if err != nil { log.Error("RenderRefIssueTitle: %v", err) return "" @@ -150,7 +152,7 @@ func RenderLabel(ctx context.Context, locale translation.Locale, label *issues_m labelScope = label.ExclusiveScope() ) - description := emoji.ReplaceAliases(template.HTMLEscapeString(label.Description)) + description := emoji.ReplaceAliases(html.EscapeString(label.Description)) if label.IsArchived() { archivedCSSClass = "archived-label" @@ -212,7 +214,7 @@ func RenderLabel(ctx context.Context, locale translation.Locale, label *issues_m // RenderEmoji renders html text with emoji post processors func RenderEmoji(ctx context.Context, text string) template.HTML { renderedText, err := markup.RenderEmoji(&markup.RenderContext{Ctx: ctx}, - template.HTMLEscapeString(text)) + html.EscapeString(text)) if err != nil { log.Error("RenderEmoji: %v", err) return template.HTML("") @@ -263,10 +265,20 @@ func RenderLabels(ctx context.Context, locale translation.Locale, labels []*issu return template.HTML(htmlCode) } +func RenderUser(ctx context.Context, user user_model.User) template.HTML { + if user.ID > 0 { + return template.HTML(fmt.Sprintf( + "%s", + user.HomeLink(), html.EscapeString(user.GetDisplayName()))) + } + return template.HTML(fmt.Sprintf("%s", + html.EscapeString(user.GetDisplayName()))) +} + 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())) + usernames = append(usernames, html.EscapeString(user.Name())) } htmlCode := `` diff --git a/modules/templates/util_render_test.go b/modules/templates/util_render_test.go index 62e063213c..a5fb18642a 100644 --- a/modules/templates/util_render_test.go +++ b/modules/templates/util_render_test.go @@ -11,6 +11,9 @@ import ( "forgejo.org/models/db" issues_model "forgejo.org/models/issues" "forgejo.org/models/unittest" + user_model "forgejo.org/models/user" + "forgejo.org/modules/setting" + "forgejo.org/modules/test" "forgejo.org/modules/translation" "github.com/stretchr/testify/assert" @@ -215,9 +218,51 @@ func TestRenderLabels(t *testing.T) { tr := &translation.MockLocale{} label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}) + labelScoped := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 7}) + labelMalicious := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 11}) + labelArchived := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 12}) - assert.Contains(t, RenderLabels(db.DefaultContext, tr, []*issues_model.Label{label}, "user2/repo1", false), - "user2/repo1/issues?labels=1") - assert.Contains(t, RenderLabels(db.DefaultContext, tr, []*issues_model.Label{label}, "user2/repo1", true), - "user2/repo1/pulls?labels=1") + rendered := RenderLabels(db.DefaultContext, tr, []*issues_model.Label{label}, "user2/repo1", false) + assert.Contains(t, rendered, "user2/repo1/issues?labels=1") + assert.Contains(t, rendered, ">label1<") + assert.Contains(t, rendered, "title='First label'") + rendered = RenderLabels(db.DefaultContext, tr, []*issues_model.Label{label}, "user2/repo1", true) + assert.Contains(t, rendered, "user2/repo1/pulls?labels=1") + assert.Contains(t, rendered, ">label1<") + rendered = RenderLabels(db.DefaultContext, tr, []*issues_model.Label{labelScoped}, "user2/repo1", false) + assert.Contains(t, rendered, "user2/repo1/issues?labels=7") + assert.Contains(t, rendered, ">scope<") + assert.Contains(t, rendered, ">label1<") + rendered = RenderLabels(db.DefaultContext, tr, []*issues_model.Label{labelMalicious}, "user2/repo1", false) + assert.Contains(t, rendered, "user2/repo1/issues?labels=11") + assert.Contains(t, rendered, "> <script>malicious</script> <") + assert.Contains(t, rendered, ">'?&<") + assert.Contains(t, rendered, "title='Malicious label ' <script>malicious</script>'") + rendered = RenderLabels(db.DefaultContext, tr, []*issues_model.Label{labelArchived}, "user2/repo1", false) + assert.Contains(t, rendered, "user2/repo1/issues?labels=12") + assert.Contains(t, rendered, ">archived label<><") + assert.Contains(t, rendered, "title='repo.issues.archived_label_description'") +} + +func TestRenderUser(t *testing.T) { + unittest.PrepareTestEnv(t) + + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) + ghost := user_model.NewGhostUser() + + assert.Contains(t, RenderUser(db.DefaultContext, *user), + "user2") + assert.Contains(t, RenderUser(db.DefaultContext, *org), + "org3") + assert.Contains(t, RenderUser(db.DefaultContext, *ghost), + "Ghost") + + defer test.MockVariableValue(&setting.UI.DefaultShowFullName, true)() + assert.Contains(t, RenderUser(db.DefaultContext, *user), + "< U<se>r Tw<o > ><") + assert.Contains(t, RenderUser(db.DefaultContext, *org), + "<<<< >> >> > >> > >>> >>") + assert.Contains(t, RenderUser(db.DefaultContext, *ghost), + "Ghost") } diff --git a/modules/test/distant_federation_server_mock.go b/modules/test/distant_federation_server_mock.go index 9bd908e2b9..ea8a69e9b4 100644 --- a/modules/test/distant_federation_server_mock.go +++ b/modules/test/distant_federation_server_mock.go @@ -10,56 +10,79 @@ import ( "net/http/httptest" "strings" "testing" + + "forgejo.org/modules/util" ) type FederationServerMockPerson struct { - ID int64 - Name string - PubKey string + ID int64 + Name string + PubKey string + PrivKey string } type FederationServerMockRepository struct { ID int64 } +type ApActorMock struct { + PrivKey string + PubKey string +} type FederationServerMock struct { + ApActor ApActorMock Persons []FederationServerMockPerson Repositories []FederationServerMockRepository LastPost string } func NewFederationServerMockPerson(id int64, name string) FederationServerMockPerson { + priv, pub, _ := util.GenerateKeyPair(3072) 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"`, + ID: id, + Name: name, + PubKey: pub, + PrivKey: priv, } } +func (p *FederationServerMockPerson) KeyID(host string) string { + return fmt.Sprintf("%[1]v/api/v1/activitypub/user-id/%[2]v#main-key", host, p.ID) +} + func NewFederationServerMockRepository(id int64) FederationServerMockRepository { return FederationServerMockRepository{ ID: id, } } +func NewApActorMock() ApActorMock { + priv, pub, _ := util.GenerateKeyPair(1024) + return ApActorMock{ + PrivKey: priv, + PubKey: pub, + } +} + +func (u *ApActorMock) KeyID(host string) string { + return fmt.Sprintf("%[1]v/api/v1/activitypub/actor#main-key", host) +} + 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",`+ + `"id":"http://%[1]v/api/v1/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",`+ + `"inbox":"http://%[1]v/api/v1/activitypub/user-id/%[2]v/inbox",`+ + `"outbox":"http://%[1]v/api/v1/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) + `"publicKey":{"id":"http://%[1]v/api/v1/activitypub/user-id/%[2]v#main-key",`+ + `"owner":"http://%[1]v/api/v1/activitypub/user-id/%[2]v",`+ + `"publicKeyPem":%[4]q}}`, host, p.ID, p.Name, p.PubKey) } func NewFederationServerMock() *FederationServerMock { return &FederationServerMock{ + ApActor: NewApActorMock(), Persons: []FederationServerMockPerson{ NewFederationServerMockPerson(15, "stargoose1"), NewFederationServerMockPerson(30, "stargoose2"), @@ -71,8 +94,18 @@ func NewFederationServerMock() *FederationServerMock { } } +func (mock *FederationServerMock) recordLastPost(t *testing.T, req *http.Request) { + buf := new(strings.Builder) + _, err := io.Copy(buf, req.Body) + if err != nil { + t.Errorf("Error reading body: %q", err) + } + mock.LastPost = strings.ReplaceAll(buf.String(), req.Host, "DISTANT_FEDERATION_HOST") +} + 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 @@ -87,30 +120,28 @@ func (mock *FederationServerMock) DistantServer(t *testing.T) *httptest.Server { `"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), + federatedRoutes.HandleFunc(fmt.Sprintf("POST /api/v1/activitypub/user-id/%v/inbox", person.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() + mock.recordLastPost(t, req) + }) + } + + for _, repository := range mock.Repositories { + federatedRoutes.HandleFunc(fmt.Sprintf("POST /api/v1/activitypub/repository-id/%v/inbox", repository.ID), + func(res http.ResponseWriter, req *http.Request) { + mock.recordLastPost(t, req) }) } federatedRoutes.HandleFunc("/", func(res http.ResponseWriter, req *http.Request) { - t.Errorf("Unhandled request: %q", req.URL.EscapedPath()) + t.Errorf("Unhandled %v request: %q", req.Method, req.URL.EscapedPath()) }) federatedSrv := httptest.NewServer(federatedRoutes) return federatedSrv diff --git a/modules/typesniffer/typesniffer.go b/modules/typesniffer/typesniffer.go index 262feb2b05..8cb1513a88 100644 --- a/modules/typesniffer/typesniffer.go +++ b/modules/typesniffer/typesniffer.go @@ -124,7 +124,7 @@ func (ct SniffedType) GetMimeType() string { } // DetectContentType extends http.DetectContentType with more content types. Defaults to text/unknown if input is empty. -func DetectContentType(data []byte) SniffedType { +func DetectContentType(data []byte, filename string) SniffedType { if len(data) == 0 { return SniffedType{"text/unknown"} } @@ -176,6 +176,13 @@ func DetectContentType(data []byte) SniffedType { } } + if ct == "application/octet-stream" && + filename != "" && + !strings.HasSuffix(strings.ToUpper(filename), ".LCOM") && + bytes.Contains(data, []byte("(DEFINE-FILE-INFO ")) { + ct = "text/vnd.interlisp" + } + // GLTF is unsupported by http.DetectContentType // hexdump -n 4 -C glTF.glb if bytes.HasPrefix(data, []byte("glTF")) { @@ -186,7 +193,7 @@ func DetectContentType(data []byte) SniffedType { } // DetectContentTypeFromReader guesses the content type contained in the reader. -func DetectContentTypeFromReader(r io.Reader) (SniffedType, error) { +func DetectContentTypeFromReader(r io.Reader, filename string) (SniffedType, error) { buf := make([]byte, sniffLen) n, err := util.ReadAtMost(r, buf) if err != nil { @@ -194,5 +201,5 @@ func DetectContentTypeFromReader(r io.Reader) (SniffedType, error) { } buf = buf[:n] - return DetectContentType(buf), nil + return DetectContentType(buf, filename), nil } diff --git a/modules/typesniffer/typesniffer_test.go b/modules/typesniffer/typesniffer_test.go index 176d3658bb..d2b7ed4f21 100644 --- a/modules/typesniffer/typesniffer_test.go +++ b/modules/typesniffer/typesniffer_test.go @@ -16,63 +16,63 @@ import ( func TestDetectContentTypeLongerThanSniffLen(t *testing.T) { // Pre-condition: Shorter than sniffLen detects SVG. - assert.Equal(t, "image/svg+xml", DetectContentType([]byte(``)).contentType) + assert.Equal(t, "image/svg+xml", DetectContentType([]byte(``), "").contentType) // Longer than sniffLen detects something else. - assert.NotEqual(t, "image/svg+xml", DetectContentType([]byte(``)).contentType) + assert.NotEqual(t, "image/svg+xml", DetectContentType([]byte(``), "").contentType) } func TestIsTextFile(t *testing.T) { - assert.True(t, DetectContentType([]byte{}).IsText()) - assert.True(t, DetectContentType([]byte("lorem ipsum")).IsText()) + assert.True(t, DetectContentType([]byte{}, "").IsText()) + assert.True(t, DetectContentType([]byte("lorem ipsum"), "").IsText()) } func TestIsSvgImage(t *testing.T) { - assert.True(t, DetectContentType([]byte("")).IsSvgImage()) - assert.True(t, DetectContentType([]byte(" ")).IsSvgImage()) - assert.True(t, DetectContentType([]byte(``)).IsSvgImage()) - assert.True(t, DetectContentType([]byte(``)).IsSvgImage()) + assert.True(t, DetectContentType([]byte(""), "").IsSvgImage()) + assert.True(t, DetectContentType([]byte(" "), "").IsSvgImage()) + assert.True(t, DetectContentType([]byte(``), "").IsSvgImage()) + assert.True(t, DetectContentType([]byte(``), "").IsSvgImage()) assert.True(t, DetectContentType([]byte(` - `)).IsSvgImage()) + `), "").IsSvgImage()) assert.True(t, DetectContentType([]byte(` - `)).IsSvgImage()) + `), "").IsSvgImage()) assert.True(t, DetectContentType([]byte(` - `)).IsSvgImage()) + `), "").IsSvgImage()) assert.True(t, DetectContentType([]byte(` - `)).IsSvgImage()) + `), "").IsSvgImage()) assert.True(t, DetectContentType([]byte(` - `)).IsSvgImage()) + `), "").IsSvgImage()) assert.True(t, DetectContentType([]byte(` - `)).IsSvgImage()) + `), "").IsSvgImage()) assert.True(t, DetectContentType([]byte(` - `)).IsSvgImage()) + `), "").IsSvgImage()) assert.True(t, DetectContentType([]byte(` - `)).IsSvgImage()) + `), "").IsSvgImage()) // the DetectContentType should work for incomplete data, because only beginning bytes are used for detection - assert.True(t, DetectContentType([]byte(`....`)).IsSvgImage()) + assert.True(t, DetectContentType([]byte(`....`), "").IsSvgImage()) - assert.False(t, DetectContentType([]byte{}).IsSvgImage()) - assert.False(t, DetectContentType([]byte("svg")).IsSvgImage()) - assert.False(t, DetectContentType([]byte("")).IsSvgImage()) - assert.False(t, DetectContentType([]byte("text")).IsSvgImage()) - assert.False(t, DetectContentType([]byte("")).IsSvgImage()) - assert.False(t, DetectContentType([]byte(``)).IsSvgImage()) + assert.False(t, DetectContentType([]byte{}, "").IsSvgImage()) + assert.False(t, DetectContentType([]byte("svg"), "").IsSvgImage()) + assert.False(t, DetectContentType([]byte(""), "").IsSvgImage()) + assert.False(t, DetectContentType([]byte("text"), "").IsSvgImage()) + assert.False(t, DetectContentType([]byte(""), "").IsSvgImage()) + assert.False(t, DetectContentType([]byte(``), "").IsSvgImage()) assert.False(t, DetectContentType([]byte(` - `)).IsSvgImage()) + `), "").IsSvgImage()) assert.False(t, DetectContentType([]byte(` - `)).IsSvgImage()) + `), "").IsSvgImage()) assert.False(t, DetectContentType([]byte(` @@ -80,7 +80,7 @@ func TestIsSvgImage(t *testing.T) { -`)).IsSvgImage()) +`), "").IsSvgImage()) assert.False(t, DetectContentType([]byte(` -`)).IsSvgImage()) - assert.False(t, DetectContentType([]byte(``)).IsSvgImage()) - assert.False(t, DetectContentType([]byte(``)).IsSvgImage()) +`), "").IsSvgImage()) + assert.False(t, DetectContentType([]byte(``), "").IsSvgImage()) + assert.False(t, DetectContentType([]byte(``), "").IsSvgImage()) } func TestIsPDF(t *testing.T) { pdf, _ := base64.StdEncoding.DecodeString("JVBERi0xLjYKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0ZpbHRlci9GbGF0ZURlY29kZT4+CnN0cmVhbQp4nF3NPwsCMQwF8D2f4s2CNYk1baF0EHRwOwg4iJt/NsFb/PpevUE4Mjwe") - assert.True(t, DetectContentType(pdf).IsPDF()) - assert.False(t, DetectContentType([]byte("plain text")).IsPDF()) + assert.True(t, DetectContentType(pdf, "").IsPDF()) + assert.False(t, DetectContentType([]byte("plain text"), "").IsPDF()) } func TestIsVideo(t *testing.T) { mp4, _ := base64.StdEncoding.DecodeString("AAAAGGZ0eXBtcDQyAAAAAGlzb21tcDQyAAEI721vb3YAAABsbXZoZAAAAADaBlwX2gZcFwAAA+gA") - assert.True(t, DetectContentType(mp4).IsVideo()) - assert.False(t, DetectContentType([]byte("plain text")).IsVideo()) + assert.True(t, DetectContentType(mp4, "").IsVideo()) + assert.False(t, DetectContentType([]byte("plain text"), "").IsVideo()) } func TestIsAudio(t *testing.T) { mp3, _ := base64.StdEncoding.DecodeString("SUQzBAAAAAABAFRYWFgAAAASAAADbWFqb3JfYnJhbmQAbXA0MgBUWFhYAAAAEQAAA21pbm9yX3Zl") - assert.True(t, DetectContentType(mp3).IsAudio()) - assert.False(t, DetectContentType([]byte("plain text")).IsAudio()) + assert.True(t, DetectContentType(mp3, "").IsAudio()) + assert.False(t, DetectContentType([]byte("plain text"), "").IsAudio()) - assert.True(t, DetectContentType([]byte("ID3Toy\000")).IsAudio()) - assert.True(t, DetectContentType([]byte("ID3Toy\n====\t* hi šŸŒž, ...")).IsText()) // test ID3 tag for plain text - assert.True(t, DetectContentType([]byte("ID3Toy\n====\t* hi šŸŒž, ..."+"šŸŒ›"[0:2])).IsText()) // test ID3 tag with incomplete UTF8 char + assert.True(t, DetectContentType([]byte("ID3Toy\000"), "").IsAudio()) + assert.True(t, DetectContentType([]byte("ID3Toy\n====\t* hi šŸŒž, ..."), "").IsText()) // test ID3 tag for plain text + assert.True(t, DetectContentType([]byte("ID3Toy\n====\t* hi šŸŒž, ..."+"šŸŒ›"[0:2]), "").IsText()) // test ID3 tag with incomplete UTF8 char } func TestIsGLB(t *testing.T) { glb, _ := hex.DecodeString("676c5446") - assert.True(t, DetectContentType(glb).IsGLB()) - assert.True(t, DetectContentType(glb).Is3DModel()) - assert.False(t, DetectContentType([]byte("plain text")).IsGLB()) - assert.False(t, DetectContentType([]byte("plain text")).Is3DModel()) + assert.True(t, DetectContentType(glb, "").IsGLB()) + assert.True(t, DetectContentType(glb, "").Is3DModel()) + assert.False(t, DetectContentType([]byte("plain text"), "").IsGLB()) + assert.False(t, DetectContentType([]byte("plain text"), "").Is3DModel()) } func TestDetectContentTypeFromReader(t *testing.T) { mp3, _ := base64.StdEncoding.DecodeString("SUQzBAAAAAABAFRYWFgAAAASAAADbWFqb3JfYnJhbmQAbXA0MgBUWFhYAAAAEQAAA21pbm9yX3Zl") - st, err := DetectContentTypeFromReader(bytes.NewReader(mp3)) + st, err := DetectContentTypeFromReader(bytes.NewReader(mp3), "") require.NoError(t, err) assert.True(t, st.IsAudio()) } func TestDetectContentTypeOgg(t *testing.T) { oggAudio, _ := hex.DecodeString("4f67675300020000000000000000352f0000000000007dc39163011e01766f72626973000000000244ac0000000000000071020000000000b8014f6767530000") - st, err := DetectContentTypeFromReader(bytes.NewReader(oggAudio)) + st, err := DetectContentTypeFromReader(bytes.NewReader(oggAudio), "") require.NoError(t, err) assert.True(t, st.IsAudio()) oggVideo, _ := hex.DecodeString("4f676753000200000000000000007d9747ef000000009b59daf3012a807468656f7261030201001e00110001e000010e00020000001e00000001000001000001") - st, err = DetectContentTypeFromReader(bytes.NewReader(oggVideo)) + st, err = DetectContentTypeFromReader(bytes.NewReader(oggVideo), "") require.NoError(t, err) assert.True(t, st.IsVideo()) } @@ -148,7 +148,7 @@ func TestDetectContentTypeAvif(t *testing.T) { avifImage, err := hex.DecodeString("000000206674797061766966") require.NoError(t, err) - st, err := DetectContentTypeFromReader(bytes.NewReader(avifImage)) + st, err := DetectContentTypeFromReader(bytes.NewReader(avifImage), "") require.NoError(t, err) assert.True(t, st.IsImage()) @@ -158,10 +158,24 @@ func TestDetectContentTypeModelGLB(t *testing.T) { glb, err := hex.DecodeString("676c5446") require.NoError(t, err) - st, err := DetectContentTypeFromReader(bytes.NewReader(glb)) + st, err := DetectContentTypeFromReader(bytes.NewReader(glb), "") require.NoError(t, err) // print st for debugging assert.Equal(t, "model/gltf-binary", st.GetMimeType()) assert.True(t, st.IsGLB()) } + +func TestDetectInterlisp(t *testing.T) { + interlisp, err := base64.StdEncoding.DecodeString("ICAKKERFRklORS1GSUxFLUlORk8gHlBBQ0tBR0UgIklOVEVSTElTUCIgHlJFQURUQUJMRSAiSU5URVJMSVNQIiAeQkFTRSAxMCkKCgYB") + require.NoError(t, err) + st, err := DetectContentTypeFromReader(bytes.NewReader(interlisp), "test") + require.NoError(t, err) + assert.True(t, st.IsText()) + st, err = DetectContentTypeFromReader(bytes.NewReader(interlisp), "") + require.NoError(t, err) + assert.False(t, st.IsText()) + st, err = DetectContentTypeFromReader(bytes.NewReader(interlisp), "test.lcom") + require.NoError(t, err) + assert.False(t, st.IsText()) +} diff --git a/modules/util/string.go b/modules/util/string.go index cf50f591c6..ca3d43ec6e 100644 --- a/modules/util/string.go +++ b/modules/util/string.go @@ -95,3 +95,25 @@ func UnsafeBytesToString(b []byte) string { func UnsafeStringToBytes(s string) []byte { return unsafe.Slice(unsafe.StringData(s), len(s)) } + +// AsciiEqualFold is taken from Golang, but reimplemented here, since the original is not exposed to public +// Taken from: https://cs.opensource.google/go/go/+/refs/tags/go1.24.4:src/net/http/internal/ascii/print.go +func ASCIIEqualFold(s, t string) bool { + if len(s) != len(t) { + return false + } + for i := 0; i < len(s); i++ { + if ASCIILower(s[i]) != ASCIILower(t[i]) { + return false + } + } + return true +} + +// AsciiLower returns the ASCII lowercase version of b. +func ASCIILower(b byte) byte { + if 'A' <= b && b <= 'Z' { + return b + ('a' - 'A') + } + return b +} diff --git a/modules/util/string_test.go b/modules/util/string_test.go index 0a4a8bbcfb..1012ab32a4 100644 --- a/modules/util/string_test.go +++ b/modules/util/string_test.go @@ -45,3 +45,29 @@ func TestToSnakeCase(t *testing.T) { assert.Equal(t, expected, ToSnakeCase(input)) } } + +func TestASCIIEqualFold(t *testing.T) { + cases := map[string]struct { + First string + Second string + Expected bool + }{ + "Empty String": {First: "", Second: "", Expected: true}, + "Single Letter Ident": {First: "h", Second: "h", Expected: true}, + "Single Letter Equal": {First: "h", Second: "H", Expected: true}, + "Single Letter Unequal": {First: "h", Second: "g", Expected: false}, + "Simple Match Ident": {First: "someString", Second: "someString", Expected: true}, + "Simple Match Equal": {First: "someString", Second: "someSTRIng", Expected: true}, + "Simple Match Unequal": {First: "someString", Second: "sameString", Expected: false}, + "Different Length": {First: "abcdef", Second: "abcdefg", Expected: false}, + "Unicode Kelvin": {First: "ghijklm", Second: "GHIJ\u212ALM", Expected: false}, + } + + for name := range cases { + c := cases[name] + t.Run(name, func(t *testing.T) { + Actual := ASCIIEqualFold(c.First, c.Second) + assert.Equal(t, c.Expected, Actual) + }) + } +} diff --git a/options/locale/locale_ar.ini b/options/locale/locale_ar.ini index 15d614e8bc..ba11586b44 100644 --- a/options/locale/locale_ar.ini +++ b/options/locale/locale_ar.ini @@ -297,7 +297,7 @@ twofa_disabled = Ų¹ŁŲ·Ł‘ŁŁ„ Ų§Ł„Ų§Ų³ŲŖŁŠŲ«Ų§Ł‚ Ų§Ł„Ų«Ł†Ų§Ų¦ŁŠ. theme_desc = Ų³ŲŖŁƒŁˆŁ† هذه السمة Ų§Ł„Ł…ŲØŲÆŲ¦ŁŠŲ© Ł„Łƒ Ų¹ŲØŲ± Ų§Ł„Ł…ŁˆŁ‚Ų¹. new_password = ŁƒŁ„Ł…Ų© Ų§Ł„Ł…Ų±ŁˆŲ± Ų§Ł„Ų¬ŲÆŁŠŲÆŲ© twofa_disable_desc = ŲŖŲ¹Ų·ŁŠŁ„ Ų§Ł„Ų§Ų³ŲŖŁŠŲ«Ų§Ł‚ Ų§Ł„Ų«Ł†Ų§Ų¦ŁŠ Ų³ŁŠŲ¬Ų¹Ł„ حسابك أقل أمانًا. أتريد Ų§Ł„Ų§Ų³ŲŖŁ…Ų±Ų§Ų±ŲŸ -manage_themes = Ų§Ų®ŲŖŲ± السمة Ų§Ł„Ł…ŲØŲÆŲ¦ŁŠŲ© +manage_themes = Ų§Ł„Ł…ŁˆŲ¶ŁˆŲ¹ Ų§Ł„Ų§ŁŲŖŲ±Ų§Ų¶ŁŠ delete_prompt = هذه Ų§Ł„Ų¹Ł…Ł„ŁŠŲ© ستحذف حسابك ؄لى الأبد. لا ŁŠŁ…ŁƒŁ† التراجع عنها ŲØŲ¹ŲÆ Ų°Ł„Łƒ. cancel = ألغ repos_none = Ł„ŁŠŲ³ Ł„ŲÆŁŠŁƒ أي Ł…Ų³ŲŖŁˆŲÆŲ¹. @@ -390,7 +390,7 @@ account = الحساب uploaded_avatar_is_too_big = حجم الملف Ų§Ł„Ł…Ų±ŁŁˆŲ¹ (%d ŁƒŁŠā€ŒŲØ) ŁŠŲŖŲ®Ų·Ł‰ الحجم الأقصى (%d ŁƒŁŠā€ŒŲØ). biography_placeholder = أخبرنا ؓيئا عن Ł†ŁŲ³Łƒ! (ŁŠŁ…ŁƒŁ†Łƒ Ų§Ų³ŲŖŲ®ŲÆŲ§Ł… Ł…Ų§Ų±ŁƒŲÆŲ§ŁˆŁ†) comment_type_group_reference = ال؄ؓارات -orgs = Ų„ŲÆŲ§Ų±Ų© المنظمات +orgs = المنظمات update_profile = حدِّث الملف Ų§Ł„Ų“Ų®ŲµŁŠ profile = الملف Ų§Ł„Ų“Ų®ŲµŁŠ comment_type_group_dependency = Ų§Ł„Ų§Ų¹ŲŖŁ…Ų§ŲÆŁŠŲ§ŲŖ @@ -421,7 +421,7 @@ keep_email_private_popup = سيؤدي هذا ؄لى ؄خفاؔ Ų¹Ł†ŁˆŲ§Ł† بري ssh_key_name_used = Ł‡Ł†Ų§Łƒ مفتاح SSH بنفس الاسم Ł…ŁˆŲ¬ŁˆŲÆ بالفعل على حسابك. authorized_oauth2_applications = ŲŖŲ·ŲØŁŠŁ‚Ų§ŲŖ OAuth2 Ų§Ł„Ł…Ų£Ų°ŁˆŁ†Ų© uid = المعرّف Ų§Ł„Ų±Ł…Ų²ŁŠ -manage_openid = Ų„ŲÆŲ§Ų±Ų© Ų¹Ł†Ų§ŁˆŁŠŁ† OpenID +manage_openid = Ų¹Ł†Ų§ŁˆŁŠŁ† OpenID webauthn = Ų§Ų³ŲŖŁŠŲ«Ų§Ł‚ Ų«Ł†Ų§Ų¦ŁŠ (Ł…ŁŲ§ŲŖŁŠŲ­ الأمان) comment_type_group_deadline = Ų§Ł„Ł…ŁˆŲ¹ŲÆ Ų§Ł„Ł†Ł‡Ų§Ų¦ŁŠ add_key = أضف مفتاح @@ -502,6 +502,7 @@ update_oauth2_application_success = لقد حدّثت بنجاح ŲŖŲ·ŲØŁŠŁ‚ OAut oauth2_redirect_uris = روابط Ų„Ų¹Ų§ŲÆŲ© Ų§Ł„ŲŖŁˆŲ¬ŁŠŁ‡. Ł†Ų±Ų¬Łˆ وضع ŁƒŁ„ Ų±Ų§ŲØŲ· في Ų³Ų·Ų± ŁˆŲ­ŲÆŁ‡. remove_account_link = أزل الحساب Ų§Ł„Ł…Ų±ŲØŁˆŲ· remove_account_link_success = Ų£ŁŲ²ŁŠŁ„ الحساب Ų§Ł„Ł…Ų±ŲØŁˆŲ·. +quota = كوتا [org] follow_blocked_user = لا ŁŠŁ…ŁƒŁ†Łƒ Ų„ŲŖŲØŲ§Ų¹ هذه المنظمة لأن هذه المنظمة حظرتك. @@ -1973,7 +1974,7 @@ component_failed_to_load = Ų­ŲÆŲ« Ų®Ų·Ų£ غير Ł…ŲŖŁˆŁ‚Ų¹. [search] -org_kind = ŲØŲ­Ų« في المنظمات... +org_kind = ŲØŲ­Ų« في المنظمات… code_search_unavailable = البحث في Ų§Ł„ŁƒŁˆŲÆ غير Ł…ŲŖŁˆŁŲ± Ų­Ų§Ł„ŁŠŁ‹Ų§. ŁŠŲ±Ų¬Ł‰ الاتصال ŲØŁ…ŲÆŁŠŲ± Ų§Ł„Ł…ŁˆŁ‚Ų¹. search = Ų§ŲØŲ­Ų«... type_tooltip = Ł†ŁˆŲ¹ البحث @@ -1981,13 +1982,13 @@ fuzzy = Ų£Ų¬Ų¹ŲÆ fuzzy_tooltip = قم ŲØŲŖŲ¶Ł…ŁŠŁ† النتائج Ų§Ł„ŲŖŁŠ ŲŖŲŖŲ·Ų§ŲØŁ‚ Ų£ŁŠŲ¶Ł‹Ų§ Ł…Ų¹ مصطلح البحث ŲØŲ“ŁƒŁ„ ŁˆŲ«ŁŠŁ‚ match = تتناسب match_tooltip = قم ŲØŲŖŲ¶Ł…ŁŠŁ† النتائج Ų§Ł„ŲŖŁŠ ŲŖŲ·Ų§ŲØŁ‚ مصطلح البحث المحدد فقط -repo_kind = ŲØŲ­Ų« في Ų§Ł„Ł…Ų³ŲŖŁˆŲÆŲ¹Ų§ŲŖ... -user_kind = ŲØŲ­Ų« عن Ų§Ł„Ł…Ų³ŲŖŲ®ŲÆŁ…ŁŠŁ†... -team_kind = ŲØŲ­Ų« عن الفرق ... -code_kind = ŲØŲ­Ų« في Ų§Ł„ŁƒŁˆŲÆ... -project_kind = البحث ضمن Ų§Ł„Ł…Ų“Ų§Ų±ŁŠŲ¹... -branch_kind = البحث ضمن Ų§Ł„ŁŲ±ŁˆŲ¹... +repo_kind = ŲØŲ­Ų« في Ų§Ł„Ł…Ų³ŲŖŁˆŲÆŲ¹Ų§ŲŖā€¦ +user_kind = ŲØŲ­Ų« عن Ų§Ł„Ł…Ų³ŲŖŲ®ŲÆŁ…ŁŠŁ†ā€¦ +team_kind = ŲØŲ­Ų« عن الفرق… +code_kind = ŲØŲ­Ų« في Ų§Ł„ŁƒŁˆŲÆā€¦ +project_kind = البحث ضمن Ų§Ł„Ł…Ų“Ų§Ų±ŁŠŲ¹ā€¦ +branch_kind = البحث ضمن Ų§Ł„ŁŲ±ŁˆŲ¹ā€¦ no_results = لا توجد نتائج مطابقة. -issue_kind = البحث ضمن الأعطال... -pull_kind = البحث ضمن طلبات السحب... +issue_kind = البحث ضمن الأعطال… +pull_kind = البحث ضمن طلبات السحب… keyword_search_unavailable = البحث من خلال Ų§Ł„ŁƒŁ„Ł…Ų§ŲŖ Ų§Ł„Ł…ŁŲŖŲ§Ų­ŁŠŲ© Ł„ŁŠŲ³ Ł…ŲŖŁˆŁŲ± Ų­Ų§Ł„ŁŠŲ§Ł‹. Ų±Ų¬Ų§Ų”Ų§Ł‹ ŲŖŁˆŲ§ŲµŁ„ Ł…Ų¹ مؓرف Ų§Ł„Ł…ŁˆŁ‚Ų¹. diff --git a/options/locale/locale_bg.ini b/options/locale/locale_bg.ini index 1b9767f674..8c69a36d52 100644 --- a/options/locale/locale_bg.ini +++ b/options/locale/locale_bg.ini @@ -141,6 +141,7 @@ webauthn_sign_in = ŠŠ°Ń‚ŠøŃŠ½ŠµŃ‚Šµ Š±ŃƒŃ‚Š¾Š½Š° на Š²Š°ŃˆŠøŃ ŠŗŠ»ŃŽŃ‡ за webauthn_error = ŠŠµŃƒŃŠæŠµŃˆŠ½Š¾ прочитане на Š²Š°ŃˆŠøŃ ŠŗŠ»ŃŽŃ‡ за ŃŠøŠ³ŃƒŃ€Š½Š¾ŃŃ‚. webauthn_unsupported_browser = Š’Š°ŃˆŠøŃŃ‚ Š±Ń€Š°ŃƒŠ·ŃŠŃ€ в момента не ŠæŠ¾Š“Š“ŃŠŃ€Š¶Š° WebAuthn. webauthn_error_duplicated = ŠšŠ»ŃŽŃ‡ŃŠŃ‚ за ŃŠøŠ³ŃƒŃ€Š½Š¾ŃŃ‚ не е Ń€Š°Š·Ń€ŠµŃˆŠµŠ½ за тази Š·Š°ŃŠ²ŠŗŠ°. ŠœŠ¾Š»Ń, ŃƒŠ²ŠµŃ€ŠµŃ‚Šµ се, че ŠŗŠ»ŃŽŃ‡ŃŠŃ‚ не е вече регистриран. +tracked_time_summary = ŠžŠ±Š¾Š±Ń‰ŠµŠ½ŠøŠµ на прослеГеното време въз основа на филтрите в списъка със заГачи [settings] ui = Тема @@ -324,7 +325,7 @@ permissions_list = Š Š°Š·Ń€ŠµŃˆŠµŠ½ŠøŃ: edit_oauth2_application = РеГактиране на OAuth2 приложение remove_oauth2_application = ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ на OAuth2 приложение twofa_recovery_tip = Ако Š·Š°Š³ŃƒŠ±ŠøŃ‚е ŃƒŃŃ‚Ń€Š¾Š¹ŃŃ‚Š²Š¾Ń‚Š¾ си, ще можете Га използвате ŠŗŠ»ŃŽŃ‡ за еГнократно Š²ŃŠŠ·ŃŃ‚Š°Š½Š¾Š²ŃŠ²Š°Š½Šµ, за Га си Š²ŃŠŃ€Š½ŠµŃ‚е Š“Š¾ŃŃ‚ŃŠŠæŠ° Го Š°ŠŗŠ°ŃƒŠ½Ń‚а. -visibility.private_tooltip = ВиГим само за членове на организации, в които ŃƒŃ‡Š°ŃŃ‚Š²Š°Ń‚Šµ +visibility.private_tooltip = ВиГим само за ŃƒŃ‡Š°ŃŃ‚Š½ŠøŃ†Šø в организации, в които ŃƒŃ‡Š°ŃŃ‚Š²Š°Ń‚Šµ quota.applies_to_user = ДлеГните правила за квота се прилагат за Š²Š°ŃˆŠøŃ Š°ŠŗŠ°ŃƒŠ½Ń‚ quota.rule.no_limit = ŠŠµŠ¾Š³Ń€Š°Š½ŠøŃ‡ŠµŠ½Š° hints = ПоГсказки @@ -380,6 +381,19 @@ hidden_comment_types = Дкрити типове коментари comment_type_group_lock = Š”ŃŠŃŃ‚Š¾ŃŠ½ŠøŠµ на Š·Š°ŠŗŠ»ŃŽŃ‡Š²Š°Š½Šµ can_not_add_email_activations_pending = Има чакаща Š°ŠŗŃ‚ŠøŠ²Š°Ń†ŠøŃ, опитайте отново слеГ Š½ŃŠŗŠ¾Š»ŠŗŠ¾ Š¼ŠøŠ½ŃƒŃ‚Šø, ако искате Га Гобавите нова ел. поща. storage_overview = ŠŸŃ€ŠµŠ³Š»ŠµŠ“ на ŃŃŠŃ…Ń€Š°Š½ŠµŠ½ŠøŠµŃ‚Š¾ +webauthn = Š”Š²ŃƒŃ„Š°ŠŗŃ‚Š¾Ń€Š½Š¾ ŃƒŠ“Š¾ŃŃ‚Š¾Š²ŠµŃ€ŃŠ²Š°Š½Šµ (ŠšŠ»ŃŽŃ‡Š¾Š²Šµ за ŃŠøŠ³ŃƒŃ€Š½Š¾ŃŃ‚) +quota.sizes.repos.public = ŠŸŃƒŠ±Š»ŠøŃ‡Š½Šø хранилища +quota.sizes.repos.private = Частни хранилища +quota.sizes.git.all = Git ŃŃŠŠ“ŃŠŃ€Š¶Š°Š½ŠøŠµ +quota.sizes.git.lfs = Git LFS +quota.sizes.assets.attachments.all = ŠŸŃ€ŠøŠŗŠ°Ń‡ŠµŠ½Šø файлове +quota.sizes.assets.attachments.releases = ŠŸŃ€ŠøŠŗŠ°Ń‡ŠµŠ½Šø файлове към ŠøŠ·Š“Š°Š½ŠøŃ +quota.sizes.assets.artifacts = Артефакти +quota.sizes.assets.packages.all = ŠŸŠ°ŠŗŠµŃ‚Šø +quota.sizes.wiki = Уики +quota.sizes.all = Всички +quota.sizes.repos.all = Єранилища +quota.sizes.assets.attachments.issues = ŠŸŃ€ŠøŠŗŠ°Ń‡ŠµŠ½Šø файлове към заГачи [packages] container.labels.value = Дтойност @@ -438,6 +452,112 @@ details.documentation_site = Уебсайт на Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†ŠøŃŃ‚Š° arch.version.conflicts = Š’ конфликт alpine.repository.branches = Клонове arch.pacman.repo.multi.item = ŠšŠ¾Š½Ń„ŠøŠ³ŃƒŃ€Š°Ń†ŠøŃ за %s +container.multi_arch = ŠžŠ” / ŠŃ€Ń…ŠøŃ‚ŠµŠŗŃ‚ŃƒŃ€Š° +rpm.repository = Š˜Š½Ń„Š¾Ń€Š¼Š°Ń†ŠøŃ за хранилището +container.pull = Š˜Š·Š“ŃŠŃ€ŠæŠ°Š¹Ń‚Šµ образа от ŠŗŠ¾Š¼Š°Š½Š“Š½ŠøŃ реГ: +helm.registry = ŠŠ°ŃŃ‚Ń€Š¾Š¹Ń‚Šµ този Ń€ŠµŠ³ŠøŃŃ‚ŃŠŃ€ от ŠŗŠ¾Š¼Š°Š½Š“Š½ŠøŃ реГ: +debian.repository.distributions = Š”ŠøŃŃ‚Ń€ŠøŠ±ŃƒŃ†ŠøŠø +npm.dependencies.optional = ŠžŠæŃ†ŠøŠ¾Š½Š°Š»Š½Šø зависимости +owner.settings.cargo.title = ИнГекс на Ń€ŠµŠ³ŠøŃŃ‚ŃŠŃ€Š° на Cargo +owner.settings.cleanuprules.keep.pattern.container = Š’ŠµŃ€ŃŠøŃŃ‚Š° latest винаги се запазва за Container пакети. +owner.settings.cleanuprules.remove.pattern = ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ на версии, ŃŃŠŠ¾Ń‚Š²ŠµŃ‚ŃŃ‚Š²Š°Ń‰Šø на +rpm.distros.suse = на Š“ŠøŃŃ‚Ń€ŠøŠ±ŃƒŃ†ŠøŠø, базирани на SUSE +owner.settings.cleanuprules.preview.overview = %d пакета са насрочени за премахване. +owner.settings.cleanuprules.preview = ŠŸŃ€ŠµŠ³Š»ŠµŠ“ на правило за почистване +arch.version.properties = Двойства на Š²ŠµŃ€ŃŠøŃŃ‚а +conan.registry = ŠŠ°ŃŃ‚Ń€Š¾Š¹Ń‚Šµ този Ń€ŠµŠ³ŠøŃŃ‚ŃŠŃ€ от ŠŗŠ¾Š¼Š°Š½Š“Š½ŠøŃ реГ: +conan.details.repository = Єранилище +composer.install = За Га инсталирате пакета с Composer, ŠøŠ·ŠæŃŠŠ»Š½ŠµŃ‚Šµ слеГната команГа: +chef.install = За Га инсталирате пакета, ŠøŠ·ŠæŃŠŠ»Š½ŠµŃ‚Šµ слеГната команГа: +chef.registry = ŠŠ°ŃŃ‚Ń€Š¾Š¹Ń‚Šµ този Ń€ŠµŠ³ŠøŃŃ‚ŃŠŃ€ във Š²Š°ŃˆŠøŃ файл ~/.chef/config.rb: +pub.install = За Га инсталирате пакета с Dart, ŠøŠ·ŠæŃŠŠ»Š½ŠµŃ‚Šµ слеГната команГа: +npm.details.tag = ŠœŠ°Ń€ŠŗŠµŃ€ +npm.install = За Га инсталирате пакета с npm, ŠøŠ·ŠæŃŠŠ»Š½ŠµŃ‚Šµ слеГната команГа: +maven.registry = ŠŠ°ŃŃ‚Ń€Š¾Š¹Ń‚Šµ този Ń€ŠµŠ³ŠøŃŃ‚ŃŠŃ€ във файла на Š²Š°ŃˆŠøŃ проект pom.xml: +debian.repository.components = ŠšŠ¾Š¼ŠæŠ¾Š½ŠµŠ½Ń‚Šø +debian.install = За Га инсталирате пакета, ŠøŠ·ŠæŃŠŠ»Š½ŠµŃ‚Šµ слеГната команГа: +cran.install = За Га инсталирате пакета, ŠøŠ·ŠæŃŠŠ»Š½ŠµŃ‚Šµ слеГната команГа: +cran.registry = ŠŠ°ŃŃ‚Ń€Š¾Š¹Ń‚Šµ този Ń€ŠµŠ³ŠøŃŃ‚ŃŠŃ€ във Š²Š°ŃˆŠøŃ файл Rprofile.site: +rpm.distros.redhat = на Š“ŠøŃŃ‚Ń€ŠøŠ±ŃƒŃ†ŠøŠø, базирани на RedHat +alt.registry = ŠŠ°ŃŃ‚Ń€Š¾Š¹Ń‚Šµ този Ń€ŠµŠ³ŠøŃŃ‚ŃŠŃ€ от ŠŗŠ¾Š¼Š°Š½Š“Š½ŠøŃ реГ: +rpm.repository.architectures = ŠŃ€Ń…ŠøŃ‚ŠµŠŗŃ‚ŃƒŃ€Šø +alt.registry.install = За Га инсталирате пакета, ŠøŠ·ŠæŃŠŠ»Š½ŠµŃ‚Šµ слеГната команГа: +alt.setup = Добавете хранилище към списъка със ŃŠ²ŃŠŃ€Š·Š°Š½Šø хранилища (изберете необхоГимата Š°Ń€Ń…ŠøŃ‚ŠµŠŗŃ‚ŃƒŃ€Š° вместо ā€ž_arch_ā€œ): +alt.repository = Š˜Š½Ń„Š¾Ń€Š¼Š°Ń†ŠøŃ за хранилището +owner.settings.cargo.initialize.error = ŠŠµŃƒŃŠæŠµŃˆŠ½Š¾ инициализиране на инГекса на Cargo: %v +owner.settings.cargo.initialize = Š˜Š½ŠøŃ†ŠøŠ°Š»ŠøŠ·ŠøŃ€Š°Š½Šµ на инГекс +settings.delete.description = Š˜Š·Ń‚Ń€ŠøŠ²Š°Š½ŠµŃ‚Š¾ на пакет е трайно Šø не може Га бъГе отменено. +alt.repository.multiple_groups = Този пакет е наличен в Š½ŃŠŗŠ¾Š»ŠŗŠ¾ Š³Ń€ŃƒŠæŠø. +alt.repository.architectures = ŠŃ€Ń…ŠøŃ‚ŠµŠŗŃ‚ŃƒŃ€Šø +owner.settings.chef.title = Š ŠµŠ³ŠøŃŃ‚ŃŠŃ€ на Chef +owner.settings.cleanuprules.remove.days = ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ на версии, по-стари от +owner.settings.cleanuprules.keep.pattern = Запазване на версии, ŃŃŠŠ¾Ń‚Š²ŠµŃ‚ŃŃ‚Š²Š°Ń‰Šø на +owner.settings.cleanuprules.keep.count.n = %d версии на пакет +owner.settings.cleanuprules.keep.count.1 = 1 Š²ŠµŃ€ŃŠøŃ на пакет +owner.settings.cleanuprules.keep.count = Запазване на най-новите +owner.settings.cleanuprules.enabled = Š’ŠŗŠ»ŃŽŃ‡ŠµŠ½Š¾ +owner.settings.cleanuprules.preview.none = ŠŸŃ€Š°Š²ŠøŠ»Š¾Ń‚Š¾ за почистване не съвпаГа с нито еГин пакет. +owner.settings.cleanuprules.none = Все още Š½ŃŠ¼Š° правила за почистване. +owner.settings.cleanuprules.add = Š”Š¾Š±Š°Š²ŃŠ½Šµ на правило за почистване +owner.settings.cleanuprules.title = ŠŸŃ€Š°Š²ŠøŠ»Š° за почистване +owner.settings.cargo.rebuild.success = Š˜Š½Š“ŠµŠŗŃŃŠŃ‚ на Cargo беше успешно преизграГен. +alpine.registry.key = Š˜Š·Ń‚ŠµŠ³Š»ŠµŃ‚Šµ ŠæŃƒŠ±Š»ŠøŃ‡Š½ŠøŃ RSA ŠŗŠ»ŃŽŃ‡ на Ń€ŠµŠ³ŠøŃŃ‚ŃŠŃ€Š° в папката /etc/apk/keys/, за Га проверите поГписа на инГекса: +alpine.registry.info = Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ $branch Šø $repository от списъка по-Голу. +arch.version.checkdepends = Зависимости за проверката +composer.dependencies = Зависимости +swift.install = Добавете пакета във Š²Š°ŃˆŠøŃ файл Package.swift: +settings.link.error = ŠŠµŃƒŃŠæŠµŃˆŠ½Š¾ Š¾Š±Š½Š¾Š²ŃŠ²Š°Š½Šµ на Š²Ń€ŃŠŠ·ŠŗŠ°Ń‚а на хранилището. +swift.install2 = Šø ŠøŠ·ŠæŃŠŠ»Š½ŠµŃ‚Šµ слеГната команГа: +rpm.repository.multiple_groups = Този пакет е наличен в Š½ŃŠŗŠ¾Š»ŠŗŠ¾ Š³Ń€ŃƒŠæŠø. +conda.registry = ŠŠ°ŃŃ‚Ń€Š¾Š¹Ń‚Šµ този Ń€ŠµŠ³ŠøŃŃ‚ŃŠŃ€ като Conda хранилище във Š²Š°ŃˆŠøŃ файл .condarc: +conda.install = За Га инсталирате пакета с Conda, ŠøŠ·ŠæŃŠŠ»Š½ŠµŃ‚Šµ слеГната команГа: +owner.settings.cargo.rebuild.error = ŠŠµŃƒŃŠæŠµŃˆŠ½Š¾ преизгражГане на инГекса на Cargo: %v +owner.settings.cargo.rebuild = ŠŸŃ€ŠµŠøŠ·Š³Ń€Š°Š¶Š“Š°Š½Šµ на инГекс +settings.link.button = ŠžŠ±Š½Š¾Š²ŃŠ²Š°Š½Šµ на Š²Ń€ŃŠŠ·ŠŗŠ°Ń‚а на хранилището +settings.link.select = Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ хранилище +debian.repository.architectures = ŠŃ€Ń…ŠøŃ‚ŠµŠŗŃ‚ŃƒŃ€Šø +rpm.registry = ŠŠ°ŃŃ‚Ń€Š¾Š¹Ń‚Šµ този Ń€ŠµŠ³ŠøŃŃ‚ŃŠŃ€ от ŠŗŠ¾Š¼Š°Š½Š“Š½ŠøŃ реГ: +debian.registry = ŠŠ°ŃŃ‚Ń€Š¾Š¹Ń‚Šµ този Ń€ŠµŠ³ŠøŃŃ‚ŃŠŃ€ от ŠŗŠ¾Š¼Š°Š½Š“Š½ŠøŃ реГ: +helm.install = За Га инсталирате пакета, ŠøŠ·ŠæŃŠŠ»Š½ŠµŃ‚Šµ слеГната команГа: +swift.registry = ŠŠ°ŃŃ‚Ń€Š¾Š¹Ń‚Šµ този Ń€ŠµŠ³ŠøŃŃ‚ŃŠŃ€ от ŠŗŠ¾Š¼Š°Š½Š“Š½ŠøŃ реГ: +settings.link = Š”Š²ŃŠŃ€Š·Š²Š°Š½Šµ на този пакет с хранилище +settings.link.description = Ако ŃŠ²ŃŠŃ€Š¶ŠµŃ‚Šµ пакет с хранилище, ŠæŠ°ŠŗŠµŃ‚ŃŠŃ‚ се ŠøŠ·Š±Ń€Š¾ŃŠ²Š° в списъка с пакети на хранилището. +settings.link.success = Š’Ń€ŃŠŠ·ŠŗŠ°Ń‚Š° на хранилището беше успешно обновена. +owner.settings.cleanuprules.pattern_full_match = ŠŸŃ€ŠøŠ»Š°Š³Š°Š½Šµ на шаблона към ŠæŃŠŠ»Š½Š¾Ń‚о име на пакета +owner.settings.cleanuprules.keep.title = Версиите, които ŃŃŠŠ¾Ń‚Š²ŠµŃ‚ŃŃ‚Š²Š°Ń‚ на тези правила, се запазват, Гори ако ŃŃŠŠ¾Ń‚Š²ŠµŃ‚ŃŃ‚Š²Š°Ń‚ на правило за премахване по-Голу. +debian.repository = Š˜Š½Ń„Š¾Ń€Š¼Š°Ń†ŠøŃ за хранилището +maven.install = За Га използвате пакета, Š²ŠŗŠ»ŃŽŃ‡ŠµŃ‚Šµ слеГното в блока dependencies във файла pom.xml: +nuget.install = За Га инсталирате пакета с NuGet, ŠøŠ·ŠæŃŠŠ»Š½ŠµŃ‚Šµ слеГната команГа: +alt.install = Š˜Š½ŃŃ‚Š°Š»ŠøŃ€Š°Š½Šµ на пакет +owner.settings.cleanuprules.edit = РеГактиране на правилото за почистване +rpm.install = За Га инсталирате пакета, ŠøŠ·ŠæŃŠŠ»Š½ŠµŃ‚Šµ слеГната команГа: +pypi.install = За Га инсталирате пакета с pip, ŠøŠ·ŠæŃŠŠ»Š½ŠµŃ‚Šµ слеГната команГа: +arch.version.makedepends = Зависимости за изгражГането +alpine.install = За Га инсталирате пакета, ŠøŠ·ŠæŃŠŠ»Š½ŠµŃ‚Šµ слеГната команГа: +desc = Управление на пакетите на хранилището. +owner.settings.cargo.rebuild.no_index = ŠŠµ може Га се преизграГи, Š½ŃŠ¼Š° инициализиран инГекс. +owner.settings.cargo.rebuild.description = ŠŸŃ€ŠµŠøŠ·Š³Ń€Š°Š¶Š“Š°Š½ŠµŃ‚Š¾ може Га бъГе полезно, ако ŠøŠ½Š“ŠµŠŗŃŃŠŃ‚ не е синхронизиран със ŃŃŠŃ…Ń€Š°Š½ŠµŠ½ŠøŃ‚Šµ Cargo пакети. +owner.settings.cargo.initialize.description = ŠŠµŠ¾Š±Ń…Š¾Š“ŠøŠ¼Š¾ е специално Git хранилище за инГекс, за Га се използва Ń€ŠµŠ³ŠøŃŃ‚ŃŠŃ€ŃŠŃ‚ на Cargo. Š˜Š·ŠæŠ¾Š»Š·Š²Š°Š½ŠµŃ‚Š¾ на тази Š¾ŠæŃ†ŠøŃ ще (пре)съзГаГе хранилището Šø ще го ŠŗŠ¾Š½Ń„ŠøŠ³ŃƒŃ€ŠøŃ€Š° автоматично. +pypi.requires = Изисква Python +debian.registry.info = Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ $distribution Šø $component от списъка по-Голу. +alpine.registry = ŠŠ°ŃŃ‚Ń€Š¾Š¹Ń‚Šµ този Ń€ŠµŠ³ŠøŃŃ‚ŃŠŃ€, като Гобавите URL аГреса във Š²Š°ŃˆŠøŃ файл /etc/apk/repositories: +owner.settings.cargo.initialize.success = Š˜Š½Š“ŠµŠŗŃŃŠŃ‚ на Cargo беше успешно съзГаГен. +npm.registry = ŠŠ°ŃŃ‚Ń€Š¾Š¹Ń‚Šµ този Ń€ŠµŠ³ŠøŃŃ‚ŃŠŃ€ във файла на Š²Š°ŃˆŠøŃ проект .npmrc: +owner.settings.chef.keypair = Генериране на Гвойка ŠŗŠ»ŃŽŃ‡Š¾Š²Šµ +owner.settings.chef.keypair.description = Š—Š°ŃŠ²ŠŗŠøŃ‚Šµ, изпратени Го Ń€ŠµŠ³ŠøŃŃ‚ŃŠŃ€Š° на Chef, Ń‚Ń€ŃŠ±Š²Š° Га Š±ŃŠŠ“ат криптографски поГписани като среГство за ŃƒŠ“Š¾ŃŃ‚Š¾Š²ŠµŃ€ŃŠ²Š°Š½Šµ. ŠŸŃ€Šø генериране на Гвойка ŠŗŠ»ŃŽŃ‡Š¾Š²Šµ, само ŠæŃƒŠ±Š»ŠøŃ‡Š½ŠøŃŃ‚ ŠŗŠ»ŃŽŃ‡ се ŃŃŠŃ…Ń€Š°Š½ŃŠ²Š° във Forgejo. Š§Š°ŃŃ‚Š½ŠøŃŃ‚ ŠŗŠ»ŃŽŃ‡ ви се ŠæŃ€ŠµŠ“Š¾ŃŃ‚Š°Š²Ń, за Га се използва с knife. Генерирането на нова Гвойка ŠŗŠ»ŃŽŃ‡Š¾Š²Šµ ще ŠæŃ€ŠµŠ·Š°ŠæŠøŃˆŠµ ŠæŃ€ŠµŠ“ŠøŃˆŠ½Š°Ń‚Š°. +owner.settings.cleanuprules.remove.title = Версиите, които ŃŃŠŠ¾Ń‚Š²ŠµŃ‚ŃŃ‚Š²Š°Ń‚ на тези правила, се премахват, освен ако правило по-горе не казва Га се Š·Š°ŠæŠ°Š·ŃŃ‚. +nuget.registry = ŠŠ°ŃŃ‚Ń€Š¾Š¹Ń‚Šµ този Ń€ŠµŠ³ŠøŃŃ‚ŃŠŃ€ от ŠŗŠ¾Š¼Š°Š½Š“Š½ŠøŃ реГ: +owner.settings.cleanuprules.success.update = ŠŸŃ€Š°Š²ŠøŠ»Š¾Ń‚Š¾ за почистване е обновено. +settings.delete.notice = ŠŠ° ŠæŃŠŃ‚ сте Га изтриете %s (%s). Тази Š¾ŠæŠµŃ€Š°Ń†ŠøŃ е необратима, ŃŠøŠ³ŃƒŃ€Š½Šø ли сте? +npm.install2 = или го Гобавете във файла package.json: +owner.settings.cleanuprules.success.delete = ŠŸŃ€Š°Š²ŠøŠ»Š¾Ń‚Š¾ за почистване е изтрито. +vagrant.install = За Га Гобавите Vagrant box, ŠøŠ·ŠæŃŠŠ»Š½ŠµŃ‚Šµ слеГната команГа: +nuget.dependency.framework = Целева платформа +maven.install2 = Š˜Š·ŠæŃŠŠ»Š½ŠµŃ‚Šµ през ŠŗŠ¾Š¼Š°Š½Š“Š½ŠøŃ реГ: +maven.download = За Га изтеглите зависимостта, ŠøŠ·ŠæŃŠŠ»Š½ŠµŃ‚Šµ през ŠŗŠ¾Š¼Š°Š½Š“Š½ŠøŃ реГ: +container.layers = Длоеве на образа +conan.install = За Га инсталирате пакета с Conan, ŠøŠ·ŠæŃŠŠ»Š½ŠµŃ‚Šµ слеГната команГа: +composer.registry = ŠŠ°ŃŃ‚Ń€Š¾Š¹Ń‚Šµ този Ń€ŠµŠ³ŠøŃŃ‚ŃŠŃ€ във Š²Š°ŃˆŠøŃ файл ~/.composer/config.json: [tool] hours = %d часа @@ -940,9 +1060,9 @@ editor.no_changes_to_show = ŠŃŠ¼Š° промени за показване. issues.choose.get_started = ŠŸŃŠŃ€Š²Šø ŃŃ‚ŃŠŠæŠŗŠø issues.change_milestone_at = `промени етапа от %s на %s %s` issues.change_project_at = `промени проекта от %s на %s %s` -issues.self_assign_at = `си само-възложи това %s` +issues.self_assign_at = `си самовъзложи това %s` issues.remove_assignee_at = `е премахнат като ŠøŠ·ŠæŃŠŠ»Š½ŠøŃ‚ел от %s %s` -issues.remove_self_assignment = `се само-премахна като ŠøŠ·ŠæŃŠŠ»Š½ŠøŃ‚ел %s` +issues.remove_self_assignment = `се самопремахна като ŠøŠ·ŠæŃŠŠ»Š½ŠøŃ‚ел %s` issues.add_assignee_at = `му бе възложено това от %s %s` pulls.merged_by = от %[3]s бе ŃŠ»ŃŃ‚Š° %[1]s pulls.merged_by_fake = от %[2]s бе ŃŠ»ŃŃ‚Š° %[1]s @@ -1272,7 +1392,7 @@ issues.review.show_resolved = Показване на Ń€ŠµŃˆŠµŠ½Š¾ issues.review.hide_resolved = Дкриване на Ń€ŠµŃˆŠµŠ½Š¾ issues.review.resolve_conversation = Решаване на Š¾Š±ŃŃŠŠ¶Š“ането diff.comment.markdown_info = ŠŸŠ¾Š“Š“ŃŠŃ€Š¶Š° се стилизиране с ŠœŠ°Ń€ŠŗŠ“Š°ŃƒŠ½. -diff.file_suppressed = Разликите не са показани, защото са Ń‚Š²ŃŠŃ€Š“Šµ много +diff.file_suppressed = Разликите във файла са потиснати, защото са Ń‚Š²ŃŠŃ€Š“Šµ много pulls.reject_count_n = %d поискани промени settings.pulls.default_allow_edits_from_maintainers = ŠŸŠ¾Š·Š²Š¾Š»ŃŠ²Š°Š½Šµ на реГакции от ŠæŠ¾Š“Š“ŃŠŃ€Š¶Š°Ń‰ŠøŃ‚Šµ по поГразбиране fork_branch = Клон за клониране в разклонението @@ -1347,7 +1467,7 @@ 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]` +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 = Š’ŃŠŠ·Š»Š°Š³Š°Š½Šµ на мен @@ -1446,7 +1566,7 @@ generated_from = генерирано от clear_ref = `Š˜Š·Ń‡ŠøŃŃ‚Š²Š°Š½Šµ на Ń‚ŠµŠŗŃƒŃ‰Š°Ń‚Š° препратка` file_follow = ПослеГване на символната Š²Ń€ŃŠŠ·ŠŗŠ° commitstatus.failure = ŠŠµŃƒŃŠæŠµŃ… -issues.filter_label_exclude = `Š˜Š·ŠæŠ¾Š»Š·Š²Š°Š¹Ń‚Šµ alt + click/enter, за Га ŠøŠ·ŠŗŠ»ŃŽŃ‡ŠøŃ‚е етикети` +issues.filter_label_exclude = Š˜Š·ŠæŠ¾Š»Š·Š²Š°Š¹Ń‚Šµ Alt + Click, за Га ŠøŠ·ŠŗŠ»ŃŽŃ‡ŠøŃ‚е етикети migrate.migrating_failed = ŠœŠøŠ³Ń€ŠøŃ€Š°Š½ŠµŃ‚Š¾ от %s е неуспешно. migrate.migrating_issues = ŠœŠøŠ³Ń€ŠøŃ€Š°Š½Šµ на заГачи mirror_from = оглеГално на @@ -1575,6 +1695,177 @@ migrate.migrating_failed_no_addr = ŠœŠøŠ³Ń€ŠøŃ€Š°Š½ŠµŃ‚Š¾ е неуспешно. issues.force_push_compare = Š”Ń€Š°Š²Š½ŃŠ²Š°Š½Šµ pulls.status_checking = ŠŃŠŗŠ¾Šø проверки са в очакване pulls.nothing_to_compare = Тези клонове са равни. ŠŠµ е нужно Га ŃŃŠŠ·Š“Š°Š²Š°Ń‚Šµ Š·Š°ŃŠ²ŠŗŠ° за сливане. +admin.flags_replaced = Флаговете на хранилището са заменени +editor.cannot_edit_lfs_files = LFS файлове не могат Га се реГактират в уеб интерфейса. +commits.ssh_key_fingerprint = ŠžŃ‚ŠæŠµŃ‡Š°Ń‚ŃŠŠŗ на SSH ŠŗŠ»ŃŽŃ‡ +issues.comment_on_locked = ŠŠµ можете Га коментирате Š·Š°ŠŗŠ»ŃŽŃ‡ŠµŠ½Š° заГача. +commit.revert = Š’Ń€ŃŠŃ‰Š°Š½Šµ +migrate.cancel_migrating_title = ŠžŃ‚ŠŗŠ°Š· от Š¼ŠøŠ³Ń€Š°Ń†ŠøŃŃ‚Š° +migrate.cancel_migrating_confirm = Š˜ŃŠŗŠ°Ń‚Šµ ли Га откажете тази Š¼ŠøŠ³Ń€Š°Ń†ŠøŃ? +issues.choose.invalid_config = ŠšŠ¾Š½Ń„ŠøŠ³ŃƒŃ€Š°Ń†ŠøŃŃ‚Š° на заГачите ŃŃŠŠ“ŃŠŃ€Š¶Š° Š³Ń€ŠµŃˆŠŗŠø: +unit_disabled = ŠŠ“Š¼ŠøŠ½ŠøŃŃ‚Ń€Š°Ń‚Š¾Ń€ŃŠŃ‚ на сайта е ŠøŠ·ŠŗŠ»ŃŽŃ‡ŠøŠ» тази ŃŠµŠŗŃ†ŠøŃ на хранилището. +issues.blocked_by_user = ŠŠµ можете Га ŃŃŠŠ·Š“Š°Š²Š°Ń‚Šµ заГачи в това хранилище, защото сте блокирани от ŠæŃ€ŠøŃ‚ŠµŠ¶Š°Ń‚ŠµŠ»Ń на хранилището. +commits.signed_by = ПоГписано от +commits.signed_by_untrusted_user = ПоГписано от неГоверен потребител +commits.signed_by_untrusted_user_unmatched = ПоГписано от неГоверен потребител, който не съвпаГа с ŠæŠ¾Š“Š°Š²Š°Ń‰ŠøŃ +issues.lock.notice_1 = - Š”Ń€ŃƒŠ³Šø потребители не могат Га Š“Š¾Š±Š°Š²ŃŃ‚ нови коментари към тази заГача. +issues.unlock.notice_2 = - Винаги можете Га Š·Š°ŠŗŠ»ŃŽŃ‡ŠøŃ‚е тази заГача отново в Š±ŃŠŠ“еще. +issues.unlock.title = ŠžŃ‚ŠŗŠ»ŃŽŃ‡Š²Š°Š½Šµ на Š¾Š±ŃŃŠŠ¶Š“ането по тази заГача. +issues.dependency.no_permission_1 = ŠŃŠ¼Š°Ń‚Šµ Ń€Š°Š·Ń€ŠµŃˆŠµŠ½ŠøŠµ Га прочетете %d зависимост +issues.reopen.blocked_by_user = ŠŠµ можете Га отворите наново тази заГача, защото сте блокирани от ŠæŃ€ŠøŃ‚ŠµŠ¶Š°Ń‚ŠµŠ»Ń на хранилището или от автора на тази заГача. +compare.compare_base = основа +compare.compare_head = ŃŃ€Š°Š²Š½ŃŠ²Š°Š½Šµ +template.one_item = Š¢Ń€ŃŠ±Š²Š° Га изберете поне еГин елемент от шаблона +admin.failed_to_replace_flags = ŠŠµŃƒŃŠæŠµŃˆŠ½Š° Š·Š°Š¼ŃŠ½Š° на флаговете на хранилището +mirror_interval_invalid = Š˜Š½Ń‚ŠµŃ€Š²Š°Š»ŃŠŃ‚ на оглеГалото не е валиГен. +mirror_use_ssh.not_available = SSH ŃƒŠ“Š¾ŃŃ‚Š¾Š²ŠµŃ€ŃŠ²Š°Š½ŠµŃ‚Š¾ не е налично. +mirror_address_desc = ŠŸŠ¾ŃŃ‚Š°Š²ŠµŃ‚Šµ всички необхоГими Ганни за ŃƒŠ“Š¾ŃŃ‚Š¾Š²ŠµŃ€ŃŠ²Š°Š½Šµ в ŃŠµŠŗŃ†ŠøŃŃ‚Š° ā€žŠ£ŠæŃŠŠ»Š½Š¾Š¼Š¾Ń‰Š°Š²Š°Š½Šµā€œ. +template.git_hooks = Git куки +template.invalid = Š¢Ń€ŃŠ±Š²Š° Га изберете шаблонно хранилище +issues.review.outdated = ŠžŃŃ‚Š°Ń€ŃŠ» +issues.dependency.add_error_dep_issue_not_exist = Зависимата заГача не ŃŃŠŃ‰ŠµŃŃ‚Š²ŃƒŠ²Š°. +template.items = Елементи на шаблона +issues.review.dismissed = Š¾Ń‚Ń…Š²ŃŠŃ€Š»Šø Ń€ŠµŃ†ŠµŠ½Š·ŠøŃŃ‚Š° на %s %s +audio_not_supported_in_browser = Š’Š°ŃˆŠøŃŃ‚ Š±Ń€Š°ŃƒŠ·ŃŠŃ€ не ŠæŠ¾Š“Š“ŃŠŃ€Š¶Š° HTML5 тага ā€žaudioā€œ. +stored_lfs = Š”ŃŠŃ…Ń€Š°Š½ŠµŠ½Š¾ с Git LFS +commit_graph.select = Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ клонове +issues.content_history.options = ŠžŠæŃ†ŠøŠø +editor.commit_email = Ел. поща на поГаването +commit.revert-header = Š’Ń€ŃŠŃ‰Š°Š½Šµ: %s +commits.desc = РазглежГане на ŠøŃŃ‚Š¾Ń€ŠøŃŃ‚Š° на промените в ŠæŃ€Š¾Š³Ń€Š°Š¼Š½ŠøŃ коГ. +commits.search.tooltip = ŠœŠ¾Š¶ŠµŃ‚Šµ Га Гобавите префикс към ŠŗŠ»ŃŽŃ‡Š¾Š²ŠøŃ‚е Гуми с ā€žauthor:ā€œ, ā€žcommitter:ā€œ, ā€žafter:ā€œ или ā€žbefore:ā€œ, напр. ā€žrevert author:Alice before:2019-01-13ā€œ. +issues.unlock_error = ŠŠµ може Га се Š¾Ń‚ŠŗŠ»ŃŽŃ‡Šø заГача, ŠŗŠ¾ŃŃ‚Š¾ не е Š·Š°ŠŗŠ»ŃŽŃ‡ŠµŠ½Š°. +issues.lock.unknown_reason = ŠŠµ може Га се Š·Š°ŠŗŠ»ŃŽŃ‡Šø заГача с неизвестна причина. +issues.cancel_tracking_history = `отмени ŠæŃ€Š¾ŃŠ»ŠµŠ“ŃŠ²Š°Š½ŠµŃ‚Š¾ на времето %s` +issues.dependency.add_error_dep_not_same_repo = И Гвете заГачи Ń‚Ń€ŃŠ±Š²Š° Га са в еГно Šø ŃŃŠŃ‰Š¾ хранилище. +issues.review.remove_review_requests = премахна Š·Š°ŃŠ²ŠŗŠøŃ‚е за Ń€ŠµŃ†ŠµŠ½Š·ŠøŃ за %[1]s %[2]s +issues.review.content.empty = Š¢Ń€ŃŠ±Š²Š° Га оставите коментар, посочващ исканите промени. +issues.review.hide_outdated = Дкриване на остарели +pulls.desc = Š’ŠŗŠ»ŃŽŃ‡Š²Š°Š½Šµ на Š·Š°ŃŠ²ŠŗŠø за сливане Šø рецензии на коГ. +issues.review.show_outdated = Показване на остарели +ambiguous_runes_header = `Този файл ŃŃŠŠ“ŃŠŃ€Š¶Š° Гвусмислени УникоГ знаци` +admin.update_flags = ŠžŠ±Š½Š¾Š²ŃŠ²Š°Š½Šµ на флаговете +issues.dependency.blocked_by_short = Зависи от +mirror_lfs = Š”ŃŠŃ…Ń€Š°Š½ŠµŠ½ŠøŠµ на големи файлове (LFS) +mirror_use_ssh.text = Използване на SSH ŃƒŠ“Š¾ŃŃ‚Š¾Š²ŠµŃ€ŃŠ²Š°Š½Šµ +mirror_denied_combination = ŠŠµ може Га се използва ŃƒŠ“Š¾ŃŃ‚Š¾Š²ŠµŃ€ŃŠ²Š°Š½Šµ с ŠæŃƒŠ±Š»ŠøŃ‡ŠµŠ½ ŠŗŠ»ŃŽŃ‡ Šø парола еГновременно. +rss.must_be_on_branch = Š¢Ń€ŃŠ±Š²Š° Га сте на клон, за Га имате RSS ŠµŠ¼ŠøŃŠøŃ. +admin.manage_flags = Управление на флаговете +admin.enabled_flags = Флагове, Š²ŠŗŠ»ŃŽŃ‡ŠµŠ½Šø за хранилището: +mirror_password_help = ŠŸŃ€Š¾Š¼ŠµŠ½ŠµŃ‚Šµ потребителското име, за Га изтриете запазена парола. +issues.review.remove_review_request = премахна Š·Š°ŃŠ²ŠŗŠ°Ń‚а за Ń€ŠµŃ†ŠµŠ½Š·ŠøŃ за %[1]s %[2]s +issues.review.outdated_description = Š”ŃŠŠ“ŃŠŃ€Š¶Š°Š½ŠøŠµŃ‚Š¾ е променено, слеГ като е направен този коментар +issues.dependency.setting = Š’ŠŗŠ»ŃŽŃ‡Š²Š°Š½Šµ на зависимости за заГачи Šø Š·Š°ŃŠ²ŠŗŠø за сливане +issues.dependency.add_error_same_issue = ŠŠµ можете Га направите заГача зависима от самата Š½ŠµŃ. +issues.review.self.rejection = ŠŠµ можете Га поискате промени в собствената си Š·Š°ŃŠ²ŠŗŠ° за сливане. +issues.filter_type.all_pull_requests = Всички Š·Š°ŃŠ²ŠŗŠø за сливане +fork_to_different_account = Š Š°Š·ŠŗŠ»Š¾Š½ŃŠ²Š°Š½Šµ в Š“Ń€ŃƒŠ³ Š°ŠŗŠ°ŃƒŠ½Ń‚ +mirror_sync_on_commit = Динхронизиране при изтласкване на ŠæŠ¾Š“Š°Š²Š°Š½ŠøŃ +mirror_address_protocol_invalid = ŠŸŃ€ŠµŠ“Š¾ŃŃ‚Š°Š²ŠµŠ½ŠøŃŃ‚ URL е невалиГен. Дамо http(s):// или git:// аГреси могат Га се използват за оглеГални хранилища. +template.git_hooks_tooltip = Š’ момента не можете Га ŠæŃ€Š¾Š¼ŠµŠ½ŃŃ‚е или премахвате Git куки, слеГ като са Гобавени. Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ това само ако се Š“Š¾Š²ŠµŃ€ŃŠ²Š°Ń‚Šµ на ŃˆŠ°Š±Š»Š¾Š½Š½Š¾Ń‚Š¾ хранилище. +editor.commit_signed_changes = ПоГаване на поГписани промени +editor.require_signed_commit = ŠšŠ»Š¾Š½ŃŠŃ‚ изисква поГписано поГаване +issues.desc = ŠžŃ€Š³Š°Š½ŠøŠ·ŠøŃ€Š°Š¹Ń‚Šµ ГоклаГи за Š³Ń€ŠµŃˆŠŗŠø, заГачи Šø етапи. +issues.lock_duplicate = ЗаГача не може Га бъГе Š·Š°ŠŗŠ»ŃŽŃ‡ŠµŠ½Š° Гва ŠæŃŠŃ‚Šø. +issues.lock.notice_2 = - Вие Šø Š“Ń€ŃƒŠ³Šø ŃŃŠŃ‚Ń€ŃƒŠ“Š½ŠøŃ†Šø с Š“Š¾ŃŃ‚ŃŠŠæ Го това хранилище все още можете Га Š¾ŃŃ‚Š°Š²ŃŃ‚Šµ коментари, които Š“Ń€ŃƒŠ³ŠøŃ‚Šµ Га вижГат. +issues.due_date_invalid = ŠšŃ€Š°Š¹Š½ŠøŃŃ‚ срок е невалиГен или извън обхвата. ŠœŠ¾Š»Ń, използвайте формата ā€žŠ³Š³Š³Š³-мм-Š“Š“ā€œ. +mirror_interval = Š˜Š½Ń‚ŠµŃ€Š²Š°Š» на оглеГалото (валиГни еГиници за време са ā€žhā€œ, ā€žmā€œ, ā€žsā€œ). 0 за ŠøŠ·ŠŗŠ»ŃŽŃ‡Š²Š°Š½Šµ на периоГичната ŃŠøŠ½Ń…Ń€Š¾Š½ŠøŠ·Š°Ń†ŠøŃ. (Минимален интервал: %s) +summary_card_alt = ŠšŠ°Ń€Ń‚Š° с обобщение на хранилище %s +file_copy_permalink = ŠšŠ¾ŠæŠøŃ€Š°Š½Šµ на ŠæŠ¾ŃŃ‚Š¾ŃŠ½Š½Š° Š²Ń€ŃŠŠ·ŠŗŠ° +view_git_blame = ŠŸŃ€ŠµŠ³Š»ŠµŠ“ на git blame +commit.revert-content = Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ клон, Š²ŃŠŃ€Ń…Ńƒ който Га се Š²ŃŠŃ€Š½Šµ: +issues.unlock.notice_1 = - Всеки ще може отново Га коментира тази заГача. +issues.delete.text = ŠŠ°ŠøŃŃ‚ŠøŠ½Š° ли искате Га изтриете тази заГача? (Това ще премахне трайно Ń†ŃŠ»Š¾Ń‚Š¾ ŃŃŠŠ“ŃŠŃ€Š¶Š°Š½ŠøŠµ. ŠŸŠ¾Š¼ŠøŃŠ»ŠµŃ‚Šµ Гали вместо това Га не я затворите, ако Š²ŃŠŠ·Š½Š°Š¼ŠµŃ€ŃŠ²Š°Ń‚е Га я запазите архивирана) +issues.add_time_sum_to_small = ŠŠµ е въвеГено време. +issues.dependency.no_permission_n = ŠŃŠ¼Š°Ń‚Šµ Ń€Š°Š·Ń€ŠµŃˆŠµŠ½ŠøŠµ Га прочетете %d зависимости +issues.review.pending.tooltip = Този коментар в момента не е виГим за Š“Ń€ŃƒŠ³Šø потребители. За Га изпратите изчакващите си коментари, изберете ā€ž%sā€œ -> ā€ž%s/%s/%sā€œ в горната част на страницата. +invisible_runes_description = `Този файл ŃŃŠŠ“ŃŠŃ€Š¶Š° невиГими УникоГ знаци, които са неразличими за хората, но могат Га Š±ŃŠŠ“ат обработени по различен начин от ŠŗŠ¾Š¼ŠæŃŽŃ‚ŃŠŃ€. Ако ŃŠ¼ŃŃ‚Š°Ń‚Šµ, че това е умишлено, можете спокойно Га пренебрегнете това ŠæŃ€ŠµŠ“ŃƒŠæŃ€ŠµŠ¶Š“ŠµŠ½ŠøŠµ. Š˜Š·ŠæŠ¾Š»Š·Š²Š°Š¹Ń‚Šµ Š±ŃƒŃ‚Š¾Š½Š° ā€žŠ•ŠŗŃ€Š°Š½ŠøŃ€Š°Š½Šµā€œ, за Га ги разкриете.` +video_not_supported_in_browser = Š’Š°ŃˆŠøŃŃ‚ Š±Ń€Š°ŃƒŠ·ŃŠŃ€ не ŠæŠ¾Š“Š“ŃŠŃ€Š¶Š° HTML5 тага ā€žvideoā€œ. +editor.filename_help = Добавете Š“ŠøŃ€ŠµŠŗŃ‚Š¾Ń€ŠøŃ, като Š²ŃŠŠ²ŠµŠ“ете името ѝ, послеГвано от наклонена черта (ā€ž/ā€œ). ŠŸŃ€ŠµŠ¼Š°Ń…Š½ŠµŃ‚Šµ Š“ŠøŃ€ŠµŠŗŃ‚Š¾Ń€ŠøŃ, като натиснете backspace в началото на полето за въвежГане. +commits.view_single_diff = ŠŸŃ€ŠµŠ³Š»ŠµŠ“ на промените в този файл, въвеГени в това поГаване +issues.choose.ignore_invalid_templates = ŠŠµŠ²Š°Š»ŠøŠ“Š½ŠøŃ‚Šµ шаблони са игнорирани +issues.due_date_form = гггг-мм-ГГ +issues.dependency.no_permission.can_remove = ŠŃŠ¼Š°Ń‚Šµ Ń€Š°Š·Ń€ŠµŃˆŠµŠ½ŠøŠµ Га прочетете тази зависимост, но можете Га я премахнете +issues.review.remove_review_request_self = отказа Га рецензира %s +mirror_use_ssh.helper = Forgejo ще съзГаГе оглеГало на хранилището чрез Git през SSH Šø ще генерира Гвойка ŠŗŠ»ŃŽŃ‡Š¾Š²Šµ за вас, когато изберете тази Š¾ŠæŃ†ŠøŃ. Š¢Ń€ŃŠ±Š²Š° Га се ŃƒŠ²ŠµŃ€ŠøŃ‚Šµ, че Š³ŠµŠ½ŠµŃ€ŠøŃ€Š°Š½ŠøŃŃ‚ ŠæŃƒŠ±Š»ŠøŃ‡ŠµŠ½ ŠŗŠ»ŃŽŃ‡ е ŃƒŠæŃŠŠ»Š½Š¾Š¼Š¾Ń‰ŠµŠ½ Га изтласква към целевото хранилище. ŠŠµ можете Га използвате ŃƒŠ“Š¾ŃŃ‚Š¾Š²ŠµŃ€ŃŠ²Š°Š½Šµ, базирано на парола, когато избирате това. +mirror_address_url_invalid = ŠŸŃ€ŠµŠ“Š¾ŃŃ‚Š°Š²ŠµŠ½ŠøŃŃ‚ URL е невалиГен. Š¢Ń€ŃŠ±Š²Š° Га екранирате правилно всички компоненти на URL аГреса. +template.git_content = Git ŃŃŠŠ“ŃŠŃ€Š¶Š°Š½ŠøŠµ (станГартен клон) +ambiguous_runes_description = `Този файл ŃŃŠŠ“ŃŠŃ€Š¶Š° УникоГ знаци, които могат Га Š±ŃŠŠ“ат Š¾Š±ŃŠŃ€ŠŗŠ°Š½Šø с Š“Ń€ŃƒŠ³Šø знаци. Ако ŃŠ¼ŃŃ‚Š°Ń‚Šµ, че това е умишлено, можете спокойно Га пренебрегнете това ŠæŃ€ŠµŠ“ŃƒŠæŃ€ŠµŠ¶Š“ŠµŠ½ŠøŠµ. Š˜Š·ŠæŠ¾Š»Š·Š²Š°Š¹Ń‚Šµ Š±ŃƒŃ‚Š¾Š½Š° ā€žŠ•ŠŗŃ€Š°Š½ŠøŃ€Š°Š½Šµā€œ, за Га ги разкриете.` +issues.lock.notice_3 = - Винаги можете Га Š¾Ń‚ŠŗŠ»ŃŽŃ‡ŠøŃ‚Šµ тази заГача отново в Š±ŃŠŠ“еще. +issues.lock.title = Š—Š°ŠŗŠ»ŃŽŃ‡Š²Š°Š½Šµ на Š¾Š±ŃŃŠŠ¶Š“ането по тази заГача. +issues.dependency.issue_batch_close_blocked = ŠŠµ могат Га Š±ŃŠŠ“ат затворени Š³Ń€ŃƒŠæŠ¾Š²Š¾ избраните заГачи, защото заГача #%d все още има отворени зависимости +issues.dependency.add_error_cannot_create_circular = ŠŠµ можете Га ŃŃŠŠ·Š“Š°Š“ŠµŃ‚Šµ зависимост с Гве заГачи, които се блокират взаимно. +issues.review.add_review_requests = поиска рецензии от %[1]s %[2]s +comment.blocked_by_user = ŠšŠ¾Š¼ŠµŠ½Ń‚ŠøŃ€Š°Š½ŠµŃ‚Š¾ не е възможно, защото сте блокирани от ŠæŃ€ŠøŃ‚ŠµŠ¶Š°Ń‚ŠµŠ»Ń на хранилището или от автора. +pulls.view = ŠŸŃ€ŠµŠ³Š»ŠµŠ“ на Š·Š°ŃŠ²ŠŗŠ°Ń‚а за сливане +pulls.no_merge_desc = Тази Š·Š°ŃŠ²ŠŗŠ° за сливане не може Га бъГе ŃŠ»ŃŃ‚Š°, защото всички опции за сливане в хранилището са ŠøŠ·ŠŗŠ»ŃŽŃ‡ŠµŠ½Šø. +pulls.no_merge_wip = Тази Š·Š°ŃŠ²ŠŗŠ° за сливане не може Га бъГе ŃŠ»ŃŃ‚Š°, защото е Š¾Ń‚Š±ŠµŠ»ŃŠ·Š°Š½Š° като в процес на работа. +pulls.switch_comparison_type = ŠŸŃ€ŠµŠ²ŠŗŠ»ŃŽŃ‡Š²Š°Š½Šµ на типа сравнение +pulls.has_changed_since_last_review = ŠŸŃ€Š¾Š¼ŠµŠ½ŠµŠ½Š¾ слеГ послеГната ви Ń€ŠµŃ†ŠµŠ½Š·ŠøŃ +pulls.filter_branch = Филтриране на клон +pulls.squash_merge_pull_request = ДъзГаване на сплескано поГаване +pulls.rebase_conflict_summary = Š”ŃŠŠ¾Š±Ń‰ŠµŠ½ŠøŠµ за Š³Ń€ŠµŃˆŠŗŠ° +pulls.auto_merge_button_when_succeed = (ŠšŠ¾Š³Š°Ń‚Š¾ проверките са успешни) +pulls.auto_merge_newly_scheduled_comment = `насрочи тази Š·Š°ŃŠ²ŠŗŠ° за сливане за автоматично сливане, когато всички проверки са успешни %[1]s` +pulls.auto_merge_canceled_schedule_comment = `отмени автоматичното сливане на тази Š·Š°ŃŠ²ŠŗŠ° за сливане, когато всички проверки са успешни %[1]s` +pulls.merge_manually = Š ŃŠŃ‡Š½Š¾ ŃŠ»ŃŃ‚Š° +pulls.merge_commit_id = ID на поГаването със сливане +pulls.require_signed_wont_sign = ŠšŠ»Š¾Š½ŃŠŃ‚ изисква поГписани ŠæŠ¾Š“Š°Š²Š°Š½ŠøŃ, но това сливане Š½ŃŠ¼Š° Га бъГе поГписано +pulls.no_merge_helper = Š’ŠŗŠ»ŃŽŃ‡ŠµŃ‚Šµ опциите за сливане в настройките на хранилището или слейте Š·Š°ŃŠ²ŠŗŠ°Ń‚а за сливане Ń€ŃŠŃ‡Š½Š¾. +pulls.review_only_possible_for_full_diff = Рецензирането е възможно само при преглеГ на ŠæŃŠŠ»Š½ŠøŃ‚е разлики +pulls.push_rejected = Š˜Š·Ń‚Š»Š°ŃŠŗŠ²Š°Š½ŠµŃ‚Š¾ е неуспешно: Š˜Š·Ń‚Š»Š°ŃŠŗŠ²Š°Š½ŠµŃ‚Š¾ е Š¾Ń‚Ń…Š²ŃŠŃ€Š»ŠµŠ½Š¾. ŠŸŃ€ŠµŠ³Š»ŠµŠ“Š°Š¹Ń‚Šµ Git ŠŗŃƒŠŗŠøŃ‚Šµ за това хранилище. +pulls.auto_merge_canceled_schedule = Автоматичното сливане е отменено за тази Š·Š°ŃŠ²ŠŗŠ° за сливане. +pulls.allow_edits_from_maintainers_err = ŠžŠ±Š½Š¾Š²ŃŠ²Š°Š½ŠµŃ‚Š¾ е неуспешно +pulls.auto_merge_cancel_schedule = ŠžŃ‚Š¼ŃŠ½Š° на автоматичното сливане +pulls.auto_merge_not_scheduled = Тази Š·Š°ŃŠ²ŠŗŠ° за сливане не е насрочена за автоматично сливане. +pulls.outdated_with_base_branch = Този клон е Š¾ŃŃ‚Š°Ń€ŃŠ» ŃŠæŃ€ŃŠ¼Š¾ Š¾ŃŠ½Š¾Š²Š½ŠøŃ клон +pulls.update_not_allowed = ŠŃŠ¼Š°Ń‚Šµ Ń€Š°Š·Ń€ŠµŃˆŠµŠ½ŠøŠµ Га Š¾Š±Š½Š¾Š²ŃŠ²Š°Ń‚е клона +pulls.wrong_commit_id = ID на поГаването Ń‚Ń€ŃŠ±Š²Š° Га бъГе ID на поГаване в Ń†ŠµŠ»ŠµŠ²ŠøŃ клон +pulls.blocked_by_user = ŠŠµ можете Га ŃŃŠŠ·Š“Š°Š“ŠµŃ‚Šµ Š·Š°ŃŠ²ŠŗŠ° за сливане в това хранилище, защото сте блокирани от ŠæŃ€ŠøŃ‚ŠµŠ¶Š°Ń‚ŠµŠ»Ń на хранилището. +pulls.merge_conflict_summary = Š”ŃŠŠ¾Š±Ń‰ŠµŠ½ŠøŠµ за Š³Ń€ŠµŃˆŠŗŠ° +pulls.editable_explanation = Тази Š·Š°ŃŠ²ŠŗŠ° за сливане ŠæŠ¾Š·Š²Š¾Š»ŃŠ²Š° реГакции от ŠæŠ¾Š“Š“ŃŠŃ€Š¶Š°Ń‰ŠøŃ‚Šµ. ŠœŠ¾Š¶ŠµŃ‚Šµ Га Гопринесете Гиректно към Š½ŠµŃ. +pulls.allow_edits_from_maintainers_desc = ŠŸŠ¾Ń‚Ń€ŠµŠ±ŠøŃ‚ŠµŠ»Šø с право на запис в Š¾ŃŠ½Š¾Š²Š½ŠøŃ клон могат ŃŃŠŃ‰Š¾ Га изтласкват към този клон +pulls.merge_conflict = Дливането е неуспешно: Š’ŃŠŠ·Š½ŠøŠŗŠ½Š° конфликт по време на сливането. ПоГсказка: ŠžŠæŠøŃ‚Š°Š¹Ń‚Šµ различна ŃŃ‚Ń€Š°Ń‚ŠµŠ³ŠøŃ +pulls.has_merged = ŠŠµŃƒŃŠæŠµŃˆŠ½Š¾: Š—Š°ŃŠ²ŠŗŠ°Ń‚Š° за сливане е ŃŠ»ŃŃ‚Š°, не можете Га слеете отново или Га промените Ń†ŠµŠ»ŠµŠ²ŠøŃ клон. +pulls.cmd_instruction_merge_warning = ŠŸŃ€ŠµŠ“ŃƒŠæŃ€ŠµŠ¶Š“ŠµŠ½ŠøŠµ: ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠ°Ń‚Š° ā€žŠŠ²Ń‚Š¾Š¼Š°Ń‚ŠøŃ‡Š½Š¾ откриване на Ń€ŃŠŃ‡Š½Š¾ ŃŠ»ŠøŠ²Š°Š½Šµā€œ не е Š²ŠŗŠ»ŃŽŃ‡ŠµŠ½Š° за това хранилище, ще Ń‚Ń€ŃŠ±Š²Š° Га отбележите тази Š·Š°ŃŠ²ŠŗŠ° за сливане като Ń€ŃŠŃ‡Š½Š¾ ŃŠ»ŃŃ‚Š° слеГ това. +pulls.delete.title = Да се изтрие ли тази Š·Š°ŃŠ²ŠŗŠ° за сливане? +pulls.push_rejected_no_message = Š˜Š·Ń‚Š»Š°ŃŠŗŠ²Š°Š½ŠµŃ‚Š¾ е неуспешно: Š˜Š·Ń‚Š»Š°ŃŠŗŠ²Š°Š½ŠµŃ‚Š¾ е Š¾Ń‚Ń…Š²ŃŠŃ€Š»ŠµŠ½Š¾, но Š½ŃŠ¼Š° отГалечено ŃŃŠŠ¾Š±Ń‰ŠµŠ½ŠøŠµ. ŠŸŃ€ŠµŠ³Š»ŠµŠ“Š°Š¹Ń‚Šµ Git ŠŗŃƒŠŗŠøŃ‚Šµ за това хранилище +pulls.auto_merge_newly_scheduled = Š—Š°ŃŠ²ŠŗŠ°Ń‚Š° за сливане е насрочена за сливане, когато всички проверки са успешни. +pulls.delete.text = ŠŠ°ŠøŃŃ‚ŠøŠ½Š° ли искате Га изтриете тази Š·Š°ŃŠ²ŠŗŠ° за сливане? (Това ще премахне трайно Ń†ŃŠ»Š¾Ń‚Š¾ ŃŃŠŠ“ŃŠŃ€Š¶Š°Š½ŠøŠµ. ŠŸŠ¾Š¼ŠøŃŠ»ŠµŃ‚Šµ Гали вместо това Га не я затворите, ако Š²ŃŠŠ·Š½Š°Š¼ŠµŃ€ŃŠ²Š°Ń‚е Га я запазите архивирана) +pulls.auto_merge_has_pending_schedule = %[1]s насрочи тази Š·Š°ŃŠ²ŠŗŠ° за сливане за автоматично сливане, когато всички проверки са успешни %[2]s. +pulls.auto_merge_when_succeed = Автоматично сливане, когато всички проверки са успешни +error.csv.invalid_field_count = ŠŠµ може Га се Š²ŠøŠ·ŃƒŠ°Š»ŠøŠ·ŠøŃ€Š° този файл, защото има Š³Ń€ŠµŃˆŠµŠ½ брой полета на реГ %d. +diff.bin = Š”Š’ŠžŠ˜Š§Š•Š +release.add_tag_msg = Използване на заглавието Šø ŃŃŠŠ“ŃŠŃ€Š¶Š°Š½ŠøŠµŃ‚Š¾ на изГанието като ŃŃŠŠ¾Š±Ń‰ŠµŠ½ŠøŠµ на маркера. +release.hide_archive_links_helper = Дкрийте автоматично генерираните архиви с програмен коГ за това изГание. ŠŠ°ŠæŃ€ŠøŠ¼ŠµŃ€, ако качвате свои собствени. +diff.data_not_available = Š”ŃŠŠ“ŃŠŃ€Š¶Š°Š½ŠøŠµŃ‚Š¾ на разликите не е налично +diff.has_escaped = Този реГ има скрити УникоГ знаци +branch.protected_deletion_failed = ŠšŠ»Š¾Š½ŃŠŃ‚ ā€ž%sā€œ е защитен. ŠŠµ може Га бъГе изтрит. +branch.default_deletion_failed = ŠšŠ»Š¾Š½ŃŠŃ‚ ā€ž%sā€œ е ŃŃ‚Š°Š½Š“Š°Ń€Ń‚Š½ŠøŃŃ‚ клон. ŠŠµ може Га бъГе изтрит. +diff.generated = генериран +diff.comment.add_line_comment = Š”Š¾Š±Š°Š²ŃŠ½Šµ на коментар към реГ +diff.comment.add_review_comment = Š”Š¾Š±Š°Š²ŃŠ½Šµ на коментар +diff.review.self_approve = Авторите на Š·Š°ŃŠ²ŠŗŠø за сливане не могат Га Š¾Š“Š¾Š±Ń€ŃŠ²Š°Ń‚ собствените си Š·Š°ŃŠ²ŠŗŠø +release.tag_name_protected = Š˜Š¼ŠµŃ‚Š¾ на маркера е защитено. +branch.warning_rename_default_branch = ŠŸŃ€ŠµŠøŠ¼ŠµŠ½ŃƒŠ²Š°Ń‚Šµ ŃŃ‚Š°Š½Š“Š°Ń€Ń‚Š½ŠøŃ клон. +find_file.no_matching = ŠŠµ е намерен ŃŃŠŠ²ŠæŠ°Š“Š°Ń‰ файл +issues.role.member_helper = Този потребител е ŃƒŃ‡Š°ŃŃ‚Š½ŠøŠŗ в Š¾Ń€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃŃ‚а, притежаваща това хранилище. +diff.image.overlay = ŠŠ°ŃŠ»Š°Š³Š²Š°Š½Šµ +diff.image.swipe = Плъзгане +branch.included = Š’ŠŗŠ»ŃŽŃ‡ŠµŠ½ +diff.file_suppressed_line_too_long = Разликите във файла са потиснати, защото еГин или повече реГове са Ń‚Š²ŃŠŃ€Š“Šµ Гълги +error.broken_git_hook = Git ŠŗŃƒŠŗŠøŃ‚Šµ на това хранилище изглежГат повреГени. ŠœŠ¾Š»Ń, послеГвайте Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†ŠøŃŃ‚Š°, за Га ги поправите, слеГ което изтласкайте ŠæŠ¾Š“Š°Š²Š°Š½ŠøŃ, за Га обновите ŃŃ‚Š°Ń‚ŃƒŃŠ°. +error.csv.unexpected = ŠŠµ може Га се Š²ŠøŠ·ŃƒŠ°Š»ŠøŠ·ŠøŃ€Š° този файл, защото ŃŃŠŠ“ŃŠŃ€Š¶Š° неочакван знак на реГ %d Šø колона %d. +topic.count_prompt = ŠŠµ можете Га изберете повече от 25 теми +release.hide_archive_links = Дкриване на автоматично генерираните архиви +diff.show_more = Показване на още +diff.too_many_files = ŠŃŠŗŠ¾Šø файлове не Š±ŃŃ…а показани, защото Ń‚Š²ŃŠŃ€Š“Šµ много файлове имат промени в тези разлики +diff.review.self_reject = Авторите на Š·Š°ŃŠ²ŠŗŠø за сливане не могат Га поискват промени в собствените си Š·Š°ŃŠ²ŠŗŠø +branch.included_desc = Този клон е част от ŃŃ‚Š°Š½Š“Š°Ń€Ń‚Š½ŠøŃ клон +diff.image.side_by_side = ЕГно Го Š“Ń€ŃƒŠ³Š¾ +release.summary_card_alt = ŠšŠ°Ń€Ń‚Š° с обобщение на изГание със заглавие ā€ž%sā€œ в хранилище %s +release.asset_external_url = Š’ŃŠŠ½ŃˆŠµŠ½ URL аГрес +error.csv.too_large = ŠŠµ може Га се Š²ŠøŠ·ŃƒŠ°Š»ŠøŠ·ŠøŃ€Š° този файл, защото е Ń‚Š²ŃŠŃ€Š“Šµ Š³Š¾Š»ŃŠ¼. [modal] confirm = ŠŸŠ¾Ń‚Š²ŃŠŃ€Š¶Š“Š°Š²Š°Š½Šµ @@ -1663,18 +1954,18 @@ follow_blocked_user = ŠŠµ можете Га слеГвате тази орга settings.delete_prompt = ŠžŃ€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃŃ‚Š° ще бъГе премахната завинаги. Това ŠŠ• ŠœŠžŠ–Š• Га бъГе отменено! settings.labels_desc = Добавете етикети, които могат Га се използват за заГачи за всички хранилища в тази Š¾Ń€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃ. teams.none_access = Без Š“Š¾ŃŃ‚ŃŠŠæ -teams.members.none = ŠŃŠ¼Š° членове в този екип. +teams.members.none = ŠŃŠ¼Š° ŃƒŃ‡Š°ŃŃ‚Š½ŠøŃ†Šø в този екип. repo_updated = ŠžŠ±Š½Š¾Š²ŠµŠ½Š¾ %s teams.delete_team_success = Š•ŠŗŠøŠæŃŠŃ‚ е изтрит. teams.search_repo_placeholder = ŠŸŠ¾Ń‚ŃŠŃ€ŃŠµŃ‚Šµ хранилище… teams.delete_team_title = Š˜Š·Ń‚Ń€ŠøŠ²Š°Š½Šµ на екипа -teams.add_team_member = Š”Š¾Š±Š°Š²ŃŠ½Šµ на член на екипа +teams.add_team_member = Š”Š¾Š±Š°Š²ŃŠ½Šµ на ŃƒŃ‡Š°ŃŃ‚Š½ŠøŠŗ в екипа teams.read_access_helper = Членовете могат Га преглежГат Šø клонират хранилищата на екипа. teams.invite.description = ŠœŠ¾Š»Ń, щракнете Š²ŃŠŃ€Ń…Ńƒ Š±ŃƒŃ‚Š¾Š½Š° по-Голу, за Га се ŠæŃ€ŠøŃŃŠŠµŠ“ините към екипа. teams.invite.title = Поканени сте Га се ŠæŃ€ŠøŃŃŠŠµŠ“ините към екип %s в Š¾Ń€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃ %s. team_permission_desc = Š Š°Š·Ń€ŠµŃˆŠµŠ½ŠøŠµ members.public_helper = Да е скрит -teams.members = Членове на екипа +teams.members = Участници в екипа teams.delete_team = Š˜Š·Ń‚Ń€ŠøŠ²Š°Š½Šµ на екипа members.owner = ŠŸŃ€ŠøŃ‚ŠµŠ¶Š°Ń‚ŠµŠ» members.member_role = Š Š¾Š»Ń на ŃƒŃ‡Š°ŃŃ‚Š½ŠøŠŗŠ°: @@ -1684,6 +1975,37 @@ teams.no_desc = Този екип Š½ŃŠ¼Š° описание settings.delete_org_desc = Тази Š¾Ń€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃ ще бъГе изтрита перманентно. ŠŸŃ€Š¾Š“ŃŠŠ»Š¶Š°Š²Š°Š½Šµ? open_dashboard = ŠžŃ‚Š²Š°Ń€ŃŠ½Šµ на таблото settings.change_orgname_prompt = Бележка: ŠŸŃ€Š¾Š¼ŃŠ½Š°Ń‚Š° на името на Š¾Ń€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃŃ‚а ще промени Šø URL аГреса на Š²Š°ŃˆŠ°Ń‚а Š¾Ń€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃ Šø ще освобоГи старото име. +teams.add_duplicate_users = ŠŸŠ¾Ń‚Ń€ŠµŠ±ŠøŃ‚ŠµŠ»ŃŃ‚ вече е ŃƒŃ‡Š°ŃŃ‚Š½ŠøŠŗ в екипа. +team_unit_disabled = (Š˜Š·ŠŗŠ»ŃŽŃ‡ŠµŠ½Š¾) +form.name_reserved = Š˜Š¼ŠµŃ‚Š¾ на Š¾Ń€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃŃ‚а ā€ž%sā€œ е резервирано. +settings.update_avatar_success = ŠŸŃ€Š¾Ń„ŠøŠ»Š½Š°Ń‚Š° снимка на Š¾Ń€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃŃ‚а е обновена. +teams.invite_team_member.list = Чакащи покани +teams.remove_all_repos_desc = Това ще премахне всички хранилища от екипа. +form.create_org_not_allowed = ŠŃŠ¼Š°Ń‚Šµ Ń€Š°Š·Ń€ŠµŃˆŠµŠ½ŠøŠµ Га ŃŃŠŠ·Š“Š°Š²Š°Ń‚Šµ Š¾Ń€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃ. +form.name_pattern_not_allowed = ŠØŠ°Š±Š»Š¾Š½ŃŠŃ‚ ā€ž%sā€œ не е Ń€Š°Š·Ń€ŠµŃˆŠµŠ½ в име на Š¾Ń€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃ. +members.invite_now = Поканване сега +teams.specific_repositories = ŠšŠ¾Š½ŠŗŃ€ŠµŃ‚Š½Šø хранилища +teams.repos.none = ŠŃŠ¼Š° хранилища, Го които този екип Га има Š“Š¾ŃŃ‚ŃŠŠæ. +teams.add_all_repos_title = Š”Š¾Š±Š°Š²ŃŠ½Šµ на всички хранилища +settings.hooks_desc = Добавете уеб-куки, които ще се заГействат за всички хранилища в тази Š¾Ń€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃ. +teams.add_all_repos_desc = Това ще Гобави всички хранилища на Š¾Ń€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃŃ‚а към екипа. +members.invite_desc = Š”Š¾Š±Š°Š²ŃŠ½Šµ на нов ŃƒŃ‡Š°ŃŃ‚Š½ŠøŠŗ към %s: +members.private = Дкрит +settings.change_orgname_redirect_prompt.with_cooldown.few = Дтарото име на Š¾Ń€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃŃ‚а ще бъГе Š“Š¾ŃŃ‚ŃŠŠæŠ½Š¾ за всички слеГ периоГ на изчакване от %[1]d Гни. Все още можете Га си Š²ŃŠŃ€Š½ŠµŃ‚е старото име по време на периоГа на изчакване. +team_access_desc = Š”Š¾ŃŃ‚ŃŠŠæ Го хранилище +teams.specific_repositories_helper = Участниците ще имат Š“Š¾ŃŃ‚ŃŠŠæ само Го хранилища, изрично Гобавени към екипа. Š˜Š·Š±ŠøŃ€Š°Š½ŠµŃ‚Š¾ на това Š½ŃŠ¼Š° автоматично Га премахне хранилища, вече Гобавени с Всички хранилища. +teams.delete_team_desc = Š˜Š·Ń‚Ń€ŠøŠ²Š°Š½ŠµŃ‚Š¾ на екип отнема Š“Š¾ŃŃ‚ŃŠŠæŠ° Го хранилището от неговите ŃƒŃ‡Š°ŃŃ‚Š½ŠøŃ†Šø. ŠŸŃ€Š¾Š“ŃŠŠ»Š¶Š°Š²Š°Š½Šµ? +members.membership_visibility = ВиГимост на ŃƒŃ‡Š°ŃŃ‚Š½ŠøŃ‡ŠµŃŃ‚Š²Š¾Ń‚Š¾: +members.public = ВиГим +teams.all_repositories_helper = Š•ŠŗŠøŠæŃŠŃ‚ има Š“Š¾ŃŃ‚ŃŠŠæ Го всички хранилища. Š˜Š·Š±ŠøŃ€Š°Š½ŠµŃ‚Š¾ на това ще Гобави всички ŃŃŠŃ‰ŠµŃŃ‚Š²ŃƒŠ²Š°Ń‰Šø хранилища към екипа. +team_unit_desc = Š Š°Š·Ń€ŠµŃˆŠ°Š²Š°Š½Šµ на Š“Š¾ŃŃ‚ŃŠŠæ Го секции на хранилището +settings.update_setting_success = ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠøŃ‚Šµ на Š¾Ń€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃŃ‚а са обновени. +settings.change_orgname_redirect_prompt = Дтарото име ще се пренасочва, Гокато не бъГе взето. +teams.invite_team_member = Поканване в %s +teams.admin_access = АГминистраторски Š“Š¾ŃŃ‚ŃŠŠæ +settings.change_orgname_redirect_prompt.with_cooldown.one = Дтарото име на Š¾Ń€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃŃ‚а ще бъГе Š“Š¾ŃŃ‚ŃŠŠæŠ½Š¾ за всички слеГ периоГ на изчакване от %[1]d Ген. Все още можете Га си Š²ŃŠŃ€Š½ŠµŃ‚е старото име по време на периоГа на изчакване. +teams.add_nonexistent_repo = Єранилището, което се опитвате Га Гобавите, не ŃŃŠŃ‰ŠµŃŃ‚Š²ŃƒŠ²Š°, Š¼Š¾Š»Ń, ŠæŃŠŃ€Š²Š¾ го ŃŃŠŠ·Š“Š°Š¹Ń‚Šµ. +teams.invite.by = Поканен от %s [install] admin_password = ŠŸŠ°Ń€Š¾Š»Š° @@ -1978,14 +2300,14 @@ Pronouns = ŠœŠµŃŃ‚Š¾ŠøŠ¼ŠµŠ½ŠøŃ Biography = Š‘ŠøŠ¾Š³Ń€Š°Ń„ŠøŃ Website = Уебсайт Location = ŠœŠµŃŃ‚Š¾ŠæŠ¾Š»Š¾Š¶ŠµŠ½ŠøŠµ -cannot_add_org_to_team = ŠžŃ€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃ не може Га бъГе Гобавена като член на екип. +cannot_add_org_to_team = ŠžŃ€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃ не може Га бъГе Гобавена като ŃƒŃ‡Š°ŃŃ‚Š½ŠøŠŗ в екип. auth_failed = ŠŠµŃƒŃŠæŠµŃˆŠ½Š¾ ŃƒŠ“Š¾ŃŃ‚Š¾Š²ŠµŃ€ŃŠ²Š°Š½Šµ: %v team_no_units_error = Š Š°Š·Ń€ŠµŃˆŠµŃ‚Šµ Š“Š¾ŃŃ‚ŃŠŠæ Го поне еГна ŃŠµŠŗŃ†ŠøŃ на хранилището. password_uppercase_one = Поне еГин Š³Š¾Š»ŃŠ¼ знак CommitSummary = ŠžŠ±Š¾Š±Ń‰ŠµŠ½ŠøŠµ на поГаването username_error = ` може Га ŃŃŠŠ“ŃŠŃ€Š¶Š° само буквено-цифрови знаци (ā€ž0-9ā€œ, ā€ža-zā€œ, ā€žA-Zā€œ), тире (ā€ž-ā€œ), Голна черта (ā€ž_ā€œ) Šø точка (ā€ž.ā€œ). ŠŠµ може Га започва или Š·Š°Š²ŃŠŃ€ŃˆŠ²Š° с не-буквено-цифрови знаци, като ŃŃŠŃ‰Š¾ така са забранени Šø послеГователни не-буквено-цифрови знаци.` username_error_no_dots = ` може Га ŃŃŠŠ“ŃŠŃ€Š¶Š° само буквено-цифрови знаци (ā€ž0-9ā€œ, ā€ža-zā€œ, ā€žA-Zā€œ), тире (ā€ž-ā€œ) Šø Голна черта (ā€ž_ā€œ). ŠŠµ може Га започва или Š·Š°Š²ŃŠŃ€ŃˆŠ²Š° с не-буквено-цифрови знаци, като ŃŃŠŃ‰Š¾ така са забранени Šø послеГователни не-буквено-цифрови знаци.` -duplicate_invite_to_team = ŠŸŠ¾Ń‚Ń€ŠµŠ±ŠøŃ‚ŠµŠ»ŃŃ‚ вече е поканен като член на екипа. +duplicate_invite_to_team = ŠŸŠ¾Ń‚Ń€ŠµŠ±ŠøŃ‚ŠµŠ»ŃŃ‚ вече е поканен като ŃƒŃ‡Š°ŃŃ‚Š½ŠøŠŗ в екипа. must_use_public_key = ŠšŠ»ŃŽŃ‡ŃŠŃ‚, който преГоставихте, е частен ŠŗŠ»ŃŽŃ‡. ŠœŠ¾Š»Ń, не качвайте Ń‡Š°ŃŃ‚Š½ŠøŃ си ŠŗŠ»ŃŽŃ‡ никъГе. Вместо това използвайте ŠæŃƒŠ±Š»ŠøŃ‡Š½ŠøŃ си ŠŗŠ»ŃŽŃ‡. org_still_own_packages = Тази Š¾Ń€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃ все още притежава еГин или повече пакети, ŠæŃŠŃ€Š²Š¾ ги изтрийте. admin_cannot_delete_self = ŠŠµ можете Га изтриете себе си, когато сте аГминистратор. ŠœŠ¾Š»Ń, ŠæŃŠŃ€Š²Š¾ премахнете аГминистраторските си привилегии. @@ -2006,7 +2328,7 @@ enterred_invalid_repo_name = Š˜Š¼ŠµŃ‚Š¾ на хранилището, което enterred_invalid_org_name = Š˜Š¼ŠµŃ‚Š¾ на Š¾Ń€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃŃ‚а, което Š²ŃŠŠ²ŠµŠ“охте, е неправилно. enterred_invalid_password = ŠŸŠ°Ń€Š¾Š»Š°Ń‚Š°, ŠŗŠ¾ŃŃ‚Š¾ Š²ŃŠŠ²ŠµŠ“Š¾Ń…Ń‚Šµ, е неправилна. organization_leave_success = Успешно Š½Š°ŠæŃƒŃŠ½Š°Ń…те Š¾Ń€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃŃ‚а %s. -still_has_org = Š’Š°ŃˆŠøŃŃ‚ Š°ŠŗŠ°ŃƒŠ½Ń‚ е член на еГна или повече организации, ŠæŃŠŃ€Š²Š¾ ги Š½Š°ŠæŃƒŃŠ½ŠµŃ‚е. +still_has_org = Š’Š°ŃˆŠøŃŃ‚ Š°ŠŗŠ°ŃƒŠ½Ń‚ е ŃƒŃ‡Š°ŃŃ‚Š½ŠøŠŗ в еГна или повече организации, ŠæŃŠŃ€Š²Š¾ ги Š½Š°ŠæŃƒŃŠ½ŠµŃ‚е. org_still_own_repo = Тази Š¾Ń€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃ все още притежава еГно или повече хранилища, ŠæŃŠŃ€Š²Š¾ ги изтрийте или ŠæŃ€ŠµŃ…Š²ŃŠŃ€Š»ŠµŃ‚Šµ. target_branch_not_exist = Š¦ŠµŠ»ŠµŠ²ŠøŃŃ‚ клон не ŃŃŠŃ‰ŠµŃŃ‚Š²ŃƒŠ²Š°. glob_pattern_error = ` glob ŃˆŠ°Š±Š»Š¾Š½ŃŠŃ‚ е невалиГен: %s.` @@ -2016,6 +2338,17 @@ TreeName = ŠŸŃŠŃ‚ Го файла AdminEmail = АГминистраторски аГрес за ел. поща email_domain_is_not_allowed = Š”Š¾Š¼ŠµŠ¹Š½ŃŠŃ‚ на аГреса за ел. поща на ŠæŠ¾Ń‚Ń€ŠµŠ±ŠøŃ‚ŠµŠ»Ń %s е в конфликт с EMAIL_DOMAIN_ALLOWLIST или EMAIL_DOMAIN_BLOCKLIST. Уверете се, че сте въвели правилно аГреса за ел. поща. email_been_used = ŠŠ“Ń€ŠµŃŃŠŃ‚ за ел. поща вече се използва. +unable_verify_ssh_key = ŠŠµ може Га се ŠæŠ¾Ń‚Š²ŃŠŃ€Š“Šø SSH ŠŗŠ»ŃŽŃ‡ŃŠŃ‚, проверете го отново за Š³Ń€ŠµŃˆŠŗŠø. +enterred_invalid_owner_name = Š˜Š¼ŠµŃ‚Š¾ на Š½Š¾Š²ŠøŃ притежател не е валиГно. +NewBranchName = Име на Š½Š¾Š²ŠøŃ клон +invalid_ssh_key = ŠŠµ може Га се ŠæŠ¾Ń‚Š²ŃŠŃ€Š“Šø Š²Š°ŃˆŠøŃŃ‚ SSH ŠŗŠ»ŃŽŃ‡: %s +required_prefix = Š’ŃŠŠ²ŠµŠ“ŠµŠ½ŠøŃŃ‚ текст Ń‚Ń€ŃŠ±Š²Š° Га започва с ā€ž%sā€œ +regex_pattern_error = ` ŃˆŠ°Š±Š»Š¾Š½ŃŠŃ‚ на Ń€ŠµŠ³ŃƒŠ»ŃŃ€Š½ŠøŃ израз е невалиГен: %s.` +repository_files_already_exist = Вече ŃŃŠŃ‰ŠµŃŃ‚Š²ŃƒŠ²Š°Ń‚ файлове за това хранилище. Š”Š²ŃŠŃ€Š¶ŠµŃ‚Šµ се със ŃŠøŃŃ‚ŠµŠ¼Š½ŠøŃ аГминистратор. +repository_files_already_exist.delete = Вече ŃŃŠŃ‰ŠµŃŃ‚Š²ŃƒŠ²Š°Ń‚ файлове за това хранилище. Š¢Ń€ŃŠ±Š²Š° Га ги изтриете. +invalid_gpg_key = ŠŠµ може Га се ŠæŠ¾Ń‚Š²ŃŠŃ€Š“Šø Š²Š°ŃˆŠøŃŃ‚ GPG ŠŗŠ»ŃŽŃ‡: %s +git_ref_name_error = ` Ń‚Ń€ŃŠ±Š²Š° Га е правилно форматирано име на Git препратка.` +last_org_owner = ŠŠµ можете Га премахнете ŠæŠ¾ŃŠ»ŠµŠ“Š½ŠøŃ потребител от екипа на ā€žŠæŃ€ŠøŃ‚ŠµŠ¶Š°Ń‚ŠµŠ»ŠøŃ‚Šµā€œ. Š¢Ń€ŃŠ±Š²Š° Га има поне еГин притежател за Š¾Ń€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃ. [action] close_issue = `затвори заГача %[3]s#%[2]s` @@ -2035,7 +2368,7 @@ merge_pull_request = `ŃŠ»Ń Š·Š°ŃŠ²ŠŗŠ° за сливане %[ auto_merge_pull_request = `ŃŠ»Ń автоматично Š·Š°ŃŠ²ŠŗŠ° за сливане %[3]s#%[2]s` watched_repo = започна Га Š½Š°Š±Š»ŃŽŠ“ава %[2]s delete_tag = изтри маркера %[2]s от %[3]s -delete_branch = изтри клона %[2]s от %[3]s +delete_branch = изтри клона %[2]s от %[3]s create_branch = съзГаГе клон %[3]s на %[4]s publish_release = `публикува изГание %[4]s на %[3]s` push_tag = изтласка маркер %[3]s към %[4]s @@ -2044,6 +2377,11 @@ reject_pull_request = `преГложи промени за %[3] compare_branch = Š”Ń€Š°Š²Š½ŃŠ²Š°Š½Šµ compare_commits_general = Š”Ń€Š°Š²Š½ŃŠ²Š°Š½Šµ на ŠæŠ¾Š“Š°Š²Š°Š½ŠøŃ compare_commits = Дравнете %d ŠæŠ¾Š“Š°Š²Š°Š½ŠøŃ +transfer_repo = ŠæŃ€ŠµŃ…Š²ŃŠŃ€Š»Šø хранилище %s към %s +mirror_sync_push = синхронизира ŠæŠ¾Š“Š°Š²Š°Š½ŠøŃ към %[3]s на %[4]s от оглеГало +mirror_sync_create = синхронизира нова препратка %[3]s към %[4]s от оглеГало +review_dismissed = `Š¾Ń‚Ń…Š²ŃŠŃ€Š»Šø Ń€ŠµŃ†ŠµŠ½Š·ŠøŃ от %[4]s за %[3]s#%[2]s` +mirror_sync_delete = синхронизира Šø изтри препратка %[2]s на %[3]s от оглеГало [auth] tab_openid = OpenID @@ -2177,6 +2515,14 @@ variables.management = Управление на променливи variables.not_found = ŠŸŃ€Š¾Š¼ŠµŠ½Š»ŠøŠ²Š°Ń‚Š° не е открита. variables.id_not_exist = ŠŸŃ€Š¾Š¼ŠµŠ½Š»ŠøŠ²Š° с иГентификатор %d не ŃŃŠŃ‰ŠµŃŃ‚Š²ŃƒŠ²Š°. runners.owner_type = Тип +status.cancelled = ŠžŃ‚Š¼ŠµŠ½ŠµŠ½Š¾ +status.running = Š˜Š·ŠæŃŠŠ»Š½ŃŠ²Š° се +status.success = Успешно +status.waiting = Š˜Š·Ń‡Š°ŠŗŠ²Š° се +status.unknown = ŠŠµŠøŠ·Š²ŠµŃŃ‚Š½Š¾ +status.failure = ŠŠµŃƒŃŠæŠµŃˆŠ½Š¾ +status.skipped = ŠŸŃ€Š¾ŠæŃƒŃŠ½Š°Ń‚Š¾ +unit.desc = Управление на интегрирани CI/CD pipelines с Forgejo Actions. [heatmap] less = По-малко @@ -2258,3 +2604,33 @@ eib = ЕиБ [translation_meta] test = окей + + +[gpg] +default_key = ПоГписано с ŠŗŠ»ŃŽŃ‡ по поГразбиране +error.no_gpg_keys_found = ŠŠµ е намерен известен ŠŗŠ»ŃŽŃ‡ за този поГпис в базата Ганни +error.not_signed_commit = ŠŠµ е поГписано поГаване +error.generate_hash = ŠŠµŃƒŃŠæŠµŃˆŠ½Š¾ генериране на Ń…ŠµŃˆ на поГаването +error.extract_sign = ŠŠµŃƒŃŠæŠµŃˆŠ½Š¾ извличане на поГпис +error.probable_bad_signature = Š’ŠŠ˜ŠœŠŠŠ˜Š•! Š’ŃŠŠæŃ€ŠµŠŗŠø че има ŠŗŠ»ŃŽŃ‡ с това ID в базата Ганни, той не ŠæŠ¾Ń‚Š²ŃŠŃ€Š¶Š“Š°Š²Š° това поГаване! Това поГаване е ŠŸŠžŠ”ŠžŠ—Š Š˜Š¢Š•Š›ŠŠž. +error.failed_retrieval_gpg_keys = ŠŠµŃƒŃŠæŠµŃˆŠ½Š¾ извличане на ŠŗŠ»ŃŽŃ‡, ŃŠ²ŃŠŃ€Š·Š°Š½ с Š°ŠŗŠ°ŃƒŠ½Ń‚Š° на ŠæŠ¾Š“Š°Š²Š°Ń‰ŠøŃ +error.probable_bad_default_signature = Š’ŠŠ˜ŠœŠŠŠ˜Š•! Š’ŃŠŠæŃ€ŠµŠŗŠø че ŠŗŠ»ŃŽŃ‡ŃŠŃ‚ по поГразбиране има това ID, той не ŠæŠ¾Ń‚Š²ŃŠŃ€Š¶Š“Š°Š²Š° това поГаване! Това поГаване е ŠŸŠžŠ”ŠžŠ—Š Š˜Š¢Š•Š›ŠŠž. +error.no_committer_account = ŠŃŠ¼Š° Š°ŠŗŠ°ŃƒŠ½Ń‚, ŃŠ²ŃŠŃ€Š·Š°Š½ с аГреса за ел. поща на ŠæŠ¾Š“Š°Š²Š°Ń‰ŠøŃ + +[repo.permissions] +projects.read = Четене: Š”Š¾ŃŃ‚ŃŠŠæ Го проектните табла на хранилището. +wiki.write = Писане: ДъзГаване, Š¾Š±Š½Š¾Š²ŃŠ²Š°Š½Šµ Šø изтриване на страници в интегрираното уики. +issues.read = Четене: Четене Šø съзГаване на заГачи Šø коментари. +pulls.read = Четене: Четене Šø съзГаване на Š·Š°ŃŠ²ŠŗŠø за сливане. +pulls.write = Писане: Š—Š°Ń‚Š²Š°Ń€ŃŠ½Šµ на Š·Š°ŃŠ²ŠŗŠø за сливане Šø ŃƒŠæŃ€Š°Š²Š»ŠµŠ½ŠøŠµ на метаГанни като етикети, етапи, ŠøŠ·ŠæŃŠŠ»Š½ŠøŃ‚ŠµŠ»Šø, крайни срокове Šø зависимости. +projects.write = Писане: ДъзГаване Šø реГактиране на проекти Šø колони. +releases.read = Четене: ŠŸŃ€ŠµŠ³Š»ŠµŠ“ Šø ŠøŠ·Ń‚ŠµŠ³Š»ŃŠ½Šµ на ŠøŠ·Š“Š°Š½ŠøŃ. +wiki.read = Четене: Четене на интегрираното уики Šø неговата ŠøŃŃ‚Š¾Ń€ŠøŃ. +code.read = Четене: Š”Š¾ŃŃ‚ŃŠŠæ Šø клониране на коГа на хранилището. +code.write = Писане: Š˜Š·Ń‚Š»Š°ŃŠŗŠ²Š°Š½Šµ към хранилището, съзГаване на клонове Šø маркери. +issues.write = Писане: Š—Š°Ń‚Š²Š°Ń€ŃŠ½Šµ на заГачи Šø ŃƒŠæŃ€Š°Š²Š»ŠµŠ½ŠøŠµ на метаГанни като етикети, етапи, ŠøŠ·ŠæŃŠŠ»Š½ŠøŃ‚ŠµŠ»Šø, крайни срокове Šø зависимости. + +[units] +error.no_unit_allowed_repo = ŠŃŠ¼Š°Ń‚Šµ Ń€Š°Š·Ń€ŠµŃˆŠµŠ½ŠøŠµ за Š“Š¾ŃŃ‚ŃŠŠæ Го Š½ŠøŠŗŠ¾Ń ŃŠµŠŗŃ†ŠøŃ на това хранилище. +unit = Елемент +error.unit_not_allowed = ŠŃŠ¼Š°Ń‚Šµ Ń€Š°Š·Ń€ŠµŃˆŠµŠ½ŠøŠµ за Š“Š¾ŃŃ‚ŃŠŠæ Го тази ŃŠµŠŗŃ†ŠøŃ на хранилището. \ No newline at end of file diff --git a/options/locale/locale_ca.ini b/options/locale/locale_ca.ini index 9cb7d5e50c..ea2af3b645 100644 --- a/options/locale/locale_ca.ini +++ b/options/locale/locale_ca.ini @@ -153,26 +153,26 @@ 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... +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... +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"... +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... +issue_kind = Cerca problemes… regexp = RegExp regexp_tooltip = Interpreta el terme de cerca com una expressió regular diff --git a/options/locale/locale_cs-CZ.ini b/options/locale/locale_cs-CZ.ini index 830065fb64..c7770c5ea1 100644 --- a/options/locale/locale_cs-CZ.ini +++ b/options/locale/locale_cs-CZ.ini @@ -1063,7 +1063,7 @@ language.localization_project = Pomozte nĆ”m s překladem Forgejo do vaÅ”eho jaz 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. +change_username_redirect_prompt.with_cooldown.one = StarĆ© uživatelskĆ© jmĆ©no bude dostupnĆ© ostatnĆ­m po %[1]d dnu. 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 @@ -1556,7 +1556,7 @@ issues.label_templates.info=ZatĆ­m nebyly vytvořeny žÔdnĆ© Å”tĆ­tky. Vytvořt issues.label_templates.helper=Vyberte přednastavenĆ© značky issues.label_templates.use=Použít přednastavenĆ© Å”tĆ­tky issues.label_templates.fail_to_load_file=Nepodařilo se načƭst soubor Å”ablony popisku ā€ž%sā€œ: %v -issues.add_label=přidal/a %s Å”tĆ­tek %s +issues.add_label=přidal/a Å”tĆ­tek %s %s issues.add_labels=přidal/a %s Å”tĆ­tky %s issues.remove_label=odstranil/a %s Å”tĆ­tek %s issues.remove_labels=odstranil/a %s Å”tĆ­tky %s @@ -1579,7 +1579,7 @@ issues.remove_ref_at=`odstranil/a referenci %s %s` issues.add_ref_at=`přidal/a referenci %s %s` issues.delete_branch_at=`odstranil/a větev %s %s` issues.filter_label=Å tĆ­tek -issues.filter_label_exclude=`Chcete-li vyloučit Å”tĆ­tky, použijte alt + click/enter` +issues.filter_label_exclude=Chcete-li vyloučit Å”tĆ­tky, použijte Alt + kliknutĆ­ issues.filter_label_no_select=VÅ”echny Å”tĆ­tky issues.filter_label_select_no_label=Bez Å”tĆ­tku issues.filter_milestone=MilnĆ­k @@ -1763,7 +1763,7 @@ 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 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_codes=`vynutil/a 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Ć­ @@ -1813,7 +1813,7 @@ issues.review.approve=schvĆ”lil/a tyto změny %s issues.review.comment=posoudil/a %s issues.review.dismissed=zamĆ­tl/a posouzenĆ­ uživatele %s %s issues.review.dismissed_label=ZamĆ­tnuto -issues.review.left_comment=zanechal komentÔř +issues.review.left_comment=zanechal/a 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 @@ -3058,7 +3058,7 @@ 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.one = Starý nĆ”zev organizace bude dostupný ostatnĆ­m po %[1]d dnu. 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] @@ -3636,7 +3636,7 @@ auto_merge_pull_request=`automaticky sloučen požadavek na nataženĆ­ %s push_tag=nahrĆ”l/a značku %[3]s do %[4]s delete_tag=smazal/a značku %[2]s z %[3]s -delete_branch=smazal/a větev %[2]s z %[3]s +delete_branch=smazal/a větev %[2]s z %[3]s compare_branch=Porovnat compare_commits=Porovnat %d revizĆ­ compare_commits_general=Porovnat revize diff --git a/options/locale/locale_da.ini b/options/locale/locale_da.ini index c82779ab60..1a92305515 100644 --- a/options/locale/locale_da.ini +++ b/options/locale/locale_da.ini @@ -978,8 +978,8 @@ delete_with_all_comments = Din konto er yngre end %s. For at undgĆ„ spĆøgelsesko 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. +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, Ć„r. 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, Ć„r. 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 @@ -1520,13 +1520,13 @@ 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 %[3]s, der vil genĆ„bne den, %[1]s` +issues.ref_reopening_from = `henviste til dette problem fra en pull-anmodning %[3]s, der vil genĆ„bne det, %[1]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 %s` -issues.ref_issue_from = `henviste til dette problem %[3]s %[2 ]s` +issues.ref_issue_from = `henviste til dette problem %[3]s %[1]s` issues.ref_pull_from = `henviste til denne pull-anmodning %[3]s %[1]s` issues.ref_closing_from = `henviste til dette problem fra en pull-anmodning %[3]s, der vil lukke det, %[1]s` issues.author.tooltip.issue = Denne bruger er forfatteren til dette problem. @@ -1582,7 +1582,7 @@ issues.change_ref_at = `Ʀndret reference fra %s til 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_label_exclude = Brug Alt + klik for at ekskludere etiketter issues.filter_milestone = MilepƦl issues.filter_milestone_all = Alle milepƦle issues.filter_milestone_none = Ingen milepƦle @@ -2768,7 +2768,7 @@ close_pull_request = `lukket pull request %[3]s#%[2]s` starred_repo = stjernemarkerede %[2]s close_issue = `lukket problem %[3]s#%[2]s` comment_issue = `kommenterede problem %[3]s#%[2]s` -delete_branch = slettede gren %[2]s fra %[3]s +delete_branch = slettede gren %[2]s fra %[3]s compare_commits = Sammenlign %d commits compare_commits_general = Sammenlign commits review_dismissed = `afvist anmeldelse fra %[4]s for %[3]s#%[2]s` @@ -2833,8 +2833,8 @@ team_permission_desc = Tilladelse members.member = Medlem 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.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, Ć„r. 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, Ć„r. Du kan stadig krƦve det gamle navn tilbage i. settings.update_avatar_success = Organisationens avatar er blevet opdateret. members.public_helper = GĆør skjult members.private = Skjult diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini index f8bfc9258a..8f4dfda0d1 100644 --- a/options/locale/locale_de-DE.ini +++ b/options/locale/locale_de-DE.ini @@ -752,7 +752,7 @@ organization=Organisationen uid=UID webauthn=Hardware-Sicherheitsschlüssel -public_profile=Ɩffentliches Profil +public_profile=Ɩffentliches profil 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=Über dich @@ -3640,7 +3640,7 @@ auto_merge_pull_request=`führte Pull-Request %[3]s#%[2]s au transfer_repo=hat Repository %s übertragen zu %s 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 +delete_branch=hat Branch %[2]s in %[3]s gelƶscht compare_branch=Vergleichen compare_commits=Vergleiche %d Commits compare_commits_general=Commits vergleichen diff --git a/options/locale/locale_el-GR.ini b/options/locale/locale_el-GR.ini index 398a0d9ce4..116d5ba5a8 100644 --- a/options/locale/locale_el-GR.ini +++ b/options/locale/locale_el-GR.ini @@ -3563,7 +3563,7 @@ auto_merge_pull_request=`Ī±Ļ…Ļ„ĻŒĪ¼Ī±Ļ„Ī· ĻƒĻ…Ī³Ļ‡ĻŽĪ½ĪµĻ…ĻƒĪ· του pull reque transfer_repo=μετέφερε το repository %s σε %s push_tag=ĻŽĪøĪ·ĻƒĪµ την ετικέτα %[3]s σε %[4]s delete_tag=Γιέγραψε την ετικέτα %[2]s Ī±Ļ€ĻŒ %[3]s -delete_branch=Γιέγραψε το κλάΓο %[2]s Ī±Ļ€ĻŒ %[3]s +delete_branch=Γιέγραψε το κλάΓο %[2]s Ī±Ļ€ĻŒ %[3]s compare_branch=Ī£ĻĪ³ĪŗĻĪ¹ĻƒĪ· compare_commits=Ī£ĻĪ³ĪŗĻĪ¹ĻƒĪ· %d commit compare_commits_general=Ī£ĻĪ³ĪŗĻĪ¹ĻƒĪ· commits @@ -3939,12 +3939,12 @@ submodule=΄πομονάΓα [search] code_search_unavailable = Ī— Ī±Ī½Ī±Ī¶Ī®Ļ„Ī·ĻƒĪ· ĪŗĻŽĪ“Ī¹ĪŗĪ± Γεν είναι επί του Ļ€Ī±ĻĻŒĪ½Ļ„ĪæĻ‚ Γιαθέσιμη. Ī Ī±ĻĪ±ĪŗĪ±Ī»ĻŽ ĪµĻ€Ī¹ĪŗĪæĪ¹Ī½Ļ‰Ī½Ī®ĻƒĻ„Īµ με τον Ī“Ī¹Ī±Ļ‡ĪµĪ¹ĻĪ¹ĻƒĻ„Ī® ĻƒĪ±Ļ‚. keyword_search_unavailable = Ī— Ī±Ī½Ī±Ī¶Ī®Ļ„Ī·ĻƒĪ· με την Ļ‡ĻĪ®ĻƒĪ· λέξεων-ĪŗĪ»ĪµĪ¹Ī“Ī¹ĻŽĪ½ Γεν είναι επί του Ļ€Ī±ĻĻŒĪ½Ļ„ĪæĻ‚ Γιαθέσιμη. Ī Ī±ĻĪ±ĪŗĪ±Ī»ĻŽ ĪµĻ€Ī¹ĪŗĪæĪ¹Ī½Ļ‰Ī½Ī®ĻƒĻ„Īµ με τον Ī“Ī¹Ī±Ļ‡ĪµĪ¹ĻĪ¹ĻƒĻ„Ī® ĻƒĪ±Ļ‚. -runner_kind = Ī‘Ī½Ī±Ī¶Ī®Ļ„Ī·ĻƒĪ· runner... +runner_kind = Ī‘Ī½Ī±Ī¶Ī®Ļ„Ī·ĻƒĪ· runner… code_search_by_git_grep = Για την Ī±Ī½Ī±Ī¶Ī®Ļ„Ī·ĻƒĪ· ĪŗĻŽĪ“Ī¹ĪŗĪ±, Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĪµĪÆĻ„Ī±Ī¹ Ī· εντολή Ā«git grepĀ». ĪŠĻƒĻ‰Ļ‚ να Ļ€Ī±ĻĪæĻ…ĻƒĪ¹Ī±ĻƒĻ„ĪæĻĪ½ ĪŗĪ±Ī»ĻĻ„ĪµĻĪ± Ī±Ļ€ĪæĻ„ĪµĪ»Ī­ĻƒĪ¼Ī±Ļ„Ī±, αν Īæ Ī“Ī¹Ī±Ļ‡ĪµĪ¹ĻĪ¹ĻƒĻ„Ī®Ļ‚ ĻƒĪ±Ļ‚ ĪµĪ½ĪµĻĪ³ĪæĻ€ĪæĪ¹Ī®ĻƒĪµĪ¹ ένα ευρετήριο για αποθετήρια (Ā«Repository IndexerĀ»). package_kind = Ī‘Ī½Ī±Ī¶Ī®Ļ„Ī·ĻƒĪ· πακέτων… -project_kind = Ī‘Ī½Ī±Ī¶Ī®Ļ„Ī·ĻƒĪ· έργων... +project_kind = Ī‘Ī½Ī±Ī¶Ī®Ļ„Ī·ĻƒĪ· έργων… branch_kind = Ī‘Ī½Ī±Ī¶Ī®Ļ„Ī·ĻƒĪ· κλάΓων… -commit_kind = Ī‘Ī½Ī±Ī¶Ī®Ļ„Ī·ĻƒĪ· commit... +commit_kind = Ī‘Ī½Ī±Ī¶Ī®Ļ„Ī·ĻƒĪ· commit… no_results = Δεν βρέθηκαν κατάλληλα Ī±Ļ€ĪæĻ„ĪµĪ»Ī­ĻƒĪ¼Ī±Ļ„Ī±. search = Ī‘Ī½Ī±Ī¶Ī®Ļ„Ī·ĻƒĪ·ā€¦ type_tooltip = ΕίΓος Ī±Ī½Ī±Ī¶Ī®Ļ„Ī·ĻƒĪ·Ļ‚ @@ -3958,8 +3958,8 @@ org_kind = Ī‘Ī½Ī±Ī¶Ī®Ļ„Ī·ĻƒĪ· ĪæĻĪ³Ī±Ī½Ī¹ĻƒĪ¼ĻŽĪ½ā€¦ team_kind = Ī‘Ī½Ī±Ī¶Ī®Ļ„Ī·ĻƒĪ· ĪæĪ¼Ī±Ī“ĻŽĪ½ā€¦ code_kind = Ī‘Ī½Ī±Ī¶Ī®Ļ„Ī·ĻƒĪ· ĪŗĻŽĪ“Ī¹ĪŗĪ±ā€¦ exact_tooltip = ĪĪ± ĻƒĻ…Ī¼Ļ€ĪµĻĪ¹Ī»Ī·Ļ†ĪøĪæĻĪ½ μόνο Ī±Ļ€ĪæĻ„ĪµĪ»Ī­ĻƒĪ¼Ī±Ļ„Ī± που ταιριάζουν με τον όρο Ī±Ī½Ī±Ī¶Ī®Ļ„Ī·ĻƒĪ·Ļ‚ -issue_kind = Ī‘Ī½Ī±Ī¶Ī®Ļ„Ī·ĻƒĪ· ζητημάτων... -pull_kind = Ī‘Ī½Ī±Ī¶Ī®Ļ„Ī·ĻƒĪ· pull... +issue_kind = Ī‘Ī½Ī±Ī¶Ī®Ļ„Ī·ĻƒĪ· ζητημάτων… +pull_kind = Ī‘Ī½Ī±Ī¶Ī®Ļ„Ī·ĻƒĪ· pull… exact = Ακριβής milestone_kind = Ī‘Ī½Ī±Ī¶Ī®Ļ„Ī·ĻƒĪ· ĪæĻĻŒĻƒĪ·Ī¼Ļ‰Ī½... union = ĪˆĪ½Ļ‰ĻƒĪ· diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 5fd2ebd163..cce62685bf 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -3564,7 +3564,7 @@ auto_merge_pull_request = `automatically merged pull request %[3 transfer_repo = transferred repository %s to %s push_tag = pushed tag %[3]s to %[4]s delete_tag = deleted tag %[2]s from %[3]s -delete_branch = deleted branch %[2]s from %[3]s +delete_branch = deleted branch %[2]s from %[3]s compare_branch = Compare compare_commits = Compare %d commits compare_commits_general = Compare commits diff --git a/options/locale/locale_eo.ini b/options/locale/locale_eo.ini index 6393765d63..5a06120e9e 100644 --- a/options/locale/locale_eo.ini +++ b/options/locale/locale_eo.ini @@ -630,7 +630,7 @@ account = Konto ssh_gpg_keys = SSH / GPG-ŝlosiloj twofa_disable = Malaktivigi duoblan aÅ­tentikigon twofa_enroll = Ŝalti duoblan aÅ­tentikigon -orgs = Mastrumi organizaĵojn +orgs = Organizaĵoj blocked_users = Blokitaj uzantoj profile = Profilo ui = HaÅ­to @@ -686,7 +686,7 @@ verify_ssh_key_success = SSH-ŝlosilo Ā«%sĀ» jam konfirmiĝis. edit_oauth2_application = Redakti OAuth2-programon gpg_key_deletion = Forigi GPG-ŝlosilon gpg_key_matched_identities = Akordaj identecoj: -manage_themes = Elekti implicitan haÅ­ton +manage_themes = DefaÅ­lta temo ssh_key_deletion = Forigi SSH-ŝlosilon key_state_desc = Ĉi tiu ŝlosilo uziĝis dum la pasintaj 7 tagoj valid_forever = Validos dumĉiame @@ -700,7 +700,7 @@ primary = Ĉefa ssh_disabled = SSH malaktivigita update_avatar_success = Via profilbildo konserviĝis. keep_email_private = Kaŝi retpoŝtadreson -manage_openid = Mastrumi OpenID-adresojn +manage_openid = OpenID-adresoj delete_current_avatar = Forigi nunan profilbildon email_preference_set_success = Retpoŝta prefero konserviĝis sukcese. permissions_access_all = Ĉiu (publika, privata, kaj limigita) @@ -884,9 +884,9 @@ 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... +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 +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 bdafba93b4..582baeebdd 100644 --- a/options/locale/locale_es-ES.ini +++ b/options/locale/locale_es-ES.ini @@ -740,7 +740,7 @@ avatar=Avatar ssh_gpg_keys=Claves SSH / GPG social=Redes sociales applications=Aplicaciones -orgs=Administrar organizaciones +orgs=Organizaciones repos=Repositorios delete=Eliminar cuenta twofa=Autenticación de dos factores (TOTP) @@ -1075,8 +1075,8 @@ keep_pronouns_private = Mostrar pronombres solo a personas autenticadas storage_overview = Resumen del almacenamiento quota.sizes.assets.artifacts = Artefactos quota.sizes.assets.attachments.releases = Archivos adjuntos del lanzamiento -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. -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. +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. quota.rule.exceeded = Excedido quota.rule.no_limit = Ilimitado quota.sizes.assets.all = Activos @@ -1574,7 +1574,7 @@ issues.remove_ref_at=`eliminó la referencia %s %s` issues.add_ref_at=`aƱadió la referencia %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_exclude=Usa Alt + Click para excluir etiquetas issues.filter_label_no_select=Todas las etiquetas issues.filter_label_select_no_label=Sin etiqueta issues.filter_milestone=Hito @@ -2887,6 +2887,8 @@ pulls.delete_after_merge.head_branch.is_default = La rama actual que desea elimi summary_card_alt = Tarjeta de resumen del repositorio %s settings.pull_mirror_sync_quota_exceeded = Cuota excedida, no se empujan los cambios. archive.nocomment = No es posible hacer comentarios porque el repositorio estĆ” archivado. +sync_fork.branch_behind_one = Esta rama esta %[1]d cambios detrĆ”s de %[2]s +sync_fork.branch_behind_few = Esta rama estĆ” %[1]d confirmaciones detrĆ”s de %[2]s [graphs] component_loading = Cargando %s… @@ -3586,7 +3588,7 @@ auto_merge_pull_request=`fusionado automĆ”ticamente pull request %s a %s push_tag=hizó push la etiqueta %[3]s a %[4]s delete_tag=etiqueta eliminada %[2]s de %[3]s -delete_branch=rama %[2]s eliminada, de %[3]s +delete_branch=rama %[2]s eliminada, de %[3]s compare_branch=Comparar compare_commits=Comparar %d commits compare_commits_general=Comparar commits diff --git a/options/locale/locale_et.ini b/options/locale/locale_et.ini index e54ceadbb5..58e5776d33 100644 --- a/options/locale/locale_et.ini +++ b/options/locale/locale_et.ini @@ -145,25 +145,25 @@ 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... +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... +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... +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... +pull_kind = Otsi tƵmbepƤringuid… [aria] navbar = Navigatsiooniriba diff --git a/options/locale/locale_fa-IR.ini b/options/locale/locale_fa-IR.ini index dae0695495..23cb74f814 100644 --- a/options/locale/locale_fa-IR.ini +++ b/options/locale/locale_fa-IR.ini @@ -608,7 +608,7 @@ avatar=آواتار ssh_gpg_keys=Ś©Ł„ŪŒŲÆā€ŒŁ‡Ų§ŪŒ SSH / GPG social=Ų­Ų³Ų§ŲØ Ł‡Ų§ŪŒ Ų§Ų¬ŲŖŁ…Ų§Ų¹ŪŒ applications=ŲØŲ±Ł†Ų§Ł…Ł‡ā€ŒŁ‡Ų§ -orgs=Ł…ŲÆŪŒŲ±ŪŒŲŖ Ų³Ų§Ų²Ł…Ų§Ł†ā€ŒŁ‡Ų§ +orgs=Ų³Ų§Ų²Ł…Ų§Ł†ā€ŒŁ‡Ų§ repos=مخازن delete=حذف Ų­Ų³Ų§ŲØ کاربری twofa=Ų§Ų­Ų±Ų§Ų² Ł‡ŁˆŪŒŲŖ ŲÆŁˆŚÆŲ§Ł†Ł‡ @@ -653,8 +653,8 @@ password_change_disabled=کاربران غیر Ł…Ų­Ł„ŪŒ Ł†Ł…ŪŒŲŖŁˆŲ§Ł†Ł†ŲÆ ŚÆŲ° emails=Ł†Ų“Ų§Ł†ŪŒā€ŒŁ‡Ų§ŪŒ Ų§ŪŒŁ…ŪŒŁ„ manage_emails=Ł…ŲÆŪŒŲ±ŪŒŲŖ Ł†Ų“Ų§Ł†ŪŒā€ŒŁ‡Ų§ŪŒ Ų§ŪŒŁ…ŪŒŁ„ -manage_themes=ŲŖŁ… پیؓ فرض Ų±Ų§ انتخاب Ś©Ł†ŪŒŲÆ -manage_openid=Ł…ŲÆŪŒŲ±ŪŒŲŖ Ł†Ų“Ų§Ł†ŪŒā€ŒŁ‡Ų§ŪŒ OpenID +manage_themes=ŲŖŁ… پیؓ فرض +manage_openid=Ų¢ŲÆŲ±Ų³ā€ŒŁ‡Ų§ŪŒ OpenID theme_desc=Ų§ŪŒŁ† Ł¾ŁˆŲ“ŲŖŁ‡ پیؓ فرض Ų“Ł…Ų§ ŲÆŲ± Ų³Ų±Ų§Ų³Ų± سایت Ł…ŪŒ ŲØŲ§Ų“ŲÆ. primary=Ų§ŲµŁ„ŪŒ activated=فعال ؓده @@ -2766,23 +2766,23 @@ search = جستجو... fuzzy = درهم fuzzy_tooltip = Ł¾ŪŒŲ§Ł…ŲÆŁ‡Ų§ŪŒŪŒ Ų±Ų§ ŲÆŲ±Ų¬ Ś©Ł†ŪŒŲÆ که ŲÆŁ‚ŪŒŁ‚Ų§ ŲØŲ§ Ų¹ŲØŲ§Ų±ŲŖ جستجو Ł‡Ł…Ų®ŁˆŲ§Ł†ŪŒ داؓته باؓند regexp = Ų¹ŲØŲ§Ų±Ų§ŲŖ باقاعده -pull_kind = جستجو ŁˆŲ§Ś©Ų“ŪŒā€ŒŁ‡Ų§... +pull_kind = جستجو ŁˆŲ§Ś©Ų“ŪŒā€ŒŁ‡Ų§ā€¦ no_results = Ł†ŲŖŪŒŲ¬Ł‡ درخوری یافت نؓد. -runner_kind = جستجو ŲÆŁˆŁ†ŲÆŁ‡ā€ŒŁ‡Ų§... +runner_kind = جستجو ŲÆŁˆŁ†ŲÆŁ‡ā€ŒŁ‡Ų§ā€¦ keyword_search_unavailable = جستجو Ś©Ł„ŪŒŲÆŁˆŲ§Ś˜Ł‡ Ų§Ś©Ł†ŁˆŁ† ŲÆŲ± ŲÆŲ±Ų³ŲŖŲ±Ų³ Ł†ŪŒŲ³ŲŖ. لطفا ŲØŲ§ Ł…ŲÆŪŒŲ± سایت ŲÆŲ± Ł…ŪŒŲ§Ł† بگذارید. -repo_kind = جستجو مخازن... +repo_kind = جستجو مخازن… regexp_tooltip = اصطلاح جستجو ؓده Ų±Ų§ ŲØŲ§ Ų¹ŲØŲ§Ų±Ų§ŲŖ باقاعده تفسیر کن -user_kind = جستجو کاربران... -org_kind = جستجو Ų³Ų§Ų²Ł…Ų§Ł†ā€ŒŁ‡Ų§... -team_kind = جستجو ŚÆŲ±ŁˆŁ‡ā€ŒŁ‡Ų§... -package_kind = جستجو ŲØŲ³ŲŖŁ‡ā€ŒŁ‡Ų§... -project_kind = جستجو Ł¾Ų±ŁˆŚ˜Ł‡ā€ŒŁ‡Ų§... +user_kind = جستجو کاربران… +org_kind = جستجو Ų³Ų§Ų²Ł…Ų§Ł†ā€ŒŁ‡Ų§ā€¦ +team_kind = جستجو ŚÆŲ±ŁˆŁ‡ā€ŒŁ‡Ų§ā€¦ +package_kind = جستجو ŲØŲ³ŲŖŁ‡ā€ŒŁ‡Ų§ā€¦ +project_kind = جستجو Ł¾Ų±ŁˆŚ˜Ł‡ā€ŒŁ‡Ų§ā€¦ code_search_unavailable = جستجوی کد Ų§Ś©Ł†ŁˆŁ† ŲÆŲ± ŲÆŲ³ŲŖŲ±Ų³ Ł†ŪŒŲ³ŲŖ. لطفا ŲØŲ§ Ł…ŲÆŪŒŲ± سایت ŲÆŲ±Ł…ŪŒŲ§Ł† بگذارید. -code_kind = جستجو کدها... +code_kind = جستجو کدها… union = بهم پیوستگی union_tooltip = Ł†ŲŖŲ§ŪŒŲ¬ŪŒ Ų±Ų§ ŲÆŲ± ŲØŲ± بگیر که ŲØŲ§ هر یک Ų§Ų² Ś©Ł„ŪŒŲÆŁˆŲ§Ś˜Ł‡ā€ŒŁ‡Ų§ŪŒ Ų¬ŲÆŲ§ ؓده Ų§Ų² ŁŲ¶Ų§ŪŒā€ŒŲ®Ų§Ł„ŪŒ مطابقت ŲÆŲ§Ų±ŲÆ -branch_kind = جستجو Ų“Ų§Ų®Ł‡ā€ŒŁ‡Ų§... -commit_kind = جستجو Ų³Ł¾Ų±ŲÆŁ‡ā€ŒŁ‡Ų§... -issue_kind = جستجو مؓکلات... +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 164a60cc8d..263fab8774 100644 --- a/options/locale/locale_fi-FI.ini +++ b/options/locale/locale_fi-FI.ini @@ -667,6 +667,12 @@ username_change_not_local_user = Ei-paikallisten kƤyttƤjien ei sallita vaihtaa admin_cannot_delete_self = Et voi poistaa itseƤsi, kun olet yllƤpitƤjƤ. Poista ensin yllƤpito-oikeudet itseltƤsi. username_claiming_cooldown = KƤyttƤjƤnimeƤ ei voi ottaa kƤyttƶƶn, koska siihen kohdistuva suojaamisjakso ei ole vielƤ pƤƤttynyt. KƤyttƤjƤnimen voi ottaa kƤyttƶƶn %[1]s. email_domain_is_not_allowed = KƤyttƤjƤn sƤhkƶpostiosoitteen %s verkkotunnus on ristiriidassa EMAIL_DOMAIN_ALLOWLIST:in tai EMAIL_DOMAIN_BLOCKLIST:in kanssa. Varmista, ettƤ olen asettanut sƤhkƶpostiosoitteen oikein. +unsupported_login_type = TƤllƤ kirjautumistavalla ei voi poistaa tunnusta. +invalid_ssh_principal = VƤƤrƤ toimija: %s +unset_password = Kirjautuneen kƤyttƤjƤn salasanaa ei ole asetettu. +invalid_group_team_map_error = ` kuvaus ei ole kelvollinen: %s` +2fa_auth_required = EtƤvierailu vaati kaksivaiheisen todennuksen. +visit_rate_limit = EtƤvierailujen pyyntƶrajoitukset. [user] @@ -1037,6 +1043,8 @@ passcode_invalid = Virheellinen pƤƤsykoodi. YritƤ uudelleen. then_enter_passcode = Kirjoita sovelluksessa nƤkyvƤ pƤƤsykoodi: gpg_key_matched_identities_long = TƤhƤn avaimeen upotetut identiteetit vastaavat tƤmƤn kƤyttƤjƤn seuraavia aktivoituja sƤhkƶpostiosoitteita. Kommitit, jotka vastaavat nƤitƤ sƤhkƶpostiosoitteita, voidaan vahvistaa tƤllƤ avaimella. twofa_failed_get_secret = Salaisuuden saaminen epƤonnistui. +uid = UID +hidden_comment_types.ref_tooltip = Kommentit missƤ tƤhƤn ongelmaan viitattiin toisesta ongelmasta/kommitista/… [repo] owner=Omistaja @@ -2255,14 +2263,14 @@ pulls.cmd_instruction_merge_warning = Varoitus: Asetusta ā€Tunnista manu pulls.cmd_instruction_merge_desc = YhdistƤ muutokset ja pƤivitƤ Forgejossa. pulls.cannot_auto_merge_desc = TƤtƤ vetopyyntƶƤ ei voida yhdistƤƤ automaattisesti ristiriitojen vuoksi. adopt_preexisting_success = Omaksuttu tiedostot ja luotu tietovarasto lƤhteestƤ %s -issues.comment_manually_pull_merged_at = manuaalisesti yhdistetty kommitti %[1]s %[2]s tietovarastoon %[3]s +issues.comment_manually_pull_merged_at = manuaalisesti yhdisti kommitin %[1]s %[2]s tietovarastoon %[3]s pulls.cmd_instruction_merge_title = YhdistƤ pulls.has_merged = EpƤonnistui: vetopyyntƶ on yhdistetty, joten et voi yhdistƤƤ uudelleen tai muuttaa kohdehaaraa. pulls.cmd_instruction_checkout_title = Uloskuittaus pulls.cmd_instruction_checkout_desc = Kuittaa ulos uusi haara projektitietovarastostasi ja testaa muutokset. pulls.clear_merge_message_hint = YhdistƤmisviestin tyhjentƤminen poistaa vain kommittiviestin sisƤllƶn ja sƤilyttƤƤ luodut git-trailerit, kuten "Co-Authored-By…". settings.protect_check_status_contexts_desc = Vaadi tilatarkistusten lƤpƤisy ennen yhdistƤmistƤ. Kun kƤytƶssƤ, kommitit on ensin tyƶnnettƤvƤ toiseen haaraan ja sitten yhdistettƤvƤ tai tyƶnnettƤvƤ suoraan tƤtƤ sƤƤntƶƤ vastaavaan haaraan tilantarkistuksen jƤlkeen. Jos konteksteja ei lƶydy, viimeisen kommitin on oltava onnistunut kontekstista riippumatta. -issues.comment_pull_merged_at = yhdistetty kommitti %[1]s %[2]s tietovarastoon %[3]s +issues.comment_pull_merged_at = yhdisti kommitin %[1]s %[2]s haaraan %[3]s settings.pulls.enable_autodetect_manual_merge = Ota Tunnista manuaalinen yhdistƤminen automaattisesti -asetus kƤyttƶƶn (Huomaa: joissakin erityistapauksissa voi esiintyƤ virhearviointeja) pulls.no_merge_desc = TƤtƤ vetopyyntƶƤ ei voida yhdistƤƤ, koska kaikki tietovaraston yhdistƤmisvaihtoehdot ovat poistettu kƤytƶstƤ. pulls.no_merge_not_ready = TƤmƤ vetopyyntƶ ei ole valmis yhdistettƤvƤksi. Tarkista katselmoinnin tila ja tilantarkistukset. @@ -3180,7 +3188,7 @@ 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` auto_merge_pull_request = `automaattisesti yhdisti vetopyynnƶn %[3]s#%[2]s` -delete_branch = poisti haaran %[2]s tietovarastosta %[3]s +delete_branch = poisti haaran %[2]s tietovarastosta %[3]s watched_repo = aloitti tietovaraston %[2]s tarkkailun approve_pull_request = `hyvƤksyi %[3]s#%[2]s` starred_repo = lisƤsi tƤhden tietovarastolle %[2]s diff --git a/options/locale/locale_fil.ini b/options/locale/locale_fil.ini index 8c9badb04b..032b8b0435 100644 --- a/options/locale/locale_fil.ini +++ b/options/locale/locale_fil.ini @@ -699,7 +699,7 @@ security = Seguridad avatar = Avatar ssh_gpg_keys = Mga SSH / GPG key applications = Mga Aplikasyon -orgs = Ipamahala ang mga organisasyon +orgs = Mga organisasyon repos = Mga Repositoryo delete = Burahin ang account twofa = Authentikasyong two-factor (TOTP) @@ -707,7 +707,7 @@ account_link = Mga naka-link na account uid = UID webauthn = Authentikasyong two-factor (Mga security key) blocked_users = Mga hinarang na user -public_profile = Pampublikong Profile +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. full_name = Buong pangalan @@ -3758,7 +3758,7 @@ 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 +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` diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini index 1cb7103bc0..0c9df0afa0 100644 --- a/options/locale/locale_fr-FR.ini +++ b/options/locale/locale_fr-FR.ini @@ -1579,7 +1579,7 @@ issues.remove_ref_at=`a supprimĆ© la rĆ©fĆ©rence %s %s.` issues.add_ref_at=`a ajoutĆ© la rĆ©fĆ©rence %s %s.` issues.delete_branch_at=`a supprimĆ© la branche %s %s.` issues.filter_label=Label -issues.filter_label_exclude=`Utilisez Alt + Clic/entrĆ©e pour exclure les labels.` +issues.filter_label_exclude=`Utilisez Alt + Click pour exclure les Ć©tiquettes.` issues.filter_label_no_select=Toutes les labels issues.filter_label_select_no_label=Aucun label issues.filter_milestone=Jalon @@ -3636,7 +3636,7 @@ auto_merge_pull_request=`a fusionnĆ© automatiquement la demande d’ajout %s vers %s push_tag=a poussĆ© l’étiquette %[3]s de %[4]s delete_tag=a supprimĆ© l’étiquette %[2]s de %[3]s -delete_branch=a supprimĆ©e la branche %[2]s de %[3]s +delete_branch=a supprimĆ©e la branche %[2]s de %[3]s compare_branch=Comparer compare_commits=Comparer %d rĆ©visions compare_commits_general=Comparer les rĆ©visions @@ -4091,4 +4091,4 @@ issues.write = Ɖcrire : Fermer des tickets et gĆ©rer les mĆ©tadonnĆ©es t 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 difficile 100 % de complĆ©tion. :-) +test = Ceci est une chaĆ®ne de test. Elle n'est pas affichĆ©e dans Forgejo mĆŖme 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 difficile 100 % de complĆ©tion. :-) diff --git a/options/locale/locale_ga-IE.ini b/options/locale/locale_ga-IE.ini index 3bb06e8c21..1d7414a0d8 100644 --- a/options/locale/locale_ga-IE.ini +++ b/options/locale/locale_ga-IE.ini @@ -132,20 +132,20 @@ 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... +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... +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... +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] @@ -507,12 +507,12 @@ avatar = AbhatĆ”r ssh_gpg_keys = Eochracha SSH/GPG applications = Iarratais repos = Stórais -delete = Scrios Cuntas +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Ć­ +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 @@ -2678,7 +2678,7 @@ auto_merge_pull_request = `iarratas tarraingthe cumasctha go huathoibrĆ­och %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 +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Ć­ diff --git a/options/locale/locale_gl.ini b/options/locale/locale_gl.ini index 3854b375af..c380e9b2ff 100644 --- a/options/locale/locale_gl.ini +++ b/options/locale/locale_gl.ini @@ -196,29 +196,29 @@ link_modal.paste_reminder = Consello: Coa URL no portapapeis, podes pegala direc [search] search = Buscar... type_tooltip = Tipo de procura -repo_kind = Buscar repositorios... -user_kind = Buscar usuarios... +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... +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... +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... +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... +commit_kind = Buscar achegas… +runner_kind = Buscar executores… +pull_kind = Buscar pulls… [startpage] platform = Multiplataforma diff --git a/options/locale/locale_he.ini b/options/locale/locale_he.ini index 19c4815277..8a5bc86163 100644 --- a/options/locale/locale_he.ini +++ b/options/locale/locale_he.ini @@ -150,24 +150,24 @@ union = ×ž×™×œ×•×Ŗ ×ž×¤×Ŗ×— exact = מדויק exact_tooltip = תוצאות ×™×Ŗ××™×ž×• במדויק ×œ×Ŗ×•×›×Ÿ תיבת החיפוש regexp = רג'×§×” -user_kind = חיפוש אנשים... -code_kind = חיפוש קוד... -team_kind = חיפוש ×¦×•×•×Ŗ×™×... +user_kind = חיפוש ×× ×©×™×ā€¦ +code_kind = חיפוש קוד… +team_kind = חיפוש ×¦×•×•×Ŗ×™×ā€¦ no_results = לא נמצאו תוצאות. union_tooltip = תוצאות יכללו ×œ×¤×—×•×Ŗ ×ž×™×œ×Ŗ ×ž×¤×Ŗ×— אחת; אפשר ×œ×”×¤×Ø×™×“ ×ž×™×œ×•×Ŗ ×ž×¤×Ŗ×— עם ×Ø×•×•×—×™× -org_kind = חיפוש ××Ø×’×•× ×™×... -package_kind = חיפוש ×—×‘×™×œ×•×Ŗ... -project_kind = חיפוש ×¤×Ø×•×™×™×§×˜×™×... -branch_kind = חיפוש ענפים... -commit_kind = חיפוש קומיטים... -issue_kind = חיפוש הוגיות... +org_kind = חיפוש ××Ø×’×•× ×™×ā€¦ +package_kind = חיפוש ×—×‘×™×œ×•×Ŗā€¦ +project_kind = חיפוש ×¤×Ø×•×™×™×§×˜×™×ā€¦ +branch_kind = חיפוש ×¢× ×¤×™×ā€¦ +commit_kind = חיפוש ×§×•×ž×™×˜×™×ā€¦ +issue_kind = חיפוש הוגיות… fuzzy_tooltip = תוצאות ×™×Ŗ××™×ž×• ×œ×Ŗ×•×›×Ÿ תיבת החיפוש בקירוב; מומלׄ כנגד שגיאות כתיב -repo_kind = חיפוש ×§×Ø×¤×™×¤×™×... +repo_kind = חיפוש ×§×Ø×¤×™×¤×™×ā€¦ code_search_by_git_grep = תוצאות החיפוש יוצרו על ידי "git grep"; יכול ×œ×”×™×•×Ŗ ×©×™×Ŗ×§×‘×œ×• תוצאות ×˜×•×‘×•×Ŗ יותר אם מנהלי ×”×ž×¢×Ø×›×Ŗ יפעילו את ×”×ž×¤×Ŗ×—×Ÿ. -runner_kind = חיפוש ×ž×Ø×™×¦×™×... +runner_kind = חיפוש ×ž×Ø×™×¦×™×ā€¦ keyword_search_unavailable = חיפוש ×ž×™×œ×•×Ŗ ×ž×¤×Ŗ×— לא זמין. נא לדווח למנהלי ×”×ž×¢×Ø×›×Ŗ. code_search_unavailable = חיפוש קוד לא זמין. נא לדווח למנהלי ×”×ž×¢×Ø×›×Ŗ. -pull_kind = חיפוש בקשות מיזוג... +pull_kind = חיפוש בקשות ×ž×™×–×•×’ā€¦ [heatmap] number_of_contributions_in_the_last_12_months = % ×Ŗ×Ø×•×ž×•×Ŗ ב־12 החודשים ×”××—×Ø×•× ×™× @@ -384,6 +384,8 @@ allow_password_change = הכרחת ×”×ž×©×Ŗ×ž×© לעדכן את ×”×™×”×ž×Ŗ חש account_activated = חשבונך הופעל resent_limit_prompt = כבר ביקשת מייל ××™×ž×•×Ŗ ×‘×©×œ×•×©×Ŗ הדקות האחרונות. נא ×œ×—×›×•×Ŗ ×•×œ× ×”×•×Ŗ שוב. has_unconfirmed_mail = שלום %s, חשבונך משויך ×œ×›×Ŗ×•×‘×Ŗ אימייל לא ×ž××•×ž×Ŗ×Ŗ (%s). אם לא ×§×™×‘×œ×Ŗ הודעת ××™×ž×•×Ŗ באימייל, או שאתה ×¦×Ø×™×š חדשה, נא ללחוׄ על הכפתור למטה. +confirmation_mail_sent_prompt = אימייל ××™×ž×•×Ŗ חדש נשלח ל־%s. יש לבדוק את תיבת הדואר וללחוׄ על הלינק ×Ŗ×•×š %s על ×ž× ×Ŗ להשלים את ×Ø×™×©×•× החשבון. אם כתובת המייל שגוייה, אפשר להיכנה לחשבון ולבקש דוא"ל ××™×ž×•×Ŗ ×œ×›×Ŗ×•×‘×Ŗ אחרת. +reset_password_mail_sent_prompt = אימייל ××™×ž×•×Ŗ חדש נשלח ל־%s. יש לבדוק את תיבת הדואר וללחוׄ על הלינק ×Ŗ×•×š %s על ×ž× ×Ŗ להשלים את ×Ø×™×©×•× החשבון. [settings] key_content = ×Ŗ×•×›×Ÿ @@ -661,6 +663,9 @@ issues.label_exclusive = בחירה בודדת issues.label_archive = ×œ××Ø×›×™×•×Ÿ issues.label_archived_filter = הצגת תוויות ×ž×”××Ø×›×™×•×Ÿ issues.label_archive_tooltip = תוויות ×‘××Ø×›×™×•×Ÿ לא ×ž×•×¦×¢×•×Ŗ בחיפוש על־בהיה תווית כברירת מחדל. +issues.deleted_milestone = נמחק +issues.self_assign_at = `שייךה ×¢×¦×ž×™×Ŗ %s` +issues.deleted_project = נמחק [translation_meta] test = ואהבת לרעך כמוך diff --git a/options/locale/locale_hu-HU.ini b/options/locale/locale_hu-HU.ini index 3e93ee8ba9..841fb76bbe 100644 --- a/options/locale/locale_hu-HU.ini +++ b/options/locale/locale_hu-HU.ini @@ -330,7 +330,7 @@ code_no_results=Nincs talĆ”lat a keresĆ©si kifejezĆ©sedre. code_last_indexed_at=UtoljĆ”ra indexelve: %s [auth] -create_new_account=RegisztrĆ”ció +create_new_account=Fiók regisztrĆ”lĆ”sa register_helper_msg=Van mĆ”r felhasznĆ”lói fiókja? Jelentkezzen be! social_register_helper_msg=Van mĆ”r felhasznĆ”lói fiókja? Csatlakoztassa most! disable_register_prompt=RegisztrĆ”ció le van tiltva. KĆ©rjük, lĆ©pjen kapcsolatba az oldal adminisztrĆ”torĆ”val. @@ -532,8 +532,8 @@ password_change_disabled=A nem helyi felhasznĆ”lók nem frissĆ­thetik jelszavuka emails=E-mail cĆ­mek manage_emails=E-mail cĆ­mek kezelĆ©se -manage_themes=VĆ”lassza ki az alapĆ©rtelmezett tĆ©mĆ”t -manage_openid=OpenID cĆ­mek kezelĆ©se +manage_themes=AlapĆ©rtelmezett tĆ©ma +manage_openid=OpenID cĆ­mek theme_desc=Ez lesz az alapĆ©rtelmezett tĆ©ma az oldalon. primary=Elsődleges activated=AktivĆ”lt @@ -1694,7 +1694,7 @@ create_repo=lĆ©trehozott tĆ”rolót: %s rename_repo=Ć”tnevezte a(z) %[1]s tĆ”rolót %[3]s-ra/re transfer_repo=Ć”thelyezett egy tĆ”rolót innen: %s ide: %s delete_tag=cĆ­mke %[2]s tƶrƶlve innen: %[3]s -delete_branch=Ć”g %[2]s tƶrƶlve innen: %[3]s +delete_branch=Ć”g %[2]s tƶrƶlve innen: %[3]s compare_branch=ƖsszehasonlĆ­tĆ”s compare_commits=%d commit ƶsszehasonlĆ­tĆ”sa compare_commits_general=Commitok ƶsszehasonlĆ­tĆ”sa @@ -1779,14 +1779,14 @@ directory = KƶnyvtĆ”r [search] search = KeresĆ©s... type_tooltip = KeresĆ©s tĆ­pusa -code_kind = Kód keresĆ©se... +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... +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... @@ -1794,8 +1794,8 @@ 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... +branch_kind = Ɓgak keresĆ©se… no_results = Nincsenek megfelelő talĆ”latok. -issue_kind = Hibajegyek keresĆ©se... +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 f1a392105e..c935bd9540 100644 --- a/options/locale/locale_id-ID.ini +++ b/options/locale/locale_id-ID.ini @@ -206,9 +206,9 @@ email_title = Pengaturan email smtp_from = Kirim Email Sebagai [home] -uname_holder=Nama Pengguna atau Alamat Surel +uname_holder=Nama pengguna atau alamat surel password_holder=Kata Sandi -switch_dashboard_context=Alihkan Dasbor Konteks +switch_dashboard_context=Alihkan dasbor konteks my_repos=Repositori show_more_repos=Tampilkan repositori lainnya… collaborative_repos=Repositori Kolaboratif @@ -236,7 +236,7 @@ org_no_results=Tidak ada organisasi yang cocok ditemukan. code_no_results=Tidak ada kode sumber yang cocok dengan istilah yang anda cari. [auth] -create_new_account=Daftar Akun +create_new_account=Daftar akun register_helper_msg=Sudah memiliki akun? Masuk sekarang! social_register_helper_msg=Sudah memiliki akun? Hubungkan sekarang! disable_register_prompt=Maaf, pendaftaran telah dinonaktifkan. Silakan hubungi administrator situs. @@ -269,11 +269,11 @@ twofa_passcode_incorrect=Kata sandi Anda salah. Jika Anda salah tempatkan perang twofa_scratch_token_incorrect=Kode coretan anda tidak tepat. login_userpass=Masuk tab_openid=OpenID -oauth_signup_tab=Daftar Akun Baru -oauth_signup_submit=Akun Lengkap -oauth_signin_tab=Tautkan ke Akun yang Tersedia -oauth_signin_title=Masuk untuk Izinkan Akun Tertaut -oauth_signin_submit=Taut Akun +oauth_signup_tab=Daftar akun baru +oauth_signup_submit=Akun lengkap +oauth_signin_tab=Tautkan ke akun yang tersedia +oauth_signin_title=Masuk untuk izinkan akun tertaut +oauth_signin_submit=Taut akun openid_connect_submit=Sambungkan openid_connect_title=Sambungkan ke akun yang sudah ada openid_connect_desc=OpenID URI yang dipilih tak dikenal. Asosiasikan dengan akun baru disini. @@ -398,14 +398,14 @@ avatar=Avatar ssh_gpg_keys=Kunci SSH / GPG social=Akun Sosial applications=Aplikasi -orgs=Kelola organisasi +orgs=Organisasi repos=Repositori -delete=Hapus Akun +delete=Hapus akun twofa=Otentikasi Dua-Faktor account_link=Akun Tertaut organization=Organisasi -public_profile=Profil Publik +public_profile=Profil publik password_username_disabled=Pengguna non-lokal tidak diizinkan untuk mengubah nama pengguna mereka. Silakan hubungi administrator sistem anda untuk lebih lanjut. full_name=Nama Lengkap website=Situs Web @@ -438,8 +438,8 @@ password_change_disabled=Pengguna non-lokal tidak dapat mengganti kata sandi mer emails=Alamat Surel manage_emails=Kelola Alamat Surel -manage_themes=Pilih tema default -manage_openid=Kelola alamat OpenID +manage_themes=Tema default +manage_openid=Alamat OpenID theme_desc=Ini akan menjadi tema asal Anda pada keseluruhan situs. primary=Utama activated=Diaktifkan @@ -1368,7 +1368,7 @@ create_repo=repositori dibuat %s rename_repo=ganti nama gudang penyimpanan dari %[1]s ke %[3]s transfer_repo=ditransfer repositori %s ke %s delete_tag=tag dihapus %[2]s dari %[3]s -delete_branch=cabang dihapus %[2]s dari %[3]s +delete_branch=cabang dihapus %[2]s dari %[3]s compare_commits=Bandingkan %d melakukan [tool] @@ -1484,10 +1484,10 @@ 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... +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... +branch_kind = Cari cabang… diff --git a/options/locale/locale_is-IS.ini b/options/locale/locale_is-IS.ini index baf8286923..f3333dbea2 100644 --- a/options/locale/locale_is-IS.ini +++ b/options/locale/locale_is-IS.ini @@ -223,7 +223,7 @@ default_keep_email_private.description=Fela sjĆ”lfgefiư netfƶng nýrra notenda no_reply_address_helper=LĆ©n fyrir notendur meư faliư netfang. Til dƦmis notandanafniư ā€žjoeā€œ verưur skrƔư Ć­ Git sem ā€žjoe@noreply.example.orgā€œ ef faliư tƶlvupóstlĆ©n er stillt Ć” ā€žnoreply.example.orgā€œ. [home] -uname_holder=Notandanafn eưa Netfang +uname_holder=Notandanafn eưa netfang password_holder=Lykilorư my_repos=HugbĆŗnaưarsƶfn show_more_repos=Sýna fleiri hugbĆŗnaưarsƶfn… @@ -255,7 +255,7 @@ org_no_results=Engar samsvarandi stofnanir fundust. code_no_results=Enginn samsvarandi frumkóði fannst eftur þínum leitarorưum. [auth] -create_new_account=SkrĆ” Notanda +create_new_account=SkrĆ” notanda register_helper_msg=Ertu nĆŗ þegar meư notanda? SkrƔưu þig inn nĆŗna! social_register_helper_msg=Ertu nĆŗ þegar meư reikning? Tengdu hann nĆŗna! manual_activation_only=Hafưu samband viư stjórnanda vefsvƦưisins til aư ljĆŗka virkjun. @@ -276,13 +276,13 @@ verify=Staưfesta scratch_code=Skrapkóði use_scratch_code=Nota skrapkóða twofa_scratch_token_incorrect=Skrapkóði þinn er rangur. -login_userpass=SkrĆ” Inn +login_userpass=SkrĆ” inn tab_openid=OpenID -oauth_signup_tab=SkrĆ” Nýjan Notanda -oauth_signup_title=KlĆ”ra Nýjum Notanda -oauth_signup_submit=KlĆ”ra Notanda -oauth_signin_tab=Tengja NĆŗverandi Reikning -oauth_signin_submit=Tengja Notanda +oauth_signup_tab=SkrĆ” nýjan notanda +oauth_signup_title=KlĆ”ra nýjum notanda +oauth_signup_submit=KlĆ”ra notanda +oauth_signin_tab=Tengja nĆŗverandi reikning +oauth_signin_submit=Tengja notanda openid_connect_submit=Tengjast openid_register_title=SkrĆ” nýjan notanda disable_forgot_password_mail=Endurheimting reiknings er óvirk vegna þess aư enginn tƶlvupóstur er uppsettur. Vinsamlegast hafưu samband viư sƭưustjórann þinn. @@ -434,15 +434,15 @@ avatar=Notandamynd ssh_gpg_keys=SSH og GPG Lyklar social=FĆ©lagsreikningar applications=Forrit -orgs=Stjórna Stofnunum +orgs=Stofnanir repos=HugbĆŗnaưarsƶfn -delete=Eyưa Reikningi +delete=Eyưa reikningi twofa=Tvíþætt Auưkenning account_link=Tengdir Reikningar organization=Stofnanir webauthn=Ɩryggislyklar -public_profile=Opinber Notandasƭưa +public_profile=Opinber notandasƭưa password_username_disabled=Notendum utan staưarins er ekki heimilt aư breyta notendanafni sĆ­nu. Vinsamlegast hafưu samband viư sƭưustjórann þinn til aư fĆ” frekari upplýsingar. full_name=Fullt Nafn website=Vefsƭưa diff --git a/options/locale/locale_it-IT.ini b/options/locale/locale_it-IT.ini index d46f709cde..d9acc4c430 100644 --- a/options/locale/locale_it-IT.ini +++ b/options/locale/locale_it-IT.ini @@ -423,7 +423,7 @@ allow_password_change=Richiede all'utente di cambiare la password (scelta consig 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 +prohibit_login=L'account ĆØ sospeso 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 @@ -742,7 +742,7 @@ avatar=Avatar ssh_gpg_keys=Chiavi SSH / GPG social=Account Sociali applications=Applicazioni -orgs=Gestisci le organizzazioni +orgs=Organizzazioni repos=Repositori delete=Elimina account twofa=Verifica in due passaggi @@ -803,8 +803,8 @@ password_change_disabled=Gli utenti non locali non possono cambiare la loro pass emails=Indirizzi email manage_emails=Gestisci indirizzi email -manage_themes=Seleziona il tema predefinito -manage_openid=Gestisci gli indirizzi OpenID +manage_themes=Tema predefinito +manage_openid=Indirizzi OpenID theme_desc=Questo sarĆ  il tuo tema di predefinito in tutto il sito. primary=Primario activated=Attivato @@ -3624,7 +3624,7 @@ 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 -delete_branch=branch eliminato %[2]s da %[3]s +delete_branch=branch eliminato %[2]s da %[3]s compare_branch=Confronta compare_commits=Confronta %d commits compare_commits_general=Confronta commit @@ -4014,25 +4014,25 @@ type_tooltip = Tipo ricerca search = Cerca… fuzzy = Approssimativa match = Precisa -org_kind = Cerca organizzazioni... -package_kind = Ricerca pacchetti... +org_kind = Cerca organizzazioni… +package_kind = Ricerca pacchetti… 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_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... -commit_kind = Ricerca commit... -branch_kind = Ricerca rami... +project_kind = Ricerca progetti… +commit_kind = Ricerca commit… +branch_kind = Ricerca rami… no_results = Non ĆØ stato trovato alcun risultato. keyword_search_unavailable = La ricerca per parole chiave non ĆØ attualmente disponibile. Contatta l'amministratore del sito. -runner_kind = Ricerca esecutori... +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 repo... +user_kind = Cerca utenti… +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... +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 diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini index 555f5c6a75..d7c657b149 100644 --- a/options/locale/locale_ja-JP.ini +++ b/options/locale/locale_ja-JP.ini @@ -250,7 +250,7 @@ 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=ē®”ē†č€…ć®ćƒ¦ćƒ¼ć‚¶ćƒ¼åćŒäøę­£ć§ć™ @@ -1047,6 +1047,7 @@ language.title = ę—¢å®šć®čØ€čŖž keep_activity_private.description = å…¬é–‹ć‚¢ć‚Æćƒ†ć‚£ćƒ“ćƒ†ć‚£ćÆć€ć‚ćŖćŸćØć‚¤ćƒ³ć‚¹ć‚æćƒ³ć‚¹ē®”ē†č€…ć«ć®ćæč”Øē¤ŗć•ć‚Œć¾ć™ć€‚ language.description = ć“ć®čØ€čŖžćÆć‚¢ć‚«ć‚¦ćƒ³ćƒˆć«äæå­˜ć•ć‚Œć€ćƒ­ć‚°ć‚¤ćƒ³å¾Œć«ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆćØć—ć¦ä½æē”Øć•ć‚Œć¾ć™ć€‚ language.localization_project = Forgejo ć‚’ć‚ćŖćŸć®čØ€čŖžć«ēæ»čØ³ć™ć‚‹ć®ć‚’ę‰‹ä¼ć£ć¦ćć ć•ć„ć€‚č©³ē“°ćÆć“ć”ć‚‰ć€‚ +quota = ć‚Æć‚Ŗćƒ¼ć‚æ [repo] new_repo_helper=ćƒŖćƒć‚øćƒˆćƒŖć«ćÆć€ćƒ—ćƒ­ć‚øć‚§ć‚Æćƒˆć®ć™ć¹ć¦ć®ćƒ•ć‚”ć‚¤ćƒ«ćØćƒŖćƒ“ć‚øćƒ§ćƒ³å±„ę­“ćŒå…„ć‚Šć¾ć™ć€‚ ć™ć§ć«ć»ć‹ć®å “ę‰€ć§ćƒ›ć‚¹ćƒˆć—ć¦ć„ć¾ć™ć‹ļ¼Ÿ ćƒŖćƒć‚øćƒˆćƒŖć‚’ē§»č”Œ 悂恩恆恞怂 @@ -3536,7 +3537,7 @@ auto_merge_pull_request=`ćŒćƒ—ćƒ«ćƒŖć‚Æć‚Øć‚¹ćƒˆ %[3]s#%[2]s%s 悒 %s ćøē§»č»¢ć—ć¾ć—ćŸ push_tag=ćŒć‚æć‚° %[3]s 悒 %[4]s ć«ćƒ—ćƒƒć‚·ćƒ„ć—ć¾ć—ćŸ delete_tag=ćŒć‚æć‚° %[2]s 悒 %[3]s ć‹ć‚‰å‰Šé™¤ć—ć¾ć—ćŸ -delete_branch=ćŒćƒ–ćƒ©ćƒ³ćƒ %[2]s 悒 %[3]s ć‹ć‚‰å‰Šé™¤ć—ć¾ć—ćŸ +delete_branch=ćŒćƒ–ćƒ©ćƒ³ćƒ %[2]s 悒 %[3]s ć‹ć‚‰å‰Šé™¤ć—ć¾ć—ćŸ compare_branch=ęÆ”č¼ƒ compare_commits=%dä»¶ć®ć‚³ćƒŸćƒƒćƒˆć‚’ęÆ”č¼ƒ compare_commits_general=ć‚³ćƒŸćƒƒćƒˆć‚’ęÆ”č¼ƒ @@ -3903,20 +3904,20 @@ submodule=ć‚µćƒ–ćƒ¢ć‚øćƒ„ćƒ¼ćƒ« [search] search = 検瓢... type_tooltip = ę¤œē“¢ć‚æć‚¤ćƒ— -org_kind = ēµ„ē¹”ć®ę¤œē“¢... -code_kind = ć‚³ćƒ¼ćƒ‰ć®ę¤œē“¢... +org_kind = ēµ„ē¹”ć‚’ę¤œē“¢ā€¦ +code_kind = ć‚³ćƒ¼ćƒ‰ć‚’ę¤œē“¢ā€¦ fuzzy = あいまい -repo_kind = ćƒŖćƒć‚øćƒˆćƒŖć®ę¤œē“¢... +repo_kind = ćƒŖćƒć‚øćƒˆćƒŖć‚’ę¤œē“¢ā€¦ code_search_unavailable = ć‚³ćƒ¼ćƒ‰ę¤œē“¢ćÆē¾åœØåˆ©ē”Øć§ćć¾ć›ć‚“ć€‚ć‚µć‚¤ćƒˆē®”ē†č€…ć«ćŠå•ć„åˆć‚ć›ćć ć•ć„ć€‚ -branch_kind = ćƒ–ćƒ©ćƒ³ćƒć®ę¤œē“¢... -commit_kind = ć‚³ćƒŸćƒƒćƒˆć®ę¤œē“¢... -user_kind = ćƒ¦ćƒ¼ć‚¶ćƒ¼ć®ę¤œē“¢... -team_kind = チームの検瓢... +branch_kind = ćƒ–ćƒ©ćƒ³ćƒć‚’ę¤œē“¢ā€¦ +commit_kind = ć‚³ćƒŸćƒƒćƒˆć‚’ę¤œē“¢ā€¦ +user_kind = ćƒ¦ćƒ¼ć‚¶ćƒ¼ć‚’ę¤œē“¢ā€¦ +team_kind = ćƒćƒ¼ćƒ ć‚’ę¤œē“¢ā€¦ code_search_by_git_grep = ē¾åœØć®ć‚³ćƒ¼ćƒ‰ę¤œē“¢ēµęžœćÆć€Œgit grepć€ć«ć‚ˆć£ć¦ęä¾›ć•ć‚Œć¾ć™ć€‚ć‚µć‚¤ćƒˆē®”ē†č€…ćŒć‚³ćƒ¼ćƒ‰ ć‚¤ćƒ³ćƒ‡ć‚Æć‚µćƒ¼ć‚’ęœ‰åŠ¹ć«ć™ć‚‹ćØć€ć‚ˆć‚Šč‰Æć„ēµęžœćŒå¾—ć‚‰ć‚Œć‚‹åÆčƒ½ę€§ćŒć‚ć‚Šć¾ć™ć€‚ -package_kind = ćƒ‘ćƒƒć‚±ćƒ¼ć‚øć®ę¤œē“¢... -project_kind = ćƒ—ćƒ­ć‚øć‚§ć‚Æćƒˆć®ę¤œē“¢... +package_kind = ćƒ‘ćƒƒć‚±ćƒ¼ć‚øć‚’ę¤œē“¢ā€¦ +project_kind = ćƒ—ćƒ­ć‚øć‚§ć‚Æćƒˆć‚’ę¤œē“¢ā€¦ keyword_search_unavailable = ć‚­ćƒ¼ćƒÆćƒ¼ćƒ‰ć«ć‚ˆć‚‹ę¤œē“¢ćÆē¾åœØć”åˆ©ē”Øć„ćŸć ć‘ć¾ć›ć‚“ć€‚ć‚µć‚¤ćƒˆē®”ē†č€…ć«ćŠå•ć„åˆć‚ć›ćć ć•ć„ć€‚ -runner_kind = ランナーの検瓢... +runner_kind = ćƒ©ćƒ³ćƒŠćƒ¼ć‚’ę¤œē“¢ā€¦ no_results = äø€č‡“ć™ć‚‹ēµęžœćŒč¦‹ć¤ć‹ć‚Šć¾ć›ć‚“ć§ć—ćŸć€‚ fuzzy_tooltip = å…„åŠ›ć•ć‚ŒćŸčŖžå„ć«čæ‘ć„ć‚‚ć®ć‚‚ēµęžœć«å«ć‚ć‚‹ match = 一臓 @@ -3924,8 +3925,8 @@ match_tooltip = ę¤œē“¢čŖžå„ć«åŽ³åÆ†ć«äø€č‡“ć™ć‚‹ć‚‚ć®ć®ćæēµęžœć«å«ć‚ milestone_kind = ćƒžć‚¤ćƒ«ć‚¹ćƒˆćƒ¼ćƒ³ć‚’ę¤œē“¢... union_tooltip = ē©ŗē™½ć§åŒŗåˆ‡ć‚‰ć‚ŒćŸć‚­ćƒ¼ćƒÆćƒ¼ćƒ‰ć®ć„ćšć‚Œć‹ć«äø€č‡“ć™ć‚‹ēµęžœć‚’å«ć‚ć‚‹ exact_tooltip = ę¤œē“¢čŖžå„ćØå®Œå…Øć«äø€č‡“ć™ć‚‹ēµęžœć®ćæć‚’å«ć‚ć‚‹ -issue_kind = ć‚¤ć‚·ćƒ„ćƒ¼ć‚’ę¤œē“¢... -pull_kind = ćƒ—ćƒ«ć‚’ę¤œē“¢... +issue_kind = ć‚¤ć‚·ćƒ„ćƒ¼ć‚’ę¤œē“¢ā€¦ +pull_kind = ćƒ—ćƒ«ć‚’ę¤œē“¢ā€¦ exact = å®Œå…Øäø€č‡“ regexp_tooltip = ę¤œē“¢čŖžå„ć‚’ę­£č¦č”Øē¾ćØć—ć¦č§£é‡ˆć™ć‚‹ regexp = ę­£č¦č”Øē¾ diff --git a/options/locale/locale_ko-KR.ini b/options/locale/locale_ko-KR.ini index be0400bea4..8e8d9b1d6b 100644 --- a/options/locale/locale_ko-KR.ini +++ b/options/locale/locale_ko-KR.ini @@ -588,8 +588,8 @@ password_change_disabled=딜컬 ģœ ģ €ź°€ ģ•„ė‹Œ 경우 Forgejo 웹 ģøķ„°ķŽ˜ģ“ emails=ģ“ė©”ģ¼ ģ£¼ģ†Œ manage_emails=ģ“ė©”ģ¼ ģ£¼ģ†Œ ꓀리 -manage_themes=źø°ė³ø ķ…Œė§ˆ ģ„ ķƒ -manage_openid=OpenID ģ£¼ģ†Œ ꓀리 +manage_themes=źø°ė³ø ķ…Œė§ˆ +manage_openid=OpenID ģ£¼ģ†Œ theme_desc=ģ“ ķ…Œė§ˆź°€ ģ‚¬ģ“ķŠø 전첓 źø°ė³ø ķ…Œė§ˆź°€ ė©ė‹ˆė‹¤. primary=ėŒ€ķ‘œ activated=ķ™œģ„±ķ™”ėØ @@ -1900,9 +1900,9 @@ runs.commit=커밋 [search] code_search_by_git_grep = ķ˜„ģž¬ ģ½”ė“œ ź²€ģƒ‰ ź²°ź³¼ėŠ” "git grep"에 ģ˜ķ•“ ģ œź³µė©ė‹ˆė‹¤.ź“€ė¦¬ģžź°€ ģ½”ė“œ ģøė±ģ„œė„¼ ķ™œģ„±ķ™”ķ•˜ė©“ ė” ė‚˜ģ€ 결과가 제공될 수 ģžˆģŠµė‹ˆė‹¤. -branch_kind = ėøŒėžœģ¹˜ ź²€ģƒ‰... +branch_kind = ėøŒėžœģ¹˜ ź²€ģƒ‰ā€¦ keyword_search_unavailable = ģ§€źøˆģ€ ķ‚¤ģ›Œė“œė”œ ź²€ģƒ‰ģ“ ģ§€ģ›ė˜ģ§€ ģ•ŠģŠµė‹ˆė‹¤. ģ‚¬ģ“ķŠø ź“€ė¦¬ģžģ—ź²Œ ė¬øģ˜ķ•˜ģ‹­ģ‹œģ˜¤. -commit_kind = 커밋 ź²€ģƒ‰... +commit_kind = 커밋 ź²€ģƒ‰ā€¦ no_results = ģ¼ģ¹˜ķ•˜ėŠ” 결과넼 ģ°¾ģ„ 수 ģ—†ģŠµė‹ˆė‹¤. search = ź²€ģƒ‰ā€¦ type_tooltip = ź²€ģƒ‰ ķƒ€ģž… @@ -1910,11 +1910,11 @@ fuzzy_tooltip = ź²€ģƒ‰ģ–“ģ™€ ė°€ģ ‘ķ•˜ź²Œ ģ¼ģ¹˜ķ•˜ėŠ” ź²°ź³¼ė„ ķ¬ķ•Ø repo_kind = ģ €ģž„ģ†Œ ź²€ģƒ‰ā€¦ user_kind = ģ‚¬ģš©ģž ź²€ģƒ‰ā€¦ org_kind = 씰직 ź²€ģƒ‰ā€¦ -team_kind = ķŒ€ ź²€ģƒ‰... -code_kind = ģ½”ė“œ ź²€ģƒ‰... +team_kind = ķŒ€ ź²€ģƒ‰ā€¦ +code_kind = ģ½”ė“œ ź²€ģƒ‰ā€¦ code_search_unavailable = ģ½”ė“œ ź²€ģƒ‰ģ€ ķ˜„ģž¬ ķ—ˆģš©ė˜ģ§€ ģ•Šģ•˜ģŠµė‹ˆė‹¤. ģ‚¬ģ“ķŠø ź“€ė¦¬ģžģ™€ ģ—°ė½ķ•˜ģ„øģš”. -package_kind = ķŒØķ‚¤ģ§€ ź²€ģƒ‰... -project_kind = ķ”„ė”œģ ķŠø ź²€ģƒ‰... +package_kind = ķŒØķ‚¤ģ§€ ź²€ģƒ‰ā€¦ +project_kind = ķ”„ė”œģ ķŠø ź²€ģƒ‰ā€¦ exact_tooltip = ź²€ģƒ‰ģ–“ģ™€ ģ •ķ™•ķ•˜ź²Œ ģ¼ģ¹˜ķ•˜ėŠ” 결과만 ķ¬ķ•Ø issue_kind = ģ“ģŠˆ ź²€ģƒ‰ā€¦ pull_kind = ķ’€ ź²€ģƒ‰ā€¦ diff --git a/options/locale/locale_lt.ini b/options/locale/locale_lt.ini index 868e5bff6e..9d1c938379 100644 --- a/options/locale/locale_lt.ini +++ b/options/locale/locale_lt.ini @@ -149,24 +149,24 @@ 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... +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ų... +repo_kind = IeÅ”koti saugyklų… code_search_unavailable = Kodų paieÅ”ka Å”iuo metu nepasiekiama. Kreipkis ÄÆ svetainės administratorių. -org_kind = IeÅ”koti organizacijų... +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ų... +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ų... +issue_kind = IeÅ”koti problemų… +branch_kind = IeÅ”koti Å”akų… milestone_kind = IeÅ”koti gairių... -pull_kind = IeÅ”koti sujungimų... +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ÄÆ diff --git a/options/locale/locale_lv-LV.ini b/options/locale/locale_lv-LV.ini index 98baff217b..e8ee85c61a 100644 --- a/options/locale/locale_lv-LV.ini +++ b/options/locale/locale_lv-LV.ini @@ -1577,7 +1577,7 @@ 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 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_exclude=Jāizmanto Alt + klikŔķis, 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 @@ -3635,7 +3635,7 @@ auto_merge_pull_request=`automātiski iekļāva izmaiņu pieprasÄ«jumu %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 +delete_branch=izdzēsa zaru %[2]s no %[3]s compare_branch=SalÄ«dzināt compare_commits=SalÄ«dzināt %d iesÅ«tÄ«jumus compare_commits_general=SalÄ«dzināt iesÅ«tÄ«jumus diff --git a/options/locale/locale_ml-IN.ini b/options/locale/locale_ml-IN.ini index fcc9888d8e..c4c266ad86 100644 --- a/options/locale/locale_ml-IN.ini +++ b/options/locale/locale_ml-IN.ini @@ -356,7 +356,7 @@ avatar=ą“…ą“µą“¤ą“¾ą“°ąµā€ ssh_gpg_keys=SSH / GPG ą“•ąµ€ą“•ą“³ąµā€ social=ą“øąµ‹ą“·ąµą“Æąµ½ ą“…ą“•ąµą“•ąµ—ą“£ąµą“Ÿąµą“•ąµ¾ applications=ą“…ą“Ŗąµą“²ą“æą“•ąµą“•ąµ‡ą“·ą“Øąµą“•ąµ¾ -orgs=ą“øą“‚ą“˜ą“Ÿą“Øą“•ą“³ąµ† ą“Øą“æą“Æą“Øąµą“¤ąµą“°ą“æą“•ąµą“•ąµą“• +orgs=ą“øą“‚ą“˜ą“Ÿą“Øą“•ąµ¾ repos=ą“•ą“²ą“µą“±ą“•ą“³ąµā€ delete=ą“…ą“•ąµą“•ąµ—ą“£ąµą“Ÿąµ ą“‡ą“²ąµą“²ą“¾ą“¤ą“¾ą“•ąµą“•ąµą“• twofa=ą“‡ą“°ą“Ÿąµą“Ÿ ą“˜ą“Ÿą“• ą“Ŗąµą“°ą“¾ą“®ą“¾ą“£ąµ€ą“•ą“°ą“£ą“‚ @@ -400,8 +400,8 @@ password_change_disabled=ą“Ŗąµą“°ą“¾ą“¦ąµ‡ą“¶ą“æą“• ą“‡ą“¤ą“° ą“‰ą“Ŗą“Æąµ‹ą“• emails=ą“‡-ą“®ąµ†ą“Æą“æą“²ąµā€ ą“µą“æą“²ą“¾ą“øą“™ąµą“™ą“³ąµā€ manage_emails=ą“‡ą“®ąµ†ą“Æą“æąµ½ ą“µą“æą“²ą“¾ą“øą“™ąµą“™ąµ¾ ą“Øą“æą“Æą“Øąµą“¤ąµą“°ą“æą“•ąµą“•ąµą“• -manage_themes=ą“øąµą“„ą“æą“°ą“øąµą“„ą“æą“¤ą“æ ą“Ŗąµą“°ą“®ąµ‡ą“Æą“‚ ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“• -manage_openid=ą““ą“Ŗąµą“Ŗąµŗą“ą“”ą“æ ą“µą“æą“²ą“¾ą“øą“™ąµą“™ąµ¾ ą“Øą“æą“Æą“Øąµą“¤ąµą“°ą“æą“•ąµą“•ąµą“• +manage_themes=ą“”ą“æą“«ąµ‹ąµ¾ą“Ÿąµą“Ÿąµ ą“¤ąµ€ą“‚ +manage_openid=OpenID ą“µą“æą“²ą“¾ą“øą“™ąµą“™ąµ¾ email_desc=ą“…ą“±ą“æą“Æą“æą“Ŗąµą“Ŗąµą“•ąµ¾ą“•ąµą“•ąµą“‚ ą“®ą“±ąµą“±ąµ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øą“™ąµą“™ąµ¾ą“•ąµą“•ąµą“®ą“¾ą“Æą“æ ą“Øą“æą“™ąµą“™ą“³ąµą“Ÿąµ† ą“Ŗąµą“°ą“¾ą“„ą“®ą“æą“• ą“‡ą“®ąµ†ą“Æą“æąµ½ ą“µą“æą“²ą“¾ą“øą“‚ ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“•ąµą“•ąµą“‚. theme_desc=ą“øąµˆą“±ąµą“±ą“æą“²ąµą“Ÿą“Øąµ€ą“³ą“‚ ą“‡ą“¤ąµ ą“Øą“æą“™ąµą“™ą“³ąµą“Ÿąµ† ą“øąµą“„ą“æą“°ą“øąµą“„ą“æą“¤ą“æ ą“Ŗąµą“°ą“®ąµ‡ą“Æą“‚ ą“†ą“Æą“æą“°ą“æą“•ąµą“•ąµą“‚. primary=ą“Ŗąµą“°ą“¾ą“„ą“®ą“æą“•ą“‚ diff --git a/options/locale/locale_nb_NO.ini b/options/locale/locale_nb_NO.ini index 2c8b5cfc64..59673fd4e3 100644 --- a/options/locale/locale_nb_NO.ini +++ b/options/locale/locale_nb_NO.ini @@ -60,7 +60,7 @@ rerun = KjĆør pĆ„ nytt rerun_all = KjĆør alle jobber pĆ„ nytt save = Lagre cancel = Avbryt -forks = Forks +forks = Kopier milestones = MilepƦler ok = OK test = Test @@ -133,14 +133,42 @@ webauthn_error_duplicated = SikkerhetsnĆøkkelen er ikke tillatt for denne foresp 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 +error413 = Du har brukt opp kvoten din. +issues = Saker +unpin = LĆøsne +filter.is_fork = Forks +filter.not_fork = Ikke forks +pull_requests = Pull requests +copy_branch = Kopier branch navn +error404 = Siden du forsĆøker Ć„ nĆ„ eksisterer ikke, er blitt fjernet eller du har ikke tilgang til Ć„ se den. +tracked_time_summary = Oppsummering av sporet tid basert pĆ„ problemfiltre [search] -search = SĆøk... +search = SĆøk… type_tooltip = SĆøketype fuzzy = Fuzzy union = Union regexp = RegExp exact = NĆøyaktig +team_kind = SĆøk i teams… +code_kind = SĆøk i kode… +package_kind = SĆøk i pakker… +project_kind = SĆøk i prosjekter… +branch_kind = SĆøk i brancher… +commit_kind = SĆøk i commits… +regexp_tooltip = Tolk sĆøkeordet som et regulƦruttrykk +pull_kind = SĆøk i pulls… +keyword_search_unavailable = SĆøk etter nĆøkkelord er for Ćøyeblikket ikke tilgjengelig. Kontakt administratoren. +exact_tooltip = Inkluder kun resultater som samsvarer nĆøyaktig med sĆøkeordet +repo_kind = SĆøk i repositorer… +fuzzy_tooltip = Inkluder resultater som ogsĆ„ stemmer godt overens med sĆøketermen +org_kind = SĆøk i organisasjoner… +issue_kind = SĆøk i saker… +runner_kind = SĆøk i runners… +no_results = Ingen treff funnet. +union_tooltip = Inkluder resultater som samsvarer med ett eller flere av nĆøkkelordene adskilt med mellomrom +code_search_unavailable = KodesĆøk er ikke tilgjengelig. Kontakt administratoren. +user_kind = SĆøk i brukere… [auth] verify = Bekreft @@ -152,4 +180,88 @@ 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 +uname_holder = Brukernavn eller e-postadresse + +[heatmap] +contributions_zero = Ingen bidrag +number_of_contributions_in_the_last_12_months = %s bidrag de siste 12 mĆ„nedene +contributions_one = bidrag +contributions_format = {contributions} den {day} {month} {year} +less = Mindre +contributions_few = bidrag +more = Mer + +[editor] +buttons.heading.tooltip = Legg til overskrift +buttons.bold.tooltip = Legg til uthevet tekst +buttons.italic.tooltip = Legg til kursiv text +buttons.list.unordered.tooltip = Legg til punktliste +buttons.list.ordered.tooltip = Legg til nummerert liste +buttons.link.tooltip = Legg til link +buttons.quote.tooltip = Siter tekst +buttons.mention.tooltip = Nevn en bruker eller team +buttons.list.task.tooltip = Legg til liste over saker +buttons.code.tooltip = Legg til kode +table_modal.header = Legg til tabell +table_modal.placeholder.header = Overskrift +table_modal.placeholder.content = Innhold +table_modal.label.columns = Kolonner +buttons.new_table.tooltip = Legg til tabell +table_modal.label.rows = Rader +buttons.switch_to_legacy.tooltip = Bruk den gamle editoren istedenfor +buttons.disable_monospace_font = Deaktiver monospace font +buttons.ref.tooltip = Referanse til en sak eller pull request +buttons.indent.tooltip = Grupper elementene med et nivĆ„ +buttons.unindent.tooltip = Pakk ut elementene med et nivĆ„ +link_modal.url = Url +link_modal.description = Beskrivelse +link_modal.header = Legg til en link +buttons.enable_monospace_font = Aktiver monospace font +link_modal.paste_reminder = Tips: NĆ„r du har en URL i utklippstavlen kan du lime den direkte inn i editoren for Ć„ lage en lenke. + +[aria] +footer = Bunntekst +navbar = Navigasjonslinje +footer.links = Linker +footer.software = Om dette programmet + +[filter] +string.asc = A - Z +string.desc = Z - A + +[error] +occurred = En feil oppstod +not_found = Kunne ikke finne mĆ„let. +report_message = Hvis du mener dette er en feil i Forgejo kan du sĆøke pĆ„ Codeberg eller Ć„pne en ny sak. +network_error = Nettverks feil +server_internal = Intern server feil + +[install] +docker_helper = Dersom du bruker Forgejo med Docker, anbefales det Ć„ lese dokumentasjonen fĆør du gjĆør endringer i konfigurasjonen. +db_title = Database innstillinger +require_db_desc = Forgejo krever MySQL, PostgreSQL, SQLite3 eller TiDB (MySQL protokoll). +db_type = Database type +password = Passord +user = Brukernavn +install = Installasjon +title = FĆørstegangsoppsett +host = Server +db_name = Database navn +db_schema = Skjema +db_schema_helper = La stĆ„ tomt for databasens standardverdi ("public"). +ssl_mode = SSL +path = Sti +sqlite_helper = Sti til SQLite3-databasen.
Bruk absolutt filsti dersom Forgejo kjĆøres som en tjeneste. +reinstall_error = Du prĆøver Ć„ installere i en eksisterende Forgejo-database +reinstall_confirm_message = ƅ installere pĆ„ nytt med en eksisterende Forgejo-database kan fĆøre til problemer. I de fleste tilfeller bĆør du bruke din eksisterende "app.ini" for Ć„ kjĆøre Forgejo. Hvis du vet hva du gjĆør, og vil fortsette, bekreft fĆølgende: + +[startpage] +install = Enkel Ć„ installere +platform = Plattformuavhengig +install_desc = Du kan enkelt kjĆøre programfilen for din platform, bruke Docker, eller hente den som en ferdig pakke. +lightweight_desc = Forgejo krever lite ressurser og kan kjĆøres pĆ„ en rimelig Raspberry Pi. Spar strĆøm og miljĆøet! +app_desc = En enkel Git-tjeneste du kan drifte selv +lightweight = Lettvekt +license = ƅpen kildekode +platform_desc = Forgejo fungerer pĆ„ frie operativsystemer som Linux og FreeBSD, og stĆøtter flere CPU-arkitekturer. Velg den plattformen du foretrekker! +license_desc = Last ned Forgejo! Bli med ved Ć„ bidra for Ć„ gjĆøre prosjektet enda bedre. Ikke vƦr redd for Ć„ bli en bidragsyter! \ No newline at end of file diff --git a/options/locale/locale_nds.ini b/options/locale/locale_nds.ini index 68fe899d6e..791f1b84d3 100644 --- a/options/locale/locale_nds.ini +++ b/options/locale/locale_nds.ini @@ -568,7 +568,7 @@ organization = Vereenigungen uid = UID webauthn = Twee-Faktooren-Anmellen (Sekerheids-Slƶtels) blocked_users = Blockeert Brukers -public_profile = Publikes Profil +public_profile = Publikes profil location_placeholder = Deel waar du umslags büst mit Annerns pronouns = Pronomens pronouns_custom = Eegene @@ -1552,7 +1552,7 @@ issues.dependency.pr_close_blocks = Deeser Haalvƶrslag blockeert dat Dichtmaken 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.blocked_by_short = Hangt 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. @@ -3304,7 +3304,7 @@ 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 +delete_branch = hett Twieg %[2]s vun %[3]s lƶsket compare_branch = Verglieken compare_commits = %d Kommitterens verglieken compare_commits_general = Kommitterens verglieken diff --git a/options/locale/locale_nl-NL.ini b/options/locale/locale_nl-NL.ini index 48442bc39f..d547b5bf77 100644 --- a/options/locale/locale_nl-NL.ini +++ b/options/locale/locale_nl-NL.ini @@ -1495,7 +1495,7 @@ issues.remove_ref_at=`heeft referentie %s verwijderd %s` issues.add_ref_at=`heeft referentie %s toegevoegd %s` issues.delete_branch_at=`heeft %[2]s de branch %[1]s verwijderd.` issues.filter_label=Label -issues.filter_label_exclude=Gebruik alt + klik/voer in om labels uit te sluiten +issues.filter_label_exclude=Gebruik alt + klik om labels uit te sluiten issues.filter_label_no_select=Alle labels issues.filter_milestone=Mijlpaal issues.filter_project=Project @@ -1554,8 +1554,8 @@ issues.close_comment_issue=Sluit met commentaar issues.reopen_issue=Heropen issues.reopen_comment_issue=Heropen met commentaar issues.create_comment=Reageer -issues.closed_at=`heeft dit probleem gesloten %s` -issues.reopened_at=`heropende dit probleem %s` +issues.closed_at=`heeft deze issue gesloten %s` +issues.reopened_at=`heropende deze issue %s` issues.commit_ref_at=`verwees naar dit probleem vanuit commit %s` issues.ref_issue_from=`refereerde aan dit issue %[3]s %[1]s` issues.ref_pull_from=`refereerde aan deze pull request %[3]s %[1]s` @@ -2912,6 +2912,14 @@ comment.blocked_by_user = Commentaar geven is niet mogelijk omdat u geblokkeerd sync_fork.button = Synchroniseer sync_fork.branch_behind_one = Deze branch is %[1]d commit achter %[2]s sync_fork.branch_behind_few = Deze branch is %[1]d commits achter %[2]s +settings.event_action_failure = Mislukking +settings.event_action_failure_desc = Action run is mislukt. +settings.event_action_recover = Herstel +settings.event_action_success = Succes +settings.event_action_success_desc = Action run is geslaagd. +settings.event_header_action = Actie run evenementen +issues.filter_type.all_pull_requests = Alle pull requests +settings.event_action_recover_desc = Action run is geslaagd nadat de laatste action run in dezelfde workflow is mislukt. @@ -3617,7 +3625,7 @@ create_repo=repository aangemaakt in %s rename_repo=hernoemde repository van %[1]s naar %[3]s transfer_repo=repository verplaatst naar %s naar %s delete_tag=heeft label %[2]s van %[3]s verwijderd -delete_branch=heeft branch %[2]s in %[3]s verwijderd +delete_branch=heeft branch %[2]s in %[3]s verwijderd compare_branch=Vergelijk compare_commits=Vergelijk %d commits compare_commits_general=Vergelijk commits diff --git a/options/locale/locale_pl-PL.ini b/options/locale/locale_pl-PL.ini index 189e663618..cf491d2f43 100644 --- a/options/locale/locale_pl-PL.ini +++ b/options/locale/locale_pl-PL.ini @@ -1043,8 +1043,8 @@ 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. +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. @@ -3552,7 +3552,7 @@ create_repo=tworzy repozytorium %s rename_repo=zmienia nazwę repozytorium %[1]s na %[3]s transfer_repo=przenosi repozytorium %s do %s delete_tag=usuwa tag %[2]s z %[3]s -delete_branch=usuwa gałąź %[2]s z %[3]s +delete_branch=usuwa gałąź %[2]s z %[3]s compare_branch=Porównaj compare_commits=Porównaj %d commitów compare_commits_general=Porównaj commity @@ -3951,29 +3951,29 @@ normal_file = Zwykły plik search = Wyszukaj... type_tooltip = Typ wyszukiwania fuzzy = Przybliżone -package_kind = Wyszukaj pakiety... +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... -user_kind = Wyszukaj użytkownilków... +repo_kind = Wyszukaj repozytoria… +user_kind = Wyszukaj użytkownilków… code_search_unavailable = Wyszukiwanie kodu jest obecnie niedostępne. Skontakuj sie z administratorem strony. no_results = Nie znaleziono pasujących wyników. -org_kind = Wyszukaj organizacje... -team_kind = Wyszukaj zespoły... -code_kind = Wyszukaj kod... +org_kind = Wyszukaj organizacje… +team_kind = Wyszukaj zespoły… +code_kind = Wyszukaj kod… code_search_by_git_grep = Obecne wyniki wyszukiwania kodu są dostarczane przez "git grep". Wyniki mogą być lepsze, jeśli administrator witryny włączy indeksator kodu. -project_kind = Wyszukaj projekty... -branch_kind = Wyszukaj gałęzie... -commit_kind = Wyszukaj commity... -runner_kind = Wyszukaj runnery... +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. 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... +issue_kind = Wyszukaj zgłoszenia… +pull_kind = Wyszukaj pull requesty… union = Unia regexp = RegExp regexp_tooltip = Interpretuj wyszukiwane hasło jako wyrażenie regularne diff --git a/options/locale/locale_pt-BR.ini b/options/locale/locale_pt-BR.ini index 8de0374eb2..242b915137 100644 --- a/options/locale/locale_pt-BR.ini +++ b/options/locale/locale_pt-BR.ini @@ -1278,7 +1278,7 @@ star_guest_user=Entre para adicionar este repositório aos favoritos. unwatch=Deixar de observar watch=Observar unstar=Retirar dos favoritos -star=Juntar aos favoritos +star=Adicionar aos favoritos fork=Fork download_archive=Baixar repositório more_operations=Mais operaƧƵes @@ -1934,7 +1934,7 @@ pulls.status_checks_success=Todas as verificaƧƵes foram bem sucedidas pulls.status_checks_warning=Algumas verificaƧƵes reportaram avisos pulls.status_checks_failure=Algumas verificaƧƵes falharam pulls.status_checks_error=Algumas verificaƧƵes reportaram erros -pulls.status_checks_requested=ObrigatĆ”rio +pulls.status_checks_requested=Obrigatório pulls.status_checks_details=Detalhes pulls.update_branch=Atualizar branch por merge pulls.update_branch_rebase=Atualizar branch por rebase @@ -2803,7 +2803,7 @@ mirror_use_ssh.helper = Forgejo irĆ” espelhar o repositório via Git atravĆ©s de 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. +mirror_use_ssh.not_available = A autenticação via 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. @@ -2817,7 +2817,7 @@ 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. +subscribe.pull.guest.tooltip = Inicie a sessĆ£o 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. @@ -3636,7 +3636,7 @@ auto_merge_pull_request=`fez merge automĆ”tico do pull request % transfer_repo=transferiu repositório de %s para %s push_tag=fez push da tag %[3]s to %[4]s delete_tag=excluiu tag %[2]s de %[3]s -delete_branch=excluiu branch %[2]s de %[3]s +delete_branch=excluiu branch %[2]s de %[3]s compare_branch=Comparar compare_commits=Compare %d commits compare_commits_general=Comparar commits @@ -3900,7 +3900,7 @@ 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=Gerenciar segredos +management=Gerenciamento de segredos [actions] actions=AƧƵes @@ -3909,12 +3909,12 @@ unit.desc=Gerenciar pipelines integradas de CI/CD com Forgejo Actions. status.unknown=Desconhecido status.waiting=Aguardando -status.running=Rodando +status.running=Executando status.success=Sucesso status.failure=Falha -status.cancelled=Cancelado -status.skipped=Ignorado -status.blocked=Bloqueado +status.cancelled=Cancelada +status.skipped=Ignorada +status.blocked=Bloqueada runners=Runners runners.runner_manage_panel=Gerenciar runners diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini index 0e8f2d485e..6dbc92e1f5 100644 --- a/options/locale/locale_pt-PT.ini +++ b/options/locale/locale_pt-PT.ini @@ -1063,8 +1063,8 @@ language.description = Este idioma vai ser guardado na sua conta e ser usado com language.localization_project = Ajude-nos a traduzir o Forgejo para o seu idioma! Ler 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. +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. Pode 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. Pode 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. @@ -1583,7 +1583,7 @@ issues.remove_ref_at=`removeu a referĆŖncia %s %s` issues.add_ref_at=`adicionou a referĆŖncia %s %s` issues.delete_branch_at=`eliminou o ramo %s %s` issues.filter_label=Rótulo -issues.filter_label_exclude=`Use alt + clique/enter para excluir rótulos` +issues.filter_label_exclude=Use Alt + Clique para excluir rótulos issues.filter_label_no_select=Todos os rótulos issues.filter_label_select_no_label=Sem rótulo issues.filter_milestone=Etapa @@ -2922,6 +2922,7 @@ settings.event_header_action = Eventos da execução de aƧƵes settings.event_action_recover_desc = A execução de ação foi bem sucedida depois da Ćŗltima execução de ação na mesma sequĆŖncia de trabalho ter falhado. settings.event_action_success = Sucesso settings.event_action_success_desc = A Execução de ação foi bem sucedida. +issues.filter_type.all_pull_requests = Todos os pedidos de integração [graphs] component_loading=A carregar %s… @@ -3057,8 +3058,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. +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. Pode 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. Pode ainda reivindicar o nome antigo durante o perĆ­odo de espera. [admin] dashboard=Painel de controlo @@ -3636,7 +3637,7 @@ auto_merge_pull_request=`fez automaticamente a integração constante no pedido transfer_repo=transferiu o repositório %s para %s push_tag=enviou a etiqueta %[3]s para %[4]s delete_tag=eliminou a etiqueta %[2]de %[3]s -delete_branch=eliminou o ramo %[2]s de %[3]s +delete_branch=eliminou o ramo %[2]s de %[3]s compare_branch=Comparar compare_commits=Comparar %d comentimentos compare_commits_general=Comparar comentimentos diff --git a/options/locale/locale_ro.ini b/options/locale/locale_ro.ini index 305c34d013..06fdb45785 100644 --- a/options/locale/locale_ro.ini +++ b/options/locale/locale_ro.ini @@ -223,12 +223,12 @@ 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... +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. diff --git a/options/locale/locale_ru-RU.ini b/options/locale/locale_ru-RU.ini index 2ef1b868d4..c7cccc012c 100644 --- a/options/locale/locale_ru-RU.ini +++ b/options/locale/locale_ru-RU.ini @@ -1063,7 +1063,7 @@ 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.one = ŠŸŃ€ŠµŠ¶Š½ŠµŠµ ŠøŠ¼Ń Š±ŃƒŠ“ŠµŃ‚ Š“Š¾ŃŃ‚ŃƒŠæŠ½Š¾ Š“Š»Ń ŠøŃŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Š½ŠøŃ Š“Ń€ŃƒŠ³ŠøŠ¼ ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŠ¼ после ŠøŃŃ‚ŠµŃ‡ŠµŠ½ŠøŃ ŠæŃ€Š¾ŃŃ‚Š¾Ń в %[1]d Гень. Š’Ń‹ сможете Š²ŠµŃ€Š½ŃƒŃ‚ŃŒ его себе во Š²Ń€ŠµŠ¼Ń срока ŠæŃ€Š¾ŃŃ‚Š¾Ń. change_username_redirect_prompt.with_cooldown.few = ŠŸŃ€ŠµŠ¶Š½ŠµŠµ ŠøŠ¼Ń Š±ŃƒŠ“ŠµŃ‚ Š“Š¾ŃŃ‚ŃƒŠæŠ½Š¾ Š“Š»Ń ŠøŃŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Š½ŠøŃ Š“Ń€ŃƒŠ³ŠøŠ¼ ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŠ¼ после ŠøŃŃ‚ŠµŃ‡ŠµŠ½ŠøŃ защиты в %[1]d Гней. Š’Ń‹ сможете Š²ŠµŃ€Š½ŃƒŃ‚ŃŒ его себе во Š²Ń€ŠµŠ¼Ń срока защиты. keep_pronouns_private = ŠŸŠ¾ŠŗŠ°Š·Ń‹Š²Š°Ń‚ŃŒ Š¼ŠµŃŃ‚Š¾ŠøŠ¼ŠµŠ½ŠøŃ Ń‚Š¾Š»ŃŒŠŗŠ¾ зарегистрированным ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŠ¼ keep_pronouns_private.description = ŠœŠµŃŃ‚Š¾ŠøŠ¼ŠµŠ½ŠøŃ Š±ŃƒŠ“ŃƒŃ‚ скрыты от ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŠµŠ¹, не ŠøŠ¼ŠµŃŽŃ‰ŠøŃ… ŃƒŃ‡Ń‘Ń‚Š½Ń‹Ń… записей на сервере. @@ -1641,9 +1641,9 @@ issues.closed_at=`заГача была закрыта %s` issues.reopened_at=`заГача была открыта снова %s` issues.commit_ref_at=`упоминание ŃŃ‚Š¾Š¹ заГачи в коммите %s` issues.ref_issue_from=`упоминание ŃŃ‚Š¾Š¹ заГачи %[3]s %[1]s` -issues.ref_pull_from=`упоминание ŃŃ‚Š¾Š³Š¾ запроса ŃŠ»ŠøŃŠ½ŠøŃ %[3]s %[1]s` -issues.ref_closing_from=`упоминание ŠøŠ· запроса на ŃŠ»ŠøŃŠ½ŠøŠµ %[3]s, который закроет эту Š·Š°Š“Š°Ń‡Ńƒ %[1]s` -issues.ref_reopening_from=`упоминание ŠøŠ· запроса на ŃŠ»ŠøŃŠ½ŠøŠµ %[3]s, который повторно откроет эту Š·Š°Š“Š°Ń‡Ńƒ %[1]s` +issues.ref_pull_from=`ŃƒŠæŠ¾Š¼ŃŠ½ŃƒŠ» ŃŃ‚Š¾Ń‚ запрос на ŃŠ»ŠøŃŠ½ŠøŠµ %[3]s %[1]s` +issues.ref_closing_from=`ŃƒŠæŠ¾Š¼ŃŠ½ŃƒŠ» эту Š·Š°Š“Š°Ń‡Ńƒ в запросе на ŃŠ»ŠøŃŠ½ŠøŠµ %[3]s, который закроет её %[1]s` +issues.ref_reopening_from=`ŃƒŠæŠ¾Š¼ŃŠ½ŃƒŠ» эту Š·Š°Š“Š°Ń‡Ńƒ в запросе на ŃŠ»ŠøŃŠ½ŠøŠµ %[3]s, который переоткроет эту Š·Š°Š“Š°Ń‡Ńƒ %[1]s` issues.ref_closed_from=`закрыл ŃŃ‚Š¾Ń‚ запрос %[4]s %[2]s` issues.ref_reopened_from=`заГача была открыта снова %[4]s %[2]s` issues.ref_from=`ŠøŠ· %[1]s` @@ -3639,7 +3639,7 @@ auto_merge_pull_request=`автоматически ŠæŃ€ŠøŠ½ŃŃ‚ запрос н transfer_repo=репозиторий %s был переГан: %s push_tag=отправлен тег %[3]s в %[4]s delete_tag=ŃƒŠ“Š°Š»Ń‘Š½ тег %[2]s в %[3]s -delete_branch=уГалена Š²ŠµŃ‚Š²ŃŒ %[2]s в %[3]s +delete_branch=уГалена Š²ŠµŃ‚Š²ŃŒ %[2]s в %[3]s compare_branch=Š”Ń€Š°Š²Š½ŠøŃ‚ŃŒ compare_commits=Š”Ń€Š°Š²Š½ŠøŃ‚ŃŒ %d коммитов compare_commits_general=Š”Ń€Š°Š²Š½ŠøŃ‚ŃŒ коммиты diff --git a/options/locale/locale_si-LK.ini b/options/locale/locale_si-LK.ini index 54b0b246db..d6f4525c4d 100644 --- a/options/locale/locale_si-LK.ini +++ b/options/locale/locale_si-LK.ini @@ -482,7 +482,7 @@ avatar=ą¶…ą·€ą¶­ą·ą¶»ą·Š ssh_gpg_keys=SSH/ජීඓීජී යතුරු social=ą·ƒą¶øą·ą¶¢ ą¶œą·’ą¶«ą·”ą¶øą·Š applications=ą¶ŗą·™ą¶Æą·”ą¶øą·Š -orgs=ą·ƒą¶‚ą·€ą·’ą¶°ą·ą¶± ą¶šą·…ą¶øą¶±ą·ą¶šą¶»ą¶«ą¶ŗ +orgs=ą·ƒą¶‚ą·€ą·’ą¶°ą·ą¶± repos=ą¶šą·ą·‚ą·Šą¶Ø delete=ą¶œą·’ą¶«ą·”ą¶ø මකන්න twofa=ą¶Æą·Šą·€ą·’-ą·ƒą·ą¶°ą¶š ą·ƒą¶­ą·Šą¶ŗą·ą¶“ą¶±ą¶ŗ @@ -527,8 +527,8 @@ password_change_disabled=ą¶Æą·šą·ą·“ą¶ŗ ą¶±ą·œą·€ą¶± ą¶“ą¶»ą·’ą·ą·“ą¶½ą¶šą¶ŗ emails=වි-තැඓැල් ලිඓින manage_emails=වි-තැඓැල් ලිඓින ą¶šą·…ą¶øą¶±ą·ą¶šą¶»ą¶«ą¶ŗ -manage_themes=ඓෙරනිමි ą¶­ą·šą¶øą·ą·€ ą¶­ą·ą¶»ą¶±ą·Šą¶± -manage_openid=OpenID ą¶½ą·’ą¶“ą·’ą¶±ą¶ŗą¶±ą·Š ą¶šą·…ą¶øą¶±ą·ą¶šą¶»ą¶«ą¶ŗ කරන්න +manage_themes=ඓෙරනිමි ą¶­ą·šą¶øą·ą·€ +manage_openid=OpenID ලිඓින theme_desc=මෙම ą·€ą·™ą¶¶ą·Š අඩවිය ą·„ą¶»ą·„ą· ą¶”ą¶¶ą¶œą·š ඓෙරනිමි ą¶­ą·šą¶øą·ą·€ වනු ඇත. primary=ą¶“ą·Šą¶»ą·ą¶®ą¶øą·’ą¶š activated=ą·ƒą¶šą·Šą¶»ą·’ą¶ŗ @@ -2488,7 +2488,7 @@ merge_pull_request=`ą¶’ą¶šą·ą¶¶ą¶Æą·Šą¶° ą¶…ą¶Æą·’ą¶±ą·Šą¶± ą¶‰ą¶½ą·Šą¶½ą·“ą¶ø transfer_repo=ą¶øą·ą¶»ą·” කරන ලද ą¶œą¶¶ą¶©ą·ą·€ %s ą·ƒą·’ą¶§ %s push_tag=ą¶­ą¶½ą·Šą¶½ą·” ටැගය %[3]s ගේ %[4]s ගේ delete_tag=ą¶øą¶šą·ą¶Æą·ą¶øą·”ą·€ą· ටැගය%[2]s ą·ƒą·’ą¶§ %[3]s -delete_branch=ą¶øą¶šą·ą¶Æą·ą¶øą·– ą·ą·ą¶›ą·ą·€ %[2]s ą·ƒą·’ą¶§ %[3]s +delete_branch=ą¶øą¶šą·ą¶Æą·ą¶øą·– ą·ą·ą¶›ą·ą·€ %[2]s ą·ƒą·’ą¶§ %[3]s compare_branch=සසඳන්න compare_commits=%d ą·€ą·’ą·€ą¶»ą¶ŗą¶±ą·Š ą·ƒą·ƒą¶³ą· බලන්න compare_commits_general=ą·€ą·’ą·€ą¶»ą¶ŗą¶±ą·Š ą·ƒą·ƒą¶³ą· බලන්න diff --git a/options/locale/locale_sk-SK.ini b/options/locale/locale_sk-SK.ini index 0c44df326a..aa2f863b14 100644 --- a/options/locale/locale_sk-SK.ini +++ b/options/locale/locale_sk-SK.ini @@ -597,7 +597,7 @@ avatar=Avatar ssh_gpg_keys=SSH / GPG kÄ¾ĆŗÄe social=SociĆ”lne ĆŗÄty applications=AplikĆ”cie -orgs=SpravovaÅ„ organizĆ”cie +orgs=OrganizĆ”cie repos=RepozitĆ”re delete=ZmazaÅ„ ĆŗÄet twofa=DvojfaktorovĆ© overenie @@ -656,8 +656,8 @@ password_change_disabled=Externe overovanĆ­ používatelia nemÓžu aktualizova emails=E-mailovĆ© adresy manage_emails=SprĆ”va e-mailových adries -manage_themes=Nastavenie predvolenej tĆ©my -manage_openid=SprĆ”va OpenID adries +manage_themes=PredvolenĆ” tĆ©ma +manage_openid=Adresy OpenID theme_desc=Toto bude vaÅ”a predvolenĆ” tĆ©ma vzhľadu naprieč strĆ”nkou. primary=PrimĆ”rny activated=Aktivovaný diff --git a/options/locale/locale_sl.ini b/options/locale/locale_sl.ini index 608e05afa4..07ccaed259 100644 --- a/options/locale/locale_sl.ini +++ b/options/locale/locale_sl.ini @@ -133,7 +133,7 @@ reinstall_confirm_check_3 = Potrjujete, da ste popolnoma prepričani, da se ta p require_db_desc = Forgejo zahteva MySQL, PostgreSQL, SQLite3 ali TiDB (protokol MySQL). password_algorithm_helper = Nastavite algoritem za stiskanje gesla. Algoritmi imajo različne zahteve in moč. Algoritem argon2 je precej varen, vendar porabi veliko pomnilnika in je lahko neprimeren za majhne sisteme. reinstall_confirm_message = Ponovna namestitev z obstoječo zbirko podatkov Forgejo lahko povzroči več težav. V večini primerov morate za zagon programa Forgejo uporabiti obstoječi "app.ini". Če veste, kaj počnete, potrdite naslednje: -err_admin_name_is_reserved = Administrator UporabniÅ”ko ime je neveljavno, uporabniÅ”ko ime je rezervirano +err_admin_name_is_reserved = Administrator uporabniÅ”ko ime je neveljavno, uporabniÅ”ko ime je rezervirano disable_gravatar.description = Onemogočite vire avatarjev Gravatar in avatarje tretjih oseb. Uporabi se privzeti avatar, razen če uporabnik lokalno naloži avatar. install = Namestitev title = Začetna nastavitev @@ -367,7 +367,7 @@ delete = Brisanje računa uploaded_avatar_is_too_big = Velikost naložene datoteke (%d KiB) presega največjo velikost (%d KiB). webauthn = Dvofaktorsko preverjanje pristnosti (varnostni ključi) change_username_redirect_prompt = Staro uporabniÅ”ko ime bo preusmerjeno, dokler ga nekdo ne prevzame. -orgs = Upravljanje organizacij +orgs = Organizacije public_profile = Javni profil gpg_key_verified_long = Ključ je bil preverjen z žetonom in ga je mogoče uporabiti za preverjanje zavez, ki ustrezajo vsem aktiviranim e-poÅ”tnim naslovom tega uporabnika, poleg vseh ujemajočih se identitet za ta ključ. @@ -495,14 +495,14 @@ tab_openid = Odprta identiteta [home] show_both_archived_unarchived = Prikazovanje arhiviranih in nearhiviranih -switch_dashboard_context = Kontekst stikala Nadzorna ploŔča +switch_dashboard_context = Kontekst stikala nadzorna ploŔča search_repos = PoiŔčite skladiŔče… filter_by_team_repositories = Filtriranje po skupinskih skladiŔčih show_archived = Arhivirano collaborative_repos = Sodelovalni repozitoriji my_mirrors = Moja ogledala show_only_public = Prikazovanje samo javnih -uname_holder = UporabniÅ”ko ime ali E-poÅ”tovni naslov +uname_holder = UporabniÅ”ko ime ali e-poÅ”tni naslov password_holder = Geslo my_repos = Repozitoriji show_more_repos = Prikaži več skladiÅ”Äā€¦ diff --git a/options/locale/locale_sv-SE.ini b/options/locale/locale_sv-SE.ini index 8b43cb29b8..5b06c5e3b5 100644 --- a/options/locale/locale_sv-SE.ini +++ b/options/locale/locale_sv-SE.ini @@ -918,7 +918,7 @@ migrate.migrate_items_options=ƅtkomsttoken krƤvs fƶr att migrera ytterligare migrated_from=Migrerad frĆ„n %[2]s migrated_from_fake=Migrerad frĆ„n %[1]s migrate.migrate=Migrera frĆ„n %s -migrate.migrating=Migrerar frĆ„n %s ... +migrate.migrating=Migrerar frĆ„n %s … migrate.migrating_failed=Migrering frĆ„n %s misslyckades. migrate.migrating_issues=Migrerar Ƥrenden @@ -2226,7 +2226,7 @@ create_repo=skapade utvecklingskatalog %s rename_repo=dƶpte om utvecklingskalatogen frĆ„n %[1]s till %[3]s transfer_repo=ƶverfƶrde utvecklingskalatogen %s till %s delete_tag=tog bort taggen %[2]s frĆ„n %[3]s -delete_branch=tog bort branchen %[2]s from %[3]s +delete_branch=tog bort branchen %[2]s from %[3]s compare_branch=JƤmfƶr compare_commits=JƤmfƶr %d commits compare_commits_general=JƤmfƶr commits @@ -2324,17 +2324,17 @@ 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... +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... +team_kind = Sƶk team… org_kind = Sƶk organisationer… -issue_kind = Sƶk Ƥrenden... +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 diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini index c07cefdab9..aa41d7dc63 100644 --- a/options/locale/locale_tr-TR.ini +++ b/options/locale/locale_tr-TR.ini @@ -163,8 +163,8 @@ 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ş +new_migrate.title = Yeni gƶƧ +new_migrate.link = Yeni gƶƧ copy_path = Dizini kopyala confirm_delete_artifact = "%s" adlı öğeyi silmek istediğinizden emin misiniz? @@ -179,8 +179,9 @@ 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 +contributions_one = katkı +contributions_few = katkı +contributions_format = {day} {month} {year} tarihinde {contributions} katkı [editor] buttons.heading.tooltip=Başlık ekle @@ -203,6 +204,12 @@ table_modal.placeholder.header = Başlık table_modal.placeholder.content = İƧerik table_modal.label.rows = Satırlar table_modal.label.columns = Sütunlar +link_modal.header = Bağlantı ekle +link_modal.url = Url +link_modal.description = AƧıklama +link_modal.paste_reminder = İpucu: Panonuzdaki bir URL'yi doğrudan düzenleyiciye yapıştırarak bir bağlantı oluşturabilirsiniz. +buttons.unindent.tooltip = Bir seviye girinti azalt +buttons.indent.tooltip = Bir seviye girinti artır [filter] string.asc=A - Z @@ -226,6 +233,7 @@ 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! +platform_desc = Forgejo'nun Linux ve FreeBSD gibi ƶzgür işletim sistemlerinde ve farklı CPU mimarilerinde Ƨalıştığı doğrulandı. Sevdiğinizi seƧin! [install] install=Kurulum @@ -252,9 +260,9 @@ err_empty_db_path=SQLite3 veritabanı dosya yolu boş olamaz. no_admin_and_disable_registration=Bir yƶnetici hesabı oluşturmadan kullanıcı kaydını kapatamazsınız. err_empty_admin_password=Yƶnetici parolası boş olamaz. err_empty_admin_email=Yƶnetici e-postası boş olamaz. -err_admin_name_is_reserved=Yƶnetici Kullanıcı Adı geƧersiz, bu kullanıcı adı rezerv edilen bir kelimedir +err_admin_name_is_reserved=Yƶnetici kullanıcı adı geƧersiz, bu kullanıcı adı rezerv edilen bir kelimedir 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 +err_admin_name_is_invalid=Yƶnetici kullanıcı adı geƧersiz general_title=Genel ayarlar app_name=Site Başlığı @@ -344,6 +352,7 @@ enable_update_checker_helper_forgejo = release.forgejo.org adresindeki TXT DNS k 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` +config_location_hint = Bu yapılandırma seƧenekleri şuraya kaydedilecek: [home] uname_holder=Kullanıcı adı veya e-posta adresi @@ -477,6 +486,7 @@ 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 +change_unconfirmed_email = Kayıt sırasında yanlış e-posta adresi verdiyseniz, aşağıdan değiştirebilirsiniz; yeni adresinize bir onay mesajı gƶnderilecektir. [mail] view_it_on=%s üzerinde gƶrüntüle @@ -722,16 +732,16 @@ avatar=Avatar ssh_gpg_keys=SSH / GPG Anahtarları social=Sosyal Medya Hesapları applications=Uygulamalar -orgs=Organizasyonları Yƶnet +orgs=Kuruluşlar repos=Depolar -delete=Hesabı Sil -twofa=İki Aşamalı Doğrulama +delete=Hesabı sil +twofa=İki aşamalı doğrulama account_link=Bağlı Hesaplar organization=Organizasyonlar uid=UID webauthn=Güvenlik Anahtarları -public_profile=Herkese AƧık Profil +public_profile=Herkese aƧık profil biography_placeholder=Bize kendiniz hakkında birşeyler sƶyleyin! (Markdown kullanabilirsiniz) location_placeholder=Yaklaşık konumunuzu başkalarıyla paylaşın profile_desc=Profilinizin başkalarına nasıl gƶsterildiğini yƶnetin. Ana e-posta adresiniz bildirimler, parola kurtarma ve web tabanlı Git işlemleri iƧin kullanılacaktır. @@ -796,8 +806,8 @@ password_change_disabled=Yerel olmayan kullanıcılar parolalarını Forgejo web emails=E-Posta Adresleri manage_emails=E-posta Adreslerini Yƶnet -manage_themes=Varsayılan temayı seƧ -manage_openid=OpenID Adreslerini Yƶnet +manage_themes=Varsayılan tema +manage_openid=OpenID adresleri email_desc=Ana e-posta adresiniz bildirimler, parola kurtarma ve gizlenmemişse eğer web tabanlı Git işlemleri iƧin kullanılacaktır. theme_desc=Bu, sitedeki varsayılan temanız olacak. primary=Birincil @@ -1166,7 +1176,7 @@ form.name_reserved=Depo adı "%s" rezerve edilmiş. form.name_pattern_not_allowed=Depo adında "%s" deseni kullanılamaz. need_auth=Yetkilendirme -migrate_options=GƶƧ SeƧenekleri +migrate_options=GƶƧ seƧenekleri migrate_service=GƶƧ Hizmeti migrate_options_mirror_helper=Bu depo bir yansı olacaktır migrate_options_lfs=LFS dosyalarını taşı @@ -1174,7 +1184,7 @@ migrate_options_lfs_endpoint.label=LFS UƧ Noktası migrate_options_lfs_endpoint.description=Taşıma, LFS sunucusunu belirlemek iƧin Git uzak sunucusunu kullanmaya Ƨalışacak. Eğer LFS veri deposu başka yerdeyse ƶzel bir uƧ nokta da belirtebilirsiniz. migrate_options_lfs_endpoint.description.local=Yerel bir sunucu yolu da destekleniyor. migrate_options_lfs_endpoint.placeholder=Boş bırakılırsa, uƧ nokta klon URL'sinden türetilecektir -migrate_items=GƶƧ Ɩğeleri +migrate_items=GƶƧ öğeleri migrate_items_wiki=Wiki migrate_items_milestones=Kilometre Taşları migrate_items_labels=Etiketler @@ -1215,7 +1225,7 @@ migrate.migrating_labels=Etiketleri Taşıma migrate.migrating_releases=Sürümleri Taşıma migrate.migrating_issues=Konuları Taşıma migrate.migrating_pulls=Değişiklik İsteklerini Taşıma -migrate.cancel_migrating_title=Göçü İptal Et +migrate.cancel_migrating_title=Göçü iptal et migrate.cancel_migrating_confirm=Bu göçü iptal etmek istiyor musunuz? mirror_from=şunun yansıması @@ -1252,7 +1262,7 @@ find_tag=Etiketi bul branches=Dal tags=Etiket issues=Konular -pulls=Değişiklik İstekleri +pulls=Değişiklik istekleri project_board=Projeler packages=Paketler actions=İşlemler @@ -1443,7 +1453,7 @@ projects.column.set_default=Varsayılanı Ayarla projects.column.set_default_desc=Bu sütunu kategorize edilmemiş konular ve değişiklik istekleri iƧin varsayılan olarak ayarlayın projects.column.unset_default=Varsayılanları Geri Al projects.column.unset_default_desc=Bu sütunu varsayılan olarak geri al -projects.column.delete=Sutün Sil +projects.column.delete=Sütunu sil projects.column.deletion_desc=Bir proje sütununun silinmesi, ilgili tüm konuları 'Kategorize edilmemiş'e taşır. Devam edilsin mi? projects.column.color=Renk projects.open=AƧ @@ -1595,7 +1605,7 @@ issues.reopen_issue=Yeniden aƧ issues.reopen_comment_issue=Yorum Yap ve Yeniden AƧ issues.create_comment=Yorum yap issues.closed_at=`%s konusunu kapattı` -issues.reopened_at=`%s konusunu yeniden aƧtı` +issues.reopened_at=%s sorununu yeniden aƧtı issues.commit_ref_at=`%s işlemesinde bu konuyu işaret etti` issues.ref_issue_from=`bu konuya referansta bulundu %[3]s %[1]s` issues.ref_pull_from=`bu değişiklik isteğine referansta bulundu %[3]s %[1]s` @@ -1647,7 +1657,7 @@ issues.label.filter_sort.alphabetically=Alfabetik issues.label.filter_sort.reverse_alphabetically=Ters alfabetik issues.label.filter_sort.by_size=En küçük boyut issues.label.filter_sort.reverse_by_size=En büyük boyut -issues.num_participants_few=%d Katılımcı +issues.num_participants_few=%d katılımcı issues.attachment.open_tab=`Yeni bir sekmede "%s" gƶrmek iƧin tıkla` issues.attachment.download=`"%s" indirmek iƧin tıkla` issues.subscribe=Abone Ol @@ -1984,7 +1994,7 @@ ext_wiki=Harici Vikiye Erişim ext_wiki.desc=Harici bir wiki'ye bağlantı. wiki=Wiki -wiki.welcome=Wiki'ye Hoşgeldiniz. +wiki.welcome=Viki'ye Hoş geldiniz. wiki.welcome_desc=Wiki, katkıcılarla belge yazmanıza ve paylaşmanıza olanak tanır. wiki.desc=Katkıcılarla belgeler yazın ve paylaşın. wiki.create_first_page=İlk sayfayı oluştur @@ -2140,15 +2150,15 @@ settings.use_external_wiki=Harici Wiki Kullan settings.external_wiki_url=Harici Wiki bağlantısı settings.external_wiki_url_error=Harici wiki URL'si geƧerli bir URL değil. settings.external_wiki_url_desc=ZiyaretƧiler, wiki sekmesine tıklandığında harici wiki URL'sine yƶnlendirilir. -settings.issues_desc=Depo Konu İzleyicisini Etkinleştir -settings.use_internal_issue_tracker=Yerleşik Konu İzleyici Kullan -settings.use_external_issue_tracker=Harici Konu İzleyici Kullan -settings.external_tracker_url=Harici Konu İzleyici URLsi +settings.issues_desc=Depo sorun izleyicisini etkinleştir +settings.use_internal_issue_tracker=Yerleşik sorun izleyici kullan +settings.use_external_issue_tracker=Harici sorun izleyici kullan +settings.external_tracker_url=Harici sorun izleyici URL'si settings.external_tracker_url_error=Harici konu izleyici URL'si geƧerli bir URL değil. settings.external_tracker_url_desc=ZiyaretƧiler, konular sekmesine tıkladığında harici konu izleyici URL'sine yƶnlendirilir. -settings.tracker_url_format=Harici Konu İzleyici URL BiƧimi +settings.tracker_url_format=Harici sorun izleyici URL BiƧimi settings.tracker_url_format_error=Harici konu izleyici URL biƧimi geƧerli bir URL değil. -settings.tracker_issue_style=Harici Konu İzleyici Numara BiƧimi +settings.tracker_issue_style=Harici sorun izleyici Numara BiƧimi settings.tracker_issue_style.numeric=Sayısal settings.tracker_issue_style.alphanumeric=Alfanumerik settings.tracker_issue_style.regexp=Düzenli ifade @@ -2158,13 +2168,13 @@ settings.tracker_url_format_desc=Kullanıcı adı, depo adı ve yayın dizini i settings.enable_timetracker=Zaman Takibini Etkinleştir settings.allow_only_contributors_to_track_time=Sadece Katkıcılar İƧin Zaman Takibine İzin Ver settings.pulls_desc=Değişiklik İsteklerini Etkinleştir -settings.pulls.ignore_whitespace=Ƈakışmalar iƧin Boşlukları Gƶzardı Et +settings.pulls.ignore_whitespace=Ƈakışmalar iƧin boşlukları gƶzardı et settings.pulls.enable_autodetect_manual_merge=Kendiliğinden algılamalı elle birleştirmeyi etkinleştir (Not: Bazı ƶzel durumlarda yanlış kararlar olabilir) settings.pulls.allow_rebase_update=Değişiklik isteği dalının yeniden yapılandırmayla güncellenmesine izin ver settings.pulls.default_delete_branch_after_merge=Varsayılan olarak birleştirmeden sonra değişiklik isteği dalını sil settings.pulls.default_allow_edits_from_maintainers=Bakımcıların düzenlemelerine izin ver settings.releases_desc=Depo Sürümlerini Etkinleştir -settings.packages_desc=Depo paket kütüğünü etkinleştir +settings.packages_desc=Depo paket kayıt defterini etkinleştir settings.projects_desc=Depo Projelerini Etkinleştir settings.actions_desc=Depo İşlemlerini Etkinleştir settings.admin_settings=Yƶnetici Ayarları @@ -2188,7 +2198,7 @@ settings.convert_fork_desc=Bu Ƨatalı normal bir depoya dƶnüştürebilirsiniz settings.convert_fork_notices_1=Bu işlem Ƨatalı normal bir depoya dƶnüştürür ve geri alınamaz. settings.convert_fork_confirm=Depoyu Dƶnüştür settings.convert_fork_succeed=Ƈatal normal bir depoya dƶnüştürüldü. -settings.transfer.title=Sahipliği Aktar +settings.transfer.title=Sahipliği aktar settings.transfer.rejected=Depo aktarımı reddedildi. settings.transfer.success=Depo aktarımı başarıyla tamamlandı. settings.transfer_abort=Aktarımı iptal et @@ -2448,7 +2458,7 @@ settings.block_on_official_review_requests_desc=Yeterli onay olsa bile, resmi in settings.block_outdated_branch=Değişiklik isteği güncel değilse birleştirmeyi engelle settings.block_outdated_branch_desc=Baş dal taban dalın arkasındayken birleştirme mümkün olmayacaktır. settings.default_branch_desc=Değişiklik istekleri ve kod işlemeleri iƧin varsayılan bir depo dalı seƧin: -settings.merge_style_desc=BiƧimleri Birleştir +settings.merge_style_desc=Birleştirme biƧemleri settings.default_merge_style_desc=Değişiklik istekleri iƧin varsayılan birleştirme tarzı: settings.choose_branch=Bir dal seç… settings.no_protected_branch=Korumalı dal yok. @@ -2701,7 +2711,7 @@ settings.new_owner_blocked_doer = Yeni sahip sizi engelledi. open_with_editor = %s ile aƧ object_format = Nesne BiƧimi -mirror_sync = eşitlendi +mirror_sync = eşitlenme: stars = Yıldızlar desc.sha256 = SHA256 vendored = Sağlanmış @@ -2721,6 +2731,25 @@ 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. +commits.browse_further = Daha fazlasına gƶz at +settings.units.units = Birimler +commits.renamed_from = %s adından yeniden adlandırıldı +mirror_use_ssh.text = SSH yetkilendirme kullan +settings.default_update_style_desc = Temel dalın ardındaki Ƨekme isteklerini güncellemek iƧin kullanılan varsayılan güncelleme stili. +mirror_denied_combination = Ortak anahtar ve parola tabanlı kimlik doğrulama birlikte kullanılamaz. +mirror_public_key = Ortak SSH anahtarı +n_branch_few = %s dal +n_commit_few = %s gƶnderi +n_tag_few = %s etiket +settings.wiki_rename_branch_main = Viki dal adını normalleştir +mirror_use_ssh.not_available = SSH yetkilendirme kullanılamıyor. +mirror_use_ssh.helper = Forgejo, bu seƧeneği seƧtiğinizde deponuzu SSH üzerinden Git üzerinden yansıtacak ve sizin iƧin bir anahtar Ƨifti oluşturacaktır. Oluşturulan ortak anahtarın hedef depoya gƶnderilmek üzere yetkilendirildiğinden emin olmalısınız. Bunu seƧerken parola tabanlı yetkilendirme kullanamazsınız. +n_branch_one = %s dal +settings.units.add_more = Daha fazlasını etkinleştir +settings.wiki_globally_editable = Vikiyi herkesin düzenlemesine izin ver +issues.filter_no_results_placeholder = Arama filtrelerini değiştirmeyi deneyin. +issues.filter_no_results = SonuƧ yok +issues.num_participants_one = %d katılımcı [graphs] component_loading = %s yükleniyor... @@ -2736,7 +2765,7 @@ org_name_holder=Organizasyon Adı org_full_name_holder=Organizasyon Tam Adı org_name_helper=Organizasyon adları kısa ve hatırlanabilir olmalıdır. create_org=Organizasyon Oluştur -repo_updated=Güncellendi %s +repo_updated=%s güncellendi members=Üyeler teams=Takımlar code=Kod @@ -2792,7 +2821,7 @@ members.membership_visibility=Üyelik Gƶrünürlüğü: members.public=Gƶrünür members.public_helper=gizle members.private=Gizlenmiş -members.private_helper=gƶrünür yap +members.private_helper=Gƶrünür yap members.member_role=Üye Rolü: members.owner=Sahibi members.member=Üye @@ -3311,7 +3340,7 @@ config.git_max_diff_lines=Maksimum Değişiklik Satırı (tek bir dosya iƧin) config.git_max_diff_line_characters=Maksimum Değişiklik Karakteri (tek bir satır iƧin) config.git_max_diff_files=Maksimum Değişiklik Dosyaları (gƶsterilecek) config.git_gc_args=GC Argümanları -config.git_migrate_timeout=GƶƧ İşlemi Zaman Aşımı +config.git_migrate_timeout=GƶƧ işlemi zaman aşımı config.git_mirror_timeout=Yansı Güncelleme Zaman Aşımı config.git_clone_timeout=Klonlama İşlemi Zaman Aşımı config.git_pull_timeout=Ƈekme İşlemi Zaman Aşımı @@ -3363,7 +3392,7 @@ monitor.queue.settings.maxnumberworkers=En fazla Ƨalışan Sayısı monitor.queue.settings.maxnumberworkers.placeholder=Şu anda %[1]d monitor.queue.settings.maxnumberworkers.error=En fazla Ƨalışan sayısı bir sayı olmalıdır monitor.queue.settings.submit=Ayarları Güncelle -monitor.queue.settings.changed=Ayarlar Güncellendi +monitor.queue.settings.changed=Ayarlar güncellendi monitor.queue.settings.remove_all_items=Tümünü kaldır monitor.queue.settings.remove_all_items_done=Kuyruktaki tüm öğeler kaldırıldı. @@ -3417,7 +3446,7 @@ auto_merge_pull_request=`%[3]s#%[2]s değişiklik isteği ot transfer_repo=depo %s %s'a aktarıldı push_tag=%[3]s etiketini %[4]s dalına gƶnderdi delete_tag=%[2]s etiketi %[3]s deposundan silindi -delete_branch=%[3]s deposundan %[2]s dalı silindi +delete_branch=%[3]s deposundan %[2]s dalı silindi compare_branch=Karşılaştır compare_commits=%d işlemeyi karşılaştır compare_commits_general=İşlemeleri karşılaştır @@ -3771,23 +3800,23 @@ submodule=Alt modül [search] -project_kind = Projeleri ara... +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... +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... +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... +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 @@ -3795,3 +3824,16 @@ 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 +regexp = Düzenliİfade +regexp_tooltip = Arama terimini düzenli ifade olarak yorumla +union = Anahtar sƶzcük + + +[munits.data] +tib = TiB +kib = KiB +pib = PiB +mib = MiB +b = B +gib = GiB +eib = EiB \ No newline at end of file diff --git a/options/locale/locale_uk-UA.ini b/options/locale/locale_uk-UA.ini index faa3f2a56e..b94cb64af1 100644 --- a/options/locale/locale_uk-UA.ini +++ b/options/locale/locale_uk-UA.ini @@ -149,7 +149,7 @@ filter.not_archived = ŠŠµ архівовано filter.public = Š—Š°Š³Š°Š»ŃŒŠ½Š¾Š“Š¾ŃŃ‚ŃƒŠæŠ½Ń– filter.private = ŠŸŃ€ŠøŠ²Š°Ń‚Š½Ń– more_items = Š‘Ń–Š»ŃŒŃˆŠµ ŠæŃƒŠ½ŠŗŃ‚Ń–Š² -remove_label_str = ВиГалити об'єкт Ā«%sĀ» +remove_label_str = ВиГалити елемент Ā«%sĀ» new_repo.title = ŠŠ¾Š²ŠøŠ¹ репозиторій new_migrate.title = ŠŠ¾Š²Š° Š¼Ń–Š³Ń€Š°Ń†Ń–Ń new_org.title = ŠŠ¾Š²Š° Š¾Ń€Š³Š°Š½Ń–Š·Š°Ń†Ń–Ń @@ -195,10 +195,10 @@ buttons.list.task.tooltip = ДоГати список завГань buttons.heading.tooltip = ДоГати заголовок buttons.switch_to_legacy.tooltip = Š’ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŠ²Š°Ń‚Šø застарілий реГактор Š·Š°Š¼Ń–ŃŃ‚ŃŒ поточного buttons.disable_monospace_font = Š’ŠøŠ¼ŠŗŠ½ŃƒŃ‚Šø Š¼Š¾Š½Š¾ŃˆŠøŃ€ŠøŠ½Š½ŠøŠ¹ ŃˆŃ€ŠøŃ„Ń‚ -buttons.indent.tooltip = Вкласти преГмет на оГин Ń€Ń–Š²ŠµŠ½ŃŒ -buttons.unindent.tooltip = Викласти об'єкт на оГин Ń€Ń–Š²ŠµŠ½ŃŒ +buttons.indent.tooltip = Вкласти елемент на оГин Ń€Ń–Š²ŠµŠ½ŃŒ +buttons.unindent.tooltip = Викласти елемент на оГин Ń€Ń–Š²ŠµŠ½ŃŒ buttons.mention.tooltip = ЗгаГати ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š° чи команГу -buttons.ref.tooltip = ŠŸŠ¾ŃŠ»Š°Ń‚ŠøŃŃŒ на Š·Š°Š“Š°Ń‡Ńƒ чи на запит на Š·Š»ŠøŃ‚Ń‚Ń +buttons.ref.tooltip = ŠŸŠ¾ŃŠ»Š°Ń‚ŠøŃŃ на Š·Š°Š“Š°Ń‡Ńƒ чи на запит на Š·Š»ŠøŃ‚Ń‚Ń buttons.enable_monospace_font = Š£Š²Ń–Š¼ŠŗŠ½ŃƒŃ‚Šø Š¼Š¾Š½Š¾ŃˆŠøŃ€ŠøŠ½Š½ŠøŠ¹ ŃˆŃ€ŠøŃ„Ń‚ buttons.new_table.tooltip = ДоГати Ń‚Š°Š±Š»ŠøŃ†ŃŽ table_modal.label.columns = Дтовпці @@ -348,7 +348,7 @@ app_slogan = Гасло ŠµŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Š° app_slogan_helper = Š£Š²ŠµŠ“Ń–Ń‚ŃŒ гасло вашого ŠµŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Š° тут. Š—Š°Š»ŠøŃˆŃ‚Šµ порожнім, аби Š²ŠøŠ¼ŠŗŠ½ŃƒŃ‚Šø. run_user_helper = Š†Š¼Ź¼Ń ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š° операційної системи, віГ ŃŠŗŠ¾Š³Š¾ Š·Š°ŠæŃƒŃ‰ŠµŠ½Š¾ Forgejo. Š—Š°ŃƒŠ²Š°Š¶Ń‚Šµ, що цей ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡ повинен мати Š“Š¾ŃŃ‚ŃƒŠæ Го кореневої теки Ń€ŠµŠæŠ¾Š·ŠøŃ‚Š¾Ń€Ń–ŃŽ. smtp_from_invalid = АГреса Š· Ā«Š’Ń–Š“ŠæŃ€Š°Š²Š»ŃŃ‚Šø email віГ імені» неГійсна -allow_dots_in_usernames = Дозволити ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š°Š¼ Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŠ²Š°Ń‚Šø крапки у своїх іменах. ŠŠµ впливає на облікові записи, що вже Ń–ŃŠ½ŃƒŃŽŃ‚ŃŒ. +allow_dots_in_usernames = Дозволити Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š°Š½Š½Ń крапки в іменах ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Ń–Š². ŠŠµ впливає на облікові записи, що вже Ń–ŃŠ½ŃƒŃŽŃ‚ŃŒ. invalid_password_algorithm = ŠŠµŠ“Ń–Š¹ŃŠ½ŠøŠ¹ варіант Š°Š»Š³Š¾Ń€ŠøŃ‚Š¼Ńƒ Ń…ŠµŃˆŃƒŠ²Š°Š½Š½Ń паролів enable_update_checker_helper_forgejo = ŠŠ°ŃŠ²Š½Ń–ŃŃ‚ŃŒ нових версій Forgejo періоГично ŠæŠµŃ€ŠµŠ²Ń–Ń€ŃŃ‚ŠøŠ¼ŠµŃ‚ŃŒŃŃ через ŠæŠµŃ€ŠµŠ²Ń–Ń€ŠŗŃƒ запису TXT DNS на release.forgejo.org. @@ -392,7 +392,7 @@ user_no_results=ВіГповіГних ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Ń–Š² не знайГ org_no_results=ВіГповіГних організацій не знайГено. code_no_results=ВіГповіГний пошуковому Š·Š°ŠæŠøŃ‚Š°Š½Š½ŃŽ коГ не знайГено. code_last_indexed_at=ŠžŃŃ‚Š°Š½Š½Ń– інГексовані %s -relevant_repositories = Š’Ń–Š“Š¾Š±Ń€Š°Š¶Š°ŃŽŃ‚ŃŒŃŃ лише релевантні репозиторії, ŠæŠµŃ€ŠµŠ³Š»ŃŠ½ŃƒŃ‚Šø Ń€ŠµŠ·ŃƒŠ»ŃŒŃ‚Š°Ń‚Šø без Ń„Ń–Š»ŃŒŃ‚Ń€Ńƒ. +relevant_repositories = Показано лише релевантні репозиторії, ŠæŠµŃ€ŠµŠ³Š»ŃŠ½ŃƒŃ‚Šø Ń€ŠµŠ·ŃƒŠ»ŃŒŃ‚Š°Ń‚Šø без Ń„Ń–Š»ŃŒŃ‚Ń€Ńƒ. relevant_repositories_tooltip = ŠŸŃ€ŠøŃ…Š¾Š²Š°Š½Š¾ форки, а також репозиторії без теми, значка й опису. go_to = ŠŸŠµŃ€ŠµŠ¹Ń‚Šø Го stars_one = %d зірка @@ -469,7 +469,7 @@ 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. +openid_signin_desc = Š£Š²ŠµŠ“Ń–Ń‚ŃŒ свій OpenID URI. ŠŠ°ŠæŃ€ŠøŠŗŠ»Š°Š“: alice.openid.example.org чи https://openid.example.org/alice. invalid_password = Š’Š°Ńˆ ŠæŠ°Ń€Š¾Š»ŃŒ не віГповіГає Ń‚Š¾Š¼Ńƒ, що був заГаний при створенні облікового запису. hint_login = Вже маєте обліковий запис? Š£Š²Ń–Š¹Š“Ń–Ń‚ŃŒ зараз! hint_register = ŠŸŠ¾Ń‚Ń€Ń–Š±ŠµŠ½ обліковий запис? Š—Š°Ń€ŠµŃ”ŃŃ‚Ń€ŃƒŠ¹Ń‚ŠµŃŃ зараз. @@ -813,9 +813,9 @@ manage_ssh_keys=ŠšŠµŃ€ŃƒŠ²Š°Š½Š½Ń ŠŗŠ»ŃŽŃ‡Š°Š¼Šø SSH manage_ssh_principals=Š£ŠæŃ€Š°Š²Š»Ń–Š½Š½Ń SSH сертифікатами ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Ń–Š² manage_gpg_keys=ŠšŠµŃ€ŃƒŠ²Š°Š½Š½Ń ŠŗŠ»ŃŽŃ‡Š°Š¼Šø GPG add_key=ДоГати ŠŗŠ»ŃŽŃ‡ -ssh_desc=Ці віГкриті ŠŗŠ»ŃŽŃ‡Ń– SSH ŠæŠ¾Š²Ź¼ŃŠ·Š°Š½Ń– Š· вашим обліковим записом. ВіГповіГні приватні ŠŗŠ»ŃŽŃ‡Ń– Š“Š¾Š·Š²Š¾Š»ŃŃŽŃ‚ŃŒ отримати повний Š“Š¾ŃŃ‚ŃƒŠæ Го Š²Š°ŃˆŠøŃ… репозиторіїв. ŠŸŃ–Š“Ń‚Š²ŠµŃ€Š“Š¶ŠµŠ½Ń– ŠŗŠ»ŃŽŃ‡Ń– можна використати Š“Š»Ń ŠæŃ–Š“Ń‚Š²ŠµŃ€Š“Š¶ŠµŠ½Š½Ń комітів Git, піГписані Š· SSH. +ssh_desc=Ці віГкриті ŠŗŠ»ŃŽŃ‡Ń– SSH ŠæŠ¾Š²Ź¼ŃŠ·Š°Š½Ń– Š· вашим обліковим записом. ВіГповіГні приватні ŠŗŠ»ŃŽŃ‡Ń– Š“Š¾Š·Š²Š¾Š»ŃŃŽŃ‚ŃŒ отримати повний Š“Š¾ŃŃ‚ŃƒŠæ Го Š²Š°ŃˆŠøŃ… репозиторіїв. ŠŸŃ–Š“Ń‚Š²ŠµŃ€Š“Š¶ŠµŠ½Ń– ŠŗŠ»ŃŽŃ‡Ń– можна використати Š“Š»Ń ŠæŃ–Š“Ń‚Š²ŠµŃ€Š“Š¶ŠµŠ½Š½Ń комітів Git, піГписаних Ń–Š· SSH. principal_desc=Ці настройки SSH сертифікатів вказані у вашому Š¾Š±Š»Ń–ŠŗŠ¾Š²Š¾Š¼Ńƒ записі та Š½Š°Š“Š°ŃŽŃ‚ŃŒ повний Š“Š¾ŃŃ‚ŃƒŠæ Го Š²Š°ŃˆŠøŃ… репозиторіїв. -gpg_desc=Ці ŠæŃƒŠ±Š»Ń–Ń‡Š½Ń– ŠŗŠ»ŃŽŃ‡Ń– GPG пов'ŃŠ·Š°Š½Ń– Š· вашим обліковим записом. Тримайте свої приватні ŠŗŠ»ŃŽŃ‡Ń– в безпеці, Š¾ŃŠŗŃ–Š»ŃŒŠŗŠø вони Š“Š¾Š·Š²Š¾Š»ŃŃŽŃ‚ŃŒ Š·Š“Ń–Š¹ŃŠ½ŃŽŠ²Š°Ń‚Šø ŠæŠµŃ€ŠµŠ²Ń–Ń€ŠŗŃƒ комітів. +gpg_desc=Ці ŠæŃƒŠ±Š»Ń–Ń‡Š½Ń– ŠŗŠ»ŃŽŃ‡Ń– GPG пов'ŃŠ·Š°Š½Ń– Š· вашим обліковим записом і Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃŽŃ‚ŃŒŃŃ Š“Š»Ń ŠæŃ–Š“Ń‚Š²ŠµŃ€Š“Š¶ŠµŠ½Š½Ń комітів. Тримайте свої приватні ŠŗŠ»ŃŽŃ‡Ń– в безпеці, Š¾ŃŠŗŃ–Š»ŃŒŠŗŠø вони Š“Š¾Š·Š²Š¾Š»ŃŃŽŃ‚ŃŒ ŠæŃ–Š“ŠæŠøŃŃƒŠ²Š°Ń‚Šø коміти вашим особистим піГписом. ssh_helper=ŠŸŠ¾Ń‚Ń€Ń–Š±Š½Š° Гопомога? Š”ŠøŠ²Ń–Ń‚ŃŒŃŃ гіГ на GitHub Š· генерації ŠŗŠ»ŃŽŃ‡Ń–Š² SSH або Š²ŠøŠæŃ€Š°Š²Š»ŠµŠ½Š½Ń типових неполаГок SSH. gpg_helper= ŠŸŠ¾Ń‚Ń€Ń–Š±Š½Š° Гопомога? ŠŸŠµŃ€ŠµŠ³Š»ŃŠ½ŃŒŃ‚Šµ посібник GitHub про GPG . add_new_key=ДоГати SSH ŠŗŠ»ŃŽŃ‡ @@ -893,7 +893,7 @@ 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_desc=Š’ŠøŠ“Š°Š»ŠµŠ½Š½Ń програми OAuth2 ŃŠŗŠ°ŃŃƒŃ” Š“Š¾ŃŃ‚ŃƒŠæ Го всіх піГписаних токенів Š“Š¾ŃŃ‚ŃƒŠæŃƒ. ŠŸŃ€Š¾Š“Š¾Š²Š¶ŠøŃ‚Šø? remove_oauth2_application_success=ŠŸŃ€Š¾Š³Ń€Š°Š¼Ńƒ виГалено. create_oauth2_application=Дтворити новий ГоГаток OAuth2 create_oauth2_application_button=Дтворити ŠæŃ€Š¾Š³Ń€Š°Š¼Ńƒ @@ -1076,6 +1076,8 @@ quota.rule.exceeded = ŠŸŠµŃ€ŠµŠ²ŠøŃ‰ŠµŠ½Š¾ regenerate_token = Š—Š³ŠµŠ½ŠµŃ€ŃƒŠ²Š°Ń‚Šø знову access_token_regeneration = Š—Š³ŠµŠ½ŠµŃ€ŃƒŠ²Š°Ń‚Šø новий токен Š“Š¾ŃŃ‚ŃƒŠæŃƒ quota.sizes.assets.all = Š ŠµŃŃƒŃ€ŃŠø +access_token_regeneration_desc = Š ŠµŠ³ŠµŠ½ŠµŃ€Š°Ń†Ń–Ń токена ŃŠŗŠ°ŃŃƒŃ” Š“Š¾ŃŃ‚ŃƒŠæ програм, ŃŠŗŃ– Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃŽŃ‚ŃŒ цей токен, Го вашого облікового запису. Це незворотна Š“Ń–Ń. ŠŸŃ€Š¾Š“Š¾Š²Š¶ŠøŃ‚Šø? +regenerate_token_success = Токен згенеровано наново. ŠŸŃ€Š¾Š³Ń€Š°Š¼Šø, ŃŠŗŃ– його Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃŽŃ‚ŃŒ, Š±Ń–Š»ŃŒŃˆŠµ не Š¼Š°ŃŽŃ‚ŃŒ Š“Š¾ŃŃ‚ŃƒŠæŃƒ Го вашого облікового запису; ви повинні віГновити Š“Š¾ŃŃ‚ŃƒŠæ за Š“Š¾ŠæŠ¾Š¼Š¾Š³Š¾ŃŽ нового токена. [repo] owner=Власник @@ -1143,7 +1145,7 @@ forks=Форки reactions_more=ГоГати %d Š±Ń–Š»ŃŒŃˆŠµ unit_disabled=АГміністратор ŃŠ°Š¹Ń‚Ńƒ вимкнув цей розГіл Ń€ŠµŠæŠ¾Š·ŠøŃ‚Š¾Ń€Ń–ŃŽ. language_other=Š†Š½ŃˆŃ– -adopt_search=Š’Š²ŠµŠ“Ń–Ń‚ŃŒ ім'я ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡_ŠŗŠø Š“Š»Ń пошуку Š½ŠµŠæŃ€ŠøŠ¹Š½ŃŃ‚ŠøŃ… репозиторіїв… (Š·Š°Š»ŠøŃˆŃ‚Šµ порожнім, щоб знайти всі) +adopt_search=Š£Š²ŠµŠ“Ń–Ń‚ŃŒ ім'я ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡_ŠŗŠø Š“Š»Ń пошуку Š½ŠµŠæŃ€ŠøŠ¹Š½ŃŃ‚ŠøŃ… репозиторіїв… (Š·Š°Š»ŠøŃˆŃ‚Šµ порожнім, щоб знайти всі) adopt_preexisting_label=ŠŸŃ€ŠøŠ¹Š½ŃŃ‚Ń– файли adopt_preexisting=ŠŸŃ€ŠøŠ¹Š½ŃŃ‚Šø вже Ń–ŃŠ½ŃƒŃŽŃ‡Ń– файли adopt_preexisting_content=Дтворити репозиторій Š· %s @@ -1168,7 +1170,7 @@ desc.archived=Архівний template.items=Елементи шаблону template.git_content=Вміст Git (типова гілка) -template.git_hooks=ŠŸŠµŃ€ŠµŃ…Š¾ŠæŠ»ŃŽŠ²Š°Ń‡Ń– Git +template.git_hooks=Git-Ń…ŃƒŠŗŠø template.webhooks=Webhook'Šø template.topics=Теми template.avatar=Аватар @@ -1276,7 +1278,7 @@ file_raw=ŠŠµŃ„Š¾Ń€Š¼Š°Ń‚Š¾Š²Š°Š½ŠøŠ¹ file_history=Š†ŃŃ‚Š¾Ń€Ń–Ń file_view_source=ŠŸŠµŃ€ŠµŠ³Š»ŃŠ½ŃƒŃ‚Šø вихіГний коГ file_view_rendered=ŠŸŠµŃ€ŠµŠ³Š»ŃŠ½ŃƒŃ‚Šø віГренГерено -file_view_raw=ŠŸŠµŃ€ŠµŠ³Š»ŃŠ“ Raw +file_view_raw=ŠŸŠµŃ€ŠµŠ³Š»ŃŠ½ŃƒŃ‚Šø неформатований file_permalink=ŠŸŠ¾ŃŃ‚Ń–Š¹Š½Šµ ŠæŠ¾ŃŠøŠ»Š°Š½Š½Ń file_too_large=Цей файл завеликий щоб Š±ŃƒŃ‚Šø показаним. @@ -1285,7 +1287,7 @@ video_not_supported_in_browser=Š’Š°Ńˆ Š±Ń€Š°ŃƒŠ·ŠµŃ€ не ŠæŃ–Š“Ń‚Ń€ŠøŠ¼ŃƒŃ” т audio_not_supported_in_browser=Š’Š°Ńˆ Š±Ń€Š°ŃƒŠ·ŠµŃ€ не ŠæŃ–Š“Ń‚Ń€ŠøŠ¼ŃƒŃ” тег HTML5 Ā«audioĀ». stored_lfs=Збережено Š· Git LFS symbolic_link=Димволічне ŠæŠ¾ŃŠøŠ»Š°Š½Š½Ń -commit_graph=Графік комітів +commit_graph=Граф комітів commit_graph.select=Š’ŠøŠ±ŠµŃ€Ń–Ń‚ŃŒ гілки commit_graph.hide_pr_refs=ŠŸŃ€ŠøŃ…Š¾Š²Š°Ń‚Šø запити на Š·Š»ŠøŃ‚Ń‚Ń commit_graph.monochrome=ŠœŠ¾Š½Š¾Ń…Ń€Š¾Š¼ @@ -1402,9 +1404,9 @@ issues.new.open_projects=ВіГкриті проєкти issues.new.closed_projects=Закриті проєкти issues.new.no_items=ŠŠµŠ¼Š°Ń” елементів issues.new.milestone=Етап -issues.new.no_milestone=Етап Š²Ń–Š“ŃŃƒŃ‚Š½Ń–Š¹ +issues.new.no_milestone=ŠŠµŠ¼Š°Ń” ŠµŃ‚Š°ŠæŃƒ issues.new.clear_milestone=ŠžŃ‡ŠøŃŃ‚ŠøŃ‚Šø етап -issues.new.open_milestone=Активні етапи +issues.new.open_milestone=ВіГкриті етапи issues.new.closed_milestone=Закриті етапи issues.new.assignees=Виконавці issues.new.clear_assignees=ŠŸŃ€ŠøŠ±Ń€Š°Ń‚Šø виконавців @@ -1504,7 +1506,7 @@ issues.closed_at=`закриває цю Š·Š°Š“Š°Ń‡Ńƒ %s` issues.reopened_at=`повторно віГкриває цю Š·Š°Š“Š°Ń‡Ńƒ %s` issues.commit_ref_at=`ŠæŠ¾ŃŠøŠ»Š°Ń”Ń‚ŃŒŃŃ на цю Š·Š°Š“Š°Ń‡Ńƒ в коміті %s` issues.ref_issue_from=`ŠæŠ¾ŃŠøŠ»Š°Ń”Ń‚ŃŒŃŃ на цю Š·Š°Š“Š°Ń‡Ńƒ %[3]s %[1]s` -issues.ref_pull_from=`ŠæŠ¾ŃŠøŠ»Š°Ń”Ń‚ŃŒŃŃ на цей запит Š·Š»ŠøŃ‚Ń‚Ń %[3]s %[1]s` +issues.ref_pull_from=`ŠæŠ¾ŃŠøŠ»Š°Ń”Ń‚ŃŒŃŃ на цей запит на Š·Š»ŠøŃ‚Ń‚Ń %[3]s %[1]s` issues.ref_closing_from=`ŠæŠ¾ŃŠøŠ»Š°Ń”Ń‚ŃŒŃŃ в запиті на Š·Š»ŠøŃ‚Ń‚Ń %[3]s, ŃŠŗŠøŠ¹ закриє цю Š·Š°Š“Š°Ń‡Ńƒ, %[1]s` issues.ref_reopening_from=`ŠæŠ¾ŃŠøŠ»Š°Ń”Ń‚ŃŒŃŃ в запиті на Š·Š»ŠøŃ‚Ń‚Ń %[3]s, ŃŠŗŠøŠ¹ повторно віГкриє цю Š·Š°Š“Š°Ń‡Ńƒ, %[1]s` issues.ref_closed_from=`закрив цю Š·Š°Š“Š°Ń‡Ńƒ %[4]s %[2]s` @@ -1799,7 +1801,7 @@ 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=ŠŸŠµŃ€Ń–Š¾Š“: @@ -1844,7 +1846,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 автор @@ -1886,7 +1888,7 @@ settings.collaboration.read=Читати settings.collaboration.owner=Власник settings.collaboration.undefined=ŠŠµ визначено settings.hooks=Веб-Ń…ŃƒŠŗŠø -settings.githooks=Git Ń…ŃƒŠŗŠø +settings.githooks=Git-Ń…ŃƒŠŗŠø settings.basic_settings=ŠžŃŠ½Š¾Š²Š½Ń– Š½Š°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Š½Š½Ń settings.mirror_settings=ŠŠ°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Š½Š½Ń Гзеркала settings.mirror_settings.mirrored_repository=ВіГГзеркалений репозиторій @@ -1896,7 +1898,7 @@ 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.add=ДоГати Push Гзеркало +settings.mirror_settings.push_mirror.add=ДоГати push-Гзеркало settings.sync_mirror=Š”ŠøŠ½Ń…Ń€Š¾Š½Ń–Š·ŃƒŠ²Š°Ń‚Šø зараз settings.site=Веб-сайт @@ -1927,9 +1929,9 @@ settings.pulls_desc=Š£Š²Ń–Š¼ŠŗŠ½ŃƒŃ‚Šø запити на Š·Š»ŠøŃ‚Ń‚Ń в реп settings.pulls.ignore_whitespace=Š†Š³Š½Š¾Ń€ŃƒŠ²Š°Ń‚Šø пробіл у конфліктах settings.pulls.enable_autodetect_manual_merge=Š£Š²Ń–Š¼ŠŗŠ½ŃƒŃ‚Šø Š°Š²Ń‚Š¾Š²ŠøŠ·Š½Š°Ń‡ŠµŠ½Š½Ń Ń€ŃƒŃ‡Š½Š¾Š³Š¾ Š·Š»ŠøŃ‚Ń‚Ń (ŠŸŃ€ŠøŠ¼Ń–Ń‚ŠŗŠ°: у Š“ŠµŃŠŗŠøŃ… особливий випаГках Š¼Š¾Š¶ŃƒŃ‚ŃŒ Š²ŠøŠ½ŠøŠŗŠ½ŃƒŃ‚ŃŒ помилки) settings.pulls.default_delete_branch_after_merge=Š’ŠøŠ“Š°Š»ŃŃ‚Šø Š³Ń–Š»ŠŗŃƒ Š·Š°ŠæŠøŃ‚Ńƒ Š·Š»ŠøŃ‚Ń‚Ń, коли його ŠæŃ€ŠøŠ¹Š½ŃŃ‚о -settings.projects_desc=Š£Š²Ń–Š¼ŠŗŠ½ŃƒŃ‚Šø проєкти у репозиторії +settings.projects_desc=Š£Š²Ń–Š¼ŠŗŠ½ŃƒŃ‚Šø проєкти в репозиторії settings.admin_settings=ŠŠ°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Š½Š½Ń аГміністратора -settings.admin_enable_health_check=Š’ŠŗŠ»ŃŽŃ‡ŠøŃ‚Šø перевірки працезГатності Ń€ŠµŠæŠ¾Š·ŠøŃ‚Š¾Ń€Ń–ŃŽ (git fsck) +settings.admin_enable_health_check=Š£Š²Ń–Š¼ŠŗŠ½ŃƒŃ‚Šø перевірки ŃŃ‚Š°Š½Ńƒ Ń€ŠµŠæŠ¾Š·ŠøŃ‚Š¾Ń€Ń–ŃŽ (git fsck) settings.admin_enable_close_issues_via_commit_in_any_branch=Закрити Š·Š°Š“Š°Ń‡Ńƒ за Š“Š¾ŠæŠ¾Š¼Š¾Š³Š¾ŃŽ коміта, зробленого не в головній гілці settings.danger_zone=ŠŠµŠ±ŠµŠ·ŠæŠµŃ‡Š½Š° зона settings.new_owner_has_same_repo=ŠŠ¾Š²ŠøŠ¹ власник вже має репозиторій Š· Ń‚Š°ŠŗŠ¾ŃŽ Š½Š°Š·Š²Š¾ŃŽ. Š‘ŃƒŠ“ŃŒ ласка, Š²ŠøŠ±ŠµŃ€Ń–Ń‚ŃŒ Ń–Š½ŃˆŠµ ім'я. @@ -2075,7 +2077,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=Білий список гілок Š“Š»Ń push, ŃŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń гілок та Š²ŠøŠ“Š°Š»ŠµŠ½Š½Ń гілок, Š²ŠøŠ·Š½Š°Ń‡Š°Ń”Ń‚ŃŒŃŃ ŃŠŗ шаблон glob. Якщо він порожній або Š¼Ń–ŃŃ‚ŠøŃ‚ŃŒ *, то Ń€ŠµŃ”ŃŃ‚Ń€ŃƒŃŽŃ‚ŃŒŃŃ поГії Š“Š»Ń всіх гілок. Š”ŠøŠ²Ń–Ń‚ŃŒŃŃ синтаксис у Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†Ń–Ń— на %[2]s. ŠŠ°ŠæŃ€ŠøŠŗŠ»Š°Š“: master, {master,release*}. +settings.branch_filter_desc=Білий список гілок Š“Š»Ń push, ŃŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń гілок та Š²ŠøŠ“Š°Š»ŠµŠ½Š½Ń гілок, Š²ŠøŠ·Š½Š°Ń‡Š°Ń”Ń‚ŃŒŃŃ ŃŠŗ шаблон glob. Якщо він порожній або Š¼Ń–ŃŃ‚ŠøŃ‚ŃŒ *, то Ń€ŠµŃ”ŃŃ‚Ń€ŃƒŃŽŃ‚ŃŒŃŃ поГії Š“Š»Ń всіх гілок. Š”ŠøŠ²Ń–Ń‚ŃŒŃŃ синтаксис у Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†Ń–Ń— %[2]s. ŠŸŃ€ŠøŠŗŠ»Š°Š“Šø: master, {master,release*}. settings.active=Активний settings.active_helper=Š†Š½Ń„Š¾Ń€Š¼Š°Ń†Ń–ŃŽ про викликані поГії буГе наГіслано за цією веб-Ń…ŃƒŠŗ URL-Š°Š“Ń€ŠµŃŠ¾ŃŽ. settings.add_hook_success=Веб-Ń…ŃƒŠŗ було ГоГано. @@ -2154,7 +2156,7 @@ settings.edit_protected_branch=Š ŠµŠ“Š°Š³ŃƒŠ²Š°Ń‚Šø 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=Дозволені команГи @@ -2263,7 +2265,7 @@ release.detail=Деталі Ń€ŠµŠ»Ń–Š·Ńƒ release.tags=Теги release.new_release=ŠŠ¾Š²ŠøŠ¹ випуск release.draft=Чернетка -release.prerelease=ŠŸŃ€Šµ-реліз +release.prerelease=ŠŸŠ¾ŠæŠµŃ€ŠµŠ“Š½Ń–Š¹ випуск release.stable=Š”Ń‚Š°Š±Ń–Š»ŃŒŠ½ŠøŠ¹ release.compare=ŠŸŠ¾Ń€Ń–Š²Š½ŃŃ‚Šø release.edit=Š ŠµŠ“Š°Š³ŃƒŠ²Š°Ń‚Šø @@ -2275,15 +2277,15 @@ release.edit_subheader=ŠŸŃƒŠ±Š»Ń–ŠŗŠ°Ń†Ń–Ń релізів Гопоможе ва release.tag_name=ŠŠ°Š·Š²Š° Ń‚ŠµŠ³Ńƒ release.target=Š¦Ń–Š»ŃŒ release.tag_helper=Š’ŠøŠ±ŠµŃ€Ń–Ń‚ŃŒ Ń–ŃŠ½ŃƒŃŽŃ‡ŠøŠ¹ тег або ŃŃ‚Š²Š¾Ń€Ń–Ń‚ŃŒ новий. -release.prerelease_desc=ŠŸŠ¾Š·Š½Š°Ń‡ŠøŃ‚Šø ŃŠŗ пре-реліз +release.prerelease_desc=ŠŸŠ¾Š·Š½Š°Ń‡ŠøŃ‚Šø ŃŠŗ попереГній випуск 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=Тег виГалено. @@ -2446,7 +2448,7 @@ settings.event_package = Пакунок settings.event_package_desc = Пакунок у репозиторії створено або виГалено. settings.new_owner_blocked_doer = ŠŠ¾Š²ŠøŠ¹ власник заблокував вас. settings.transfer_quota_exceeded = ŠŠ¾Š²ŠøŠ¹ власник (%s) перевищив ŠŗŠ²Š¾Ń‚Ńƒ. Репозиторій не переГано. -release.title_empty = Заголовок не може Š±ŃƒŃ‚Šø порожнім. +release.title_empty = ŠŠ°Š·Š²Š° не може Š±ŃƒŃ‚Šø ŠæŠ¾Ń€Š¾Š¶Š½ŃŒŠ¾ŃŽ. issues.role.member_helper = Цей ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡ є членом організації, що волоГіє цим репозиторієм. wiki.page_content = Вміст сторінки wiki.page_title = Заголовок сторінки @@ -2530,7 +2532,7 @@ settings.add_web_hook_desc = Š†Š½Ń‚ŠµŠ³Ń€ŃƒŠ²Š°Ń‚Šø Š£Š²Ń–Š¹Š“Ń–Ń‚ŃŒ, щоб створити новий запит на Š·Š»ŠøŃ‚Ń‚Ń. @@ -2541,8 +2543,8 @@ auto_init_description = ŠŸŠ¾Ń‡Š½Ń–Ń‚ŃŒ Ń–ŃŃ‚Š¾Ń€Ń–ŃŽ Git Š· README і за ба 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Ā». Š¦Ń зміна є Š¾ŃŃ‚Š°Ń‚Š¾Ń‡Š½Š¾ŃŽ і її неможливо ŃŠŗŠ°ŃŃƒŠ²Š°Ń‚Šø. +form.name_pattern_not_allowed = Вираз Ā«%sĀ» не може Š±ŃƒŃ‚Šø Ń‡Š°ŃŃ‚ŠøŠ½Š¾ŃŽ назви Ń€ŠµŠæŠ¾Š·ŠøŃ‚Š¾Ń€Ń–ŃŽ. +settings.wiki_rename_branch_main_desc = ŠŸŠµŃ€ŠµŠ¹Š¼ŠµŠ½ŃƒŠ²Š°Ń‚Šø Š²Š½ŃƒŃ‚Ń€Ń–ŃˆŠ½ŃŽ Š³Ń–Š»ŠŗŃƒ, ŃŠŗŠ° Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃ”Ń‚ŃŒŃŃ Š“Š»Ń вікі, на Ā«%sĀ». Š¦Ń зміна є Š¾ŃŃ‚Š°Ń‚Š¾Ń‡Š½Š¾ŃŽ і її неможливо ŃŠŗŠ°ŃŃƒŠ²Š°Ń‚Šø. wiki.reserved_page = ŠŠ°Š·Š²Ńƒ вікі-сторінки Ā«%sĀ» зарезервовано. stars = Зірки mirror_public_key = ВіГкритий SSH-ŠŗŠ»ŃŽŃ‡ @@ -2669,6 +2671,108 @@ settings.event_action_recover = ВіГновлено commitstatus.success = Успіх commitstatus.failure = Збій issues.filter_type.all_pull_requests = Усі запити на Š·Š»ŠøŃ‚Ń‚Ń +broken_message = ŠŠµŠ¼Š¾Š¶Š»ŠøŠ²Š¾ прочитати Гані Git, що Š»ŠµŠ¶Š°Ń‚ŃŒ в основі Ń†ŃŒŠ¾Š³Š¾ Ń€ŠµŠæŠ¾Š·ŠøŃ‚Š¾Ń€Ń–ŃŽ. Š—Š²ŠµŃ€Š½Ń–Ń‚ŃŒŃŃ Го аГміністратора Ń†ŃŒŠ¾Š³Š¾ ŠµŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Š° або Š²ŠøŠ“Š°Š»Ń–Ń‚ŃŒ репозиторій. +migrate.invalid_local_path = Š›Š¾ŠŗŠ°Š»ŃŒŠ½ŠøŠ¹ ŃˆŠ»ŃŃ… неГійсний. Він не Ń–ŃŠ½ŃƒŃ” або не є каталогом. +editor.filename_is_a_directory = ŠŠ°Š·Š²Š° Ń„Š°Š¹Š»Ńƒ Ā«%sĀ» уже Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃ”Ń‚ŃŒŃŃ в Ń†ŃŒŠ¾Š¼Ńƒ репозиторії ŃŠŗ назва ŠŗŠ°Ń‚Š°Š»Š¾Š³Ńƒ. +editor.filename_is_invalid = Єибна назва Ń„Š°Š¹Š»Ńƒ: Ā«%sĀ». +migrate_options_lfs_endpoint.placeholder = Якщо Š·Š°Š»ŠøŃˆŠøŃ‚Šø порожнім, то ŠŗŃ–Š½Ń†ŠµŠ²Ńƒ Ń‚Š¾Ń‡ŠŗŃƒ буГе визначено Š· URL-аГреси клону +cite_this_repo = ŠŸŠ¾ŃŠ»Š°Ń‚ŠøŃŃ на цей репозиторій +editor.directory_is_a_file = ŠŠ°Š·Š²Š° ŠŗŠ°Ń‚Š°Š»Š¾Š³Ńƒ Ā«%sĀ» уже Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃ”Ń‚ŃŒŃŃ в Ń†ŃŒŠ¾Š¼Ńƒ репозиторії ŃŠŗ назва Ń„Š°Š¹Š»Ńƒ. +subscribe.issue.guest.tooltip = Š£Š²Ń–Š¹Š“Ń–Ń‚ŃŒ, щоб ŠæŃ–Š“ŠæŠøŃŠ°Ń‚ŠøŃŃ на цю Š·Š°Š“Š°Ń‡Ńƒ. +invisible_runes_header = `Цей файл Š¼Ń–ŃŃ‚ŠøŃ‚ŃŒ невиГимі символи Š®Š½Ń–ŠŗŠ¾Š“Ńƒ` +invisible_runes_line = `Š£ Ń†ŃŒŠ¾Š¼Ńƒ Ń€ŃŠ“ŠŗŃƒ є невиГимі символи Š®Š½Ń–ŠŗŠ¾Š“Ńƒ` +subscribe.pull.guest.tooltip = Š£Š²Ń–Š¹Š“Ń–Ń‚ŃŒ, щоб ŠæŃ–Š“ŠæŠøŃŠ°Ń‚ŠøŃŃ на цей запит на Š·Š»ŠøŃ‚Ń‚Ń. +ambiguous_runes_header = `Цей файл Š¼Ń–ŃŃ‚ŠøŃ‚ŃŒ неоГнозначні символи Š®Š½Ń–ŠŗŠ¾Š“Ńƒ` +ambiguous_runes_line = `Š£ Ń†ŃŒŠ¾Š¼Ńƒ Ń€ŃŠ“ŠŗŃƒ є неоГнозначні символи Š®Š½Ń–ŠŗŠ¾Š“Ńƒ` +issues.choose.invalid_config = Š£ ŠŗŠ¾Š½Ń„Ń–Š³ŃƒŃ€Š°Ń†Ń–Ń— заГачі є помилки: +escape_control_characters = Escape +ambiguous_runes_description = `Цей файл Š¼Ń–ŃŃ‚ŠøŃ‚ŃŒ символи Š®Š½Ń–ŠŗŠ¾Š“Ńƒ, ŃŠŗŃ– легко ŃŠæŠ»ŃƒŃ‚Š°Ń‚Šø Š· Ń–Š½ŃˆŠøŠ¼Šø символами. Якщо так зроблено навмисно, можете Ń–Š³Š½Š¾Ń€ŃƒŠ²Š°Ń‚Šø це ŠæŠ¾ŠæŠµŃ€ŠµŠ“Š¶ŠµŠ½Š½Ń. Щоб показати ці символи, ŃŠŗŠ¾Ń€ŠøŃŃ‚Š°Š¹Ń‚ŠµŃŃ ŠŗŠ½Š¾ŠæŠŗŠ¾ŃŽ Ā«EscapeĀ».` +unescape_control_characters = Unescape +invisible_runes_description = `Цей файл Š¼Ń–ŃŃ‚ŠøŃ‚ŃŒ невиГимі символи Š®Š½Ń–ŠŗŠ¾Š“Ńƒ, ŃŠŗŃ– Š»ŃŽŠ“ŠøŠ½Ń– неможливо розрізнити, але ŃŠŗŃ– по-Ń€Ń–Š·Š½Š¾Š¼Ńƒ Š¾Š±Ń€Š¾Š±Š»ŃŃŽŃ‚ŃŒŃŃ комп'ŃŽŃ‚ŠµŃ€Š¾Š¼. Якщо так зроблено навмисно, можете Ń–Š³Š½Š¾Ń€ŃƒŠ²Š°Ń‚Šø це ŠæŠ¾ŠæŠµŃ€ŠµŠ“Š¶ŠµŠ½Š½Ń. Щоб показати ці символи, ŃŠŗŠ¾Ń€ŠøŃŃ‚Š°Š¹Ń‚ŠµŃŃ ŠŗŠ½Š¾ŠæŠŗŠ¾ŃŽ Ā«EscapeĀ».` +ambiguous_character = `%[1]c [U+%04[1]X] можна ŃŠæŠ»ŃƒŃ‚Š°Ń‚Šø Š· %[2]c [U+%04[2]X]` +settings.sourcehut_builds.secrets_helper = ŠŠ°Š“Š°Ń‚Šø Š·Š°Š²Š“Š°Š½Š½ŃŽ Š“Š¾ŃŃ‚ŃƒŠæ Го секретів збірки (потрібен Гозвіл SECRETS:RO) +no_eol.text = Без EOL +settings.remove_protected_branch_failed = ŠŠµ Š²Š“Š°Š»Š¾ŃŃ виГалити правило Š·Š°Ń…ŠøŃŃ‚Ńƒ гілок Ā«%sĀ». +summary_card_alt = ŠŸŃ–Š“ŃŃƒŠ¼ŠŗŠ¾Š²Š° картка Ń€ŠµŠæŠ¾Š·ŠøŃ‚Š¾Ń€Ń–ŃŽ %s +issues.summary_card_alt = ŠŸŃ–Š“ŃŃƒŠ¼ŠŗŠ¾Š²Š° картка заГачі Ā«%sĀ» в репозиторії %s +release.summary_card_alt = ŠŸŃ–Š“ŃŃƒŠ¼ŠŗŠ¾Š²Š° картка випуску Ā«%sĀ» в репозиторії %s +release.hide_archive_links_helper = ŠŸŃ€ŠøŃ…Š¾Š²Š°Ń‚Šø Š“Š»Ń Ń†ŃŒŠ¾Š³Š¾ випуску архіви вихіГного коГу, що Š³ŠµŠ½ŠµŃ€ŃƒŃŽŃ‚ŃŒŃŃ автоматично. ŠŠ°ŠæŃ€ŠøŠŗŠ»Š°Š“, ŃŠŗŃ‰Š¾ ви Š·Š°Š²Š°Š½Ń‚Š°Š¶ŃƒŃ”Ń‚Šµ свої архіви. +activity.published_prerelease_label = ŠŸŃ€Šµ-реліз +release.title = ŠŠ°Š·Š²Š° випуску +release.system_generated = Це Š²ŠŗŠ»Š°Š“ŠµŠ½Š½Ń згенеровано автоматично. +release.hide_archive_links = ŠŸŃ€ŠøŃ…Š¾Š²Š°Ń‚Šø автоматично генеровані архіви +branch.delete_desc = Š’ŠøŠ“Š°Š»ŠµŠ½Š½Ń гілки є остаточним. Єоча виГалена гілка може Ń–ŃŠ½ŃƒŠ²Š°Ń‚Šø ще Š“ŠµŃŠŗŠøŠ¹ час Го того, ŃŠŗ її буГе виГалено, цю Š“Ń–ŃŽ ŠŠ•ŠœŠžŠ–Š›Š˜Š’Šž ŃŠŗŠ°ŃŃƒŠ²Š°Ń‚Šø в Š±Ń–Š»ŃŒŃˆŠ¾ŃŃ‚Ń– випаГків. ŠŸŃ€Š¾Š“Š¾Š²Š¶ŠøŃ‚Šø? +release.deletion_desc = Š’ŠøŠ“Š°Š»ŠµŠ½Š½Ń випуску Š²ŠøŠ“Š°Š»ŃŃ” його лише Š· Forgejo. ŠŸŃ€Šø Ń†ŃŒŠ¾Š¼Ńƒ тег Git, вміст Ń€ŠµŠæŠ¾Š·ŠøŃ‚Š¾Ń€Ń–ŃŽ чи його Ń–ŃŃ‚Š¾Ń€Ń–ŃŽ не буГе змінено. ŠŸŃ€Š¾Š“Š¾Š²Š¶ŠøŃ‚Šø? +settings.sourcehut_builds.manifest_path = ŠØŠ»ŃŃ… Го Š¼Š°Š½Ń–Ń„ŠµŃŃ‚Ńƒ збірки +settings.wiki_branch_rename_failure = ŠŠµ Š²Š“Š°Š»Š¾ŃŃ Š½Š¾Ń€Š¼Š°Š»Ń–Š·ŃƒŠ²Š°Ń‚Šø назву вікі-гілки Ń€ŠµŠæŠ¾Š·ŠøŃ‚Š¾Ń€Ń–ŃŽ. +settings.sourcehut_builds.visibility = Š’ŠøŠ“ŠøŠ¼Ń–ŃŃ‚ŃŒ завГань +settings.unarchive.header = Š Š¾Š·Š°Ń€Ń…Ń–Š²ŃƒŠ²Š°Ń‚Šø цей репозиторій +settings.unarchive.success = Репозиторій ŃƒŃŠæŃ–ŃˆŠ½Š¾ розархівовано. +diff.git-notes.remove-body = Š¦ŃŽ ŠæŃ€ŠøŠ¼Ń–Ń‚ŠŗŃƒ буГе виГалено. +tag.ahead.target = Го %s ŠæŃ–ŃŠ»Ń Ń†ŃŒŠ¾Š³Š¾ Ń‚ŠµŠ³Ńƒ +branch.tag_collision = ŠŠµŠ¼Š¾Š¶Š»ŠøŠ²Š¾ створити Š³Ń–Š»ŠŗŃƒ Ā«%sĀ», Š¾ŃŠŗŃ–Š»ŃŒŠŗŠø у репозиторії вже є тег Ń–Š· Ń‚Š°ŠŗŠ¾ŃŽ Š½Š°Š·Š²Š¾ŃŽ. +branch.branch_name_conflict = ŠŠ°Š·Š²Š° гілки Ā«%sĀ» ŠŗŠ¾Š½Ń„Š»Ń–ŠŗŃ‚ŃƒŃ” Š· Š½Š°ŃŠ²Š½Š¾ŃŽ Š³Ń–Š»ŠŗŠ¾ŃŽ Ā«%sĀ». +settings.wiki_branch_rename_success = ŠŠ°Š·Š²Ńƒ вікі-гілки Ń€ŠµŠæŠ¾Š·ŠøŃ‚Š¾Ń€Ń–ŃŽ ŃƒŃŠæŃ–ŃˆŠ½Š¾ нормалізовано. +diff.has_escaped = Š£ Ń†ŃŒŠ¾Š¼Ńƒ Ń€ŃŠ“ŠŗŃƒ є приховані символи Š®Š½Ń–ŠŗŠ¾Š“Ńƒ +settings.unarchive.text = Š Š¾Š·Š°Ń€Ń…Ń–Š²ŃƒŠ²Š°Š½Š½Ń Ń€ŠµŠæŠ¾Š·ŠøŃ‚Š¾Ń€Ń–ŃŽ Š²Ń–Š“Š½Š¾Š²ŠøŃ‚ŃŒ Š¼Š¾Š¶Š»ŠøŠ²Ń–ŃŃ‚ŃŒ наГсилати Го нього коміти і Š²ŠøŠŗŠ¾Š½ŃƒŠ²Š°Ń‚Šø push, а також ŃŃ‚Š²Š¾Ń€ŃŽŠ²Š°Ń‚Šø заГачі і запити на Š·Š»ŠøŃ‚Ń‚Ń. +settings.wiki_rename_branch_main_notices_1 = Š¦ŃŽ Š¾ŠæŠµŃ€Š°Ń†Ń–ŃŽ ŠŠ•ŠœŠžŠ–Š›Š˜Š’Šž ŃŠŗŠ°ŃŃƒŠ²Š°Ń‚Šø. +settings.unarchive.error = Š”Ń‚Š°Š»Š°ŃŃ помилка при спробі Ń€Š¾Š·Š°Ń€Ń…Ń–Š²ŃƒŠ²Š°Ń‚Šø репозиторій. Š”Š¾ŠŗŠ»Š°Š“Š½Ń–ŃˆŃƒ Ń–Š½Ń„Š¾Ń€Š¼Š°Ń†Ń–ŃŽ Гив. у Š¶ŃƒŃ€Š½Š°Š»Ń–. +settings.wiki_rename_branch_main = ŠŠ¾Ń€Š¼Š°Š»Ń–Š·ŃƒŠ²Š°Ń‚Šø назву вікі-гілки +settings.wiki_rename_branch_main_notices_2 = Š’Š½ŃƒŃ‚Ń€Ń–ŃˆŠ½ŃŽ вікі-Š³Ń–Š»ŠŗŃƒ Ń€ŠµŠæŠ¾Š·ŠøŃ‚Š¾Ń€Ń–ŃŽ %s буГе назавжГи перейменовано. Š†ŃŠ½ŃƒŃŽŃ‡Ń– перевірки потрібно буГе оновити. +settings.pull_mirror_sync_in_progress = Триває Š¾Ń‚Ń€ŠøŠ¼Š°Š½Š½Ń змін Š· віГГаленого Ń€ŠµŠæŠ¾Š·ŠøŃ‚Š¾Ń€Ń–ŃŽ %s. +settings.enter_repo_name = Š£Š²ŠµŠ“Ń–Ń‚ŃŒ ім'я власника і назву Ń€ŠµŠæŠ¾Š·ŠøŃ‚Š¾Ń€Ń–ŃŽ, ŃŠŗ показано: +settings.pulls.allow_rebase_update = Š£Š²Ń–Š¼ŠŗŠ½ŃƒŃ‚Šø Š¾Š½Š¾Š²Š»ŠµŠ½Š½Ń гілки Š·Š°ŠæŠøŃ‚Ńƒ на Š·Š»ŠøŃ‚Ń‚Ń за Š“Š¾ŠæŠ¾Š¼Š¾Š³Š¾ŃŽ ŠæŠµŃ€ŠµŠ±Š°Š·ŃƒŠ²Š°Š½Š½Ń +settings.mirror_settings.docs.pulling_remote_title = ŠžŃ‚Ń€ŠøŠ¼Š°Š½Š½Ń Š· віГГаленого Ń€ŠµŠæŠ¾Š·ŠøŃ‚Š¾Ń€Ń–ŃŽ +settings.mirror_settings.docs.doc_link_pull_section = розГіл Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†Ń–Ń— Ā«ŠžŃ‚Ń€ŠøŠ¼Š°Š½Š½Ń Š· віГГаленого Ń€ŠµŠæŠ¾Š·ŠøŃ‚Š¾Ń€Ń–ŃŽĀ». +settings.pull_mirror_sync_quota_exceeded = ŠŸŠµŃ€ŠµŠ²ŠøŃ‰ŠµŠ½Š¾ ŠŗŠ²Š¾Ń‚Ńƒ, Š¾Ń‚Ń€ŠøŠ¼Š°Š½Š½Ń змін неможливе. +settings.mirror_settings.push_mirror.none_ssh = ŠŠµŠ¼Š°Ń” +settings.admin_stats_indexer = ІнГексатор статистики коГу +settings.admin_indexer_commit_sha = ŠžŃŃ‚Š°Š½Š½Ń–Š¹ інГексований коміт +settings.discord_icon_url.exceeds_max_length = URL-аГреса значка не може Š±ŃƒŃ‚Šø Š“Š¾Š²ŃˆŠ¾ŃŽ, ніж 2048 символи +settings.protect_invalid_status_check_pattern = ŠŠµŠ“Ń–Š¹ŃŠ½ŠøŠ¹ шаблон перевірки ŃŃ‚Š°Š½Ńƒ: Ā«%sĀ». +settings.protect_no_valid_status_check_patterns = ŠŠµŠ¼Š°Ń” Гійсних ŃˆŠ°Š±Š»Š¾Š½Ń–Š² перевірки ŃŃ‚Š°Š½Ńƒ. +settings.admin_indexer_unindexed = ŠŠµ інГексовано +settings.push_mirror_sync_in_progress = Триває Š½Š°Š“ŃŠøŠ»Š°Š½Š½Ń змін Го віГГаленого Ń€ŠµŠæŠ¾Š·ŠøŃ‚Š¾Ń€Ń–ŃŽ %s. +settings.releases_desc = Š£Š²Ń–Š¼ŠŗŠ½ŃƒŃ‚Šø випуски в репозиторії +settings.admin_code_indexer = ІнГексатор коГу +settings.protect_status_check_patterns_desc = Š£Š²ŠµŠ“Ń–Ń‚ŃŒ шаблони, щоб вказати, ŃŠŗŃ– перевірки ŃŃ‚Š°Š½Ńƒ повинні пройти гілки, ŠæŠµŃ€Ńˆ ніж їх буГе об'єГнано у Š³Ń–Š»ŠŗŃƒ, що віГповіГає Ń†ŃŒŠ¾Š¼Ńƒ ŠæŃ€Š°Š²ŠøŠ»Ńƒ. Кожен Ń€ŃŠ“Š¾Šŗ визначає шаблон. Шаблони не Š¼Š¾Š¶ŃƒŃ‚ŃŒ Š±ŃƒŃ‚Šø порожніми. +settings.add_webhook.invalid_path = ŠØŠ»ŃŃ… не повинен містити частини Ā«.Ā» або Ā«..Ā» і не повинен Š±ŃƒŃ‚Šø порожнім. Він не може ŠæŠ¾Ń‡ŠøŠ½Š°Ń‚ŠøŃŃ або Š·Š°ŠŗŃ–Š½Ń‡ŃƒŠ²Š°Ń‚ŠøŃŃ ŠŗŠ¾ŃŠ¾ŃŽ Ń€ŠøŃŠŗŠ¾ŃŽ. +settings.matrix.access_token_helper = Š ŠµŠŗŠ¾Š¼ŠµŠ½Š“ŃƒŃ”Ń‚ŃŒŃŃ створити окремий обліковий запис Matrix. Токен Š“Š¾ŃŃ‚ŃƒŠæŃƒ можна отримати у вебклієнті Element (у приватній/інкогніто вклаГці): User menu (вгорі Š»Ń–Š²Š¾Ń€ŃƒŃ‡) > All settings > Help & About > Advanced > Access Token (піГ URL-Š°Š“Ń€ŠµŃŠ¾ŃŽ Homeserver). Закрийте ŠæŃ€ŠøŠ²Š°Ń‚Š½Ńƒ вклаГку (вихіГ Ń–Š· системи Š·Ń€Š¾Š±ŠøŃ‚ŃŒ токен неГійсним). +settings.protect_patterns = Шаблони +settings.sourcehut_builds.access_token_helper = Токен Š“Š¾ŃŃ‚ŃƒŠæŃƒ, ŃŠŗŠøŠ¹ має Гозвіл JOBS:RW. Š—Š³ŠµŠ½ŠµŃ€ŃƒŠ¹Ń‚Šµ токен builds.sr.ht або токен builds.sr.ht Š· Š“Š¾ŃŃ‚ŃƒŠæŠ¾Š¼ Го секретів на meta.sr.ht. +editor.unable_to_upload_files = ŠŠµ Š²Š“Š°Š»Š¾ŃŃ завантажити файли в Ā«%sĀ» через помилку: %v +view_git_blame = ŠŸŠµŃ€ŠµŠ³Š»ŃŠ½ŃƒŃ‚Šø git blame +commits.ssh_key_fingerprint = ВіГбиток ŠŗŠ»ŃŽŃ‡Š° SSH +settings.web_hook_name_telegram = Telegram +pulls.status_checks_hide_all = ŠŸŃ€ŠøŃ…Š¾Š²Š°Ń‚Šø всі перевірки +settings.thread_id = Thread ID +settings.matrix.room_id_helper = ID кімнати можна отримати у вебклієнті Element: Room Settings > Advanced > Internal room ID. ŠŸŃ€ŠøŠŗŠ»Š°Š“: %s. +editor.push_rejected_no_message = Š—Š¼Ń–Š½Ńƒ віГхилено сервером без ŠæŠ¾Š²Ń–Š“Š¾Š¼Š»ŠµŠ½Š½Ń. Š‘ŃƒŠ“ŃŒ ласка, перевірте Git-Ń…ŃƒŠŗŠø. +editor.upload_files_to_dir = Завантажити файли в Ā«%sĀ» +issues.filter_sort.relevance = За Š²Ń–Š“ŠæŠ¾Š²Ń–Š“Š½Ń–ŃŃ‚ŃŽ +editor.cannot_commit_to_protected_branch = ŠŠµŠ¼Š¾Š¶Š»ŠøŠ²Š¾ зГійснити коміт Го захищеної гілки Ā«%sĀ». +editor.file_deleting_no_longer_exists = Файл Ā«%sĀ», ŃŠŗŠøŠ¹ ви Š²ŠøŠ“Š°Š»ŃŃ”Ń‚Šµ, Š±Ń–Š»ŃŒŃˆŠµ не Ń–ŃŠ½ŃƒŃ” у Ń†ŃŒŠ¾Š¼Ńƒ репозиторії. +editor.file_editing_no_longer_exists = Файл Ā«%sĀ», ŃŠŗŠøŠ¹ ви Ń€ŠµŠ“Š°Š³ŃƒŃ”Ń‚Šµ, Š±Ń–Š»ŃŒŃˆŠµ не Ń–ŃŠ½ŃƒŃ” у Ń†ŃŒŠ¾Š¼Ńƒ репозиторії. +diff.show_file_tree = ŠŸŠ¾ŠŗŠ°Š·Š°Ń‚Šø Герево файлів +milestones.filter_sort.name = За Š½Š°Š·Š²Š¾ŃŽ +pulls.allow_edits_from_maintainers_err = ŠŠµ Š²Š“Š°Š»Š¾ŃŃ оновити +pulls.has_viewed_file = ŠŸŠµŃ€ŠµŠ³Š»ŃŠ½ŃƒŃ‚Š¾ +editor.file_already_exists = Файл Ń–Š· Š½Š°Š·Š²Š¾ŃŽ Ā«%sĀ» вже є у Ń†ŃŒŠ¾Š¼Ńƒ репозиторії. +commits.view_path = ŠŸŠµŃ€ŠµŠ³Š»ŃŠ½ŃƒŃ‚Šø на Ń†ŃŒŠ¾Š¼Ńƒ етапі історії +editor.push_rejected = Š—Š¼Ń–Š½Ńƒ віГхилено сервером. Š‘ŃƒŠ“ŃŒ ласка, перевірте Git-Ń…ŃƒŠŗŠø. +commits.renamed_from = ŠŸŠµŃ€ŠµŠ¹Š¼ŠµŠ½Š¾Š²Š°Š½Š¾ Š· %s +diff.hide_file_tree = ŠŸŃ€ŠøŃ…Š¾Š²Š°Ń‚Šø Герево файлів +pulls.viewed_files_label = %[1]d Š· %[2]d файлів ŠæŠµŃ€ŠµŠ³Š»ŃŠ½ŃƒŃ‚Š¾ +settings.protected_branch_duplicate_rule_name = Š”Š»Ń Ń†ŃŒŠ¾Š³Š¾ Š½Š°Š±Š¾Ń€Ńƒ гілок уже є правило +settings.mirror_settings.push_mirror.edit_sync_time = Змінити інтервал синхронізації Гзеркала +wiki.delete_page_notice_1 = Š’ŠøŠ“Š°Š»ŠµŠ½Š½Ń вікі-сторінки Ā«%sĀ» неможливо ŃŠŗŠ°ŃŃƒŠ²Š°Ń‚Šø. ŠŸŃ€Š¾Š“Š¾Š²Š¶ŠøŃ‚Šø? +issues.label_archived_filter = ŠŸŠ¾ŠŗŠ°Š·Š°Ń‚Šø архівовані мітки +milestones.new_subheader = Етапи Š“Š¾ŠæŠ¾Š¼Š°Š³Š°ŃŽŃ‚ŃŒ Š¾Ń€Š³Š°Š½Ń–Š·ŃƒŠ²Š°Ń‚Šø заГачі та Š²Ń–Š“ŃŃ‚ŠµŠ¶ŃƒŠ²Š°Ń‚Šø прогрес їх Š²ŠøŠŗŠ¾Š½Š°Š½Š½Ń. +issues.closed_by_fake = віГ %[2]s закрито %[1]s +issues.closed_by = віГ %[3]s закрито %[1]s +issues.action_check = ŠŸŠ¾ŃŃ‚Š°Š²ŠøŃ‚Šø/Š·Š½ŃŃ‚Šø ŠæŠ¾Š·Š½Š°Ń‡ŠŗŃƒ +issues.action_check_all = ŠŸŠ¾ŃŃ‚Š°Š²ŠøŃ‚Šø/Š·Š½ŃŃ‚Šø ŠæŠ¾Š·Š½Š°Ń‡ŠŗŃƒ Š· усіх елементів +vendored = Дторонній [graphs] contributors.what = внески @@ -2798,6 +2902,8 @@ teams.invite_team_member = Запросити Го %s teams.write_access = Запис teams.invite.by = Вас Š·Š°ŠæŃ€Š¾ŃˆŃƒŃ” %s teams.invite_team_member.list = Š—Š°ŠæŃ€Š¾ŃˆŠµŠ½Š½Ń в Š¾Ń‡Ń–ŠŗŃƒŠ²Š°Š½Š½Ń– +form.name_pattern_not_allowed = Вираз Ā«%sĀ» не може Š±ŃƒŃ‚Šø Ń‡Š°ŃŃ‚ŠøŠ½Š¾ŃŽ назви організації. +teams.add_nonexistent_repo = Репозиторій, ŃŠŗŠøŠ¹ ви Š½Š°Š¼Š°Š³Š°Ń”Ń‚ŠµŃŃ ГоГати, не Ń–ŃŠ½ŃƒŃ”. Š”ŠæŠ¾Ń‡Š°Ń‚ŠŗŃƒ ŃŃ‚Š²Š¾Ń€Ń–Ń‚ŃŒ його. [admin] dashboard=Панель ŃƒŠæŃ€Š°Š²Š»Ń–Š½Š½Ń @@ -2909,7 +3015,7 @@ users.is_activated=ŠžŠ±Š»Ń–ŠŗŠ¾Š²ŠøŠ¹ запис ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š° ŃƒŠ²Ń–Š¼ users.prohibit_login=Заблокований обліковий запис users.is_admin=ŠžŠ±Š»Ń–ŠŗŠ¾Š²ŠøŠ¹ запис аГміністратора users.is_restricted=ŠžŠ±Š¼ŠµŠ¶ŠµŠ½ŠøŠ¹ -users.allow_git_hook=Може ŃŃ‚Š²Š¾Ń€ŃŽŠ²Š°Ń‚Šø Git Ń…ŃƒŠŗŠø +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=Може ŃŃ‚Š²Š¾Ń€ŃŽŠ²Š°Ń‚Šø організації @@ -3051,7 +3157,7 @@ auths.sspi_default_language_helper=Типова мова Š“Š»Ń ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ² auths.tips=ŠŸŠ¾Ń€Š°Š“Šø auths.tips.oauth2.general=ŠŠ²Ń‚ŠµŠ½Ń‚ŠøŃ„Ń–ŠŗŠ°Ń†Ń–Ń OAuth2 auths.tip.oauth2_provider=ŠŸŠ¾ŃŃ‚Š°Ń‡Š°Š»ŃŒŠ½ŠøŠŗ OAuth2 -auths.tip.bitbucket=Š”Ń‚Š²Š¾Ń€Ń–Ń‚ŃŒ OAuth URI на сторінці %s +auths.tip.bitbucket=Š—Š°Ń€ŠµŃ”ŃŃ‚Ń€ŃƒŠ¹Ń‚Šµ нового споживача OAuth на %s і ГоГайте Гозвіл Ā«ŠžŠ±Š»Ń–ŠŗŠ¾Š²ŠøŠ¹ запис» — Ā«Š§ŠøŃ‚Š°Š½Š½ŃĀ» auths.tip.nextcloud=`Š—Š°Ń€ŠµŃ”ŃŃ‚Ń€ŃƒŠ¹Ń‚Šµ нового споживача OAuth у вашому ŠµŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Ń– за Š“Š¾ŠæŠ¾Š¼Š¾Š³Š¾ŃŽ Š½Š°ŃŃ‚ŃƒŠæŠ½Š¾Š³Š¾ Š¼ŠµŠ½ŃŽ "ŠŠ°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Š½Š½Ń -> Безпека -> клієнт OAuth 2.0"` auths.tip.dropbox=Š”Ń‚Š²Š¾Ń€Ń–Ń‚ŃŒ новий ГоГаток на %s auths.tip.facebook=Š—Š°Ń€ŠµŃ”ŃŃ‚Ń€ŃƒŠ¹Ń‚Šµ новий ГоГаток на %s і ГоГайте моГуль Ā«Facebook LoginĀ» @@ -3059,7 +3165,7 @@ auths.tip.github=Š—Š°Ń€ŠµŃ”ŃŃ‚Ń€ŃƒŠ¹Ń‚Šµ новий ГоГаток OAuth на % auths.tip.gitlab=ДоГайте новий ГоГаток на https://gitlab.com/profile/applications auths.tip.google_plus=ŠžŃ‚Ń€ŠøŠ¼Š°Š¹Ń‚Šµ облікові Гані клієнта OAuth2 в консолі Google API на сторінці %s auths.tip.openid_connect=Š’ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŠ¹Ń‚Šµ OpenID Connect Discovery URL (/.well-known/openid-configuration) Š“Š»Ń автоматичної настройки Š²Ń…Š¾Š“Ńƒ OAuth -auths.tip.twitter=ŠŸŠµŃ€ŠµŠ¹Š“Ń–Ń‚ŃŒ на %s, ŃŃ‚Š²Š¾Ń€Ń–Ń‚ŃŒ ŠæŃ€Š¾Š³Ń€Š°Š¼Ńƒ і ŠæŠµŃ€ŠµŠŗŠ¾Š½Š°Š¹Ń‚ŠµŃŃ, що Š²ŠŗŠ»ŃŽŃ‡ŠµŠ½Š° Š¾ŠæŃ†Ń–Ń «Дозволити цю ŠæŃ€Š¾Š³Ń€Š°Š¼Ńƒ Š“Š»Ń Š²Ń…Š¾Š“Ńƒ в ŃŠøŃŃ‚ŠµŠ¼Ńƒ за Š“Š¾ŠæŠ¾Š¼Š¾Š³Š¾ŃŽ TwitterĀ» +auths.tip.twitter=ŠŸŠµŃ€ŠµŠ¹Š“Ń–Ń‚ŃŒ на %s, ŃŃ‚Š²Š¾Ń€Ń–Ń‚ŃŒ ŠæŃ€Š¾Š³Ń€Š°Š¼Ńƒ і ŠæŠµŃ€ŠµŠŗŠ¾Š½Š°Š¹Ń‚ŠµŃŃ, що ввімкнено Š¾ŠæŃ†Ń–ŃŽ «Дозволити Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š°Š½Š½Ń цієї програми Š“Š»Ń Š²Ń…Š¾Š“Ńƒ через TwitterĀ» auths.tip.discord=Š—Š°Ń€ŠµŃ”ŃŃ‚Ń€ŃƒŠ¹Ń‚Šµ новий ГоГаток на %s auths.tip.yandex=Š”Ń‚Š²Š¾Ń€Ń–Ń‚ŃŒ новий ГоГаток на %s. Š£ розГілі Ā«Yandex.Passport APIĀ» Š²ŠøŠ±ŠµŃ€Ń–Ń‚ŃŒ такі Гозволи: Ā«Š”Š¾ŃŃ‚ŃƒŠæ Го аГреси електронної ŠæŠ¾ŃˆŃ‚ŠøĀ», Ā«Š”Š¾ŃŃ‚ŃƒŠæ Го аватара» і Ā«Š”Š¾ŃŃ‚ŃƒŠæ Го імені ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š°, імені та прізвища, статі» auths.tip.mastodon=Š’Š²ŠµŠ“Ń–Ń‚ŃŒ URL ŃŠæŠµŃ†Ń–Š°Š»ŃŒŠ½Š¾Š³Š¾ ŠµŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Š° Š“Š»Ń ŠµŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Š° mastodon, ŃŠŗŠøŠ¹ ви хочете Š°Š²Ń‚ŠµŠ½Ń‚ŠøŃ„Ń–ŠŗŃƒŠ²Š°Ń‚Šø за Š“Š¾ŠæŠ¾Š¼Š¾Š³Š¾ŃŽ (або Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŠ²Š°Ń‚Šø за Š·Š°Š¼Š¾Š²Ń‡ŃƒŠ²Š°Š½Š½ŃŠ¼) @@ -3193,7 +3299,7 @@ config.git_gc_timeout=Тайм-Š°ŃƒŃ‚ операції збирача смітт config.log_config=ŠšŠ¾Š½Ń„Ń–Š³ŃƒŃ€Š°Ń†Ń–Ń Š¶ŃƒŃ€Š½Š°Š»Ńƒ config.disabled_logger=Вимкнено -config.access_log_mode=Режим Š“Š¾ŃŃ‚ŃƒŠæŃƒ Го Š¶ŃƒŃ€Š½Š°Š»Ńƒ +config.access_log_mode=Режим Š¶ŃƒŃ€Š½Š°Š»ŃŽŠ²Š°Š½Š½Ń Š“Š¾ŃŃ‚ŃƒŠæŃƒ config.xorm_log_sql=Š–ŃƒŃ€Š½Š°Š» SQL @@ -3250,13 +3356,13 @@ packages.package_manage_panel = ŠšŠµŃ€ŃƒŠ²Š°Š½Š½Ń пакунками packages.published = ŠžŠæŃƒŠ±Š»Ń–ŠŗŠ¾Š²Š°Š½Š¾ notices.operations = Дії packages.cleanup = ŠžŃ‡ŠøŃŃ‚ŠøŃ‚Šø неГійсні Гані -packages.cleanup.success = Š£ŃŠæŃ–ŃˆŠ½Š¾ очищено неГійсні Гані +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.allow_dots_in_usernames = Дозволити Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š°Š½Š½Ń крапки в іменах ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Ń–Š². ŠŠµ впливає на облікові записи, що вже Ń–ŃŠ½ŃƒŃŽŃ‚ŃŒ. config.mailer_enable_helo = Š£Š²Ń–Š¼ŠŗŠ½ŃƒŃ‚Šø HELO users.organization_creation.description = Дозволити ŃŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń нових організацій. users.cannot_delete_self = Š’Šø не можете виГалити себе @@ -3306,6 +3412,17 @@ defaulthooks.desc = Š’ŠµŠ±Ń…ŃƒŠŗŠø автоматично ŃŠæŠ¾Š²Ń–Ń‰Š°ŃŽŃ‚ŃŒ H assets = Š ŠµŃŃƒŃ€ŃŠø коГу auths.invalid_openIdConnectAutoDiscoveryURL = ŠŠµŠæŃ€Š°Š²ŠøŠ»ŃŒŠ½Š° URL-аГреса автоматичного Š²ŠøŃŠ²Š»ŠµŠ½Š½Ń (повинна Š±ŃƒŃ‚Šø Гійсна URL-аГреса, що ŠæŠ¾Ń‡ŠøŠ½Š°Ń”Ń‚ŃŒŃŃ Š· http:// або https://) settings = ŠŠ°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Š½Š½Ń аГміністратора +dashboard.start_schedule_tasks = Š—Š°ŠæŃƒŃŃ‚ŠøŃ‚Šø заплановані Š·Š°Š²Š“Š°Š½Š½Ń Гій +config.logger_name_fmt = Š–ŃƒŃ€Š½Š°Š»: %s +config.set_setting_failed = ŠŠµ Š²Š“Š°Š»Š¾ŃŃ встановити параметр %s +config.access_log_template = Шаблон Š¶ŃƒŃ€Š½Š°Š»Ńƒ Š“Š¾ŃŃ‚ŃƒŠæŃƒ +dashboard.cancel_abandoned_jobs = Š”ŠŗŠ°ŃŃƒŠ²Š°Ń‚Šø ŠæŠ¾ŠŗŠøŠ½ŃƒŃ‚Ń– Š·Š°Š²Š“Š°Š½Š½Ń Гій +monitor.download_diagnosis_report = Завантажити Гіагностичний звіт +auths.oauth2_map_group_to_team_removal = Š’ŠøŠ“Š°Š»ŃŃ‚Šø ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Ń–Š² Ń–Š· синхронізованих команГ, ŃŠŗŃ‰Š¾ ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Ń– не Š½Š°Š»ŠµŠ¶Š°Ń‚ŃŒ Го віГповіГної Š³Ń€ŃƒŠæŠø. +config.mailer_smtp_addr = АГреса SMTP +dashboard.update_checker = ŠŸŠµŃ€ŠµŠ²Ń–Ń€ŠŗŠ° оновлень +auths.map_group_to_team_removal = Š’ŠøŠ“Š°Š»ŃŃ‚Šø ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Ń–Š² Ń–Š· синхронізованих команГ, ŃŠŗŃ‰Š¾ ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Ń– не Š½Š°Š»ŠµŠ¶Š°Ń‚ŃŒ Го віГповіГної Š³Ń€ŃƒŠæŠø LDAP +auths.enable_ldap_groups = Š£Š²Ń–Š¼ŠŗŠ½ŃƒŃ‚Šø Š³Ń€ŃƒŠæŠø LDAP [action] @@ -3324,7 +3441,7 @@ merge_pull_request=`ŠæŃ€ŠøŠ¹Š½ŃŠ² запит Š·Š»ŠøŃ‚Ń‚Ń %[3]s transfer_repo=перенесено репозиторій %s у %s push_tag=наГсилає тег %[3]s в %[4]s delete_tag=Š²ŠøŠ“Š°Š»ŃŃ” тег %[2]s Ń–Š· %[3]s -delete_branch=виГалено Š³Ń–Š»ŠŗŃƒ %[2]s Š· %[3]s +delete_branch=виГалено Š³Ń–Š»ŠŗŃƒ %[2]s Š· %[3]s compare_branch=ŠŸŠ¾Ń€Ń–Š²Š½ŃŃ‚Šø compare_commits=ŠŸŠ¾Ń€Ń–Š²Š½ŃŃ‚Šø %d комітів compare_commits_general=ŠŸŠ¾Ń€Ń–Š²Š½ŃŃ‚Šø коміти @@ -3410,7 +3527,7 @@ settings.delete.notice = Š’Šø Š·Š±ŠøŃ€Š°Ń”Ń‚ŠµŃŃ виГалити %s (%s). Ц details.author = Автор title = Пакунки arch.version.backup = Резервне ŠŗŠ¾ŠæŃ–ŃŽŠ²Š°Š½Š½Ń -arch.version.conflicts = Š”ŃƒŠæŠµŃ€ŠµŃ‡ŠŗŠø +arch.version.conflicts = ŠšŠ¾Š½Ń„Š»Ń–ŠŗŃ‚Šø arch.version.replaces = Заміни arch.version.provides = ŠŠ°Š“Š°Ń” arch.version.groups = Š“Ń€ŃƒŠæŠ° @@ -3526,6 +3643,14 @@ cran.registry = ŠŠ°Š»Š°ŃˆŃ‚ŃƒŠ¹Ń‚Šµ цей реєстр у файлі Rpr npm.registry = ŠŠ°Š»Š°ŃˆŃ‚ŃƒŠ¹Ń‚Šµ цей реєстр у файлі .npmrc свого ŠæŃ€Š¾Ń”ŠŗŃ‚Ńƒ: chef.registry = ŠŠ°Š»Š°ŃˆŃ‚ŃƒŠ¹Ń‚Šµ цей реєстр у файлі ~/.chef/config.rb: owner.settings.chef.keypair.description = Запити Го Ń€ŠµŃ”ŃŃ‚Ń€Ńƒ Chef повинні Š±ŃƒŃ‚Šø криптографічно піГписані ŃŠŗ засіб автентифікації. ŠŸŃ€Šø генерації пари ŠŗŠ»ŃŽŃ‡Ń–в на Forgejo Š·Š±ŠµŃ€Ń–Š³Š°Ń”Ń‚ŃŒŃŃ Ń‚Ń–Š»ŃŒŠŗŠø ŠæŃƒŠ±Š»Ń–Ń‡Š½ŠøŠ¹ ŠŗŠ»ŃŽŃ‡. ŠŸŃ€ŠøŠ²Š°Ń‚Š½ŠøŠ¹ ŠŗŠ»ŃŽŃ‡ Š½Š°Š“Š°Ń”Ń‚ŃŒŃŃ вам Š“Š»Ń Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š°Š½Š½Ń команГ knife. Š“ŠµŠ½ŠµŃ€Š°Ń†Ń–Ń нової пари ŠŗŠ»ŃŽŃ‡Ń–в Š·Š°Š¼Ń–Š½ŠøŃ‚ŃŒ ŠæŠ¾ŠæŠµŃ€ŠµŠ“Š½ŃŽ. +nuget.dependency.framework = Š¦Ń–Š»ŃŒŠ¾Š²ŠøŠ¹ фреймворк +owner.settings.cleanuprules.preview.overview = Заплановано виГалити %d ŠæŠ°ŠŗŃƒŠ½ŠŗŃ–Š². +owner.settings.cleanuprules.pattern_full_match = Š—Š°ŃŃ‚Š¾ŃŃƒŠ²Š°Ń‚Šø шаблон Го повної назви пакунка +maven.download = Щоб завантажити Š·Š°Š»ŠµŠ¶Š½Ń–ŃŃ‚ŃŒ, Š·Š°ŠæŃƒŃŃ‚Ń–Ń‚ŃŒ Ń–Š· команГного Ń€ŃŠ“ŠŗŠ°: +maven.install2 = Š—Š°ŠæŃƒŃŃ‚ŠøŃ‚Šø Š· команГного Ń€ŃŠ“ŠŗŠ°: +npm.dependencies.bundle = ŠŸŠ°ŠŗŠµŃ‚Š½Ń– залежності +npm.dependencies.peer = ŠžŠ“Š½Š¾Ń€Š°Š½Š³Š¾Š²Ń– залежності +arch.pacman.repo.multi = %s має оГну й ту саму Š²ŠµŃ€ŃŃ–ŃŽ в різних Š“ŠøŃŃ‚Ń€ŠøŠ±ŃƒŃ‚ŠøŠ²Š°Ń…. [secrets] deletion = ВиГалити секрет @@ -3629,6 +3754,10 @@ runners.update_runner_success = Ранер оновлено runners.delete_runner_header = ŠŸŃ–Š“Ń‚Š²ŠµŃ€Š“Ń–Ń‚ŃŒ Š²ŠøŠ“Š°Š»ŠµŠ½Š½Ń ранера runners.status.offline = ŠŠµŠ°ŠŗŃ‚ŠøŠ²Š½ŠøŠ¹ runners.status.idle = ŠŸŃ€Š¾ŃŃ‚Š¾ŃŽŃ” +runs.invalid_workflow_helper = ŠŠµŠ“Ń–Š¹ŃŠ½ŠøŠ¹ файл ŠŗŠ¾Š½Ń„Ń–Š³ŃƒŃ€Š°Ń†Ń–Ń— робочого ŠæŠ¾Ń‚Š¾ŠŗŃƒ. Š‘ŃƒŠ“ŃŒ ласка, перевірте файл ŠŗŠ¾Š½Ń„Ń–Š³ŃƒŃ€Š°Ń†Ń–Ń—: %s +runs.no_job = Робочий потік повинен містити принаймні оГне Š·Š°Š²Š“Š°Š½Š½Ń +workflow.dispatch.use_from = Використати робочий потік Ń–Š· +runs.no_job_without_needs = Робочий потік повинен містити принаймні оГне Š·Š°Š²Š“Š°Š½Š½Ń без залежностей. @@ -3641,7 +3770,7 @@ deleted.display_name = ВиГалений проєкт [git.filemode] symbolic_link=Димволічне ŠæŠ¾ŃŠøŠ»Š°Š½Š½Ń -directory = Тека +directory = ŠšŠ°Ń‚Š°Š»Š¾Š³ submodule = ŠŸŃ–Š“Š¼Š¾Š“ŃƒŠ»ŃŒ normal_file = Звичайний файл executable_file = Š’ŠøŠŗŠ¾Š½ŃƒŠ²Š°Š½ŠøŠ¹ файл diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index c6c534df9f..59901392c2 100644 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -70,7 +70,7 @@ your_starred=ē‚¹čµž your_settings=设置 all=ꉀ꜉ -sources=ę„ęŗ +sources=原创 mirrors=镜像 collaborative=协作 forks=ę“¾ē”Ÿ @@ -171,7 +171,7 @@ copy_path = å¤åˆ¶č·Æå¾„ [aria] navbar=åÆ¼čˆŖę  footer=锵脚 -footer.software=å…³äŗŽč½Æä»¶ +footer.software=å…³äŗŽę­¤č½Æä»¶ footer.links=é“¾ęŽ„ [heatmap] @@ -1062,7 +1062,7 @@ 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.one = ę—§ē”Øęˆ·åå°†åœØ %[1]d å¤©ēš„äæęŠ¤ęœŸåŽåÆ¹ę‰€ęœ‰äŗŗåÆē”Øć€‚ę‚Øä»åÆä»„åœØę­¤ęœŸé—“é‡ę–°č®¤é¢†ę—§ē”Øęˆ·åć€‚ change_username_redirect_prompt.with_cooldown.few = ę—§ē”Øęˆ·åå°†åœØ %[1]d å¤©ēš„äæęŠ¤ęœŸåŽåÆ¹ę‰€ęœ‰äŗŗåÆē”Øļ¼Œę‚Øä»åÆä»„åœØę­¤ęœŸé—“é‡ę–°č®¤é¢†ę—§ē”Øęˆ·åć€‚ keep_pronouns_private = ä»…å‘å·²č®¤čÆē”Øęˆ·ę˜¾ē¤ŗä»£čÆ keep_pronouns_private.description = čæ™å°†åÆ¹ęœŖē™»å½•ēš„č®æé—®č€…éšč—ę‚Øēš„ä»£čÆć€‚ @@ -3636,7 +3636,7 @@ auto_merge_pull_request=`č‡ŖåŠØåˆå¹¶äŗ†ę‹‰å–čÆ·ę±‚ %[3]s#%[2]s transfer_repo=将仓库 %s 转移至 %s push_tag=ęŽØé€äŗ†ę ‡ē­¾ %[3]s 至仓库 %[4]s delete_tag=从%[3]s åˆ é™¤äŗ†ę ‡ē­¾ %[2]s -delete_branch=从 %[3]s åˆ é™¤åˆ†ę”Æ %[2]s +delete_branch=åˆ é™¤äŗ† %[3]s ēš„ %[2]s åˆ†ę”Æ compare_branch=ęÆ”č¾ƒ compare_commits=ęÆ”č¾ƒ %d ęäŗ¤ compare_commits_general=ęÆ”č¾ƒęäŗ¤ diff --git a/options/locale/locale_zh-TW.ini b/options/locale/locale_zh-TW.ini index fba51a391e..5f52a02018 100644 --- a/options/locale/locale_zh-TW.ini +++ b/options/locale/locale_zh-TW.ini @@ -1062,7 +1062,7 @@ language.localization_project = å¹«åŠ©ęˆ‘å€‘ēæ»č­Æ Forgejo č‡³ę‚Øēš„čŖžčØ€ļ¼å…¬é–‹ę“»å‹•åŖęœ‰ä½ å’Œē«™é»žē®”ē†å“”åÆč¦‹ć€‚ quota.rule.exceeded = 已超出 @@ -3633,7 +3633,7 @@ auto_merge_pull_request=`č‡Ŗå‹•åˆä½µäŗ†åˆä½µč«‹ę±‚ %[3]s#%[2]s transfer_repo=å°‡å„²å­˜åŗ« %s 轉移至 %s push_tag=ęŽØé€äŗ†ęØ™ē±¤ %[3]s 到 %[4]s delete_tag=åˆŖé™¤äŗ† %[3]s ēš„ęØ™ē±¤ %[2]s -delete_branch=åˆŖé™¤äŗ† %[3]s ēš„ %[2]s åˆ†ę”Æ +delete_branch=åˆŖé™¤äŗ† %[3]s ēš„ %[2]s åˆ†ę”Æ compare_branch=ęÆ”č¼ƒ compare_commits=ęÆ”č¼ƒ %d å€‹ęäŗ¤ compare_commits_general=ęÆ”č¼ƒęäŗ¤ diff --git a/options/locale_next/locale_ar.json b/options/locale_next/locale_ar.json index 3d87c7ee95..cef0f06e23 100644 --- a/options/locale_next/locale_ar.json +++ b/options/locale_next/locale_ar.json @@ -3,5 +3,7 @@ "home.welcome.no_activity": "لا يوجد نؓاط", "home.explore_repos": "اكتؓف Ų§Ł„Ł…Ų³ŲŖŁˆŲÆŲ¹Ų§ŲŖ", "home.explore_users": "اكتؓف Ų§Ł„Ł…Ų³ŲŖŲ®ŲÆŁ…ŁŠŁ†", - "home.explore_orgs": "اكتؓف المنظمات" + "home.explore_orgs": "اكتؓف المنظمات", + "moderation.abuse_category.illegal_content": "Ų§Ł„Ł…Ų­ŲŖŁˆŁ‰ غير Ų§Ł„Ł…Ų“Ų±ŁˆŲ¹", + "moderation.abuse_category.malware": "ŲØŲ±Ł…Ų¬ŁŠŲ© خبيثة" } diff --git a/options/locale_next/locale_be.json b/options/locale_next/locale_be.json index 0967ef424b..40dfec0b41 100644 --- a/options/locale_next/locale_be.json +++ b/options/locale_next/locale_be.json @@ -1 +1,3 @@ -{} +{ + "moderation.abuse_category.malware": "ŠØŠŗŠ¾Š“Š½Š°Ń праграма" +} diff --git a/options/locale_next/locale_bg.json b/options/locale_next/locale_bg.json index 1faf269aba..be8477a98a 100644 --- a/options/locale_next/locale_bg.json +++ b/options/locale_next/locale_bg.json @@ -7,7 +7,6 @@ "one": "иска Га слее %[1]d поГаване от %[2]s в %[3]s", "other": "иска Га слее %[1]d ŠæŠ¾Š“Š°Š²Š°Š½ŠøŃ от %[2]s в %[3]s" }, - "mail.actions.run_info_ref": "Клон: %[1]s (%[2]s)", "mail.actions.run_info_trigger": "ЗаГействано пораГи: %[1]s от: %[2]s", "meta.last_line": "Š’ Š‘ŃŠŠ»Š³Š°Ń€ŠøŃ расте най-старото Š“ŃŠŃ€Š²Š¾ в страната, Š‘Š°Š¹ŠŗŃƒŃˆŠµŠ²Š°Ń‚Š° Š¼ŃƒŃ€Š°, на Š²ŃŠŠ·Ń€Š°ŃŃ‚ наГ 1300 гоГини.", "relativetime.1day": "вчера", diff --git a/options/locale_next/locale_bn.json b/options/locale_next/locale_bn.json index 0967ef424b..56a6e6dae4 100644 --- a/options/locale_next/locale_bn.json +++ b/options/locale_next/locale_bn.json @@ -1 +1,3 @@ -{} +{ + "moderation.abuse_category.malware": "ą¦®ą§ą¦Æą¦¾ą¦²ą¦“ą¦Æą¦¼ą§ą¦Æą¦¾ą¦°" +} diff --git a/options/locale_next/locale_ca.json b/options/locale_next/locale_ca.json index 8eefc65a1a..606ab99173 100644 --- a/options/locale_next/locale_ca.json +++ b/options/locale_next/locale_ca.json @@ -1,3 +1,4 @@ { - "search.milestone_kind": "Cerca fites..." + "search.milestone_kind": "Cerca fites...", + "moderation.abuse_category.malware": "Programari maliciós" } diff --git a/options/locale_next/locale_cs-CZ.json b/options/locale_next/locale_cs-CZ.json index 97a8536d4f..3ce42e6bb0 100644 --- a/options/locale_next/locale_cs-CZ.json +++ b/options/locale_next/locale_cs-CZ.json @@ -28,7 +28,6 @@ "mail.actions.not_successful_run": "Workflow %[1]s selhal v repozitÔři %[2]s", "mail.actions.run_info_cur_status": "Stav tohoto procesu: %[1]s (prĆ”vě aktualizovĆ”no z %[2]s)", "mail.actions.run_info_previous_status": "Stav předchozĆ­ho procesu: %[1]s", - "mail.actions.run_info_ref": "Větev: %[1]s (%[2]s)", "mail.actions.run_info_trigger": "SpuÅ”těno z dÅÆvodu: %[1]s od: %[2]s", "mail.actions.successful_run_after_failure_subject": "Workflow %[1]s obnoven v repozitÔři %[2]s", "mail.actions.successful_run_after_failure": "Workflow %[1]s obnoven v repozitÔři %[2]s", @@ -105,5 +104,12 @@ "settings.visibility.description": "Viditelnost profilu ovlivňuje možnost ostatnĆ­ch přistupovat k vaÅ”im veřejným repozitÔřům. Zjistit vĆ­ce", "avatar.constraints_hint": "Velikost vlastnĆ­ho avataru nesmĆ­ překročit %[1]s nebo být větŔí než %[2]dx%[3]d pixelÅÆ", "repo.diff.commit.next-short": "DalŔí", - "repo.diff.commit.previous-short": "PředchozĆ­" + "repo.diff.commit.previous-short": "PředchozĆ­", + "profile.actions.tooltip": "DalŔí akce", + "keys.gpg.link": "Klƭče GPG", + "profile.edit.link": "Upravit profil", + "feed.atom.link": "Zdroj Atom", + "keys.ssh.link": "Klƭče SSH", + "og.repo.summary_card.alt_description": "Karta se souhrnem repozitÔře %[1]s, popsaným jako: %[2]s", + "mail.actions.run_info_sha": "Revize: %[1]s" } diff --git a/options/locale_next/locale_da.json b/options/locale_next/locale_da.json index 8315e06bcc..2620127b8c 100644 --- a/options/locale_next/locale_da.json +++ b/options/locale_next/locale_da.json @@ -28,7 +28,6 @@ "mail.actions.not_successful_run": "Arbejdsgangen %[1]s mislykkedes i depotet %[2]s", "mail.actions.run_info_cur_status": "Status for denne kĆørsel: %[1]s (lige opdateret fra %[2]s)", "mail.actions.run_info_previous_status": "Status for forrige kĆørsel: %[1]s", - "mail.actions.run_info_ref": "Gren: %[1]s (%[2]s)", "mail.actions.run_info_trigger": "UdlĆøst fordi: %[1]s af: %[2]s", "discussion.locked": "Denne diskussion er blevet lĆ„st. Kommentarer er begrƦnset til bidragydere.", "relativetime.now": "nu", @@ -97,5 +96,10 @@ "settings.visibility.description": "Profilsynlighed pĆ„virker andres adgang til dine ikke-private depoter. LƦs mere", "avatar.constraints_hint": "Brugerdefineret avatar mĆ„ ikke overstige %[1]s i stĆørrelse eller vƦre stĆørre end %[2]dx%[3]d pixels", "repo.diff.commit.next-short": "NƦste", - "repo.diff.commit.previous-short": "Forrige" + "repo.diff.commit.previous-short": "Forrige", + "profile.actions.tooltip": "Flere handlinger", + "profile.edit.link": "Redigere profil", + "feed.atom.link": "Atom feed", + "keys.ssh.link": "SSH NĆøgler", + "keys.gpg.link": "GPG NĆøgler" } diff --git a/options/locale_next/locale_de-DE.json b/options/locale_next/locale_de-DE.json index 3847de2b43..5d670aeedf 100644 --- a/options/locale_next/locale_de-DE.json +++ b/options/locale_next/locale_de-DE.json @@ -27,7 +27,6 @@ "mail.actions.successful_run_after_failure": "Arbeitsablauf %[1]s in Repository %[2]s wiederhergestellt", "mail.actions.not_successful_run": "Arbeitsablauf %[1]s in Repository %[2]s fehlgeschlagen", "mail.actions.run_info_previous_status": "Vorheriger Status des Runs: %[1]s", - "mail.actions.run_info_ref": "Branch: %[1]s (%[2]s)", "mail.actions.run_info_trigger": "Ausgelƶst, weil: %[1]s durch: %[2]s", "mail.actions.run_info_cur_status": "Status dieses Runs: %[1]s (gerade eben von %[2]s aktualisiert)", "discussion.locked": "Diese Diskussion wurde gesperrt. Nur Mitwirkende kƶnnen kommentieren.", @@ -102,5 +101,7 @@ "feed.atom.link": "Atom-Feed", "keys.ssh.link": "SSH-Schlüssel", "keys.gpg.link": "GPG-Schlüssel", - "profile.actions.tooltip": "Mehr Aktionen" + "profile.actions.tooltip": "Mehr Aktionen", + "og.repo.summary_card.alt_description": "Zusammenfassungskarte des Repositorys %[1]s, beschrieben als %[2]s", + "mail.actions.run_info_sha": "Commit: %[1]s" } diff --git a/options/locale_next/locale_el-GR.json b/options/locale_next/locale_el-GR.json index d3ba25b170..cca89efd0e 100644 --- a/options/locale_next/locale_el-GR.json +++ b/options/locale_next/locale_el-GR.json @@ -12,7 +12,6 @@ "mail.actions.successful_run_after_failure_subject": "Ī— ροή ĪµĻĪ³Ī±ĻƒĪÆĪ±Ļ‚ %[1]s Ī±Ļ€ĪæĪŗĪ±Ļ„Ī±ĻƒĻ„Ī¬ĪøĪ·ĪŗĪµ ĻƒĻ„Īæ αποθετήριο %[2]s", "mail.actions.not_successful_run_subject": "Ī— ροή ĪµĻĪ³Ī±ĻƒĪÆĪ±Ļ‚ %[1]s απέτυχε ĻƒĻ„Īæ αποθετήριο %[2]s", "mail.actions.run_info_trigger": "Ενεργοποιήθηκε επειΓή: %[1]s Ī±Ļ€ĻŒ: %[2]s", - "mail.actions.run_info_ref": "Αποθετήριο: %[1]s (%[2]s)", "meta.last_line": "Ī•Ļ…Ļ‡Ī±ĻĪ¹ĻƒĻ„ĪæĻĪ¼Īµ που μεταφράζετε το Forgejo! Αυτή Ī· γραμμή Γεν είναι ορατή Ī±Ļ€ĻŒ τους Ļ‡ĻĪ®ĻƒĻ„ĪµĻ‚ αλλά εξυπηρετεί άλλους ĻƒĪŗĪæĻ€ĪæĻĻ‚ ĻƒĻ„Ī· Ī“Ī¹Ī±Ļ‡ĪµĪÆĻĪ¹ĻƒĪ· της Ī¼ĪµĻ„Ī¬Ļ†ĻĪ±ĻƒĪ·Ļ‚. ĪœĻ€ĪæĻĪµĪÆĻ„Īµ να Ī³ĻĪ¬ĻˆĪµĻ„Īµ κάποιο Ī±ĻƒĻ„ĪµĪÆĪæ αντί για Ī¼ĪµĻ„Ī¬Ļ†ĻĪ±ĻƒĪ·.", "mail.actions.successful_run_after_failure": "Ī— ροή ĪµĻĪ³Ī±ĻƒĪÆĪ±Ļ‚ %[1]s Ī±Ļ€ĪæĪŗĪ±Ļ„Ī±ĻƒĻ„Ī¬ĪøĪ·ĪŗĪµ ĻƒĻ„Īæ αποθετήριο %[2]s", "discussion.locked": "Αυτή Ī· ĻƒĻ…Ī¶Ī®Ļ„Ī·ĻƒĪ· έχει κλειΓωθεί. Ο ĻƒĻ‡ĪæĪ»Ī¹Ī±ĻƒĪ¼ĻŒĻ‚ περιορίζεται ĻƒĻ„ĪæĻ…Ļ‚ ĻƒĻ…Ī½ĪµĪ¹ĻƒĻ†Ī­ĻĪæĪ½Ļ„ĪµĻ‚.", diff --git a/options/locale_next/locale_en-US.json b/options/locale_next/locale_en-US.json index a551db87dc..e08c8b2aee 100644 --- a/options/locale_next/locale_en-US.json +++ b/options/locale_next/locale_en-US.json @@ -92,7 +92,7 @@ "mail.actions.not_successful_run": "Workflow %[1]s failed in repository %[2]s", "mail.actions.run_info_cur_status": "This Run's Status: %[1]s (just updated from %[2]s)", "mail.actions.run_info_previous_status": "Previous Run's Status: %[1]s", - "mail.actions.run_info_ref": "Branch: %[1]s (%[2]s)", + "mail.actions.run_info_sha": "Commit: %[1]s", "mail.actions.run_info_trigger": "Triggered because: %[1]s by: %[2]s", "repo.diff.commit.next-short": "Next", "repo.diff.commit.previous-short": "Prev", diff --git a/options/locale_next/locale_es-ES.json b/options/locale_next/locale_es-ES.json index 37edef9211..82fbcfb4b6 100644 --- a/options/locale_next/locale_es-ES.json +++ b/options/locale_next/locale_es-ES.json @@ -30,5 +30,6 @@ "relativetime.future": "en el futuro", "home.explore_repos": "Explorar repositorios", "home.explore_users": "Explorar usuarios", - "home.explore_orgs": "Explorar organizaciones" + "home.explore_orgs": "Explorar organizaciones", + "moderation.abuse_category.malware": "Malware" } diff --git a/options/locale_next/locale_fi-FI.json b/options/locale_next/locale_fi-FI.json index cb26d76e66..fdc740b978 100644 --- a/options/locale_next/locale_fi-FI.json +++ b/options/locale_next/locale_fi-FI.json @@ -63,6 +63,6 @@ "mail.actions.successful_run_after_failure": "Tyƶnkulku %[1]s palautettu tietovarastoon %[2]s", "mail.actions.run_info_cur_status": "TƤmƤn juoksun tila: %[1]s (juuri pƤivitetty %[2]s:sta)", "mail.actions.run_info_previous_status": "Edellisen ajon tila: %[1]s", - "mail.actions.run_info_ref": "Haara: %[1]s (%[2]s)", - "mail.actions.run_info_trigger": "Laukaistui, koska: %[1]s, tekijƤnƤ: %[2]s" + "mail.actions.run_info_trigger": "Laukaistui, koska: %[1]s, tekijƤnƤ: %[2]s", + "moderation.abuse_category.malware": "Haittaohjelma" } diff --git a/options/locale_next/locale_fil.json b/options/locale_next/locale_fil.json index 884a7b44eb..2c62514648 100644 --- a/options/locale_next/locale_fil.json +++ b/options/locale_next/locale_fil.json @@ -25,7 +25,6 @@ "mail.actions.successful_run_after_failure": "Na-recover ang workflow na %[1]s sa repositoryong %[2]s", "mail.actions.not_successful_run": "Nabigo ang workflow na %[1]s sa repositoryong %[2]s", "mail.actions.run_info_previous_status": "Nakaraang Status ng Run: %[1]s", - "mail.actions.run_info_ref": "Branch: %[1]s (%[2]s)", "mail.actions.run_info_trigger": "Na-trigger dahil: %[1]s ni/ng: %[2]s", "mail.actions.successful_run_after_failure_subject": "Na-recover ang workflow na %[1]s sa repositoryong %[2]s", "mail.actions.not_successful_run_subject": "Nabigo ang workflow na %[1]s sa repositoryong %[2]s", @@ -102,5 +101,6 @@ "feed.atom.link": "Atom feed", "keys.ssh.link": "Mga SSH key", "keys.gpg.link": "Mga GPG key", - "profile.actions.tooltip": "Higit pang mga aksyon" + "profile.actions.tooltip": "Higit pang mga aksyon", + "og.repo.summary_card.alt_description": "Card ng pangkalahatang ideya ng repositoryong %[1]s, inilalarawan bilang: %[2]s" } diff --git a/options/locale_next/locale_fr-FR.json b/options/locale_next/locale_fr-FR.json index da26d56107..438e0433d0 100644 --- a/options/locale_next/locale_fr-FR.json +++ b/options/locale_next/locale_fr-FR.json @@ -10,7 +10,6 @@ "other": "" }, "search.milestone_kind": "Recherche dans les jalons…", - "mail.actions.run_info_ref": "Branche : %[1]s (%[2]s)", "discussion.locked": "Cette discussion a Ć©tĆ© bloquĆ©. Les commentaires sont limitĆ©s aux contributeurs.", "relativetime.now": "maintenant", "relativetime.future": "dans le future", diff --git a/options/locale_next/locale_hu-HU.json b/options/locale_next/locale_hu-HU.json index 9d52509102..1c02002e6e 100644 --- a/options/locale_next/locale_hu-HU.json +++ b/options/locale_next/locale_hu-HU.json @@ -1,5 +1,6 @@ { "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..." + "search.milestone_kind": "MĆ©rfƶldkƶvek keresĆ©se...", + "moderation.abuse_category.malware": "Malware" } diff --git a/options/locale_next/locale_id-ID.json b/options/locale_next/locale_id-ID.json index f2dac8114f..14bf491789 100644 --- a/options/locale_next/locale_id-ID.json +++ b/options/locale_next/locale_id-ID.json @@ -1,8 +1,5 @@ { - "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" - } + "repo.pulls.merged_title_desc": "commit %[1]d telah digabungkan dari %[2]s menjadi %[3]s %[4]s", + "repo.pulls.title_desc": "ingin menggabungkan komit %[1]d dari %[2]s menuju %[3]s", + "moderation.abuse_category.malware": "Perangkat pembahaya" } diff --git a/options/locale_next/locale_it-IT.json b/options/locale_next/locale_it-IT.json index 8464d6244e..f4cc7755f0 100644 --- a/options/locale_next/locale_it-IT.json +++ b/options/locale_next/locale_it-IT.json @@ -82,7 +82,6 @@ "moderation.report_abuse_form.invalid": "Argomenti non validi", "moderation.reporting_failed": "Impossibile inviare segnalazione: %v", "moderation.reported_thank_you": "Grazie per la segnalazione. L'amministratore ĆØ stato avvertito.", - "mail.actions.run_info_ref": "Ramo: %[1]s (%[2]s)", "alert.asset_load_failed": "Impossibile caricare i file di risorsa da {path}. Controlla che i file di risorsa siano accessibili.", "install.invalid_lfs_path": "Non ĆØ possibile creare una root LFS nel percorso specificato: %[1]s", "home.welcome.activity_hint": "Non c'ĆØ nulla nel tuo feed. Le tue azioni e le attivitĆ  dei repositori che segui verranno mostrate qui.", diff --git a/options/locale_next/locale_ja-JP.json b/options/locale_next/locale_ja-JP.json index 40edf8cb90..c4b3a0a2e0 100644 --- a/options/locale_next/locale_ja-JP.json +++ b/options/locale_next/locale_ja-JP.json @@ -1,5 +1,6 @@ { "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": "ćƒžć‚¤ćƒ«ć‚¹ćƒˆćƒ¼ćƒ³ć‚’ę¤œē“¢..." + "search.milestone_kind": "ćƒžć‚¤ćƒ«ć‚¹ćƒˆćƒ¼ćƒ³ć‚’ę¤œē“¢...", + "moderation.abuse_category.malware": "ę‚Ŗę„ć®ć‚³ćƒ¼ćƒ‰" } diff --git a/options/locale_next/locale_ko-KR.json b/options/locale_next/locale_ko-KR.json index 98c949d517..2e51144cb7 100644 --- a/options/locale_next/locale_ko-KR.json +++ b/options/locale_next/locale_ko-KR.json @@ -1,5 +1,6 @@ { "repo.pulls.merged_title_desc": "ė‹˜ģ“ %[2]s ģ—ģ„œ %[3]s 딜 %[1]d ģ»¤ė°‹ģ„ %[4]s 병합함", "repo.pulls.title_desc": "%[2]s ģ—ģ„œ %[3]s 딜 %[1]dź°œģ˜ ģ»¤ė°‹ė“¤ģ„ ė³‘ķ•©ķ•˜ė ¤ķ•Ø", - "home.welcome.no_activity": "ķ™œė™ ģ—†ģŒ" + "home.welcome.no_activity": "ķ™œė™ ģ—†ģŒ", + "moderation.abuse_category.malware": "악성 ģ†Œķ”„ķŠøģ›Øģ–“" } diff --git a/options/locale_next/locale_lv-LV.json b/options/locale_next/locale_lv-LV.json index f71cfa227d..22b80f2fad 100644 --- a/options/locale_next/locale_lv-LV.json +++ b/options/locale_next/locale_lv-LV.json @@ -30,7 +30,6 @@ "mail.actions.not_successful_run": "DarbplÅ«smas %[1] atteice glabātavā %[2]s", "mail.actions.run_info_cur_status": "Å Ä« izpildÄ«juma stāvoklis: %[1]s (tikko atjaunināts no %[2]s)", "mail.actions.run_info_previous_status": "IepriekŔējā izpildÄ«juma stāvoklis: %[1]s", - "mail.actions.run_info_ref": "Zars: %[1]s (%[2]s)", "mail.actions.run_info_trigger": "IzraisīŔanas iemesls: %[2]s no: %[2]s", "discussion.locked": "Å Ä« apspriede tika slēgta. Piebilžu pievienoÅ”ana ir ļauta tikai lÄ«dzdalÄ«bniekiem.", "relativetime.future": "nākotnē", @@ -105,5 +104,12 @@ "settings.visibility.description": "Profila redzamÄ«ba ietekmē iespēju citiem piekļūt Tavām glabātavām, kas nav privātas. Uzzināt vairāk", "avatar.constraints_hint": "Pielāgots profila attēls nevar pārsniegt %[1]s vai bÅ«t lielāks par %[2]dx%[3]d pikseļiem", "repo.diff.commit.next-short": "Nāk.", - "repo.diff.commit.previous-short": "Iepr." + "repo.diff.commit.previous-short": "Iepr.", + "profile.actions.tooltip": "Vairāk darbÄ«bu", + "profile.edit.link": "Labot profilu", + "feed.atom.link": "Atom barotne", + "keys.ssh.link": "SSH atslēgas", + "keys.gpg.link": "GPG atslēgas", + "og.repo.summary_card.alt_description": "Glabātavas %[1]s kopsavilkuma kartÄ«te, aprakstÄ«ta kā: %[2]s", + "mail.actions.run_info_sha": "IesÅ«tÄ«jums: %[1]s" } diff --git a/options/locale_next/locale_nb_NO.json b/options/locale_next/locale_nb_NO.json index 0967ef424b..b6b10cebb5 100644 --- a/options/locale_next/locale_nb_NO.json +++ b/options/locale_next/locale_nb_NO.json @@ -1 +1,106 @@ -{} +{ + "relativetime.1day": "i gĆ„r", + "moderation.abuse_category.other_violations": "Andre regel overtredelser", + "moderation.report_remarks": "Kommentar", + "moderation.report_remarks.placeholder": "Skriv noen detaljer rundt missbruket du rapporterer.", + "moderation.submit_report": "Send rapport", + "moderation.reporting_failed": "Missbruk rapporten kunne ikke sendes inn: %v", + "relativetime.hours": { + "one": "%d time siden", + "other": "%d timer siden" + }, + "repo.form.cannot_create": "Det maksimale antallet repositories er nĆ„dd i alle omrĆ„dene du har tilgang til.", + "repo.issue_indexer.title": "Saksindekserer", + "moderation.abuse_category.illegal_content": "Ulovlig innhold", + "error.not_found.title": "Fant ikke siden", + "themes.names.forgejo-light": "Forgejo lyst", + "themes.names.forgejo-dark": "Forgejo mĆørk", + "stars.list.none": "Ingen har gitt stjerner til dette repoet.", + "watch.list.none": "Ingen fĆølger dette repoet.", + "followers.incoming.list.none": "Ingen fĆølger denne brukeren.", + "followers.outgoing.list.self.none": "Du fĆølger ikke noen.", + "followers.outgoing.list.none": "%s fĆølger ikke noen.", + "relativetime.2days": "to dager siden", + "relativetime.1week": "forrige uke", + "relativetime.2weeks": "to uker siden", + "relativetime.1month": "forrige mĆ„ned", + "relativetime.2months": "to mĆ„neder siden", + "relativetime.1year": "i fjor", + "relativetime.2years": "to Ć„r siden", + "alert.asset_load_failed": "Kunne ikke laste inn ressursfiler fra {path}. SĆørg for at ressursfilene er tilgjengelige.", + "search.milestone_kind": "SĆøker i milepƦler…", + "home.welcome.no_activity": "Ingen aktivitet", + "home.explore_repos": "Utforsk repositorier", + "home.explore_users": "Utforsk brukere", + "home.explore_orgs": "Utforsk organisasjoner", + "relativetime.mins": { + "one": "%d minutt siden", + "other": "%d minutter siden" + }, + "relativetime.months": { + "one": "%d mĆ„ned siden", + "other": "%d mĆ„neder siden" + }, + "relativetime.years": { + "one": "%d Ć„r siden", + "other": "%d Ć„r siden" + }, + "repo.pulls.title_desc": { + "one": "Ćønsker Ć„ slĆ„ sammen %[1]d commit fra %[2]s inn i %[3]s", + "other": "Ćønsker Ć„ slĆ„ sammen %[1]d commits fra %[2]s inn i %[3]s" + }, + "og.repo.summary_card.alt_description": "Sammendrag for repository %[1]s, beskrevet som: %[2]s", + "followers.incoming.list.self.none": "Ingen fĆølger profilen din.", + "install.invalid_lfs_path": "Kan ikke opprette LFS-root pĆ„: %[1]s", + "relativetime.now": "nĆ„", + "relativetime.future": "i fremtiden", + "repo.pulls.merged_title_desc": { + "one": "slo sammen %[1]d commit fra %[2]s inn i %[3]s %[4]s", + "other": "slo sammen %[1]d commits fra %[2]s inn i %[3]s %[4]s" + }, + "editor.textarea.tab_hint": "Linjen er allerede innrykket. Trykk Tab igjen eller trykk Escape for Ć„ gĆ„ ut av editoren.", + "editor.textarea.shift_tab_hint": "Ingen innrykk pĆ„ denne linjen. Trykk Shift + Tab igjen eller Escape for Ć„ gĆ„ ut av editoren.", + "alert.range_error": " mĆ„ vƦre et nummer mellom %[1]s og %[2]s.", + "themes.names.forgejo-auto": "Forgejo (fĆølg systemtema)", + "home.welcome.activity_hint": "Det er forelĆøpig ingenting i feeden din. Aktivitetene dine og handlingene dine fra repositorier du fĆølger, vil vises her etter hvert.", + "incorrect_root_url": "Denne Forgejo instansen er konfigurert til Ć„ bruke \"%s\". Du bruker Forgejo via en annen URL, noe som kan forĆ„rsake at deler av applikasjonen ikke fungerer. Den kanoniske URL-en styres av Forgejo-administratorer via innstillingen ROOT_URL i app.ini-filen.", + "mail.actions.run_info_trigger": "Startet pĆ„ grunn av: %[1]s by: %[2]s", + "admin.dashboard.cleanup_offline_runners": "Rydd opp offline runners", + "settings.visibility.description": "Profilens synlighet pĆ„virker andres mulighet til Ć„ fĆ„ tilgang til dine ikke-private repositorier. Les mer", + "profile.actions.tooltip": "Flere handlinger", + "profile.edit.link": "Rediger profil", + "relativetime.days": { + "one": "%d dag siden", + "other": "%d dager siden" + }, + "relativetime.weeks": { + "one": "%d uke siden", + "other": "%d uker siden" + }, + "feed.atom.link": "Atom feed", + "keys.ssh.link": "SSH nĆøkler", + "keys.gpg.link": "GPG nĆøkler", + "admin.config.moderation_config": "Moderasjonskonfigurasjon", + "moderation.report_abuse": "Rapporter missbruk", + "moderation.report_content": "Rapporter innhold", + "moderation.report_abuse_form.header": "Rapporter missbruk til en administrator", + "moderation.report_abuse_form.details": "Denne formen skal brukes for Ć„ rapporterer brukere som oppretter spam profiler, repositorier, saker, kommentarer eller oppfĆører seg upassende.", + "moderation.report_abuse_form.invalid": "Ugyldige argumenter", + "moderation.report_abuse_form.already_reported": "Du har allerede rapportert dette innholdet", + "moderation.abuse_category": "Kategori", + "moderation.abuse_category.placeholder": "Velg en kategori", + "moderation.abuse_category.spam": "Spam", + "moderation.abuse_category.malware": "Skadelig programvare", + "moderation.reported_thank_you": "Takk for meldingen. Vi har varslet administratorene.", + "mail.actions.successful_run_after_failure_subject": "Arbeidsflyten %[1]s er gjenopprettet i repository %[2]s", + "mail.actions.not_successful_run_subject": "Arbeidsflyten %[1]s feilet i repository %[2]s", + "mail.actions.successful_run_after_failure": "Arbeidsflyten %[1]s er gjenopprettet i repository %[2]s", + "mail.actions.not_successful_run": "Arbeidsflyten %[1]s feilet i repository %[2]s", + "mail.actions.run_info_cur_status": "Status for denne kjĆøringen: %[1]s (oppdatert fra %[2]s)", + "mail.actions.run_info_previous_status": "Status for forrige kjĆøring: %[1]s", + "repo.diff.commit.next-short": "Neste", + "repo.diff.commit.previous-short": "Forrige", + "discussion.locked": "Denne diskusjonen er lĆ„st. Kommentarer kan kun gjĆøres av bidragsytere.", + "avatar.constraints_hint": "Egendefinert avatar kan ikke overstige %[1]s i stĆørrelse eller vƦre stĆørre enn %[2]d Ɨ %[3]d piksler", + "meta.last_line": "Vi gir oss ikke. Kongen har sagt nei!" +} diff --git a/options/locale_next/locale_nds.json b/options/locale_next/locale_nds.json index 24268e2082..20c1208c42 100644 --- a/options/locale_next/locale_nds.json +++ b/options/locale_next/locale_nds.json @@ -28,7 +28,6 @@ "mail.actions.not_successful_run": "Warkwies %[1]s in Repositorium %[2]s is fehlslagen", "mail.actions.run_info_cur_status": "Tostand vun deesem Utfƶhren: %[1]s (jüüst vun %[2]s verneeit)", "mail.actions.run_info_previous_status": "Tostand vun de vƶrig Utfƶhren: %[1]s", - "mail.actions.run_info_ref": "Twieg: %[1]s (%[2]s)", "mail.actions.run_info_trigger": "Utlƶƶst um: %[1]s vun: %[2]s", "discussion.locked": "Deeser Snack is tosloten worden. Blots Bidragers kƶnen kommenteren.", "relativetime.future": "in Tokunft", @@ -102,5 +101,7 @@ "keys.ssh.link": "SSH-Slƶtels", "keys.gpg.link": "GPG-Slƶtels", "profile.actions.tooltip": "Mehr Aktioonen", - "profile.edit.link": "Profil bewarken" + "profile.edit.link": "Profil bewarken", + "og.repo.summary_card.alt_description": "Tosamenfatens-Kaart vun de Repositorium %[1]s, beschrieven as: %[2]s", + "mail.actions.run_info_sha": "Kommitteren: %[1]s" } diff --git a/options/locale_next/locale_nl-NL.json b/options/locale_next/locale_nl-NL.json index 4f109825aa..e049db3d41 100644 --- a/options/locale_next/locale_nl-NL.json +++ b/options/locale_next/locale_nl-NL.json @@ -28,7 +28,6 @@ "mail.actions.not_successful_run": "Werkstroom %[1]s mislukt in repositorie %[2]s", "mail.actions.run_info_cur_status": "De status van deze run: %[1]s (zojuist bijgewerkt van %[2]s)", "mail.actions.run_info_previous_status": "Status vorige run: %[1]s", - "mail.actions.run_info_ref": "Branch: %[1]s (%[2]s)", "mail.actions.run_info_trigger": "Getriggerd omdat: %[1]s door: %[2]s", "discussion.locked": "Deze discussie is afgesloten. Commentaar is alleen mogelijk voor bijdragers.", "relativetime.now": "nu", @@ -92,5 +91,17 @@ "watch.list.none": "Niemand houdt deze repo in de gaten.", "followers.incoming.list.self.none": "Niemand volgt uw profiel.", "followers.incoming.list.none": "Deze gebruiker wordt door niemand gevolgd.", - "followers.outgoing.list.self.none": "U volgt niemand." + "followers.outgoing.list.self.none": "U volgt niemand.", + "settings.visibility.description": "Profielzichtbaarheid beĆÆnvloedt de mogelijkheid van anderen om toegang te krijgen tot je niet-privĆ© repositories. Lees meer", + "repo.diff.commit.next-short": "Volgende", + "admin.dashboard.cleanup_offline_runners": "Offline runners opruimen", + "keys.ssh.link": "SSH sleutels", + "keys.gpg.link": "GPG sleutels", + "profile.actions.tooltip": "Meer acties", + "profile.edit.link": "Profiel bewerken", + "feed.atom.link": "Atom-feed", + "repo.diff.commit.previous-short": "Vorige", + "avatar.constraints_hint": "Eigen avatars mogen niet groter zijn dan %[1]s in grootte of groter zijn dan %[2]dx%[3]d pixels", + "og.repo.summary_card.alt_description": "Samenvattingsoverzicht van repositorie %[1]s, omschreven als: %[2]s", + "mail.actions.run_info_sha": "Commit: %[1]s" } diff --git a/options/locale_next/locale_pt-BR.json b/options/locale_next/locale_pt-BR.json index 1a5eca6d34..6ed6c5defd 100644 --- a/options/locale_next/locale_pt-BR.json +++ b/options/locale_next/locale_pt-BR.json @@ -26,7 +26,6 @@ "meta.last_line": "real hot girl shit", "mail.actions.run_info_cur_status": "Status desta execução: %[1]s (atualizado recentemente de %[2]s)", "mail.actions.run_info_previous_status": "Status da execução anterior: %[1]s", - "mail.actions.run_info_ref": "Branch: %[1]s (%[2]s)", "mail.actions.successful_run_after_failure_subject": "Workflow %[1]s recuperado no repositório %[2]s", "mail.actions.not_successful_run_subject": "Workflow %[1]s falhou no repositório %[2]s", "mail.actions.successful_run_after_failure": "Workflow %[1]s recuperado no repositório %[2]s", @@ -83,7 +82,7 @@ "moderation.abuse_category": "Categoria", "moderation.abuse_category.placeholder": "Selecione uma categoria", "moderation.abuse_category.spam": "Spam", - "moderation.abuse_category.malware": "Malware", + "moderation.abuse_category.malware": "Software malicioso", "moderation.abuse_category.illegal_content": "ConteĆŗdo ilegal", "moderation.abuse_category.other_violations": "Outras violaƧƵes de regras da plataforma", "moderation.report_remarks": "ObservaƧƵes", @@ -105,5 +104,12 @@ "avatar.constraints_hint": "Imagem de perfil personalizada nĆ£o pode exceder %[1]s em tamanho ou ser maior que %[2]dx%[3]d pixels", "settings.visibility.description": "A visibilidade do perfil afeta a habilidade de acessarem seus repositórios nĆ£o-privados. Saiba mais", "repo.diff.commit.next-short": "Próximo", - "repo.diff.commit.previous-short": "Anterior" + "repo.diff.commit.previous-short": "Anterior", + "profile.edit.link": "Editar perfil", + "feed.atom.link": "Feed Atom", + "keys.gpg.link": "Chaves GPG", + "og.repo.summary_card.alt_description": "CartĆ£o de resumo do repositório %[1]s, descrito como: %[2]s", + "profile.actions.tooltip": "Mais Actions", + "keys.ssh.link": "Chaves SSH", + "mail.actions.run_info_sha": "Commit: %[1]s" } diff --git a/options/locale_next/locale_pt-PT.json b/options/locale_next/locale_pt-PT.json index 78e6dc4493..352e948966 100644 --- a/options/locale_next/locale_pt-PT.json +++ b/options/locale_next/locale_pt-PT.json @@ -27,7 +27,6 @@ "mail.actions.successful_run_after_failure_subject": "SequĆŖncia de trabalho %[1]s foi recuperada no repositório %[2]s", "mail.actions.not_successful_run_subject": "SequĆŖncia de trabalho %[1]s falhou no repositório %[2]s", "mail.actions.not_successful_run": "SequĆŖncia de trabalho %[1]s falhou no repositório %[2]s", - "mail.actions.run_info_ref": "Ramo: %[1]s (%[2]s)", "mail.actions.successful_run_after_failure": "SequĆŖncia de trabalho %[1]s foi recuperada no repositório %[2]s", "discussion.locked": "Esta discussĆ£o foi fechada. Apenas contribuidores podem publicar comentĆ”rios.", "mail.actions.run_info_cur_status": "Estado desta execução: %[1]s (atualizado recentemente de %[2]s)", @@ -103,5 +102,12 @@ "stars.list.none": "NinguĆ©m juntou este repositório aos favoritos.", "admin.dashboard.cleanup_offline_runners": "Limpeza de executores offline", "settings.visibility.description": "A visibilidade do perfil afecta a capacidade de outros acederem aos seus repositórios nĆ£o privados. Ler mais", - "avatar.constraints_hint": "O avatar personalizado nĆ£o pode exceder %[1]s de tamanho ou ser maior do que %[2]dx%[3]d pixĆ©is" + "avatar.constraints_hint": "O avatar personalizado nĆ£o pode exceder %[1]s de tamanho ou ser maior do que %[2]dx%[3]d pixĆ©is", + "repo.diff.commit.next-short": "Seg.", + "profile.actions.tooltip": "Mais Actions", + "profile.edit.link": "Editar perfil", + "feed.atom.link": "Feed Atom", + "keys.ssh.link": "Chaves SSH", + "keys.gpg.link": "Chaves GPG", + "repo.diff.commit.previous-short": "Ant." } diff --git a/options/locale_next/locale_ru-RU.json b/options/locale_next/locale_ru-RU.json index 922e2612af..19167d7177 100644 --- a/options/locale_next/locale_ru-RU.json +++ b/options/locale_next/locale_ru-RU.json @@ -26,7 +26,6 @@ "meta.last_line": "Unskip..", "mail.actions.not_successful_run_subject": "ŠŸŃ€Š¾Š²Š°Š» раб. потока %[1]s в репозитории %[2]s", "mail.actions.successful_run_after_failure_subject": "Возобновление раб. потока %[1]s в репозитории %[2]s", - "mail.actions.run_info_ref": "Š’ŠµŃ‚Š²ŃŒ: %[1]s (%[2]s)", "mail.actions.run_info_trigger": "ŠŸŃ€ŠøŃ‡ŠøŠ½Š° ŃŃ€Š°Š±Š°Ń‚Ń‹Š²Š°Š½ŠøŃ: %[1]s by: %[2]s", "mail.actions.successful_run_after_failure": "Рабочий поток %[1]s в репозитории %[2]s был возобновлён после провала", "mail.actions.run_info_cur_status": "Š¢ŠµŠŗŃƒŃ‰ŠµŠµ ŃŠ¾ŃŃ‚Š¾ŃŠ½ŠøŠµ: %[1]s (обновлено после %[2]s)", @@ -110,5 +109,7 @@ "feed.atom.link": "Atom-лента", "keys.ssh.link": "ŠšŠ»ŃŽŃ‡Šø SSH", "keys.gpg.link": "ŠšŠ»ŃŽŃ‡Šø GPG", - "profile.edit.link": "Š˜Š·Š¼ŠµŠ½ŠøŃ‚ŃŒ ŠæŃ€Š¾Ń„ŠøŠ»ŃŒ" + "profile.edit.link": "Š˜Š·Š¼ŠµŠ½ŠøŃ‚ŃŒ ŠæŃ€Š¾Ń„ŠøŠ»ŃŒ", + "og.repo.summary_card.alt_description": "ŠšŠ°Ń€Ń‚Š¾Ń‡ŠŗŠ° со своГкой о репозитории %s. ŠžŠæŠøŃŠ°Š½ŠøŠµ: %[2]s", + "mail.actions.run_info_sha": "ŠšŠ¾Š¼Š¼ŠøŃ‚: %[1]s" } diff --git a/options/locale_next/locale_sr-SP.json b/options/locale_next/locale_sr-SP.json index 0967ef424b..611f997b3e 100644 --- a/options/locale_next/locale_sr-SP.json +++ b/options/locale_next/locale_sr-SP.json @@ -1 +1,3 @@ -{} +{ + "moderation.abuse_category.malware": "ŠœŠ°Š»Š²ŠµŃ€" +} diff --git a/options/locale_next/locale_sv-SE.json b/options/locale_next/locale_sv-SE.json index 9a8762212c..1195647bf5 100644 --- a/options/locale_next/locale_sv-SE.json +++ b/options/locale_next/locale_sv-SE.json @@ -27,7 +27,6 @@ "moderation.reporting_failed": "Det gick inte att skicka in den nya ƶvergreppsrapporten: %v", "mail.actions.run_info_cur_status": "Status fƶr denna kƶrning: %[1]s (just uppdaterad frĆ„n %[2]s)", "mail.actions.run_info_previous_status": "Status fƶr fƶregĆ„ende kƶrning: %[1]s", - "mail.actions.run_info_ref": "Gren: %[1]s (%[2]s)", "mail.actions.run_info_trigger": "Utlƶses pĆ„ grund av: %[1]s av: %[2]s", "alert.asset_load_failed": "Misslyckades med att lƤsa in resursfiler frĆ„n {path}. Kontrollera att resursfilerna Ƥr Ć„tkomliga.", "install.invalid_lfs_path": "Det gick inte att skapa LFS-roten pĆ„ den angivna sƶkvƤgen: %[1]s", @@ -95,5 +94,13 @@ "moderation.abuse_category.spam": "SkrƤppost", "moderation.abuse_category.malware": "Skadlig kod", "settings.visibility.description": "Profilens synlighet pĆ„verkar andras mƶjlighet att komma Ć„t dina icke-privata fƶrrĆ„d. LƤs mer", - "avatar.constraints_hint": "Anpassade avatarer fĆ„r inte vara stƶrre Ƥn %[1] eller %[2]dx%[3] bildpunkter" + "avatar.constraints_hint": "Anpassade avatarer fĆ„r inte vara stƶrre Ƥn %[1] eller %[2]dx%[3] bildpunkter", + "og.repo.summary_card.alt_description": "Sammanfattningskort fƶr arkivet %[1]s, beskrivet som: %[2]s", + "profile.actions.tooltip": "Fler Ć„tgƤrder", + "keys.gpg.link": "GPG-nycklar", + "profile.edit.link": "Redigera profil", + "keys.ssh.link": "SSH-nycklar", + "repo.diff.commit.next-short": "NƤsta", + "repo.diff.commit.previous-short": "Fƶreg", + "feed.atom.link": "Atom-flƶde" } diff --git a/options/locale_next/locale_tr-TR.json b/options/locale_next/locale_tr-TR.json index b0e34e677f..fa71cb8e7d 100644 --- a/options/locale_next/locale_tr-TR.json +++ b/options/locale_next/locale_tr-TR.json @@ -1,5 +1,6 @@ { "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..." + "search.milestone_kind": "Kilometre taşlarını ara...", + "moderation.abuse_category.malware": "Malware" } diff --git a/options/locale_next/locale_uk-UA.json b/options/locale_next/locale_uk-UA.json index 33cb5a41a3..8e99505e57 100644 --- a/options/locale_next/locale_uk-UA.json +++ b/options/locale_next/locale_uk-UA.json @@ -25,7 +25,6 @@ "alert.range_error": " має Š±ŃƒŃ‚Šø числом віГ %[1]s Го %[2]s.", "meta.last_line": "ŠŠµ зливай злий запити на Š·Š»ŠøŃ‚Ń‚Ń — Š·Ń–Š»Š»Ń”Ń‚ŃŒŃŃ зле.", "mail.actions.successful_run_after_failure": "Робочий потік %[1]s віГновлено в репозиторії %[2]s", - "mail.actions.run_info_ref": "Гілка: %[1]s (%[2]s)", "mail.actions.successful_run_after_failure_subject": "Робочий потік %[1]s віГновлено в репозиторії %[2]s", "mail.actions.run_info_previous_status": "Дтан ŠæŠ¾ŠæŠµŃ€ŠµŠ“Š½ŃŒŠ¾Š³Š¾ запуску: %[1]s", "mail.actions.run_info_cur_status": "Дтан Ń†ŃŒŠ¾Š³Š¾ запуску: %[1]s (щойно оновлено Š· %[2]s)", @@ -110,5 +109,7 @@ "keys.gpg.link": "ŠšŠ»ŃŽŃ‡Ń– GPG", "profile.edit.link": "Š ŠµŠ“Š°Š³ŃƒŠ²Š°Ń‚Šø ŠæŃ€Š¾Ń„Ń–Š»ŃŒ", "feed.atom.link": "Дтрічка Atom", - "profile.actions.tooltip": "Š‘Ń–Š»ŃŒŃˆŠµ Гій" + "profile.actions.tooltip": "Š‘Ń–Š»ŃŒŃˆŠµ Гій", + "og.repo.summary_card.alt_description": "ŠŸŃ–Š“ŃŃƒŠ¼ŠŗŠ¾Š²Š° картка Ń€ŠµŠæŠ¾Š·ŠøŃ‚Š¾Ń€Ń–ŃŽ %[1]s Š· описом: %[2]s", + "mail.actions.run_info_sha": "ŠšŠ¾Š¼Ń–Ń‚: %[1]s" } diff --git a/options/locale_next/locale_vi.json b/options/locale_next/locale_vi.json index 0967ef424b..7ae64113b6 100644 --- a/options/locale_next/locale_vi.json +++ b/options/locale_next/locale_vi.json @@ -1 +1,3 @@ -{} +{ + "moderation.abuse_category.malware": "Phįŗ§n mềm Ć”c ý" +} diff --git a/options/locale_next/locale_zh-CN.json b/options/locale_next/locale_zh-CN.json index 0f408997bf..c235ebd0ad 100644 --- a/options/locale_next/locale_zh-CN.json +++ b/options/locale_next/locale_zh-CN.json @@ -20,7 +20,6 @@ "mail.actions.not_successful_run_subject": "仓库 %[2]s äø­ēš„å·„ä½œęµ %[1]s 已失蓄", "mail.actions.successful_run_after_failure": "仓库 %[2]s äø­ēš„å·„ä½œęµ %[1]s å·²ę¢å¤", "mail.actions.run_info_previous_status": "äøŠę¬”čæč”Œēš„ēŠ¶ę€ļ¼š%[1]s", - "mail.actions.run_info_ref": "åˆ†ę”Æļ¼š%[1]s(%[2]s)", "mail.actions.run_info_cur_status": "ę­¤ę¬”čæč”Œēš„ēŠ¶ę€ļ¼š%[1]sļ¼ˆä»Ž %[2]s 曓新)", "mail.actions.run_info_trigger": "ē”± %[2]s %[1]s č§¦å‘", "mail.actions.not_successful_run": "仓库 %[2]s äø­ēš„å·„ä½œęµ %[1]s 已失蓄", @@ -71,12 +70,13 @@ "editor.textarea.shift_tab_hint": "ę­¤č”Œę— ē¼©čæ›ć€‚å†ę¬”ęŒ‰ Shift + Tab ꈖꌉ Escape 退出编辑器。", "admin.dashboard.cleanup_offline_runners": "ęø…ē†ē¦»ēŗæčæč”Œå™Ø", "settings.visibility.description": "äøŖäŗŗčµ„ę–™åÆč§ę€§č®¾ē½®ä¼šå½±å“ä»–äŗŗåÆ¹ę‚Øēš„éžē§ęœ‰ä»“åŗ“ēš„č®æé—®ć€‚äŗ†č§£ę›“å¤š", - "avatar.constraints_hint": "č‡Ŗå®šä¹‰å¤“åƒå¤§å°äøå¾—č¶…čæ‡ %[1]sļ¼Œęˆ–å¤§äŗŽ %[2]dƗ%[3]d åƒē“ ", + "avatar.constraints_hint": "č‡Ŗå®šä¹‰å¤“åƒå¤§å°äøå¾—č¶…čæ‡ %[1]sļ¼Œäø”åˆ†č¾ØēŽ‡äøå¾—å¤§äŗŽ %[2]dƗ%[3]d åƒē“ ", "keys.ssh.link": "SSH 密钄", "keys.gpg.link": "GPG 密钄", "profile.actions.tooltip": "ę›“å¤šę“ä½œ", - "repo.diff.commit.next-short": "äø‹äøŖ", - "repo.diff.commit.previous-short": "上个", + "repo.diff.commit.next-short": "下一个", + "repo.diff.commit.previous-short": "äøŠäø€äøŖ", "feed.atom.link": "Atom č®¢é˜…ęŗ", - "profile.edit.link": "编辑个人资料" + "profile.edit.link": "编辑个人资料", + "og.repo.summary_card.alt_description": "仓库 %[1]s ēš„ę‘˜č¦å”ē‰‡ļ¼Œęčæ°äøŗļ¼š%[2]s" } diff --git a/options/locale_next/locale_zh-HK.json b/options/locale_next/locale_zh-HK.json index 6baf89e022..277385cf5f 100644 --- a/options/locale_next/locale_zh-HK.json +++ b/options/locale_next/locale_zh-HK.json @@ -1,5 +1,4 @@ { - "repo.pulls.merged_title_desc": { - "other": "ę–¼ %[4]s 將 %[1]d ę¬”ä»£ē¢¼ęäŗ¤å¾ž %[2]såˆä½µč‡³ %[3]s" - } + "repo.pulls.merged_title_desc": "ę–¼ %[4]s 將 %[1]d ę¬”ä»£ē¢¼ęäŗ¤å¾ž %[2]såˆä½µč‡³ %[3]s", + "moderation.abuse_category.malware": "ęƒ”ę„ēØ‹å¼" } diff --git a/options/locale_next/locale_zh-TW.json b/options/locale_next/locale_zh-TW.json index 3ae0b00d2b..8a5a17a774 100644 --- a/options/locale_next/locale_zh-TW.json +++ b/options/locale_next/locale_zh-TW.json @@ -55,7 +55,6 @@ "mail.actions.not_successful_run": "å„²å­˜åŗ« %[2]s äø­ēš„å·„ä½œęµēØ‹ %[1]s 已失敗", "mail.actions.run_info_cur_status": "ęœ¬ę¬”åŸ·č”Œē‹€ę…‹ļ¼š%[1]sļ¼ˆå‰›å¾ž %[2]s 曓新)", "mail.actions.run_info_previous_status": "å‰äø€ę¬”åŸ·č”Œē‹€ę…‹ļ¼š%[1]s", - "mail.actions.run_info_ref": "åˆ†ę”Æļ¼š%[1]s (%[2]s)", "mail.actions.run_info_trigger": "č§øē™¼åŽŸå› ļ¼š%[1]sļ¼Œē”± %[2]s 執蔌", "discussion.locked": "ę­¤čØŽč«–å·²č¢«éŽ–å®šć€‚åƒ…é™č²¢ē»č€…ē•™čØ€ć€‚", "alert.asset_load_failed": "ē„”ę³•å¾ž {path} č¼‰å…„č³‡ęŗęŖ”ę”ˆć€‚č«‹ē¢ŗäæé€™äŗ›č³‡ęŗęŖ”ę”ˆåÆä»„č¢«å­˜å–ć€‚", diff --git a/package-lock.json b/package-lock.json index 06a9497efc..edb57b618a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,7 +32,7 @@ "idiomorph": "0.3.0", "jquery": "3.7.1", "katex": "0.16.22", - "mermaid": "11.7.0", + "mermaid": "11.8.1", "mini-css-extract-plugin": "2.9.2", "minimatch": "10.0.3", "monaco-editor": "0.52.2", @@ -56,22 +56,22 @@ "vue-chartjs": "5.3.1", "vue-loader": "17.4.2", "vue3-calendar-heatmap": "2.0.5", - "webpack": "5.99.9", + "webpack": "5.100.0", "webpack-cli": "6.0.1", "wrap-ansi": "9.0.0" }, "devDependencies": { "@axe-core/playwright": "4.10.2", "@eslint-community/eslint-plugin-eslint-comments": "4.5.0", - "@playwright/test": "1.52.0", + "@playwright/test": "1.53.2", "@stoplight/spectral-cli": "6.15.0", - "@stylistic/eslint-plugin": "5.0.0", + "@stylistic/eslint-plugin": "5.1.0", "@stylistic/stylelint-plugin": "3.1.3", "@vitejs/plugin-vue": "6.0.0", - "@vitest/coverage-v8": "3.2.3", - "@vitest/eslint-plugin": "1.2.2", + "@vitest/coverage-v8": "3.2.4", + "@vitest/eslint-plugin": "1.3.4", "@vue/test-utils": "2.4.6", - "eslint": "9.30.0", + "eslint": "9.30.1", "eslint-import-resolver-typescript": "4.4.4", "eslint-plugin-array-func": "5.0.2", "eslint-plugin-import-x": "4.16.1", @@ -83,24 +83,24 @@ "eslint-plugin-toml": "0.12.0", "eslint-plugin-unicorn": "59.0.1", "eslint-plugin-vitest-globals": "1.5.0", - "eslint-plugin-vue": "10.2.0", - "eslint-plugin-vue-scoped-css": "2.10.0", + "eslint-plugin-vue": "10.3.0", + "eslint-plugin-vue-scoped-css": "2.11.0", "eslint-plugin-wc": "3.0.1", - "globals": "16.1.0", + "globals": "16.3.0", "happy-dom": "18.0.1", "license-checker-rseidelsohn": "4.4.2", "markdownlint-cli": "0.45.0", "postcss-html": "1.8.0", - "sharp": "0.34.2", - "stylelint": "16.21.0", + "sharp": "0.34.3", + "stylelint": "16.21.1", "stylelint-declaration-block-no-ignored-properties": "2.8.0", "stylelint-declaration-strict-value": "1.10.11", "stylelint-value-no-unknown-custom-properties": "6.0.1", "svgo": "4.0.0", "typescript": "5.8.3", - "typescript-eslint": "8.35.0", + "typescript-eslint": "8.35.1", "vite-string-plugin": "1.3.4", - "vitest": "3.2.3" + "vitest": "3.2.4" }, "engines": { "node": ">= 20.0.0" @@ -216,12 +216,12 @@ } }, "node_modules/@babel/parser": { - "version": "7.27.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.7.tgz", - "integrity": "sha512-qnzXzDXdr/po3bOTbTIQZ7+TxNKxpkN5IifVLXS+r7qwynkZfPyjZfE7hCXbo7IoO9TNcSyibgONsf2HauUd3Q==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz", + "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==", "license": "MIT", "dependencies": { - "@babel/types": "^7.27.7" + "@babel/types": "^7.28.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -240,9 +240,9 @@ } }, "node_modules/@babel/types": { - "version": "7.27.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.7.tgz", - "integrity": "sha512-8OLQgDScAOHXnAz2cV+RfzzNMipuLVBz2biuAJFMV9bfkNf393je3VM8CLkjQodW5+iWsSJdSgSWT6rsZoXHPw==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.0.tgz", + "integrity": "sha512-jYnje+JyZG5YThjHiF28oT4SIZLnYOcSBb6+SDaFIyzDVSkXQmQQYclJ2R+YxcdmK0AX6x1E5OQNtuh3jHDrUg==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", @@ -537,9 +537,9 @@ } }, "node_modules/@emnapi/runtime": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.3.tgz", - "integrity": "sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==", + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.4.tgz", + "integrity": "sha512-hHyapA4A3gPaDCNfiqyZUStTMqIkKRshqPIuDOXv1hcBnD4U3l8cP0T1HMCfGRxQ6V64TGCcoswChANyOAwbQg==", "dev": true, "license": "MIT", "optional": true, @@ -1146,9 +1146,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.30.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.30.0.tgz", - "integrity": "sha512-Wzw3wQwPvc9sHM+NjakWTcPx11mbZyiYHuwWa/QfZ7cIRX7WK54PSk7bdyXDaoaopUcMatv1zaQvOAAO8hCdww==", + "version": "9.30.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.30.1.tgz", + "integrity": "sha512-zXhuECFlyep42KZUhWjfvsmXGX39W8K8LFb8AWXM9gSV9dQB+MrJGLKvW6Zw0Ggnbpw0VHTtrhFXYe3Gym18jg==", "dev": true, "license": "MIT", "engines": { @@ -1340,9 +1340,9 @@ } }, "node_modules/@img/sharp-darwin-arm64": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.2.tgz", - "integrity": "sha512-OfXHZPppddivUJnqyKoi5YVeHRkkNE2zUFT2gbpKxp/JZCFYEYubnMg+gOp6lWfasPrTS+KPosKqdI+ELYVDtg==", + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.3.tgz", + "integrity": "sha512-ryFMfvxxpQRsgZJqBd4wsttYQbCxsJksrv9Lw/v798JcQ8+w84mBWuXwl+TT0WJ/WrYOLaYpwQXi3sA9nTIaIg==", "cpu": [ "arm64" ], @@ -1359,13 +1359,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.1.0" + "@img/sharp-libvips-darwin-arm64": "1.2.0" } }, "node_modules/@img/sharp-darwin-x64": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.2.tgz", - "integrity": "sha512-dYvWqmjU9VxqXmjEtjmvHnGqF8GrVjM2Epj9rJ6BUIXvk8slvNDJbhGFvIoXzkDhrJC2jUxNLz/GUjjvSzfw+g==", + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.3.tgz", + "integrity": "sha512-yHpJYynROAj12TA6qil58hmPmAwxKKC7reUqtGLzsOHfP7/rniNGTL8tjWX6L3CTV4+5P4ypcS7Pp+7OB+8ihA==", "cpu": [ "x64" ], @@ -1382,13 +1382,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-darwin-x64": "1.1.0" + "@img/sharp-libvips-darwin-x64": "1.2.0" } }, "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.1.0.tgz", - "integrity": "sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.0.tgz", + "integrity": "sha512-sBZmpwmxqwlqG9ueWFXtockhsxefaV6O84BMOrhtg/YqbTaRdqDE7hxraVE3y6gVM4eExmfzW4a8el9ArLeEiQ==", "cpu": [ "arm64" ], @@ -1403,9 +1403,9 @@ } }, "node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.1.0.tgz", - "integrity": "sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.0.tgz", + "integrity": "sha512-M64XVuL94OgiNHa5/m2YvEQI5q2cl9d/wk0qFTDVXcYzi43lxuiFTftMR1tOnFQovVXNZJ5TURSDK2pNe9Yzqg==", "cpu": [ "x64" ], @@ -1420,9 +1420,9 @@ } }, "node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.1.0.tgz", - "integrity": "sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.0.tgz", + "integrity": "sha512-mWd2uWvDtL/nvIzThLq3fr2nnGfyr/XMXlq8ZJ9WMR6PXijHlC3ksp0IpuhK6bougvQrchUAfzRLnbsen0Cqvw==", "cpu": [ "arm" ], @@ -1437,9 +1437,9 @@ } }, "node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.1.0.tgz", - "integrity": "sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.0.tgz", + "integrity": "sha512-RXwd0CgG+uPRX5YYrkzKyalt2OJYRiJQ8ED/fi1tq9WQW2jsQIn0tqrlR5l5dr/rjqq6AHAxURhj2DVjyQWSOA==", "cpu": [ "arm64" ], @@ -1454,9 +1454,9 @@ } }, "node_modules/@img/sharp-libvips-linux-ppc64": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.1.0.tgz", - "integrity": "sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.0.tgz", + "integrity": "sha512-Xod/7KaDDHkYu2phxxfeEPXfVXFKx70EAFZ0qyUdOjCcxbjqyJOEUpDe6RIyaunGxT34Anf9ue/wuWOqBW2WcQ==", "cpu": [ "ppc64" ], @@ -1471,9 +1471,9 @@ } }, "node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.1.0.tgz", - "integrity": "sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.0.tgz", + "integrity": "sha512-eMKfzDxLGT8mnmPJTNMcjfO33fLiTDsrMlUVcp6b96ETbnJmd4uvZxVJSKPQfS+odwfVaGifhsB07J1LynFehw==", "cpu": [ "s390x" ], @@ -1488,9 +1488,9 @@ } }, "node_modules/@img/sharp-libvips-linux-x64": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.1.0.tgz", - "integrity": "sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.0.tgz", + "integrity": "sha512-ZW3FPWIc7K1sH9E3nxIGB3y3dZkpJlMnkk7z5tu1nSkBoCgw2nSRTFHI5pB/3CQaJM0pdzMF3paf9ckKMSE9Tg==", "cpu": [ "x64" ], @@ -1505,9 +1505,9 @@ } }, "node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.1.0.tgz", - "integrity": "sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.0.tgz", + "integrity": "sha512-UG+LqQJbf5VJ8NWJ5Z3tdIe/HXjuIdo4JeVNADXBFuG7z9zjoegpzzGIyV5zQKi4zaJjnAd2+g2nna8TZvuW9Q==", "cpu": [ "arm64" ], @@ -1522,9 +1522,9 @@ } }, "node_modules/@img/sharp-libvips-linuxmusl-x64": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.1.0.tgz", - "integrity": "sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.0.tgz", + "integrity": "sha512-SRYOLR7CXPgNze8akZwjoGBoN1ThNZoqpOgfnOxmWsklTGVfJiGJoC/Lod7aNMGA1jSsKWM1+HRX43OP6p9+6Q==", "cpu": [ "x64" ], @@ -1539,9 +1539,9 @@ } }, "node_modules/@img/sharp-linux-arm": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.2.tgz", - "integrity": "sha512-0DZzkvuEOqQUP9mo2kjjKNok5AmnOr1jB2XYjkaoNRwpAYMDzRmAqUIa1nRi58S2WswqSfPOWLNOr0FDT3H5RQ==", + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.3.tgz", + "integrity": "sha512-oBK9l+h6KBN0i3dC8rYntLiVfW8D8wH+NPNT3O/WBHeW0OQWCjfWksLUaPidsrDKpJgXp3G3/hkmhptAW0I3+A==", "cpu": [ "arm" ], @@ -1558,13 +1558,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-arm": "1.1.0" + "@img/sharp-libvips-linux-arm": "1.2.0" } }, "node_modules/@img/sharp-linux-arm64": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.2.tgz", - "integrity": "sha512-D8n8wgWmPDakc83LORcfJepdOSN6MvWNzzz2ux0MnIbOqdieRZwVYY32zxVx+IFUT8er5KPcyU3XXsn+GzG/0Q==", + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.3.tgz", + "integrity": "sha512-QdrKe3EvQrqwkDrtuTIjI0bu6YEJHTgEeqdzI3uWJOH6G1O8Nl1iEeVYRGdj1h5I21CqxSvQp1Yv7xeU3ZewbA==", "cpu": [ "arm64" ], @@ -1581,13 +1581,36 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-arm64": "1.1.0" + "@img/sharp-libvips-linux-arm64": "1.2.0" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.3.tgz", + "integrity": "sha512-GLtbLQMCNC5nxuImPR2+RgrviwKwVql28FWZIW1zWruy6zLgA5/x2ZXk3mxj58X/tszVF69KK0Is83V8YgWhLA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.2.0" } }, "node_modules/@img/sharp-linux-s390x": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.2.tgz", - "integrity": "sha512-EGZ1xwhBI7dNISwxjChqBGELCWMGDvmxZXKjQRuqMrakhO8QoMgqCrdjnAqJq/CScxfRn+Bb7suXBElKQpPDiw==", + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.3.tgz", + "integrity": "sha512-3gahT+A6c4cdc2edhsLHmIOXMb17ltffJlxR0aC2VPZfwKoTGZec6u5GrFgdR7ciJSsHT27BD3TIuGcuRT0KmQ==", "cpu": [ "s390x" ], @@ -1604,13 +1627,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-s390x": "1.1.0" + "@img/sharp-libvips-linux-s390x": "1.2.0" } }, "node_modules/@img/sharp-linux-x64": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.2.tgz", - "integrity": "sha512-sD7J+h5nFLMMmOXYH4DD9UtSNBD05tWSSdWAcEyzqW8Cn5UxXvsHAxmxSesYUsTOBmUnjtxghKDl15EvfqLFbQ==", + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.3.tgz", + "integrity": "sha512-8kYso8d806ypnSq3/Ly0QEw90V5ZoHh10yH0HnrzOCr6DKAPI6QVHvwleqMkVQ0m+fc7EH8ah0BB0QPuWY6zJQ==", "cpu": [ "x64" ], @@ -1627,13 +1650,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-x64": "1.1.0" + "@img/sharp-libvips-linux-x64": "1.2.0" } }, "node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.2.tgz", - "integrity": "sha512-NEE2vQ6wcxYav1/A22OOxoSOGiKnNmDzCYFOZ949xFmrWZOVII1Bp3NqVVpvj+3UeHMFyN5eP/V5hzViQ5CZNA==", + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.3.tgz", + "integrity": "sha512-vAjbHDlr4izEiXM1OTggpCcPg9tn4YriK5vAjowJsHwdBIdx0fYRsURkxLG2RLm9gyBq66gwtWI8Gx0/ov+JKQ==", "cpu": [ "arm64" ], @@ -1650,13 +1673,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-arm64": "1.1.0" + "@img/sharp-libvips-linuxmusl-arm64": "1.2.0" } }, "node_modules/@img/sharp-linuxmusl-x64": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.2.tgz", - "integrity": "sha512-DOYMrDm5E6/8bm/yQLCWyuDJwUnlevR8xtF8bs+gjZ7cyUNYXiSf/E8Kp0Ss5xasIaXSHzb888V1BE4i1hFhAA==", + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.3.tgz", + "integrity": "sha512-gCWUn9547K5bwvOn9l5XGAEjVTTRji4aPTqLzGXHvIr6bIDZKNTA34seMPgM0WmSf+RYBH411VavCejp3PkOeQ==", "cpu": [ "x64" ], @@ -1673,13 +1696,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-x64": "1.1.0" + "@img/sharp-libvips-linuxmusl-x64": "1.2.0" } }, "node_modules/@img/sharp-wasm32": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.2.tgz", - "integrity": "sha512-/VI4mdlJ9zkaq53MbIG6rZY+QRN3MLbR6usYlgITEzi4Rpx5S6LFKsycOQjkOGmqTNmkIdLjEvooFKwww6OpdQ==", + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.3.tgz", + "integrity": "sha512-+CyRcpagHMGteySaWos8IbnXcHgfDn7pO2fiC2slJxvNq9gDipYBN42/RagzctVRKgxATmfqOSulgZv5e1RdMg==", "cpu": [ "wasm32" ], @@ -1687,7 +1710,7 @@ "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", "optional": true, "dependencies": { - "@emnapi/runtime": "^1.4.3" + "@emnapi/runtime": "^1.4.4" }, "engines": { "node": "^18.17.0 || ^20.3.0 || >=21.0.0" @@ -1697,9 +1720,9 @@ } }, "node_modules/@img/sharp-win32-arm64": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.2.tgz", - "integrity": "sha512-cfP/r9FdS63VA5k0xiqaNaEoGxBg9k7uE+RQGzuK9fHt7jib4zAVVseR9LsE4gJcNWgT6APKMNnCcnyOtmSEUQ==", + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.3.tgz", + "integrity": "sha512-MjnHPnbqMXNC2UgeLJtX4XqoVHHlZNd+nPt1kRPmj63wURegwBhZlApELdtxM2OIZDRv/DFtLcNhVbd1z8GYXQ==", "cpu": [ "arm64" ], @@ -1717,9 +1740,9 @@ } }, "node_modules/@img/sharp-win32-ia32": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.2.tgz", - "integrity": "sha512-QLjGGvAbj0X/FXl8n1WbtQ6iVBpWU7JO94u/P2M4a8CFYsvQi4GW2mRy/JqkRx0qpBzaOdKJKw8uc930EX2AHw==", + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.3.tgz", + "integrity": "sha512-xuCdhH44WxuXgOM714hn4amodJMZl3OEvf0GVTm0BEyMeA2to+8HEdRPShH0SLYptJY1uBw+SCFP9WVQi1Q/cw==", "cpu": [ "ia32" ], @@ -1737,9 +1760,9 @@ } }, "node_modules/@img/sharp-win32-x64": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.2.tgz", - "integrity": "sha512-aUdT6zEYtDKCaxkofmmJDJYGCf0+pJg3eU9/oBuqvEeoB9dKI6ZLc/1iLJCTuJQDO4ptntAlkUmHgGjyuobZbw==", + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.3.tgz", + "integrity": "sha512-OWwz05d++TxzLEv4VnsTz5CmZ6mI6S05sfQGEMrNrQcOEERbX46332IvE7pO/EUiw7jUrrS40z/M7kPyjfl04g==", "cpu": [ "x64" ], @@ -1884,9 +1907,9 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.9.tgz", - "integrity": "sha512-xpz6C/vXOegF9VEtlMBlkNNIjHrLhKaFBsO4lmQGr00x5BHp7p+oliR6i7LwIcM5cZU2VjLSwm2R+/zj5IjPWg==", + "version": "0.3.12", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", + "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", @@ -1903,9 +1926,9 @@ } }, "node_modules/@jridgewell/source-map": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.7.tgz", - "integrity": "sha512-maArE+jvYbj06DXh2iFlXSSDjTWXODlPTQHdDRQdGoYw7KvT4SfYCnPHfCyww8Z3JqFsW0BBjPLj8A2fwAvv7Q==", + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.10.tgz", + "integrity": "sha512-0pPkgz9dY+bijgistcTTJ5mR+ocqRXLuhXHYdzoMmmoJ2C9S46RCm2GMUbatPEUK9Yjy26IrAy8D/M00lLkv+Q==", "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", @@ -1913,15 +1936,15 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.1.tgz", - "integrity": "sha512-mBLKRHc7Ffw/hObYb9+cunuGNjshQk+vZdwZBJoqiysK/mW3Jq0UXosq8aIhMnLevANhR9yoYfdUEOHg6M9y0g==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", + "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==", "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.26", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.26.tgz", - "integrity": "sha512-Z9rjt4BUVEbLFpw0qjCklVxxf421wrmcbP4w+LmBUxYCyJTYYSclgJD0YsCgGqQCtCIPiz7kjbYYJiAKhjJ3kA==", + "version": "0.3.29", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", + "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -2075,9 +2098,9 @@ } }, "node_modules/@mermaid-js/parser": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-0.5.0.tgz", - "integrity": "sha512-AiaN7+VjXC+3BYE+GwNezkpjIcCI2qIMB/K4S2/vMWe0q/XJCBbx5+K7iteuz7VyltX9iAK4FmVTvGc9kjOV4w==", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-0.6.1.tgz", + "integrity": "sha512-lCQNpV8R4lgsGcjX5667UiuDLk2micCtjtxR1YKbBXvN5w2v+FeLYoHrTSSrjwXdMcDYvE4ZBPvKT31dfeSmmA==", "license": "MIT", "dependencies": { "langium": "3.3.1" @@ -2174,13 +2197,13 @@ } }, "node_modules/@playwright/test": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.52.0.tgz", - "integrity": "sha512-uh6W7sb55hl7D6vsAeA+V2p5JnlAqzhqFyF0VcJkKZXkgnFcVG9PziERRHQfPLfNGx1C292a4JqbWzhR8L4R1g==", + "version": "1.53.2", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.53.2.tgz", + "integrity": "sha512-tEB2U5z74ebBeyfGNZ3Jfg29AnW+5HlWhvHtb/Mqco9pFdZU1ZLNdVb2UtB5CvmiilNr2ZfVH/qMmAROG/XTzw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright": "1.52.0" + "playwright": "1.53.2" }, "bin": { "playwright": "cli.js" @@ -2263,9 +2286,9 @@ "license": "MIT" }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.44.1.tgz", - "integrity": "sha512-JAcBr1+fgqx20m7Fwe1DxPUl/hPkee6jA6Pl7n1v2EFiktAHenTaXl5aIFjUIEsfn9w3HE4gK1lEgNGMzBDs1w==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.44.2.tgz", + "integrity": "sha512-g0dF8P1e2QYPOj1gu7s/3LVP6kze9A7m6x0BZ9iTdXK8N5c2V7cpBKHV3/9A4Zd8xxavdhK0t4PnqjkqVmUc9Q==", "cpu": [ "arm" ], @@ -2277,9 +2300,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.44.1.tgz", - "integrity": "sha512-RurZetXqTu4p+G0ChbnkwBuAtwAbIwJkycw1n6GvlGlBuS4u5qlr5opix8cBAYFJgaY05TWtM+LaoFggUmbZEQ==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.44.2.tgz", + "integrity": "sha512-Yt5MKrOosSbSaAK5Y4J+vSiID57sOvpBNBR6K7xAaQvk3MkcNVV0f9fE20T+41WYN8hDn6SGFlFrKudtx4EoxA==", "cpu": [ "arm64" ], @@ -2291,9 +2314,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.44.1.tgz", - "integrity": "sha512-fM/xPesi7g2M7chk37LOnmnSTHLG/v2ggWqKj3CCA1rMA4mm5KVBT1fNoswbo1JhPuNNZrVwpTvlCVggv8A2zg==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.44.2.tgz", + "integrity": "sha512-EsnFot9ZieM35YNA26nhbLTJBHD0jTwWpPwmRVDzjylQT6gkar+zenfb8mHxWpRrbn+WytRRjE0WKsfaxBkVUA==", "cpu": [ "arm64" ], @@ -2305,9 +2328,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.44.1.tgz", - "integrity": "sha512-gDnWk57urJrkrHQ2WVx9TSVTH7lSlU7E3AFqiko+bgjlh78aJ88/3nycMax52VIVjIm3ObXnDL2H00e/xzoipw==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.44.2.tgz", + "integrity": "sha512-dv/t1t1RkCvJdWWxQ2lWOO+b7cMsVw5YFaS04oHpZRWehI1h0fV1gF4wgGCTyQHHjJDfbNpwOi6PXEafRBBezw==", "cpu": [ "x64" ], @@ -2319,9 +2342,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.44.1.tgz", - "integrity": "sha512-wnFQmJ/zPThM5zEGcnDcCJeYJgtSLjh1d//WuHzhf6zT3Md1BvvhJnWoy+HECKu2bMxaIcfWiu3bJgx6z4g2XA==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.44.2.tgz", + "integrity": "sha512-W4tt4BLorKND4qeHElxDoim0+BsprFTwb+vriVQnFFtT/P6v/xO5I99xvYnVzKWrK6j7Hb0yp3x7V5LUbaeOMg==", "cpu": [ "arm64" ], @@ -2333,9 +2356,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.44.1.tgz", - "integrity": "sha512-uBmIxoJ4493YATvU2c0upGz87f99e3wop7TJgOA/bXMFd2SvKCI7xkxY/5k50bv7J6dw1SXT4MQBQSLn8Bb/Uw==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.44.2.tgz", + "integrity": "sha512-tdT1PHopokkuBVyHjvYehnIe20fxibxFCEhQP/96MDSOcyjM/shlTkZZLOufV3qO6/FQOSiJTBebhVc12JyPTA==", "cpu": [ "x64" ], @@ -2347,9 +2370,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.44.1.tgz", - "integrity": "sha512-n0edDmSHlXFhrlmTK7XBuwKlG5MbS7yleS1cQ9nn4kIeW+dJH+ExqNgQ0RrFRew8Y+0V/x6C5IjsHrJmiHtkxQ==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.44.2.tgz", + "integrity": "sha512-+xmiDGGaSfIIOXMzkhJ++Oa0Gwvl9oXUeIiwarsdRXSe27HUIvjbSIpPxvnNsRebsNdUo7uAiQVgBD1hVriwSQ==", "cpu": [ "arm" ], @@ -2361,9 +2384,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.44.1.tgz", - "integrity": "sha512-8WVUPy3FtAsKSpyk21kV52HCxB+me6YkbkFHATzC2Yd3yuqHwy2lbFL4alJOLXKljoRw08Zk8/xEj89cLQ/4Nw==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.44.2.tgz", + "integrity": "sha512-bDHvhzOfORk3wt8yxIra8N4k/N0MnKInCW5OGZaeDYa/hMrdPaJzo7CSkjKZqX4JFUWjUGm88lI6QJLCM7lDrA==", "cpu": [ "arm" ], @@ -2375,9 +2398,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.44.1.tgz", - "integrity": "sha512-yuktAOaeOgorWDeFJggjuCkMGeITfqvPgkIXhDqsfKX8J3jGyxdDZgBV/2kj/2DyPaLiX6bPdjJDTu9RB8lUPQ==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.44.2.tgz", + "integrity": "sha512-NMsDEsDiYghTbeZWEGnNi4F0hSbGnsuOG+VnNvxkKg0IGDvFh7UVpM/14mnMwxRxUf9AdAVJgHPvKXf6FpMB7A==", "cpu": [ "arm64" ], @@ -2389,9 +2412,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.44.1.tgz", - "integrity": "sha512-W+GBM4ifET1Plw8pdVaecwUgxmiH23CfAUj32u8knq0JPFyK4weRy6H7ooxYFD19YxBulL0Ktsflg5XS7+7u9g==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.44.2.tgz", + "integrity": "sha512-lb5bxXnxXglVq+7imxykIp5xMq+idehfl+wOgiiix0191av84OqbjUED+PRC5OA8eFJYj5xAGcpAZ0pF2MnW+A==", "cpu": [ "arm64" ], @@ -2403,9 +2426,9 @@ ] }, "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.44.1.tgz", - "integrity": "sha512-1zqnUEMWp9WrGVuVak6jWTl4fEtrVKfZY7CvcBmUUpxAJ7WcSowPSAWIKa/0o5mBL/Ij50SIf9tuirGx63Ovew==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.44.2.tgz", + "integrity": "sha512-Yl5Rdpf9pIc4GW1PmkUGHdMtbx0fBLE1//SxDmuf3X0dUC57+zMepow2LK0V21661cjXdTn8hO2tXDdAWAqE5g==", "cpu": [ "loong64" ], @@ -2417,9 +2440,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.44.1.tgz", - "integrity": "sha512-Rl3JKaRu0LHIx7ExBAAnf0JcOQetQffaw34T8vLlg9b1IhzcBgaIdnvEbbsZq9uZp3uAH+JkHd20Nwn0h9zPjA==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.44.2.tgz", + "integrity": "sha512-03vUDH+w55s680YYryyr78jsO1RWU9ocRMaeV2vMniJJW/6HhoTBwyyiiTPVHNWLnhsnwcQ0oH3S9JSBEKuyqw==", "cpu": [ "ppc64" ], @@ -2431,9 +2454,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.44.1.tgz", - "integrity": "sha512-j5akelU3snyL6K3N/iX7otLBIl347fGwmd95U5gS/7z6T4ftK288jKq3A5lcFKcx7wwzb5rgNvAg3ZbV4BqUSw==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.44.2.tgz", + "integrity": "sha512-iYtAqBg5eEMG4dEfVlkqo05xMOk6y/JXIToRca2bAWuqjrJYJlx/I7+Z+4hSrsWU8GdJDFPL4ktV3dy4yBSrzg==", "cpu": [ "riscv64" ], @@ -2445,9 +2468,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.44.1.tgz", - "integrity": "sha512-ppn5llVGgrZw7yxbIm8TTvtj1EoPgYUAbfw0uDjIOzzoqlZlZrLJ/KuiE7uf5EpTpCTrNt1EdtzF0naMm0wGYg==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.44.2.tgz", + "integrity": "sha512-e6vEbgaaqz2yEHqtkPXa28fFuBGmUJ0N2dOJK8YUfijejInt9gfCSA7YDdJ4nYlv67JfP3+PSWFX4IVw/xRIPg==", "cpu": [ "riscv64" ], @@ -2459,9 +2482,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.44.1.tgz", - "integrity": "sha512-Hu6hEdix0oxtUma99jSP7xbvjkUM/ycke/AQQ4EC5g7jNRLLIwjcNwaUy95ZKBJJwg1ZowsclNnjYqzN4zwkAw==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.44.2.tgz", + "integrity": "sha512-evFOtkmVdY3udE+0QKrV5wBx7bKI0iHz5yEVx5WqDJkxp9YQefy4Mpx3RajIVcM6o7jxTvVd/qpC1IXUhGc1Mw==", "cpu": [ "s390x" ], @@ -2473,9 +2496,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.44.1.tgz", - "integrity": "sha512-EtnsrmZGomz9WxK1bR5079zee3+7a+AdFlghyd6VbAjgRJDbTANJ9dcPIPAi76uG05micpEL+gPGmAKYTschQw==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.44.2.tgz", + "integrity": "sha512-/bXb0bEsWMyEkIsUL2Yt5nFB5naLAwyOWMEviQfQY1x3l5WsLKgvZf66TM7UTfED6erckUVUJQ/jJ1FSpm3pRQ==", "cpu": [ "x64" ], @@ -2487,9 +2510,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.44.1.tgz", - "integrity": "sha512-iAS4p+J1az6Usn0f8xhgL4PaU878KEtutP4hqw52I4IO6AGoyOkHCxcc4bqufv1tQLdDWFx8lR9YlwxKuv3/3g==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.44.2.tgz", + "integrity": "sha512-3D3OB1vSSBXmkGEZR27uiMRNiwN08/RVAcBKwhUYPaiZ8bcvdeEwWPvbnXvvXHY+A/7xluzcN+kaiOFNiOZwWg==", "cpu": [ "x64" ], @@ -2501,9 +2524,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.44.1.tgz", - "integrity": "sha512-NtSJVKcXwcqozOl+FwI41OH3OApDyLk3kqTJgx8+gp6On9ZEt5mYhIsKNPGuaZr3p9T6NWPKGU/03Vw4CNU9qg==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.44.2.tgz", + "integrity": "sha512-VfU0fsMK+rwdK8mwODqYeM2hDrF2WiHaSmCBrS7gColkQft95/8tphyzv2EupVxn3iE0FI78wzffoULH1G+dkw==", "cpu": [ "arm64" ], @@ -2515,9 +2538,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.44.1.tgz", - "integrity": "sha512-JYA3qvCOLXSsnTR3oiyGws1Dm0YTuxAAeaYGVlGpUsHqloPcFjPg+X0Fj2qODGLNwQOAcCiQmHub/V007kiH5A==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.44.2.tgz", + "integrity": "sha512-+qMUrkbUurpE6DVRjiJCNGZBGo9xM4Y0FXU5cjgudWqIBWbcLkjE3XprJUsOFgC6xjBClwVa9k6O3A7K3vxb5Q==", "cpu": [ "ia32" ], @@ -2529,9 +2552,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.44.1.tgz", - "integrity": "sha512-J8o22LuF0kTe7m+8PvW9wk3/bRq5+mRo5Dqo6+vXb7otCm3TPhYOJqOaQtGU9YMWQSL3krMnoOxMr0+9E6F3Ug==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.44.2.tgz", + "integrity": "sha512-3+QZROYfJ25PDcxFF66UEk8jGWigHJeecZILvkPkyQN7oc5BvFo4YEXFkOs154j3FTMp9mn9Ky8RCOwastduEA==", "cpu": [ "x64" ], @@ -3050,9 +3073,9 @@ } }, "node_modules/@stylistic/eslint-plugin": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.0.0.tgz", - "integrity": "sha512-nVV2FSzeTJ3oFKw+3t9gQYQcrgbopgCASSY27QOtkhEGgSfdQQjDmzZd41NeT1myQ8Wc6l+pZllST9qIu4NKzg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.1.0.tgz", + "integrity": "sha512-TJRJul4u/lmry5N/kyCU+7RWWOk0wyXN+BncRlDYBqpLFnzXkd7QGVfN7KewarFIXv0IX0jSF/Ksu7aHWEDeuw==", "dev": true, "license": "MIT", "dependencies": { @@ -3494,9 +3517,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.19.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.2.tgz", - "integrity": "sha512-9pLGGwdzOUBDYi0GNjM97FIA+f92fqSke6joWeBjWXllfNxZBs7qeMF7tvtOIsbY45xkWkxrdwUfUf3MnQa9gA==", + "version": "20.19.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.4.tgz", + "integrity": "sha512-OP+We5WV8Xnbuvw0zC2m4qfB/BJvjyCwtNjhHdJxV1639SGSKrLmJkc3fMnp2Qy8nJyHp8RO6umxELN/dS1/EA==", "license": "MIT", "dependencies": { "undici-types": "~6.21.0" @@ -3546,17 +3569,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.35.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.35.0.tgz", - "integrity": "sha512-ijItUYaiWuce0N1SoSMrEd0b6b6lYkYt99pqCPfybd+HKVXtEvYhICfLdwp42MhiI5mp0oq7PKEL+g1cNiz/Eg==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.35.1.tgz", + "integrity": "sha512-9XNTlo7P7RJxbVeICaIIIEipqxLKguyh+3UbXuT2XQuFp6d8VOeDEGuz5IiX0dgZo8CiI6aOFLg4e8cF71SFVg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.35.0", - "@typescript-eslint/type-utils": "8.35.0", - "@typescript-eslint/utils": "8.35.0", - "@typescript-eslint/visitor-keys": "8.35.0", + "@typescript-eslint/scope-manager": "8.35.1", + "@typescript-eslint/type-utils": "8.35.1", + "@typescript-eslint/utils": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", @@ -3570,7 +3593,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.35.0", + "@typescript-eslint/parser": "^8.35.1", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } @@ -3586,16 +3609,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.35.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.35.0.tgz", - "integrity": "sha512-6sMvZePQrnZH2/cJkwRpkT7DxoAWh+g6+GFRK6bV3YQo7ogi3SX5rgF6099r5Q53Ma5qeT7LGmOmuIutF4t3lA==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.35.1.tgz", + "integrity": "sha512-3MyiDfrfLeK06bi/g9DqJxP5pV74LNv4rFTyvGDmT3x2p1yp1lOd+qYZfiRPIOf/oON+WRZR5wxxuF85qOar+w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.35.0", - "@typescript-eslint/types": "8.35.0", - "@typescript-eslint/typescript-estree": "8.35.0", - "@typescript-eslint/visitor-keys": "8.35.0", + "@typescript-eslint/scope-manager": "8.35.1", + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/typescript-estree": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1", "debug": "^4.3.4" }, "engines": { @@ -3611,14 +3634,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.35.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.35.0.tgz", - "integrity": "sha512-41xatqRwWZuhUMF/aZm2fcUsOFKNcG28xqRSS6ZVr9BVJtGExosLAm5A1OxTjRMagx8nJqva+P5zNIGt8RIgbQ==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.35.1.tgz", + "integrity": "sha512-VYxn/5LOpVxADAuP3NrnxxHYfzVtQzLKeldIhDhzC8UHaiQvYlXvKuVho1qLduFbJjjy5U5bkGwa3rUGUb1Q6Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.35.0", - "@typescript-eslint/types": "^8.35.0", + "@typescript-eslint/tsconfig-utils": "^8.35.1", + "@typescript-eslint/types": "^8.35.1", "debug": "^4.3.4" }, "engines": { @@ -3633,14 +3656,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.35.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.35.0.tgz", - "integrity": "sha512-+AgL5+mcoLxl1vGjwNfiWq5fLDZM1TmTPYs2UkyHfFhgERxBbqHlNjRzhThJqz+ktBqTChRYY6zwbMwy0591AA==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.35.1.tgz", + "integrity": "sha512-s/Bpd4i7ht2934nG+UoSPlYXd08KYz3bmjLEb7Ye1UVob0d1ENiT3lY8bsCmik4RqfSbPw9xJJHbugpPpP5JUg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.35.0", - "@typescript-eslint/visitor-keys": "8.35.0" + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3651,9 +3674,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.35.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.35.0.tgz", - "integrity": "sha512-04k/7247kZzFraweuEirmvUj+W3bJLI9fX6fbo1Qm2YykuBvEhRTPl8tcxlYO8kZZW+HIXfkZNoasVb8EV4jpA==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.35.1.tgz", + "integrity": "sha512-K5/U9VmT9dTHoNowWZpz+/TObS3xqC5h0xAIjXPw+MNcKV9qg6eSatEnmeAwkjHijhACH0/N7bkhKvbt1+DXWQ==", "dev": true, "license": "MIT", "engines": { @@ -3668,14 +3691,14 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.35.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.35.0.tgz", - "integrity": "sha512-ceNNttjfmSEoM9PW87bWLDEIaLAyR+E6BoYJQ5PfaDau37UGca9Nyq3lBk8Bw2ad0AKvYabz6wxc7DMTO2jnNA==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.35.1.tgz", + "integrity": "sha512-HOrUBlfVRz5W2LIKpXzZoy6VTZzMu2n8q9C2V/cFngIC5U1nStJgv0tMV4sZPzdf4wQm9/ToWUFPMN9Vq9VJQQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.35.0", - "@typescript-eslint/utils": "8.35.0", + "@typescript-eslint/typescript-estree": "8.35.1", + "@typescript-eslint/utils": "8.35.1", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, @@ -3692,9 +3715,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.35.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.35.0.tgz", - "integrity": "sha512-0mYH3emanku0vHw2aRLNGqe7EXh9WHEhi7kZzscrMDf6IIRUQ5Jk4wp1QrledE/36KtdZrVfKnE32eZCf/vaVQ==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.35.1.tgz", + "integrity": "sha512-q/O04vVnKHfrrhNAscndAn1tuQhIkwqnaW+eu5waD5IPts2eX1dgJxgqcPx5BX109/qAz7IG6VrEPTOYKCNfRQ==", "dev": true, "license": "MIT", "engines": { @@ -3706,16 +3729,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.35.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.35.0.tgz", - "integrity": "sha512-F+BhnaBemgu1Qf8oHrxyw14wq6vbL8xwWKKMwTMwYIRmFFY/1n/9T/jpbobZL8vp7QyEUcC6xGrnAO4ua8Kp7w==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.35.1.tgz", + "integrity": "sha512-Vvpuvj4tBxIka7cPs6Y1uvM7gJgdF5Uu9F+mBJBPY4MhvjrjWGK4H0lVgLJd/8PWZ23FTqsaJaLEkBCFUk8Y9g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.35.0", - "@typescript-eslint/tsconfig-utils": "8.35.0", - "@typescript-eslint/types": "8.35.0", - "@typescript-eslint/visitor-keys": "8.35.0", + "@typescript-eslint/project-service": "8.35.1", + "@typescript-eslint/tsconfig-utils": "8.35.1", + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -3768,16 +3791,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.35.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.35.0.tgz", - "integrity": "sha512-nqoMu7WWM7ki5tPgLVsmPM8CkqtoPUG6xXGeefM5t4x3XumOEKMoUZPdi+7F+/EotukN4R9OWdmDxN80fqoZeg==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.35.1.tgz", + "integrity": "sha512-lhnwatFmOFcazAsUm3ZnZFpXSxiwoa1Lj50HphnDe1Et01NF4+hrdXONSUHIcbVu2eFb1bAf+5yjXkGVkXBKAQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.35.0", - "@typescript-eslint/types": "8.35.0", - "@typescript-eslint/typescript-estree": "8.35.0" + "@typescript-eslint/scope-manager": "8.35.1", + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/typescript-estree": "8.35.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3792,13 +3815,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.35.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.35.0.tgz", - "integrity": "sha512-zTh2+1Y8ZpmeQaQVIc/ZZxsx8UzgKJyNg1PTvjzC7WMhPSVS8bfDX34k1SrwOf016qd5RU3az2UxUNue3IfQ5g==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.35.1.tgz", + "integrity": "sha512-VRwixir4zBWCSTP/ljEo091lbpypz57PoeAQ9imjG+vbeof9LplljsL1mos4ccG6H9IjfrVGM359RozUnuFhpw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.35.0", + "@typescript-eslint/types": "8.35.1", "eslint-visitor-keys": "^4.2.1" }, "engines": { @@ -3810,9 +3833,9 @@ } }, "node_modules/@unrs/resolver-binding-android-arm-eabi": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.9.2.tgz", - "integrity": "sha512-tS+lqTU3N0kkthU+rYp0spAYq15DU8ld9kXkaKg9sbQqJNF+WPMuNHZQGCgdxrUOEO0j22RKMwRVhF1HTl+X8A==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.0.tgz", + "integrity": "sha512-LRw5BW29sYj9NsQC6QoqeLVQhEa+BwVINYyMlcve+6stwdBsSt5UB7zw4UZB4+4PNqIVilHoMaPWCb/KhABHQw==", "cpu": [ "arm" ], @@ -3824,9 +3847,9 @@ ] }, "node_modules/@unrs/resolver-binding-android-arm64": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.9.2.tgz", - "integrity": "sha512-MffGiZULa/KmkNjHeuuflLVqfhqLv1vZLm8lWIyeADvlElJ/GLSOkoUX+5jf4/EGtfwrNFcEaB8BRas03KT0/Q==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.0.tgz", + "integrity": "sha512-zYX8D2zcWCAHqghA8tPjbp7LwjVXbIZP++mpU/Mrf5jUVlk3BWIxkeB8yYzZi5GpFSlqMcRZQxQqbMI0c2lASQ==", "cpu": [ "arm64" ], @@ -3838,9 +3861,9 @@ ] }, "node_modules/@unrs/resolver-binding-darwin-arm64": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.9.2.tgz", - "integrity": "sha512-dzJYK5rohS1sYl1DHdJ3mwfwClJj5BClQnQSyAgEfggbUwA9RlROQSSbKBLqrGfsiC/VyrDPtbO8hh56fnkbsQ==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.0.tgz", + "integrity": "sha512-YsYOT049hevAY/lTYD77GhRs885EXPeAfExG5KenqMJ417nYLS2N/kpRpYbABhFZBVQn+2uRPasTe4ypmYoo3w==", "cpu": [ "arm64" ], @@ -3852,9 +3875,9 @@ ] }, "node_modules/@unrs/resolver-binding-darwin-x64": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.9.2.tgz", - "integrity": "sha512-gaIMWK+CWtXcg9gUyznkdV54LzQ90S3X3dn8zlh+QR5Xy7Y+Efqw4Rs4im61K1juy4YNb67vmJsCDAGOnIeffQ==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.0.tgz", + "integrity": "sha512-PSjvk3OZf1aZImdGY5xj9ClFG3bC4gnSSYWrt+id0UAv+GwwVldhpMFjAga8SpMo2T1GjV9UKwM+QCsQCQmtdA==", "cpu": [ "x64" ], @@ -3866,9 +3889,9 @@ ] }, "node_modules/@unrs/resolver-binding-freebsd-x64": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.9.2.tgz", - "integrity": "sha512-S7QpkMbVoVJb0xwHFwujnwCAEDe/596xqY603rpi/ioTn9VDgBHnCCxh+UFrr5yxuMH+dliHfjwCZJXOPJGPnw==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.0.tgz", + "integrity": "sha512-KC/iFaEN/wsTVYnHClyHh5RSYA9PpuGfqkFua45r4sweXpC0KHZ+BYY7ikfcGPt5w1lMpR1gneFzuqWLQxsRKg==", "cpu": [ "x64" ], @@ -3880,9 +3903,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.9.2.tgz", - "integrity": "sha512-+XPUMCuCCI80I46nCDFbGum0ZODP5NWGiwS3Pj8fOgsG5/ctz+/zzuBlq/WmGa+EjWZdue6CF0aWWNv84sE1uw==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.0.tgz", + "integrity": "sha512-CDh/0v8uot43cB4yKtDL9CVY8pbPnMV0dHyQCE4lFz6PW/+9tS0i9eqP5a91PAqEBVMqH1ycu+k8rP6wQU846w==", "cpu": [ "arm" ], @@ -3894,9 +3917,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.9.2.tgz", - "integrity": "sha512-sqvUyAd1JUpwbz33Ce2tuTLJKM+ucSsYpPGl2vuFwZnEIg0CmdxiZ01MHQ3j6ExuRqEDUCy8yvkDKvjYFPb8Zg==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.0.tgz", + "integrity": "sha512-+TE7epATDSnvwr3L/hNHX3wQ8KQYB+jSDTdywycg3qDqvavRP8/HX9qdq/rMcnaRDn4EOtallb3vL/5wCWGCkw==", "cpu": [ "arm" ], @@ -3908,9 +3931,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.9.2.tgz", - "integrity": "sha512-UYA0MA8ajkEDCFRQdng/FVx3F6szBvk3EPnkTTQuuO9lV1kPGuTB+V9TmbDxy5ikaEgyWKxa4CI3ySjklZ9lFA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.0.tgz", + "integrity": "sha512-VBAYGg3VahofpQ+L4k/ZO8TSICIbUKKTaMYOWHWfuYBFqPbSkArZZLezw3xd27fQkxX4BaLGb/RKnW0dH9Y/UA==", "cpu": [ "arm64" ], @@ -3922,9 +3945,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-arm64-musl": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.9.2.tgz", - "integrity": "sha512-P/CO3ODU9YJIHFqAkHbquKtFst0COxdphc8TKGL5yCX75GOiVpGqd1d15ahpqu8xXVsqP4MGFP2C3LRZnnL5MA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.0.tgz", + "integrity": "sha512-9IgGFUUb02J1hqdRAHXpZHIeUHRrbnGo6vrRbz0fREH7g+rzQy53/IBSyadZ/LG5iqMxukriNPu4hEMUn+uWEg==", "cpu": [ "arm64" ], @@ -3936,9 +3959,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.9.2.tgz", - "integrity": "sha512-uKStFlOELBxBum2s1hODPtgJhY4NxYJE9pAeyBgNEzHgTqTiVBPjfTlPFJkfxyTjQEuxZbbJlJnMCrRgD7ubzw==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.0.tgz", + "integrity": "sha512-LR4iQ/LPjMfivpL2bQ9kmm3UnTas3U+umcCnq/CV7HAkukVdHxrDD1wwx74MIWbbgzQTLPYY7Ur2MnnvkYJCBQ==", "cpu": [ "ppc64" ], @@ -3950,9 +3973,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.9.2.tgz", - "integrity": "sha512-LkbNnZlhINfY9gK30AHs26IIVEZ9PEl9qOScYdmY2o81imJYI4IMnJiW0vJVtXaDHvBvxeAgEy5CflwJFIl3tQ==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.0.tgz", + "integrity": "sha512-HCupFQwMrRhrOg7YHrobbB5ADg0Q8RNiuefqMHVsdhEy9lLyXm/CxsCXeLJdrg27NAPsCaMDtdlm8Z2X8x91Tg==", "cpu": [ "riscv64" ], @@ -3964,9 +3987,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.9.2.tgz", - "integrity": "sha512-vI+e6FzLyZHSLFNomPi+nT+qUWN4YSj8pFtQZSFTtmgFoxqB6NyjxSjAxEC1m93qn6hUXhIsh8WMp+fGgxCoRg==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.0.tgz", + "integrity": "sha512-Ckxy76A5xgjWa4FNrzcKul5qFMWgP5JSQ5YKd0XakmWOddPLSkQT+uAvUpQNnFGNbgKzv90DyQlxPDYPQ4nd6A==", "cpu": [ "riscv64" ], @@ -3978,9 +4001,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.9.2.tgz", - "integrity": "sha512-sSO4AlAYhSM2RAzBsRpahcJB1msc6uYLAtP6pesPbZtptF8OU/CbCPhSRW6cnYOGuVmEmWVW5xVboAqCnWTeHQ==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.0.tgz", + "integrity": "sha512-HfO0PUCCRte2pMJmVyxPI+eqT7KuV3Fnvn2RPvMe5mOzb2BJKf4/Vth8sSt9cerQboMaTVpbxyYjjLBWIuI5BQ==", "cpu": [ "s390x" ], @@ -3992,9 +4015,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-x64-gnu": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.9.2.tgz", - "integrity": "sha512-jkSkwch0uPFva20Mdu8orbQjv2A3G88NExTN2oPTI1AJ+7mZfYW3cDCTyoH6OnctBKbBVeJCEqh0U02lTkqD5w==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.0.tgz", + "integrity": "sha512-9PZdjP7tLOEjpXHS6+B/RNqtfVUyDEmaViPOuSqcbomLdkJnalt5RKQ1tr2m16+qAufV0aDkfhXtoO7DQos/jg==", "cpu": [ "x64" ], @@ -4006,9 +4029,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-x64-musl": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.9.2.tgz", - "integrity": "sha512-Uk64NoiTpQbkpl+bXsbeyOPRpUoMdcUqa+hDC1KhMW7aN1lfW8PBlBH4mJ3n3Y47dYE8qi0XTxy1mBACruYBaw==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.0.tgz", + "integrity": "sha512-qkE99ieiSKMnFJY/EfyGKVtNra52/k+lVF/PbO4EL5nU6AdvG4XhtJ+WHojAJP7ID9BNIra/yd75EHndewNRfA==", "cpu": [ "x64" ], @@ -4020,9 +4043,9 @@ ] }, "node_modules/@unrs/resolver-binding-wasm32-wasi": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.9.2.tgz", - "integrity": "sha512-EpBGwkcjDicjR/ybC0g8wO5adPNdVuMrNalVgYcWi+gYtC1XYNuxe3rufcO7dA76OHGeVabcO6cSkPJKVcbCXQ==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.0.tgz", + "integrity": "sha512-MjXek8UL9tIX34gymvQLecz2hMaQzOlaqYJJBomwm1gsvK2F7hF+YqJJ2tRyBDTv9EZJGMt4KlKkSD/gZWCOiw==", "cpu": [ "wasm32" ], @@ -4037,9 +4060,9 @@ } }, "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.9.2.tgz", - "integrity": "sha512-EdFbGn7o1SxGmN6aZw9wAkehZJetFPao0VGZ9OMBwKx6TkvDuj6cNeLimF/Psi6ts9lMOe+Dt6z19fZQ9Ye2fw==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.0.tgz", + "integrity": "sha512-9LT6zIGO7CHybiQSh7DnQGwFMZvVr0kUjah6qQfkH2ghucxPV6e71sUXJdSM4Ba0MaGE6DC/NwWf7mJmc3DAng==", "cpu": [ "arm64" ], @@ -4051,9 +4074,9 @@ ] }, "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.9.2.tgz", - "integrity": "sha512-JY9hi1p7AG+5c/dMU8o2kWemM8I6VZxfGwn1GCtf3c5i+IKcMo2NQ8OjZ4Z3/itvY/Si3K10jOBQn7qsD/whUA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.0.tgz", + "integrity": "sha512-HYchBYOZ7WN266VjoGm20xFv5EonG/ODURRgwl9EZT7Bq1nLEs6VKJddzfFdXEAho0wfFlt8L/xIiE29Pmy1RA==", "cpu": [ "ia32" ], @@ -4065,9 +4088,9 @@ ] }, "node_modules/@unrs/resolver-binding-win32-x64-msvc": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.9.2.tgz", - "integrity": "sha512-ryoo+EB19lMxAd80ln9BVf8pdOAxLb97amrQ3SFN9OCRn/5M5wvwDgAe4i8ZjhpbiHoDeP8yavcTEnpKBo7lZg==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.0.tgz", + "integrity": "sha512-+oLKLHw3I1UQo4MeHfoLYF+e6YBa8p5vYUw3Rgt7IDzCs+57vIZqQlIo62NDpYM0VG6BjWOwnzBczMvbtH8hag==", "cpu": [ "x64" ], @@ -4096,9 +4119,9 @@ } }, "node_modules/@vitest/coverage-v8": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.2.3.tgz", - "integrity": "sha512-D1QKzngg8PcDoCE8FHSZhREDuEy+zcKmMiMafYse41RZpBE5EDJyKOTdqK3RQfsV2S2nyKor5KCs8PyPRFqKPg==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.2.4.tgz", + "integrity": "sha512-EyF9SXU6kS5Ku/U82E259WSnvg6c8KTjppUncuNdm5QHpe17mwREHnjDzozC8x9MZ0xfBUFSaLkRv4TMA75ALQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4120,8 +4143,8 @@ "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "@vitest/browser": "3.2.3", - "vitest": "3.2.3" + "@vitest/browser": "3.2.4", + "vitest": "3.2.4" }, "peerDependenciesMeta": { "@vitest/browser": { @@ -4140,13 +4163,13 @@ } }, "node_modules/@vitest/eslint-plugin": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@vitest/eslint-plugin/-/eslint-plugin-1.2.2.tgz", - "integrity": "sha512-R8NwW+VxyKqVGcMfYsUbdThQyMbtNcoeg+jJeTgMHqWdFdcS0nrODAQXhkplvWzgd7jIJ+GQeydGqFLibsxMxg==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@vitest/eslint-plugin/-/eslint-plugin-1.3.4.tgz", + "integrity": "sha512-EOg8d0jn3BAiKnR55WkFxmxfWA3nmzrbIIuOXyTe6A72duryNgyU+bdBEauA97Aab3ho9kLmAwgPX63Ckj4QEg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/utils": "^8.24.0" + "@typescript-eslint/utils": "^8.24.1" }, "peerDependencies": { "eslint": ">= 8.57.0", @@ -4163,15 +4186,15 @@ } }, "node_modules/@vitest/expect": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.3.tgz", - "integrity": "sha512-W2RH2TPWVHA1o7UmaFKISPvdicFJH+mjykctJFoAkUw+SPTJTGjUNdKscFBrqM7IPnCVu6zihtKYa7TkZS1dkQ==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz", + "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==", "dev": true, "license": "MIT", "dependencies": { "@types/chai": "^5.2.2", - "@vitest/spy": "3.2.3", - "@vitest/utils": "3.2.3", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", "chai": "^5.2.0", "tinyrainbow": "^2.0.0" }, @@ -4180,13 +4203,13 @@ } }, "node_modules/@vitest/mocker": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.3.tgz", - "integrity": "sha512-cP6fIun+Zx8he4rbWvi+Oya6goKQDZK+Yq4hhlggwQBbrlOQ4qtZ+G4nxB6ZnzI9lyIb+JnvyiJnPC2AGbKSPA==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz", + "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "3.2.3", + "@vitest/spy": "3.2.4", "estree-walker": "^3.0.3", "magic-string": "^0.30.17" }, @@ -4234,9 +4257,9 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.3.tgz", - "integrity": "sha512-yFglXGkr9hW/yEXngO+IKMhP0jxyFw2/qys/CK4fFUZnSltD+MU7dVYGrH8rvPcK/O6feXQA+EU33gjaBBbAng==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz", + "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==", "dev": true, "license": "MIT", "dependencies": { @@ -4247,13 +4270,13 @@ } }, "node_modules/@vitest/runner": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.3.tgz", - "integrity": "sha512-83HWYisT3IpMaU9LN+VN+/nLHVBCSIUKJzGxC5RWUOsK1h3USg7ojL+UXQR3b4o4UBIWCYdD2fxuzM7PQQ1u8w==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.4.tgz", + "integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "3.2.3", + "@vitest/utils": "3.2.4", "pathe": "^2.0.3", "strip-literal": "^3.0.0" }, @@ -4262,13 +4285,13 @@ } }, "node_modules/@vitest/snapshot": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.3.tgz", - "integrity": "sha512-9gIVWx2+tysDqUmmM1L0hwadyumqssOL1r8KJipwLx5JVYyxvVRfxvMq7DaWbZZsCqZnu/dZedaZQh4iYTtneA==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.4.tgz", + "integrity": "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "3.2.3", + "@vitest/pretty-format": "3.2.4", "magic-string": "^0.30.17", "pathe": "^2.0.3" }, @@ -4287,9 +4310,9 @@ } }, "node_modules/@vitest/spy": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.3.tgz", - "integrity": "sha512-JHu9Wl+7bf6FEejTCREy+DmgWe+rQKbK+y32C/k5f4TBIAlijhJbRBIRIOCEpVevgRsCQR2iHRUH2/qKVM/plw==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz", + "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==", "dev": true, "license": "MIT", "dependencies": { @@ -4300,14 +4323,14 @@ } }, "node_modules/@vitest/utils": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.3.tgz", - "integrity": "sha512-4zFBCU5Pf+4Z6v+rwnZ1HU1yzOKKvDkMXZrymE2PBlbjKJRlrOxbvpfPSvJTGRIwGoahaOGvp+kbCoxifhzJ1Q==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz", + "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "3.2.3", - "loupe": "^3.1.3", + "@vitest/pretty-format": "3.2.4", + "loupe": "^3.1.4", "tinyrainbow": "^2.0.0" }, "funding": { @@ -4671,6 +4694,18 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-import-phases": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.3.tgz", + "integrity": "sha512-jtKLnfoOzm28PazuQ4dVBcE9Jeo6ha1GAJvq3N0LlNOszmTfx+wSycBehn+FN0RnyeR77IBxN/qVYMw0Rlj0Xw==", + "license": "MIT", + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "acorn": "^8.14.0" + } + }, "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", @@ -5245,14 +5280,14 @@ } }, "node_modules/cacheable": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-1.10.0.tgz", - "integrity": "sha512-SSgQTAnhd7WlJXnGlIi4jJJOiHzgnM5wRMEPaXAU4kECTAMpBoYKoZ9i5zHmclIEZbxcu3j7yY/CF8DTmwIsHg==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-1.10.1.tgz", + "integrity": "sha512-Fa2BZY0CS9F0PFc/6aVA6tgpOdw+hmv9dkZOlHXII5v5Hw+meJBIWDcPrG9q/dXxGcNbym5t77fzmawrBQfTmQ==", "dev": true, "license": "MIT", "dependencies": { - "hookified": "^1.8.2", - "keyv": "^5.3.3" + "hookified": "^1.10.0", + "keyv": "^5.3.4" } }, "node_modules/cacheable/node_modules/keyv": { @@ -5334,9 +5369,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001726", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001726.tgz", - "integrity": "sha512-VQAUIUzBiZ/UnlM28fSp2CRF3ivUn1BWEvxMcVTNwpw91Py1pGbPIyIKtd+tzct9C3ouceCVdGAXxZOpZAsgdw==", + "version": "1.0.30001727", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz", + "integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==", "funding": [ { "type": "opencollective", @@ -5539,9 +5574,9 @@ } }, "node_modules/ci-info": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.2.0.tgz", - "integrity": "sha512-cYY9mypksY8NRqgDB1XD1RiJL338v/551niynFTGkZOO2LHuB2OmOYxDIe/ttN9AHwrqdum1360G3ald0W9kCg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.0.tgz", + "integrity": "sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==", "dev": true, "funding": [ { @@ -6904,9 +6939,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.177", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.177.tgz", - "integrity": "sha512-7EH2G59nLsEMj97fpDuvVcYi6lwTcM1xuWw3PssD8xzboAW7zj7iB3COEEEATUfjLHrs5uKBLQT03V/8URx06g==", + "version": "1.5.179", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.179.tgz", + "integrity": "sha512-UWKi/EbBopgfFsc5k61wFpV7WrnnSlSzW/e2XcBmS6qKYTivZlLtoll5/rdqRTxGglGHkmkW0j0pFNJG10EUIQ==", "license": "ISC" }, "node_modules/emoji-regex": { @@ -7250,9 +7285,9 @@ } }, "node_modules/eslint": { - "version": "9.30.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.30.0.tgz", - "integrity": "sha512-iN/SiPxmQu6EVkf+m1qpBxzUhE12YqFLOSySuOyVLJLEF9nzTf+h/1AJYc1JWzCnktggeNrjvQGLngDzXirU6g==", + "version": "9.30.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.30.1.tgz", + "integrity": "sha512-zmxXPNMOXmwm9E0yQLi5uqXHs7uq2UIiqEKo3Gq+3fwo1XrJ+hijAZImyF7hclW3E6oHz43Yk3RP8at6OTKflQ==", "dev": true, "license": "MIT", "dependencies": { @@ -7262,7 +7297,7 @@ "@eslint/config-helpers": "^0.3.0", "@eslint/core": "^0.14.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.30.0", + "@eslint/js": "9.30.1", "@eslint/plugin-kit": "^0.3.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", @@ -7669,9 +7704,9 @@ "license": "MIT" }, "node_modules/eslint-plugin-vue": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-10.2.0.tgz", - "integrity": "sha512-tl9s+KN3z0hN2b8fV2xSs5ytGl7Esk1oSCxULLwFcdaElhZ8btYYZFrWxvh4En+czrSDtuLCeCOGa8HhEZuBdQ==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-10.3.0.tgz", + "integrity": "sha512-A0u9snqjCfYaPnqqOaH6MBLVWDUIN4trXn8J3x67uDcXvR7X6Ut8p16N+nYhMCQ9Y7edg2BIRGzfyZsY0IdqoQ==", "dev": true, "license": "MIT", "dependencies": { @@ -7686,24 +7721,30 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "peerDependencies": { + "@typescript-eslint/parser": "^7.0.0 || ^8.0.0", "eslint": "^8.57.0 || ^9.0.0", "vue-eslint-parser": "^10.0.0" + }, + "peerDependenciesMeta": { + "@typescript-eslint/parser": { + "optional": true + } } }, "node_modules/eslint-plugin-vue-scoped-css": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue-scoped-css/-/eslint-plugin-vue-scoped-css-2.10.0.tgz", - "integrity": "sha512-oH2NY7XFHF3EGOotvuPdnhB0x4uOmjoRoWZVfMnJ2PILDKVgZgM8WZ0rhDlh+fsr9jO9P8CAXO5/9s9v/GZNhg==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue-scoped-css/-/eslint-plugin-vue-scoped-css-2.11.0.tgz", + "integrity": "sha512-rrJgLY8iroTIUMSyxhyhJzFcRxABbk3gFrOLkl41F9G1VBqNNpDShyf6PmDoBEWDk07/bJlnqYlvnQ3giUrRYQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "eslint-compat-utils": "^0.6.0", + "eslint-compat-utils": "^0.6.5", "lodash": "^4.17.21", "postcss": "^8.4.31", "postcss-safe-parser": "^6.0.0", "postcss-scss": "^4.0.3", - "postcss-selector-parser": "^6.0.9", + "postcss-selector-parser": "^7.0.0", "postcss-styl": "^0.12.0" }, "engines": { @@ -7717,6 +7758,20 @@ "vue-eslint-parser": ">=7.1.0" } }, + "node_modules/eslint-plugin-vue-scoped-css/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/eslint-plugin-wc": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/eslint-plugin-wc/-/eslint-plugin-wc-3.0.1.tgz", @@ -7893,9 +7948,9 @@ } }, "node_modules/expect-type": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.1.tgz", - "integrity": "sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz", + "integrity": "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -8440,9 +8495,9 @@ } }, "node_modules/globals": { - "version": "16.1.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-16.1.0.tgz", - "integrity": "sha512-aibexHNbb/jiUSObBgpHLj+sIuUmJnYcgXBlrfsiDZ9rt4aF2TFRbyLgZ2iFQuVZ1K5Mx3FVkbKRSgKrbK3K2g==", + "version": "16.3.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.3.0.tgz", + "integrity": "sha512-bqWEnJ1Nt3neqx2q5SFfGS8r/ahumIakg3HcwtNlrVlwXIeNumWn/c7Pn/wKzGhf6SaW6H6uWXLqC30STCMchQ==", "dev": true, "license": "MIT", "engines": { @@ -10538,14 +10593,14 @@ } }, "node_modules/mermaid": { - "version": "11.7.0", - "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.7.0.tgz", - "integrity": "sha512-/1/5R0rt0Z1Ak0CuznAnCF3HtQgayRXUz6SguzOwN4L+DuCobz0UxnQ+ZdTSZ3AugKVVh78tiVmsHpHWV25TCw==", + "version": "11.8.1", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.8.1.tgz", + "integrity": "sha512-VSXJLqP1Sqw5sGr273mhvpPRhXwE6NlmMSqBZQw+yZJoAJkOIPPn/uT3teeCBx60Fkt5zEI3FrH2eVT0jXRDzw==", "license": "MIT", "dependencies": { "@braintree/sanitize-url": "^7.0.4", "@iconify/utils": "^2.1.33", - "@mermaid-js/parser": "^0.5.0", + "@mermaid-js/parser": "^0.6.1", "@types/d3": "^7.4.3", "cytoscape": "^3.29.3", "cytoscape-cose-bilkent": "^4.1.0", @@ -11320,9 +11375,9 @@ } }, "node_modules/napi-postinstall": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.2.5.tgz", - "integrity": "sha512-kmsgUvCRIJohHjbZ3V8avP0I1Pekw329MVAMDzVxsrkjgdnqiwvMX5XwR+hWV66vsAtZ+iM+fVnq8RTQawUmCQ==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.0.tgz", + "integrity": "sha512-M7NqKyhODKV1gRLdkwE7pDsZP2/SC2a2vHkOYh9MCpKMbWVfyVfUw5MaH83Fv6XMjxr5jryUp3IDDL9rlxsTeA==", "dev": true, "license": "MIT", "bin": { @@ -11919,9 +11974,9 @@ } }, "node_modules/pkg-types": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.1.1.tgz", - "integrity": "sha512-eY0QFb6eSwc9+0d/5D2lFFUq+A3n3QNGSy/X2Nvp+6MfzGw2u6EbA7S80actgjY1lkvvI0pqB+a4hioMh443Ew==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.2.0.tgz", + "integrity": "sha512-2SM/GZGAEkPp3KWORxQZns4M+WSeXbC2HEvmOIJe3Cmiv6ieAJvdVhDldtHqM5J1Y7MrR1XhkBT/rMlhh9FdqQ==", "license": "MIT", "dependencies": { "confbox": "^0.2.2", @@ -11930,13 +11985,13 @@ } }, "node_modules/playwright": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.52.0.tgz", - "integrity": "sha512-JAwMNMBlxJ2oD1kce4KPtMkDeKGHQstdpFPcPH3maElAXon/QZeTvtsfXmTMRyO9TslfoYOXkSsvao2nE1ilTw==", + "version": "1.53.2", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.53.2.tgz", + "integrity": "sha512-6K/qQxVFuVQhRQhFsVZ9fGeatxirtrpPgxzBYWyZLEXJzqYwuL4fuNmfOfD5et1tJE4GScKyPNeLhZeRwuTU3A==", "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.52.0" + "playwright-core": "1.53.2" }, "bin": { "playwright": "cli.js" @@ -11949,9 +12004,9 @@ } }, "node_modules/playwright-core": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.52.0.tgz", - "integrity": "sha512-l2osTgLXSMeuLZOML9qYODUQoPPnUsKsb5/P6LJ2e6uPKXUdPK5WYhN4z03G+YNbWmGDY4YENauNu4ZKczreHg==", + "version": "1.53.2", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.53.2.tgz", + "integrity": "sha512-ox/OytMy+2w1jcYEYlOo1Hhp8hZkLCximMTUTMBXjGUA1KoFfiSZ+DU+3a739jsPY0yoKH2TFy9S2fsJas8yAw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -13189,9 +13244,9 @@ } }, "node_modules/sharp": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.2.tgz", - "integrity": "sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg==", + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.3.tgz", + "integrity": "sha512-eX2IQ6nFohW4DbvHIOLRB3MHFpYqaqvXd3Tp5e/T/dSH83fxaNJQRvDMhASmkNTsNTVF2/OOopzRCt7xokgPfg==", "dev": true, "hasInstallScript": true, "license": "Apache-2.0", @@ -13207,27 +13262,28 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-darwin-arm64": "0.34.2", - "@img/sharp-darwin-x64": "0.34.2", - "@img/sharp-libvips-darwin-arm64": "1.1.0", - "@img/sharp-libvips-darwin-x64": "1.1.0", - "@img/sharp-libvips-linux-arm": "1.1.0", - "@img/sharp-libvips-linux-arm64": "1.1.0", - "@img/sharp-libvips-linux-ppc64": "1.1.0", - "@img/sharp-libvips-linux-s390x": "1.1.0", - "@img/sharp-libvips-linux-x64": "1.1.0", - "@img/sharp-libvips-linuxmusl-arm64": "1.1.0", - "@img/sharp-libvips-linuxmusl-x64": "1.1.0", - "@img/sharp-linux-arm": "0.34.2", - "@img/sharp-linux-arm64": "0.34.2", - "@img/sharp-linux-s390x": "0.34.2", - "@img/sharp-linux-x64": "0.34.2", - "@img/sharp-linuxmusl-arm64": "0.34.2", - "@img/sharp-linuxmusl-x64": "0.34.2", - "@img/sharp-wasm32": "0.34.2", - "@img/sharp-win32-arm64": "0.34.2", - "@img/sharp-win32-ia32": "0.34.2", - "@img/sharp-win32-x64": "0.34.2" + "@img/sharp-darwin-arm64": "0.34.3", + "@img/sharp-darwin-x64": "0.34.3", + "@img/sharp-libvips-darwin-arm64": "1.2.0", + "@img/sharp-libvips-darwin-x64": "1.2.0", + "@img/sharp-libvips-linux-arm": "1.2.0", + "@img/sharp-libvips-linux-arm64": "1.2.0", + "@img/sharp-libvips-linux-ppc64": "1.2.0", + "@img/sharp-libvips-linux-s390x": "1.2.0", + "@img/sharp-libvips-linux-x64": "1.2.0", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.0", + "@img/sharp-libvips-linuxmusl-x64": "1.2.0", + "@img/sharp-linux-arm": "0.34.3", + "@img/sharp-linux-arm64": "0.34.3", + "@img/sharp-linux-ppc64": "0.34.3", + "@img/sharp-linux-s390x": "0.34.3", + "@img/sharp-linux-x64": "0.34.3", + "@img/sharp-linuxmusl-arm64": "0.34.3", + "@img/sharp-linuxmusl-x64": "0.34.3", + "@img/sharp-wasm32": "0.34.3", + "@img/sharp-win32-arm64": "0.34.3", + "@img/sharp-win32-ia32": "0.34.3", + "@img/sharp-win32-x64": "0.34.3" } }, "node_modules/shebang-command": { @@ -13777,9 +13833,9 @@ "license": "ISC" }, "node_modules/stylelint": { - "version": "16.21.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.21.0.tgz", - "integrity": "sha512-ki3PpJGG7xhm3WtINoWGnlvqAmbqSexoRMbEMJzlwewSIOqPRKPlq452c22xAdEJISVi80r+I7KL9GPUiwFgbg==", + "version": "16.21.1", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.21.1.tgz", + "integrity": "sha512-WCXdXnYK2tpCbebgMF0Bme3YZH/Rh/UXerj75twYo4uLULlcrLwFVdZTvTEF8idFnAcW21YUDJFyKOfaf6xJRw==", "dev": true, "funding": [ { @@ -13820,7 +13876,7 @@ "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "picocolors": "^1.1.1", - "postcss": "^8.5.5", + "postcss": "^8.5.6", "postcss-resolve-nested-selector": "^0.1.6", "postcss-safe-parser": "^7.0.1", "postcss-selector-parser": "^7.1.0", @@ -13940,15 +13996,15 @@ } }, "node_modules/stylelint/node_modules/flat-cache": { - "version": "6.1.10", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.10.tgz", - "integrity": "sha512-B6/v1f0NwjxzmeOhzfXPGWpKBVA207LS7lehaVKQnFrVktcFRfkzjZZ2gwj2i1TkEUMQht7ZMJbABUT5N+V1Nw==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.11.tgz", + "integrity": "sha512-zfOAns94mp7bHG/vCn9Ru2eDCmIxVQ5dELUHKjHfDEOJmHNzE+uGa6208kfkgmtym4a0FFjEuFksCXFacbVhSg==", "dev": true, "license": "MIT", "dependencies": { - "cacheable": "^1.10.0", + "cacheable": "^1.10.1", "flatted": "^3.3.3", - "hookified": "^1.9.1" + "hookified": "^1.10.0" } }, "node_modules/stylelint/node_modules/ignore": { @@ -13961,6 +14017,35 @@ "node": ">= 4" } }, + "node_modules/stylelint/node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "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.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, "node_modules/stylelint/node_modules/postcss-safe-parser": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.1.tgz", @@ -14834,15 +14919,15 @@ } }, "node_modules/typescript-eslint": { - "version": "8.35.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.35.0.tgz", - "integrity": "sha512-uEnz70b7kBz6eg/j0Czy6K5NivaYopgxRjsnAJ2Fx5oTLo3wefTHIbL7AkQr1+7tJCRVpTs/wiM8JR/11Loq9A==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.35.1.tgz", + "integrity": "sha512-xslJjFzhOmHYQzSB/QTeASAHbjmxOGEP6Coh93TXmUBFQoJ1VU35UHIDmG06Jd6taf3wqqC1ntBnCMeymy5Ovw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.35.0", - "@typescript-eslint/parser": "8.35.0", - "@typescript-eslint/utils": "8.35.0" + "@typescript-eslint/eslint-plugin": "8.35.1", + "@typescript-eslint/parser": "8.35.1", + "@typescript-eslint/utils": "8.35.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -14917,38 +15002,38 @@ } }, "node_modules/unrs-resolver": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.9.2.tgz", - "integrity": "sha512-VUyWiTNQD7itdiMuJy+EuLEErLj3uwX/EpHQF8EOf33Dq3Ju6VW1GXm+swk6+1h7a49uv9fKZ+dft9jU7esdLA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.0.tgz", + "integrity": "sha512-uw3hCGO/RdAEAb4zgJ3C/v6KIAFFOtBoxR86b2Ejc5TnH7HrhTWJR2o0A9ullC3eWMegKQCw/arQ/JivywQzkg==", "dev": true, "hasInstallScript": true, "license": "MIT", "dependencies": { - "napi-postinstall": "^0.2.4" + "napi-postinstall": "^0.3.0" }, "funding": { "url": "https://opencollective.com/unrs-resolver" }, "optionalDependencies": { - "@unrs/resolver-binding-android-arm-eabi": "1.9.2", - "@unrs/resolver-binding-android-arm64": "1.9.2", - "@unrs/resolver-binding-darwin-arm64": "1.9.2", - "@unrs/resolver-binding-darwin-x64": "1.9.2", - "@unrs/resolver-binding-freebsd-x64": "1.9.2", - "@unrs/resolver-binding-linux-arm-gnueabihf": "1.9.2", - "@unrs/resolver-binding-linux-arm-musleabihf": "1.9.2", - "@unrs/resolver-binding-linux-arm64-gnu": "1.9.2", - "@unrs/resolver-binding-linux-arm64-musl": "1.9.2", - "@unrs/resolver-binding-linux-ppc64-gnu": "1.9.2", - "@unrs/resolver-binding-linux-riscv64-gnu": "1.9.2", - "@unrs/resolver-binding-linux-riscv64-musl": "1.9.2", - "@unrs/resolver-binding-linux-s390x-gnu": "1.9.2", - "@unrs/resolver-binding-linux-x64-gnu": "1.9.2", - "@unrs/resolver-binding-linux-x64-musl": "1.9.2", - "@unrs/resolver-binding-wasm32-wasi": "1.9.2", - "@unrs/resolver-binding-win32-arm64-msvc": "1.9.2", - "@unrs/resolver-binding-win32-ia32-msvc": "1.9.2", - "@unrs/resolver-binding-win32-x64-msvc": "1.9.2" + "@unrs/resolver-binding-android-arm-eabi": "1.11.0", + "@unrs/resolver-binding-android-arm64": "1.11.0", + "@unrs/resolver-binding-darwin-arm64": "1.11.0", + "@unrs/resolver-binding-darwin-x64": "1.11.0", + "@unrs/resolver-binding-freebsd-x64": "1.11.0", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.0", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.0", + "@unrs/resolver-binding-linux-arm64-gnu": "1.11.0", + "@unrs/resolver-binding-linux-arm64-musl": "1.11.0", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.0", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.0", + "@unrs/resolver-binding-linux-riscv64-musl": "1.11.0", + "@unrs/resolver-binding-linux-s390x-gnu": "1.11.0", + "@unrs/resolver-binding-linux-x64-gnu": "1.11.0", + "@unrs/resolver-binding-linux-x64-musl": "1.11.0", + "@unrs/resolver-binding-wasm32-wasi": "1.11.0", + "@unrs/resolver-binding-win32-arm64-msvc": "1.11.0", + "@unrs/resolver-binding-win32-ia32-msvc": "1.11.0", + "@unrs/resolver-binding-win32-x64-msvc": "1.11.0" } }, "node_modules/update-browserslist-db": { @@ -15055,9 +15140,9 @@ "license": "MIT" }, "node_modules/vite": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.0.0.tgz", - "integrity": "sha512-ixXJB1YRgDIw2OszKQS9WxGHKwLdCsbQNkpJN171udl6szi/rIySHL6/Os3s2+oE4P/FLD4dxg4mD7Wust+u5g==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.0.2.tgz", + "integrity": "sha512-hxdyZDY1CM6SNpKI4w4lcUc3Mtkd9ej4ECWVHSMrOdSinVc2zYOAppHeGc/hzmRo3pxM5blMzkuWHOJA/3NiFw==", "dev": true, "license": "MIT", "dependencies": { @@ -15130,9 +15215,9 @@ } }, "node_modules/vite-node": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.3.tgz", - "integrity": "sha512-gc8aAifGuDIpZHrPjuHyP4dpQmYXqWw7D1GmDnWeNWP654UEXzVfQ5IHPSK5HaHkwB/+p1atpYpSdw/2kOv8iQ==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", + "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", "dev": true, "license": "MIT", "dependencies": { @@ -15239,9 +15324,9 @@ } }, "node_modules/vite/node_modules/rollup": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.44.1.tgz", - "integrity": "sha512-x8H8aPvD+xbl0Do8oez5f5o8eMS3trfCghc4HhLAnCkj7Vl0d1JWGs0UF/D886zLW2rOj2QymV/JcSSsw+XDNg==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.44.2.tgz", + "integrity": "sha512-PVoapzTwSEcelaWGth3uR66u7ZRo6qhPHc0f2uRO9fX6XDVNrIiGYS0Pj9+R8yIIYSD/mCx2b16Ws9itljKSPg==", "dev": true, "license": "MIT", "dependencies": { @@ -15255,44 +15340,44 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.44.1", - "@rollup/rollup-android-arm64": "4.44.1", - "@rollup/rollup-darwin-arm64": "4.44.1", - "@rollup/rollup-darwin-x64": "4.44.1", - "@rollup/rollup-freebsd-arm64": "4.44.1", - "@rollup/rollup-freebsd-x64": "4.44.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.44.1", - "@rollup/rollup-linux-arm-musleabihf": "4.44.1", - "@rollup/rollup-linux-arm64-gnu": "4.44.1", - "@rollup/rollup-linux-arm64-musl": "4.44.1", - "@rollup/rollup-linux-loongarch64-gnu": "4.44.1", - "@rollup/rollup-linux-powerpc64le-gnu": "4.44.1", - "@rollup/rollup-linux-riscv64-gnu": "4.44.1", - "@rollup/rollup-linux-riscv64-musl": "4.44.1", - "@rollup/rollup-linux-s390x-gnu": "4.44.1", - "@rollup/rollup-linux-x64-gnu": "4.44.1", - "@rollup/rollup-linux-x64-musl": "4.44.1", - "@rollup/rollup-win32-arm64-msvc": "4.44.1", - "@rollup/rollup-win32-ia32-msvc": "4.44.1", - "@rollup/rollup-win32-x64-msvc": "4.44.1", + "@rollup/rollup-android-arm-eabi": "4.44.2", + "@rollup/rollup-android-arm64": "4.44.2", + "@rollup/rollup-darwin-arm64": "4.44.2", + "@rollup/rollup-darwin-x64": "4.44.2", + "@rollup/rollup-freebsd-arm64": "4.44.2", + "@rollup/rollup-freebsd-x64": "4.44.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.44.2", + "@rollup/rollup-linux-arm-musleabihf": "4.44.2", + "@rollup/rollup-linux-arm64-gnu": "4.44.2", + "@rollup/rollup-linux-arm64-musl": "4.44.2", + "@rollup/rollup-linux-loongarch64-gnu": "4.44.2", + "@rollup/rollup-linux-powerpc64le-gnu": "4.44.2", + "@rollup/rollup-linux-riscv64-gnu": "4.44.2", + "@rollup/rollup-linux-riscv64-musl": "4.44.2", + "@rollup/rollup-linux-s390x-gnu": "4.44.2", + "@rollup/rollup-linux-x64-gnu": "4.44.2", + "@rollup/rollup-linux-x64-musl": "4.44.2", + "@rollup/rollup-win32-arm64-msvc": "4.44.2", + "@rollup/rollup-win32-ia32-msvc": "4.44.2", + "@rollup/rollup-win32-x64-msvc": "4.44.2", "fsevents": "~2.3.2" } }, "node_modules/vitest": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.3.tgz", - "integrity": "sha512-E6U2ZFXe3N/t4f5BwUaVCKRLHqUpk1CBWeMh78UT4VaTPH/2dyvH6ALl29JTovEPu9dVKr/K/J4PkXgrMbw4Ww==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz", + "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", "dev": true, "license": "MIT", "dependencies": { "@types/chai": "^5.2.2", - "@vitest/expect": "3.2.3", - "@vitest/mocker": "3.2.3", - "@vitest/pretty-format": "^3.2.3", - "@vitest/runner": "3.2.3", - "@vitest/snapshot": "3.2.3", - "@vitest/spy": "3.2.3", - "@vitest/utils": "3.2.3", + "@vitest/expect": "3.2.4", + "@vitest/mocker": "3.2.4", + "@vitest/pretty-format": "^3.2.4", + "@vitest/runner": "3.2.4", + "@vitest/snapshot": "3.2.4", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", "chai": "^5.2.0", "debug": "^4.4.1", "expect-type": "^1.2.1", @@ -15303,10 +15388,10 @@ "tinybench": "^2.9.0", "tinyexec": "^0.3.2", "tinyglobby": "^0.2.14", - "tinypool": "^1.1.0", + "tinypool": "^1.1.1", "tinyrainbow": "^2.0.0", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", - "vite-node": "3.2.3", + "vite-node": "3.2.4", "why-is-node-running": "^2.3.0" }, "bin": { @@ -15322,8 +15407,8 @@ "@edge-runtime/vm": "*", "@types/debug": "^4.1.12", "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "@vitest/browser": "3.2.3", - "@vitest/ui": "3.2.3", + "@vitest/browser": "3.2.4", + "@vitest/ui": "3.2.4", "happy-dom": "*", "jsdom": "*" }, @@ -15462,16 +15547,16 @@ } }, "node_modules/vue-component-type-helpers": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/vue-component-type-helpers/-/vue-component-type-helpers-2.2.10.tgz", - "integrity": "sha512-iDUO7uQK+Sab2tYuiP9D1oLujCWlhHELHMgV/cB13cuGbG4qwkLHvtfWb6FzvxrIOPDnU0oHsz2MlQjhYDeaHA==", + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/vue-component-type-helpers/-/vue-component-type-helpers-2.2.12.tgz", + "integrity": "sha512-YbGqHZ5/eW4SnkPNR44mKVc6ZKQoRs/Rux1sxC6rdwXb4qpbOSYfDr9DsTHolOTGmIKgM9j141mZbBeg05R1pw==", "dev": true, "license": "MIT" }, "node_modules/vue-eslint-parser": { - "version": "10.1.4", - "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-10.1.4.tgz", - "integrity": "sha512-EIZvCukIEMHEb3mxOKemtvWR1fcUAdWWAgkfyjmRHzvyhrZvBvH9oz69+thDIWhGiIQjZnPkCn8yHqvjM+a9eg==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-10.2.0.tgz", + "integrity": "sha512-CydUvFOQKD928UzZhTp4pr2vWz1L+H99t7Pkln2QSPdvmURT0MoC4wUccfCnuEaihNsu9aYYyk+bep8rlfkUXw==", "dev": true, "license": "MIT", "peer": true, @@ -15481,7 +15566,6 @@ "eslint-visitor-keys": "^4.2.0", "espree": "^10.3.0", "esquery": "^1.6.0", - "lodash": "^4.17.21", "semver": "^7.6.3" }, "engines": { @@ -15549,21 +15633,22 @@ "license": "BSD-2-Clause" }, "node_modules/webpack": { - "version": "5.99.9", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.9.tgz", - "integrity": "sha512-brOPwM3JnmOa+7kd3NsmOUOwbDAj8FT9xDsG3IW0MgbN9yZV7Oi/s/+MNQ/EcSMqw7qfoRyXPoeEWT8zLVdVGg==", + "version": "5.100.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.100.0.tgz", + "integrity": "sha512-H8yBSBTk+BqxrINJnnRzaxU94SVP2bjd7WmA+PfCphoIdDpeQMJ77pq9/4I7xjLq38cB1bNKfzYPZu8pB3zKtg==", "license": "MIT", "dependencies": { "@types/eslint-scope": "^3.7.7", - "@types/estree": "^1.0.6", + "@types/estree": "^1.0.8", "@types/json-schema": "^7.0.15", "@webassemblyjs/ast": "^1.14.1", "@webassemblyjs/wasm-edit": "^1.14.1", "@webassemblyjs/wasm-parser": "^1.14.1", - "acorn": "^8.14.0", + "acorn": "^8.15.0", + "acorn-import-phases": "^1.0.3", "browserslist": "^4.24.0", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.1", + "enhanced-resolve": "^5.17.2", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", @@ -15577,7 +15662,7 @@ "tapable": "^2.1.1", "terser-webpack-plugin": "^5.3.11", "watchpack": "^2.4.1", - "webpack-sources": "^3.2.3" + "webpack-sources": "^3.3.3" }, "bin": { "webpack": "bin/webpack.js" diff --git a/package.json b/package.json index 88f904c44b..c154270c6c 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "idiomorph": "0.3.0", "jquery": "3.7.1", "katex": "0.16.22", - "mermaid": "11.7.0", + "mermaid": "11.8.1", "mini-css-extract-plugin": "2.9.2", "minimatch": "10.0.3", "monaco-editor": "0.52.2", @@ -55,22 +55,22 @@ "vue-chartjs": "5.3.1", "vue-loader": "17.4.2", "vue3-calendar-heatmap": "2.0.5", - "webpack": "5.99.9", + "webpack": "5.100.0", "webpack-cli": "6.0.1", "wrap-ansi": "9.0.0" }, "devDependencies": { "@axe-core/playwright": "4.10.2", "@eslint-community/eslint-plugin-eslint-comments": "4.5.0", - "@playwright/test": "1.52.0", + "@playwright/test": "1.53.2", "@stoplight/spectral-cli": "6.15.0", - "@stylistic/eslint-plugin": "5.0.0", + "@stylistic/eslint-plugin": "5.1.0", "@stylistic/stylelint-plugin": "3.1.3", "@vitejs/plugin-vue": "6.0.0", - "@vitest/coverage-v8": "3.2.3", - "@vitest/eslint-plugin": "1.2.2", + "@vitest/coverage-v8": "3.2.4", + "@vitest/eslint-plugin": "1.3.4", "@vue/test-utils": "2.4.6", - "eslint": "9.30.0", + "eslint": "9.30.1", "eslint-import-resolver-typescript": "4.4.4", "eslint-plugin-array-func": "5.0.2", "eslint-plugin-import-x": "4.16.1", @@ -82,24 +82,24 @@ "eslint-plugin-toml": "0.12.0", "eslint-plugin-unicorn": "59.0.1", "eslint-plugin-vitest-globals": "1.5.0", - "eslint-plugin-vue": "10.2.0", - "eslint-plugin-vue-scoped-css": "2.10.0", + "eslint-plugin-vue": "10.3.0", + "eslint-plugin-vue-scoped-css": "2.11.0", "eslint-plugin-wc": "3.0.1", - "globals": "16.1.0", + "globals": "16.3.0", "happy-dom": "18.0.1", "license-checker-rseidelsohn": "4.4.2", "markdownlint-cli": "0.45.0", "postcss-html": "1.8.0", - "sharp": "0.34.2", - "stylelint": "16.21.0", + "sharp": "0.34.3", + "stylelint": "16.21.1", "stylelint-declaration-block-no-ignored-properties": "2.8.0", "stylelint-declaration-strict-value": "1.10.11", "stylelint-value-no-unknown-custom-properties": "6.0.1", "svgo": "4.0.0", "typescript": "5.8.3", - "typescript-eslint": "8.35.0", + "typescript-eslint": "8.35.1", "vite-string-plugin": "1.3.4", - "vitest": "3.2.3" + "vitest": "3.2.4" }, "browserslist": [ "defaults" diff --git a/release-notes-published/11.0.3.md b/release-notes-published/11.0.3.md new file mode 100644 index 0000000000..ed6f150af9 --- /dev/null +++ b/release-notes-published/11.0.3.md @@ -0,0 +1,34 @@ +## Git update fixing CVE-2025-48385 + +Git vulnerabilities were [disclosed 8 July 2025](https://groups.google.com/g/git-packagers/c/cYJ6peBtyxk/m/xVukiATcBQAJ) and require an update of the Git version used by Forgejo to Git [v2.43.7, v2.44.4, v2.45.4, v2.46.4, v2.47.3, v2.48.2, v2.49.1, or v2.50.1](https://nvd.nist.gov/vuln/detail/CVE-2025-48385). The [containers of this release](https://codeberg.org/forgejo/-/packages/container/forgejo/11.0.3) include a Git binary that is not vulnerable. If Forgejo was installed using a container, it is enough to upgrade the container to get the latest Git binary. + +Security bug fixes are only for Git, there are no security fixes for Forgejo itself in this release. + +## Wiki permissions manual steps + +If collaborators with write access can't edit the wiki, an administrator can now go to the Units settings (`//settings/units#wiki`) and Save the wiki settings (no change is needed) to fix the problem. This is a manual step that will trigger a database update that is currently not possible to automate for Forgejo stable releases. + + + +## Release notes + +- User Interface bug fixes + - [PR](https://codeberg.org/forgejo/forgejo/pulls/8246) ([backported](https://codeberg.org/forgejo/forgejo/pulls/8283)): fix(ui): add missing lazy load attribute to images (#8246) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/8170) ([backported](https://codeberg.org/forgejo/forgejo/pulls/8262)): fix(ui): erroneous list continuation on Cmd+Enter on macOS +- Localization + - [PR](https://codeberg.org/forgejo/forgejo/pulls/8300): i18n: backport of translation updates +- Bug fixes + - [PR](https://codeberg.org/forgejo/forgejo/pulls/8189) ([backported](https://codeberg.org/forgejo/forgejo/pulls/8456)): fix: do not ignore automerge while a PR is checking for conflicts + - [PR](https://codeberg.org/forgejo/forgejo/pulls/8367) ([backported](https://codeberg.org/forgejo/forgejo/pulls/8385)): fix: user activation with uppercase email address + - [PR](https://codeberg.org/forgejo/forgejo/pulls/8234) ([backported](https://codeberg.org/forgejo/forgejo/pulls/8237)): fix: collaborator can edit wiki with write access +- Included for completeness but not worth a release note + - [PR](https://codeberg.org/forgejo/forgejo/pulls/8460) ([backported](https://codeberg.org/forgejo/forgejo/pulls/8465)): chore: disable mismatched root URL e2e test for safari + - [PR](https://codeberg.org/forgejo/forgejo/pulls/8461) ([backported](https://codeberg.org/forgejo/forgejo/pulls/8462)): chore: do not navigate to same URL in E2E test + - [PR](https://codeberg.org/forgejo/forgejo/pulls/8258) ([backported](https://codeberg.org/forgejo/forgejo/pulls/8445)): fix: corrupted wiki unit default permission (#8234 follow-up) (#8258) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/8261) ([backported](https://codeberg.org/forgejo/forgejo/pulls/8412)): fix: skip empty tokens in SearchOptions.Tokens() + - [PR](https://codeberg.org/forgejo/forgejo/pulls/8400) ([backported](https://codeberg.org/forgejo/forgejo/pulls/8401)): chore: improve reliability of webauthn e2e test + - [PR](https://codeberg.org/forgejo/forgejo/pulls/8326) ([backported](https://codeberg.org/forgejo/forgejo/pulls/8333)): fix: make API /repos/{owner}/{repo}/compare/{basehead} work with forks + - [PR](https://codeberg.org/forgejo/forgejo/pulls/8226) ([backported](https://codeberg.org/forgejo/forgejo/pulls/8292)): chore: sort mailer messages in test assertion + - [PR](https://codeberg.org/forgejo/forgejo/pulls/8002) ([backported](https://codeberg.org/forgejo/forgejo/pulls/8289)): fix(ui): release: name is overridden with tag name on edit + - [PR](https://codeberg.org/forgejo/forgejo/pulls/8286) ([backported](https://codeberg.org/forgejo/forgejo/pulls/8287)): Revert "fix(api): document `is_system_webhook` field (#7784)" + diff --git a/release-notes-published/7.0.16.md b/release-notes-published/7.0.16.md new file mode 100644 index 0000000000..5d09ddc245 --- /dev/null +++ b/release-notes-published/7.0.16.md @@ -0,0 +1,11 @@ +## Git update fixing CVE-2025-48385 + +Git vulnerabilities were [disclosed 8 July 2025](https://groups.google.com/g/git-packagers/c/cYJ6peBtyxk/m/xVukiATcBQAJ) and require an update of the Git version used by Forgejo to Git [v2.43.7, v2.44.4, v2.45.4, v2.46.4, v2.47.3, v2.48.2, v2.49.1, or v2.50.1](https://nvd.nist.gov/vuln/detail/CVE-2025-48385). The [containers of this release](https://codeberg.org/forgejo/-/packages/container/forgejo/7.0.16) include a Git binary that is not vulnerable. If Forgejo was installed using a container, it is enough to upgrade the container to get the latest Git binary. + +Security bug fixes are only for Git, there are no security fixes for Forgejo itself in this release. + + + +## Release notes + + diff --git a/routers/api/packages/api.go b/routers/api/packages/api.go index 79e61cf352..c53edfbf96 100644 --- a/routers/api/packages/api.go +++ b/routers/api/packages/api.go @@ -631,7 +631,7 @@ func CommonRoutes() *web.Route { 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`) + 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) { diff --git a/routers/api/v1/activitypub/actor.go b/routers/api/v1/activitypub/actor.go index e49f277842..0ff822c7f4 100644 --- a/routers/api/v1/activitypub/actor.go +++ b/routers/api/v1/activitypub/actor.go @@ -32,7 +32,7 @@ func Actor(ctx *context.APIContext) { actor := ap.ActorNew(ap.IRI(link), ap.ApplicationType) actor.PreferredUsername = ap.NaturalLanguageValuesNew() - err := actor.PreferredUsername.Set("en", ap.Content(setting.Domain)) + err := actor.PreferredUsername.Set("en", ap.Content("ghost")) if err != nil { ctx.ServerError("PreferredUsername.Set", err) return @@ -41,8 +41,6 @@ func Actor(ctx *context.APIContext) { 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) diff --git a/routers/api/v1/activitypub/reqsignature.go b/routers/api/v1/activitypub/reqsignature.go index b84fbe05fa..91274249ec 100644 --- a/routers/api/v1/activitypub/reqsignature.go +++ b/routers/api/v1/activitypub/reqsignature.go @@ -4,132 +4,17 @@ package activitypub import ( - "crypto" - "crypto/x509" - "database/sql" - "encoding/pem" - "errors" - "fmt" "net/http" - "net/url" - "forgejo.org/models/db" - "forgejo.org/models/forgefed" - "forgejo.org/models/user" - "forgejo.org/modules/activitypub" - fm "forgejo.org/modules/forgefed" "forgejo.org/modules/log" "forgejo.org/modules/setting" gitea_context "forgejo.org/services/context" "forgejo.org/services/federation" "github.com/42wim/httpsig" - ap "github.com/go-ap/activitypub" ) -func decodePublicKeyPem(pubKeyPem string) ([]byte, error) { - block, _ := pem.Decode([]byte(pubKeyPem)) - if block == nil || block.Type != "PUBLIC KEY" { - return nil, errors.New("could not decode publicKeyPem to PUBLIC KEY pem block type") - } - - return block.Bytes, nil -} - -func getFederatedUser(ctx *gitea_context.APIContext, person *ap.Person, federationHost *forgefed.FederationHost) (*user.FederatedUser, error) { - personID, err := fm.NewPersonID(person.ID.String(), string(federationHost.NodeInfo.SoftwareName)) - if err != nil { - return nil, err - } - _, federatedUser, err := user.FindFederatedUser(ctx, personID.ID, federationHost.ID) - if err != nil { - return nil, err - } - - if federatedUser != nil { - return federatedUser, nil - } - - _, newFederatedUser, err := federation.CreateUserFromAP(ctx, personID, federationHost.ID) - if err != nil { - return nil, err - } - - return newFederatedUser, nil -} - -func storePublicKey(ctx *gitea_context.APIContext, person *ap.Person, pubKeyBytes []byte) error { - federationHost, err := federation.GetFederationHostForURI(ctx, person.ID.String()) - if err != nil { - return err - } - - if person.Type == ap.ActivityVocabularyType("Application") { - federationHost.KeyID = sql.NullString{ - String: person.PublicKey.ID.String(), - Valid: true, - } - - federationHost.PublicKey = sql.Null[sql.RawBytes]{ - V: pubKeyBytes, - Valid: true, - } - - _, err = db.GetEngine(ctx).ID(federationHost.ID).Update(federationHost) - if err != nil { - return err - } - } else if person.Type == ap.ActivityVocabularyType("Person") { - federatedUser, err := getFederatedUser(ctx, person, federationHost) - if err != nil { - return err - } - - federatedUser.KeyID = sql.NullString{ - String: person.PublicKey.ID.String(), - Valid: true, - } - - federatedUser.PublicKey = sql.Null[sql.RawBytes]{ - V: pubKeyBytes, - Valid: true, - } - - _, err = db.GetEngine(ctx).ID(federatedUser.ID).Update(federatedUser) - if err != nil { - return err - } - } - - return nil -} - -func getPublicKeyFromResponse(b []byte, keyID *url.URL) (person *ap.Person, pubKeyBytes []byte, p crypto.PublicKey, err error) { - person = ap.PersonNew(ap.IRI(keyID.String())) - err = person.UnmarshalJSON(b) - if err != nil { - return nil, nil, nil, fmt.Errorf("ActivityStreams type cannot be converted to one known to have publicKey property: %w", err) - } - - pubKey := person.PublicKey - if pubKey.ID.String() != keyID.String() { - return nil, nil, nil, fmt.Errorf("cannot find publicKey with id: %s in %s", keyID, string(b)) - } - - pubKeyBytes, err = decodePublicKeyPem(pubKey.PublicKeyPem) - if err != nil { - return nil, nil, nil, err - } - - p, err = x509.ParsePKIXPublicKey(pubKeyBytes) - if err != nil { - return nil, nil, nil, err - } - - return person, pubKeyBytes, p, err -} - -func verifyHTTPSignatures(ctx *gitea_context.APIContext) (authenticated bool, err error) { +func verifyHTTPUserOrInstanceSignature(ctx *gitea_context.APIContext) (authenticated bool, err error) { if !setting.Federation.SignatureEnforced { return true, nil } @@ -142,84 +27,64 @@ func verifyHTTPSignatures(ctx *gitea_context.APIContext) (authenticated bool, er return false, err } - ID := v.KeyId() - idIRI, err := url.Parse(ID) + signatureAlgorithm := httpsig.Algorithm(setting.Federation.SignatureAlgorithms[0]) + pubKey, err := federation.FindOrCreateFederatedUserKey(ctx.Base, v.KeyId()) + if err != nil || pubKey == nil { + pubKey, err = federation.FindOrCreateFederationHostKey(ctx.Base, v.KeyId()) + if err != nil { + return false, err + } + } + + err = v.Verify(pubKey, signatureAlgorithm) + if err != nil { + return false, err + } + return true, nil +} + +func verifyHTTPUserSignature(ctx *gitea_context.APIContext) (authenticated bool, err error) { + if !setting.Federation.SignatureEnforced { + return true, nil + } + + r := ctx.Req + + // 1. Figure out what key we need to verify + v, err := httpsig.NewVerifier(r) if err != nil { return false, err } signatureAlgorithm := httpsig.Algorithm(setting.Federation.SignatureAlgorithms[0]) - - // 2. Fetch the public key of the other actor - // Try if the signing actor is an already known federated user - _, federationUser, err := user.FindFederatedUserByKeyID(ctx, idIRI.String()) + pubKey, err := federation.FindOrCreateFederatedUserKey(ctx.Base, v.KeyId()) if err != nil { return false, err } - if federationUser != nil && federationUser.PublicKey.Valid { - pubKey, err := x509.ParsePKIXPublicKey(federationUser.PublicKey.V) - if err != nil { - return false, err - } - - authenticated = v.Verify(pubKey, signatureAlgorithm) == nil - return authenticated, err - } - - // Try if the signing actor is an already known federation host - federationHost, err := forgefed.FindFederationHostByKeyID(ctx, idIRI.String()) + err = v.Verify(pubKey, signatureAlgorithm) if err != nil { return false, err } - - if federationHost != nil && federationHost.PublicKey.Valid { - pubKey, err := x509.ParsePKIXPublicKey(federationHost.PublicKey.V) - if err != nil { - return false, err - } - - authenticated = v.Verify(pubKey, signatureAlgorithm) == nil - return authenticated, err - } - - // Fetch missing public key - actionsUser := user.NewAPServerActor() - clientFactory, err := activitypub.GetClientFactory(ctx) - if err != nil { - return false, err - } - - apClient, err := clientFactory.WithKeys(ctx, actionsUser, actionsUser.APActorKeyID()) - if err != nil { - return false, err - } - - b, err := apClient.GetBody(idIRI.String()) - if err != nil { - return false, err - } - - person, pubKeyBytes, pubKey, err := getPublicKeyFromResponse(b, idIRI) - if err != nil { - return false, err - } - - authenticated = v.Verify(pubKey, signatureAlgorithm) == nil - if authenticated { - err = storePublicKey(ctx, person, pubKeyBytes) - if err != nil { - return false, err - } - } - - return authenticated, err + return true, nil } // ReqHTTPSignature function -func ReqHTTPSignature() func(ctx *gitea_context.APIContext) { +func ReqHTTPUserOrInstanceSignature() func(ctx *gitea_context.APIContext) { return func(ctx *gitea_context.APIContext) { - if authenticated, err := verifyHTTPSignatures(ctx); err != nil { + if authenticated, err := verifyHTTPUserOrInstanceSignature(ctx); err != nil { + log.Warn("verifyHttpSignatures failed: %v", err) + ctx.Error(http.StatusBadRequest, "reqSignature", "request signature verification failed") + } else if !authenticated { + ctx.Error(http.StatusForbidden, "reqSignature", "request signature verification failed") + } + } +} + +// ReqHTTPSignature function +func ReqHTTPUserSignature() func(ctx *gitea_context.APIContext) { + return func(ctx *gitea_context.APIContext) { + if authenticated, err := verifyHTTPUserSignature(ctx); err != nil { log.Warn("verifyHttpSignatures failed: %v", err) ctx.Error(http.StatusBadRequest, "reqSignature", "request signature verification failed") } else if !authenticated { diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index bf08bdd249..3b66d02fba 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -92,6 +92,7 @@ import ( _ "forgejo.org/routers/api/v1/swagger" // for swagger generation "code.forgejo.org/go-chi/binding" + ap "github.com/go-ap/activitypub" ) func sudo() func(ctx *context.APIContext) { @@ -826,24 +827,22 @@ func Routes() *web.Route { if setting.Federation.Enabled { m.Get("/nodeinfo", misc.NodeInfo) m.Group("/activitypub", func() { - // deprecated, remove in 1.20, use /user-id/{user-id} instead - m.Group("/user/{username}", func() { - m.Get("", activitypub.ReqHTTPSignature(), activitypub.Person) - m.Post("/inbox", activitypub.ReqHTTPSignature(), activitypub.PersonInbox) - }, context.UserAssignmentAPI(), checkTokenPublicOnly()) m.Group("/user-id/{user-id}", func() { - m.Get("", activitypub.ReqHTTPSignature(), activitypub.Person) - m.Post("/inbox", activitypub.ReqHTTPSignature(), activitypub.PersonInbox) + m.Get("", activitypub.ReqHTTPUserOrInstanceSignature(), activitypub.Person) + m.Post("/inbox", + activitypub.ReqHTTPUserSignature(), + bind(ap.Activity{}), + activitypub.PersonInbox) }, context.UserIDAssignmentAPI(), checkTokenPublicOnly()) m.Group("/actor", func() { m.Get("", activitypub.Actor) - m.Post("/inbox", activitypub.ReqHTTPSignature(), activitypub.ActorInbox) + m.Post("/inbox", activitypub.ReqHTTPUserOrInstanceSignature(), activitypub.ActorInbox) }) m.Group("/repository-id/{repository-id}", func() { - m.Get("", activitypub.ReqHTTPSignature(), activitypub.Repository) + m.Get("", activitypub.ReqHTTPUserSignature(), activitypub.Repository) m.Post("/inbox", bind(forgefed.ForgeLike{}), - activitypub.ReqHTTPSignature(), + activitypub.ReqHTTPUserSignature(), activitypub.RepositoryInbox) }, context.RepositoryIDAssignmentAPI()) }, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryActivityPub)) @@ -1178,7 +1177,7 @@ func Routes() *web.Route { }) m.Group("/workflows", func() { - m.Group("/{workflowname}", func() { + m.Group("/{workflowfilename}", func() { m.Post("/dispatches", reqToken(), reqRepoWriter(unit.TypeActions), mustNotBeArchived, bind(api.DispatchWorkflowOption{}), repo.DispatchWorkflow) }) }) diff --git a/routers/api/v1/repo/action.go b/routers/api/v1/repo/action.go index dbc4933de6..fe29d534ff 100644 --- a/routers/api/v1/repo/action.go +++ b/routers/api/v1/repo/action.go @@ -615,7 +615,7 @@ func ListActionTasks(ctx *context.APIContext) { // DispatchWorkflow dispatches a workflow func DispatchWorkflow(ctx *context.APIContext) { - // swagger:operation POST /repos/{owner}/{repo}/actions/workflows/{workflowname}/dispatches repository DispatchWorkflow + // swagger:operation POST /repos/{owner}/{repo}/actions/workflows/{workflowfilename}/dispatches repository DispatchWorkflow // --- // summary: Dispatches a workflow // consumes: @@ -631,7 +631,7 @@ func DispatchWorkflow(ctx *context.APIContext) { // description: name of the repo // type: string // required: true - // - name: workflowname + // - name: workflowfilename // in: path // description: name of the workflow // type: string @@ -649,13 +649,13 @@ func DispatchWorkflow(ctx *context.APIContext) { // "$ref": "#/responses/notFound" opt := web.GetForm(ctx).(*api.DispatchWorkflowOption) - name := ctx.Params("workflowname") + name := ctx.Params("workflowfilename") if len(opt.Ref) == 0 { ctx.Error(http.StatusBadRequest, "ref", "ref is empty") return } else if len(name) == 0 { - ctx.Error(http.StatusBadRequest, "workflowname", "workflow name is empty") + ctx.Error(http.StatusBadRequest, "workflowfilename", "workflow file name is empty") return } diff --git a/routers/api/v1/repo/branch.go b/routers/api/v1/repo/branch.go index 7c9593d625..e043448590 100644 --- a/routers/api/v1/repo/branch.go +++ b/routers/api/v1/repo/branch.go @@ -594,7 +594,7 @@ func CreateBranchProtection(ctx *context.APIContext) { isPlainRule := !git_model.IsRuleNameSpecial(ruleName) var isBranchExist bool if isPlainRule { - isBranchExist = git.IsBranchExist(ctx.Req.Context(), ctx.Repo.Repository.RepoPath(), ruleName) + isBranchExist = ctx.Repo.GitRepo.IsBranchExist(ruleName) } protectBranch, err := git_model.GetProtectedBranchRuleByName(ctx, repo.ID, ruleName) @@ -982,7 +982,7 @@ func EditBranchProtection(ctx *context.APIContext) { isPlainRule := !git_model.IsRuleNameSpecial(bpName) var isBranchExist bool if isPlainRule { - isBranchExist = git.IsBranchExist(ctx.Req.Context(), ctx.Repo.Repository.RepoPath(), bpName) + isBranchExist = ctx.Repo.GitRepo.IsBranchExist(bpName) } if isBranchExist { diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index 3d6a40e9ab..42385d54a6 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -861,7 +861,7 @@ func updateRepoUnits(ctx *context.APIContext, owner string, repo *repo_model.Rep if *opts.GloballyEditableWiki { wikiPermissions = repo_model.UnitAccessModeWrite } else { - wikiPermissions = repo_model.UnitAccessModeRead + wikiPermissions = repo_model.UnitAccessModeUnset } } diff --git a/routers/private/manager.go b/routers/private/manager.go index 7ab198f71b..90b48256df 100644 --- a/routers/private/manager.go +++ b/routers/private/manager.go @@ -145,6 +145,7 @@ func AddLogger(ctx *context.PrivateContext) { writerMode.Prefix, _ = opts.Config["prefix"].(string) writerMode.Expression, _ = opts.Config["expression"].(string) + writerMode.Exclusion, _ = opts.Config["exclusion"].(string) switch writerType { case "console": diff --git a/routers/web/auth/oauth.go b/routers/web/auth/oauth.go index e8e5d2c54b..f287e0e900 100644 --- a/routers/web/auth/oauth.go +++ b/routers/web/auth/oauth.go @@ -668,6 +668,11 @@ func GrantApplicationOAuth(ctx *context.Context) { // OIDCWellKnown generates JSON so OIDC clients know Gitea's capabilities func OIDCWellKnown(ctx *context.Context) { + if !setting.OAuth2.Enabled { + ctx.Status(http.StatusNotFound) + return + } + ctx.Data["SigningKey"] = oauth2.DefaultSigningKey ctx.Data["Issuer"] = strings.TrimSuffix(setting.AppURL, "/") ctx.JSONTemplate("user/auth/oidc_wellknown") diff --git a/routers/web/repo/editor.go b/routers/web/repo/editor.go index d40a02ad0e..ccbb3ac2eb 100644 --- a/routers/web/repo/editor.go +++ b/routers/web/repo/editor.go @@ -189,7 +189,7 @@ func editFile(ctx *context.Context, isNewFile bool) { buf = buf[:n] // Only some file types are editable online as text. - if !typesniffer.DetectContentType(buf).IsRepresentableAsText() { + if !typesniffer.DetectContentType(buf, blob.Name()).IsRepresentableAsText() { ctx.NotFound("typesniffer.IsRepresentableAsText", nil) return } diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index a34e3b7c78..a4f6f97a05 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -3593,9 +3593,9 @@ func GetIssueAttachments(ctx *context.Context) { if ctx.Written() { return } - attachments := make([]*api.Attachment, len(issue.Attachments)) + attachments := make([]*api.WebAttachment, len(issue.Attachments)) for i := 0; i < len(issue.Attachments); i++ { - attachments[i] = convert.ToAttachment(ctx.Repo.Repository, issue.Attachments[i]) + attachments[i] = convert.ToWebAttachment(ctx.Repo.Repository, issue.Attachments[i]) } ctx.JSON(http.StatusOK, attachments) } @@ -3628,13 +3628,13 @@ func GetCommentAttachments(ctx *context.Context) { return } - attachments := make([]*api.Attachment, 0) if err := comment.LoadAttachments(ctx); err != nil { ctx.ServerError("LoadAttachments", err) return } + attachments := make([]*api.WebAttachment, len(comment.Attachments)) for i := 0; i < len(comment.Attachments); i++ { - attachments = append(attachments, convert.ToAttachment(ctx.Repo.Repository, comment.Attachments[i])) + attachments[i] = convert.ToWebAttachment(ctx.Repo.Repository, comment.Attachments[i]) } ctx.JSON(http.StatusOK, attachments) } diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index 4e365f24ea..c9a2bb4e08 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -638,7 +638,7 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C if pull.Flow == issues_model.PullRequestFlowGithub { headBranchExist = headGitRepo.IsBranchExist(pull.HeadBranch) } else { - headBranchExist = git.IsReferenceExist(ctx, baseGitRepo.Path, pull.GetGitRefName()) + headBranchExist = baseGitRepo.IsReferenceExist(pull.GetGitRefName()) } if headBranchExist { diff --git a/routers/web/repo/render.go b/routers/web/repo/render.go index b31e2e203a..05eeadc519 100644 --- a/routers/web/repo/render.go +++ b/routers/web/repo/render.go @@ -41,7 +41,7 @@ func RenderFile(ctx *context.Context) { n, _ := util.ReadAtMost(dataRc, buf) buf = buf[:n] - st := typesniffer.DetectContentType(buf) + st := typesniffer.DetectContentType(buf, blob.Name()) isTextFile := st.IsText() rd := charset.ToUTF8WithFallbackReader(io.MultiReader(bytes.NewReader(buf), dataRc), charset.ConvertOpts{}) diff --git a/routers/web/repo/setting/avatar.go b/routers/web/repo/setting/avatar.go index 84d7cccdb8..20e211316d 100644 --- a/routers/web/repo/setting/avatar.go +++ b/routers/web/repo/setting/avatar.go @@ -45,7 +45,7 @@ func UpdateAvatarSetting(ctx *context.Context, form forms.AvatarForm) error { if err != nil { return fmt.Errorf("io.ReadAll: %w", err) } - st := typesniffer.DetectContentType(data) + st := typesniffer.DetectContentType(data, "") if !st.IsImage() || st.IsSvgImage() { return errors.New(ctx.Locale.TrString("settings.uploaded_avatar_not_a_image")) } diff --git a/routers/web/repo/setting/lfs.go b/routers/web/repo/setting/lfs.go index b9cb86bd08..9930d03e8e 100644 --- a/routers/web/repo/setting/lfs.go +++ b/routers/web/repo/setting/lfs.go @@ -291,7 +291,7 @@ func LFSFileGet(ctx *context.Context) { } buf = buf[:n] - st := typesniffer.DetectContentType(buf) + st := typesniffer.DetectContentType(buf, "") ctx.Data["IsTextFile"] = st.IsText() isRepresentableAsText := st.IsRepresentableAsText() diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go index bb3e1388a8..d00f85a134 100644 --- a/routers/web/repo/view.go +++ b/routers/web/repo/view.go @@ -228,7 +228,7 @@ func getFileReader(ctx gocontext.Context, repoID int64, blob *git.Blob) ([]byte, n, _ := util.ReadAtMost(dataRc, buf) buf = buf[:n] - st := typesniffer.DetectContentType(buf) + st := typesniffer.DetectContentType(buf, blob.Name()) isTextFile := st.IsText() // FIXME: what happens when README file is an image? @@ -262,7 +262,7 @@ func getFileReader(ctx gocontext.Context, repoID int64, blob *git.Blob) ([]byte, } buf = buf[:n] - st = typesniffer.DetectContentType(buf) + st = typesniffer.DetectContentType(buf, blob.Name()) return buf, dataRc, &fileInfo{st.IsText(), true, meta.Size, &meta.Pointer, st}, nil } diff --git a/routers/web/user/setting/profile.go b/routers/web/user/setting/profile.go index 400ee71f08..e0ce88b582 100644 --- a/routers/web/user/setting/profile.go +++ b/routers/web/user/setting/profile.go @@ -151,7 +151,7 @@ func UpdateAvatarSetting(ctx *context.Context, form *forms.AvatarForm, ctxUser * return fmt.Errorf("io.ReadAll: %w", err) } - st := typesniffer.DetectContentType(data) + st := typesniffer.DetectContentType(data, "") if !st.IsImage() || st.IsSvgImage() { return errors.New(ctx.Locale.TrString("settings.uploaded_avatar_not_a_image")) } diff --git a/routers/web/webfinger.go b/routers/web/webfinger.go index be3c2925fe..372c08f7d8 100644 --- a/routers/web/webfinger.go +++ b/routers/web/webfinger.go @@ -58,7 +58,33 @@ func WebfingerQuery(ctx *context.Context) { return } + // Instance actor + if parts[0] == "ghost" { + aliases := []string{ + appURL.String() + "api/v1/activitypub/actor", + } + + links := []*webfingerLink{ + { + Rel: "self", + Type: "application/activity+json", + Href: appURL.String() + "api/v1/activitypub/actor", + }, + } + + ctx.Resp.Header().Add("Access-Control-Allow-Origin", "*") + ctx.JSON(http.StatusOK, &webfingerJRD{ + Subject: fmt.Sprintf("acct:%s@%s", "ghost", appURL.Host), + Aliases: aliases, + Links: links, + }) + ctx.Resp.Header().Set("Content-Type", "application/jrd+json") + + return + } + u, err = user_model.GetUserByName(ctx, parts[0]) + case "mailto": u, err = user_model.GetUserByEmail(ctx, resource.Opaque) if u != nil && u.KeepEmailPrivate { diff --git a/services/actions/notifier.go b/services/actions/notifier.go index f1e9a6d7e9..a5bac730be 100644 --- a/services/actions/notifier.go +++ b/services/actions/notifier.go @@ -788,7 +788,7 @@ func (n *actionsNotifier) MigrateRepository(ctx context.Context, doer, u *user_m // the ActionRun of the same workflow that finished before priorRun/updatedRun. func sendActionRunNowDoneNotificationIfNeeded(ctx context.Context, priorRun, updatedRun *actions_model.ActionRun) error { if !priorRun.Status.IsDone() && updatedRun.Status.IsDone() { - lastRun, err := actions_model.GetRunBefore(ctx, updatedRun.RepoID, updatedRun.Stopped) + lastRun, err := actions_model.GetRunBefore(ctx, updatedRun) if err != nil && !errors.Is(err, util.ErrNotExist) { return err } diff --git a/services/agit/agit.go b/services/agit/agit.go index 20e87642c3..8ef641629a 100644 --- a/services/agit/agit.go +++ b/services/agit/agit.go @@ -221,7 +221,7 @@ func ProcReceive(ctx context.Context, repo *repo_model.Repository, gitRepo *git. } // Validate pull request. - pull_service.ValidatePullRequest(ctx, pr, oldCommitID, opts.NewCommitIDs[i], pusher) + pull_service.ValidatePullRequest(ctx, pr, opts.NewCommitIDs[i], oldCommitID, pusher) // TODO: call `InvalidateCodeComments` diff --git a/services/auth/oauth2.go b/services/auth/oauth2.go index 093940aa18..4fdd15d7ec 100644 --- a/services/auth/oauth2.go +++ b/services/auth/oauth2.go @@ -17,6 +17,7 @@ import ( "forgejo.org/modules/log" "forgejo.org/modules/setting" "forgejo.org/modules/timeutil" + "forgejo.org/modules/util" "forgejo.org/modules/web/middleware" "forgejo.org/services/actions" "forgejo.org/services/auth/source/oauth2" @@ -125,7 +126,7 @@ func parseToken(req *http.Request) (string, bool) { // check header token if auHead := req.Header.Get("Authorization"); auHead != "" { auths := strings.Fields(auHead) - if len(auths) == 2 && (auths[0] == "token" || strings.ToLower(auths[0]) == "bearer") { + if len(auths) == 2 && (util.ASCIIEqualFold(auths[0], "token") || util.ASCIIEqualFold(auths[0], "bearer")) { return auths[1], true } } diff --git a/services/auth/oauth2_test.go b/services/auth/oauth2_test.go index d6455b33ad..3fce7df50b 100644 --- a/services/auth/oauth2_test.go +++ b/services/auth/oauth2_test.go @@ -4,6 +4,7 @@ package auth import ( + "net/http" "testing" "forgejo.org/models/unittest" @@ -52,3 +53,30 @@ func TestCheckTaskIsRunning(t *testing.T) { }) } } + +func TestParseToken(t *testing.T) { + cases := map[string]struct { + Header string + ExpectedToken string + Expected bool + }{ + "Token Uppercase": {Header: "Token 1234567890123456789012345687901325467890", ExpectedToken: "1234567890123456789012345687901325467890", Expected: true}, + "Token Lowercase": {Header: "token 1234567890123456789012345687901325467890", ExpectedToken: "1234567890123456789012345687901325467890", Expected: true}, + "Token Unicode": {Header: "to\u212Aen 1234567890123456789012345687901325467890", ExpectedToken: "", Expected: false}, + "Bearer Uppercase": {Header: "Bearer 1234567890123456789012345687901325467890", ExpectedToken: "1234567890123456789012345687901325467890", Expected: true}, + "Bearer Lowercase": {Header: "bearer 1234567890123456789012345687901325467890", ExpectedToken: "1234567890123456789012345687901325467890", Expected: true}, + "Missing type": {Header: "1234567890123456789012345687901325467890", ExpectedToken: "", Expected: false}, + "Three Parts": {Header: "abc 1234567890 test", ExpectedToken: "", Expected: false}, + } + + for name := range cases { + c := cases[name] + t.Run(name, func(t *testing.T) { + req, _ := http.NewRequest("GET", "/", nil) + req.Header.Add("Authorization", c.Header) + ActualToken, ActualSuccess := parseToken(req) + assert.Equal(t, c.ExpectedToken, ActualToken) + assert.Equal(t, c.Expected, ActualSuccess) + }) + } +} diff --git a/services/automerge/automerge.go b/services/automerge/automerge.go index cbfe3bd54e..0cdc113379 100644 --- a/services/automerge/automerge.go +++ b/services/automerge/automerge.go @@ -162,7 +162,7 @@ func handlePullRequestAutoMerge(pullID int64, sha string) { return } case issues_model.PullRequestFlowAGit: - headBranchExist := git.IsReferenceExist(ctx, baseGitRepo.Path, pr.GetGitRefName()) + headBranchExist := baseGitRepo.IsReferenceExist(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 diff --git a/services/convert/attachment.go b/services/convert/attachment.go index 6617aac906..74ae7c509c 100644 --- a/services/convert/attachment.go +++ b/services/convert/attachment.go @@ -4,6 +4,9 @@ package convert import ( + "mime" + "path/filepath" + repo_model "forgejo.org/models/repo" api "forgejo.org/modules/structs" ) @@ -20,9 +23,13 @@ func APIAssetDownloadURL(repo *repo_model.Repository, attach *repo_model.Attachm return attach.DownloadURL() } -// ToAttachment converts models.Attachment to api.Attachment for API usage -func ToAttachment(repo *repo_model.Repository, a *repo_model.Attachment) *api.Attachment { - return toAttachment(repo, a, WebAssetDownloadURL) +// ToWebAttachment converts models.Attachment to api.WebAttachment for API usage +func ToWebAttachment(repo *repo_model.Repository, a *repo_model.Attachment) *api.WebAttachment { + attachment := toAttachment(repo, a, WebAssetDownloadURL) + return &api.WebAttachment{ + Attachment: attachment, + MimeType: mime.TypeByExtension(filepath.Ext(attachment.Name)), + } } // ToAPIAttachment converts models.Attachment to api.Attachment for API usage diff --git a/services/convert/attachment_test.go b/services/convert/attachment_test.go new file mode 100644 index 0000000000..d7bf0c1ee7 --- /dev/null +++ b/services/convert/attachment_test.go @@ -0,0 +1,56 @@ +// Copyright 2025 The Forgejo Authors. All rights reserved. +// SPDX-License-Identifier: GPL-3.0-or-later + +package convert + +import ( + "fmt" + "testing" + "time" + + repo_model "forgejo.org/models/repo" + "forgejo.org/models/unittest" + "forgejo.org/modules/setting" + api "forgejo.org/modules/structs" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestToWebAttachment(t *testing.T) { + require.NoError(t, unittest.PrepareTestDatabase()) + headRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + attachment := &repo_model.Attachment{ + ID: 10, + UUID: "uuidxxx", + RepoID: 1, + IssueID: 1, + ReleaseID: 0, + UploaderID: 0, + CommentID: 0, + Name: "test.png", + DownloadCount: 90, + Size: 30, + NoAutoTime: false, + CreatedUnix: 9342, + CustomDownloadURL: "", + ExternalURL: "", + } + + webAttachment := ToWebAttachment(headRepo, attachment) + + assert.NotNil(t, webAttachment) + assert.Equal(t, &api.WebAttachment{ + Attachment: &api.Attachment{ + ID: 10, + Name: "test.png", + Created: time.Unix(9342, 0), + DownloadCount: 90, + Size: 30, + UUID: "uuidxxx", + DownloadURL: fmt.Sprintf("%sattachments/uuidxxx", setting.AppURL), + Type: "attachment", + }, + MimeType: "image/png", + }, webAttachment) +} diff --git a/services/convert/issue_test.go b/services/convert/issue_test.go index 97bacfb229..ea8ad9b7ef 100644 --- a/services/convert/issue_test.go +++ b/services/convert/issue_test.go @@ -24,10 +24,11 @@ func TestLabel_ToLabel(t *testing.T) { label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: label.RepoID}) assert.Equal(t, &api.Label{ - ID: label.ID, - Name: label.Name, - Color: "abcdef", - URL: fmt.Sprintf("%sapi/v1/repos/user2/repo1/labels/%d", setting.AppURL, label.ID), + ID: label.ID, + Name: label.Name, + Color: "abcdef", + Description: label.Description, + URL: fmt.Sprintf("%sapi/v1/repos/user2/repo1/labels/%d", setting.AppURL, label.ID), }, ToLabel(label, repo, nil)) } diff --git a/services/federation/federation_service.go b/services/federation/federation_service.go index a3b719d1a7..b71d8d2575 100644 --- a/services/federation/federation_service.go +++ b/services/federation/federation_service.go @@ -5,15 +5,12 @@ package federation import ( "context" - "errors" + "database/sql" "fmt" - "net/http" "net/url" "strings" - "time" "forgejo.org/models/forgefed" - "forgejo.org/models/repo" "forgejo.org/models/user" "forgejo.org/modules/activitypub" "forgejo.org/modules/auth/password" @@ -21,91 +18,84 @@ import ( "forgejo.org/modules/log" "forgejo.org/modules/setting" "forgejo.org/modules/validation" + context_service "forgejo.org/services/context" "github.com/google/uuid" ) -// ProcessLikeActivity receives a ForgeLike activity and does the following: -// Validation of the activity -// Creation of a (remote) federationHost if not existing -// Creation of a forgefed Person if not existing -// Validation of incoming RepositoryID against Local RepositoryID -// Star the repo if it wasn't already stared -// Do some mitigation against out of order attacks -func ProcessLikeActivity(ctx context.Context, form any, repositoryID int64) (int, string, error) { - activity := form.(*fm.ForgeLike) - if res, err := validation.IsValid(activity); !res { - return http.StatusNotAcceptable, "Invalid activity", err - } - log.Info("Activity validated:%v", activity) +func Init() error { + return nil +} - // parse actorID (person) - actorURI := activity.Actor.GetID().String() - log.Info("actorURI was: %v", actorURI) - federationHost, err := GetFederationHostForURI(ctx, actorURI) +func FindOrCreateFederationHost(ctx *context_service.Base, actorURI string) (*forgefed.FederationHost, error) { + rawActorID, err := fm.NewActorID(actorURI) if err != nil { - return http.StatusInternalServerError, "Wrong FederationHost", err + return nil, err } - if !activity.IsNewer(federationHost.LatestActivity) { - return http.StatusNotAcceptable, "Activity out of order.", errors.New("Activity already processed") + federationHost, err := forgefed.FindFederationHostByFqdnAndPort(ctx, rawActorID.Host, rawActorID.HostPort) + if err != nil { + return nil, err + } + if federationHost == nil { + result, err := createFederationHostFromAP(ctx, rawActorID) + if err != nil { + return nil, err + } + federationHost = result + } + return federationHost, nil +} + +func FindOrCreateFederatedUser(ctx *context_service.Base, actorURI string) (*user.User, *user.FederatedUser, *forgefed.FederationHost, error) { + user, federatedUser, federationHost, err := findFederatedUser(ctx, actorURI) + if err != nil { + return nil, nil, nil, err + } + personID, err := fm.NewPersonID(actorURI, string(federationHost.NodeInfo.SoftwareName)) + if err != nil { + return nil, nil, nil, err + } + + if user != nil { + log.Trace("Found local federatedUser: %#v", user) + } else { + user, federatedUser, err = createUserFromAP(ctx, personID, federationHost.ID) + if err != nil { + return nil, nil, nil, err + } + log.Trace("Created federatedUser from ap: %#v", user) + } + log.Trace("Got user: %v", user.Name) + + return user, federatedUser, federationHost, nil +} + +func findFederatedUser(ctx *context_service.Base, actorURI string) (*user.User, *user.FederatedUser, *forgefed.FederationHost, error) { + federationHost, err := FindOrCreateFederationHost(ctx, actorURI) + if err != nil { + return nil, nil, nil, err } actorID, err := fm.NewPersonID(actorURI, string(federationHost.NodeInfo.SoftwareName)) if err != nil { - return http.StatusNotAcceptable, "Invalid PersonID", err + return nil, nil, nil, err } - log.Info("Actor accepted:%v", actorID) - // parse objectID (repository) - objectID, err := fm.NewRepositoryID(activity.Object.GetID().String(), string(forgefed.ForgejoSourceType)) + user, federatedUser, err := user.FindFederatedUser(ctx, actorID.ID, federationHost.ID) if err != nil { - return http.StatusNotAcceptable, "Invalid objectId", err - } - if objectID.ID != fmt.Sprint(repositoryID) { - return http.StatusNotAcceptable, "Invalid objectId", err - } - log.Info("Object accepted:%v", objectID) - - // Check if user already exists - user, _, err := user.FindFederatedUser(ctx, actorID.ID, federationHost.ID) - if err != nil { - return http.StatusInternalServerError, "Searching for user failed", err - } - if user != nil { - log.Info("Found local federatedUser: %v", user) - } else { - user, _, err = CreateUserFromAP(ctx, actorID, federationHost.ID) - if err != nil { - return http.StatusInternalServerError, "Error creating federatedUser", err - } - log.Info("Created federatedUser from ap: %v", user) - } - log.Info("Got user:%v", user.Name) - - // execute the activity if the repo was not stared already - alreadyStared := repo.IsStaring(ctx, user.ID, repositoryID) - if !alreadyStared { - err = repo.StarRepo(ctx, user.ID, repositoryID, true) - if err != nil { - return http.StatusNotAcceptable, "Error staring", err - } - } - federationHost.LatestActivity = activity.StartTime - err = forgefed.UpdateFederationHost(ctx, federationHost) - if err != nil { - return http.StatusNotAcceptable, "Error updating federatedHost", err + return nil, nil, nil, err } - return 0, "", nil + return user, federatedUser, federationHost, nil } -func CreateFederationHostFromAP(ctx context.Context, actorID fm.ActorID) (*forgefed.FederationHost, error) { +func createFederationHostFromAP(ctx context.Context, actorID fm.ActorID) (*forgefed.FederationHost, error) { actionsUser := user.NewAPServerActor() clientFactory, err := activitypub.GetClientFactory(ctx) if err != nil { return nil, err } - client, err := clientFactory.WithKeys(ctx, actionsUser, actionsUser.APActorKeyID()) + client, err := clientFactory.WithKeys(ctx, actionsUser, actionsUser.KeyID()) if err != nil { return nil, err } @@ -130,6 +120,7 @@ func CreateFederationHostFromAP(ctx context.Context, actorID fm.ActorID) (*forge return nil, err } + // TODO: we should get key material here also to have it immediately result, err := forgefed.NewFederationHost(actorID.Host, nodeInfo, actorID.HostPort, actorID.HostSchema) if err != nil { return nil, err @@ -143,34 +134,14 @@ func CreateFederationHostFromAP(ctx context.Context, actorID fm.ActorID) (*forge return &result, nil } -func GetFederationHostForURI(ctx context.Context, actorURI string) (*forgefed.FederationHost, error) { - log.Info("Input was: %v", actorURI) - rawActorID, err := fm.NewActorID(actorURI) - if err != nil { - return nil, err - } - federationHost, err := forgefed.FindFederationHostByFqdnAndPort(ctx, rawActorID.Host, rawActorID.HostPort) - if err != nil { - return nil, err - } - if federationHost == nil { - result, err := CreateFederationHostFromAP(ctx, rawActorID) - if err != nil { - return nil, err - } - federationHost = result - } - return federationHost, nil -} - -func CreateUserFromAP(ctx context.Context, personID fm.PersonID, federationHostID int64) (*user.User, *user.FederatedUser, error) { +func fetchUserFromAP(ctx context.Context, personID fm.PersonID, federationHostID int64) (*user.User, *user.FederatedUser, error) { actionsUser := user.NewAPServerActor() clientFactory, err := activitypub.GetClientFactory(ctx) if err != nil { return nil, nil, err } - apClient, err := clientFactory.WithKeys(ctx, actionsUser, actionsUser.APActorKeyID()) + apClient, err := clientFactory.WithKeys(ctx, actionsUser, actionsUser.KeyID()) if err != nil { return nil, nil, err } @@ -216,6 +187,11 @@ func CreateUserFromAP(ctx context.Context, personID fm.PersonID, federationHostI return nil, nil, err } + pubKeyBytes, err := decodePublicKeyPem(person.PublicKey.PublicKeyPem) + if err != nil { + return nil, nil, err + } + newUser := user.User{ LowerName: strings.ToLower(name), Name: name, @@ -234,86 +210,30 @@ func CreateUserFromAP(ctx context.Context, personID fm.PersonID, federationHostI FederationHostID: federationHostID, InboxPath: inbox.Path, NormalizedOriginalURL: personID.AsURI(), + KeyID: sql.NullString{ + String: person.PublicKey.ID.String(), + Valid: true, + }, + PublicKey: sql.Null[sql.RawBytes]{ + V: pubKeyBytes, + Valid: true, + }, } - err = user.CreateFederatedUser(ctx, &newUser, &federatedUser) + log.Info("Fetch federatedUser:%q", federatedUser) + return &newUser, &federatedUser, nil +} + +func createUserFromAP(ctx context.Context, personID fm.PersonID, federationHostID int64) (*user.User, *user.FederatedUser, error) { + newUser, federatedUser, err := fetchUserFromAP(ctx, personID, federationHostID) + if err != nil { + return nil, nil, err + } + err = user.CreateFederatedUser(ctx, newUser, federatedUser) if err != nil { return nil, nil, err } log.Info("Created federatedUser:%q", federatedUser) - return &newUser, &federatedUser, nil -} - -// Create or update a list of FollowingRepo structs -func StoreFollowingRepoList(ctx context.Context, localRepoID int64, followingRepoList []string) (int, string, error) { - followingRepos := make([]*repo.FollowingRepo, 0, len(followingRepoList)) - for _, uri := range followingRepoList { - federationHost, err := GetFederationHostForURI(ctx, uri) - if err != nil { - return http.StatusInternalServerError, "Wrong FederationHost", err - } - followingRepoID, err := fm.NewRepositoryID(uri, string(federationHost.NodeInfo.SoftwareName)) - if err != nil { - return http.StatusNotAcceptable, "Invalid federated repo", err - } - followingRepo, err := repo.NewFollowingRepo(localRepoID, followingRepoID.ID, federationHost.ID, uri) - if err != nil { - return http.StatusNotAcceptable, "Invalid federated repo", err - } - followingRepos = append(followingRepos, &followingRepo) - } - - if err := repo.StoreFollowingRepos(ctx, localRepoID, followingRepos); err != nil { - return 0, "", err - } - - return 0, "", nil -} - -func DeleteFollowingRepos(ctx context.Context, localRepoID int64) error { - return repo.StoreFollowingRepos(ctx, localRepoID, []*repo.FollowingRepo{}) -} - -func SendLikeActivities(ctx context.Context, doer user.User, repoID int64) error { - followingRepos, err := repo.FindFollowingReposByRepoID(ctx, repoID) - log.Info("Federated Repos is: %v", followingRepos) - if err != nil { - return err - } - - likeActivityList := make([]fm.ForgeLike, 0) - for _, followingRepo := range followingRepos { - log.Info("Found following repo: %v", followingRepo) - target := followingRepo.URI - likeActivity, err := fm.NewForgeLike(doer.APActorID(), target, time.Now()) - if err != nil { - return err - } - likeActivityList = append(likeActivityList, likeActivity) - } - - apclientFactory, err := activitypub.GetClientFactory(ctx) - if err != nil { - return err - } - - apclient, err := apclientFactory.WithKeys(ctx, &doer, doer.APActorKeyID()) - if err != nil { - return err - } - for i, activity := range likeActivityList { - activity.StartTime = activity.StartTime.Add(time.Duration(i) * time.Second) - json, err := activity.MarshalJSON() - if err != nil { - return err - } - - _, err = apclient.Post(json, fmt.Sprintf("%s/inbox", activity.Object)) - if err != nil { - log.Error("error %v while sending activity: %q", err, activity) - } - } - - return nil + return newUser, federatedUser, nil } diff --git a/services/federation/repo_like.go b/services/federation/repo_like.go new file mode 100644 index 0000000000..c1e6500c61 --- /dev/null +++ b/services/federation/repo_like.go @@ -0,0 +1,146 @@ +// Copyright 2024 The Forgejo Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package federation + +import ( + "context" + "errors" + "fmt" + "net/http" + "time" + + "forgejo.org/models/forgefed" + "forgejo.org/models/repo" + "forgejo.org/models/user" + "forgejo.org/modules/activitypub" + fm "forgejo.org/modules/forgefed" + "forgejo.org/modules/log" + "forgejo.org/modules/validation" + context_service "forgejo.org/services/context" +) + +// ProcessLikeActivity receives a ForgeLike activity and does the following: +// Validation of the activity +// Creation of a (remote) federationHost if not existing +// Creation of a forgefed Person if not existing +// Validation of incoming RepositoryID against Local RepositoryID +// Star the repo if it wasn't already stared +// Do some mitigation against out of order attacks +func ProcessLikeActivity(ctx *context_service.APIContext, form any, repositoryID int64) (int, string, error) { + activity := form.(*fm.ForgeLike) + if res, err := validation.IsValid(activity); !res { + return http.StatusNotAcceptable, "Invalid activity", err + } + log.Trace("Activity validated: %#v", activity) + + // parse actorID (person) + actorURI := activity.Actor.GetID().String() + user, _, federationHost, err := FindOrCreateFederatedUser(ctx.Base, actorURI) + if err != nil { + ctx.Error(http.StatusNotAcceptable, "Federated user not found", err) + return http.StatusInternalServerError, "FindOrCreateFederatedUser", err + } + + if !activity.IsNewer(federationHost.LatestActivity) { + return http.StatusNotAcceptable, "Activity out of order.", errors.New("Activity already processed") + } + + // parse objectID (repository) + objectID, err := fm.NewRepositoryID(activity.Object.GetID().String(), string(forgefed.ForgejoSourceType)) + if err != nil { + return http.StatusNotAcceptable, "Invalid objectId", err + } + if objectID.ID != fmt.Sprint(repositoryID) { + return http.StatusNotAcceptable, "Invalid objectId", err + } + log.Trace("Object accepted: %#v", objectID) + + // execute the activity if the repo was not stared already + alreadyStared := repo.IsStaring(ctx, user.ID, repositoryID) + if !alreadyStared { + err = repo.StarRepo(ctx, user.ID, repositoryID, true) + if err != nil { + return http.StatusNotAcceptable, "Error staring", err + } + } + federationHost.LatestActivity = activity.StartTime + err = forgefed.UpdateFederationHost(ctx, federationHost) + if err != nil { + return http.StatusNotAcceptable, "Error updating federatedHost", err + } + + return 0, "", nil +} + +// Create or update a list of FollowingRepo structs +func StoreFollowingRepoList(ctx *context_service.Context, localRepoID int64, followingRepoList []string) (int, string, error) { + followingRepos := make([]*repo.FollowingRepo, 0, len(followingRepoList)) + for _, uri := range followingRepoList { + federationHost, err := FindOrCreateFederationHost(ctx.Base, uri) + if err != nil { + return http.StatusInternalServerError, "Wrong FederationHost", err + } + followingRepoID, err := fm.NewRepositoryID(uri, string(federationHost.NodeInfo.SoftwareName)) + if err != nil { + return http.StatusNotAcceptable, "Invalid federated repo", err + } + followingRepo, err := repo.NewFollowingRepo(localRepoID, followingRepoID.ID, federationHost.ID, uri) + if err != nil { + return http.StatusNotAcceptable, "Invalid federated repo", err + } + followingRepos = append(followingRepos, &followingRepo) + } + + if err := repo.StoreFollowingRepos(ctx, localRepoID, followingRepos); err != nil { + return 0, "", err + } + + return 0, "", nil +} + +func DeleteFollowingRepos(ctx context.Context, localRepoID int64) error { + return repo.StoreFollowingRepos(ctx, localRepoID, []*repo.FollowingRepo{}) +} + +func SendLikeActivities(ctx context.Context, doer user.User, repoID int64) error { + followingRepos, err := repo.FindFollowingReposByRepoID(ctx, repoID) + log.Trace("Federated Repos is: %#v", followingRepos) + if err != nil { + return err + } + + likeActivityList := make([]fm.ForgeLike, 0) + for _, followingRepo := range followingRepos { + log.Trace("Found following repo: %#v", followingRepo) + target := followingRepo.URI + likeActivity, err := fm.NewForgeLike(doer.APActorID(), target, time.Now()) + if err != nil { + return err + } + likeActivityList = append(likeActivityList, likeActivity) + } + + apclientFactory, err := activitypub.GetClientFactory(ctx) + if err != nil { + return err + } + apclient, err := apclientFactory.WithKeys(ctx, &doer, doer.APActorID()+"#main-key") + if err != nil { + return err + } + for i, activity := range likeActivityList { + activity.StartTime = activity.StartTime.Add(time.Duration(i) * time.Second) + json, err := activity.MarshalJSON() + if err != nil { + return err + } + + _, err = apclient.Post(json, fmt.Sprintf("%v/inbox", activity.Object)) + if err != nil { + log.Error("error %v while sending activity: %#v", err, activity) + } + } + + return nil +} diff --git a/services/federation/signature_service.go b/services/federation/signature_service.go new file mode 100644 index 0000000000..e5102b89d8 --- /dev/null +++ b/services/federation/signature_service.go @@ -0,0 +1,234 @@ +// Copyright 2024, 2025 The Forgejo Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package federation + +import ( + "crypto/x509" + "database/sql" + "encoding/pem" + "errors" + "fmt" + "net/url" + + "forgejo.org/models/forgefed" + "forgejo.org/models/user" + "forgejo.org/modules/activitypub" + fm "forgejo.org/modules/forgefed" + context_service "forgejo.org/services/context" + + ap "github.com/go-ap/activitypub" +) + +// Factory function for ActorID. Created struct is asserted to be valid +func NewActorIDFromKeyID(ctx *context_service.Base, uri string) (fm.ActorID, error) { + parsedURI, err := url.Parse(uri) + parsedURI.Fragment = "" + if err != nil { + return fm.ActorID{}, err + } + + actionsUser := user.NewAPServerActor() + clientFactory, err := activitypub.GetClientFactory(ctx) + if err != nil { + return fm.ActorID{}, err + } + + apClient, err := clientFactory.WithKeys(ctx, actionsUser, actionsUser.KeyID()) + if err != nil { + return fm.ActorID{}, err + } + + userResponse, err := apClient.GetBody(parsedURI.String()) + if err != nil { + return fm.ActorID{}, err + } + + var actor ap.Actor + err = actor.UnmarshalJSON(userResponse) + if err != nil { + return fm.ActorID{}, err + } + + result, err := fm.NewActorID(actor.PublicKey.Owner.String()) + return result, err +} + +func FindOrCreateFederatedUserKey(ctx *context_service.Base, keyID string) (pubKey any, err error) { + var federatedUser *user.FederatedUser + var keyURL *url.URL + + keyURL, err = url.Parse(keyID) + if err != nil { + return nil, err + } + + // Try if the signing actor is an already known federated user + _, federatedUser, err = user.FindFederatedUserByKeyID(ctx, keyURL.String()) + if err != nil { + return nil, err + } + + if federatedUser == nil { + rawActorID, err := NewActorIDFromKeyID(ctx, keyID) + if err != nil { + return nil, err + } + + _, federatedUser, _, err = FindOrCreateFederatedUser(ctx, rawActorID.AsURI()) + if err != nil { + return nil, err + } + } else { + _, err = forgefed.GetFederationHost(ctx, federatedUser.FederationHostID) + if err != nil { + return nil, err + } + } + + if federatedUser.PublicKey.Valid { + pubKey, err := x509.ParsePKIXPublicKey(federatedUser.PublicKey.V) + if err != nil { + return nil, err + } + return pubKey, nil + } + + // Fetch missing public key + pubKey, pubKeyBytes, apPerson, err := fetchKeyFromAp(ctx, *keyURL) + if err != nil { + return nil, err + } + if apPerson.Type == ap.ActivityVocabularyType("Person") { + // Check federatedUser.id = person.id + if federatedUser.ExternalID != apPerson.ID.String() { + return nil, fmt.Errorf("federated user fetched (%v) does not match the stored one %v", apPerson, federatedUser) + } + // update federated user + federatedUser.KeyID = sql.NullString{ + String: apPerson.PublicKey.ID.String(), + Valid: true, + } + federatedUser.PublicKey = sql.Null[sql.RawBytes]{ + V: pubKeyBytes, + Valid: true, + } + err = user.UpdateFederatedUser(ctx, federatedUser) + if err != nil { + return nil, err + } + return pubKey, nil + } + return nil, nil +} + +func FindOrCreateFederationHostKey(ctx *context_service.Base, keyID string) (pubKey any, err error) { + keyURL, err := url.Parse(keyID) + if err != nil { + return nil, err + } + rawActorID, err := NewActorIDFromKeyID(ctx, keyID) + if err != nil { + return nil, err + } + + // Is there an already known federation host? + federationHost, err := forgefed.FindFederationHostByKeyID(ctx, keyURL.String()) + if err != nil { + return nil, err + } + + if federationHost == nil { + federationHost, err = FindOrCreateFederationHost(ctx, rawActorID.AsURI()) + if err != nil { + return nil, err + } + } + + // Is there an already an key? + if federationHost.PublicKey.Valid { + pubKey, err := x509.ParsePKIXPublicKey(federationHost.PublicKey.V) + if err != nil { + return nil, err + } + return pubKey, nil + } + + // If not, fetch missing public key + pubKey, pubKeyBytes, apPerson, err := fetchKeyFromAp(ctx, *keyURL) + if err != nil { + return nil, err + } + if apPerson.Type == ap.ActivityVocabularyType("Application") { + // Check federationhost.id = person.id + if federationHost.HostPort != rawActorID.HostPort || federationHost.HostFqdn != rawActorID.Host || + federationHost.HostSchema != rawActorID.HostSchema { + return nil, fmt.Errorf("federation host fetched (%v) does not match the stored one %v", apPerson, federationHost) + } + // update federation host + federationHost.KeyID = sql.NullString{ + String: apPerson.PublicKey.ID.String(), + Valid: true, + } + federationHost.PublicKey = sql.Null[sql.RawBytes]{ + V: pubKeyBytes, + Valid: true, + } + err = forgefed.UpdateFederationHost(ctx, federationHost) + if err != nil { + return nil, err + } + return pubKey, nil + } + return nil, nil +} + +func fetchKeyFromAp(ctx *context_service.Base, keyURL url.URL) (pubKey any, pubKeyBytes []byte, apPerson *ap.Person, err error) { + actionsUser := user.NewAPServerActor() + clientFactory, err := activitypub.GetClientFactory(ctx) + if err != nil { + return nil, nil, nil, err + } + + apClient, err := clientFactory.WithKeys(ctx, actionsUser, actionsUser.KeyID()) + if err != nil { + return nil, nil, nil, err + } + + b, err := apClient.GetBody(keyURL.String()) + if err != nil { + return nil, nil, nil, err + } + + person := ap.PersonNew(ap.IRI(keyURL.String())) + err = person.UnmarshalJSON(b) + if err != nil { + return nil, nil, nil, fmt.Errorf("ActivityStreams type cannot be converted to one known to have publicKey property: %w", err) + } + + pubKeyFromAp := person.PublicKey + if pubKeyFromAp.ID.String() != keyURL.String() { + return nil, nil, nil, fmt.Errorf("cannot find publicKey with id: %v in %v", keyURL, string(b)) + } + + pubKeyBytes, err = decodePublicKeyPem(pubKeyFromAp.PublicKeyPem) + if err != nil { + return nil, nil, nil, err + } + + pubKey, err = x509.ParsePKIXPublicKey(pubKeyBytes) + if err != nil { + return nil, nil, nil, err + } + + return pubKey, pubKeyBytes, person, err +} + +func decodePublicKeyPem(pubKeyPem string) ([]byte, error) { + block, _ := pem.Decode([]byte(pubKeyPem)) + if block == nil || block.Type != "PUBLIC KEY" { + return nil, errors.New("could not decode publicKeyPem to PUBLIC KEY pem block type") + } + + return block.Bytes, nil +} diff --git a/services/mailer/mail_actions.go b/services/mailer/mail_actions.go index 09763e164e..a99af823b3 100644 --- a/services/mailer/mail_actions.go +++ b/services/mailer/mail_actions.go @@ -16,8 +16,8 @@ const ( tplActionNowDone base.TplName = "actions/now_done" ) -// requires !run.Status.IsSuccess() or !lastRun.Status.IsSuccess() -func MailActionRun(run *actions_model.ActionRun, priorStatus actions_model.Status, lastRun *actions_model.ActionRun) error { +var MailActionRun = mailActionRun // make it mockable +func mailActionRun(run *actions_model.ActionRun, priorStatus actions_model.Status, lastRun *actions_model.ActionRun) error { if setting.MailService == nil { // No mail service configured return nil @@ -60,7 +60,6 @@ func sendMailActionRun(to *user_model.User, run *actions_model.ActionRun, priorS if len(commitSHA) > 7 { commitSHA = commitSHA[:7] } - branch := run.PrettyRef() data := map[string]any{ "locale": locale, @@ -73,7 +72,6 @@ func sendMailActionRun(to *user_model.User, run *actions_model.ActionRun, priorS "LastRun": lastRun, "PriorStatus": priorStatus, "CommitSHA": commitSHA, - "Branch": branch, "IsSuccess": run.Status.IsSuccess(), } diff --git a/services/mailer/mail_actions_now_done_test.go b/services/mailer/mail_actions_now_done_test.go index 6a01ea7631..e84441f460 100644 --- a/services/mailer/mail_actions_now_done_test.go +++ b/services/mailer/mail_actions_now_done_test.go @@ -54,7 +54,92 @@ func getActionsNowDoneTestOrg(t *testing.T, name, email string, owner *user_mode } func assertTranslatedLocaleMailActionsNowDone(t *testing.T, msgBody string) { - AssertTranslatedLocale(t, msgBody, "mail.actions.successful_run_after_failure", "mail.actions.not_successful_run", "mail.actions.run_info_cur_status", "mail.actions.run_info_ref", "mail.actions.run_info_previous_status", "mail.actions.run_info_trigger", "mail.view_it_on") + AssertTranslatedLocale(t, msgBody, "mail.actions.successful_run_after_failure", "mail.actions.not_successful_run", "mail.actions.run_info_cur_status", "mail.actions.run_info_sha", "mail.actions.run_info_previous_status", "mail.actions.run_info_trigger", "mail.view_it_on") +} + +func TestActionRunNowDoneStatusMatrix(t *testing.T) { + successStatuses := []actions_model.Status{ + actions_model.StatusSuccess, + actions_model.StatusSkipped, + actions_model.StatusCancelled, + } + failureStatuses := []actions_model.Status{ + actions_model.StatusFailure, + } + + for _, testCase := range []struct { + name string + statuses []actions_model.Status + hasLastRun bool + lastStatuses []actions_model.Status + run bool + }{ + { + name: "FailureNoLastRun", + statuses: failureStatuses, + run: true, + }, + { + name: "SuccessNoLastRun", + statuses: successStatuses, + run: false, + }, + { + name: "FailureLastRunSuccess", + statuses: failureStatuses, + hasLastRun: true, + lastStatuses: successStatuses, + run: true, + }, + { + name: "FailureLastRunFailure", + statuses: failureStatuses, + hasLastRun: true, + lastStatuses: failureStatuses, + run: true, + }, + { + name: "SuccessLastRunFailure", + statuses: successStatuses, + hasLastRun: true, + lastStatuses: failureStatuses, + run: true, + }, + { + name: "SuccessLastRunSuccess", + statuses: successStatuses, + hasLastRun: true, + lastStatuses: successStatuses, + run: false, + }, + } { + t.Run(testCase.name, func(t *testing.T) { + var called bool + defer test.MockVariableValue(&MailActionRun, func(run *actions_model.ActionRun, priorStatus actions_model.Status, lastRun *actions_model.ActionRun) error { + called = true + return nil + })() + for _, status := range testCase.statuses { + for _, lastStatus := range testCase.lastStatuses { + called = false + n := NewNotifier() + var lastRun *actions_model.ActionRun + if testCase.hasLastRun { + lastRun = &actions_model.ActionRun{ + Status: lastStatus, + } + } + n.ActionRunNowDone(t.Context(), + &actions_model.ActionRun{ + Status: status, + }, + actions_model.StatusUnknown, + lastRun) + assert.Equal(t, testCase.run, called, "status = %s, lastStatus = %s", status, lastStatus) + } + } + }) + } } func TestActionRunNowDoneNotificationMail(t *testing.T) { diff --git a/services/mailer/notify.go b/services/mailer/notify.go index 7461a67181..640de31fcc 100644 --- a/services/mailer/notify.go +++ b/services/mailer/notify.go @@ -212,7 +212,7 @@ func (m *mailNotifier) NewUserSignUp(ctx context.Context, newUser *user_model.Us func (m *mailNotifier) ActionRunNowDone(ctx context.Context, run *actions_model.ActionRun, priorStatus actions_model.Status, lastRun *actions_model.ActionRun) { // Only send a mail on a successful run when the workflow recovered (i.e., the run before failed). - if run.Status.IsSuccess() && (lastRun == nil || lastRun.Status.IsSuccess()) { + if !run.Status.IsFailure() && (lastRun == nil || !lastRun.Status.IsFailure()) { return } if err := MailActionRun(run, priorStatus, lastRun); err != nil { diff --git a/services/packages/alt/repository.go b/services/packages/alt/repository.go index 317862da9d..9693f4322e 100644 --- a/services/packages/alt/repository.go +++ b/services/packages/alt/repository.go @@ -714,21 +714,23 @@ func buildRelease(ctx context.Context, pv *packages_model.PackageVersion, pfs [] for architecture := range architectures.Seq() { version := time.Now().Unix() label := setting.AppName - data := fmt.Sprintf(`Archive: Alt Linux Team + origin := setting.AppName + archive := setting.AppName + + data := fmt.Sprintf(`Archive: %s Component: classic Version: %d -Origin: Alt Linux Team +Origin: %s Label: %s Architecture: %s NotAutomatic: false `, - version, label, architecture) + archive, version, origin, label, architecture) fileInfo, err := addReleaseAsFileToRepo(ctx, pv, "release.classic", data, group, architecture) if err != nil { return err } - origin := setting.AppName codename := time.Now().Unix() date := time.Now().UTC().Format(time.RFC1123) @@ -744,7 +746,7 @@ NotAutomatic: false data = fmt.Sprintf(`Origin: %s Label: %s -Suite: Sisyphus +Suite: Unknown Codename: %d Date: %s Architectures: %s diff --git a/services/pull/commit_status.go b/services/pull/commit_status.go index 3c864c8ef2..0a95ea1152 100644 --- a/services/pull/commit_status.go +++ b/services/pull/commit_status.go @@ -12,7 +12,6 @@ import ( "forgejo.org/models/db" git_model "forgejo.org/models/git" issues_model "forgejo.org/models/issues" - "forgejo.org/modules/git" "forgejo.org/modules/gitrepo" "forgejo.org/modules/log" "forgejo.org/modules/structs" @@ -105,7 +104,7 @@ func GetPullRequestCommitStatusState(ctx context.Context, pr *issues_model.PullR if pr.Flow == issues_model.PullRequestFlowGithub && !headGitRepo.IsBranchExist(pr.HeadBranch) { return "", errors.New("head branch does not exist, can not merge") } - if pr.Flow == issues_model.PullRequestFlowAGit && !git.IsReferenceExist(ctx, headGitRepo.Path, pr.GetGitRefName()) { + if pr.Flow == issues_model.PullRequestFlowAGit && !headGitRepo.IsReferenceExist(pr.GetGitRefName()) { return "", errors.New("head branch does not exist, can not merge") } diff --git a/services/pull/review.go b/services/pull/review.go index c740328e4c..7d232d6d79 100644 --- a/services/pull/review.go +++ b/services/pull/review.go @@ -9,8 +9,6 @@ import ( "errors" "fmt" "io" - "regexp" - "strings" "forgejo.org/models/db" issues_model "forgejo.org/models/issues" @@ -25,8 +23,6 @@ import ( notify_service "forgejo.org/services/notify" ) -var notEnoughLines = regexp.MustCompile(`fatal: file .* has only \d+ lines?`) - // ErrDismissRequestOnClosedPR represents an error when an user tries to dismiss a review associated to a closed or merged PR. type ErrDismissRequestOnClosedPR struct{} @@ -48,8 +44,8 @@ func (err ErrDismissRequestOnClosedPR) Unwrap() error { // If the line got changed the comment is going to be invalidated. func checkInvalidation(ctx context.Context, c *issues_model.Comment, repo *git.Repository, branch string) error { // FIXME differentiate between previous and proposed line - commit, err := repo.LineBlame(branch, repo.Path, c.TreePath, uint(c.UnsignedLine())) - if err != nil && (strings.Contains(err.Error(), "fatal: no such path") || notEnoughLines.MatchString(err.Error())) { + commit, err := repo.LineBlame(branch, c.TreePath, c.UnsignedLine()) + if err != nil && (errors.Is(err, git.ErrBlameFileDoesNotExist) || errors.Is(err, git.ErrBlameFileNotEnoughLines)) { c.Invalidated = true return issues_model.UpdateCommentInvalidate(ctx, c) } @@ -230,10 +226,10 @@ func CreateCodeCommentKnownReviewID(ctx context.Context, doer *user_model.User, // FIXME validate treePath // Get latest commit referencing the commented line // No need for get commit for base branch changes - commit, err := gitRepo.LineBlame(head, gitRepo.Path, treePath, uint(line)) + commit, err := gitRepo.LineBlame(head, treePath, uint64(line)) if err == nil { commitID = commit.ID.String() - } else if !strings.Contains(err.Error(), "exit status 128 - fatal: no such path") && !notEnoughLines.MatchString(err.Error()) { + } else if !errors.Is(err, git.ErrBlameFileDoesNotExist) && !errors.Is(err, git.ErrBlameFileNotEnoughLines) { return nil, fmt.Errorf("LineBlame[%s, %s, %s, %d]: %w", pr.GetGitRefName(), gitRepo.Path, treePath, line, err) } } diff --git a/templates/mail/actions/now_done.tmpl b/templates/mail/actions/now_done.tmpl index a890411055..adc990c545 100644 --- a/templates/mail/actions/now_done.tmpl +++ b/templates/mail/actions/now_done.tmpl @@ -21,7 +21,7 @@
{{.locale.Tr "mail.actions.run_info_cur_status" .Run.Status .PriorStatus}}
- {{.locale.Tr "mail.actions.run_info_ref" .Branch .CommitSHA}}
+ {{.locale.Tr "mail.actions.run_info_sha" .CommitSHA}}
{{if .LastRun}} {{.locale.Tr "mail.actions.run_info_previous_status" .LastRun.Status}}
{{end}} diff --git a/templates/package/content/alt.tmpl b/templates/package/content/alt.tmpl index 9a5e9c7656..0a5c328e6d 100644 --- a/templates/package/content/alt.tmpl +++ b/templates/package/content/alt.tmpl @@ -24,7 +24,7 @@ apt-get install {{$.PackageDescriptor.Package.Name}}
- +
diff --git a/templates/repo/issue/view_content/comments.tmpl b/templates/repo/issue/view_content/comments.tmpl index 3bc4cd0773..4ab1fa7584 100644 --- a/templates/repo/issue/view_content/comments.tmpl +++ b/templates/repo/issue/view_content/comments.tmpl @@ -221,27 +221,23 @@ {{else if and (eq .Type 9) (gt .AssigneeID 0)}}
{{svg "octicon-person"}} - {{if .RemovedAssignee}} - {{template "shared/user/avatarlink" dict "user" .Assignee}} - - {{template "shared/user/authorlink" .Assignee}} + {{template "shared/user/avatarlink" dict "user" .Assignee}} + + {{template "shared/user/authorlink" .Assignee}} + {{if .RemovedAssignee}} {{if eq .Poster.ID .Assignee.ID}} {{ctx.Locale.Tr "repo.issues.remove_self_assignment" $createdStr}} {{else}} - {{ctx.Locale.Tr "repo.issues.remove_assignee_at" .Poster.GetDisplayName $createdStr}} + {{ctx.Locale.Tr "repo.issues.remove_assignee_at" (RenderUser $.Context .Poster) $createdStr}} {{end}} - - {{else}} - {{template "shared/user/avatarlink" dict "user" .Assignee}} - - {{template "shared/user/authorlink" .Assignee}} + {{else}} {{if eq .Poster.ID .AssigneeID}} {{ctx.Locale.Tr "repo.issues.self_assign_at" $createdStr}} {{else}} - {{ctx.Locale.Tr "repo.issues.add_assignee_at" .Poster.GetDisplayName $createdStr}} + {{ctx.Locale.Tr "repo.issues.add_assignee_at" (RenderUser $.Context .Poster) $createdStr}} {{end}} - - {{end}} + {{end}} +
{{else if eq .Type 10}}
diff --git a/templates/repo/release_tag_header.tmpl b/templates/repo/release_tag_header.tmpl index 63d0689c50..75a115e31e 100644 --- a/templates/repo/release_tag_header.tmpl +++ b/templates/repo/release_tag_header.tmpl @@ -2,24 +2,23 @@ {{$canReadCode := $.Permission.CanRead $.UnitTypeCode}} {{if $canReadReleases}} -
-
- +
+ {{if .ShowReleaseSearch}} -
+ {{template "shared/search/combo" dict "Value" .Keyword}}
{{end}} -
+
{{if .EnableFeed}} - - {{svg "octicon-rss" 16}} {{ctx.Locale.Tr "rss_feed"}} + + {{svg "octicon-rss" 16}} + {{end}} {{if and (not .PageIsTagList) .CanCreateRelease}} diff --git a/templates/repo/settings/navbar.tmpl b/templates/repo/settings/navbar.tmpl index 0f6cb74d8c..6e9f396e2e 100644 --- a/templates/repo/settings/navbar.tmpl +++ b/templates/repo/settings/navbar.tmpl @@ -7,7 +7,7 @@
{{ctx.Locale.Tr "repo.settings.units.units"}} - {{svg "octicon-download"}} - {{svg "octicon-copy" 14}} + + {{svg "octicon-download"}} + + + {{svg "octicon-copy" 14}} + {{if .EnableFeed}} {{if .IsViewBranch}} @@ -74,14 +78,22 @@ {{end}} {{if .Repository.CanEnableEditor}} {{if .CanEditFile}} - {{svg "octicon-pencil"}} + + {{svg "octicon-pencil"}} + {{else}} - {{svg "octicon-pencil"}} + + {{svg "octicon-pencil"}} + {{end}} {{if .CanDeleteFile}} - {{svg "octicon-trash"}} + + {{svg "octicon-trash"}} + {{else}} - {{svg "octicon-trash"}} + + {{svg "octicon-trash"}} + {{end}} {{end}} {{else if .EscapeStatus.Escaped}} diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 0e8382b8ab..ee5e919757 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -5533,7 +5533,7 @@ } } }, - "/repos/{owner}/{repo}/actions/workflows/{workflowname}/dispatches": { + "/repos/{owner}/{repo}/actions/workflows/{workflowfilename}/dispatches": { "post": { "consumes": [ "application/json" @@ -5561,7 +5561,7 @@ { "type": "string", "description": "name of the workflow", - "name": "workflowname", + "name": "workflowfilename", "in": "path", "required": true }, diff --git a/tests/e2e/issue-comment-dropzone.test.e2e.ts b/tests/e2e/issue-comment-dropzone.test.e2e.ts new file mode 100644 index 0000000000..33ea2c9403 --- /dev/null +++ b/tests/e2e/issue-comment-dropzone.test.e2e.ts @@ -0,0 +1,94 @@ +// Copyright 2025 The Forgejo Authors. All rights reserved. +// SPDX-License-Identifier: GPL-3.0-or-later + +// @watch start +// web_src/js/features/common-global.js +// web_src/js/features/comp/Paste.js +// web_src/js/features/repo-issue.js +// web_src/js/features/repo-legacy.js +// @watch end + +import {expect, type Locator, type Page, type TestInfo} from '@playwright/test'; +import {test, save_visual, dynamic_id} from './utils_e2e.ts'; + +test.use({user: 'user2'}); + +async function pasteImage(el: Locator) { + await el.evaluate(async (el) => { + const base64 = `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAHklEQVQoU2MUk1P7z0AGYBzViDvURgMHT4oaQoEDAFuJEu2fuGfhAAAAAElFTkSuQmCC`; + // eslint-disable-next-line no-restricted-syntax + const response = await fetch(base64); + const blob = await response.blob(); + + el.focus(); + + let pasteEvent = new Event('paste', {bubbles: true, cancelable: true}); + pasteEvent = Object.assign(pasteEvent, { + clipboardData: { + items: [ + { + kind: 'file', + type: 'image/png', + getAsFile() { + return new File([blob], 'foo.png', {type: blob.type}); + }, + }, + ], + }, + }); + + el.dispatchEvent(pasteEvent); + }); +} + +async function assertCopy(page: Page, workerInfo: TestInfo, startWith: string) { + const project = workerInfo.project.name; + if (project === 'webkit' || project === 'Mobile Safari') return; + + const dropzone = page.locator('.dropzone'); + const preview = dropzone.locator('.dz-preview'); + const copyLink = preview.locator('.octicon-copy').locator('..'); + await copyLink.click(); + + const clipboardContent = await page.evaluate(() => navigator.clipboard.readText()); + expect(clipboardContent).toContain(startWith); +} + +test('Paste image in new comment', async ({page}, workerInfo) => { + await page.goto('/user2/repo1/issues/new'); + + await pasteImage(page.locator('.markdown-text-editor')); + + const dropzone = page.locator('.dropzone'); + await expect(dropzone.locator('.files')).toHaveCount(1); + const preview = dropzone.locator('.dz-preview'); + await expect(preview).toHaveCount(1); + await expect(preview.locator('.dz-filename')).toHaveText('foo.png'); + await expect(preview.locator('.octicon-copy')).toBeVisible(); + await assertCopy(page, workerInfo, '![foo]('); + + await save_visual(page); +}); + +test('Re-add images to dropzone on edit', async ({page}, workerInfo) => { + await page.goto('/user2/repo1/issues/new'); + + const issueTitle = dynamic_id(); + await page.locator('#issue_title').fill(issueTitle); + await pasteImage(page.locator('.markdown-text-editor')); + await page.getByRole('button', {name: 'Create issue'}).click(); + + await expect(page).toHaveURL(/\/user2\/repo1\/issues\/\d+$/); + await page.click('.comment-container .context-menu'); + await page.click('.comment-container .menu > .edit-content'); + + const dropzone = page.locator('.dropzone'); + await expect(dropzone.locator('.files').first()).toHaveCount(1); + const preview = dropzone.locator('.dz-preview'); + await expect(preview).toHaveCount(1); + await expect(preview.locator('.dz-filename')).toHaveText('foo.png'); + await expect(preview.locator('.octicon-copy')).toBeVisible(); + await assertCopy(page, workerInfo, '![foo]('); + + await save_visual(page); +}); diff --git a/tests/e2e/issue-sidebar.test.e2e.ts b/tests/e2e/issue-sidebar.test.e2e.ts index 34885d0d5d..9d2975b612 100644 --- a/tests/e2e/issue-sidebar.test.e2e.ts +++ b/tests/e2e/issue-sidebar.test.e2e.ts @@ -50,7 +50,6 @@ test.describe('Pull: Toggle WIP', () => { test('simple toggle', async ({page}, workerInfo) => { test.skip(workerInfo.project.name === 'Mobile Safari', 'Unable to get tests working on Safari Mobile, see https://codeberg.org/forgejo/forgejo/pulls/3445#issuecomment-1789636'); - await page.goto('/user2/repo1/pulls/5'); // toggle to WIP await toggle_wip_to({page}, true); await check_wip({page}, true); diff --git a/tests/e2e/login.test.e2e.ts b/tests/e2e/login.test.e2e.ts index 1ffa0b2e5d..01cf4d7b8d 100644 --- a/tests/e2e/login.test.e2e.ts +++ b/tests/e2e/login.test.e2e.ts @@ -10,7 +10,8 @@ import {expect} from '@playwright/test'; import {test, save_visual, test_context} from './utils_e2e.ts'; -test('Mismatched ROOT_URL', async ({browser}) => { +test('Mismatched ROOT_URL', async ({browser}, workerInfo) => { + test.skip(['Mobile Safari', 'webkit'].includes(workerInfo.project.name), 'init script gets randomly ignored'); const context = await test_context(browser); const page = await context.newPage(); diff --git a/tests/e2e/webauthn.test.e2e.ts b/tests/e2e/webauthn.test.e2e.ts index 0b5a6a6c2b..d4b81621d2 100644 --- a/tests/e2e/webauthn.test.e2e.ts +++ b/tests/e2e/webauthn.test.e2e.ts @@ -42,7 +42,6 @@ test('WebAuthn register & login flow', async ({browser, request}, workerInfo) => await page.locator('div[aria-label="Profile and settings…"]').click(); await page.getByText('Sign out').click(); }).toPass(); - await page.waitForURL(`${workerInfo.project.use.baseURL}/`); // Login. response = await page.goto('/user/login'); diff --git a/tests/integration/actions_run_now_done_notification_test.go b/tests/integration/actions_run_now_done_notification_test.go index d5142096c5..480d67a73d 100644 --- a/tests/integration/actions_run_now_done_notification_test.go +++ b/tests/integration/actions_run_now_done_notification_test.go @@ -49,41 +49,22 @@ func (m *mockNotifier) ActionRunNowDone(ctx context.Context, run *actions_model. assert.Equal(m.t, m.runID, run.ID) assert.Equal(m.t, actions_model.StatusFailure, run.Status) assert.Equal(m.t, actions_model.StatusRunning, priorStatus) - assert.Equal(m.t, m.lastRunID, lastRun.ID) - assert.Equal(m.t, actions_model.StatusSuccess, lastRun.Status) assert.True(m.t, run.NotifyEmail) case 2: assert.Equal(m.t, m.runID, run.ID) assert.Equal(m.t, actions_model.StatusCancelled, run.Status) assert.Equal(m.t, actions_model.StatusRunning, priorStatus) - assert.Equal(m.t, m.lastRunID, lastRun.ID) - assert.Equal(m.t, actions_model.StatusFailure, lastRun.Status) - assert.True(m.t, run.NotifyEmail) - case 3: - assert.Equal(m.t, m.runID, run.ID) - assert.Equal(m.t, actions_model.StatusSuccess, run.Status) - assert.Equal(m.t, actions_model.StatusRunning, priorStatus) - assert.Equal(m.t, m.lastRunID, lastRun.ID) - assert.Equal(m.t, actions_model.StatusCancelled, lastRun.Status) - assert.True(m.t, run.NotifyEmail) - case 4: - assert.Equal(m.t, m.runID, run.ID) - assert.Equal(m.t, actions_model.StatusSuccess, run.Status) - assert.Equal(m.t, actions_model.StatusRunning, priorStatus) - assert.Equal(m.t, m.lastRunID, lastRun.ID) - assert.Equal(m.t, actions_model.StatusSuccess, lastRun.Status) assert.True(m.t, run.NotifyEmail) default: assert.Fail(m.t, "too many notifications") } - m.lastRunID = m.runID m.runID++ m.testIdx++ } // ensure all tests have been run func (m *mockNotifier) complete() { - assert.Equal(m.t, 5, m.testIdx) + assert.Equal(m.t, 3, m.testIdx) } func TestActionNowDoneNotification(t *testing.T) { @@ -159,24 +140,6 @@ func TestActionNowDoneNotification(t *testing.T) { task = runner.fetchTask(t) require.NoError(t, actions_service.StopTask(db.DefaultContext, task.Id, actions_model.StatusCancelled)) - // we can't differentiate different runs without a delay - time.Sleep(time.Millisecond * 2000) - - // 3: successful run after failure - _, _, err = workflow.Dispatch(db.DefaultContext, inputGetter, repo, user2) - require.NoError(t, err) - task = runner.fetchTask(t) - runner.succeedAtTask(t, task) - - // we can't differentiate different runs without a delay - time.Sleep(time.Millisecond * 2000) - - // 4: successful run after success - _, _, err = workflow.Dispatch(db.DefaultContext, inputGetter, repo, user2) - require.NoError(t, err) - task = runner.fetchTask(t) - runner.succeedAtTask(t, task) - notifier.complete() }) } diff --git a/tests/integration/activitypub_client_test.go b/tests/integration/activitypub_client_test.go index afafca52ae..2adb8304c2 100644 --- a/tests/integration/activitypub_client_test.go +++ b/tests/integration/activitypub_client_test.go @@ -29,7 +29,7 @@ func TestActivityPubClientBodySize(t *testing.T) { clientFactory, err := activitypub.GetClientFactory(db.DefaultContext) require.NoError(t, err) - apClient, err := clientFactory.WithKeys(db.DefaultContext, user1, user1.APActorKeyID()) + apClient, err := clientFactory.WithKeys(db.DefaultContext, user1, user1.KeyID()) require.NoError(t, err) url := u.JoinPath("/api/v1/nodeinfo").String() diff --git a/tests/integration/api_activitypub_actor_test.go b/tests/integration/api_activitypub_actor_test.go deleted file mode 100644 index 778a34d785..0000000000 --- a/tests/integration/api_activitypub_actor_test.go +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2024 The Forgejo Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package integration - -import ( - "net/http" - "testing" - - "forgejo.org/modules/setting" - "forgejo.org/modules/test" - "forgejo.org/routers" - "forgejo.org/tests" - - ap "github.com/go-ap/activitypub" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestActivityPubActor(t *testing.T) { - defer test.MockVariableValue(&setting.Federation.Enabled, true)() - defer test.MockVariableValue(&testWebRoutes, routers.NormalRoutes())() - defer tests.PrepareTestEnv(t)() - - req := NewRequest(t, "GET", "/api/v1/activitypub/actor") - resp := MakeRequest(t, req, http.StatusOK) - assert.Contains(t, resp.Body.String(), "@context") - - var actor ap.Actor - err := actor.UnmarshalJSON(resp.Body.Bytes()) - require.NoError(t, err) - - assert.Equal(t, ap.ApplicationType, actor.Type) - assert.Equal(t, setting.Domain, actor.PreferredUsername.String()) - keyID := actor.GetID().String() - assert.Regexp(t, "activitypub/actor$", keyID) - assert.Regexp(t, "activitypub/actor/outbox$", actor.Outbox.GetID().String()) - assert.Regexp(t, "activitypub/actor/inbox$", actor.Inbox.GetID().String()) - - pubKey := actor.PublicKey - assert.NotNil(t, pubKey) - publicKeyID := keyID + "#main-key" - assert.Equal(t, pubKey.ID.String(), publicKeyID) - - pubKeyPem := pubKey.PublicKeyPem - assert.NotNil(t, pubKeyPem) - assert.Regexp(t, "^-----BEGIN PUBLIC KEY-----", pubKeyPem) -} diff --git a/tests/integration/api_activitypub_person_test.go b/tests/integration/api_activitypub_person_test.go deleted file mode 100644 index c89951ecf1..0000000000 --- a/tests/integration/api_activitypub_person_test.go +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2022 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package integration - -import ( - "fmt" - "net/http" - "net/url" - "testing" - - "forgejo.org/models/db" - "forgejo.org/models/unittest" - user_model "forgejo.org/models/user" - "forgejo.org/modules/activitypub" - "forgejo.org/modules/setting" - "forgejo.org/modules/test" - "forgejo.org/routers" - "forgejo.org/tests" - - ap "github.com/go-ap/activitypub" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestActivityPubPerson(t *testing.T) { - defer test.MockVariableValue(&setting.Federation.Enabled, true)() - defer test.MockVariableValue(&testWebRoutes, routers.NormalRoutes())() - onGiteaRun(t, func(t *testing.T, u *url.URL) { - userID := 2 - username := "user2" - userURL := fmt.Sprintf("%sapi/v1/activitypub/user-id/%d", u, userID) - - user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) - - clientFactory, err := activitypub.GetClientFactory(db.DefaultContext) - require.NoError(t, err) - - apClient, err := clientFactory.WithKeys(db.DefaultContext, user1, user1.APActorKeyID()) - require.NoError(t, err) - - // Unsigned request - t.Run("UnsignedRequest", func(t *testing.T) { - req := NewRequest(t, "GET", userURL) - MakeRequest(t, req, http.StatusBadRequest) - }) - - t.Run("SignedRequestValidation", func(t *testing.T) { - // Signed request - resp, err := apClient.GetBody(userURL) - require.NoError(t, err) - - var person ap.Person - err = person.UnmarshalJSON(resp) - require.NoError(t, err) - - assert.Equal(t, ap.PersonType, person.Type) - assert.Equal(t, username, person.PreferredUsername.String()) - assert.Regexp(t, fmt.Sprintf("activitypub/user-id/%d$", userID), person.GetID()) - assert.Regexp(t, fmt.Sprintf("activitypub/user-id/%d/outbox$", userID), person.Outbox.GetID().String()) - assert.Regexp(t, fmt.Sprintf("activitypub/user-id/%d/inbox$", userID), person.Inbox.GetID().String()) - - assert.NotNil(t, person.PublicKey) - assert.Regexp(t, fmt.Sprintf("activitypub/user-id/%d#main-key$", userID), person.PublicKey.ID) - - assert.NotNil(t, person.PublicKey.PublicKeyPem) - assert.Regexp(t, "^-----BEGIN PUBLIC KEY-----", person.PublicKey.PublicKeyPem) - }) - }) -} - -func TestActivityPubMissingPerson(t *testing.T) { - defer test.MockVariableValue(&setting.Federation.Enabled, true)() - defer test.MockVariableValue(&testWebRoutes, routers.NormalRoutes())() - defer tests.PrepareTestEnv(t)() - - req := NewRequest(t, "GET", "/api/v1/activitypub/user-id/999999999") - resp := MakeRequest(t, req, http.StatusNotFound) - assert.Contains(t, resp.Body.String(), "user does not exist") -} - -func TestActivityPubPersonInbox(t *testing.T) { - defer test.MockVariableValue(&setting.Federation.Enabled, true)() - defer test.MockVariableValue(&testWebRoutes, routers.NormalRoutes())() - - onGiteaRun(t, func(t *testing.T, u *url.URL) { - defer test.MockVariableValue(&setting.AppURL, u.String())() - user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) - - user1url := u.JoinPath("/api/v1/activitypub/user-id/1").String() + "#main-key" - cf, err := activitypub.GetClientFactory(db.DefaultContext) - require.NoError(t, err) - c, err := cf.WithKeys(db.DefaultContext, user1, user1url) - require.NoError(t, err) - user2inboxurl := u.JoinPath("/api/v1/activitypub/user-id/2/inbox").String() - - // Signed request succeeds - resp, err := c.Post([]byte{}, user2inboxurl) - require.NoError(t, err) - assert.Equal(t, http.StatusNoContent, resp.StatusCode) - - // Unsigned request fails - req := NewRequest(t, "POST", user2inboxurl) - MakeRequest(t, req, http.StatusBadRequest) - }) -} diff --git a/tests/integration/api_activitypub_repository_test.go b/tests/integration/api_activitypub_repository_test.go deleted file mode 100644 index fd19b4ce33..0000000000 --- a/tests/integration/api_activitypub_repository_test.go +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright 2024, 2025 The Forgejo Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package integration - -import ( - "fmt" - "net/http" - "net/url" - "testing" - "time" - - "forgejo.org/models/db" - "forgejo.org/models/forgefed" - "forgejo.org/models/unittest" - "forgejo.org/models/user" - "forgejo.org/modules/activitypub" - forgefed_modules "forgejo.org/modules/forgefed" - "forgejo.org/modules/setting" - "forgejo.org/modules/test" - "forgejo.org/routers" - "forgejo.org/tests" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestActivityPubRepository(t *testing.T) { - defer test.MockVariableValue(&setting.Federation.Enabled, true)() - defer test.MockVariableValue(&testWebRoutes, routers.NormalRoutes())() - - onGiteaRun(t, func(t *testing.T, u *url.URL) { - repositoryID := 2 - - apServerActor := user.NewAPServerActor() - - cf, err := activitypub.GetClientFactory(db.DefaultContext) - require.NoError(t, err) - - c, err := cf.WithKeys(db.DefaultContext, apServerActor, apServerActor.APActorKeyID()) - require.NoError(t, err) - - resp, err := c.GetBody(fmt.Sprintf("%sapi/v1/activitypub/repository-id/%d", u, repositoryID)) - require.NoError(t, err) - assert.Contains(t, string(resp), "@context") - - var repository forgefed_modules.Repository - err = repository.UnmarshalJSON(resp) - require.NoError(t, err) - - assert.Regexp(t, fmt.Sprintf("activitypub/repository-id/%d$", repositoryID), repository.GetID().String()) - }) -} - -func TestActivityPubMissingRepository(t *testing.T) { - defer test.MockVariableValue(&setting.Federation.Enabled, true)() - defer test.MockVariableValue(&testWebRoutes, routers.NormalRoutes())() - defer tests.PrepareTestEnv(t)() - - repositoryID := 9999999 - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/activitypub/repository-id/%d", repositoryID)) - resp := MakeRequest(t, req, http.StatusNotFound) - assert.Contains(t, resp.Body.String(), "repository does not exist") -} - -func TestActivityPubRepositoryInboxValid(t *testing.T) { - defer test.MockVariableValue(&setting.Federation.Enabled, true)() - defer test.MockVariableValue(&testWebRoutes, routers.NormalRoutes())() - - mock := test.NewFederationServerMock() - federatedSrv := mock.DistantServer(t) - defer federatedSrv.Close() - - onGiteaRun(t, func(t *testing.T, u *url.URL) { - apServerActor := user.NewAPServerActor() - repositoryID := 2 - timeNow := time.Now().UTC() - - cf, err := activitypub.GetClientFactory(db.DefaultContext) - require.NoError(t, err) - - c, err := cf.WithKeys(db.DefaultContext, apServerActor, apServerActor.APActorKeyID()) - require.NoError(t, err) - - repoInboxURL := u.JoinPath(fmt.Sprintf("/api/v1/activitypub/repository-id/%d/inbox", repositoryID)).String() - - activity1 := []byte(fmt.Sprintf( - `{"type":"Like",`+ - `"startTime":"%s",`+ - `"actor":"%s/api/v1/activitypub/user-id/15",`+ - `"object":"%s"}`, - timeNow.Format(time.RFC3339), - federatedSrv.URL, u.JoinPath(fmt.Sprintf("/api/v1/activitypub/repository-id/%d", repositoryID)).String())) - t.Logf("activity: %s", activity1) - resp, err := c.Post(activity1, repoInboxURL) - - require.NoError(t, err) - assert.Equal(t, http.StatusNoContent, resp.StatusCode) - - federationHost := unittest.AssertExistsAndLoadBean(t, &forgefed.FederationHost{HostFqdn: "127.0.0.1"}) - federatedUser := unittest.AssertExistsAndLoadBean(t, &user.FederatedUser{ExternalID: "15", FederationHostID: federationHost.ID}) - unittest.AssertExistsAndLoadBean(t, &user.User{ID: federatedUser.UserID}) - - // A like activity by a different user of the same federated host. - activity2 := []byte(fmt.Sprintf( - `{"type":"Like",`+ - `"startTime":"%s",`+ - `"actor":"%s/api/v1/activitypub/user-id/30",`+ - `"object":"%s"}`, - // Make sure this activity happens later then the one before - timeNow.Add(time.Second).Format(time.RFC3339), - federatedSrv.URL, u.JoinPath(fmt.Sprintf("/api/v1/activitypub/repository-id/%d", repositoryID)).String())) - t.Logf("activity: %s", activity2) - resp, err = c.Post(activity2, repoInboxURL) - - require.NoError(t, err) - assert.Equal(t, http.StatusNoContent, resp.StatusCode) - - federatedUser = unittest.AssertExistsAndLoadBean(t, &user.FederatedUser{ExternalID: "30", FederationHostID: federationHost.ID}) - unittest.AssertExistsAndLoadBean(t, &user.User{ID: federatedUser.UserID}) - - // The same user sends another like activity - otherRepositoryID := 3 - otherRepoInboxURL := u.JoinPath(fmt.Sprintf("/api/v1/activitypub/repository-id/%d/inbox", otherRepositoryID)).String() - activity3 := []byte(fmt.Sprintf( - `{"type":"Like",`+ - `"startTime":"%s",`+ - `"actor":"%s/api/v1/activitypub/user-id/30",`+ - `"object":"%s"}`, - // Make sure this activity happens later then the ones before - timeNow.Add(time.Second*2).Format(time.RFC3339), - federatedSrv.URL, u.JoinPath(fmt.Sprintf("/api/v1/activitypub/repository-id/%d", otherRepositoryID)).String())) - t.Logf("activity: %s", activity3) - resp, err = c.Post(activity3, otherRepoInboxURL) - - require.NoError(t, err) - assert.Equal(t, http.StatusNoContent, resp.StatusCode) - - federatedUser = unittest.AssertExistsAndLoadBean(t, &user.FederatedUser{ExternalID: "30", FederationHostID: federationHost.ID}) - unittest.AssertExistsAndLoadBean(t, &user.User{ID: federatedUser.UserID}) - - // Replay activity2. - resp, err = c.Post(activity2, repoInboxURL) - require.NoError(t, err) - assert.Equal(t, http.StatusNotAcceptable, resp.StatusCode) - }) -} - -func TestActivityPubRepositoryInboxInvalid(t *testing.T) { - defer test.MockVariableValue(&setting.Federation.Enabled, true)() - defer test.MockVariableValue(&testWebRoutes, routers.NormalRoutes())() - - onGiteaRun(t, func(t *testing.T, u *url.URL) { - apServerActor := user.NewAPServerActor() - repositoryID := 2 - - cf, err := activitypub.GetClientFactory(db.DefaultContext) - require.NoError(t, err) - - c, err := cf.WithKeys(db.DefaultContext, apServerActor, apServerActor.APActorKeyID()) - require.NoError(t, err) - - repoInboxURL := u.JoinPath(fmt.Sprintf("/api/v1/activitypub/repository-id/%d/inbox", repositoryID)).String() - activity := []byte(`{"type":"Wrong"}`) - resp, err := c.Post(activity, repoInboxURL) - require.NoError(t, err) - assert.Equal(t, http.StatusNotAcceptable, resp.StatusCode) - }) -} diff --git a/tests/integration/api_federation_httpsig_test.go b/tests/integration/api_federation_httpsig_test.go deleted file mode 100644 index a7a5ae26ed..0000000000 --- a/tests/integration/api_federation_httpsig_test.go +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright 2025 The Forgejo Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package integration - -import ( - "fmt" - "net/http" - "net/url" - "testing" - - "forgejo.org/models/db" - "forgejo.org/models/forgefed" - "forgejo.org/models/unittest" - "forgejo.org/models/user" - "forgejo.org/modules/activitypub" - "forgejo.org/modules/setting" - "forgejo.org/modules/test" - "forgejo.org/routers" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestFederationHttpSigValidation(t *testing.T) { - defer test.MockVariableValue(&setting.Federation.Enabled, true)() - defer test.MockVariableValue(&testWebRoutes, routers.NormalRoutes())() - - onGiteaRun(t, func(t *testing.T, u *url.URL) { - userID := 2 - userURL := fmt.Sprintf("%sapi/v1/activitypub/user-id/%d", u, userID) - - user1 := unittest.AssertExistsAndLoadBean(t, &user.User{ID: 1}) - - clientFactory, err := activitypub.GetClientFactory(db.DefaultContext) - require.NoError(t, err) - - apClient, err := clientFactory.WithKeys(db.DefaultContext, user1, user1.APActorKeyID()) - require.NoError(t, err) - - // Unsigned request - t.Run("UnsignedRequest", func(t *testing.T) { - req := NewRequest(t, "GET", userURL) - MakeRequest(t, req, http.StatusBadRequest) - }) - - // Signed request - t.Run("SignedRequest", func(t *testing.T) { - resp, err := apClient.Get(userURL) - require.NoError(t, err) - assert.Equal(t, http.StatusOK, resp.StatusCode) - }) - - // HACK HACK HACK: the host part of the URL gets set to which IP forgejo is - // listening on, NOT localhost, which is the Domain given to forgejo which - // is then used for eg. the keyID all requests - applicationKeyID := fmt.Sprintf("%sapi/v1/activitypub/actor#main-key", setting.AppURL) - actorKeyID := fmt.Sprintf("%sapi/v1/activitypub/user-id/1#main-key", setting.AppURL) - - // Check for cached public keys - t.Run("ValidateCaches", func(t *testing.T) { - host, err := forgefed.FindFederationHostByKeyID(db.DefaultContext, applicationKeyID) - require.NoError(t, err) - assert.NotNil(t, host) - assert.True(t, host.PublicKey.Valid) - - _, user, err := user.FindFederatedUserByKeyID(db.DefaultContext, actorKeyID) - require.NoError(t, err) - assert.NotNil(t, user) - assert.True(t, user.PublicKey.Valid) - }) - - // Disable signature validation - defer test.MockVariableValue(&setting.Federation.SignatureEnforced, false)() - - // Unsigned request - t.Run("SignatureValidationDisabled", func(t *testing.T) { - req := NewRequest(t, "GET", userURL) - MakeRequest(t, req, http.StatusOK) - }) - }) -} diff --git a/tests/integration/api_packages_alt_test.go b/tests/integration/api_packages_alt_test.go index c7ee2c49a5..f43759364e 100644 --- a/tests/integration/api_packages_alt_test.go +++ b/tests/integration/api_packages_alt_test.go @@ -214,7 +214,7 @@ enabled=1`, } assert.Equal(t, "classic", result.Component) - assert.Equal(t, "Alt Linux Team", result.Origin) + assert.Equal(t, "Forgejo", result.Origin) assert.Equal(t, "Forgejo", result.Label) assert.Equal(t, "x86_64", result.Architecture) assert.False(t, result.NotAutomatic) @@ -299,17 +299,17 @@ enabled=1`, assert.Equal(t, "Forgejo", result.Origin) assert.Equal(t, "Forgejo", result.Label) - assert.Equal(t, "Sisyphus", result.Suite) + assert.Equal(t, "Unknown", result.Suite) assert.Equal(t, "x86_64", result.Architectures) assert.Len(t, result.MD5Sum, 3) - assert.Equal(t, "bbf7ae6b2f540673ed1cfc0266b5f319", result.MD5Sum[0].Hash) - assert.Equal(t, 1003, result.MD5Sum[0].Size) + assert.Equal(t, "3f25f44163e8e512efb248d3b96949c3", result.MD5Sum[0].Hash) + assert.Equal(t, 1147, result.MD5Sum[0].Size) assert.Equal(t, "base/pkglist.classic", result.MD5Sum[0].File) assert.Len(t, result.BLAKE2B, 3) - assert.Equal(t, "b527bf038895ce29107ec3a6d2eebd7c365e8ce5ab767276eeddd7c549a159025225cb0ecfdbf7b71da13db7e865e77bcb0e2dae4d21335df01a4a17e0056a70", result.BLAKE2B[0].Hash) - assert.Equal(t, 1003, result.BLAKE2B[0].Size) + assert.Equal(t, "21a63e12a41f70e0697d354ae31e22ad6f024ec5ead2ea498b9a1b7db0f98a4e441f46c96d6912fba19148ff013457561fbb9bf3fca2a21d04cf15a325be7de9", result.BLAKE2B[0].Hash) + assert.Equal(t, 1147, result.BLAKE2B[0].Size) assert.Equal(t, "base/pkglist.classic", result.BLAKE2B[0].File) }) @@ -567,9 +567,9 @@ enabled=1`, assert.Equal(t, "https://gitea.io", result.URL) assert.Equal(t, "x86_64", result.Arch) assert.Equal(t, "gitea-test-1.0.2-1.src.rpm", result.SourceRpm) - assert.Equal(t, []string{"", ""}, result.ProvideNames) + assert.Equal(t, []string{"gitea-test(x86-64)", "gitea-test(x86-64)"}, result.ProvideNames) assert.Equal(t, []int{16777226, 16777226, 16777226, 16777226, 16777226, 16777226, 16777226}, result.RequireFlags) - assert.Equal(t, []string{"", "", "", "", "", "", ""}, result.RequireNames) + assert.Equal(t, []string{"rpmlib(PayloadIsXz)", "rpmlib(PayloadIsXz)", "rpmlib(PayloadIsXz)", "rpmlib(PayloadIsXz)", "rpmlib(PayloadIsXz)", "rpmlib(PayloadIsXz)", "rpmlib(PayloadIsXz)"}, result.RequireNames) assert.Equal(t, []string{"5.2-1", "5.2-1", "5.2-1", "5.2-1", "5.2-1", "5.2-1", "5.2-1"}, result.RequireVersions) assert.Equal(t, []int{1678276800}, result.ChangeLogTimes) assert.Equal(t, []string{"KN4CK3R "}, result.ChangeLogNames) diff --git a/tests/integration/issue_comment_test.go b/tests/integration/issue_comment_test.go index 0c53c3028b..6c4a514eba 100644 --- a/tests/integration/issue_comment_test.go +++ b/tests/integration/issue_comment_test.go @@ -223,15 +223,13 @@ func TestIssueCommentChangeAssignee(t *testing.T) { testIssueCommentChangeEvent(t, htmlDoc, "2041", "octicon-person", "User One", "/user1", []string{"user1 was unassigned by user2"}, - []string{"/user1"}) - // []string{"/user1", "/user2"}) + []string{"/user1", "/user2"}) // Add other testIssueCommentChangeEvent(t, htmlDoc, "2042", "octicon-person", "< Ur Tw ><", "/user2", []string{"user2 was assigned by user1"}, - []string{"/user2"}) - // []string{"/user2", "/user1"}) + []string{"/user2", "/user1"}) // Self-remove testIssueCommentChangeEvent(t, htmlDoc, "2043", diff --git a/tests/integration/issue_test.go b/tests/integration/issue_test.go index 34a6e53a37..72fe2a4e49 100644 --- a/tests/integration/issue_test.go +++ b/tests/integration/issue_test.go @@ -629,7 +629,12 @@ func TestIssueCommentAttachment(t *testing.T) { assert.NotEqual(t, 0, id) req = NewRequest(t, "GET", fmt.Sprintf("/%s/%s/comments/%d/attachments", "user2", "repo1", id)) - session.MakeRequest(t, req, http.StatusOK) + resp = session.MakeRequest(t, req, http.StatusOK) + var attachments []*api.WebAttachment + DecodeJSON(t, resp, &attachments) + assert.Len(t, attachments, 1) + assert.Equal(t, attachments[0].UUID, uuid) + assert.Equal(t, "image/png", attachments[0].MimeType) // Using the ID of a comment that does not belong to the repository must fail req = NewRequest(t, "GET", fmt.Sprintf("/%s/%s/comments/%d/attachments", "user5", "repo4", id)) diff --git a/tests/integration/oauth_test.go b/tests/integration/oauth_test.go index 2b44863ec2..188b0426da 100644 --- a/tests/integration/oauth_test.go +++ b/tests/integration/oauth_test.go @@ -632,17 +632,29 @@ func TestSignInOAuthCallbackPKCE(t *testing.T) { }) } -func TestWellKnownDocumentIssuerDoesNotEndWithASlash(t *testing.T) { +func TestWellKnownOpenIDConfiguration(t *testing.T) { defer tests.PrepareTestEnv(t)() - req := NewRequest(t, "GET", "/.well-known/openid-configuration") - resp := MakeRequest(t, req, http.StatusOK) - type response struct { - Issuer string `json:"issuer"` - } - parsed := new(response) - DecodeJSON(t, resp, parsed) - assert.Equal(t, strings.TrimSuffix(setting.AppURL, "/"), parsed.Issuer) + t.Run("Issuer does not end with a slash", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + req := NewRequest(t, "GET", "/.well-known/openid-configuration") + resp := MakeRequest(t, req, http.StatusOK) + type response struct { + Issuer string `json:"issuer"` + } + parsed := new(response) + + DecodeJSON(t, resp, parsed) + assert.Equal(t, strings.TrimSuffix(setting.AppURL, "/"), parsed.Issuer) + }) + + t.Run("Not found if OAuth2 is not enabled", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + defer test.MockVariableValue(&setting.OAuth2.Enabled, false)() + + MakeRequest(t, NewRequest(t, "GET", "/.well-known/openid-configuration"), http.StatusNotFound) + }) } func TestSignInOAuthCallbackRedirectToEscaping(t *testing.T) { diff --git a/tests/integration/pull_commit_test.go b/tests/integration/pull_commit_test.go index f82fc08df4..8a632fa338 100644 --- a/tests/integration/pull_commit_test.go +++ b/tests/integration/pull_commit_test.go @@ -65,7 +65,7 @@ func TestPullCommitLinks(t *testing.T) { func TestPullCommitSignature(t *testing.T) { t.Cleanup(func() { // Cannot use t.Context(), it is in the done state. - require.NoError(t, git.InitFull(context.Background())) //nolint:usetesting + require.NoError(t, git.InitFull(context.Background())) }) defer test.MockVariableValue(&setting.Repository.Signing.SigningName, "UwU")() diff --git a/tests/integration/pull_review_test.go b/tests/integration/pull_review_test.go index 603252f45f..4af0a1100e 100644 --- a/tests/integration/pull_review_test.go +++ b/tests/integration/pull_review_test.go @@ -5,19 +5,23 @@ package integration import ( + "bytes" "fmt" "io" "net/http" "net/http/httptest" "net/url" + "os" "path" "strconv" "strings" "testing" + "time" "forgejo.org/models/db" issues_model "forgejo.org/models/issues" repo_model "forgejo.org/models/repo" + unit_model "forgejo.org/models/unit" "forgejo.org/models/unittest" user_model "forgejo.org/models/user" "forgejo.org/modules/git" @@ -761,3 +765,158 @@ func updateFileInBranch(user *user_model.User, repo *repo_model.Repository, tree _, err = files_service.ChangeRepoFiles(git.DefaultContext, repo, user, opts) return err } + +func TestPullRequestStaleReview(t *testing.T) { + onGiteaRun(t, func(t *testing.T, u *url.URL) { + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + session := loginUser(t, user2.Name) + + // Create temporary repository. + repo, _, f := tests.CreateDeclarativeRepo(t, user2, "", + []unit_model.Type{unit_model.TypePullRequests}, nil, + []*files_service.ChangeRepoFile{ + { + Operation: "create", + TreePath: "FUNFACT", + ContentReader: strings.NewReader("Smithy was the runner up to be Forgejo's name"), + }, + }, + ) + defer f() + + // Clone it. + dstPath := t.TempDir() + r := fmt.Sprintf("%suser2/%s.git", u.String(), repo.Name) + cloneURL, _ := url.Parse(r) + cloneURL.User = url.UserPassword("user2", userPassword) + require.NoError(t, git.CloneWithArgs(t.Context(), nil, cloneURL.String(), dstPath, git.CloneRepoOptions{})) + + // Create first commit. + require.NoError(t, os.WriteFile(path.Join(dstPath, "README.md"), []byte("## test content"), 0o600)) + require.NoError(t, git.AddChanges(dstPath, true)) + require.NoError(t, git.CommitChanges(dstPath, git.CommitChangesOptions{ + Committer: &git.Signature{ + Email: "user2@example.com", + Name: "user2", + When: time.Now(), + }, + Author: &git.Signature{ + Email: "user2@example.com", + Name: "user2", + When: time.Now(), + }, + Message: "Add README.", + })) + stdout := &bytes.Buffer{} + require.NoError(t, git.NewCommand(t.Context(), "rev-parse", "HEAD").Run(&git.RunOpts{Dir: dstPath, Stdout: stdout})) + firstCommitID := strings.TrimSpace(stdout.String()) + + // Create agit PR. + require.NoError(t, git.NewCommand(t.Context(), "push", "origin", "HEAD:refs/for/main", "-o", "topic=agit-pr").Run(&git.RunOpts{Dir: dstPath})) + + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{Index: 1, BaseRepoID: repo.ID}) + + req := NewRequest(t, "GET", "/"+repo.FullName()+"/pulls/1/files/reviews/new_comment") + resp := session.MakeRequest(t, req, http.StatusOK) + doc := NewHTMLParser(t, resp.Body) + + t.Run("Mark review as stale", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + // Create a approved review against against this commit. + req = NewRequestWithValues(t, "POST", "/"+repo.FullName()+"/pulls/1/files/reviews/comments", map[string]string{ + "_csrf": doc.GetCSRF(), + "origin": doc.GetInputValueByName("origin"), + "latest_commit_id": firstCommitID, + "side": "proposed", + "line": "1", + "path": "FUNFACT", + "diff_start_cid": doc.GetInputValueByName("diff_start_cid"), + "diff_end_cid": doc.GetInputValueByName("diff_end_cid"), + "diff_base_cid": doc.GetInputValueByName("diff_base_cid"), + "content": "nitpicking comment", + "pending_review": "", + }) + session.MakeRequest(t, req, http.StatusOK) + + req = NewRequestWithValues(t, "POST", "/"+repo.FullName()+"/pulls/1/files/reviews/submit", map[string]string{ + "_csrf": doc.GetCSRF(), + "commit_id": firstCommitID, + "content": "looks good", + "type": "comment", + }) + session.MakeRequest(t, req, http.StatusOK) + + // Review is not stale. + review := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{IssueID: pr.IssueID}) + assert.False(t, review.Stale) + + // Create second commit + require.NoError(t, os.WriteFile(path.Join(dstPath, "README.md"), []byte("## I prefer this heading"), 0o600)) + require.NoError(t, git.AddChanges(dstPath, true)) + require.NoError(t, git.CommitChanges(dstPath, git.CommitChangesOptions{ + Committer: &git.Signature{ + Email: "user2@example.com", + Name: "user2", + When: time.Now(), + }, + Author: &git.Signature{ + Email: "user2@example.com", + Name: "user2", + When: time.Now(), + }, + Message: "Add README.", + })) + + // Push to agit PR. + require.NoError(t, git.NewCommand(t.Context(), "push", "origin", "HEAD:refs/for/main", "-o", "topic=agit-pr").Run(&git.RunOpts{Dir: dstPath})) + + // Review is stale. + review = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{IssueID: pr.IssueID}) + assert.True(t, review.Stale) + }) + + t.Run("Create stale review", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + // Review based on the first commit, which is a stale review because the + // PR's head is at the seconnd commit. + req := NewRequestWithValues(t, "POST", "/"+repo.FullName()+"/pulls/1/files/reviews/submit", map[string]string{ + "_csrf": doc.GetCSRF(), + "commit_id": firstCommitID, + "content": "looks good", + "type": "approve", + }) + session.MakeRequest(t, req, http.StatusOK) + + // There does not exist a review that is not stale, because all reviews + // are based on the first commit and the PR's head is at the second commit. + unittest.AssertExistsIf(t, false, &issues_model.Review{IssueID: pr.IssueID}, "stale = false") + }) + + t.Run("Mark unstale", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + // Force push the PR to the first commit. + require.NoError(t, git.NewCommand(t.Context(), "reset", "--hard", "HEAD~1").Run(&git.RunOpts{Dir: dstPath})) + require.NoError(t, git.NewCommand(t.Context(), "push", "origin", "HEAD:refs/for/main", "-o", "topic=agit-pr", "-o", "force-push").Run(&git.RunOpts{Dir: dstPath})) + + // There does not exist a review that is stale, because all reviews + // are based on the first commit and thus all reviews are no longer marked + // as stale. + unittest.AssertExistsIf(t, false, &issues_model.Review{IssueID: pr.IssueID}, "stale = true") + }) + + t.Run("Diff did not change", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + // Create a empty commit and push it to the PR. + require.NoError(t, git.NewCommand(t.Context(), "commit", "--allow-empty", "-m", "Empty commit").Run(&git.RunOpts{Dir: dstPath})) + require.NoError(t, git.NewCommand(t.Context(), "push", "origin", "HEAD:refs/for/main", "-o", "topic=agit-pr").Run(&git.RunOpts{Dir: dstPath})) + + // There does not exist a review that is stale, because the diff did not + // change. + unittest.AssertExistsIf(t, false, &issues_model.Review{IssueID: pr.IssueID}, "stale = true") + }) + }) +} diff --git a/tests/integration/release_test.go b/tests/integration/release_test.go index b5cccc65e8..f9ce3c81de 100644 --- a/tests/integration/release_test.go +++ b/tests/integration/release_test.go @@ -70,7 +70,7 @@ func checkLatestReleaseAndCount(t *testing.T, session *TestSession, repoURL, ver // Check release count in the counter on the Release/Tag switch, as well as that the tab is highlighted if count < 10 { // Only check values less than 10, should be enough attempts before this test cracks // 10 is the pagination limit, but the counter can have more than that - releaseTab := htmlDoc.doc.Find(".repository.releases .ui.compact.menu a.active.item[href$='/releases']") + releaseTab := htmlDoc.doc.Find(".repository.releases .switch a.active.item[href$='/releases']") assert.Contains(t, releaseTab.Text(), strconv.Itoa(count)+" release") // Could be "1 release" or "4 releases" } diff --git a/tests/integration/repo_settings_test.go b/tests/integration/repo_settings_test.go index 63cc5332bc..6b467d78b2 100644 --- a/tests/integration/repo_settings_test.go +++ b/tests/integration/repo_settings_test.go @@ -6,21 +6,16 @@ package integration import ( "fmt" "net/http" - "strings" "testing" "forgejo.org/models/db" - "forgejo.org/models/forgefed" git_model "forgejo.org/models/git" repo_model "forgejo.org/models/repo" unit_model "forgejo.org/models/unit" "forgejo.org/models/unittest" user_model "forgejo.org/models/user" - fm "forgejo.org/modules/forgefed" "forgejo.org/modules/optional" "forgejo.org/modules/setting" - "forgejo.org/modules/test" - "forgejo.org/modules/validation" gitea_context "forgejo.org/services/context" repo_service "forgejo.org/services/repository" user_service "forgejo.org/services/user" @@ -311,63 +306,3 @@ func TestProtectedBranch(t *testing.T) { unittest.AssertCount(t, &git_model.ProtectedBranch{RuleName: "master", RepoID: repo.ID}, 1) }) } - -func TestRepoFollowing(t *testing.T) { - defer tests.PrepareTestEnv(t)() - defer test.MockVariableValue(&setting.Federation.Enabled, true)() - - mock := test.NewFederationServerMock() - federatedSrv := mock.DistantServer(t) - defer federatedSrv.Close() - - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1, OwnerID: user.ID}) - session := loginUser(t, user.Name) - - t.Run("Add a following repo", func(t *testing.T) { - defer tests.PrintCurrentTest(t)() - link := fmt.Sprintf("/%s/settings", repo.FullName()) - - req := NewRequestWithValues(t, "POST", link, map[string]string{ - "_csrf": GetCSRF(t, session, link), - "action": "federation", - "following_repos": fmt.Sprintf("%s/api/v1/activitypub/repository-id/1", federatedSrv.URL), - }) - session.MakeRequest(t, req, http.StatusSeeOther) - - // Verify it was added. - federationHost := unittest.AssertExistsAndLoadBean(t, &forgefed.FederationHost{HostFqdn: "127.0.0.1"}) - unittest.AssertExistsAndLoadBean(t, &repo_model.FollowingRepo{ - ExternalID: "1", - FederationHostID: federationHost.ID, - }) - }) - - t.Run("Star a repo having a following repo", func(t *testing.T) { - defer tests.PrintCurrentTest(t)() - repoLink := fmt.Sprintf("/%s", repo.FullName()) - link := fmt.Sprintf("%s/action/star", repoLink) - req := NewRequestWithValues(t, "POST", link, map[string]string{ - "_csrf": GetCSRF(t, session, repoLink), - }) - - session.MakeRequest(t, req, http.StatusOK) - - // Verify distant server received a like activity - like := fm.ForgeLike{} - err := like.UnmarshalJSON([]byte(mock.LastPost)) - if err != nil { - t.Errorf("Error unmarshalling ForgeLike: %q", err) - } - if isValid, err := validation.IsValid(like); !isValid { - t.Errorf("ForgeLike is not valid: %q", err) - } - activityType := like.Type - object := like.Object.GetLink().String() - isLikeType := activityType == "Like" - isCorrectObject := strings.HasSuffix(object, "/api/v1/activitypub/repository-id/1") - if !isLikeType || !isCorrectObject { - t.Error("Activity is not a like for this repo") - } - }) -} diff --git a/tests/integration/repo_tag_test.go b/tests/integration/repo_tag_test.go index 9be33ec8a8..4f72b58d12 100644 --- a/tests/integration/repo_tag_test.go +++ b/tests/integration/repo_tag_test.go @@ -41,11 +41,11 @@ func TestTagViewWithoutRelease(t *testing.T) { // Test that the tags sub-menu is active and has a counter htmlDoc := NewHTMLParser(t, resp.Body) - tagsTab := htmlDoc.Find(".small-menu-items .active.item[href$='/tags']") + tagsTab := htmlDoc.Find(".switch .active.item[href$='/tags']") assert.Contains(t, tagsTab.Text(), "4 tags") // Test that the release sub-menu isn't active - releaseLink := htmlDoc.Find(".small-menu-items .item[href$='/releases']") + releaseLink := htmlDoc.Find(".switch .item[href$='/releases']") assert.False(t, releaseLink.HasClass("active")) // Test that the title is displayed diff --git a/tests/integration/repo_test.go b/tests/integration/repo_test.go index 598a508294..3d5922c0b1 100644 --- a/tests/integration/repo_test.go +++ b/tests/integration/repo_test.go @@ -690,7 +690,7 @@ func TestViewCommit(t *testing.T) { func TestViewCommitSignature(t *testing.T) { t.Cleanup(func() { // Cannot use t.Context(), it is in the done state. - require.NoError(t, git.InitFull(context.Background())) //nolint:usetesting + require.NoError(t, git.InitFull(context.Background())) }) defer test.MockVariableValue(&setting.Repository.Signing.SigningName, "UwU")() diff --git a/tests/integration/signing_git_test.go b/tests/integration/signing_git_test.go index 8b6b30ecab..7018b10376 100644 --- a/tests/integration/signing_git_test.go +++ b/tests/integration/signing_git_test.go @@ -32,7 +32,7 @@ import ( func TestInstanceSigning(t *testing.T) { t.Cleanup(func() { // Cannot use t.Context(), it is in the done state. - require.NoError(t, git.InitFull(context.Background())) //nolint:usetesting + require.NoError(t, git.InitFull(context.Background())) }) onGiteaRun(t, func(t *testing.T, u *url.URL) { diff --git a/tests/integration/webfinger_test.go b/tests/integration/webfinger_test.go index 078be6fa54..9708fc1627 100644 --- a/tests/integration/webfinger_test.go +++ b/tests/integration/webfinger_test.go @@ -52,6 +52,15 @@ func TestWebfinger(t *testing.T) { assert.Equal(t, "acct:user2@"+appURL.Host, jrd.Subject) assert.ElementsMatch(t, []string{user.HTMLURL(), appURL.String() + "api/v1/activitypub/user-id/" + fmt.Sprint(user.ID)}, jrd.Aliases) + instanceReq := NewRequest(t, "GET", fmt.Sprintf("/.well-known/webfinger?resource=acct:ghost@%s", appURL.Host)) + instanceResp := MakeRequest(t, instanceReq, http.StatusOK) + assert.Equal(t, "application/jrd+json", instanceResp.Header().Get("Content-Type")) + + var instanceActor webfingerJRD + DecodeJSON(t, instanceResp, &instanceActor) + assert.Equal(t, "acct:ghost@"+appURL.Host, instanceActor.Subject) + assert.ElementsMatch(t, []string{appURL.String() + "api/v1/activitypub/actor"}, instanceActor.Aliases) + req = NewRequest(t, "GET", fmt.Sprintf("/.well-known/webfinger?resource=acct:%s@%s", user.LowerName, "unknown.host")) MakeRequest(t, req, http.StatusBadRequest) diff --git a/web_src/css/repo/release-tag.css b/web_src/css/repo/release-tag.css index 9860813e98..4a4158f4ba 100644 --- a/web_src/css/repo/release-tag.css +++ b/web_src/css/repo/release-tag.css @@ -110,6 +110,12 @@ .repository.new.release .field button { margin-bottom: 1em; } + .release-list-search { + order: 2 !important; + } + .release-list-buttons { + margin-left: auto; + } } .repository.new.release .field .attachment_edit { diff --git a/web_src/fomantic/package-lock.json b/web_src/fomantic/package-lock.json index d91eb98866..314afd5869 100644 --- a/web_src/fomantic/package-lock.json +++ b/web_src/fomantic/package-lock.json @@ -494,9 +494,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "24.0.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.7.tgz", - "integrity": "sha512-YIEUUr4yf8q8oQoXPpSlnvKNVKDQlPMWrmOcgzoduo7kvA2UF0/BwJ/eMKFTiTtkNL17I0M6Xe2tvwFU7be6iw==", + "version": "24.0.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.10.tgz", + "integrity": "sha512-ENHwaH+JIRTDIEEbDK6QSQntAYGtbvdDXnMXnZaZ6k13Du1dPMmprkEHIL7ok2Wl2aZevetwTAb5S+7yIF+enA==", "license": "MIT", "dependencies": { "undici-types": "~7.8.0" @@ -1249,9 +1249,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001726", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001726.tgz", - "integrity": "sha512-VQAUIUzBiZ/UnlM28fSp2CRF3ivUn1BWEvxMcVTNwpw91Py1pGbPIyIKtd+tzct9C3ouceCVdGAXxZOpZAsgdw==", + "version": "1.0.30001727", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz", + "integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==", "funding": [ { "type": "opencollective", @@ -2005,9 +2005,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.177", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.177.tgz", - "integrity": "sha512-7EH2G59nLsEMj97fpDuvVcYi6lwTcM1xuWw3PssD8xzboAW7zj7iB3COEEEATUfjLHrs5uKBLQT03V/8URx06g==", + "version": "1.5.179", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.179.tgz", + "integrity": "sha512-UWKi/EbBopgfFsc5k61wFpV7WrnnSlSzW/e2XcBmS6qKYTivZlLtoll5/rdqRTxGglGHkmkW0j0pFNJG10EUIQ==", "license": "ISC" }, "node_modules/emoji-regex": { diff --git a/web_src/js/features/common-global.js b/web_src/js/features/common-global.js index 1aa9edf60f..c6cb4fa47c 100644 --- a/web_src/js/features/common-global.js +++ b/web_src/js/features/common-global.js @@ -208,65 +208,133 @@ export function initGlobalDropzone() { } } -export function initDropzone(el) { - const $dropzone = $(el); - const _promise = createDropzone(el, { - url: $dropzone.data('upload-url'), +export async function initDropzone(dropzoneEl, zone = undefined) { + if (!dropzoneEl) return; + + let disableRemovedfileEvent = false; // when resetting the dropzone (removeAllFiles), disable the "removedfile" event + let fileUuidDict = {}; // to record: if a comment has been saved, then the uploaded files won't be deleted from server when clicking the Remove in the dropzone + + const initFilePreview = (file, data, isReload = false) => { + file.uuid = data.uuid; + fileUuidDict[file.uuid] = {submitted: isReload}; + const input = document.createElement('input'); + input.id = data.uuid; + input.name = 'files'; + input.type = 'hidden'; + input.value = data.uuid; + const inputPath = document.createElement('input'); + inputPath.name = `files_fullpath[${data.uuid}]`; + inputPath.type = 'hidden'; + inputPath.value = htmlEscape(file.fullPath || file.name); + dropzoneEl.querySelector('.files').append(input).append(inputPath); + + // Create a "Copy Link" element, to conveniently copy the image + // or file link as Markdown to the clipboard + const copyLinkElement = document.createElement('div'); + copyLinkElement.className = 'tw-text-center'; + // The a element has a hardcoded cursor: pointer because the default is overridden by .dropzone + copyLinkElement.innerHTML = `${svg('octicon-copy', 14, 'copy link')} Copy link`; + copyLinkElement.addEventListener('click', async (e) => { + e.preventDefault(); + const name = file.name.slice(0, file.name.lastIndexOf('.')); + let fileMarkdown = `[${name}](/attachments/${file.uuid})`; + if (file.type.startsWith('image/')) { + fileMarkdown = `!${fileMarkdown}`; + } else if (file.type.startsWith('video/')) { + fileMarkdown = ``; + } + const success = await clippie(fileMarkdown); + showTemporaryTooltip(e.target, success ? i18n.copy_success : i18n.copy_error); + }); + file.previewTemplate.append(copyLinkElement); + }; + const updateDropzoneState = () => { + if (dropzoneEl.querySelector('.dz-preview')) { + dropzoneEl.classList.add('dz-started'); + } else { + dropzoneEl.classList.remove('dz-started'); + } + }; + + const dz = await createDropzone(dropzoneEl, { + url: dropzoneEl.getAttribute('data-upload-url'), headers: {'X-Csrf-Token': csrfToken}, - maxFiles: $dropzone.data('max-file'), - maxFilesize: $dropzone.data('max-size'), - acceptedFiles: (['*/*', ''].includes($dropzone.data('accepts'))) ? null : $dropzone.data('accepts'), + maxFiles: dropzoneEl.getAttribute('data-max-file'), + maxFilesize: dropzoneEl.getAttribute('data-max-size'), + acceptedFiles: (['*/*', ''].includes(dropzoneEl.getAttribute('data-accepts')) ? null : dropzoneEl.getAttribute('data-accepts')), addRemoveLinks: true, - dictDefaultMessage: $dropzone.data('default-message'), - dictInvalidFileType: $dropzone.data('invalid-input-type'), - dictFileTooBig: $dropzone.data('file-too-big'), - dictRemoveFile: $dropzone.data('remove-file'), + dictDefaultMessage: dropzoneEl.getAttribute('data-default-message'), + dictInvalidFileType: dropzoneEl.getAttribute('data-invalid-input-type'), + dictFileTooBig: dropzoneEl.getAttribute('data-file-too-big'), + dictRemoveFile: dropzoneEl.getAttribute('data-remove-file'), timeout: 0, thumbnailMethod: 'contain', thumbnailWidth: 480, thumbnailHeight: 480, init() { - this.on('success', (file, data) => { - file.uuid = data.uuid; - const $input = $(``).val(data.uuid); - const $inputPath = $(``); - $dropzone.find('.files').append($input).append($inputPath); - // Create a "Copy Link" element, to conveniently copy the image - // or file link as Markdown to the clipboard - const copyLinkElement = document.createElement('div'); - copyLinkElement.className = 'tw-text-center'; - // The a element has a hardcoded cursor: pointer because the default is overridden by .dropzone - copyLinkElement.innerHTML = `${svg('octicon-copy', 14, 'copy link')} Copy link`; - copyLinkElement.addEventListener('click', async (e) => { - e.preventDefault(); - let fileMarkdown = `[${file.name}](/attachments/${file.uuid})`; - if (file.type.startsWith('image/')) { - fileMarkdown = `!${fileMarkdown}`; - } else if (file.type.startsWith('video/')) { - fileMarkdown = ``; + this.on('success', initFilePreview); + this.on('removedfile', async (file) => { + document.getElementById(file.uuid)?.remove(); + document.querySelector(`input[name="files_fullpath[${file.uuid}]"]`)?.remove(); + if (disableRemovedfileEvent) return; + if (dropzoneEl.getAttribute('data-remove-url') && !fileUuidDict[file.uuid].submitted) { + try { + await POST(dropzoneEl.getAttribute('data-remove-url'), {data: new URLSearchParams({file: file.uuid})}); + } catch (error) { + console.error(error); } - const success = await clippie(fileMarkdown); - showTemporaryTooltip(e.target, success ? i18n.copy_success : i18n.copy_error); - }); - file.previewTemplate.append(copyLinkElement); - }); - this.on('removedfile', (file) => { - // Remove the hidden input for the file - $(`#${file.uuid}`).remove(); - - // Remove the hidden input for files_fullpath - $(`input[name="files_fullpath[${file.uuid}]"]`).remove(); - - if ($dropzone.data('remove-url')) { - POST($dropzone.data('remove-url'), { - data: new URLSearchParams({file: file.uuid}), - }); } + updateDropzoneState(); }); this.on('error', function (file, message) { showErrorToast(message); this.removeFile(file); }); + this.on('reload', async () => { + if (!zone || !dz.removeAllFiles) return; + try { + const response = await GET(zone.getAttribute('data-attachment-url')); + const data = await response.json(); + // do not trigger the "removedfile" event, otherwise the attachments would be deleted from server + disableRemovedfileEvent = true; + dz.removeAllFiles(true); + dropzoneEl.querySelector('.files').innerHTML = ''; + for (const element of dropzoneEl.querySelectorAll('.dz-preview')) element.remove(); + fileUuidDict = {}; + disableRemovedfileEvent = false; + + for (const attachment of data) { + attachment.type = attachment.mime_type; + dz.emit('addedfile', attachment); + dz.emit('complete', attachment); + if (attachment.type.startsWith('image/')) { + const imgSrc = `${dropzoneEl.getAttribute('data-link-url')}/${attachment.uuid}`; + dz.emit('thumbnail', attachment, imgSrc); + } + initFilePreview(attachment, {uuid: attachment.uuid}, true); + fileUuidDict[attachment.uuid] = {submitted: true}; + } + } catch (error) { + console.error(error); + } + updateDropzoneState(); + }); + this.on('create-thumbnail', (attachment, file) => { + if (attachment.type && /image.*/.test(attachment.type)) { + // When a new issue is created, a thumbnail cannot be fetch, so we need to create it locally. + // The implementation is took from the dropzone library (`dropzone.js` > `_processThumbnailQueue()`) + dz.createThumbnail( + file, + dz.options.thumbnailWidth, + dz.options.thumbnailHeight, + dz.options.thumbnailMethod, + true, + (dataUrl) => { + dz.emit('thumbnail', attachment, dataUrl); + }, + ); + } + }); }, }); } diff --git a/web_src/js/features/comp/Paste.js b/web_src/js/features/comp/Paste.js index 7e4ecbbeda..0fb6cf4615 100644 --- a/web_src/js/features/comp/Paste.js +++ b/web_src/js/features/comp/Paste.js @@ -82,9 +82,8 @@ class CodeMirrorEditor { async function handleClipboardImages(editor, dropzone, images, e) { const uploadUrl = dropzone.getAttribute('data-upload-url'); - const filesContainer = dropzone.querySelector('.files'); - if (!dropzone || !uploadUrl || !filesContainer || !images.length) return; + if (!dropzone || !uploadUrl || !images.length) return; e.preventDefault(); e.stopPropagation(); @@ -92,7 +91,7 @@ async function handleClipboardImages(editor, dropzone, images, e) { for (const img of images) { const name = img.name.slice(0, img.name.lastIndexOf('.')); - const placeholder = `![${name}](uploading ...)`; + const placeholder = `![${name}](uploading...)`; editor.insertPlaceholder(placeholder); const {uuid} = await uploadFile(img, uploadUrl); @@ -101,12 +100,11 @@ async function handleClipboardImages(editor, dropzone, images, e) { const text = `![${name}](${url})`; editor.replacePlaceholder(placeholder, text); - const input = document.createElement('input'); - input.setAttribute('name', 'files'); - input.setAttribute('type', 'hidden'); - input.setAttribute('id', uuid); - input.value = uuid; - filesContainer.append(input); + const attachment = {uuid, name: img.name, browser_download_url: url, size: img.size, type: img.type}; + dropzone.dropzone.emit('addedfile', attachment); + dropzone.dropzone.emit('create-thumbnail', attachment, img); + dropzone.dropzone.emit('complete', attachment); + dropzone.dropzone.emit('success', attachment, {uuid}); } } diff --git a/web_src/js/features/repo-issue.js b/web_src/js/features/repo-issue.js index bf76453428..d678d9195b 100644 --- a/web_src/js/features/repo-issue.js +++ b/web_src/js/features/repo-issue.js @@ -445,7 +445,7 @@ export async function handleReply($el) { // When the page is loaded, the dropzone is initialized by initGlobalDropzone, but the editor is not initialized. // When the form is submitted and partially reload, none of them is initialized. const dropzone = $form.find('.dropzone')[0]; - if (!dropzone.dropzone) initDropzone(dropzone); + if (!dropzone.dropzone) await initDropzone(dropzone); editor = await initComboMarkdownEditor($form.find('.combo-markdown-editor')); } editor.focus(); @@ -580,7 +580,7 @@ export function initRepoPullRequestReview() { $td.find("input[name='side']").val(side === 'left' ? 'previous' : 'proposed'); $td.find("input[name='path']").val(path); - initDropzone($td.find('.dropzone')[0]); + await initDropzone($td.find('.dropzone')[0]); const editor = await initComboMarkdownEditor($td.find('.combo-markdown-editor')); editor.focus(); } catch (error) { diff --git a/web_src/js/features/repo-legacy.js b/web_src/js/features/repo-legacy.js index 25ed181616..e6af4cbf04 100644 --- a/web_src/js/features/repo-legacy.js +++ b/web_src/js/features/repo-legacy.js @@ -16,7 +16,6 @@ import { import {initCitationFileCopyContent} from './citation.js'; import {initCompLabelEdit} from './comp/LabelEdit.js'; import {initRepoDiffConversationNav} from './repo-diff.js'; -import {createDropzone} from './dropzone.js'; import {showErrorToast} from '../modules/toast.js'; import {initCommentContent, initMarkupContent} from '../markup/content.js'; import {initCompReactionSelector} from './comp/ReactionSelector.js'; @@ -26,12 +25,10 @@ import {initRepoPullRequestCommitStatus} from './repo-issue-pr-status.js'; import {hideElem, showElem} from '../utils/dom.js'; import {getComboMarkdownEditor, initComboMarkdownEditor} from './comp/ComboMarkdownEditor.js'; import {attachRefIssueContextPopup} from './contextpopup.js'; -import {POST, GET} from '../modules/fetch.js'; +import {POST} from '../modules/fetch.js'; import {MarkdownQuote} from '@github/quote-selection'; import {toAbsoluteUrl} from '../utils.js'; -import {initGlobalShowModal} from './common-global.js'; - -const {csrfToken} = window.config; +import {initDropzone, initGlobalShowModal} from './common-global.js'; export function initRepoCommentForm() { const $commentForm = $('.comment.form'); @@ -312,115 +309,27 @@ async function onEditContent(event) { let comboMarkdownEditor; - /** - * @param {HTMLElement} dropzone - */ - const setupDropzone = async (dropzone) => { - if (!dropzone) return null; - - let disableRemovedfileEvent = false; // when resetting the dropzone (removeAllFiles), disable the "removedfile" event - let fileUuidDict = {}; // to record: if a comment has been saved, then the uploaded files won't be deleted from server when clicking the Remove in the dropzone - const dz = await createDropzone(dropzone, { - url: dropzone.getAttribute('data-upload-url'), - headers: {'X-Csrf-Token': csrfToken}, - maxFiles: dropzone.getAttribute('data-max-file'), - maxFilesize: dropzone.getAttribute('data-max-size'), - acceptedFiles: ['*/*', ''].includes(dropzone.getAttribute('data-accepts')) ? null : dropzone.getAttribute('data-accepts'), - addRemoveLinks: true, - dictDefaultMessage: dropzone.getAttribute('data-default-message'), - dictInvalidFileType: dropzone.getAttribute('data-invalid-input-type'), - dictFileTooBig: dropzone.getAttribute('data-file-too-big'), - dictRemoveFile: dropzone.getAttribute('data-remove-file'), - timeout: 0, - thumbnailMethod: 'contain', - thumbnailWidth: 480, - thumbnailHeight: 480, - init() { - this.on('success', (file, data) => { - file.uuid = data.uuid; - fileUuidDict[file.uuid] = {submitted: false}; - const input = document.createElement('input'); - input.id = data.uuid; - input.name = 'files'; - input.type = 'hidden'; - input.value = data.uuid; - dropzone.querySelector('.files').append(input); - }); - this.on('removedfile', async (file) => { - document.getElementById(file.uuid)?.remove(); - if (disableRemovedfileEvent) return; - if (dropzone.getAttribute('data-remove-url') && !fileUuidDict[file.uuid].submitted) { - try { - await POST(dropzone.getAttribute('data-remove-url'), {data: new URLSearchParams({file: file.uuid})}); - } catch (error) { - console.error(error); - } - } - }); - this.on('submit', () => { - for (const fileUuid of Object.keys(fileUuidDict)) { - fileUuidDict[fileUuid].submitted = true; - } - }); - this.on('reload', async () => { - try { - const response = await GET(editContentZone.getAttribute('data-attachment-url')); - const data = await response.json(); - // do not trigger the "removedfile" event, otherwise the attachments would be deleted from server - disableRemovedfileEvent = true; - dz.removeAllFiles(true); - dropzone.querySelector('.files').innerHTML = ''; - for (const el of dropzone.querySelectorAll('.dz-preview')) el.remove(); - fileUuidDict = {}; - disableRemovedfileEvent = false; - - for (const attachment of data) { - const imgSrc = `${dropzone.getAttribute('data-link-url')}/${attachment.uuid}`; - dz.emit('addedfile', attachment); - dz.emit('thumbnail', attachment, imgSrc); - dz.emit('complete', attachment); - fileUuidDict[attachment.uuid] = {submitted: true}; - dropzone.querySelector(`img[src='${imgSrc}']`).style.maxWidth = '100%'; - const input = document.createElement('input'); - input.id = attachment.uuid; - input.name = 'files'; - input.type = 'hidden'; - input.value = attachment.uuid; - dropzone.querySelector('.files').append(input); - } - if (!dropzone.querySelector('.dz-preview')) { - dropzone.classList.remove('dz-started'); - } - } catch (error) { - console.error(error); - } - }); - }, - }); - dz.emit('reload'); - return dz; - }; - const cancelAndReset = (e) => { e.preventDefault(); showElem(renderContent); hideElem(editContentZone); comboMarkdownEditor.value(rawContent.textContent); - comboMarkdownEditor.attachedDropzoneInst?.emit('reload'); + editContentZone.querySelector('.dropzone')?.dropzone?.emit('reload'); }; const saveAndRefresh = async (e) => { e.preventDefault(); showElem(renderContent); hideElem(editContentZone); - const dropzoneInst = comboMarkdownEditor.attachedDropzoneInst; + const dropzone = editContentZone.querySelector('.dropzone')?.dropzone; + for (const element of dropzone?.element?.querySelectorAll('.dz-preview') ?? []) element.classList.remove('dz-success'); try { const params = new URLSearchParams({ content: comboMarkdownEditor.value(), context: editContentZone.getAttribute('data-context'), content_version: editContentZone.getAttribute('data-content-version'), }); - const files = dropzoneInst?.element?.querySelectorAll('.files [name=files]') ?? []; + const files = dropzone?.element?.querySelectorAll('.files [name=files]') ?? []; for (const fileInput of files) { params.append('files[]', fileInput.value); } @@ -451,8 +360,7 @@ async function onEditContent(event) { } else { content.querySelector('.dropzone-attachments').outerHTML = data.attachments; } - dropzoneInst?.emit('submit'); - dropzoneInst?.emit('reload'); + dropzone?.emit('submit'); initMarkupContent(); initCommentContent(); } catch (error) { @@ -463,8 +371,10 @@ async function onEditContent(event) { comboMarkdownEditor = getComboMarkdownEditor(editContentZone.querySelector('.combo-markdown-editor')); if (!comboMarkdownEditor) { editContentZone.innerHTML = document.getElementById('issue-comment-editor-template').innerHTML; + const dropzone = editContentZone.querySelector('.dropzone'); + if (!dropzone.dropzone) await initDropzone(dropzone, editContentZone); comboMarkdownEditor = await initComboMarkdownEditor(editContentZone.querySelector('.combo-markdown-editor')); - comboMarkdownEditor.attachedDropzoneInst = await setupDropzone(editContentZone.querySelector('.dropzone')); + dropzone.dropzone.emit('reload'); editContentZone.addEventListener('ce-quick-submit', saveAndRefresh); editContentZone.querySelector('button[data-button-name="cancel-edit"]').addEventListener('click', cancelAndReset); editContentZone.querySelector('button[data-button-name="save-edit"]').addEventListener('click', saveAndRefresh);