Merge pull request '[gitea] cherry-pick' (#2478) from earl-warren/forgejo:wip-gitea-cherry-pick into forgejo

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/2478
This commit is contained in:
Earl Warren 2024-02-27 10:39:41 +00:00
commit 3fa4962a88
342 changed files with 4265 additions and 1514 deletions

View file

@ -296,6 +296,7 @@ package "code.gitea.io/gitea/modules/translation"
package "code.gitea.io/gitea/modules/util"
func UnsafeStringToBytes
func OptionalBoolFromGeneric
package "code.gitea.io/gitea/modules/util/filebuffer"
func CreateFromReader

View file

@ -296,7 +296,7 @@ rules:
jquery/no-delegate: [2]
jquery/no-each: [0]
jquery/no-extend: [2]
jquery/no-fade: [0]
jquery/no-fade: [2]
jquery/no-filter: [0]
jquery/no-find: [0]
jquery/no-global-eval: [2]
@ -309,7 +309,7 @@ rules:
jquery/no-is-function: [2]
jquery/no-is: [0]
jquery/no-load: [2]
jquery/no-map: [0]
jquery/no-map: [2]
jquery/no-merge: [2]
jquery/no-param: [2]
jquery/no-parent: [0]
@ -451,7 +451,7 @@ rules:
no-jquery/no-load: [2]
no-jquery/no-map-collection: [0]
no-jquery/no-map-util: [2]
no-jquery/no-map: [0]
no-jquery/no-map: [2]
no-jquery/no-merge: [2]
no-jquery/no-node-name: [2]
no-jquery/no-noop: [2]

View file

@ -98,7 +98,7 @@ rules:
at-rule-allowed-list: null
at-rule-disallowed-list: null
at-rule-empty-line-before: null
at-rule-no-unknown: true
at-rule-no-unknown: [true, {ignoreAtRules: [tailwind]}]
at-rule-no-vendor-prefix: true
at-rule-property-required-list: null
block-no-empty: true

View file

@ -107,7 +107,7 @@ GO_TEST_PACKAGES ?= $(filter-out $(shell $(GO) list code.gitea.io/gitea/models/m
FOMANTIC_WORK_DIR := web_src/fomantic
WEBPACK_SOURCES := $(shell find web_src/js web_src/css -type f)
WEBPACK_CONFIGS := webpack.config.js
WEBPACK_CONFIGS := webpack.config.js tailwind.config.js
WEBPACK_DEST := public/assets/js/index.js public/assets/css/index.css
WEBPACK_DEST_ENTRIES := public/assets/js public/assets/css public/assets/fonts public/assets/img/webpack
@ -625,8 +625,7 @@ test-mssql\#%: integrations.mssql.test generate-ini-mssql
test-mssql-migration: migrations.mssql.test migrations.individual.mssql.test
.PHONY: playwright
playwright: $(PLAYWRIGHT_DIR)
npm install --no-save @playwright/test
playwright: deps-frontend
npx playwright install $(PLAYWRIGHT_FLAGS)
.PHONY: test-e2e%
@ -1010,7 +1009,7 @@ generate-gitignore:
.PHONY: generate-images
generate-images: | node_modules
npm install --no-save --no-package-lock fabric@5 imagemin-zopfli@7
npm install --no-save fabric@6.0.0-beta19 imagemin-zopfli@7
node build/generate-images.js $(TAGS)
.PHONY: generate-manpage

View file

@ -1,20 +1,13 @@
#!/usr/bin/env node
import imageminZopfli from 'imagemin-zopfli';
import {optimize} from 'svgo';
import {fabric} from 'fabric';
import {loadSVGFromString, Canvas, Rect, util} from 'fabric/node';
import {readFile, writeFile} from 'node:fs/promises';
import {argv, exit} from 'node:process';
function exit(err) {
function doExit(err) {
if (err) console.error(err);
process.exit(err ? 1 : 0);
}
function loadSvg(svg) {
return new Promise((resolve) => {
fabric.loadSVGFromString(svg, (objects, options) => {
resolve({objects, options});
});
});
exit(err ? 1 : 0);
}
async function generate(svg, path, {size, bg}) {
@ -35,14 +28,14 @@ async function generate(svg, path, {size, bg}) {
return;
}
const {objects, options} = await loadSvg(svg);
const canvas = new fabric.Canvas();
const {objects, options} = await loadSVGFromString(svg);
const canvas = new Canvas();
canvas.setDimensions({width: size, height: size});
const ctx = canvas.getContext('2d');
ctx.scale(options.width ? (size / options.width) : 1, options.height ? (size / options.height) : 1);
if (bg) {
canvas.add(new fabric.Rect({
canvas.add(new Rect({
left: 0,
top: 0,
height: size * (1 / (size / options.height)),
@ -51,7 +44,7 @@ async function generate(svg, path, {size, bg}) {
}));
}
canvas.add(fabric.util.groupSVGElements(objects, options));
canvas.add(util.groupSVGElements(objects, options));
canvas.renderAll();
let png = Buffer.from([]);
@ -64,7 +57,7 @@ async function generate(svg, path, {size, bg}) {
}
async function main() {
const gitea = process.argv.slice(2).includes('gitea');
const gitea = argv.slice(2).includes('gitea');
const logoSvg = await readFile(new URL('../assets/logo.svg', import.meta.url), 'utf8');
const faviconSvg = await readFile(new URL('../assets/favicon.svg', import.meta.url), 'utf8');
@ -80,7 +73,7 @@ async function main() {
}
try {
exit(await main());
doExit(await main());
} catch (err) {
exit(err);
doExit(err);
}

View file

@ -4,15 +4,16 @@ import {optimize} from 'svgo';
import {parse} from 'node:path';
import {readFile, writeFile, mkdir} from 'node:fs/promises';
import {fileURLToPath} from 'node:url';
import {exit} from 'node:process';
const glob = (pattern) => fastGlob.sync(pattern, {
cwd: fileURLToPath(new URL('..', import.meta.url)),
absolute: true,
});
function exit(err) {
function doExit(err) {
if (err) console.error(err);
process.exit(err ? 1 : 0);
exit(err ? 1 : 0);
}
async function processFile(file, {prefix, fullName} = {}) {
@ -63,7 +64,7 @@ async function main() {
}
try {
exit(await main());
doExit(await main());
} catch (err) {
exit(err);
doExit(err);
}

View file

@ -5,7 +5,6 @@ package cmd
import (
asymkey_model "code.gitea.io/gitea/models/asymkey"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/graceful"
repo_service "code.gitea.io/gitea/services/repository"
@ -33,12 +32,6 @@ func runRegenerateHooks(_ *cli.Context) error {
if err := initDB(ctx); err != nil {
return err
}
// Detection of ProcReceive support relies on Git module being initalized.
if err := git.InitFull(ctx); err != nil {
return err
}
return repo_service.SyncRepositoryHooks(graceful.GetManager().ShutdownContext())
}

View file

@ -10,8 +10,8 @@ import (
auth_model "code.gitea.io/gitea/models/auth"
user_model "code.gitea.io/gitea/models/user"
pwd "code.gitea.io/gitea/modules/auth/password"
"code.gitea.io/gitea/modules/optional"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
"github.com/urfave/cli/v2"
)
@ -123,10 +123,10 @@ func runCreateUser(c *cli.Context) error {
changePassword = c.Bool("must-change-password")
}
restricted := util.OptionalBoolNone
restricted := optional.None[bool]()
if c.IsSet("restricted") {
restricted = util.OptionalBoolOf(c.Bool("restricted"))
restricted = optional.Some(c.Bool("restricted"))
}
// default user visibility in app.ini
@ -142,7 +142,7 @@ func runCreateUser(c *cli.Context) error {
}
overwriteDefault := &user_model.CreateUserOverwriteOptions{
IsActive: util.OptionalBoolTrue,
IsActive: optional.Some(true),
IsRestricted: restricted,
}

View file

@ -71,7 +71,7 @@ func runKeys(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setup(ctx, false)
setup(ctx, c.Bool("debug"))
authorizedString, extra := private.AuthorizedPublicKeyByContent(ctx, content)
// do not use handleCliResponseExtra or cli.NewExitError, if it exists immediately, it breaks some tests like Test_CmdKeys

View file

@ -63,21 +63,10 @@ func setup(ctx context.Context, debug bool) {
setupConsoleLogger(log.FATAL, false, os.Stderr)
}
setting.MustInstalled()
if debug {
setting.RunMode = "dev"
}
// Check if setting.RepoRootPath exists. It could be the case that it doesn't exist, this can happen when
// `[repository]` `ROOT` is a relative path and $GITEA_WORK_DIR isn't passed to the SSH connection.
if _, err := os.Stat(setting.RepoRootPath); err != nil {
if os.IsNotExist(err) {
_ = fail(ctx, "Incorrect configuration, no repository directory.", "Directory `[repository].ROOT` %q was not found, please check if $GITEA_WORK_DIR is passed to the SSH connection or make `[repository].ROOT` an absolute value.", setting.RepoRootPath)
} else {
_ = fail(ctx, "Incorrect configuration, repository directory is inaccessible", "Directory `[repository].ROOT` %q is inaccessible. err: %v", setting.RepoRootPath, err)
}
_ = fail(ctx, "Unable to access repository path", "Unable to access repository path %q, err: %v", setting.RepoRootPath, err)
return
}
if err := git.InitSimple(context.Background()); err != nil {
_ = fail(ctx, "Failed to init git", "Failed to init git, err: %v", err)
}

View file

@ -1492,6 +1492,9 @@ LEVEL = Info
;DEFAULT_EMAIL_NOTIFICATIONS = enabled
;; Send an email to all admins when a new user signs up to inform the admins about this act. Options: true, false
;SEND_NOTIFICATION_EMAIL_ON_NEW_USER = false
;; Disabled features for users, could be "deletion", more features can be disabled in future
;; - deletion: a user cannot delete their own account
;USER_DISABLED_FEATURES =
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

View file

@ -101,6 +101,10 @@ i.e. `services/user`, `models/repository`.
Since there are some packages which use the same package name, it is possible that you find packages like `modules/user`, `models/user`, and `services/user`. When these packages are imported in one Go file, it's difficult to know which package we are using and if it's a variable name or an import name. So, we always recommend to use import aliases. To differ from package variables which are commonly in camelCase, just use **snake_case** for import aliases.
i.e. `import user_service "code.gitea.io/gitea/services/user"`
### Implementing `io.Closer`
If a type implements `io.Closer`, calling `Close` multiple times must not fail or `panic` but return an error or `nil`.
### Important Gotchas
- Never write `x.Update(exemplar)` without an explicit `WHERE` clause:

View file

@ -135,3 +135,27 @@
user_id: 31
repo_id: 28
mode: 4
-
id: 24
user_id: 38
repo_id: 60
mode: 2
-
id: 25
user_id: 38
repo_id: 61
mode: 1
-
id: 26
user_id: 39
repo_id: 61
mode: 1
-
id: 27
user_id: 40
repo_id: 61
mode: 4

View file

@ -45,3 +45,9 @@
repo_id: 22
user_id: 18
mode: 2 # write
-
id: 9
repo_id: 60
user_id: 38
mode: 2 # write

View file

@ -293,3 +293,27 @@
lower_email: user37@example.com
is_activated: true
is_primary: true
-
id: 38
uid: 38
email: user38@example.com
lower_email: user38@example.com
is_activated: true
is_primary: true
-
id: 39
uid: 39
email: user39@example.com
lower_email: user39@example.com
is_activated: true
is_primary: true
-
id: 40
uid: 40
email: user40@example.com
lower_email: user40@example.com
is_activated: true
is_primary: true

View file

@ -338,3 +338,37 @@
created_unix: 978307210
updated_unix: 978307210
is_locked: false
-
id: 21
repo_id: 60
index: 1
poster_id: 39
original_author_id: 0
name: repo60 pull1
content: content for the 1st issue
milestone_id: 0
priority: 0
is_closed: false
is_pull: true
num_comments: 0
created_unix: 1707270422
updated_unix: 1707270422
is_locked: false
-
id: 22
repo_id: 61
index: 1
poster_id: 40
original_author_id: 0
name: repo61 pull1
content: content for the 1st issue
milestone_id: 0
priority: 0
is_closed: false
is_pull: true
num_comments: 0
created_unix: 1707270422
updated_unix: 1707270422
is_locked: false

View file

@ -99,3 +99,21 @@
uid: 5
org_id: 36
is_public: true
-
id: 18
uid: 38
org_id: 41
is_public: true
-
id: 19
uid: 39
org_id: 41
is_public: true
-
id: 20
uid: 40
org_id: 41
is_public: true

View file

@ -9,6 +9,7 @@
head_branch: branch1
base_branch: master
merge_base: 4a357436d925b5c974181ff12a994538ddc5a269
merged_commit_id: 1a8823cd1a9549fde083f992f6b9b87a7ab74fb3
has_merged: true
merger_id: 2
@ -98,3 +99,21 @@
index: 1
head_repo_id: 23
base_repo_id: 23
-
id: 9
type: 0 # gitea pull request
status: 2 # mergable
issue_id: 21
index: 1
head_repo_id: 60
base_repo_id: 60
-
id: 10
type: 0 # gitea pull request
status: 2 # mergable
issue_id: 22
index: 1
head_repo_id: 61
base_repo_id: 61

View file

@ -708,3 +708,45 @@
type: 1
config: "{}"
created_unix: 946684810
-
id: 102
repo_id: 60
type: 1
config: "{}"
created_unix: 946684810
-
id: 103
repo_id: 60
type: 2
config: "{\"EnableTimetracker\":true,\"AllowOnlyContributorsToTrackTime\":true}"
created_unix: 946684810
-
id: 104
repo_id: 60
type: 3
config: "{\"IgnoreWhitespaceConflicts\":false,\"AllowMerge\":true,\"AllowRebase\":true,\"AllowRebaseMerge\":true,\"AllowSquash\":true}"
created_unix: 946684810
-
id: 105
repo_id: 61
type: 1
config: "{}"
created_unix: 946684810
-
id: 106
repo_id: 61
type: 2
config: "{\"EnableTimetracker\":true,\"AllowOnlyContributorsToTrackTime\":true}"
created_unix: 946684810
-
id: 107
repo_id: 61
type: 3
config: "{\"IgnoreWhitespaceConflicts\":false,\"AllowMerge\":true,\"AllowRebase\":true,\"AllowRebaseMerge\":true,\"AllowSquash\":true}"
created_unix: 946684810

View file

@ -1720,3 +1720,65 @@
is_private: true
status: 0
num_issues: 0
-
id: 60
owner_id: 40
owner_name: user40
lower_name: repo60
name: repo60
default_branch: main
num_watches: 0
num_stars: 0
num_forks: 0
num_issues: 0
num_closed_issues: 0
num_pulls: 1
num_closed_pulls: 0
num_milestones: 0
num_closed_milestones: 0
num_projects: 0
num_closed_projects: 0
is_private: false
is_empty: false
is_archived: false
is_mirror: false
status: 0
is_fork: false
fork_id: 0
is_template: false
template_id: 0
size: 0
is_fsck_enabled: true
close_issues_via_commit_in_any_branch: false
-
id: 61
owner_id: 41
owner_name: org41
lower_name: repo61
name: repo61
default_branch: main
num_watches: 0
num_stars: 0
num_forks: 0
num_issues: 0
num_closed_issues: 0
num_pulls: 1
num_closed_pulls: 0
num_milestones: 0
num_closed_milestones: 0
num_projects: 0
num_closed_projects: 0
is_private: false
is_empty: false
is_archived: false
is_mirror: false
status: 0
is_fork: false
fork_id: 0
is_template: false
template_id: 0
size: 0
is_fsck_enabled: true
close_issues_via_commit_in_any_branch: false

View file

@ -217,3 +217,25 @@
num_members: 1
includes_all_repositories: false
can_create_org_repo: true
-
id: 21
org_id: 41
lower_name: owners
name: Owners
authorize: 4 # owner
num_repos: 1
num_members: 1
includes_all_repositories: true
can_create_org_repo: true
-
id: 22
org_id: 41
lower_name: team1
name: Team1
authorize: 1 # read
num_repos: 1
num_members: 2
includes_all_repositories: false
can_create_org_repo: false

View file

@ -63,3 +63,15 @@
org_id: 17
team_id: 9
repo_id: 24
-
id: 12
org_id: 41
team_id: 21
repo_id: 61
-
id: 13
org_id: 41
team_id: 22
repo_id: 61

View file

@ -286,3 +286,39 @@
team_id: 2
type: 8
access_mode: 2
-
id: 49
team_id: 21
type: 1
access_mode: 4
-
id: 50
team_id: 21
type: 2
access_mode: 4
-
id: 51
team_id: 21
type: 3
access_mode: 4
-
id: 52
team_id: 22
type: 1
access_mode: 1
-
id: 53
team_id: 22
type: 2
access_mode: 1
-
id: 54
team_id: 22
type: 3
access_mode: 1

View file

@ -129,3 +129,21 @@
org_id: 17
team_id: 9
uid: 15
-
id: 23
org_id: 41
team_id: 21
uid: 40
-
id: 24
org_id: 41
team_id: 22
uid: 38
-
id: 25
org_id: 41
team_id: 22
uid: 39

View file

@ -1369,3 +1369,151 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
-
id: 38
lower_name: user38
name: user38
full_name: User38
email: user38@example.com
keep_email_private: false
email_notifications_preference: enabled
passwd: ZogKvWdyEx:password
passwd_hash_algo: dummy
must_change_password: false
login_source: 0
login_name: user38
type: 0
salt: ZogKvWdyEx
max_repo_creation: -1
is_active: true
is_admin: false
is_restricted: false
allow_git_hook: false
allow_import_local: false
allow_create_organization: true
prohibit_login: false
avatar: avatar38
avatar_email: user38@example.com
use_custom_avatar: false
num_followers: 0
num_following: 0
num_stars: 0
num_repos: 0
num_teams: 0
num_members: 0
visibility: 0
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
-
id: 39
lower_name: user39
name: user39
full_name: User39
email: user39@example.com
keep_email_private: false
email_notifications_preference: enabled
passwd: ZogKvWdyEx:password
passwd_hash_algo: dummy
must_change_password: false
login_source: 0
login_name: user39
type: 0
salt: ZogKvWdyEx
max_repo_creation: -1
is_active: true
is_admin: false
is_restricted: false
allow_git_hook: false
allow_import_local: false
allow_create_organization: true
prohibit_login: false
avatar: avatar39
avatar_email: user39@example.com
use_custom_avatar: false
num_followers: 0
num_following: 0
num_stars: 0
num_repos: 0
num_teams: 0
num_members: 0
visibility: 0
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
-
id: 40
lower_name: user40
name: user40
full_name: User40
email: user40@example.com
keep_email_private: false
email_notifications_preference: onmention
passwd: ZogKvWdyEx:password
passwd_hash_algo: dummy
must_change_password: false
login_source: 0
login_name: user40
type: 0
salt: ZogKvWdyEx
max_repo_creation: -1
is_active: true
is_admin: false
is_restricted: false
allow_git_hook: false
allow_import_local: false
allow_create_organization: true
prohibit_login: false
avatar: avatar40
avatar_email: user40@example.com
use_custom_avatar: false
num_followers: 0
num_following: 0
num_stars: 0
num_repos: 1
num_teams: 0
num_members: 0
visibility: 0
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
-
id: 41
lower_name: org41
name: org41
full_name: Org41
email: org41@example.com
keep_email_private: false
email_notifications_preference: onmention
passwd: ZogKvWdyEx:password
passwd_hash_algo: dummy
must_change_password: false
login_source: 0
login_name: org41
type: 1
salt: ZogKvWdyEx
max_repo_creation: -1
is_active: false
is_admin: false
is_restricted: false
allow_git_hook: false
allow_import_local: false
allow_create_organization: true
prohibit_login: false
avatar: avatar41
avatar_email: org41@example.com
use_custom_avatar: false
num_followers: 0
num_following: 0
num_stars: 0
num_repos: 1
num_teams: 2
num_members: 3
visibility: 0
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false

View file

@ -9,7 +9,7 @@ import (
"code.gitea.io/gitea/models/db"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/optional"
"xorm.io/builder"
)
@ -67,7 +67,7 @@ type FindBranchOptions struct {
db.ListOptions
RepoID int64
ExcludeBranchNames []string
IsDeletedBranch util.OptionalBool
IsDeletedBranch optional.Option[bool]
OrderBy string
Keyword string
}
@ -81,8 +81,8 @@ func (opts FindBranchOptions) ToConds() builder.Cond {
if len(opts.ExcludeBranchNames) > 0 {
cond = cond.And(builder.NotIn("name", opts.ExcludeBranchNames))
}
if !opts.IsDeletedBranch.IsNone() {
cond = cond.And(builder.Eq{"is_deleted": opts.IsDeletedBranch.IsTrue()})
if opts.IsDeletedBranch.Has() {
cond = cond.And(builder.Eq{"is_deleted": opts.IsDeletedBranch.Value()})
}
if opts.Keyword != "" {
cond = cond.And(builder.Like{"name", opts.Keyword})
@ -92,7 +92,7 @@ func (opts FindBranchOptions) ToConds() builder.Cond {
func (opts FindBranchOptions) ToOrders() string {
orderBy := opts.OrderBy
if !opts.IsDeletedBranch.IsFalse() { // if deleted branch included, put them at the end
if opts.IsDeletedBranch.ValueOrDefault(true) { // if deleted branch included, put them at the end
if orderBy != "" {
orderBy += ", "
}

View file

@ -12,7 +12,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/optional"
"github.com/stretchr/testify/assert"
)
@ -49,7 +49,7 @@ func TestGetDeletedBranches(t *testing.T) {
branches, err := db.Find[git_model.Branch](db.DefaultContext, git_model.FindBranchOptions{
ListOptions: db.ListOptionsAll,
RepoID: repo.ID,
IsDeletedBranch: util.OptionalBoolTrue,
IsDeletedBranch: optional.Some(true),
})
assert.NoError(t, err)
assert.Len(t, branches, 2)

View file

@ -8,7 +8,7 @@ import (
"sort"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/optional"
"github.com/gobwas/glob"
)
@ -56,7 +56,7 @@ func FindAllMatchedBranches(ctx context.Context, repoID int64, ruleName string)
Page: page,
},
RepoID: repoID,
IsDeletedBranch: util.OptionalBoolFalse,
IsDeletedBranch: optional.Some(false),
})
if err != nil {
return nil, err

View file

@ -381,7 +381,7 @@ func TestCountIssues(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
count, err := issues_model.CountIssues(db.DefaultContext, &issues_model.IssuesOptions{})
assert.NoError(t, err)
assert.EqualValues(t, 20, count)
assert.EqualValues(t, 22, count)
}
func TestIssueLoadAttributes(t *testing.T) {

View file

@ -1122,3 +1122,23 @@ func InsertPullRequests(ctx context.Context, prs ...*PullRequest) error {
}
return committer.Commit()
}
// GetPullRequestByMergedCommit returns a merged pull request by the given commit
func GetPullRequestByMergedCommit(ctx context.Context, repoID int64, sha string) (*PullRequest, error) {
pr := new(PullRequest)
has, err := db.GetEngine(ctx).Where("base_repo_id = ? AND merged_commit_id = ?", repoID, sha).Get(pr)
if err != nil {
return nil, err
} else if !has {
return nil, ErrPullRequestNotExist{0, 0, 0, repoID, "", ""}
}
if err = pr.LoadAttributes(ctx); err != nil {
return nil, err
}
if err = pr.LoadIssue(ctx); err != nil {
return nil, err
}
return pr, nil
}

View file

@ -425,6 +425,18 @@ func TestGetApprovers(t *testing.T) {
assert.EqualValues(t, expected, approvers)
}
func TestGetPullRequestByMergedCommit(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
pr, err := issues_model.GetPullRequestByMergedCommit(db.DefaultContext, 1, "1a8823cd1a9549fde083f992f6b9b87a7ab74fb3")
assert.NoError(t, err)
assert.EqualValues(t, 1, pr.ID)
_, err = issues_model.GetPullRequestByMergedCommit(db.DefaultContext, 0, "1a8823cd1a9549fde083f992f6b9b87a7ab74fb3")
assert.ErrorAs(t, err, &issues_model.ErrPullRequestNotExist{})
_, err = issues_model.GetPullRequestByMergedCommit(db.DefaultContext, 1, "")
assert.ErrorAs(t, err, &issues_model.ErrPullRequestNotExist{})
}
func TestMigrate_InsertPullRequests(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
reponame := "repo1"

View file

@ -292,8 +292,14 @@ func IsOfficialReviewerTeam(ctx context.Context, issue *Issue, team *organizatio
// CreateReview creates a new review based on opts
func CreateReview(ctx context.Context, opts CreateReviewOptions) (*Review, error) {
ctx, committer, err := db.TxContext(ctx)
if err != nil {
return nil, err
}
defer committer.Close()
sess := db.GetEngine(ctx)
review := &Review{
Type: opts.Type,
Issue: opts.Issue,
IssueID: opts.Issue.ID,
Reviewer: opts.Reviewer,
@ -303,15 +309,39 @@ func CreateReview(ctx context.Context, opts CreateReviewOptions) (*Review, error
CommitID: opts.CommitID,
Stale: opts.Stale,
}
if opts.Reviewer != nil {
review.Type = opts.Type
review.ReviewerID = opts.Reviewer.ID
} else {
if review.Type != ReviewTypeRequest {
review.Type = ReviewTypeRequest
reviewCond := builder.Eq{"reviewer_id": opts.Reviewer.ID, "issue_id": opts.Issue.ID}
// make sure user review requests are cleared
if opts.Type != ReviewTypePending {
if _, err := sess.Where(reviewCond.And(builder.Eq{"type": ReviewTypeRequest})).Delete(new(Review)); err != nil {
return nil, err
}
}
// make sure if the created review gets dismissed no old review surface
// other types can be ignored, as they don't affect branch protection
if opts.Type == ReviewTypeApprove || opts.Type == ReviewTypeReject {
if _, err := sess.Where(reviewCond.And(builder.In("type", ReviewTypeApprove, ReviewTypeReject))).
Cols("dismissed").Update(&Review{Dismissed: true}); err != nil {
return nil, err
}
}
} else if opts.ReviewerTeam != nil {
review.Type = ReviewTypeRequest
review.ReviewerTeamID = opts.ReviewerTeam.ID
} else {
return nil, fmt.Errorf("provide either reviewer or reviewer team")
}
return review, db.Insert(ctx, review)
if _, err := sess.Insert(review); err != nil {
return nil, err
}
return review, committer.Commit()
}
// GetCurrentReview returns the current pending review of reviewer for given issue

View file

@ -356,7 +356,6 @@ func HasAccessUnit(ctx context.Context, user *user_model.User, repo *repo_model.
// CanBeAssigned return true if user can be assigned to issue or pull requests in repo
// Currently any write access (code, issues or pr's) is assignable, to match assignee list in user interface.
// FIXME: user could send PullRequest also could be assigned???
func CanBeAssigned(ctx context.Context, user *user_model.User, repo *repo_model.Repository, _ bool) (bool, error) {
if user.IsOrganization() {
return false, fmt.Errorf("Organization can't be added as assignee [user_id: %d, repo_id: %d]", user.ID, repo.ID)
@ -365,7 +364,8 @@ func CanBeAssigned(ctx context.Context, user *user_model.User, repo *repo_model.
if err != nil {
return false, err
}
return perm.CanAccessAny(perm_model.AccessModeWrite, unit.TypeCode, unit.TypeIssues, unit.TypePullRequests), nil
return perm.CanAccessAny(perm_model.AccessModeWrite, unit.AllRepoUnitTypes...) ||
perm.CanAccessAny(perm_model.AccessModeRead, unit.TypePullRequests), nil
}
// HasAccess returns true if user has access to repo

View file

@ -138,12 +138,12 @@ func getTestCases() []struct {
{
name: "AllPublic/PublicRepositoriesOfUserIncludingCollaborative",
opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 15, AllPublic: true, Template: util.OptionalBoolFalse},
count: 32,
count: 34,
},
{
name: "AllPublic/PublicAndPrivateRepositoriesOfUserIncludingCollaborative",
opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 15, Private: true, AllPublic: true, AllLimited: true, Template: util.OptionalBoolFalse},
count: 37,
count: 39,
},
{
name: "AllPublic/PublicAndPrivateRepositoriesOfUserIncludingCollaborativeByName",
@ -158,7 +158,7 @@ func getTestCases() []struct {
{
name: "AllPublic/PublicRepositoriesOfOrganization",
opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 17, AllPublic: true, Collaborate: util.OptionalBoolFalse, Template: util.OptionalBoolFalse},
count: 32,
count: 34,
},
{
name: "AllTemplates",

View file

@ -8,6 +8,7 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/container"
api "code.gitea.io/gitea/modules/structs"
@ -78,7 +79,8 @@ func GetRepoAssignees(ctx context.Context, repo *Repository) (_ []*user_model.Us
if err = e.Table("team_user").
Join("INNER", "team_repo", "`team_repo`.team_id = `team_user`.team_id").
Join("INNER", "team_unit", "`team_unit`.team_id = `team_user`.team_id").
Where("`team_repo`.repo_id = ? AND `team_unit`.access_mode >= ?", repo.ID, perm.AccessModeWrite).
Where("`team_repo`.repo_id = ? AND (`team_unit`.access_mode >= ? OR (`team_unit`.access_mode = ? AND `team_unit`.`type` = ?))",
repo.ID, perm.AccessModeWrite, perm.AccessModeRead, unit.TypePullRequests).
Distinct("`team_user`.uid").
Select("`team_user`.uid").
Find(&additionalUserIDs); err != nil {

View file

@ -131,8 +131,8 @@ func AssertSuccessfulInsert(t assert.TestingT, beans ...any) {
}
// AssertCount assert the count of a bean
func AssertCount(t assert.TestingT, bean, expected any) {
assert.EqualValues(t, expected, GetCount(t, bean))
func AssertCount(t assert.TestingT, bean, expected any) bool {
return assert.EqualValues(t, expected, GetCount(t, bean))
}
// AssertInt64InRange assert value is in range [low, high]
@ -150,7 +150,7 @@ func GetCountByCond(t assert.TestingT, tableName string, cond builder.Cond) int6
}
// AssertCountByCond test the count of database entries matching bean
func AssertCountByCond(t assert.TestingT, tableName string, cond builder.Cond, expected int) {
assert.EqualValues(t, expected, GetCountByCond(t, tableName, cond),
func AssertCountByCond(t assert.TestingT, tableName string, cond builder.Cond, expected int) bool {
return assert.EqualValues(t, expected, GetCountByCond(t, tableName, cond),
"Failed consistency test, the counted bean (of table %s) was %+v", tableName, cond)
}

View file

@ -25,6 +25,7 @@ import (
"code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/optional"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/timeutil"
@ -585,14 +586,14 @@ func IsUsableUsername(name string) error {
// CreateUserOverwriteOptions are an optional options who overwrite system defaults on user creation
type CreateUserOverwriteOptions struct {
KeepEmailPrivate util.OptionalBool
KeepEmailPrivate optional.Option[bool]
Visibility *structs.VisibleType
AllowCreateOrganization util.OptionalBool
AllowCreateOrganization optional.Option[bool]
EmailNotificationsPreference *string
MaxRepoCreation *int
Theme *string
IsRestricted util.OptionalBool
IsActive util.OptionalBool
IsRestricted optional.Option[bool]
IsActive optional.Option[bool]
}
// CreateUser creates record of a new user.
@ -619,14 +620,14 @@ func CreateUser(ctx context.Context, u *User, overwriteDefault ...*CreateUserOve
// overwrite defaults if set
if len(overwriteDefault) != 0 && overwriteDefault[0] != nil {
overwrite := overwriteDefault[0]
if !overwrite.KeepEmailPrivate.IsNone() {
u.KeepEmailPrivate = overwrite.KeepEmailPrivate.IsTrue()
if overwrite.KeepEmailPrivate.Has() {
u.KeepEmailPrivate = overwrite.KeepEmailPrivate.Value()
}
if overwrite.Visibility != nil {
u.Visibility = *overwrite.Visibility
}
if !overwrite.AllowCreateOrganization.IsNone() {
u.AllowCreateOrganization = overwrite.AllowCreateOrganization.IsTrue()
if overwrite.AllowCreateOrganization.Has() {
u.AllowCreateOrganization = overwrite.AllowCreateOrganization.Value()
}
if overwrite.EmailNotificationsPreference != nil {
u.EmailNotificationsPreference = *overwrite.EmailNotificationsPreference
@ -637,11 +638,11 @@ func CreateUser(ctx context.Context, u *User, overwriteDefault ...*CreateUserOve
if overwrite.Theme != nil {
u.Theme = *overwrite.Theme
}
if !overwrite.IsRestricted.IsNone() {
u.IsRestricted = overwrite.IsRestricted.IsTrue()
if overwrite.IsRestricted.Has() {
u.IsRestricted = overwrite.IsRestricted.Value()
}
if !overwrite.IsActive.IsNone() {
u.IsActive = overwrite.IsActive.IsTrue()
if overwrite.IsActive.Has() {
u.IsActive = overwrite.IsActive.Value()
}
}

View file

@ -89,7 +89,7 @@ func TestSearchUsers(t *testing.T) {
[]int64{19, 25})
testOrgSuccess(&user_model.SearchUserOptions{OrderBy: "id ASC", ListOptions: db.ListOptions{Page: 4, PageSize: 2}},
[]int64{26})
[]int64{26, 41})
testOrgSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 5, PageSize: 2}},
[]int64{})
@ -101,13 +101,13 @@ func TestSearchUsers(t *testing.T) {
}
testUserSuccess(&user_model.SearchUserOptions{OrderBy: "id ASC", ListOptions: db.ListOptions{Page: 1}},
[]int64{1, 2, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 21, 24, 27, 28, 29, 30, 32, 34, 37})
[]int64{1, 2, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 21, 24, 27, 28, 29, 30, 32, 34, 37, 38, 39, 40})
testUserSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 1}, IsActive: util.OptionalBoolFalse},
[]int64{9})
testUserSuccess(&user_model.SearchUserOptions{OrderBy: "id ASC", ListOptions: db.ListOptions{Page: 1}, IsActive: util.OptionalBoolTrue},
[]int64{1, 2, 4, 5, 8, 10, 11, 12, 13, 14, 15, 16, 18, 20, 21, 24, 27, 28, 29, 30, 32, 34, 37})
[]int64{1, 2, 4, 5, 8, 10, 11, 12, 13, 14, 15, 16, 18, 20, 21, 24, 27, 28, 29, 30, 32, 34, 37, 38, 39, 40})
testUserSuccess(&user_model.SearchUserOptions{Keyword: "user1", OrderBy: "id ASC", ListOptions: db.ListOptions{Page: 1}, IsActive: util.OptionalBoolTrue},
[]int64{1, 10, 11, 12, 13, 14, 15, 16, 18})

View file

@ -25,6 +25,45 @@ const (
GithubEventSchedule = "schedule"
)
// IsDefaultBranchWorkflow returns true if the event only triggers workflows on the default branch
func IsDefaultBranchWorkflow(triggedEvent webhook_module.HookEventType) bool {
switch triggedEvent {
case webhook_module.HookEventDelete:
// GitHub "delete" event
// https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#delete
return true
case webhook_module.HookEventFork:
// GitHub "fork" event
// https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#fork
return true
case webhook_module.HookEventIssueComment:
// GitHub "issue_comment" event
// https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#issue_comment
return true
case webhook_module.HookEventPullRequestComment:
// GitHub "pull_request_comment" event
// https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_comment-use-issue_comment
return true
case webhook_module.HookEventWiki:
// GitHub "gollum" event
// https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#gollum
return true
case webhook_module.HookEventSchedule:
// GitHub "schedule" event
// https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#schedule
return true
case webhook_module.HookEventIssues,
webhook_module.HookEventIssueAssign,
webhook_module.HookEventIssueLabel,
webhook_module.HookEventIssueMilestone:
// Github "issues" event
// https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#issues
return true
}
return false
}
// canGithubEventMatch check if the input Github event can match any Gitea event.
func canGithubEventMatch(eventName string, triggedEvent webhook_module.HookEventType) bool {
switch eventName {
@ -75,6 +114,11 @@ func canGithubEventMatch(eventName string, triggedEvent webhook_module.HookEvent
return false
}
case GithubEventIssueComment:
// https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_comment-use-issue_comment
return triggedEvent == webhook_module.HookEventIssueComment ||
triggedEvent == webhook_module.HookEventPullRequestComment
default:
return eventName == string(triggedEvent)
}

View file

@ -103,6 +103,12 @@ func TestCanGithubEventMatch(t *testing.T) {
webhook_module.HookEventCreate,
true,
},
{
"create pull request comment",
GithubEventIssueComment,
webhook_module.HookEventPullRequestComment,
true,
},
}
for _, tc := range testCases {

View file

@ -309,12 +309,6 @@ func RepoRefForAPI(next http.Handler) http.Handler {
return
}
objectFormat, err := ctx.Repo.GitRepo.GetObjectFormat()
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetCommit", err)
return
}
if ref := ctx.FormTrim("ref"); len(ref) > 0 {
commit, err := ctx.Repo.GitRepo.GetCommit(ref)
if err != nil {
@ -333,6 +327,7 @@ func RepoRefForAPI(next http.Handler) http.Handler {
}
refName := getRefName(ctx.Base, ctx.Repo, RepoRefAny)
var err error
if ctx.Repo.GitRepo.IsBranchExist(refName) {
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName)
@ -348,7 +343,7 @@ func RepoRefForAPI(next http.Handler) http.Handler {
return
}
ctx.Repo.CommitID = ctx.Repo.Commit.ID.String()
} else if len(refName) == objectFormat.FullLength() {
} else if len(refName) == ctx.Repo.GetObjectFormat().FullLength() {
ctx.Repo.CommitID = refName
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetCommit(refName)
if err != nil {

View file

@ -11,6 +11,8 @@ import (
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/markup/markdown"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/structs"
)
@ -255,6 +257,19 @@ func HandleOrgAssignment(ctx *Context, args ...bool) {
ctx.Data["CanReadProjects"] = ctx.Org.CanReadUnit(ctx, unit.TypeProjects)
ctx.Data["CanReadPackages"] = ctx.Org.CanReadUnit(ctx, unit.TypePackages)
ctx.Data["CanReadCode"] = ctx.Org.CanReadUnit(ctx, unit.TypeCode)
ctx.Data["IsFollowing"] = ctx.Doer != nil && user_model.IsFollowing(ctx, ctx.Doer.ID, ctx.ContextUser.ID)
if len(ctx.ContextUser.Description) != 0 {
content, err := markdown.RenderString(&markup.RenderContext{
Metas: map[string]string{"mode": "document"},
Ctx: ctx,
}, ctx.ContextUser.Description)
if err != nil {
ctx.ServerError("RenderString", err)
return
}
ctx.Data["RenderedDescription"] = content
}
}
// OrgAssignment returns a middleware to handle organization assignment

View file

@ -27,6 +27,7 @@ import (
"code.gitea.io/gitea/modules/gitrepo"
code_indexer "code.gitea.io/gitea/modules/indexer/code"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/optional"
repo_module "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
@ -82,6 +83,10 @@ func (r *Repository) CanCreateBranch() bool {
return r.Permission.CanWrite(unit_model.TypeCode) && r.Repository.CanCreateBranch()
}
func (r *Repository) GetObjectFormat() git.ObjectFormat {
return git.ObjectFormatFromName(r.Repository.ObjectFormatName)
}
// RepoMustNotBeArchived checks if a repo is archived
func RepoMustNotBeArchived() func(ctx *Context) {
return func(ctx *Context) {
@ -672,7 +677,7 @@ func RepoAssignment(ctx *Context) context.CancelFunc {
branchOpts := git_model.FindBranchOptions{
RepoID: ctx.Repo.Repository.ID,
IsDeletedBranch: util.OptionalBoolFalse,
IsDeletedBranch: optional.Some(false),
ListOptions: db.ListOptionsAll,
}
branchesTotal, err := db.Count[git_model.Branch](ctx, branchOpts)
@ -830,9 +835,8 @@ func getRefName(ctx *Base, repo *Repository, pathType RepoRefType) string {
}
// For legacy and API support only full commit sha
parts := strings.Split(path, "/")
objectFormat, _ := repo.GitRepo.GetObjectFormat()
if len(parts) > 0 && len(parts[0]) == objectFormat.FullLength() {
if len(parts) > 0 && len(parts[0]) == git.ObjectFormatFromName(repo.Repository.ObjectFormatName).FullLength() {
repo.TreePath = strings.Join(parts[1:], "/")
return parts[0]
}
@ -876,9 +880,8 @@ func getRefName(ctx *Base, repo *Repository, pathType RepoRefType) string {
return getRefNameFromPath(ctx, repo, path, repo.GitRepo.IsTagExist)
case RepoRefCommit:
parts := strings.Split(path, "/")
objectFormat, _ := repo.GitRepo.GetObjectFormat()
if len(parts) > 0 && len(parts[0]) >= 7 && len(parts[0]) <= objectFormat.FullLength() {
if len(parts) > 0 && len(parts[0]) >= 7 && len(parts[0]) <= repo.GetObjectFormat().FullLength() {
repo.TreePath = strings.Join(parts[1:], "/")
return parts[0]
}
@ -937,12 +940,6 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context
}
}
objectFormat, err := ctx.Repo.GitRepo.GetObjectFormat()
if err != nil {
log.Error("Cannot determine objectFormat for repository: %w", err)
ctx.Repo.Repository.MarkAsBrokenEmpty()
}
// Get default branch.
if len(ctx.Params("*")) == 0 {
refName = ctx.Repo.Repository.DefaultBranch
@ -1009,7 +1006,7 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context
return cancel
}
ctx.Repo.CommitID = ctx.Repo.Commit.ID.String()
} else if len(refName) >= 7 && len(refName) <= objectFormat.FullLength() {
} else if len(refName) >= 7 && len(refName) <= ctx.Repo.GetObjectFormat().FullLength() {
ctx.Repo.IsViewCommit = true
ctx.Repo.CommitID = refName
@ -1019,7 +1016,7 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context
return cancel
}
// If short commit ID add canonical link header
if len(refName) < objectFormat.FullLength() {
if len(refName) < ctx.Repo.GetObjectFormat().FullLength() {
ctx.RespHeader().Set("Link", fmt.Sprintf("<%s>; rel=\"canonical\"",
util.URLJoin(setting.AppURL, strings.Replace(ctx.Req.URL.RequestURI(), util.PathEscapeSegments(refName), url.PathEscape(ctx.Repo.Commit.ID.String()), 1))))
}

View file

@ -203,16 +203,7 @@ headerLoop:
}
// Discard the rest of the tag
discard := size - n + 1
for discard > math.MaxInt32 {
_, err := rd.Discard(math.MaxInt32)
if err != nil {
return id, err
}
discard -= math.MaxInt32
}
_, err := rd.Discard(int(discard))
return id, err
return id, DiscardFull(rd, size-n+1)
}
// ReadTreeID reads a tree ID from a cat-file --batch stream, throwing away the rest of the stream.
@ -238,16 +229,7 @@ headerLoop:
}
// Discard the rest of the commit
discard := size - n + 1
for discard > math.MaxInt32 {
_, err := rd.Discard(math.MaxInt32)
if err != nil {
return id, err
}
discard -= math.MaxInt32
}
_, err := rd.Discard(int(discard))
return id, err
return id, DiscardFull(rd, size-n+1)
}
// git tree files are a list:
@ -345,3 +327,21 @@ func init() {
_, filename, _, _ := runtime.Caller(0)
callerPrefix = strings.TrimSuffix(filename, "modules/git/batch_reader.go")
}
func DiscardFull(rd *bufio.Reader, discard int64) error {
if discard > math.MaxInt32 {
n, err := rd.Discard(math.MaxInt32)
discard -= int64(n)
if err != nil {
return err
}
}
for discard > 0 {
n, err := rd.Discard(int(discard))
discard -= int64(n)
if err != nil {
return err
}
}
return nil
}

View file

@ -115,6 +115,10 @@ func (r *BlameReader) NextPart() (*BlamePart, error) {
// Close BlameReader - don't run NextPart after invoking that
func (r *BlameReader) Close() error {
if r.bufferedReader == nil {
return nil
}
err := <-r.done
r.bufferedReader = nil
_ = r.reader.Close()

View file

@ -9,7 +9,6 @@ import (
"bufio"
"bytes"
"io"
"math"
"code.gitea.io/gitea/modules/log"
)
@ -103,26 +102,17 @@ func (b *blobReader) Read(p []byte) (n int, err error) {
// Close implements io.Closer
func (b *blobReader) Close() error {
defer b.cancel()
if b.n > 0 {
for b.n > math.MaxInt32 {
n, err := b.rd.Discard(math.MaxInt32)
b.n -= int64(n)
if err != nil {
return err
}
b.n -= math.MaxInt32
}
n, err := b.rd.Discard(int(b.n))
b.n -= int64(n)
if err != nil {
return err
}
if b.rd == nil {
return nil
}
if b.n == 0 {
_, err := b.rd.Discard(1)
b.n--
defer b.cancel()
if err := DiscardFull(b.rd, b.n+1); err != nil {
return err
}
b.rd = nil
return nil
}

View file

@ -151,6 +151,9 @@ func GetLastCommitForPaths(ctx context.Context, commit *Commit, treePath string,
return nil, err
}
if typ != "commit" {
if err := DiscardFull(batchReader, size+1); err != nil {
return nil, err
}
return nil, fmt.Errorf("unexpected type: %s for commit id: %s", typ, commitID)
}
c, err = CommitFromReader(commit.repo, MustIDFromString(commitID), io.LimitReader(batchReader, size))

View file

@ -169,6 +169,10 @@ func FindLFSFile(repo *git.Repository, objectID git.ObjectID) ([]*LFSResult, err
} else {
break commitReadingLoop
}
default:
if err := git.DiscardFull(batchReader, size+1); err != nil {
return nil, err
}
}
}
}

View file

@ -88,16 +88,17 @@ func OpenRepository(ctx context.Context, repoPath string) (*Repository, error) {
}
// Close this repository, in particular close the underlying gogitStorage if this is not nil
func (repo *Repository) Close() (err error) {
func (repo *Repository) Close() error {
if repo == nil || repo.gogitStorage == nil {
return
return nil
}
if err := repo.gogitStorage.Close(); err != nil {
gitealog.Error("Error closing storage: %v", err)
}
repo.gogitStorage = nil
repo.LastCommitCache = nil
repo.tagCache = nil
return
return nil
}
// GoGitRepo gets the go-git repo representation

View file

@ -27,10 +27,12 @@ type Repository struct {
gpgSettings *GPGSettings
batchInUse bool
batchCancel context.CancelFunc
batchReader *bufio.Reader
batchWriter WriteCloserError
checkInUse bool
checkCancel context.CancelFunc
checkReader *bufio.Reader
checkWriter WriteCloserError
@ -79,24 +81,29 @@ func OpenRepository(ctx context.Context, repoPath string) (*Repository, error) {
// CatFileBatch obtains a CatFileBatch for this repository
func (repo *Repository) CatFileBatch(ctx context.Context) (WriteCloserError, *bufio.Reader, func()) {
if repo.batchCancel == nil || repo.batchReader.Buffered() > 0 {
if repo.batchCancel == nil || repo.batchInUse {
log.Debug("Opening temporary cat file batch for: %s", repo.Path)
return CatFileBatch(ctx, repo.Path)
}
return repo.batchWriter, repo.batchReader, func() {}
repo.batchInUse = true
return repo.batchWriter, repo.batchReader, func() {
repo.batchInUse = false
}
}
// CatFileBatchCheck obtains a CatFileBatchCheck for this repository
func (repo *Repository) CatFileBatchCheck(ctx context.Context) (WriteCloserError, *bufio.Reader, func()) {
if repo.checkCancel == nil || repo.checkReader.Buffered() > 0 {
log.Debug("Opening temporary cat file batch-check: %s", repo.Path)
if repo.checkCancel == nil || repo.checkInUse {
log.Debug("Opening temporary cat file batch-check for: %s", repo.Path)
return CatFileBatchCheck(ctx, repo.Path)
}
return repo.checkWriter, repo.checkReader, func() {}
repo.checkInUse = true
return repo.checkWriter, repo.checkReader, func() {
repo.checkInUse = false
}
}
// Close this repository, in particular close the underlying gogitStorage if this is not nil
func (repo *Repository) Close() (err error) {
func (repo *Repository) Close() error {
if repo == nil {
return nil
}
@ -105,14 +112,16 @@ func (repo *Repository) Close() (err error) {
repo.batchReader = nil
repo.batchWriter = nil
repo.batchCancel = nil
repo.batchInUse = false
}
if repo.checkCancel != nil {
repo.checkCancel()
repo.checkCancel = nil
repo.checkReader = nil
repo.checkWriter = nil
repo.checkInUse = false
}
repo.LastCommitCache = nil
repo.tagCache = nil
return err
return nil
}

View file

@ -121,8 +121,7 @@ func (repo *Repository) getCommitFromBatchReader(rd *bufio.Reader, id ObjectID)
return commit, nil
default:
log.Debug("Unknown typ: %s", typ)
_, err = rd.Discard(int(size) + 1)
if err != nil {
if err := DiscardFull(rd, size+1); err != nil {
return nil, err
}
return nil, ErrNotExist{

View file

@ -7,10 +7,8 @@
package git
import (
"bufio"
"bytes"
"io"
"math"
"strings"
"code.gitea.io/gitea/modules/analyze"
@ -174,8 +172,7 @@ func (repo *Repository) GetLanguageStats(commitID string) (map[string]int64, err
return nil, err
}
content = contentBuf.Bytes()
err = discardFull(batchReader, discard)
if err != nil {
if err := DiscardFull(batchReader, discard); err != nil {
return nil, err
}
}
@ -224,21 +221,3 @@ func (repo *Repository) GetLanguageStats(commitID string) (map[string]int64, err
return mergeLanguageStats(sizes), nil
}
func discardFull(rd *bufio.Reader, discard int64) error {
if discard > math.MaxInt32 {
n, err := rd.Discard(math.MaxInt32)
discard -= int64(n)
if err != nil {
return err
}
}
for discard > 0 {
n, err := rd.Discard(int(discard))
discard -= int64(n)
if err != nil {
return err
}
}
return nil
}

View file

@ -103,6 +103,9 @@ func (repo *Repository) getTag(tagID ObjectID, name string) (*Tag, error) {
return nil, err
}
if typ != "tag" {
if err := DiscardFull(rd, size+1); err != nil {
return nil, err
}
return nil, ErrNotExist{ID: tagID.String()}
}

View file

@ -58,6 +58,9 @@ func (repo *Repository) getTree(id ObjectID) (*Tree, error) {
tree.entriesParsed = true
return tree, nil
default:
if err := DiscardFull(rd, size+1); err != nil {
return nil, err
}
return nil, ErrNotExist{
ID: id.String(),
}

View file

@ -7,7 +7,6 @@ package git
import (
"io"
"math"
"strings"
)
@ -63,19 +62,8 @@ func (t *Tree) ListEntries() (Entries, error) {
}
// Not a tree just use ls-tree instead
for sz > math.MaxInt32 {
discarded, err := rd.Discard(math.MaxInt32)
sz -= int64(discarded)
if err != nil {
return nil, err
}
}
for sz > 0 {
discarded, err := rd.Discard(int(sz))
sz -= int64(discarded)
if err != nil {
return nil, err
}
if err := DiscardFull(rd, sz+1); err != nil {
return nil, err
}
}

27
modules/git/tree_test.go Normal file
View file

@ -0,0 +1,27 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package git
import (
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
)
func TestSubTree_Issue29101(t *testing.T) {
repo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "repo1_bare"))
assert.NoError(t, err)
defer repo.Close()
commit, err := repo.GetCommit("ce064814f4a0d337b333e646ece456cd39fab612")
assert.NoError(t, err)
// old code could produce a different error if called multiple times
for i := 0; i < 10; i++ {
_, err = commit.SubTree("file1.txt")
assert.Error(t, err)
assert.True(t, IsErrNotExist(err))
}
}

View file

@ -91,7 +91,7 @@ func (i *Indexer) Ping(_ context.Context) error {
}
func (i *Indexer) Close() {
if i == nil {
if i == nil || i.Indexer == nil {
return
}

View file

@ -87,8 +87,5 @@ func (i *Indexer) Close() {
if i == nil {
return
}
if i.Client == nil {
return
}
i.Client = nil
}

View file

@ -218,7 +218,7 @@ func searchIssueIsPull(t *testing.T) {
SearchOptions{
IsPull: util.OptionalBoolTrue,
},
[]int64{12, 11, 20, 19, 9, 8, 3, 2},
[]int64{22, 21, 12, 11, 20, 19, 9, 8, 3, 2},
},
}
for _, test := range tests {
@ -239,7 +239,7 @@ func searchIssueIsClosed(t *testing.T) {
SearchOptions{
IsClosed: util.OptionalBoolFalse,
},
[]int64{17, 16, 15, 14, 13, 12, 11, 20, 6, 19, 18, 10, 7, 9, 8, 3, 2, 1},
[]int64{22, 21, 17, 16, 15, 14, 13, 12, 11, 20, 6, 19, 18, 10, 7, 9, 8, 3, 2, 1},
},
{
SearchOptions{
@ -305,7 +305,7 @@ func searchIssueByLabelID(t *testing.T) {
SearchOptions{
ExcludedLabelIDs: []int64{1},
},
[]int64{17, 16, 15, 14, 13, 12, 11, 20, 6, 5, 19, 18, 10, 7, 4, 9, 8, 3},
[]int64{22, 21, 17, 16, 15, 14, 13, 12, 11, 20, 6, 5, 19, 18, 10, 7, 4, 9, 8, 3},
},
}
for _, test := range tests {
@ -329,7 +329,7 @@ func searchIssueByTime(t *testing.T) {
SearchOptions{
UpdatedAfterUnix: int64Pointer(0),
},
[]int64{17, 16, 15, 14, 13, 12, 11, 20, 6, 5, 19, 18, 10, 7, 4, 9, 8, 3, 2, 1},
[]int64{22, 21, 17, 16, 15, 14, 13, 12, 11, 20, 6, 5, 19, 18, 10, 7, 4, 9, 8, 3, 2, 1},
},
}
for _, test := range tests {
@ -350,7 +350,7 @@ func searchIssueWithOrder(t *testing.T) {
SearchOptions{
SortBy: internal.SortByCreatedAsc,
},
[]int64{1, 2, 3, 8, 9, 4, 7, 10, 18, 19, 5, 6, 20, 11, 12, 13, 14, 15, 16, 17},
[]int64{1, 2, 3, 8, 9, 4, 7, 10, 18, 19, 5, 6, 20, 11, 12, 13, 14, 15, 16, 17, 21, 22},
},
}
for _, test := range tests {
@ -410,8 +410,8 @@ func searchIssueWithPaginator(t *testing.T) {
PageSize: 5,
},
},
[]int64{17, 16, 15, 14, 13},
20,
[]int64{22, 21, 17, 16, 15},
22,
},
}
for _, test := range tests {

View file

@ -1,48 +1,49 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package optional
package optional_test
import (
"testing"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/optional"
"github.com/stretchr/testify/assert"
)
func TestOption(t *testing.T) {
var uninitialized Option[int]
var uninitialized optional.Option[int]
assert.False(t, uninitialized.Has())
assert.Equal(t, int(0), uninitialized.Value())
assert.Equal(t, int(1), uninitialized.ValueOrDefault(1))
none := None[int]()
none := optional.None[int]()
assert.False(t, none.Has())
assert.Equal(t, int(0), none.Value())
assert.Equal(t, int(1), none.ValueOrDefault(1))
some := Some[int](1)
some := optional.Some[int](1)
assert.True(t, some.Has())
assert.Equal(t, int(1), some.Value())
assert.Equal(t, int(1), some.ValueOrDefault(2))
var ptr *int
assert.False(t, FromPtr(ptr).Has())
assert.False(t, optional.FromPtr(ptr).Has())
opt1 := FromPtr(util.ToPointer(1))
int1 := 1
opt1 := optional.FromPtr(&int1)
assert.True(t, opt1.Has())
assert.Equal(t, int(1), opt1.Value())
assert.False(t, FromNonDefault("").Has())
assert.False(t, optional.FromNonDefault("").Has())
opt2 := FromNonDefault("test")
opt2 := optional.FromNonDefault("test")
assert.True(t, opt2.Has())
assert.Equal(t, "test", opt2.Value())
assert.False(t, FromNonDefault(0).Has())
assert.False(t, optional.FromNonDefault(0).Has())
opt3 := FromNonDefault(1)
opt3 := optional.FromNonDefault(1)
assert.True(t, opt3.Has())
assert.Equal(t, int(1), opt3.Value())
}

View file

@ -0,0 +1,46 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package optional
import (
"code.gitea.io/gitea/modules/json"
"gopkg.in/yaml.v3"
)
func (o *Option[T]) UnmarshalJSON(data []byte) error {
var v *T
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*o = FromPtr(v)
return nil
}
func (o Option[T]) MarshalJSON() ([]byte, error) {
if !o.Has() {
return []byte("null"), nil
}
return json.Marshal(o.Value())
}
func (o *Option[T]) UnmarshalYAML(value *yaml.Node) error {
var v *T
if err := value.Decode(&v); err != nil {
return err
}
*o = FromPtr(v)
return nil
}
func (o Option[T]) MarshalYAML() (interface{}, error) {
if !o.Has() {
return nil, nil
}
value := new(yaml.Node)
err := value.Encode(o.Value())
return value, err
}

View file

@ -0,0 +1,190 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package optional_test
import (
std_json "encoding/json" //nolint:depguard
"testing"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/optional"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
)
type testSerializationStruct struct {
NormalString string `json:"normal_string" yaml:"normal_string"`
NormalBool bool `json:"normal_bool" yaml:"normal_bool"`
OptBool optional.Option[bool] `json:"optional_bool,omitempty" yaml:"optional_bool,omitempty"`
OptString optional.Option[string] `json:"optional_string,omitempty" yaml:"optional_string,omitempty"`
OptTwoBool optional.Option[bool] `json:"optional_two_bool" yaml:"optional_two_bool"`
OptTwoString optional.Option[string] `json:"optional_twostring" yaml:"optional_two_string"`
}
func TestOptionalToJson(t *testing.T) {
tests := []struct {
name string
obj *testSerializationStruct
want string
}{
{
name: "empty",
obj: new(testSerializationStruct),
want: `{"normal_string":"","normal_bool":false,"optional_two_bool":null,"optional_twostring":null}`,
},
{
name: "some",
obj: &testSerializationStruct{
NormalString: "a string",
NormalBool: true,
OptBool: optional.Some(false),
OptString: optional.Some(""),
OptTwoBool: optional.None[bool](),
OptTwoString: optional.None[string](),
},
want: `{"normal_string":"a string","normal_bool":true,"optional_bool":false,"optional_string":"","optional_two_bool":null,"optional_twostring":null}`,
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
b, err := json.Marshal(tc.obj)
assert.NoError(t, err)
assert.EqualValues(t, tc.want, string(b), "gitea json module returned unexpected")
b, err = std_json.Marshal(tc.obj)
assert.NoError(t, err)
assert.EqualValues(t, tc.want, string(b), "std json module returned unexpected")
})
}
}
func TestOptionalFromJson(t *testing.T) {
tests := []struct {
name string
data string
want testSerializationStruct
}{
{
name: "empty",
data: `{}`,
want: testSerializationStruct{
NormalString: "",
},
},
{
name: "some",
data: `{"normal_string":"a string","normal_bool":true,"optional_bool":false,"optional_string":"","optional_two_bool":null,"optional_twostring":null}`,
want: testSerializationStruct{
NormalString: "a string",
NormalBool: true,
OptBool: optional.Some(false),
OptString: optional.Some(""),
},
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
var obj1 testSerializationStruct
err := json.Unmarshal([]byte(tc.data), &obj1)
assert.NoError(t, err)
assert.EqualValues(t, tc.want, obj1, "gitea json module returned unexpected")
var obj2 testSerializationStruct
err = std_json.Unmarshal([]byte(tc.data), &obj2)
assert.NoError(t, err)
assert.EqualValues(t, tc.want, obj2, "std json module returned unexpected")
})
}
}
func TestOptionalToYaml(t *testing.T) {
tests := []struct {
name string
obj *testSerializationStruct
want string
}{
{
name: "empty",
obj: new(testSerializationStruct),
want: `normal_string: ""
normal_bool: false
optional_two_bool: null
optional_two_string: null
`,
},
{
name: "some",
obj: &testSerializationStruct{
NormalString: "a string",
NormalBool: true,
OptBool: optional.Some(false),
OptString: optional.Some(""),
},
want: `normal_string: a string
normal_bool: true
optional_bool: false
optional_string: ""
optional_two_bool: null
optional_two_string: null
`,
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
b, err := yaml.Marshal(tc.obj)
assert.NoError(t, err)
assert.EqualValues(t, tc.want, string(b), "yaml module returned unexpected")
})
}
}
func TestOptionalFromYaml(t *testing.T) {
tests := []struct {
name string
data string
want testSerializationStruct
}{
{
name: "empty",
data: ``,
want: testSerializationStruct{},
},
{
name: "empty but init",
data: `normal_string: ""
normal_bool: false
optional_bool:
optional_two_bool:
optional_two_string:
`,
want: testSerializationStruct{},
},
{
name: "some",
data: `
normal_string: a string
normal_bool: true
optional_bool: false
optional_string: ""
optional_two_bool: null
optional_twostring: null
`,
want: testSerializationStruct{
NormalString: "a string",
NormalBool: true,
OptBool: optional.Some(false),
OptString: optional.Some(""),
},
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
var obj testSerializationStruct
err := yaml.Unmarshal([]byte(tc.data), &obj)
assert.NoError(t, err)
assert.EqualValues(t, tc.want, obj, "yaml module returned unexpected")
})
}
}

View file

@ -9,7 +9,6 @@ import (
"path/filepath"
"runtime"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
)
@ -94,15 +93,14 @@ done
`, setting.ScriptType, util.ShellEscape(setting.AppPath), util.ShellEscape(setting.CustomConf)),
}
if git.SupportProcReceive {
hookNames = append(hookNames, "proc-receive")
hookTpls = append(hookTpls,
fmt.Sprintf(`#!/usr/bin/env %s
// although only new git (>=2.29) supports proc-receive, it's still good to create its hook, in case the user upgrades git
hookNames = append(hookNames, "proc-receive")
hookTpls = append(hookTpls,
fmt.Sprintf(`#!/usr/bin/env %s
# AUTO GENERATED BY GITEA, DO NOT MODIFY
%s hook --config=%s proc-receive
`, setting.ScriptType, util.ShellEscape(setting.AppPath), util.ShellEscape(setting.CustomConf)))
giteaHookTpls = append(giteaHookTpls, "")
}
giteaHookTpls = append(giteaHookTpls, "")
return hookNames, hookTpls, giteaHookTpls
}

View file

@ -376,7 +376,9 @@ func SyncReleasesWithTags(ctx context.Context, repo *repo_model.Repository, gitR
}
if err := PushUpdateAddTag(ctx, repo, gitRepo, tagName, sha1, refname); err != nil {
return fmt.Errorf("unable to PushUpdateAddTag: %q to Repo[%d:%s/%s]: %w", tagName, repo.ID, repo.OwnerName, repo.Name, err)
// sometimes, some tags will be sync failed. i.e. https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tag/?h=v2.6.11
// this is a tree object, not a tag object which created before git
log.Error("unable to PushUpdateAddTag: %q to Repo[%d:%s/%s]: %v", tagName, repo.ID, repo.OwnerName, repo.Name, err)
}
return nil

View file

@ -3,15 +3,23 @@
package setting
import "code.gitea.io/gitea/modules/container"
// Admin settings
var Admin struct {
DisableRegularOrgCreation bool
DefaultEmailNotification string
SendNotificationEmailOnNewUser bool
UserDisabledFeatures container.Set[string]
}
func loadAdminFrom(rootCfg ConfigProvider) {
mustMapSetting(rootCfg, "admin", &Admin)
sec := rootCfg.Section("admin")
Admin.DisableRegularOrgCreation = sec.Key("DISABLE_REGULAR_ORG_CREATION").MustBool(false)
Admin.DefaultEmailNotification = sec.Key("DEFAULT_EMAIL_NOTIFICATIONS").MustString("enabled")
Admin.UserDisabledFeatures = container.SetOf(sec.Key("USER_DISABLED_FEATURES").Strings(",")...)
}
const (
UserFeatureDeletion = "deletion"
)

View file

@ -9,12 +9,12 @@ import (
"html"
"html/template"
"net/url"
"slices"
"strings"
"time"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/emoji"
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/svg"
@ -35,8 +35,9 @@ func NewFuncMap() template.FuncMap {
// html/template related functions
"dict": dict, // it's lowercase because this name has been widely used. Our other functions should have uppercase names.
"Eval": Eval,
"Safe": Safe,
"Escape": Escape,
"SafeHTML": SafeHTML,
"HTMLFormat": HTMLFormat,
"HTMLEscape": HTMLEscape,
"QueryEscape": url.QueryEscape,
"JSEscape": JSEscapeSafe,
"Str2html": Str2html, // TODO: rename it to SanitizeHTML
@ -162,7 +163,6 @@ func NewFuncMap() template.FuncMap {
"RenderCodeBlock": RenderCodeBlock,
"RenderIssueTitle": RenderIssueTitle,
"RenderEmoji": RenderEmoji,
"RenderEmojiPlain": RenderEmojiPlain,
"ReactionToEmoji": ReactionToEmoji,
"RenderMarkdownToHtml": RenderMarkdownToHtml,
@ -182,8 +182,25 @@ func NewFuncMap() template.FuncMap {
}
}
// Safe render raw as HTML
func Safe(s any) template.HTML {
func HTMLFormat(s string, rawArgs ...any) template.HTML {
args := slices.Clone(rawArgs)
for i, v := range args {
switch v := v.(type) {
case nil, bool, int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64, template.HTML:
// for most basic types (including template.HTML which is safe), just do nothing and use it
case string:
args[i] = template.HTMLEscapeString(v)
case fmt.Stringer:
args[i] = template.HTMLEscapeString(v.String())
default:
args[i] = template.HTMLEscapeString(fmt.Sprint(v))
}
}
return template.HTML(fmt.Sprintf(s, args...))
}
// SafeHTML render raw as HTML
func SafeHTML(s any) template.HTML {
switch v := s.(type) {
case string:
return template.HTML(v)
@ -204,7 +221,7 @@ func Str2html(s any) template.HTML {
panic(fmt.Sprintf("unexpected type %T", s))
}
func Escape(s any) template.HTML {
func HTMLEscape(s any) template.HTML {
switch v := s.(type) {
case string:
return template.HTML(html.EscapeString(v))
@ -218,16 +235,6 @@ func JSEscapeSafe(s string) template.HTML {
return template.HTML(template.JSEscapeString(s))
}
func RenderEmojiPlain(s any) any {
switch v := s.(type) {
case string:
return emoji.ReplaceAliases(v)
case template.HTML:
return template.HTML(emoji.ReplaceAliases(string(v)))
}
panic(fmt.Sprintf("unexpected type %T", s))
}
// DotEscape wraps a dots in names with ZWJ [U+200D] in order to prevent autolinkers from detecting these as urls
func DotEscape(raw string) string {
return strings.ReplaceAll(raw, ".", "\u200d.\u200d")

View file

@ -4,6 +4,7 @@
package templates
import (
"html/template"
"testing"
"github.com/stretchr/testify/assert"
@ -56,3 +57,7 @@ func TestSubjectBodySeparator(t *testing.T) {
func TestJSEscapeSafe(t *testing.T) {
assert.EqualValues(t, `\u0026\u003C\u003E\'\"`, JSEscapeSafe(`&<>'"`))
}
func TestHTMLFormat(t *testing.T) {
assert.Equal(t, template.HTML("<a>&lt; < 1</a>"), HTMLFormat("<a>%s %s %d</a>", "<", template.HTML("<"), 1))
}

View file

@ -149,6 +149,7 @@ func (b *FileBackedBuffer) Close() error {
if b.file != nil {
err := b.file.Close()
os.Remove(b.file.Name())
b.file = nil
return err
}
return nil

View file

@ -11,6 +11,8 @@ import (
"strconv"
"strings"
"code.gitea.io/gitea/modules/optional"
"golang.org/x/text/cases"
"golang.org/x/text/language"
)
@ -42,6 +44,22 @@ func (o OptionalBool) IsNone() bool {
return o == OptionalBoolNone
}
// ToGeneric converts OptionalBool to optional.Option[bool]
func (o OptionalBool) ToGeneric() optional.Option[bool] {
if o.IsNone() {
return optional.None[bool]()
}
return optional.Some[bool](o.IsTrue())
}
// OptionalBoolFromGeneric converts optional.Option[bool] to OptionalBool
func OptionalBoolFromGeneric(o optional.Option[bool]) OptionalBool {
if o.Has() {
return OptionalBoolOf(o.Value())
}
return OptionalBoolNone
}
// OptionalBoolOf get the corresponding OptionalBool of a bool
func OptionalBoolOf(b bool) OptionalBool {
if b {

View file

@ -590,6 +590,7 @@ org_still_own_packages=Organizace stále vlastní jeden nebo více balíčků. N
target_branch_not_exist=Cílová větev neexistuje.
[user]
change_avatar=Změnit váš avatar…
joined_on=Přidal/a se %s
@ -1956,6 +1957,8 @@ activity.git_stats_and_deletions=a
activity.git_stats_deletion_1=%d odebrání
activity.git_stats_deletion_n=%d odebrání
contributors.contribution_type.commits=Commity
search=Vyhledat
search.search_repo=Hledat repozitář
search.type.tooltip=Druh vyhledávání
@ -2544,6 +2547,8 @@ error.csv.too_large=Tento soubor nelze vykreslit, protože je příliš velký.
error.csv.unexpected=Tento soubor nelze vykreslit, protože obsahuje neočekávaný znak na řádku %d ve sloupci %d.
error.csv.invalid_field_count=Soubor nelze vykreslit, protože má nesprávný počet polí na řádku %d.
[graphs]
[org]
org_name_holder=Název organizace
org_full_name_holder=Celý název organizace
@ -3182,6 +3187,7 @@ notices.desc=Popis
notices.op=Akce
notices.delete_success=Systémové upozornění bylo smazáno.
[action]
create_repo=vytvořil/a repozitář <a href="%s">%s</a>
rename_repo=přejmenoval/a repozitář z <code>%[1]s</code> na <a href="%[2]s">%[3]s</a>
@ -3366,6 +3372,8 @@ rpm.registry=Nastavte tento registr z příkazového řádku:
rpm.distros.redhat=na distribuce založené na RedHat
rpm.distros.suse=na distribuce založené na SUSE
rpm.install=Pro instalaci balíčku spusťte následující příkaz:
rpm.repository=Informace o repozitáři
rpm.repository.architectures=Architektury
rubygems.install=Pro instalaci balíčku pomocí gem spusťte následující příkaz:
rubygems.install2=nebo ho přidejte do Gemfie:
rubygems.dependencies.runtime=Běhové závislosti
@ -3493,8 +3501,6 @@ runs.actors_no_select=Všichni aktéři
runs.status_no_select=Všechny stavy
runs.no_results=Nebyly nalezeny žádné výsledky.
runs.no_workflows=Zatím neexistují žádné pracovní postupy.
runs.no_workflows.quick_start=Nevíte jak začít s Gitea Action? Podívejte se na <a target="_blank" rel="noopener noreferrer" href="%s">průvodce rychlým startem</a>.
runs.no_workflows.documentation=Další informace o Gitea Action, viz <a target="_blank" rel="noopener noreferrer" href="%s">dokumentace</a>.
runs.no_runs=Pracovní postup zatím nebyl spuštěn.
runs.empty_commit_message=(prázdná zpráva commitu)
@ -3512,7 +3518,6 @@ variables.none=Zatím nejsou žádné proměnné.
variables.deletion=Odstranit proměnnou
variables.deletion.description=Odstranění proměnné je trvalé a nelze jej vrátit zpět. Pokračovat?
variables.description=Proměnné budou předány určitým akcím a nelze je přečíst jinak.
variables.id_not_exist=Proměnná s id %d neexistuje.
variables.edit=Upravit proměnnou
variables.deletion.failed=Nepodařilo se odstranit proměnnou.
variables.deletion.success=Proměnná byla odstraněna.

View file

@ -601,6 +601,7 @@ target_branch_not_exist=Der Ziel-Branch existiert nicht.
username_error_no_dots = ` darf nur alphanumerische Zeichen („0-9“, „a-z“, „A-Z“), Bindestriche („-“), Unterstriche („_“) enthalten. Es kann nicht mit nicht-alphanumerischen Zeichen beginnen oder enden und aufeinanderfolgende nicht-alphanumerische Zeichen sind ebenfalls verboten.`
admin_cannot_delete_self = Du kannst dich nicht selbst löschen, wenn du ein Admin bist. Bitte entferne zuerst deine Adminrechte.
[user]
change_avatar=Profilbild ändern …
joined_on=Beigetreten am %s
@ -1985,6 +1986,8 @@ activity.git_stats_and_deletions=und
activity.git_stats_deletion_1=%d Löschung
activity.git_stats_deletion_n=%d Löschungen
contributors.contribution_type.commits=Commits
search=Suchen
search.search_repo=Repository durchsuchen
search.type.tooltip=Suchmodus
@ -2645,6 +2648,8 @@ vendored = Vendored
activity.navbar.pulse = Puls
pulls.made_using_agit = AGit
[graphs]
[org]
org_name_holder=Name der Organisation
org_full_name_holder=Vollständiger Name der Organisation
@ -3306,6 +3311,7 @@ self_check.no_problem_found = Noch kein Problem gefunden.
self_check.database_inconsistent_collation_columns = Datenbank benutzt Collation %s, aber diese Spalten benutzen Collations, die nicht zusammenpassen. Das könnte ein paar unerwartete Probleme verursachen.
self_check.database_collation_mismatch = Erwarte von Datenbank, folgende Collation zu verwenden: %s
[action]
create_repo=hat das Repository <a href="%s">%s</a> erstellt
rename_repo=hat das Repository von <code>%[1]s</code> zu <a href="%[2]s">%[3]s</a> umbenannt
@ -3490,6 +3496,8 @@ rpm.registry=Diese Registry über die Kommandozeile einrichten:
rpm.distros.redhat=auf RedHat-basierten Distributionen
rpm.distros.suse=auf SUSE-basierten Distributionen
rpm.install=Nutze folgenden Befehl, um das Paket zu installieren:
rpm.repository=Repository-Informationen
rpm.repository.architectures=Architekturen
rubygems.install=Um das Paket mit gem zu installieren, führe den folgenden Befehl aus:
rubygems.install2=oder füg es zum Gemfile hinzu:
rubygems.dependencies.runtime=Laufzeitabhängigkeiten
@ -3640,7 +3648,6 @@ variables.none=Es gibt noch keine Variablen.
variables.deletion=Variable entfernen
variables.deletion.description=Das Entfernen einer Variable ist dauerhaft und kann nicht rückgängig gemacht werden. Fortfahren?
variables.description=Variablen werden an bestimmte Aktionen übergeben und können nicht anderweitig gelesen werden.
variables.id_not_exist=Variable mit ID %d existiert nicht.
variables.edit=Variable bearbeiten
variables.deletion.failed=Fehler beim Entfernen der Variable.
variables.deletion.success=Die Variable wurde entfernt.

View file

@ -589,6 +589,7 @@ org_still_own_packages=Αυτός ο οργανισμός κατέχει ακό
target_branch_not_exist=Ο κλάδος προορισμού δεν υπάρχει.
[user]
change_avatar=Αλλαγή του avatar σας…
joined_on=Εγγράφηκε την %s
@ -1967,6 +1968,8 @@ activity.git_stats_and_deletions=και
activity.git_stats_deletion_1=%d διαγραφή
activity.git_stats_deletion_n=%d διαγραφές
contributors.contribution_type.commits=Υποβολές
search=Αναζήτηση
search.search_repo=Αναζήτηση αποθετηρίου
search.type.tooltip=Τύπος αναζήτησης
@ -2567,6 +2570,8 @@ error.csv.too_large=Δεν είναι δυνατή η απόδοση αυτού
error.csv.unexpected=Δεν είναι δυνατή η απόδοση αυτού του αρχείου, επειδή περιέχει έναν μη αναμενόμενο χαρακτήρα στη γραμμή %d και στη στήλη %d.
error.csv.invalid_field_count=Δεν είναι δυνατή η απόδοση αυτού του αρχείου, επειδή έχει λάθος αριθμό πεδίων στη γραμμή %d.
[graphs]
[org]
org_name_holder=Όνομα Οργανισμού
org_full_name_holder=Πλήρες Όνομα Οργανισμού
@ -3218,6 +3223,7 @@ notices.desc=Περιγραφή
notices.op=Λειτ.
notices.delete_success=Οι ειδοποιήσεις του συστήματος έχουν διαγραφεί.
[action]
create_repo=δημιούργησε το αποθετήριο <a href="%s">%s</a>
rename_repo=μετονόμασε το αποθετήριο από <code>%[1]s</code> σε <a href="%[2]s">%[3]s</a>
@ -3402,6 +3408,8 @@ rpm.registry=Ρυθμίστε αυτό το μητρώο από τη γραμμ
rpm.distros.redhat=σε διανομές βασισμένες στο RedHat
rpm.distros.suse=σε διανομές με βάση το SUSE
rpm.install=Για να εγκαταστήσετε το πακέτο, εκτελέστε την ακόλουθη εντολή:
rpm.repository=Πληροφορίες Αποθετηρίου
rpm.repository.architectures=Αρχιτεκτονικές
rubygems.install=Για να εγκαταστήσετε το πακέτο χρησιμοποιώντας το gem, εκτελέστε την ακόλουθη εντολή:
rubygems.install2=ή προσθέστε το στο Gemfile:
rubygems.dependencies.runtime=Εξαρτήσεις Εκτέλεσης
@ -3534,8 +3542,6 @@ runs.actors_no_select=Όλοι οι φορείς
runs.status_no_select=Όλες οι καταστάσεις
runs.no_results=Δεν βρέθηκαν αποτελέσματα.
runs.no_workflows=Δεν υπάρχουν ροές εργασίας ακόμα.
runs.no_workflows.quick_start=Δεν ξέρετε πώς να ξεκινήσετε με τις Δράσεις Gitea; Συμβουλευτείτε <a target="_blank" rel="noopener noreferrer" href="%s">τον οδηγό για γρήγορη αρχή</a>.
runs.no_workflows.documentation=Για περισσότερες πληροφορίες σχετικά με τη Δράση Gitea, ανατρέξτε <a target="_blank" rel="noopener noreferrer" href="%s">στην τεκμηρίωση</a>.
runs.no_runs=Η ροή εργασίας δεν έχει τρέξει ακόμα.
runs.empty_commit_message=(κενό μήνυμα υποβολής)
@ -3554,7 +3560,6 @@ variables.none=Δεν υπάρχουν μεταβλητές ακόμα.
variables.deletion=Αφαίρεση μεταβλητής
variables.deletion.description=Η αφαίρεση μιας μεταβλητής είναι μόνιμη και δεν μπορεί να αναιρεθεί. Συνέχεια;
variables.description=Η μεταβλητές θα δίνονται σε ορισμένες δράσεις και δεν μπορούν να διαβαστούν αλλιώς.
variables.id_not_exist=Η μεταβλητή με id %d δεν υπάρχει.
variables.edit=Επεξεργασία Μεταβλητής
variables.deletion.failed=Αποτυχία αφαίρεσης της μεταβλητής.
variables.deletion.success=Η μεταβλητή έχει αφαιρεθεί.

View file

@ -248,6 +248,7 @@ email_title = Email Settings
smtp_addr = SMTP Host
smtp_port = SMTP Port
smtp_from = Send Email As
smtp_from_invalid = The "Send Email As" address is invalid
smtp_from_helper = Email address Forgejo will use. Enter a plain email address or use the "Name" <email@example.com> format.
mailer_user = SMTP Username
mailer_password = SMTP Password
@ -1960,7 +1961,9 @@ wiki.original_git_entry_tooltip = View original Git file instead of using friend
activity = Activity
activity.navbar.pulse = Pulse
activity.navbar.code_frequency = Code Frequency
activity.navbar.contributors = Contributors
activity.navbar.recent_commits = Recent Commits
activity.period.filter_label = Period:
activity.period.daily = 1 day
activity.period.halfweekly = 3 days
@ -2655,7 +2658,9 @@ component_loading = Loading %s...
component_loading_failed = Could not load %s
component_loading_info = This might take a bit…
component_failed_to_load = An unexpected error happened.
code_frequency.what = code frequency
contributors.what = contributions
recent_commits.what = recent commits
[org]
org_name_holder = Organization Name

View file

@ -599,6 +599,7 @@ target_branch_not_exist=La rama de destino no existe
admin_cannot_delete_self = No puedes eliminarte a ti mismo cuando eres un admin (administrador). Por favor, elimina primero tus privilegios de administrador.
username_error_no_dots = ` solo puede contener carácteres alfanuméricos ('0-9','a-z','A-Z'), guiones ('-') y guiones bajos ('_'). No puede empezar o terminar con carácteres no alfanuméricos y también están prohibidos los carácteres no alfanuméricos consecutivos.`
[user]
change_avatar=Cambiar su avatar…
joined_on=Se unió el %s
@ -1982,6 +1983,8 @@ activity.git_stats_and_deletions=y
activity.git_stats_deletion_1=%d eliminación
activity.git_stats_deletion_n=%d eliminaciones
contributors.contribution_type.commits=Commits
search=Buscar
search.search_repo=Buscar repositorio
search.type.tooltip=Tipo de búsqueda
@ -2582,6 +2585,8 @@ error.csv.unexpected=No se puede procesar este archivo porque contiene un carác
error.csv.invalid_field_count=No se puede procesar este archivo porque tiene un número incorrecto de campos en la línea %d.
rss.must_be_on_branch = Debes estar en una rama para tener un feed RSS.
[graphs]
[org]
org_name_holder=Nombre de la organización
org_full_name_holder=Nombre completo de la organización
@ -3231,6 +3236,7 @@ notices.desc=Descripción
notices.op=Operación
notices.delete_success=Los avisos del sistema se han eliminado.
[action]
create_repo=creó el repositorio <a href="%s">%s</a>
rename_repo=repositorio renombrado de <code>%[1]s</code> a <a href="%[2]s">%[3]s</a>
@ -3415,6 +3421,8 @@ rpm.registry=Configurar este registro desde la línea de comandos:
rpm.distros.redhat=en distribuciones basadas en RedHat
rpm.distros.suse=en distribuciones basadas en SUSE
rpm.install=Para instalar el paquete, ejecute el siguiente comando:
rpm.repository=Información del repositorio
rpm.repository.architectures=Arquitecturas
rubygems.install=Para instalar el paquete usando gem, ejecute el siguiente comando:
rubygems.install2=o añádelo al archivo Gemfile:
rubygems.dependencies.runtime=Dependencias en tiempo de ejecución
@ -3562,7 +3570,6 @@ variables.none=Aún no hay variables.
variables.deletion=Eliminar variable
variables.deletion.description=Eliminar una variable es permanente y no se puede deshacer. ¿Continuar?
variables.description=Las variables se pasarán a ciertas acciones y no se podrán leer de otro modo.
variables.id_not_exist=Variable con id %d no existe.
variables.edit=Editar variable
variables.deletion.failed=No se pudo eliminar la variable.
variables.deletion.success=La variable ha sido eliminada.

View file

@ -464,6 +464,7 @@ auth_failed=تشخیص هویت ناموفق: %v
target_branch_not_exist=شاخه مورد نظر وجود ندارد.
[user]
change_avatar=تغییر آواتار…
repositories=مخازن
@ -1499,6 +1500,8 @@ activity.git_stats_and_deletions=و
activity.git_stats_deletion_1=%d مذحوف
activity.git_stats_deletion_n=%d مذحوف
contributors.contribution_type.commits=کامیت‌ها
search=جستجو
search.search_repo=جستجوی مخزن
search.fuzzy=درهم
@ -1952,6 +1955,8 @@ error.csv.too_large=نمی توان این فایل را رندر کرد زیر
error.csv.unexpected=نمی توان این فایل را رندر کرد زیرا حاوی یک کاراکتر غیرمنتظره در خط %d و ستون %d است.
error.csv.invalid_field_count=نمی توان این فایل را رندر کرد زیرا تعداد فیلدهای آن در خط %d اشتباه است.
[graphs]
[org]
org_name_holder=نام سازمان
org_full_name_holder=نام کامل سازمان
@ -2502,6 +2507,7 @@ notices.desc=توضیحات
notices.op=عملیات.
notices.delete_success=گزارش سیستم حذف شده است.
[action]
create_repo=مخزن ایجاد شده <a href="%s"> %s</a>
rename_repo=مخزن تغییر نام داد از <code>%[1]s</code> به <a href="%[2]s">%[3]s</a>

View file

@ -426,6 +426,7 @@ auth_failed=Todennus epäonnistui: %v
target_branch_not_exist=Kohde branchia ei ole olemassa.
[user]
change_avatar=Vaihda profiilikuvasi…
repositories=Repot
@ -1075,6 +1076,8 @@ activity.git_stats_and_deletions=ja
activity.git_stats_deletion_1=%d poisto
activity.git_stats_deletion_n=%d poistoa
contributors.contribution_type.commits=Commitit
search=Haku
search.match=Osuma
search.code_no_results=Hakuehtoasi vastaavaa lähdekoodia ei löytynyt.
@ -1316,6 +1319,8 @@ topic.done=Valmis
[graphs]
[org]
org_name_holder=Organisaatio
org_full_name_holder=Organisaation täydellinen nimi
@ -1661,6 +1666,7 @@ notices.type_1=Repo
notices.desc=Kuvaus
notices.op=Toiminta
[action]
create_repo=luotu repo <a href="%s">%s</a>
rename_repo=uudelleennimetty repo <code>%[1]s</code> nimelle <a href="%[2]s">%[3]s</a>

View file

@ -600,6 +600,7 @@ target_branch_not_exist=La branche cible n'existe pas.
username_error_no_dots = ` peut uniquement contenir des caractères alphanumériques ('0-9','a-z','A-Z'), tiret ('-') et souligné ('_'). Ne peut commencer ou terminer avec un caractère non-alphanumérique, et l'utilisation de caractères non-alphanumériques consécutifs n'est pas permise.`
admin_cannot_delete_self = Vous ne pouvez supprimer votre compte lorsque vous disposez de droits d'administration. Veuillez d'abord renoncer à vos droits d'administration.
[user]
change_avatar=Changer votre avatar…
joined_on=Inscrit le %s
@ -1991,6 +1992,8 @@ activity.git_stats_and_deletions=et
activity.git_stats_deletion_1=%d suppression
activity.git_stats_deletion_n=%d suppressions
contributors.contribution_type.commits=Révisions
search=Chercher
search.search_repo=Rechercher dans le dépôt
search.type.tooltip=Type de recherche
@ -2642,6 +2645,8 @@ contributors.contribution_type.additions = Ajouts
contributors.contribution_type.filter_label = Type de contributeur :
contributors.contribution_type.deletions = Suppressions
[graphs]
[org]
org_name_holder=Nom de l'organisation
org_full_name_holder=Nom complet de l'organisation
@ -3303,6 +3308,7 @@ self_check.database_inconsistent_collation_columns = La base de donnée utilise
self_check.database_fix_mysql = Les utilisateurs de MySQL/MariaDB peuvent utiliser la commande "forgejo doctor convert" pour corriger les problèmes de collation, ou bien manuellement avec la commande SQL "ALTER ... COLLATE ...".
self_check.database_fix_mssql = Les utilisateurs de MSSQL sont pour l'instant contraint d'utiliser la commande SQL "ALTER ... COLLATE ..." pour corriger ce problème.
[action]
create_repo=a créé le dépôt <a href="%s">%s</a>
rename_repo=a rebaptisé le dépôt <s><code>%[1]s</code></s> en <a href="%[2]s">%[3]s</a>
@ -3487,6 +3493,8 @@ rpm.registry=Configurez ce registre à partir d'un terminal :
rpm.distros.redhat=sur les distributions basées sur RedHat
rpm.distros.suse=sur les distributions basées sur SUSE
rpm.install=Pour installer le paquet, exécutez la commande suivante :
rpm.repository=Informations sur le Dépôt
rpm.repository.architectures=Architectures
rubygems.install=Pour installer le paquet en utilisant gem, exécutez la commande suivante :
rubygems.install2=ou ajoutez-le au Gemfile :
rubygems.dependencies.runtime=Dépendances d'exécution
@ -3622,8 +3630,6 @@ runs.actors_no_select=Tous les acteurs
runs.status_no_select=Touts les statuts
runs.no_results=Aucun résultat correspondant.
runs.no_workflows=Il n'y a pas encore de workflows.
runs.no_workflows.quick_start=Vous ne savez pas comment commencer avec Forgejo Action ? Consultez <a target="_blank" rel="noopener noreferrer" href="%s">le guide de démarrage rapide</a>.
runs.no_workflows.documentation=Pour plus dinformations sur les Actions Forgejo, voir <a target="_blank" rel="noopener noreferrer" href="%s">la documentation</a>.
runs.no_runs=Le flux de travail n'a pas encore d'exécution.
runs.empty_commit_message=(message de révision vide)
@ -3642,7 +3648,6 @@ variables.none=Il n'y a pas encore de variables.
variables.deletion=Retirer la variable
variables.deletion.description=La suppression dune variable est permanente et ne peut être défaite. Continuer ?
variables.description=Les variables sont passées aux actions et ne peuvent être lues autrement.
variables.id_not_exist=La variable numéro %d nexiste pas.
variables.edit=Modifier la variable
variables.deletion.failed=Impossible de retirer la variable.
variables.deletion.success=La variable a bien été retirée.

View file

@ -370,6 +370,7 @@ auth_failed=A hitelesítés sikertelen: %v
target_branch_not_exist=Cél ág nem létezik.
[user]
change_avatar=Profilkép megváltoztatása…
repositories=Tárolók
@ -1054,6 +1055,8 @@ activity.git_stats_and_deletions=és
activity.git_stats_deletion_1=%d törlés
activity.git_stats_deletion_n=%d törlés
contributors.contribution_type.commits=Commit-ok
search=Keresés
search.search_repo=Tároló keresés
search.results=`"%s" találatok keresése itt: <a href="%s">%s</a>`
@ -1169,6 +1172,8 @@ topic.done=Kész
[graphs]
[org]
org_name_holder=Szervezet neve
org_full_name_holder=Szervezet teljes neve
@ -1581,6 +1586,7 @@ config.domain = Kiszolgálótartomány
config.cache_item_ttl = Gyorsítótárelem TTL értéke
config.app_data_path = Alkalmazásadatok elérési útja
[action]
create_repo=létrehozott tárolót: <a href="%s"> %s</a>
rename_repo=átnevezte a(z) <code>%[1]s</code> tárolót <a href="%[2]s">%[3]s</a>-ra/re

View file

@ -294,6 +294,7 @@ auth_failed=Otentikasi gagal: %v
target_branch_not_exist=Target cabang tidak ada.
[user]
change_avatar=Ganti avatar anda…
repositories=Repositori
@ -839,6 +840,8 @@ activity.title.releases_n=%d Rilis
activity.title.releases_published_by=%s dikeluarkan oleh %s
activity.published_release_label=Dikeluarkan
contributors.contribution_type.commits=Melakukan
search=Cari
search.search_repo=Cari repositori
search.results=Cari hasil untuk "%s" dalam <a href="%s">%s</a>
@ -954,6 +957,8 @@ branch.deleted_by=Dihapus oleh %s
[graphs]
[org]
org_name_holder=Nama Organisasi
org_full_name_holder=Organisasi Nama Lengkap
@ -1263,6 +1268,7 @@ notices.desc=Deskripsi
notices.op=Op.
notices.delete_success=Laporan sistem telah dihapus.
[action]
create_repo=repositori dibuat <a href="%s">%s</a>
rename_repo=ganti nama gudang penyimpanan dari <code>%[1]s</code> ke <a href="%[2]s">%[3]s</a>

View file

@ -402,6 +402,7 @@ team_not_exist=Liðið er ekki til.
[user]
change_avatar=Breyttu notandamyndinni þinni…
repositories=Hugbúnaðarsöfn
@ -990,6 +991,8 @@ activity.git_stats_and_deletions=og
activity.git_stats_deletion_1=%d eyðing
activity.git_stats_deletion_n=%d eyðingar
contributors.contribution_type.commits=Framlög
search=Leita
search.fuzzy=Óljóst
search.code_no_results=Enginn samsvarandi frumkóði fannst eftur þínum leitarorðum.
@ -1114,6 +1117,8 @@ topic.done=Í lagi
[graphs]
[org]
repo_updated=Uppfært
members=Meðlimar
@ -1280,6 +1285,7 @@ notices.type_1=Hugbúnaðarsafn
notices.type_2=Verkefni
notices.desc=Lýsing
[action]
create_issue=`opnaði vandamál <a href="%[1]s">%[3]s#%[2]s</a>`
reopen_issue=`enduropnaði vandamál <a href="%[1]s">%[3]s#%[2]s</a>`

View file

@ -491,6 +491,7 @@ auth_failed=Autenticazione non riuscita: %v
target_branch_not_exist=Il ramo (branch) di destinazione non esiste.
[user]
change_avatar=Modifica il tuo avatar…
repositories=Repository
@ -1624,6 +1625,8 @@ activity.git_stats_and_deletions=e
activity.git_stats_deletion_1=%d cancellazione
activity.git_stats_deletion_n=%d cancellazioni
contributors.contribution_type.commits=Commit
search=Ricerca
search.search_repo=Ricerca repository
search.fuzzy=Fuzzy
@ -2119,6 +2122,8 @@ error.csv.too_large=Impossibile visualizzare questo file perché è troppo grand
error.csv.unexpected=Impossibile visualizzare questo file perché contiene un carattere inatteso alla riga %d e alla colonna %d.
error.csv.invalid_field_count=Impossibile visualizzare questo file perché ha un numero errato di campi alla riga %d.
[graphs]
[org]
org_name_holder=Nome dell'Organizzazione
org_full_name_holder=Nome completo dell'organizzazione
@ -2705,6 +2710,7 @@ notices.desc=Descrizione
notices.op=Op.
notices.delete_success=Gli avvisi di sistema sono stati eliminati.
[action]
create_repo=ha creato il repository <a href="%s">%s</a>
rename_repo=repository rinominato da <code>%[1]s</code> a <a href="%[2]s">[3]s</a>

View file

@ -599,6 +599,7 @@ target_branch_not_exist=ターゲットのブランチが存在していませ
admin_cannot_delete_self = 管理者である場合、自分自身を削除することはできません。最初に管理者権限を削除してください。
username_error_no_dots = `英数字 (「0-9」、「a-z」、「A-Z」)、ダッシュ (「-」)、およびアンダースコア (「_」) のみを含めることができます。英数字以外の文字で開始または終了することはできず、連続した英数字以外の文字も禁止されています。`
[user]
change_avatar=アバターを変更…
joined_on=%sに登録
@ -1986,6 +1987,8 @@ activity.git_stats_and_deletions=、
activity.git_stats_deletion_1=%d行削除
activity.git_stats_deletion_n=%d行削除
contributors.contribution_type.commits=コミット
search=検索
search.search_repo=リポジトリを検索
search.type.tooltip=検索タイプ
@ -2589,6 +2592,8 @@ admin.enabled_flags = このリポジトリで有効になっているフラグ
clone_in_vscodium = VSCodiumでcloneする
desc.sha256 = SHA256
[graphs]
[org]
org_name_holder=組織名
org_full_name_holder=組織のフルネーム
@ -3240,6 +3245,7 @@ notices.desc=説明
notices.op=操作
notices.delete_success=システム通知を削除しました。
[action]
create_repo=がリポジトリ <a href="%s">%s</a> を作成しました
rename_repo=がリポジトリ名を <code>%[1]s</code> から <a href="%[2]s">%[3]s</a> へ変更しました
@ -3424,6 +3430,8 @@ rpm.registry=このレジストリをコマンドラインからセットアッ
rpm.distros.redhat=RedHat系ディストリビューションの場合
rpm.distros.suse=SUSE系ディストリビューションの場合
rpm.install=パッケージをインストールするには、次のコマンドを実行します:
rpm.repository=リポジトリ情報
rpm.repository.architectures=Architectures
rubygems.install=gem を使用してパッケージをインストールするには、次のコマンドを実行します:
rubygems.install2=または Gemfile に追加します:
rubygems.dependencies.runtime=実行用依存関係
@ -3556,8 +3564,6 @@ runs.actors_no_select=すべてのアクター
runs.status_no_select=すべてのステータス
runs.no_results=一致する結果はありません。
runs.no_workflows=ワークフローはまだありません。
runs.no_workflows.quick_start=Forgejo Action の始め方がわからない? <a target="_blank" rel="noopener noreferrer" href="%s">クイックスタートガイド</a>をご覧ください。
runs.no_workflows.documentation=Forgejo Action の詳細については、<a target="_blank" rel="noopener noreferrer" href="%s">ドキュメント</a>を参照してください。
runs.no_runs=ワークフローはまだ実行されていません。
runs.empty_commit_message=(空のコミットメッセージ)
@ -3576,7 +3582,6 @@ variables.none=変数はまだありません。
variables.deletion=変数を削除
variables.deletion.description=変数の削除は恒久的で元に戻すことはできません。 続行しますか?
variables.description=変数は特定のActionsに渡されます。 それ以外で読み出されることはありません。
variables.id_not_exist=idが%dの変数は存在しません。
variables.edit=変数の編集
variables.deletion.failed=変数を削除できませんでした。
variables.deletion.success=変数を削除しました。

View file

@ -350,6 +350,7 @@ auth_failed=인증 실패: %v
target_branch_not_exist=대상 브랜치가 존재하지 않습니다.
[user]
change_avatar=아바타 변경
repositories=저장소
@ -950,6 +951,8 @@ activity.title.releases_n=%d 개의 릴리즈
activity.title.releases_published_by=%s 가 %s 에 의하여 배포되었습니다.
activity.published_release_label=배포됨
contributors.contribution_type.commits=커밋
search=검색
search.search_repo=저장소 검색
search.results="<a href=\"%s\">%s</a> 에서 \"%s\" 에 대한 검색 결과"
@ -1162,6 +1165,8 @@ topic.count_prompt=25개 이상의 토픽을 선택하실 수 없습니다.
[graphs]
[org]
org_name_holder=조직 이름
org_full_name_holder=조직 전체 이름
@ -1522,6 +1527,7 @@ notices.desc=설명
notices.op=일.
notices.delete_success=시스템 알림이 삭제되었습니다.
[action]
create_repo=저장소를 만들었습니다. <a href="%s">%s</a>
rename_repo=<code>%[1]s에서</code>에서 <a href="%[2]s"> %[3]s</a>으로 저장소 이름을 바꾸었습니다.

File diff suppressed because it is too large Load diff

View file

@ -601,6 +601,7 @@ invalid_group_team_map_error = ` mapping is ongeldig: %s"
org_still_own_repo = Deze organisatie is eigenaar van één of meer repositories, verwijder of draag deze eerst over.
org_still_own_packages = Deze organisatie is eigenaar van één of meer pakketten, verwijder deze eerst.
[user]
change_avatar=Wijzig je profielfoto…
repositories=repositories
@ -1807,6 +1808,8 @@ activity.git_stats_and_deletions=en
activity.git_stats_deletion_1=%d verwijdering
activity.git_stats_deletion_n=%d verwijderingen
contributors.contribution_type.commits=Commits
search=Zoek
search.search_repo=Zoek repository
search.fuzzy=Vergelijkbaar
@ -2643,6 +2646,8 @@ settings.convert_notices_1 = Deze bewerking zet de mirror om in een reguliere re
[graphs]
[org]
org_name_holder=Organisatienaam
org_full_name_holder=Volledige naam organisatie
@ -3304,6 +3309,7 @@ config.mailer_enable_helo = HELO inschakelen
auths.oauth2_map_group_to_team_removal = Verwijder gebruikers uit gesynchroniseerde teams als de gebruiker niet tot de overeenkomstige groep behoort.
config.mailer_config = Mailer configuratie
[action]
create_repo=repository aangemaakt in <a href="%s">%s</a>
rename_repo=hernoemde repository van <code>%[1]s</code> naar <a href="%[2]s">%[3]s</a>

View file

@ -492,6 +492,7 @@ auth_failed=Uwierzytelnienie się nie powiodło: %v
target_branch_not_exist=Gałąź docelowa nie istnieje.
[user]
change_avatar=Zmień swój awatar…
repositories=Repozytoria
@ -1485,6 +1486,8 @@ activity.git_stats_and_deletions=i
activity.git_stats_deletion_1=%d usunięcie
activity.git_stats_deletion_n=%d usunięć
contributors.contribution_type.commits=Commity
search=Szukaj
search.search_repo=Przeszukaj repozytorium
search.fuzzy=Fuzzy
@ -1917,6 +1920,8 @@ error.csv.too_large=Nie można wyświetlić tego pliku, ponieważ jest on zbyt d
error.csv.unexpected=Nie można renderować tego pliku, ponieważ zawiera nieoczekiwany znak w wierszu %d i kolumnie %d.
error.csv.invalid_field_count=Nie można renderować tego pliku, ponieważ ma nieprawidłową liczbę pól w wierszu %d.
[graphs]
[org]
org_name_holder=Nazwa organizacji
org_full_name_holder=Pełna nazwa organizacji
@ -2443,6 +2448,7 @@ notices.desc=Opis
notices.op=Operacja
notices.delete_success=Powiadomienia systemu zostały usunięte.
[action]
create_repo=tworzy repozytorium <a href="%s">%s</a>
rename_repo=zmienia nazwę repozytorium <code>%[1]s</code> na <a href="%[2]s">%[3]s</a>

View file

@ -599,6 +599,7 @@ target_branch_not_exist=O branch de destino não existe.
username_error_no_dots = ` pode conter apenas caracteres alfanuméricos ("0-9, "a-z", "A-Z"), hífens ("-") e traços inferiores ("_"). Não é permitido conter caracteres não alfanuméricos no início ou fim e caracteres não alfanuméricos consecutivos.`
admin_cannot_delete_self = Você não pode excluir a si mesmo quando você é um administrador. Por favor, remova suas permissões de administrador primeiro.
[user]
change_avatar=Altere seu avatar...
joined_on=Inscreveu-se em %s
@ -1960,6 +1961,8 @@ activity.git_stats_and_deletions=e
activity.git_stats_deletion_1=%d exclusão
activity.git_stats_deletion_n=%d exclusões
contributors.contribution_type.commits=Commits
search=Pesquisar
search.search_repo=Pesquisar no repositório...
search.type.tooltip=Tipo de pesquisa
@ -2566,6 +2569,8 @@ editor.invalid_commit_mail = E-mail inválido para criar um commit.
issues.role.contributor_helper = Este usuário fez commits para o repositório anteriormente.
issues.choose.invalid_config = A configuração de issue contém erros:
[graphs]
[org]
org_name_holder=Nome da organização
org_full_name_holder=Nome completo da organização
@ -3202,6 +3207,7 @@ emails.change_email_text = Tem certeza de que deseja atualizar este endereço de
self_check = Autodiagnóstico
auths.tip.gitea = Registre um novo aplicativo OAuth2. A documentação pode ser encontrada em https://forgejo.org/docs/latest/user/oauth2-provider/
[action]
create_repo=criou o repositório <a href="%s">%s</a>
rename_repo=renomeou o repositório <code>%[1]s</code> para <a href="%[2]s">%[3]s</a>
@ -3385,6 +3391,8 @@ rpm.registry=Configure este registro pela linha de comando:
rpm.distros.redhat=em distribuições baseadas no RedHat
rpm.distros.suse=em distribuições baseadas no SUSE
rpm.install=Para instalar o pacote, execute o seguinte comando:
rpm.repository=Informações do repositório
rpm.repository.architectures=Arquiteturas
rubygems.install=Para instalar o pacote usando gem, execute o seguinte comando:
rubygems.install2=ou adicione-o ao Gemfile:
rubygems.dependencies.runtime=Dependências de Execução

View file

@ -124,6 +124,7 @@ pin=Fixar
unpin=Desafixar
artifacts=Artefactos
confirm_delete_artifact=Tem a certeza que quer eliminar este artefacto "%s"?
archived=Arquivado
@ -424,6 +425,7 @@ authorization_failed_desc=A autorização falhou porque encontrámos um pedido i
sspi_auth_failed=Falhou a autenticação SSPI
password_pwned=A senha utilizada está numa <a target="_blank" rel="noopener noreferrer" href="https://haveibeenpwned.com/Passwords">lista de senhas roubadas</a> anteriormente expostas em fugas de dados públicas. Tente novamente com uma senha diferente e considere também mudar esta senha nos outros sítios.
password_pwned_err=Não foi possível completar o pedido ao HaveIBeenPwned
last_admin=Não pode remover o último administrador. Tem que existir pelo menos um administrador.
[mail]
view_it_on=Ver em %s
@ -589,6 +591,8 @@ org_still_own_packages=Esta organização ainda possui um ou mais pacotes, elimi
target_branch_not_exist=O ramo de destino não existe.
admin_cannot_delete_self=Não se pode auto-remover quando tem privilégios de administração. Remova esses privilégios primeiro.
[user]
change_avatar=Mude o seu avatar…
joined_on=Inscreveu-se em %s
@ -968,6 +972,8 @@ issue_labels_helper=Escolha um conjunto de rótulos para as questões.
license=Licença
license_helper=Escolha um ficheiro de licença.
license_helper_desc=Uma licença rege o que os outros podem, ou não, fazer com o seu código fonte. Não tem a certeza sobre qual a mais indicada para o seu trabalho? Veja: <a target="_blank" rel="noopener noreferrer" href="%s">Escolher uma licença.</a>
object_format=Formato dos elementos
object_format_helper=Formato dos elementos do repositório. Não poderá ser alterado mais tarde. SHA1 é o mais compatível.
readme=README
readme_helper=Escolha um modelo de ficheiro README.
readme_helper_desc=Este é o sítio onde pode escrever uma descrição completa do seu trabalho.
@ -985,6 +991,7 @@ mirror_prune=Podar
mirror_prune_desc=Remover referências obsoletas de seguimento remoto
mirror_interval=Intervalo entre sincronizações (as unidades de tempo válidas são 'h', 'm' e 's'). O valor zero desabilita a sincronização periódica. (Intervalo mínimo: %s)
mirror_interval_invalid=O intervalo entre sincronizações não é válido.
mirror_sync=sincronizado
mirror_sync_on_commit=Sincronizar quando forem enviados cometimentos
mirror_address=Clonar a partir do URL
mirror_address_desc=Coloque, na secção de autorização, as credenciais que, eventualmente, sejam necessárias.
@ -1035,6 +1042,7 @@ desc.public=Público
desc.template=Modelo
desc.internal=Interno
desc.archived=Arquivado
desc.sha256=SHA256
template.items=Itens do modelo
template.git_content=Conteúdo Git (ramo principal)
@ -1185,6 +1193,8 @@ audio_not_supported_in_browser=O seu navegador não suporta a etiqueta 'audio' d
stored_lfs=Armazenado com Git LFS
symbolic_link=Ligação simbólica
executable_file=Ficheiro executável
vendored=Externo
generated=Gerado
commit_graph=Gráfico de cometimentos
commit_graph.select=Escolher ramos
commit_graph.hide_pr_refs=Ocultar pedidos de integração
@ -1708,6 +1718,7 @@ pulls.select_commit_hold_shift_for_range=Escolha o comentimento. Mantenha premid
pulls.review_only_possible_for_full_diff=A revisão só é possível ao visualizar o diff completo
pulls.filter_changes_by_commit=Filtrar por cometimento
pulls.nothing_to_compare=Estes ramos são iguais. Não há necessidade de criar um pedido de integração.
pulls.nothing_to_compare_have_tag=O ramo/etiqueta escolhidos são iguais.
pulls.nothing_to_compare_and_allow_empty_pr=Estes ramos são iguais. Este pedido de integração ficará vazio.
pulls.has_pull_request=`Já existe um pedido de integração entre estes ramos: <a href="%[1]s">%[2]s#%[3]d</a>`
pulls.create=Criar um pedido de integração
@ -1766,6 +1777,7 @@ pulls.merge_pull_request=Criar um cometimento de integração
pulls.rebase_merge_pull_request=Mudar a base e avançar rapidamente
pulls.rebase_merge_commit_pull_request=Mudar a base e criar um cometimento de integração
pulls.squash_merge_pull_request=Criar cometimento de compactação
pulls.fast_forward_only_merge_pull_request=Avançar rapidamente apenas
pulls.merge_manually=Integrado manualmente
pulls.merge_commit_id=O ID de cometimento da integração
pulls.require_signed_wont_sign=O ramo requer que os cometimentos sejam assinados mas esta integração não vai ser assinada
@ -1902,6 +1914,8 @@ wiki.page_name_desc=Insira um nome para esta página Wiki. Alguns dos nomes espe
wiki.original_git_entry_tooltip=Ver o ficheiro Git original, ao invés de usar uma ligação amigável.
activity=Trabalho
activity.navbar.pulse=Pulso
activity.navbar.contributors=Contribuidores
activity.period.filter_label=Período:
activity.period.daily=1 dia
activity.period.halfweekly=3 dias
@ -1967,6 +1981,11 @@ activity.git_stats_and_deletions=e
activity.git_stats_deletion_1=%d eliminação
activity.git_stats_deletion_n=%d eliminações
contributors.contribution_type.filter_label=Tipo de contribuição:
contributors.contribution_type.commits=Cometimentos
contributors.contribution_type.additions=Adições
contributors.contribution_type.deletions=Eliminações
search=Procurar
search.search_repo=Procurar repositório
search.type.tooltip=Tipo de pesquisa
@ -2004,6 +2023,7 @@ settings.mirror_settings.docs.doc_link_title=Como é que eu replico repositório
settings.mirror_settings.docs.doc_link_pull_section=a parte "Puxar de um repositório remoto" da documentação.
settings.mirror_settings.docs.pulling_remote_title=Puxando a partir de um repositório remoto
settings.mirror_settings.mirrored_repository=Repositório replicado
settings.mirror_settings.pushed_repository=Repositório enviado
settings.mirror_settings.direction=Sentido
settings.mirror_settings.direction.pull=Puxada
settings.mirror_settings.direction.push=Envio
@ -2314,6 +2334,8 @@ settings.protect_approvals_whitelist_users=Revisores com permissão:
settings.protect_approvals_whitelist_teams=Equipas com permissão para rever:
settings.dismiss_stale_approvals=Descartar aprovações obsoletas
settings.dismiss_stale_approvals_desc=Quando novos cometimentos que mudam o conteúdo do pedido de integração forem enviados para o ramo, as aprovações antigas serão descartadas.
settings.ignore_stale_approvals=Ignorar aprovações obsoletas
settings.ignore_stale_approvals_desc=Não contar as aprovações feitas em cometimentos mais antigos (revisões obsoletas) para o número de aprovações do pedido de integração. É irrelevante se as revisões obsoletas já forem descartadas.
settings.require_signed_commits=Exigir cometimentos assinados
settings.require_signed_commits_desc=Rejeitar envios para este ramo que não estejam assinados ou que não sejam validáveis.
settings.protect_branch_name_pattern=Padrão do nome do ramo protegido
@ -2369,6 +2391,7 @@ settings.archive.error=Ocorreu um erro enquanto decorria o processo de arquivo d
settings.archive.error_ismirror=Não pode arquivar um repositório que tenha sido replicado.
settings.archive.branchsettings_unavailable=As configurações dos ramos não estão disponíveis quando o repositório está arquivado.
settings.archive.tagsettings_unavailable=As configurações sobre etiquetas não estão disponíveis quando o repositório está arquivado.
settings.archive.mirrors_unavailable=As réplicas não estão disponíveis se o repositório estiver arquivado.
settings.unarchive.button=Desarquivar repositório
settings.unarchive.header=Desarquivar este repositório
settings.unarchive.text=Desarquivar o repositório irá restaurar a capacidade de receber cometimentos e envios, assim como novas questões e pedidos de integração.
@ -2567,6 +2590,13 @@ error.csv.too_large=Não é possível apresentar este ficheiro por ser demasiado
error.csv.unexpected=Não é possível apresentar este ficheiro porque contém um caractere inesperado na linha %d e coluna %d.
error.csv.invalid_field_count=Não é possível apresentar este ficheiro porque tem um número errado de campos na linha %d.
[graphs]
component_loading=A carregar %s...
component_loading_failed=Não foi possível carregar %s
component_loading_info=Isto pode demorar um pouco…
component_failed_to_load=Ocorreu um erro inesperado.
contributors.what=contribuições
[org]
org_name_holder=Nome da organização
org_full_name_holder=Nome completo da organização
@ -2693,6 +2723,7 @@ teams.invite.description=Clique no botão abaixo para se juntar à equipa.
[admin]
dashboard=Painel de controlo
self_check=Auto-verificação
identity_access=Identidade e acesso
users=Contas de utilizador
organizations=Organizações
@ -2738,6 +2769,7 @@ dashboard.delete_missing_repos=Eliminar todos os repositórios que não tenham o
dashboard.delete_missing_repos.started=Foi iniciada a tarefa de eliminação de todos os repositórios que não têm ficheiros git.
dashboard.delete_generated_repository_avatars=Eliminar avatares gerados do repositório
dashboard.sync_repo_branches=Sincronizar ramos perdidos de dados do git para bases de dados
dashboard.sync_repo_tags=Sincronizar etiquetas dos dados do git para a base de dados
dashboard.update_mirrors=Sincronizar réplicas
dashboard.repo_health_check=Verificar a saúde de todos os repositórios
dashboard.check_repo_stats=Verificar as estatísticas de todos os repositórios
@ -2792,6 +2824,7 @@ dashboard.stop_endless_tasks=Parar tarefas intermináveis
dashboard.cancel_abandoned_jobs=Cancelar trabalhos abandonados
dashboard.start_schedule_tasks=Iniciar tarefas de agendamento
dashboard.sync_branch.started=Sincronização de ramos iniciada
dashboard.sync_tag.started=Sincronização de etiquetas iniciada
dashboard.rebuild_issue_indexer=Reconstruir indexador de questões
users.user_manage_panel=Gestão das contas de utilizadores
@ -3218,6 +3251,13 @@ notices.desc=Descrição
notices.op=Op.
notices.delete_success=As notificações do sistema foram eliminadas.
self_check.no_problem_found=Nenhum problema encontrado até agora.
self_check.database_collation_mismatch=Supor que a base de dados usa a colação: %s
self_check.database_collation_case_insensitive=A base de dados está a usar a colação %s, que é insensível à diferença entre maiúsculas e minúsculas. Embora o Gitea possa trabalhar com ela, pode haver alguns casos raros que não funcionem como esperado.
self_check.database_inconsistent_collation_columns=A base de dados está a usar a colação %s, mas estas colunas estão a usar colações diferentes. Isso poderá causar alguns problemas inesperados.
self_check.database_fix_mysql=Para utilizadores do MySQL/MariaDB, pode usar o comando "gitea doctor convert" para resolver os problemas de colação. Também pode resolver o problema com comandos SQL "ALTER ... COLLATE ..." aplicados manualmente.
self_check.database_fix_mssql=Para utilizadores do MSSQL só pode resolver o problema aplicando comandos SQL "ALTER ... COLLATE ..." manualmente, por enquanto.
[action]
create_repo=criou o repositório <a href="%s">%s</a>
rename_repo=renomeou o repositório de <code>%[1]s</code> para <a href="%[2]s">%[3]s</a>
@ -3402,6 +3442,9 @@ rpm.registry=Configurar este registo usando a linha de comandos:
rpm.distros.redhat=em distribuições baseadas no RedHat
rpm.distros.suse=em distribuições baseadas no SUSE
rpm.install=Para instalar o pacote, execute o seguinte comando:
rpm.repository=Informação do repositório
rpm.repository.architectures=Arquitecturas
rpm.repository.multiple_groups=Este pacote está disponível em vários grupos.
rubygems.install=Para instalar o pacote usando o gem, execute o seguinte comando:
rubygems.install2=ou adicione-o ao ficheiro <code>Gemfile</code>:
rubygems.dependencies.runtime=Dependências do tempo de execução (runtime)
@ -3534,8 +3577,6 @@ runs.actors_no_select=Todos os intervenientes
runs.status_no_select=Todos os estados
runs.no_results=Nenhum resultado obtido.
runs.no_workflows=Ainda não há sequências de trabalho.
runs.no_workflows.quick_start=Não sabe como começar com o Forgejo Action? Veja o <a target="_blank" rel="noopener noreferrer" href="%s">guia de iniciação rápida</a>.
runs.no_workflows.documentation=Para mais informação sobre o Forgejo Action, veja <a target="_blank" rel="noopener noreferrer" href="%s">a documentação</a>.
runs.no_runs=A sequência de trabalho ainda não foi executada.
runs.empty_commit_message=(mensagem de cometimento vazia)
@ -3554,7 +3595,7 @@ variables.none=Ainda não há variáveis.
variables.deletion=Remover variável
variables.deletion.description=Remover uma variável é permanente e não pode ser revertido. Quer continuar?
variables.description=As variáveis serão transmitidas a certas operações e não poderão ser lidas de outra forma.
variables.id_not_exist=A variável com o id %d não existe.
variables.id_not_exist=A variável com o ID %d não existe.
variables.edit=Editar variável
variables.deletion.failed=Falha ao remover a variável.
variables.deletion.success=A variável foi removida.

View file

@ -601,6 +601,7 @@ target_branch_not_exist=Целевая ветка не существует.
admin_cannot_delete_self = Вы не можете удалить свою учётную запись, будучи администратором. Сперва снимите с себя роль администратора.
username_error_no_dots = ` может состоять только из латинских букв ('a-z','A-Z'), цифр ('0-9'), знаков минуса ('-') и нижнего подчёркивания ('_'). Знаки не могут стоять в начале или в конце, а также идти подряд.`
[user]
change_avatar=Изменить свой аватар…
joined_on=Зарегистрирован(а) с %s
@ -1961,6 +1962,8 @@ activity.git_stats_and_deletions=и
activity.git_stats_deletion_1=%d удаление
activity.git_stats_deletion_n=%d удалений
contributors.contribution_type.commits=коммитов
search=Поиск
search.search_repo=Поиск по репозиторию
search.type.tooltip=Тип поиска
@ -2632,6 +2635,8 @@ pulls.commit_ref_at = `сослался(ась) на этот запрос сл
settings.thread_id = ИД обсуждения
pulls.made_using_agit = AGit
[graphs]
[org]
org_name_holder=Название организации
org_full_name_holder=Полное название организации
@ -3287,6 +3292,7 @@ dashboard.sync_repo_tags = Синхронизировать теги из git в
self_check.database_collation_mismatch = Ожидается, что БД использует сопоставление: %s
self_check = Самопроверка
[action]
create_repo=создал(а) репозиторий <a href="%s"> %s</a>
rename_repo=переименовал(а) репозиторий из <code>%[1]s</code> на <a href="%[2]s">%[3]s</a>
@ -3471,6 +3477,8 @@ rpm.registry=Настроить реестр из командной строк
rpm.distros.redhat=на дистрибутивах семейства RedHat
rpm.distros.suse=на дистрибутивах семейства SUSE
rpm.install=Чтобы установить пакет, выполните следующую команду:
rpm.repository=О репозитории
rpm.repository.architectures=Архитектуры
rubygems.install=Чтобы установить пакет с помощью gem, выполните следующую команду:
rubygems.install2=или добавьте его в Gemfile:
rubygems.dependencies.runtime=Зависимости времени выполнения
@ -3603,8 +3611,6 @@ runs.status=Статус
runs.actors_no_select=Все акторы
runs.no_results=Ничего не найдено.
runs.no_workflows=Пока нет рабочих процессов.
runs.no_workflows.quick_start=Не знаете, как начать использовать Действия Forgejo? Читайте <a target="_blank" rel="noopener noreferrer" href="%s">руководство по быстрому старту</a>.
runs.no_workflows.documentation=Чтобы узнать больше о Действиях Forgejo, читайте <a target="_blank" rel="noopener noreferrer" href="%s">документацию</a>.
runs.no_runs=Рабочий поток ещё не запускался.
runs.empty_commit_message=(пустое сообщение коммита)
@ -3623,7 +3629,6 @@ variables.none=Переменных пока нет.
variables.deletion=Удалить переменную
variables.deletion.description=Удаление переменной необратимо, его нельзя отменить. Продолжить?
variables.description=Переменные будут передаваться определенным действиям и не могут быть прочитаны иначе.
variables.id_not_exist=Переменная с идентификатором %d не существует.
variables.edit=Изменить переменную
variables.deletion.failed=Не удалось удалить переменную.
variables.deletion.success=Переменная удалена.

View file

@ -451,6 +451,7 @@ auth_failed=සත්යාපන අසමත් විය: %v
target_branch_not_exist=ඉලක්කගත ශාඛාව නොපවතී.
[user]
change_avatar=ඔබගේ අවතාරය වෙනස් කරන්න…
repositories=කෝෂ්ඨ
@ -1460,6 +1461,8 @@ activity.git_stats_and_deletions=සහ
activity.git_stats_deletion_1=%d මකාදැමීම
activity.git_stats_deletion_n=%d මකාදැමීම්
contributors.contribution_type.commits=විවරයන්
search=සොයන්න
search.search_repo=කෝෂ්ඨය සොයන්න
search.fuzzy=සිනිඳු
@ -1911,6 +1914,8 @@ error.csv.too_large=එය ඉතා විශාල නිසා මෙම ග
error.csv.unexpected=%d පේළියේ සහ %dතීරුවේ අනපේක්ෂිත චරිතයක් අඩංගු බැවින් මෙම ගොනුව විදැහුම්කරණය කළ නොහැක.
error.csv.invalid_field_count=මෙම ගොනුව රේඛාවේ වැරදි ක්ෂේත්ර සංඛ්යාවක් ඇති බැවින් එය විදැහුම්කරණය කළ නොහැක %d.
[graphs]
[org]
org_name_holder=සංවිධානයේ නම
org_full_name_holder=සංවිධානයේ සම්පූර්ණ නම
@ -2457,6 +2462,7 @@ notices.desc=සවිස්තරය
notices.op=ඔප්.
notices.delete_success=පද්ධති දැන්වීම් මකා දමා ඇත.
[action]
create_repo=නිර්මිත ගබඩාව <a href="%s">%s</a>
rename_repo=<code>%[1]s</code> සිට <a href="%[2]s">%[3]s</a>දක්වා නම් කරන ලද ගබඩාව

View file

@ -564,6 +564,7 @@ auth_failed=Overenie zlyhalo: %v
target_branch_not_exist=Cieľová vetva neexistuje.
[user]
change_avatar=Zmeniť svoj avatar…
joined_on=Pripojil/a sa %s
@ -1145,6 +1146,8 @@ activity.unresolved_conv_label=Otvoriť
activity.git_stats_commit_1=%d commit
activity.git_stats_commit_n=%d commity
contributors.contribution_type.commits=Commitov
search=Hľadať
search.type.tooltip=Typ vyhľadávania
search.fuzzy=Fuzzy
@ -1248,6 +1251,8 @@ release.cancel=Zrušiť
[graphs]
[org]
code=Kód
lower_repositories=repozitáre
@ -1330,6 +1335,7 @@ monitor.process.cancel=Zrušiť proces
[action]
compare_commits=Porovnať %d commitov
compare_commits_general=Porovnať commity

View file

@ -391,6 +391,7 @@ auth_failed=Autentisering misslyckades: %v
target_branch_not_exist=Målgrenen finns inte.
[user]
change_avatar=Byt din avatar…
repositories=Utvecklingskataloger
@ -1228,6 +1229,8 @@ activity.git_stats_and_deletions=och
activity.git_stats_deletion_1=%d borttagen
activity.git_stats_deletion_n=%d borttagningar
contributors.contribution_type.commits=Incheckningar
search=Sök
search.search_repo=Sök utvecklingskatalog
search.results=Sökresultat för ”%s” i <a href="%s"> %s</a>
@ -1536,6 +1539,8 @@ topic.count_prompt=Du kan inte välja fler än 25 ämnen
[graphs]
[org]
org_name_holder=Organisationsnamn
org_full_name_holder=Organisationens Fullständiga Namn
@ -1972,6 +1977,7 @@ notices.desc=Beskrivning
notices.op=Op.
notices.delete_success=Systemnotifikationer har blivit raderade.
[action]
create_repo=skapade utvecklingskatalog <a href="%s"> %s</a>
rename_repo=döpte om utvecklingskalatogen från <code>%[1]s</code> till <a href="%[2]s">%[3]s</a>

View file

@ -589,6 +589,7 @@ org_still_own_packages=Bu organizasyon hala bir veya daha fazla pakete sahip, ö
target_branch_not_exist=Hedef dal mevcut değil.
[user]
change_avatar=Profil resmini değiştir…
joined_on=%s tarihinde katıldı
@ -1967,6 +1968,8 @@ activity.git_stats_and_deletions=ve
activity.git_stats_deletion_1=%d silme oldu
activity.git_stats_deletion_n=%d silme oldu
contributors.contribution_type.commits=İşleme
search=Ara
search.search_repo=Depo ara
search.type.tooltip=Arama türü
@ -2567,6 +2570,8 @@ error.csv.too_large=Bu dosya çok büyük olduğu için işlenemiyor.
error.csv.unexpected=%d satırı ve %d sütununda beklenmeyen bir karakter içerdiğinden bu dosya işlenemiyor.
error.csv.invalid_field_count=%d satırında yanlış sayıda alan olduğundan bu dosya işlenemiyor.
[graphs]
[org]
org_name_holder=Organizasyon Adı
org_full_name_holder=Organizasyon Tam Adı
@ -3218,6 +3223,7 @@ notices.desc=Açıklama
notices.op=İşlem
notices.delete_success=Sistem bildirimleri silindi.
[action]
create_repo=depo <a href="%s">%s</a> oluşturuldu
rename_repo=<code>%[1]s</code> olan depo adını <a href="%[2]s">%[3]s</a> buna çevirdi
@ -3402,6 +3408,8 @@ rpm.registry=Bu kütüğü komut satırını kullanarak kurun:
rpm.distros.redhat=RedHat tabanlı dağıtımlarda
rpm.distros.suse=SUSE tabanlı dağıtımlarda
rpm.install=Paketi kurmak için, aşağıdaki komutu çalıştırın:
rpm.repository=Depo Bilgisi
rpm.repository.architectures=Mimariler
rubygems.install=Paketi gem ile kurmak için, şu komutu çalıştırın:
rubygems.install2=veya paketi Gemfile dosyasına ekleyin:
rubygems.dependencies.runtime=Çalışma Zamanı Bağımlılıkları
@ -3534,8 +3542,6 @@ runs.actors_no_select=Tüm aktörler
runs.status_no_select=Tüm durumlar
runs.no_results=Eşleşen sonuç yok.
runs.no_workflows=Henüz hiç bir iş akışı yok.
runs.no_workflows.quick_start=Gitea İşlem'i nasıl başlatacağınızı bilmiyor musunuz? <a target="_blank" rel="noopener noreferrer" href="%s">Hızlı başlangıç rehberine</a> bakabilirsiniz.
runs.no_workflows.documentation=Gitea İşlem'i hakkında daha fazla bilgi için, <a target="_blank" rel="noopener noreferrer" href="%s">belgeye</a> bakabilirsiniz.
runs.no_runs=İş akışı henüz hiç çalıştırılmadı.
runs.empty_commit_message=(boş işleme iletisi)
@ -3554,7 +3560,6 @@ variables.none=Henüz hiçbir değişken yok.
variables.deletion=Değişkeni kaldır
variables.deletion.description=Bir değişkeni kaldırma kalıcıdır ve geri alınamaz. Devam edilsin mi?
variables.description=Değişkenler belirli işlemlere aktarılacaktır, bunun dışında okunamaz.
variables.id_not_exist=%d kimlikli değişken mevcut değil.
variables.edit=Değişkeni Düzenle
variables.deletion.failed=Değişken kaldırılamadı.
variables.deletion.success=Değişken kaldırıldı.

View file

@ -518,6 +518,7 @@ auth_failed=Помилка автентифікації: %v
target_branch_not_exist=Цільової гілки не існує.
[user]
change_avatar=Змінити свій аватар…
repositories=Репозиторії
@ -1577,6 +1578,8 @@ activity.git_stats_and_deletions=та
activity.git_stats_deletion_1=%d видалений
activity.git_stats_deletion_n=%d видалені
contributors.contribution_type.commits=Коміти
search=Пошук
search.search_repo=Пошук репозиторію
search.fuzzy=Неточний
@ -2068,6 +2071,8 @@ commit.cherry-pick-content = Оберіть гілку, на яку висмик
pulls.expand_files = Розгорнути всі файли
pulls.collapse_files = Згорнути всі файли
[graphs]
[org]
org_name_holder=Назва організації
org_full_name_holder=Повна назва організації
@ -2626,6 +2631,7 @@ packages.package_manage_panel = Менеджмент Пакунків
packages.published = Опубліковано
notices.operations = Дії
[action]
create_repo=створив(ла) репозиторій <a href="%s">%s</a>
rename_repo=репозиторій перейменовано з <code>%[1]s</code> на <a href="%[2]s">%[3]s</a>

View file

@ -124,6 +124,7 @@ pin=固定
unpin=取消置顶
artifacts=制品
confirm_delete_artifact=您确定要删除制品'%s'吗?
archived=已归档
@ -426,10 +427,7 @@ authorization_failed_desc=因为检测到无效请求,授权失败。请尝试
sspi_auth_failed=SSPI 认证失败
password_pwned=此密码出现在 <a target="_blank" rel="noopener noreferrer" href="https://haveibeenpwned.com/Passwords">被盗密码</a> 列表上并且曾经被公开。 请使用另一个密码再试一次。
password_pwned_err=无法完成对 HaveIBeenPwned 的请求
change_unconfirmed_email_summary = 修改用来接收激活邮件的邮箱地址。
change_unconfirmed_email_error = 无法修改邮箱地址: %v
change_unconfirmed_email = 如果您在注册时提供了错误的邮箱地址,您可以在下方修改,激活邮件会发送到修改后的邮箱地址。
last_admin = 您无法删除唯一的管理员。您至少需要有一个管理员。
last_admin=您不能删除最后一个管理员。必须至少保留一个管理员。
[mail]
view_it_on=在 %s 上查看
@ -600,6 +598,8 @@ target_branch_not_exist=目标分支不存在。
username_error_no_dots = ` 只能包含英文字母与数字 ('0-9','a-z','A-Z') 连字符 ('-') 与下划线 ('_')。 开头与结尾的字符只能使用英文字母或数字,且不能包含连续的非字母非数字字符。`
admin_cannot_delete_self = 您无法以管理员的身份删除自己。请先移除您的管理员权限。
admin_cannot_delete_self=当您是管理员时,您不能删除自己。请先移除您的管理员权限
[user]
change_avatar=修改头像
joined_on=加入于 %s
@ -992,6 +992,8 @@ issue_labels_helper=选择一个工单标签集
license=授权许可
license_helper=选择授权许可文件。
license_helper_desc=许可证说明了其他人可以和不可以用您的代码做什么。不确定哪一个适合你的项目?见 <a target="_blank" rel="noopener noreferrer" href="%s">选择一个许可证</a>
object_format=对象格式
object_format_helper=仓库的对象格式。之后无法更改。SHA1 是最兼容的。
readme=自述
readme_helper=选择自述文件模板。
readme_helper_desc=这是您可以为您的项目撰写完整描述的地方。
@ -1009,6 +1011,7 @@ mirror_prune=修剪
mirror_prune_desc=删除过时的远程跟踪引用
mirror_interval=镜像间隔 (有效的时间单位是 'h', 'm', 's')。0 禁用自动定期同步 (最短间隔: %s)
mirror_interval_invalid=镜像间隔无效。
mirror_sync=已同步
mirror_sync_on_commit=推送提交时同步
mirror_address=从 URL 克隆
mirror_address_desc=在授权框中输入必要的凭据。
@ -1059,6 +1062,7 @@ desc.public=公开
desc.template=模板
desc.internal=内部
desc.archived=已存档
desc.sha256=SHA256
template.items=模板选项
template.git_content=Git数据(默认分支)
@ -1209,6 +1213,8 @@ audio_not_supported_in_browser=您的浏览器不支持使用 HTML5 'video' 标
stored_lfs=存储到Git LFS
symbolic_link=符号链接
executable_file=可执行文件
vendored=被供应的
generated=已生成的
commit_graph=提交图
commit_graph.select=选择分支
commit_graph.hide_pr_refs=隐藏合并请求
@ -1732,6 +1738,7 @@ pulls.select_commit_hold_shift_for_range=选择提交。按住 Shift + 单击选
pulls.review_only_possible_for_full_diff=只有在查看全部差异时才能进行审核
pulls.filter_changes_by_commit=按提交筛选
pulls.nothing_to_compare=分支内容相同,无需创建合并请求。
pulls.nothing_to_compare_have_tag=所选分支/标签相同。
pulls.nothing_to_compare_and_allow_empty_pr=这些分支是相等的,此合并请求将为空。
pulls.has_pull_request=这些分支之间的合并请求已存在: <a href="%[1]s">%[2]s#%[3]d</a>
pulls.create=创建合并请求
@ -1926,6 +1933,7 @@ wiki.page_name_desc=输入此 Wiki 页面的名称。特殊名称有:'Home', '
wiki.original_git_entry_tooltip=查看原始的 Git 文件而不是使用友好链接。
activity=动态
activity.navbar.contributors=贡献者
activity.period.filter_label=周期:
activity.period.daily=1 天
activity.period.halfweekly=3 天
@ -1991,6 +1999,11 @@ activity.git_stats_and_deletions=和
activity.git_stats_deletion_1=删除 %d 行
activity.git_stats_deletion_n=删除 %d 行
contributors.contribution_type.filter_label=贡献类型:
contributors.contribution_type.commits=提交
contributors.contribution_type.additions=更多
contributors.contribution_type.deletions=删除
search=搜索
search.search_repo=搜索仓库...
search.type.tooltip=搜索类型
@ -2028,6 +2041,7 @@ settings.mirror_settings.docs.doc_link_title=如何镜像仓库?
settings.mirror_settings.docs.doc_link_pull_section=文档中的 “从远程仓库拉取” 部分。
settings.mirror_settings.docs.pulling_remote_title=从远程仓库拉取代码
settings.mirror_settings.mirrored_repository=镜像库
settings.mirror_settings.pushed_repository=推送仓库
settings.mirror_settings.direction=方向
settings.mirror_settings.direction.pull=拉取
settings.mirror_settings.direction.push=推送
@ -2338,6 +2352,8 @@ settings.protect_approvals_whitelist_users=审查者白名单:
settings.protect_approvals_whitelist_teams=审查团队白名单:
settings.dismiss_stale_approvals=取消过时的批准
settings.dismiss_stale_approvals_desc=当新的提交更改合并请求内容被推送到分支时,旧的批准将被撤销。
settings.ignore_stale_approvals=忽略过期批准
settings.ignore_stale_approvals_desc=对旧提交(过期审核)的批准将不计入 PR 的批准数。如果过期审查已被驳回,则与此无关。
settings.require_signed_commits=需要签名提交
settings.require_signed_commits_desc=拒绝推送未签名或无法验证的提交到分支
settings.protect_branch_name_pattern=受保护的分支名称模式
@ -2393,6 +2409,7 @@ settings.archive.error=仓库在归档时出现异常。请通过日志获取详
settings.archive.error_ismirror=请不要对镜像仓库归档,谢谢!
settings.archive.branchsettings_unavailable=已归档仓库无法进行分支设置。
settings.archive.tagsettings_unavailable=已归档仓库的Git标签设置不可用。
settings.archive.mirrors_unavailable=如果仓库已被归档,镜像将不可用。
settings.unarchive.button=撤销仓库归档
settings.unarchive.header=撤销此仓库归档
settings.unarchive.text=撤销归档将恢复仓库接收提交、推送,以及新工单和合并请求的能力。
@ -2634,6 +2651,13 @@ pulls.fast_forward_only_merge_pull_request = 仅快速向前
settings.units.overview = 概览
settings.units.add_more = 添加更多
[graphs]
component_loading=正在加载 %s...
component_loading_failed=无法加载 %s
component_loading_info=这可能需要一点…
component_failed_to_load=意外的错误发生了。
contributors.what=贡献
[org]
org_name_holder=组织名称
org_full_name_holder=组织全名
@ -2761,6 +2785,7 @@ follow_blocked_user = 你无法关注此组织,因为此组织已屏蔽你。
[admin]
dashboard=管理面板
self_check=自我检查
identity_access=身份及认证
users=帐户管理
organizations=组织管理
@ -2806,6 +2831,7 @@ dashboard.delete_missing_repos=删除所有丢失 Git 文件的仓库
dashboard.delete_missing_repos.started=删除所有丢失 Git 文件的仓库任务已启动。
dashboard.delete_generated_repository_avatars=删除生成的仓库头像
dashboard.sync_repo_branches=将缺少的分支从 git 数据同步到数据库
dashboard.sync_repo_tags=从 git 数据同步标签到数据库
dashboard.update_mirrors=更新镜像仓库
dashboard.repo_health_check=健康检查所有仓库
dashboard.check_repo_stats=检查所有仓库统计
@ -2860,6 +2886,7 @@ dashboard.stop_endless_tasks=停止永不停止的任务
dashboard.cancel_abandoned_jobs=取消丢弃的任务
dashboard.start_schedule_tasks=开始调度任务
dashboard.sync_branch.started=分支同步已开始
dashboard.sync_tag.started=标签同步已开始
dashboard.rebuild_issue_indexer=重建工单索引
users.user_manage_panel=用户帐户管理
@ -3295,6 +3322,11 @@ self_check.database_inconsistent_collation_columns = 数据库正在使用 %s
self_check.database_fix_mysql = 对于 MySQL/MariaDB 用户,您可以使用 "gitea doctor convert" 命令来修复排序规则问题也可以通过SQL命令 "ALTER ... COLLATE ..." 来手动修复问题。
self_check.database_fix_mssql = 对于 MSSQL 用户目前您只能通过SQL命令 "ALTER ... COLLATE ..." 来手动修复问题。
self_check.no_problem_found=尚未发现问题。
self_check.database_collation_mismatch=期望数据库使用的校验方式:%s
self_check.database_collation_case_insensitive=数据库正在使用一个校验 %s, 这是一个不敏感的校验. 虽然Gitea可以与它合作但可能有一些罕见的情况不如预期的那样起作用。
self_check.database_fix_mysql=对于MySQL/MariaDB用户您可以使用“gitea doctor convert”命令来解决校验问题。 或者您也可以通过 "ALTER ... COLLATE ..." 这样的SQL 来手动解决这个问题。
[action]
create_repo=创建了仓库 <a href="%s">%s</a>
rename_repo=重命名仓库 <code>%[1]s</code> 为 <a href="%[2]s">%[3]s</a>
@ -3479,6 +3511,9 @@ rpm.registry=从命令行设置此注册中心:
rpm.distros.redhat=在基于 RedHat 的发行版
rpm.distros.suse=在基于 SUSE 的发行版
rpm.install=要安装包,请运行以下命令:
rpm.repository=仓库信息
rpm.repository.architectures=架构
rpm.repository.multiple_groups=此软件包可在多个组中使用。
rubygems.install=要使用 gem 安装软件包,请运行以下命令:
rubygems.install2=或将它添加到 Gemfile
rubygems.dependencies.runtime=运行时依赖
@ -3614,8 +3649,8 @@ runs.actors_no_select=所有操作者
runs.status_no_select=所有状态
runs.no_results=没有匹配的结果。
runs.no_workflows=目前还没有工作流。
runs.no_workflows.quick_start=不知道如何启动Gitea Action请参阅 <a target="_blank" rel="noopener noreferrer" href="%s">快速启动指南</a>
runs.no_workflows.documentation=更多有关 Gitea Action 的信息,请访问 <a target="_blank" rel="noopener noreferrer" href="%s">文档</a>。
runs.no_workflows.quick_start=不知道如何使用 Gitea Actions吗请查看 <a target="_blank" rel="noopener noreferrer" href="%s">快速启动指南</a>
runs.no_workflows.documentation=关于Gitea Actions的更多信息请参阅 <a target="_blank" rel="noopener noreferrer" href="%s">文档</a>。
runs.no_runs=工作流尚未运行过。
runs.empty_commit_message=(空白的提交消息)
@ -3634,7 +3669,7 @@ variables.none=目前还没有变量。
variables.deletion=删除变量
variables.deletion.description=删除变量是永久性的,无法撤消。继续吗?
variables.description=变量将被传给特定的 Actions其它情况将不能读取
variables.id_not_exist=ID %d 变量不存在。
variables.id_not_exist=ID %d 变量不存在。
variables.edit=编辑变量
variables.deletion.failed=删除变量失败。
variables.deletion.success=变量已被删除。

View file

@ -196,6 +196,7 @@ auth_failed=授權驗證失敗:%v
target_branch_not_exist=目標分支不存在
[user]
repositories=儲存庫列表
activity=公開活動
@ -538,6 +539,8 @@ activity.merged_prs_label=已合併
activity.closed_issue_label=已關閉
activity.new_issues_count_1=建立問題
contributors.contribution_type.commits=提交歷史
search=搜尋
settings=儲存庫設定
@ -640,6 +643,8 @@ release.downloads=下載附件
[graphs]
[org]
org_name_holder=組織名稱
org_full_name_holder=組織全名
@ -916,6 +921,7 @@ notices.desc=描述
notices.op=操作
notices.delete_success=已刪除系統提示。
[action]
create_repo=建立了儲存庫 <a href="%s">%s</a>
rename_repo=重新命名儲存庫 <code>%[1]s</code> 為 <a href="%[2]s">%[3]s</a>

View file

@ -556,6 +556,7 @@ org_still_own_packages=此組織仍然擁有一個以上的套件,請先刪除
target_branch_not_exist=目標分支不存在
[user]
change_avatar=更改大頭貼...
repositories=儲存庫
@ -1777,6 +1778,8 @@ activity.git_stats_and_deletions=和
activity.git_stats_deletion_1=刪除 %d 行
activity.git_stats_deletion_n=刪除 %d 行
contributors.contribution_type.commits=提交歷史
search=搜尋
search.search_repo=搜尋儲存庫
search.type.tooltip=搜尋類型
@ -2323,6 +2326,8 @@ error.csv.too_large=無法渲染此檔案,因為它太大了。
error.csv.unexpected=無法渲染此檔案,因為它包含了未預期的字元,於第 %d 行第 %d 列。
error.csv.invalid_field_count=無法渲染此檔案,因為它第 %d 行的欄位數量有誤。
[graphs]
[org]
org_name_holder=組織名稱
org_full_name_holder=組織全名
@ -2935,6 +2940,7 @@ notices.desc=描述
notices.op=操作
notices.delete_success=已刪除系統提示。
[action]
create_repo=建立了儲存庫 <a href="%s">%s</a>
rename_repo=重新命名儲存庫 <code>%[1]s</code> 為 <a href="%[2]s">%[3]s</a>
@ -3111,6 +3117,8 @@ pypi.requires=需要 Python
pypi.install=執行下列命令以使用 pip 安裝此套件:
rpm.registry=透過下列命令設定此註冊中心:
rpm.install=執行下列命令安裝此套件:
rpm.repository=儲存庫資訊
rpm.repository.architectures=架構
rubygems.install=執行下列命令以使用 gem 安裝此套件:
rubygems.install2=或將它加到 Gemfile:
rubygems.dependencies.runtime=執行階段相依性

514
package-lock.json generated
View file

@ -24,6 +24,7 @@
"chartjs-plugin-zoom": "2.0.1",
"clippie": "4.0.6",
"css-loader": "6.10.0",
"css-variables-parser": "1.0.1",
"dayjs": "1.11.10",
"dropzone": "6.0.0-beta.2",
"easymde": "2.18.0",
@ -41,9 +42,12 @@
"monaco-editor": "0.46.0",
"monaco-editor-webpack-plugin": "7.1.0",
"pdfobject": "2.3.0",
"postcss": "8.4.35",
"postcss-loader": "8.1.0",
"pretty-ms": "9.0.0",
"sortablejs": "1.15.2",
"swagger-ui-dist": "5.11.6",
"tailwindcss": "3.4.1",
"throttle-debounce": "5.0.0",
"tinycolor2": "1.6.0",
"tippy.js": "6.3.7",
@ -105,6 +109,17 @@
"node": ">=0.10.0"
}
},
"node_modules/@alloc/quick-lru": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
"integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@asyncapi/specs": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/@asyncapi/specs/-/specs-4.3.1.tgz",
@ -118,7 +133,6 @@
"version": "7.23.5",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz",
"integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==",
"dev": true,
"dependencies": {
"@babel/highlight": "^7.23.4",
"chalk": "^2.4.2"
@ -131,7 +145,6 @@
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"dependencies": {
"color-convert": "^1.9.0"
},
@ -143,7 +156,6 @@
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"dev": true,
"dependencies": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
@ -157,7 +169,6 @@
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true,
"dependencies": {
"color-name": "1.1.3"
}
@ -165,14 +176,12 @@
"node_modules/@babel/code-frame/node_modules/color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
"dev": true
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
},
"node_modules/@babel/code-frame/node_modules/escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
"dev": true,
"engines": {
"node": ">=0.8.0"
}
@ -181,7 +190,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
"dev": true,
"engines": {
"node": ">=4"
}
@ -190,7 +198,6 @@
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"dependencies": {
"has-flag": "^3.0.0"
},
@ -202,7 +209,6 @@
"version": "7.22.20",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
"integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
"dev": true,
"engines": {
"node": ">=6.9.0"
}
@ -211,7 +217,6 @@
"version": "7.23.4",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz",
"integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==",
"dev": true,
"dependencies": {
"@babel/helper-validator-identifier": "^7.22.20",
"chalk": "^2.4.2",
@ -225,7 +230,6 @@
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"dependencies": {
"color-convert": "^1.9.0"
},
@ -237,7 +241,6 @@
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"dev": true,
"dependencies": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
@ -251,7 +254,6 @@
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true,
"dependencies": {
"color-name": "1.1.3"
}
@ -259,14 +261,12 @@
"node_modules/@babel/highlight/node_modules/color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
"dev": true
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
},
"node_modules/@babel/highlight/node_modules/escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
"dev": true,
"engines": {
"node": ">=0.8.0"
}
@ -275,7 +275,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
"dev": true,
"engines": {
"node": ">=4"
}
@ -283,14 +282,12 @@
"node_modules/@babel/highlight/node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"dev": true
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
},
"node_modules/@babel/highlight/node_modules/supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"dependencies": {
"has-flag": "^3.0.0"
},
@ -1111,7 +1108,6 @@
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
"integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
"dev": true,
"dependencies": {
"string-width": "^5.1.2",
"string-width-cjs": "npm:string-width@^4.2.0",
@ -1128,7 +1124,6 @@
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
"integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
"dev": true,
"engines": {
"node": ">=12"
},
@ -1140,7 +1135,6 @@
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
"integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
"dev": true,
"engines": {
"node": ">=12"
},
@ -1151,14 +1145,12 @@
"node_modules/@isaacs/cliui/node_modules/emoji-regex": {
"version": "9.2.2",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
"dev": true
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="
},
"node_modules/@isaacs/cliui/node_modules/string-width": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
"integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
"dev": true,
"dependencies": {
"eastasianwidth": "^0.2.0",
"emoji-regex": "^9.2.2",
@ -1175,7 +1167,6 @@
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
"integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
"dev": true,
"dependencies": {
"ansi-regex": "^6.0.1"
},
@ -1190,7 +1181,6 @@
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
"integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
"dev": true,
"dependencies": {
"ansi-styles": "^6.1.0",
"string-width": "^5.0.1",
@ -1381,7 +1371,6 @@
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
"integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
"dev": true,
"optional": true,
"engines": {
"node": ">=14"
@ -3086,6 +3075,28 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/any-promise": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
"integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="
},
"node_modules/anymatch": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
"dependencies": {
"normalize-path": "^3.0.0",
"picomatch": "^2.0.4"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/arg": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
"integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="
},
"node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
@ -3400,6 +3411,14 @@
"node": "*"
}
},
"node_modules/binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
"engines": {
"node": ">=8"
}
},
"node_modules/boolbase": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
@ -3534,11 +3553,18 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
"dev": true,
"engines": {
"node": ">=6"
}
},
"node_modules/camelcase-css": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
"integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
"engines": {
"node": ">= 6"
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001587",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001587.tgz",
@ -3646,6 +3672,40 @@
"node": "*"
}
},
"node_modules/chokidar": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
"integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
"dependencies": {
"anymatch": "~3.1.2",
"braces": "~3.0.2",
"glob-parent": "~5.1.2",
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
"normalize-path": "~3.0.0",
"readdirp": "~3.6.0"
},
"engines": {
"node": ">= 8.10.0"
},
"funding": {
"url": "https://paulmillr.com/funding/"
},
"optionalDependencies": {
"fsevents": "~2.3.2"
}
},
"node_modules/chokidar/node_modules/glob-parent": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dependencies": {
"is-glob": "^4.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/chrome-trace-event": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz",
@ -3857,7 +3917,6 @@
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz",
"integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==",
"dev": true,
"dependencies": {
"env-paths": "^2.2.1",
"import-fresh": "^3.3.0",
@ -3975,6 +4034,35 @@
"node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
}
},
"node_modules/css-variables-parser": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/css-variables-parser/-/css-variables-parser-1.0.1.tgz",
"integrity": "sha512-GWaqrwGtAWVr/yjjE17iyvbcy+W3voe0vko1/xLCwFeYd3kTLstzUdVH+g5TTXejrtlsb1FS4L9rP6PmeTa8wQ==",
"dependencies": {
"postcss": "^7.0.36"
}
},
"node_modules/css-variables-parser/node_modules/picocolors": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
"integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA=="
},
"node_modules/css-variables-parser/node_modules/postcss": {
"version": "7.0.39",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
"integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
"dependencies": {
"picocolors": "^0.2.1",
"source-map": "^0.6.1"
},
"engines": {
"node": ">=6.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
}
},
"node_modules/css-what": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
@ -4661,6 +4749,11 @@
"node": ">=6"
}
},
"node_modules/didyoumean": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
"integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw=="
},
"node_modules/diff": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz",
@ -4690,6 +4783,11 @@
"node": ">=8"
}
},
"node_modules/dlv": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
"integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="
},
"node_modules/doctrine": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
@ -4774,8 +4872,7 @@
"node_modules/eastasianwidth": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
"dev": true
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="
},
"node_modules/easymde": {
"version": "2.18.0",
@ -4839,7 +4936,6 @@
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
"integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
"dev": true,
"engines": {
"node": ">=6"
}
@ -4859,7 +4955,6 @@
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
"integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
"dev": true,
"dependencies": {
"is-arrayish": "^0.2.1"
}
@ -6154,7 +6249,6 @@
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz",
"integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==",
"dev": true,
"dependencies": {
"cross-spawn": "^7.0.0",
"signal-exit": "^4.0.1"
@ -6203,7 +6297,6 @@
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
"dev": true,
"hasInstallScript": true,
"optional": true,
"os": [
@ -6390,7 +6483,6 @@
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
"dev": true,
"dependencies": {
"is-glob": "^4.0.3"
},
@ -6815,7 +6907,6 @@
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
"integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
"dev": true,
"dependencies": {
"parent-module": "^1.0.0",
"resolve-from": "^4.0.0"
@ -6935,8 +7026,7 @@
"node_modules/is-arrayish": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
"integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
"dev": true
"integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="
},
"node_modules/is-async-function": {
"version": "2.0.0",
@ -6965,6 +7055,17 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-binary-path": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
"dependencies": {
"binary-extensions": "^2.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/is-boolean-object": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
@ -7377,7 +7478,6 @@
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz",
"integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==",
"dev": true,
"dependencies": {
"@isaacs/cliui": "^8.0.2"
},
@ -7418,6 +7518,14 @@
"url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
"node_modules/jiti": {
"version": "1.21.0",
"resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz",
"integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==",
"bin": {
"jiti": "bin/jiti.js"
}
},
"node_modules/jquery": {
"version": "3.7.1",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz",
@ -7779,11 +7887,18 @@
"node": ">=8"
}
},
"node_modules/lilconfig": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
"integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==",
"engines": {
"node": ">=10"
}
},
"node_modules/lines-and-columns": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
"dev": true
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
},
"node_modules/linkify-it": {
"version": "5.0.0",
@ -8707,7 +8822,6 @@
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz",
"integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==",
"dev": true,
"engines": {
"node": ">=16 || 14 >=14.17"
}
@ -8759,6 +8873,16 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node_modules/mz": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
"integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
"dependencies": {
"any-promise": "^1.0.0",
"object-assign": "^4.0.1",
"thenify-all": "^1.0.0"
}
},
"node_modules/nanoid": {
"version": "3.3.7",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
@ -8902,7 +9026,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
@ -8969,6 +9092,14 @@
"node": ">=0.10.0"
}
},
"node_modules/object-hash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
"integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
"engines": {
"node": ">= 6"
}
},
"node_modules/object-inspect": {
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz",
@ -9148,7 +9279,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
"integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
"dev": true,
"dependencies": {
"callsites": "^3.0.0"
},
@ -9160,7 +9290,6 @@
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
"integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
"dev": true,
"dependencies": {
"@babel/code-frame": "^7.0.0",
"error-ex": "^1.3.1",
@ -9230,7 +9359,6 @@
"version": "1.10.1",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz",
"integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==",
"dev": true,
"dependencies": {
"lru-cache": "^9.1.1 || ^10.0.0",
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
@ -9246,7 +9374,6 @@
"version": "10.2.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz",
"integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==",
"dev": true,
"engines": {
"node": "14 || >=16.14"
}
@ -9296,6 +9423,22 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/pify": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/pirates": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz",
"integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==",
"engines": {
"node": ">= 6"
}
},
"node_modules/pkg-dir": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
@ -9462,6 +9605,70 @@
"node": "^12 || >=14"
}
},
"node_modules/postcss-import": {
"version": "15.1.0",
"resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz",
"integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
"dependencies": {
"postcss-value-parser": "^4.0.0",
"read-cache": "^1.0.0",
"resolve": "^1.1.7"
},
"engines": {
"node": ">=14.0.0"
},
"peerDependencies": {
"postcss": "^8.0.0"
}
},
"node_modules/postcss-js": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz",
"integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==",
"dependencies": {
"camelcase-css": "^2.0.1"
},
"engines": {
"node": "^12 || ^14 || >= 16"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
"peerDependencies": {
"postcss": "^8.4.21"
}
},
"node_modules/postcss-loader": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-8.1.0.tgz",
"integrity": "sha512-AbperNcX3rlob7Ay7A/HQcrofug1caABBkopoFeOQMspZBqcqj6giYn1Bwey/0uiOPAcR+NQD0I2HC7rXzk91w==",
"dependencies": {
"cosmiconfig": "^9.0.0",
"jiti": "^1.20.0",
"semver": "^7.5.4"
},
"engines": {
"node": ">= 18.12.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"peerDependencies": {
"@rspack/core": "0.x || 1.x",
"postcss": "^7.0.0 || ^8.0.1",
"webpack": "^5.0.0"
},
"peerDependenciesMeta": {
"@rspack/core": {
"optional": true
},
"webpack": {
"optional": true
}
}
},
"node_modules/postcss-modules-extract-imports": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz",
@ -9517,6 +9724,24 @@
"postcss": "^8.1.0"
}
},
"node_modules/postcss-nested": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz",
"integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==",
"dependencies": {
"postcss-selector-parser": "^6.0.11"
},
"engines": {
"node": ">=12.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
"peerDependencies": {
"postcss": "^8.2.14"
}
},
"node_modules/postcss-resolve-nested-selector": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz",
@ -9754,6 +9979,14 @@
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
"dev": true
},
"node_modules/read-cache": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
"integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
"dependencies": {
"pify": "^2.3.0"
}
},
"node_modules/read-pkg": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
@ -9856,6 +10089,17 @@
"node": ">=8"
}
},
"node_modules/readdirp": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
"dependencies": {
"picomatch": "^2.2.1"
},
"engines": {
"node": ">=8.10.0"
}
},
"node_modules/rechoir": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz",
@ -10037,7 +10281,6 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
"dev": true,
"engines": {
"node": ">=4"
}
@ -10398,7 +10641,6 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
"dev": true,
"engines": {
"node": ">=14"
},
@ -10609,7 +10851,6 @@
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dev": true,
"dependencies": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
@ -10680,7 +10921,6 @@
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dev": true,
"dependencies": {
"ansi-regex": "^5.0.1"
},
@ -10999,6 +11239,56 @@
"node": ">= 8"
}
},
"node_modules/sucrase": {
"version": "3.35.0",
"resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
"integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==",
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.2",
"commander": "^4.0.0",
"glob": "^10.3.10",
"lines-and-columns": "^1.1.6",
"mz": "^2.7.0",
"pirates": "^4.0.1",
"ts-interface-checker": "^0.1.9"
},
"bin": {
"sucrase": "bin/sucrase",
"sucrase-node": "bin/sucrase-node"
},
"engines": {
"node": ">=16 || 14 >=14.17"
}
},
"node_modules/sucrase/node_modules/commander": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
"integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
"engines": {
"node": ">= 6"
}
},
"node_modules/sucrase/node_modules/glob": {
"version": "10.3.10",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz",
"integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==",
"dependencies": {
"foreground-child": "^3.1.0",
"jackspeak": "^2.3.5",
"minimatch": "^9.0.1",
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0",
"path-scurry": "^1.10.1"
},
"bin": {
"glob": "dist/esm/bin.mjs"
},
"engines": {
"node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/superstruct": {
"version": "0.10.13",
"resolved": "https://registry.npmjs.org/superstruct/-/superstruct-0.10.13.tgz",
@ -11144,6 +11434,87 @@
"node": ">=10.0.0"
}
},
"node_modules/tailwindcss": {
"version": "3.4.1",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.1.tgz",
"integrity": "sha512-qAYmXRfk3ENzuPBakNK0SRrUDipP8NQnEY6772uDhflcQz5EhRdD7JNZxyrFHVQNCwULPBn6FNPp9brpO7ctcA==",
"dependencies": {
"@alloc/quick-lru": "^5.2.0",
"arg": "^5.0.2",
"chokidar": "^3.5.3",
"didyoumean": "^1.2.2",
"dlv": "^1.1.3",
"fast-glob": "^3.3.0",
"glob-parent": "^6.0.2",
"is-glob": "^4.0.3",
"jiti": "^1.19.1",
"lilconfig": "^2.1.0",
"micromatch": "^4.0.5",
"normalize-path": "^3.0.0",
"object-hash": "^3.0.0",
"picocolors": "^1.0.0",
"postcss": "^8.4.23",
"postcss-import": "^15.1.0",
"postcss-js": "^4.0.1",
"postcss-load-config": "^4.0.1",
"postcss-nested": "^6.0.1",
"postcss-selector-parser": "^6.0.11",
"resolve": "^1.22.2",
"sucrase": "^3.32.0"
},
"bin": {
"tailwind": "lib/cli.js",
"tailwindcss": "lib/cli.js"
},
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/tailwindcss/node_modules/postcss-load-config": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz",
"integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==",
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"dependencies": {
"lilconfig": "^3.0.0",
"yaml": "^2.3.4"
},
"engines": {
"node": ">= 14"
},
"peerDependencies": {
"postcss": ">=8.0.9",
"ts-node": ">=9.0.0"
},
"peerDependenciesMeta": {
"postcss": {
"optional": true
},
"ts-node": {
"optional": true
}
}
},
"node_modules/tailwindcss/node_modules/postcss-load-config/node_modules/lilconfig": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz",
"integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==",
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/sponsors/antonk52"
}
},
"node_modules/tapable": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
@ -11258,6 +11629,25 @@
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
"dev": true
},
"node_modules/thenify": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
"integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
"dependencies": {
"any-promise": "^1.0.0"
}
},
"node_modules/thenify-all": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
"integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
"dependencies": {
"thenify": ">= 3.1.0 < 4"
},
"engines": {
"node": ">=0.8"
}
},
"node_modules/throttle-debounce": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-5.0.0.tgz",
@ -11380,6 +11770,11 @@
"node": ">=6.10"
}
},
"node_modules/ts-interface-checker": {
"version": "0.1.13",
"resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
"integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="
},
"node_modules/tsconfig-paths": {
"version": "3.15.0",
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz",
@ -12431,7 +12826,6 @@
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"dev": true,
"dependencies": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
@ -12569,6 +12963,14 @@
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
"node_modules/yaml": {
"version": "2.3.4",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz",
"integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==",
"engines": {
"node": ">= 14"
}
},
"node_modules/yargs": {
"version": "17.3.1",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.3.1.tgz",

View file

@ -23,6 +23,7 @@
"chartjs-plugin-zoom": "2.0.1",
"clippie": "4.0.6",
"css-loader": "6.10.0",
"css-variables-parser": "1.0.1",
"dayjs": "1.11.10",
"dropzone": "6.0.0-beta.2",
"easymde": "2.18.0",
@ -40,9 +41,12 @@
"monaco-editor": "0.46.0",
"monaco-editor-webpack-plugin": "7.1.0",
"pdfobject": "2.3.0",
"postcss": "8.4.35",
"postcss-loader": "8.1.0",
"pretty-ms": "9.0.0",
"sortablejs": "1.15.2",
"swagger-ui-dist": "5.11.6",
"tailwindcss": "3.4.1",
"throttle-debounce": "5.0.0",
"tinycolor2": "1.6.0",
"tippy.js": "6.3.7",

View file

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" class="gitea-discord__svg gitea-discord__gitea-discord svg gitea-discord" preserveAspectRatio="xMidYMid" viewBox="0 0 256 293" width="16" height="16"><path fill="#7289DA" d="M226.011 0H29.99C13.459 0 0 13.458 0 30.135v197.778c0 16.677 13.458 30.135 29.989 30.135h165.888l-7.754-27.063 18.725 17.408 17.7 16.384L256 292.571V30.135C256 13.458 242.542 0 226.011 0m-56.466 191.05s-5.266-6.291-9.655-11.85c19.164-5.413 26.478-17.408 26.478-17.408-5.998 3.95-11.703 6.73-16.823 8.63-7.314 3.073-14.336 5.12-21.211 6.291-14.044 2.633-26.917 1.902-37.888-.146-8.339-1.61-15.507-3.95-21.504-6.29-3.365-1.317-7.022-2.926-10.68-4.974-.438-.293-.877-.439-1.316-.732a2 2 0 0 1-.585-.438c-2.633-1.463-4.096-2.487-4.096-2.487s7.022 11.703 25.6 17.261c-4.388 5.56-9.801 12.142-9.801 12.142-32.33-1.024-44.617-22.235-44.617-22.235 0-47.104 21.065-85.285 21.065-85.285 21.065-15.799 41.106-15.36 41.106-15.36l1.463 1.756C80.75 77.53 68.608 89.088 68.608 89.088s3.218-1.755 8.63-4.242c15.653-6.876 28.088-8.777 33.208-9.216.877-.147 1.609-.293 2.487-.293a123.8 123.8 0 0 1 29.55-.292c13.896 1.609 28.818 5.705 44.031 14.043 0 0-11.556-10.971-36.425-18.578l2.048-2.34s20.041-.44 41.106 15.36c0 0 21.066 38.18 21.066 85.284 0 0-12.435 21.211-44.764 22.235zm-68.023-68.316c-8.338 0-14.92 7.314-14.92 16.237 0 8.924 6.728 16.238 14.92 16.238 8.339 0 14.921-7.314 14.921-16.238.147-8.923-6.582-16.237-14.92-16.237m53.394 0c-8.339 0-14.922 7.314-14.922 16.237 0 8.924 6.73 16.238 14.922 16.238 8.338 0 14.92-7.314 14.92-16.238s-6.582-16.237-14.92-16.237"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 127.14 96.36" class="svg gitea-discord" width="16" height="16" aria-hidden="true"><path fill="#5865f2" d="M107.7 8.07A105.2 105.2 0 0 0 81.47 0a72 72 0 0 0-3.36 6.83 97.7 97.7 0 0 0-29.11 0A72 72 0 0 0 45.64 0a106 106 0 0 0-26.25 8.09C2.79 32.65-1.71 56.6.54 80.21a105.7 105.7 0 0 0 32.17 16.15 77.7 77.7 0 0 0 6.89-11.11 68.4 68.4 0 0 1-10.85-5.18c.91-.66 1.8-1.34 2.66-2a75.57 75.57 0 0 0 64.32 0c.87.71 1.76 1.39 2.66 2a68.7 68.7 0 0 1-10.87 5.19 77 77 0 0 0 6.89 11.1 105.3 105.3 0 0 0 32.19-16.14c2.64-27.38-4.51-51.11-18.9-72.15M42.45 65.69C36.18 65.69 31 60 31 53s5-12.74 11.43-12.74S54 46 53.89 53s-5.05 12.69-11.44 12.69m42.24 0C78.41 65.69 73.25 60 73.25 53s5-12.74 11.44-12.74S96.23 46 96.12 53s-5.04 12.69-11.43 12.69"/></svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 791 B

Some files were not shown because too many files have changed in this diff Show more