aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore12
-rw-r--r--CHANGELOG.md423
-rw-r--r--Makefile17
-rw-r--r--build.go11
-rw-r--r--build/generate-bindata.go83
-rw-r--r--cmd/embedded.go8
-rw-r--r--cmd/serv.go2
-rw-r--r--custom/conf/app.example.ini20
-rw-r--r--go.mod45
-rw-r--r--go.sum75
-rw-r--r--modules/assetfs/embed.go375
-rw-r--r--modules/assetfs/embed_test.go98
-rw-r--r--modules/assetfs/layered.go4
-rw-r--r--modules/git/command.go13
-rw-r--r--modules/git/key.go15
-rw-r--r--modules/git/repo.go1
-rw-r--r--modules/git/repo_gpg.go12
-rw-r--r--modules/git/repo_tree.go11
-rw-r--r--modules/migration/schemas_bindata.go24
-rw-r--r--modules/migration/schemas_static.go15
-rw-r--r--modules/options/options_bindata.go17
-rw-r--r--modules/options/options_dynamic.go (renamed from modules/options/dynamic.go)0
-rw-r--r--modules/options/static.go14
-rw-r--r--modules/public/public.go13
-rw-r--r--modules/public/public_bindata.go17
-rw-r--r--modules/public/public_dynamic.go (renamed from modules/public/serve_dynamic.go)0
-rw-r--r--modules/public/serve_static.go24
-rw-r--r--modules/setting/repository.go6
-rw-r--r--modules/templates/static.go22
-rw-r--r--modules/templates/templates_bindata.go17
-rw-r--r--modules/templates/templates_dynamic.go (renamed from modules/templates/dynamic.go)0
-rw-r--r--modules/timeutil/executable.go50
-rw-r--r--modules/zstd/zstd_test.go8
-rw-r--r--options/locale/locale_ga-IE.ini1
-rw-r--r--options/locale/locale_uk-UA.ini459
-rw-r--r--options/locale/locale_zh-CN.ini372
-rw-r--r--package-lock.json1003
-rw-r--r--package.json24
-rw-r--r--routers/api/v1/api.go6
-rw-r--r--routers/api/v1/misc/signing.go78
-rw-r--r--routers/web/misc/misc.go2
-rw-r--r--routers/web/repo/setting/setting.go4
-rw-r--r--routers/web/repo/view_file.go74
-rw-r--r--services/asymkey/commit.go67
-rw-r--r--services/asymkey/commit_test.go54
-rw-r--r--services/asymkey/sign.go167
-rw-r--r--services/context/repo.go7
-rw-r--r--services/pull/merge.go7
-rw-r--r--services/pull/merge_prepare.go6
-rw-r--r--services/pull/merge_squash.go7
-rw-r--r--services/repository/files/temp_repo.go11
-rw-r--r--services/repository/init.go7
-rw-r--r--services/wiki/wiki.go4
-rw-r--r--templates/swagger/v1_json.tmpl56
-rw-r--r--tests/integration/gpg_ssh_git_test.go (renamed from tests/integration/gpg_git_test.go)35
-rw-r--r--web_src/css/markup/content.css2
-rw-r--r--web_src/css/repo/home.css1
-rw-r--r--web_src/fomantic/build/components/dropdown.js1
-rw-r--r--web_src/js/features/common-fetch-action.ts13
-rw-r--r--web_src/js/features/comp/LabelEdit.ts3
60 files changed, 2552 insertions, 1371 deletions
diff --git a/.gitignore b/.gitignore
index 272ea2b5ed..0791a17c71 100644
--- a/.gitignore
+++ b/.gitignore
@@ -42,14 +42,10 @@ _testmain.go
coverage.all
cpu.out
-/modules/migration/bindata.go
-/modules/migration/bindata.go.hash
-/modules/options/bindata.go
-/modules/options/bindata.go.hash
-/modules/public/bindata.go
-/modules/public/bindata.go.hash
-/modules/templates/bindata.go
-/modules/templates/bindata.go.hash
+/modules/migration/bindata.*
+/modules/options/bindata.*
+/modules/public/bindata.*
+/modules/templates/bindata.*
*.db
*.log
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ca2e67929c..b72ac4849a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,429 @@ This changelog goes through the changes that have been made in each release
without substantial changes to our git log; to see the highlights of what has
been added to each release, please refer to the [blog](https://blog.gitea.com).
+## [1.24.0](https://github.com/go-gitea/gitea/releases/tag/1.24.0) - 2025-05-26
+
+* BREAKING
+ * Make Gitea always use its internal config, ignore `/etc/gitconfig` (#33076)
+ * Improve log format (#33814)
+ * Fix markdown render behaviors (#34122)
+ * Add package version api endpoints (#34173)
+
+* FEATURES
+ * Enforce two-factor auth (2FA: TOTP or WebAuthn) (#34187)
+ * Add fullscreen mode as a more efficient operation way to view projects (#34081)
+ * Add anonymous access support for private/unlisted repositories (#34051)
+ * Support public code/issue access for private repositories (#33127)
+ * Add middleware for request prioritization (#33951)
+ * Add cli flags LDAP group configuration (#33933)
+ * Add file tree to file view page (#32721)
+ * Add material icons for file list (#33837)
+ * Artifacts download api for artifact actions v4 (#33510)
+ * Support choose email when creating a commit via web UI (#33432)
+ * Add basic auth support to rss/atom feeds (#33371)
+ * Add sorting by exclusive labels (issue priority) (#33206)
+ * Add sub issue list support (#32940)
+ * Private README.md for organization (#32872)
+ * Email option to embed images as base64 instead of link (#32061)
+ * Option to delay conflict checking of old pull requests until page view (#27779)
+ * Worktime tracking for the organization level (#19808)
+
+* PERFORMANCE
+ * Add cache for common package queries (#22491)
+ * Move issue pin to an standalone table for querying performance (#33452)
+ * Improve commits list performance to reduce unnecessary database queries (#33528)
+ * Optimize total count of feed when loading activities in user dashboard. (#33841)
+ * Optimize heatmap query (#33853)
+ * Only use prev and next buttons for pagination on user dashboard (#33981)
+ * Improve pull request list API performance (#34052)
+ * Cache GPG keys, emails and users when list commits (#34086)
+ * Refactor Git Attribute & performance optimization (#34154)
+ * Performance optimization for tags synchronization (#34355) #34522
+
+* ENHANCEMENTS
+ * Code
+ * Display when a release attachment was uploaded (#34261)
+ * Support creating relative link to raw path in markdown (#34105)
+ * Improve code block readability and isolate copy button (#34009)
+ * Improve repository commit view (#33877)
+ * Full-file syntax highlighting for diff pages (#33766)
+ * Clone repository with Tea CLI (#33725)
+ * Improve sync fork behavior (#33319)
+ * Make git clone URL could use current signed-in user (#33091)
+ * Add submodule diff links (#33097)
+ * Link to tree views of submodules if possible (#33424)
+ * Only keep popular licenses (#33832)
+ * De-emphasize signed commits (#31160)
+
+ * Actions
+ * Add flat-square action badge style (#34062)
+ * Update action status badge layout (#34018)
+ * Download actions job logs from API (#33858)
+ * Always show the "rerun" button for action jobs (#33692)
+ * Add auto-expanding running actions step (#30058)
+ * Update status check for all supported on.pull_request.types in Gitea (#33117)
+ * Workflow_dispatch use workflow from trigger branch (#33098)
+ * Add action auto-scroll (#30057)
+ * Add workflow_job webhook (#33694)
+ * Add a button editing action secret (#34462)
+
+ * Pull Request
+ * Auto expand "New PR" form (#33971)
+ * Mark parent directory as viewed when all files are viewed (#33958)
+ * Show info about maintainers are allowed to edit a PR (#33738)
+ * Automerge supports deleting branch automatically after merging (#32343)
+ * Add additional command hints for PowerShell & CMD (#33548)
+
+ * Issues
+ * Allow filtering issues by any assignee (#33343)
+ * Show warning on navigation if currently editing comment or title (#32920)
+ * Make tracked time representation display as hours (#33315)
+ * Add No Results Prompt Message on Issue List Page (#33699)
+ * Add sort option recentclose for issues and pulls (#34525) #34539
+
+ * Packages
+ * Link to nuget dependencies (#26554)
+ * Add composor source field (#33502)
+
+ * Administration
+ * Improve navbar: add "admin" tip, add "active" style (#32927)
+ * Add a option "--user-type bot" to admin user create, improve role display (#27885)
+ * Improve admin user view page (#33735)
+ * Support performance trace (#32973)
+ * Change pprof labels to be prometheus compatible (#32865)
+ * Allow admins and org owners to change org member public status (#28294)
+ * Optimize the installation page (#32994)
+ * Make public URL generation configurable (#34250)
+ * Add a --fullname arg to gitea admin user create. (#34241)
+
+ * Others
+ * Improve oauth2 error handling (#33969)
+ * Fail mirroring more gracefully (#34002)
+ * Align User Details Page Header Layout with Design Specifications (#34192)
+ * Webhook add X-Gitea-Hook-Installation-Target-Type Header (#33752)
+ * Optimize the dashboard (#32990)
+ * Improve button layout on small screens (#33633)
+ * Add cropping support when modifying the user/org/repo avatar (#33498)
+ * Make ROOT_URL support using request Host header (#32564)
+ * Add `show more` organizations icon in user's profile (#32986)
+ * Introduce `--page-space-bottom` at 64px (#30692)
+ * Improve theme display (#30671)
+ * Add alphabetical project sorting (#33504)
+ * Add global lock for migrations to make upgrade more safe with multiple replications (#33706)
+ * Add descriptions for private repo public access settings and improve the UI (#34057)
+
+* API
+ * Actions Runner rest api (#33873)
+ * Inclusion of rename organization api (#33303)
+ * Add API to support link package to repository and unlink it (#33481)
+ * Add API endpoint to request contents of multiple files simultaniously (#34139)
+ * Actions artifacts API list/download check status upload confirmed (#34273)
+ * Add API routes to lock and unlock issues (#34165)
+ * Fix some user name usages (#33689)
+ * Allow filtering /repos/{owner}/{repo}/pulls by target base branch queryparam (#33684)
+ * Improve swagger generation (#33664)
+ * Support Ephemeral action runners (#33570)
+ * Support workflow event dispatch via API (#33545)
+ * Support workflow event dispatch via API (#32059)
+ * Added Description Field for Secrets and Variables (#33526)
+ * Reject star-related requests if stars are disabled (#33208)
+ * Let API create and edit system webhooks, attempt 2 (#33180)
+ * Use `Project-URL` metadata field to get a PyPI package's homepage URL (#33089)
+ * Add `last_committer_date` and `last_author_date` for file contents API (#32921)
+
+* REFACTORS
+ * Remove context from git struct (#33793)
+ * Refactor admin/common.ts (#33788)
+ * Refactor repo-settings.ts (#33785)
+ * Refactor repo-issue.ts (#33784)
+ * Small refactor to reduce unnecessary database queries and remove duplicated functions (#33779)
+ * Refactor initRepoBranchTagSelector to use new init framework (#33776)
+ * Refactor buttons to use new init framework (#33774)
+ * Refactor markup and pdf-viewer to use new init framework (#33772)
+ * Refactor error system (#33771)
+ * Refactor mail code (#33768)
+ * Update TypeScript types (#33799)
+ * Refactor older tests to use testify (#33140)
+ * Move notifywatch to service layer (#33825)
+ * Decouple context from repository related structs (#33823)
+ * Remove context from mail struct (#33811)
+ * Refactor dropdown ellipsis (#34123)
+ * Refactor functions to reduce repopath expose (#33892)
+ * Refactor repo-diff.ts (#33746)
+ * Refactor web route handler (#33488)
+ * Refactor user & avatar (#33433)
+ * Refactor user package (#33423)
+ * Refactor decouple context from migration structs (#33399)
+ * Refactor context flash msg and global variables (#33375)
+ * Refactor response writer & access logger (#33323)
+ * Refactor ref type (#33242)
+ * Refactor context repository (#33202)
+ * Refactor legacy JS (#33115)
+ * Refactor legacy line-number and scroll code (#33094)
+ * Refactor env var related code (#33075)
+ * Move SetMerged to service layer (#33045)
+ * Merge updatecommentattachment functions (#33044)
+ * Refactor pull-request compare&create page (#33071)
+ * Refactor repo-new.ts (#33070)
+ * Refactor pagination (#33037)
+ * Refactor tests (#33021)
+ * Refactor markup render to fix various path problems (#34114)
+ * Refactor Branch struct in package modules/git (#33980)
+ * Don't create duplicated functions for code repositories and wiki repositories (#33924)
+ * Move git references checking to gitrepo packages to reduce expose of repository path (#33891)
+ * Refactor cache-control (#33861)
+ * Decouple diff stats query from actual diffing (#33810)
+ * Move part of updating protected branch logic to service layer (#33742)
+ * Decouple Batch from git.Repository to simplify usage without requiring the creation of a Repository struct. (#34001)
+ * Refactor tmpl and blob_excerpt (#32967)
+ * Refactor template & test related code (#32938)
+ * Refactor db package and remove unnecessary `DumpTables` (#32930)
+ * Refactor pprof labels and process desc (#32909)
+ * Refactor repo-projects.ts (#32892)
+ * Refactor getpatch/getdiff functions and remove unnecessary fallback (#32817)
+ * Uniform all temporary directories and allow customizing temp path (#32352)
+ * Remove context from retry downloader (#33871)
+ * Refactor global init code and add more comments (#33755)
+ * Remove some unnecessary template helpers (#33069)
+ * Move and rename UpdateRepository (#34136)
+ * Move hooks function to gitrepo and reduce expose repopath (#33890)
+ * Add abstraction layer to delete repository from disk (#33879)
+ * Add abstraction layer to check if the repository exists on disk (#33874)
+ * Move ParseCommitWithSSHSignature to service layer (#34087)
+ * Move duplicated functions (#33977)
+ * Extract code to their own functions for push update (#33944)
+ * Move gitgraph from modules to services layer (#33527)
+ * Move commits signature and verify functions to service layers (#33605)
+ * Use `CloseIssue` and `ReopenIssue` instead of `ChangeStatus` (#32467)
+ * Refactor arch route handlers (#32993)
+ * Refactor "string truncate" (#32984)
+ * Refactor arch route handlers (#32972)
+ * Clarify path param naming (#32969)
+ * Refactor request context (#32956)
+ * Move some errors to their own sub packages (#32880)
+ * Move RepoTransfer from models to models/repo sub package (#32506)
+ * Move delete deploy keys into service layer (#32201)
+ * Refactor webhook events (#33337)
+ * Move some Actions related functions from `routers` to `services` (#33280)
+ * Refactor RefName (#33234)
+ * Refactor context RefName and RepoAssignment (#33226)
+ * Refactor repository transfer (#33211)
+ * Refactor error system (#33626)
+ * Refactor error system (#33610)
+ * Refactor package (routes and error handling, npm peer dependency) (#33111)
+ * Use test context in tests and new loop system in benchmarks (#33648)
+ * Some small refactors (#33144)
+ * Simplify context ref name (#33267)
+
+* BUGFIXES
+ * Fix some dropdown problems on the issue sidebar (#34308) #34327
+ * Do not return archive download URLs in API if downloads are disabled (#34324) #34338
+ * Fix LFS files being editable in web UI (#34356) #34362
+ * Fix only text/* being viewable in web UI (#34374) #34378
+ * Fix LFS file not stored in LFS when uploaded/edited via API or web UI (#34367)
+ * Grey out expired artifact on Artifacts list (#34314) #34404
+ * Fix incorrect divergence cache after switching default branch (#34370) #34406
+ * Refactor commit message rendering and fix bugs (#34412) #34414
+ * Merge and tweak markup editor expander CSS (#34409) #34415
+ * Fix GetUsersByEmails (#34423) #34425
+ * Only git operations should update last changed of a repository (#34388) #34427
+ * Fix comment textarea scroll issue in Firefox (#34438) #34446
+ * Fix repo broken check (#34444) #34452
+ * Fix remove org user failure on mssql (#34449) #34453
+ * Fix Workflow run Not Found page (#34459) #34466
+ * When updating comment, if the content is the same, just return and not update the database (#34422) #34464
+ * Fix project board view (#34470) #34475
+ * Fix get / delete runner to use consistent http 404 and 500 status (#34480) #34488
+ * Fix url validation in webhook add/edit API (#34492) #34496
+ * Fix edithook api can not update package, status and workflow_job events (#34495) #34499
+ * Fix ephemeral runner deletion (#34447) #34513
+ * Don't display error log when .git-blame-ignore-revs doesn't exist (#34457)
+ * Only allow admins to rename default/protected branches (#33276)
+ * Improve "lock conversation" UI (#34207)
+ * Fix incorrect file links (#34189)
+ * Optimize Overflow Menu (#34183)
+ * Check user/org repo limit instead of doer (#34147)
+ * Make markdown render match GitHub's behavior (#34129)
+ * Fix team permission (#34128)
+ * Correctly handle submodule view and avoid throwing 500 error (#34121)
+ * Fix users being able bypass limits with repo transfers (#34031)
+ * Avoid creating unnecessary temporary cat file sub process (#33942)
+ * Refactor organization menu (#33928)
+ * Fix various Fomantic UI and htmx problems (#33851)
+ * Fix 500 error when error occurred in migration page (#33256)
+ * Validate that the tag doesn't exist when creating a tag via the web (#33241)
+ * Add missed transaction on setmerged (#33079)
+ * Rework create/fork/adopt/generate repository to make sure resources will be cleanup once failed (#31035)
+ * Valid email address should only start with alphanumeric (#28174)
+ * Fix webhook url (#34186)
+ * Fix "toAbsoluteLocaleDate" test when system locale is not en-US (#33939)
+ * Fix file name could not be searched if the file was not a text file when using the Bleve indexer (#33959)
+ * Fix cannot delete runners via the modal dialog (#33895)
+ * Fix unpin hint on the pinned pull requests (#33207)
+ * Fix parentCommit invalid memory address or nil pointer dereference. (#33204)
+ * Fix comment header padding (#33377)
+ * Fix some migration and repo name problems (#33986)
+ * Fix various trivial frontend problems (#34263)
+ * Fix Set Email Preference dropdown and button placement (#34255)
+ * Fix quoted replies incorrectly render user input as part of the quote (#34216)
+ * Fix button alignments and remove unnecessary styles (#34206)
+ * Restore form inputs on organization create error (#34201)
+ * Try to fix ACME (3rd) (#33807)
+ * Fix incorrect ref "blob" (#33240)
+ * Fix dynamic content loading init problem (#33748)
+ * Fix git empty check and HEAD request (#33690)
+ * Fix Untranslated Text on Actions Page (#33635)
+ * Fix issue label delete incorrect labels webhook payload (#34575)
+ * Fix incorrect page navigation with up and down arrow on last item of dashboard repos (#34570)
+ * Fix/improve avatar sync from LDAP (#34573)
+ * Fix some trivial problems (#34579)
+ * Retain issue sort type when a keyword search is introduced (#34559)
+ * Always use an empty line to separate the commit message and trailer (#34512)
+ * Fix line-button issue after file selection in file tree (#34574)
+ * Fix doctor deleting orphaned issues attachments (#34142)
+ * Add webhook assigning test and fix possible bug (#34420)
+ * Fix possible nil description of pull request when migrating from CodeCommit (#34541)
+ * Refactor commit reader (#34542)
+ * Fix possible pull request broken when leave the page immediately after clicking the update button #34509
+ * Ignore "Close" error when uploading container blob (#34620)
+ * Fix missed merge commit sha and time when migrating from codecommit (#34645)
+ * Fix GetUsersByEmails (#34643)
+ * Misc CSS fixes (#34638)
+ * Add codecommit to supported services in api docs (#34626)
+ * Validate hex colors when creating/editing labels (#34623)
+ * Fix possible pull request broken when leave the page immediately after clicking the update button (#34509)
+ * Fix margin issue in markup paragraph rendering (#34599)
+ * Fix migration pull request title too long (#34577)
+ * Fix footnote jump behavior on the issue page. (#34621)
+ * Fix "oras" OCI client compatibility (#34666)
+ * Fix last admin check when syncing users (#34649)
+ * Fix skip paths check on tag push events in workflows (#34602) #34670
+
+* MISC
+
+ * Bump to alpine 3.22 (#34613)
+ * Make pull request and issue history more compact (#34588)
+ * Run integration tests against postgres 14 (#34514) #34536
+ * Enable addtional linters (#34085)
+ * Enable testifylint rules (#34075)
+ * Enable staticcheck QFxxxx rules (#34064)
+ * Improve Actions test (#32883)
+ * Drop fomantic build (#33845)
+ * Go1.24 (#33562)
+ * Run yamllint with strict mode, fix issue (#33551)
+ * Disable cron task to update license (#33486)
+ * Optimize makefile help information generation (#33390)
+ * Convert github.com/xanzy/go-gitlab into gitlab.com/gitlab-org/api/client-go (#33126)
+ * Add missed changelogs (#33649)
+ * Update .changelog file to add performance label group (#33472)
+ * Add missing POPULATE_SQUASH_COMMENT_WITH_COMMIT_MESSAGES in app.example.ini (#33363)
+ * Update README screenshots (#33347)
+ * Update unrs-resolver (#34279)
+ * Update go&js dependencies (#34262)
+ * Optimize the calling code of queryElems (#34235)
+ * Update protected_branch.tmpl (#34193)
+ * Feat/optimize span svg layout (#34185)
+ * Set MERMAID_MAX_SOURCE_CHARACTERS to 50000 (#34152)
+ * Update JS and PY deps (#34143)
+ * Add Chinese translations for README files (#34132)
+ * Use `overflow-wrap: anywhere` to replace `word-break: break-all` (#34126)
+ * Clarify ownership in password change error messages (#34092)
+ * Add toggleClass function in dom.ts (#34063)
+ * Update to golangci-lint v2 (#34054)
+ * Update Makefile test comments (#34013)
+ * Update go mod dependencies (#33988)
+ * Use filepath.Join instead of path.Join for file system file operations (#33978)
+ * Prepare common tmpl functions in a middleware (#33957)
+ * Remove unused or abused styles (#33918)
+ * Update JS and PY deps, misc tweaks (#33903)
+ * Try to figure out attribute checker problem (#33901)
+ * Add lock for a repository pull mirror (#33876)
+ * Fine tune push mirror UI (#33866)
+ * Improve issue & code search (#33860)
+ * Use pullrequestlist instead of []*pullrequest (#33765)
+ * Upgrade act to 0.261.4 and actions-proto-go to v0.4.1 (#33760)
+ * Align sidebar gears to the right (#33721)
+ * Update Go dependencies (skip blevesearch, meilisearch) (#33655)
+ * Add migrations and doctor fixes (#33556)
+ * Remove "class-name" from svg icon (#33540)
+ * Update MAINTAINERS (#33529)
+ * Add "No data available" display when list is empty (#33517)
+ * Use `git diff-tree` for `DiffFileTree` on diff pages (#33514)
+ * Give organisation members access to organisation feeds (#33508)
+ * Update feishu icon (#33470)
+ * Hide/disable unusable UI elements when a repository is archived (#33459)
+ * Update `@github/text-expander-element` to 2.9.0 (#33435)
+ * Do not access GitRepo when a repo is being created (#33380)
+ * Fix incorrect ref usages (#33301)
+ * Prepare for support performance trace (#33286)
+ * Enable Typescript `noImplicitThis` (#33250)
+ * Remove unused CSS styles and move some styles to proper files (#33217)
+ * Add .run to gitignore (#33175)
+ * Fix typo in gitea downloader test and add missing codebase in `ToGitServiceType` (#33146)
+ * Remove extended glob pattern from branch protection UI (#33125)
+ * Clean up legacy form CSS styles (#33081)
+ * Unset XDG_HOME_CONFIG as gitea manages configuration locations (#33067)
+ * Add IntelliJ Gateway's .uuid to gitignore (#33052)
+ * User facing messages for AGit errors (#33012)
+ * Always show assignees on right (#33006)
+ * Fix eslint (#33002)
+ * Update JS dependencies (#32914)
+ * Bump x/net (#32896) (#32900)
+ * Only activity tab needs heatmap data loading (#34652)
+
+## [1.23.8](https://github.com/go-gitea/gitea/releases/tag/1.23.8) - 2025-05-11
+
+* SECURITY
+ * Fix a bug when uploading file via lfs ssh command (#34408) (#34411)
+ * Update net package (#34228) (#34232)
+* BUGFIXES
+ * Fix releases sidebar navigation link (#34436) #34439
+ * Fix bug webhook milestone is not right. (#34419) #34429
+ * Fix two missed null value checks on the wiki page. (#34205) (#34215)
+ * Swift files can be passed either as file or as form value (#34068) (#34236)
+ * Fix bug when API get pull changed files for deleted head repository (#34333) (#34368)
+ * Upgrade github v61 -> v71 to fix migrating bug (#34389)
+ * Fix bug when visiting comparation page (#34334) (#34364)
+ * Fix wrong review requests when updating the pull request (#34286) (#34304)
+ * Fix github migration error when using multiple tokens (#34144) (#34302)
+ * Explicitly not update indexes when sync database schemas (#34281) (#34295)
+ * Fix panic when comment is nil (#34257) (#34277)
+ * Fix project board links to related Pull Requests (#34213) (#34222)
+ * Don't assume the default wiki branch is master in the wiki API (#34244) (#34245)
+* DOCUMENTATION
+ * Update token creation API swagger documentation (#34288) (#34296)
+* MISC
+ * Fix CI Build (#34315)
+ * Add riscv64 support (#34199) (#34204)
+ * Bump go version in go.mod (#34160)
+ * remove hardcoded 'code' string in clone_panel.tmpl (#34153) (#34158)
+
+## [1.23.7](https://github.com/go-gitea/gitea/releases/tag/1.23.7) - 2025-04-07
+
+* Enhancements
+ * Add a config option to block "expensive" pages for anonymous users (#34024) (#34071)
+ * Also check default ssh-cert location for host (#34099) (#34100) (#34116)
+* BUGFIXES
+ * Fix discord webhook 400 status code when description limit is exceeded (#34084) (#34124)
+ * Get changed files based on merge base when checking `pull_request` actions trigger (#34106) (#34120)
+ * Fix invalid version in RPM package path (#34112) (#34115)
+ * Return default avatar url when user id is zero rather than updating database (#34094) (#34095)
+ * Add additional ReplaceAll in pathsep to cater for different pathsep (#34061) (#34070)
+ * Try to fix check-attr bug (#34029) (#34033)
+ * Git client will follow 301 but 307 (#34005) (#34010)
+ * Fix block expensive for 1.23 (#34127)
+ * Fix markdown frontmatter rendering (#34102) (#34107)
+ * Add new CLI flags to set name and scopes when creating a user with access token (#34080) (#34103)
+ * Do not show 500 error when default branch doesn't exist (#34096) (#34097)
+ * Hide activity contributors, recent commits and code frequrency left tabs if there is no code permission (#34053) (#34065)
+ * Simplify emoji rendering (#34048) (#34049)
+ * Adjust the layout of the toolbar on the Issues/Projects page (#33667) (#34047)
+ * Pull request updates will also trigger code owners review requests (#33744) (#34045)
+ * Fix org repo creation being limited by user limits (#34030) (#34044)
+ * Fix git client accessing renamed repo (#34034) (#34043)
+ * Fix the issue with error message logging for the `check-attr` command on Windows OS. (#34035) (#34036)
+ * Polyfill WeakRef (#34025) (#34028)
+
## [1.23.6](https://github.com/go-gitea/gitea/releases/tag/v1.23.6) - 2025-03-24
* SECURITY
diff --git a/Makefile b/Makefile
index d10250bbc7..f67762f8c1 100644
--- a/Makefile
+++ b/Makefile
@@ -120,8 +120,7 @@ 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
-BINDATA_DEST := modules/public/bindata.go modules/options/bindata.go modules/templates/bindata.go
-BINDATA_HASH := $(addsuffix .hash,$(BINDATA_DEST))
+BINDATA_DEST := modules/public/bindata.dat modules/options/bindata.dat modules/templates/bindata.dat
GENERATED_GO_DEST := modules/charset/invisible_gen.go modules/charset/ambiguous_gen.go
@@ -149,14 +148,8 @@ SPELLCHECK_FILES := $(GO_DIRS) $(WEB_DIRS) templates options/locale/locale_en-US
EDITORCONFIG_FILES := templates .github/workflows options/locale/locale_en-US.ini
GO_SOURCES := $(wildcard *.go)
-GO_SOURCES += $(shell find $(GO_DIRS) -type f -name "*.go" ! -path modules/options/bindata.go ! -path modules/public/bindata.go ! -path modules/templates/bindata.go)
+GO_SOURCES += $(shell find $(GO_DIRS) -type f -name "*.go")
GO_SOURCES += $(GENERATED_GO_DEST)
-GO_SOURCES_NO_BINDATA := $(GO_SOURCES)
-
-ifeq ($(filter $(TAGS_SPLIT),bindata),bindata)
- GO_SOURCES += $(BINDATA_DEST)
- GENERATED_GO_DEST += $(BINDATA_DEST)
-endif
# Force installation of playwright dependencies by setting this flag
ifdef DEPS_PLAYWRIGHT
@@ -226,7 +219,7 @@ clean-all: clean ## delete backend, frontend and integration files
.PHONY: clean
clean: ## delete backend and integration files
- rm -rf $(EXECUTABLE) $(DIST) $(BINDATA_DEST) $(BINDATA_HASH) \
+ rm -rf $(EXECUTABLE) $(DIST) $(BINDATA_DEST) \
integrations*.test \
e2e*.test \
tests/integration/gitea-integration-* \
@@ -268,7 +261,7 @@ endif
.PHONY: generate-swagger
generate-swagger: $(SWAGGER_SPEC) ## generate the swagger spec from code comments
-$(SWAGGER_SPEC): $(GO_SOURCES_NO_BINDATA) $(SWAGGER_SPEC_INPUT)
+$(SWAGGER_SPEC): $(GO_SOURCES) $(SWAGGER_SPEC_INPUT)
$(GO) run $(SWAGGER_PACKAGE) generate spec --exclude "$(SWAGGER_EXCLUDE)" --input "$(SWAGGER_SPEC_INPUT)" --output './$(SWAGGER_SPEC)'
.PHONY: swagger-check
@@ -373,7 +366,7 @@ lint-go-gitea-vet: ## lint go files with gitea-vet
.PHONY: lint-go-gopls
lint-go-gopls: ## lint go files with gopls
@echo "Running gopls check..."
- @GO=$(GO) GOPLS_PACKAGE=$(GOPLS_PACKAGE) tools/lint-go-gopls.sh $(GO_SOURCES_NO_BINDATA)
+ @GO=$(GO) GOPLS_PACKAGE=$(GOPLS_PACKAGE) tools/lint-go-gopls.sh $(GO_SOURCES)
.PHONY: lint-editorconfig
lint-editorconfig:
diff --git a/build.go b/build.go
index 234579b514..e81ba54690 100644
--- a/build.go
+++ b/build.go
@@ -5,19 +5,10 @@
package main
-// Libraries that are included to vendor utilities used during build.
+// Libraries that are included to vendor utilities used during Makefile build.
// These libraries will not be included in a normal compilation.
import (
- // for embed
- _ "github.com/shurcooL/vfsgen"
-
- // for cover merge
- _ "golang.org/x/tools/cover"
-
// for vet
_ "code.gitea.io/gitea-vet"
-
- // for swagger
- _ "github.com/go-swagger/go-swagger/cmd/swagger"
)
diff --git a/build/generate-bindata.go b/build/generate-bindata.go
index 2fcb7c2f2a..2553770762 100644
--- a/build/generate-bindata.go
+++ b/build/generate-bindata.go
@@ -6,87 +6,22 @@
package main
import (
- "bytes"
- "crypto/sha1"
"fmt"
- "log"
- "net/http"
"os"
- "path/filepath"
- "strconv"
- "github.com/shurcooL/vfsgen"
+ "code.gitea.io/gitea/modules/assetfs"
)
-func needsUpdate(dir, filename string) (bool, []byte) {
- needRegen := false
- _, err := os.Stat(filename)
- if err != nil {
- needRegen = true
- }
-
- oldHash, err := os.ReadFile(filename + ".hash")
- if err != nil {
- oldHash = []byte{}
- }
-
- hasher := sha1.New()
-
- err = filepath.WalkDir(dir, func(path string, d os.DirEntry, err error) error {
- if err != nil {
- return err
- }
- info, err := d.Info()
- if err != nil {
- return err
- }
- _, _ = hasher.Write([]byte(d.Name()))
- _, _ = hasher.Write([]byte(info.ModTime().String()))
- _, _ = hasher.Write([]byte(strconv.FormatInt(info.Size(), 16)))
- return nil
- })
- if err != nil {
- return true, oldHash
- }
-
- newHash := hasher.Sum([]byte{})
-
- if bytes.Compare(oldHash, newHash) != 0 {
- return true, newHash
- }
-
- return needRegen, newHash
-}
-
func main() {
- if len(os.Args) < 4 {
- log.Fatal("Insufficient number of arguments. Need: directory packageName filename")
- }
-
- dir, packageName, filename := os.Args[1], os.Args[2], os.Args[3]
- var useGlobalModTime bool
- if len(os.Args) == 5 {
- useGlobalModTime, _ = strconv.ParseBool(os.Args[4])
- }
-
- update, newHash := needsUpdate(dir, filename)
-
- if !update {
- fmt.Printf("bindata for %s already up-to-date\n", packageName)
- return
+ if len(os.Args) != 3 {
+ fmt.Println("usage: ./generate-bindata {local-directory} {bindata-filename}")
+ os.Exit(1)
}
- fmt.Printf("generating bindata for %s\n", packageName)
- var fsTemplates http.FileSystem = http.Dir(dir)
- err := vfsgen.Generate(fsTemplates, vfsgen.Options{
- PackageName: packageName,
- BuildTags: "bindata",
- VariableName: "Assets",
- Filename: filename,
- UseGlobalModTime: useGlobalModTime,
- })
- if err != nil {
- log.Fatalf("%v\n", err)
+ dir, filename := os.Args[1], os.Args[2]
+ fmt.Printf("generating bindata for %s to %s\n", dir, filename)
+ if err := assetfs.GenerateEmbedBindata(dir, filename); err != nil {
+ fmt.Printf("failed: %s\n", err.Error())
+ os.Exit(1)
}
- _ = os.WriteFile(filename+".hash", newHash, 0o666)
}
diff --git a/cmd/embedded.go b/cmd/embedded.go
index 086bc06863..6a2fa07a93 100644
--- a/cmd/embedded.go
+++ b/cmd/embedded.go
@@ -118,7 +118,7 @@ func initEmbeddedExtractor(c *cli.Command) error {
func runList(_ context.Context, c *cli.Command) error {
if err := runListDo(c); err != nil {
- fmt.Fprintf(os.Stderr, "%v\n", err)
+ _, _ = fmt.Fprintf(os.Stderr, "%v\n", err)
return err
}
return nil
@@ -126,7 +126,7 @@ func runList(_ context.Context, c *cli.Command) error {
func runView(_ context.Context, c *cli.Command) error {
if err := runViewDo(c); err != nil {
- fmt.Fprintf(os.Stderr, "%v\n", err)
+ _, _ = fmt.Fprintf(os.Stderr, "%v\n", err)
return err
}
return nil
@@ -134,7 +134,7 @@ func runView(_ context.Context, c *cli.Command) error {
func runExtract(_ context.Context, c *cli.Command) error {
if err := runExtractDo(c); err != nil {
- fmt.Fprintf(os.Stderr, "%v\n", err)
+ _, _ = fmt.Fprintf(os.Stderr, "%v\n", err)
return err
}
return nil
@@ -217,7 +217,7 @@ func runExtractDo(c *cli.Command) error {
for _, a := range matchedAssetFiles {
if err := extractAsset(destdir, a, overwrite, rename); err != nil {
// Non-fatal error
- fmt.Fprintf(os.Stderr, "%s: %v", a.path, err)
+ _, _ = fmt.Fprintf(os.Stderr, "%s: %v\n", a.path, err)
}
}
diff --git a/cmd/serv.go b/cmd/serv.go
index e4434450d6..8c6001e727 100644
--- a/cmd/serv.go
+++ b/cmd/serv.go
@@ -212,7 +212,7 @@ func runServ(ctx context.Context, c *cli.Command) error {
if git.DefaultFeatures().SupportProcReceive {
// for AGit Flow
if cmd == "ssh_info" {
- fmt.Print(`{"type":"gitea","version":1}`)
+ fmt.Print(`{"type":"agit","version":1}`)
return nil
}
}
diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini
index e9a378e877..aa2fcee765 100644
--- a/custom/conf/app.example.ini
+++ b/custom/conf/app.example.ini
@@ -1186,17 +1186,24 @@ LEVEL = Info
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
-;; GPG key to use to sign commits, Defaults to the default - that is the value of git config --get user.signingkey
+;; GPG or SSH key to use to sign commits, Defaults to the default - that is the value of git config --get user.signingkey
+;; Depending on the value of SIGNING_FORMAT this is either:
+;; - openpgp: the GPG key ID
+;; - ssh: the path to the ssh public key "/path/to/key.pub": where "/path/to/key" is the private key, use ssh-keygen -t ed25519 to generate a new key pair without password
;; run in the context of the RUN_USER
;; Switch to none to stop signing completely
;SIGNING_KEY = default
;;
-;; If a SIGNING_KEY ID is provided and is not set to default, use the provided Name and Email address as the signer.
+;; If a SIGNING_KEY ID is provided and is not set to default, use the provided Name and Email address as the signer and the signing format.
;; These should match a publicized name and email address for the key. (When SIGNING_KEY is default these are set to
-;; the results of git config --get user.name and git config --get user.email respectively and can only be overridden
+;; the results of git config --get user.name, git config --get user.email and git config --default openpgp --get gpg.format respectively and can only be overridden
;; by setting the SIGNING_KEY ID to the correct ID.)
;SIGNING_NAME =
;SIGNING_EMAIL =
+;; SIGNING_FORMAT can be one of:
+;; - openpgp (default): use GPG to sign commits
+;; - ssh: use SSH to sign commits
+;SIGNING_FORMAT = openpgp
;;
;; Sets the default trust model for repositories. Options are: collaborator, committer, collaboratorcommitter
;DEFAULT_TRUST_MODEL = collaborator
@@ -1223,6 +1230,13 @@ LEVEL = Info
;; - commitssigned: require that all the commits in the head branch are signed.
;; - approved: only sign when merging an approved pr to a protected branch
;MERGES = pubkey, twofa, basesigned, commitssigned
+;;
+;; Determines which additional ssh keys are trusted for all signed commits regardless of the user
+;; This is useful for ssh signing key rotation.
+;; Exposes the provided SIGNING_NAME and SIGNING_EMAIL as the signer, regardless of the SIGNING_FORMAT value.
+;; Multiple keys should be comma separated.
+;; E.g."ssh-<algorithm> <key>". or "ssh-<algorithm> <key1>, ssh-<algorithm> <key2>".
+;TRUSTED_SSH_KEYS =
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
diff --git a/go.mod b/go.mod
index d2305b4f12..9bc93ccd47 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
module code.gitea.io/gitea
-go 1.24.2
+go 1.24.4
// rfc5280 said: "The serial number is an integer assigned by the CA to each certificate."
// But some CAs use negative serial number, just relax the check. related:
@@ -60,7 +60,6 @@ require (
github.com/go-ldap/ldap/v3 v3.4.11
github.com/go-redsync/redsync/v4 v4.13.0
github.com/go-sql-driver/mysql v1.9.2
- github.com/go-swagger/go-swagger v0.31.0
github.com/go-webauthn/webauthn v0.12.3
github.com/gobwas/glob v0.2.3
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f
@@ -105,7 +104,6 @@ require (
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1
github.com/sassoftware/go-rpmutils v0.4.0
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3
- github.com/shurcooL/vfsgen v0.0.0-20230704071429-0000e147ea92
github.com/stretchr/testify v1.10.0
github.com/syndtr/goleveldb v1.0.0
github.com/tstranex/u2f v1.0.0
@@ -126,7 +124,6 @@ require (
golang.org/x/sync v0.15.0
golang.org/x/sys v0.33.0
golang.org/x/text v0.26.0
- golang.org/x/tools v0.33.0
google.golang.org/grpc v1.72.0
google.golang.org/protobuf v1.36.6
gopkg.in/ini.v1 v1.67.0
@@ -144,15 +141,11 @@ require (
git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 // indirect
github.com/DataDog/zstd v1.5.7 // indirect
- github.com/Masterminds/goutils v1.1.1 // indirect
- github.com/Masterminds/semver/v3 v3.3.1 // indirect
- github.com/Masterminds/sprig/v3 v3.3.0 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/RoaringBitmap/roaring/v2 v2.4.5 // indirect
github.com/andybalholm/brotli v1.1.1 // indirect
github.com/andybalholm/cascadia v1.3.3 // indirect
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect
- github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/aws/aws-sdk-go-v2 v1.36.3 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 // indirect
@@ -195,7 +188,6 @@ require (
github.com/dlclark/regexp2 v1.11.5 // indirect
github.com/emersion/go-sasl v0.0.0-20241020182733-b788ff22d5a6 // indirect
github.com/fatih/color v1.18.0 // indirect
- github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fxamacker/cbor/v2 v2.8.0 // indirect
github.com/git-lfs/pktline v0.0.0-20230103162542-ca444d533ef1 // indirect
github.com/go-ap/errors v0.0.0-20250409143711-5686c11ae650 // indirect
@@ -204,18 +196,6 @@ require (
github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-ini/ini v1.67.0 // indirect
- github.com/go-openapi/analysis v0.23.0 // indirect
- github.com/go-openapi/errors v0.22.1 // indirect
- github.com/go-openapi/inflect v0.21.2 // indirect
- github.com/go-openapi/jsonpointer v0.21.1 // indirect
- github.com/go-openapi/jsonreference v0.21.0 // indirect
- github.com/go-openapi/loads v0.22.0 // indirect
- github.com/go-openapi/runtime v0.28.0 // indirect
- github.com/go-openapi/spec v0.21.0 // indirect
- github.com/go-openapi/strfmt v0.23.0 // indirect
- github.com/go-openapi/swag v0.23.1 // indirect
- github.com/go-openapi/validate v0.24.0 // indirect
- github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
github.com/go-webauthn/x v0.1.20 // indirect
github.com/goccy/go-json v0.10.5 // indirect
github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
@@ -229,7 +209,6 @@ require (
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/go-tpm v0.9.3 // indirect
github.com/gorilla/css v1.0.1 // indirect
- github.com/gorilla/handlers v1.5.2 // indirect
github.com/gorilla/mux v1.8.1 // indirect
github.com/gorilla/securecookie v1.1.2 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
@@ -237,12 +216,9 @@ require (
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
- github.com/jessevdk/go-flags v1.6.1 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/klauspost/pgzip v1.2.6 // indirect
- github.com/kr/pretty v0.3.1 // indirect
- github.com/kr/text v0.2.0 // indirect
github.com/libdns/libdns v1.0.0-beta.1 // indirect
github.com/mailru/easyjson v0.9.0 // indirect
github.com/markbates/going v1.0.3 // indirect
@@ -253,19 +229,15 @@ require (
github.com/miekg/dns v1.1.65 // indirect
github.com/minio/crc64nvme v1.0.1 // indirect
github.com/minio/md5-simd v1.1.2 // indirect
- github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
- github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/mrjones/oauth v0.0.0-20190623134757-126b35219450 // indirect
github.com/mschoch/smat v0.2.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/nwaples/rardecode v1.1.3 // indirect
- github.com/oklog/ulid v1.3.1 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/onsi/ginkgo v1.16.5 // indirect
- github.com/pelletier/go-toml/v2 v2.2.4 // indirect
github.com/pierrec/lz4/v4 v4.1.22 // indirect
github.com/pjbgf/sha1cd v0.3.2 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
@@ -274,22 +246,11 @@ require (
github.com/prometheus/procfs v0.16.1 // indirect
github.com/rhysd/actionlint v1.7.7 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
- github.com/rogpeppe/go-internal v1.14.1 // indirect
github.com/rs/xid v1.6.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
- github.com/sagikazarmark/locafero v0.9.0 // indirect
- github.com/shopspring/decimal v1.4.0 // indirect
- github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/skeema/knownhosts v1.3.1 // indirect
- github.com/sourcegraph/conc v0.3.0 // indirect
- github.com/spf13/afero v1.14.0 // indirect
- github.com/spf13/cast v1.7.1 // indirect
- github.com/spf13/pflag v1.0.6 // indirect
- github.com/spf13/viper v1.20.1 // indirect
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect
- github.com/subosito/gotenv v1.6.0 // indirect
- github.com/toqueteos/webbrowser v1.2.0 // indirect
github.com/unknwon/com v1.0.1 // indirect
github.com/valyala/fastjson v1.6.4 // indirect
github.com/x448/float16 v0.8.4 // indirect
@@ -300,7 +261,6 @@ require (
github.com/zeebo/assert v1.3.0 // indirect
github.com/zeebo/blake3 v0.2.4 // indirect
go.etcd.io/bbolt v1.4.0 // indirect
- go.mongodb.org/mongo-driver v1.17.3 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
@@ -308,6 +268,7 @@ require (
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 // indirect
golang.org/x/mod v0.25.0 // indirect
golang.org/x/time v0.11.0 // indirect
+ golang.org/x/tools v0.33.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250422160041-2d3770c4ea7f // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
@@ -315,8 +276,6 @@ require (
replace github.com/hashicorp/go-version => github.com/6543/go-version v1.3.1
-replace github.com/shurcooL/vfsgen => github.com/lunny/vfsgen v0.0.0-20220105142115-2c99e1ffdfa0
-
replace github.com/nektos/act => gitea.com/gitea/act v0.261.6
// TODO: the only difference is in `PutObject`: the fork doesn't use `NewVerifyingReader(r, sha256.New(), oid, expectedSize)`, need to figure out why
diff --git a/go.sum b/go.sum
index 090a04346d..9810c4a36d 100644
--- a/go.sum
+++ b/go.sum
@@ -62,12 +62,6 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE=
github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw=
github.com/Julusian/godocdown v0.0.0-20170816220326-6d19f8ff2df8/go.mod h1:INZr5t32rG59/5xeltqoCJoNY7e5x/3xoY9WSWVWg74=
-github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
-github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
-github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4=
-github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
-github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs=
-github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0=
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
@@ -103,8 +97,6 @@ github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuW
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
-github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
-github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/aws/aws-sdk-go-v2 v1.36.3 h1:mJoei2CxPutQVxaATCzDUjcZEjVRdpsiiXi2o38yqWM=
github.com/aws/aws-sdk-go-v2 v1.36.3/go.mod h1:LLXuLpgzEbD766Z5ECcRmi8AzSwfZItDtmABVkRLGzg=
github.com/aws/aws-sdk-go-v2/credentials v1.17.67 h1:9KxtdcIA/5xPNQyZRgUSpYOE6j9Bc4+D7nZua0KGYOM=
@@ -274,12 +266,8 @@ github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/felixge/fgprof v0.9.5 h1:8+vR6yu2vvSKn08urWyEuxx75NWPEvybbkBirEpsbVY=
github.com/felixge/fgprof v0.9.5/go.mod h1:yKl+ERSa++RYOs32d8K6WEXCB4uXdLls4ZaZPpayhMM=
-github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
-github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
-github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
-github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
@@ -325,28 +313,6 @@ github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-ldap/ldap/v3 v3.4.11 h1:4k0Yxweg+a3OyBLjdYn5OKglv18JNvfDykSoI8bW0gU=
github.com/go-ldap/ldap/v3 v3.4.11/go.mod h1:bY7t0FLK8OAVpp/vV6sSlpz3EQDGcQwc8pF0ujLgKvM=
-github.com/go-openapi/analysis v0.23.0 h1:aGday7OWupfMs+LbmLZG4k0MYXIANxcuBTYUC03zFCU=
-github.com/go-openapi/analysis v0.23.0/go.mod h1:9mz9ZWaSlV8TvjQHLl2mUW2PbZtemkE8yA5v22ohupo=
-github.com/go-openapi/errors v0.22.1 h1:kslMRRnK7NCb/CvR1q1VWuEQCEIsBGn5GgKD9e+HYhU=
-github.com/go-openapi/errors v0.22.1/go.mod h1:+n/5UdIqdVnLIJ6Q9Se8HNGUXYaY6CN8ImWzfi/Gzp0=
-github.com/go-openapi/inflect v0.21.2 h1:0gClGlGcxifcJR56zwvhaOulnNgnhc4qTAkob5ObnSM=
-github.com/go-openapi/inflect v0.21.2/go.mod h1:INezMuUu7SJQc2AyR3WO0DqqYUJSj8Kb4hBd7WtjlAw=
-github.com/go-openapi/jsonpointer v0.21.1 h1:whnzv/pNXtK2FbX/W9yJfRmE2gsmkfahjMKB0fZvcic=
-github.com/go-openapi/jsonpointer v0.21.1/go.mod h1:50I1STOfbY1ycR8jGz8DaMeLCdXiI6aDteEdRNNzpdk=
-github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=
-github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4=
-github.com/go-openapi/loads v0.22.0 h1:ECPGd4jX1U6NApCGG1We+uEozOAvXvJSF4nnwHZ8Aco=
-github.com/go-openapi/loads v0.22.0/go.mod h1:yLsaTCS92mnSAZX5WWoxszLj0u+Ojl+Zs5Stn1oF+rs=
-github.com/go-openapi/runtime v0.28.0 h1:gpPPmWSNGo214l6n8hzdXYhPuJcGtziTOgUpvsFWGIQ=
-github.com/go-openapi/runtime v0.28.0/go.mod h1:QN7OzcS+XuYmkQLw05akXk0jRH/eZ3kb18+1KwW9gyc=
-github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY=
-github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk=
-github.com/go-openapi/strfmt v0.23.0 h1:nlUS6BCqcnAk0pyhi9Y+kdDVZdZMHfEKQiS4HaMgO/c=
-github.com/go-openapi/strfmt v0.23.0/go.mod h1:NrtIpfKtWIygRkKVsxh7XQMDQW5HKQl6S5ik2elW+K4=
-github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU=
-github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0=
-github.com/go-openapi/validate v0.24.0 h1:LdfDKwNbpB6Vn40xhTdNZAnfLECL81w+VX3BumrGD58=
-github.com/go-openapi/validate v0.24.0/go.mod h1:iyeX1sEufmv3nPbBdX3ieNviWnOZaJ1+zquzJEf2BAQ=
github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg=
github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
github.com/go-redis/redis/v7 v7.4.1 h1:PASvf36gyUpr2zdOUS/9Zqc80GbM+9BDyiJSJDDOrTI=
@@ -357,13 +323,9 @@ github.com/go-redsync/redsync/v4 v4.13.0 h1:49X6GJfnbLGaIpBBREM/zA4uIMDXKAh1NDkv
github.com/go-redsync/redsync/v4 v4.13.0/go.mod h1:HMW4Q224GZQz6x1Xc7040Yfgacukdzu7ifTDAKiyErQ=
github.com/go-sql-driver/mysql v1.9.2 h1:4cNKDYQ1I84SXslGddlsrMhc8k4LeDVj6Ad6WRjiHuU=
github.com/go-sql-driver/mysql v1.9.2/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=
-github.com/go-swagger/go-swagger v0.31.0 h1:H8eOYQnY2u7vNKWDNykv2xJP3pBhRG/R+SOCAmKrLlc=
-github.com/go-swagger/go-swagger v0.31.0/go.mod h1:WSigRRWEig8zV6t6Sm8Y+EmUjlzA/HoaZJ5edupq7po=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg=
github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
-github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss=
-github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/go-webauthn/webauthn v0.12.3 h1:hHQl1xkUuabUU9uS+ISNCMLs9z50p9mDUZI/FmkayNE=
github.com/go-webauthn/webauthn v0.12.3/go.mod h1:4JRe8Z3W7HIw8NGEWn2fnUwecoDzkkeach/NnvhkqGY=
github.com/go-webauthn/x v0.1.20 h1:brEBDqfiPtNNCdS/peu8gARtq8fIPsHz0VzpPjGvgiw=
@@ -446,8 +408,6 @@ github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8=
github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0=
github.com/gorilla/feeds v1.2.0 h1:O6pBiXJ5JHhPvqy53NsjKOThq+dNFm8+DFrxBEdzSCc=
github.com/gorilla/feeds v1.2.0/go.mod h1:WMib8uJP3BbY+X8Szd1rA5Pzhdfh+HCCAYT2z7Fza6Y=
-github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE=
-github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w=
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/gorilla/pat v0.0.0-20180118222023-199c85a7f6d1 h1:LqbZZ9sNMWVjeXS4NN5oVvhMjDyLhmA1LG86oSo+IqY=
@@ -497,8 +457,6 @@ github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh6
github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs=
github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY=
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
-github.com/jessevdk/go-flags v1.6.1 h1:Cvu5U8UGrLay1rZfv/zP7iLpSHGUZ/Ou68T0iX1bBK4=
-github.com/jessevdk/go-flags v1.6.1/go.mod h1:Mk8T1hIAWpOiJiHa9rJASDK2UGWji0EuPGBnNLMooyc=
github.com/jhillyerd/enmime v1.3.0 h1:LV5kzfLidiOr8qRGIpYYmUZCnhrPbcFAnAFUnWn99rw=
github.com/jhillyerd/enmime v1.3.0/go.mod h1:6c6jg5HdRRV2FtvVL69LjiX1M8oE0xDX9VEhV3oy4gs=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
@@ -540,8 +498,6 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/libdns/libdns v1.0.0-beta.1 h1:KIf4wLfsrEpXpZ3vmc/poM8zCATXT2klbdPe6hyOBjQ=
github.com/libdns/libdns v1.0.0-beta.1/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ=
-github.com/lunny/vfsgen v0.0.0-20220105142115-2c99e1ffdfa0 h1:F/3FfGmKdiKFa8kL3YrpZ7pe9H4l4AzA1pbaOUnRvPI=
-github.com/lunny/vfsgen v0.0.0-20220105142115-2c99e1ffdfa0/go.mod h1:JEfTc3+2DF9Z4PXhLLvXL42zexJyh8rIq3OzUj/0rAk=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4=
@@ -577,14 +533,10 @@ github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
github.com/minio/minio-go/v7 v7.0.91 h1:tWLZnEfo3OZl5PoXQwcwTAPNNrjyWwOh6cbZitW5JQc=
github.com/minio/minio-go/v7 v7.0.91/go.mod h1:uvMUcGrpgeSAAI6+sD3818508nUyMULw94j2Nxku/Go=
-github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
-github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
-github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
-github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -607,8 +559,6 @@ github.com/nwaples/rardecode v1.1.3/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWk
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
-github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
-github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/olivere/elastic/v7 v7.0.32 h1:R7CXvbu8Eq+WlsLgxmKVKPox0oOwAE/2T9Si5BnvK6E=
@@ -629,8 +579,6 @@ github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJw
github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
-github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
-github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU=
@@ -674,7 +622,6 @@ github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
-github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU=
@@ -682,8 +629,6 @@ github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
-github.com/sagikazarmark/locafero v0.9.0 h1:GbgQGNtTrEmddYDSAH9QLRyfAHY12md+8YFTqyMTC9k=
-github.com/sagikazarmark/locafero v0.9.0/go.mod h1:UBUyz37V+EdMS3hDF3QWIiVr/2dPrx49OMO0Bn0hJqk=
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4=
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY=
github.com/sassoftware/go-rpmutils v0.4.0 h1:ojND82NYBxgwrV+mX1CWsd5QJvvEZTKddtCdFLPWhpg=
@@ -692,10 +637,6 @@ github.com/serenize/snaker v0.0.0-20171204205717-a683aaf2d516/go.mod h1:Yow6lPLS
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
-github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
-github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
-github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c h1:aqg5Vm5dwtvL+YgDpBcK1ITf3o96N/K7/wsRXQnUTEs=
-github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c/go.mod h1:owqhoLW1qZoYLZzLnBw+QkPP9WZnjlSWihhxAJC1+/M=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
@@ -707,22 +648,12 @@ github.com/smartystreets/assertions v1.1.1/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYl
github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8=
github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
-github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
-github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
-github.com/spf13/afero v1.14.0 h1:9tH6MapGnn/j0eb0yIXiLjERO8RB6xIVZRDCX7PtqWA=
-github.com/spf13/afero v1.14.0/go.mod h1:acJQ8t0ohCGuMN3O+Pv0V0hgMxNYDlvdk+VTfyZmbYo=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
-github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y=
-github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
-github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
-github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
-github.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4=
-github.com/spf13/viper v1.20.1/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4=
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf h1:pvbZ0lM0XWPBqUKqFU8cmavspvIl9nulOYwdy6IFRRo=
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf/go.mod h1:RJID2RhlZKId02nZ62WenDCkgHFerpIOmW0iT7GKmXM=
github.com/stephens2424/writerset v1.0.2/go.mod h1:aS2JhsMn6eA7e82oNmW4rfsgAOp9COBTTl8mzkwADnc=
@@ -745,13 +676,9 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stvp/tempredis v0.0.0-20181119212430-b82af8480203 h1:QVqDTf3h2WHt08YuiTGPZLls0Wq99X9bWd0Q5ZSBesM=
github.com/stvp/tempredis v0.0.0-20181119212430-b82af8480203/go.mod h1:oqN97ltKNihBbwlX8dLpwxCl3+HnXKV/R0e+sRLd9C8=
-github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
-github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
-github.com/toqueteos/webbrowser v1.2.0 h1:tVP/gpK69Fx+qMJKsLE7TD8LuGWPnEV71wBN9rrstGQ=
-github.com/toqueteos/webbrowser v1.2.0/go.mod h1:XWoZq4cyp9WeUeak7w7LXRUQf1F1ATJMir8RTqb4ayM=
github.com/tstranex/u2f v1.0.0 h1:HhJkSzDDlVSVIVt7pDJwCHQj67k7A5EeBgPmeD+pVsQ=
github.com/tstranex/u2f v1.0.0/go.mod h1:eahSLaqAS0zsIEv80+vXT7WanXs7MQQDg3j3wGBSayo=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
@@ -809,8 +736,6 @@ gitlab.com/gitlab-org/api/client-go v0.127.0/go.mod h1:bYC6fPORKSmtuPRyD9Z2rtbAj
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
go.etcd.io/bbolt v1.4.0 h1:TU77id3TnN/zKr7CO/uk+fBCwF2jGcMuw2B/FMAzYIk=
go.etcd.io/bbolt v1.4.0/go.mod h1:AsD+OCi/qPN1giOX1aiLAha3o1U8rAz65bvN4j0sRuk=
-go.mongodb.org/mongo-driver v1.17.3 h1:TQyXhnsWfWtgAhMtOgtYHMTkZIfBTpMTsMnd9ZBeHxQ=
-go.mongodb.org/mongo-driver v1.17.3/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
diff --git a/modules/assetfs/embed.go b/modules/assetfs/embed.go
new file mode 100644
index 0000000000..95176372d1
--- /dev/null
+++ b/modules/assetfs/embed.go
@@ -0,0 +1,375 @@
+// Copyright 2025 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package assetfs
+
+import (
+ "bytes"
+ "compress/gzip"
+ "io"
+ "io/fs"
+ "os"
+ "path"
+ "path/filepath"
+ "strings"
+ "sync"
+ "time"
+
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/util"
+)
+
+type EmbeddedFile interface {
+ io.ReadSeeker
+ fs.ReadDirFile
+ ReadDir(n int) ([]fs.DirEntry, error)
+}
+
+type EmbeddedFileInfo interface {
+ fs.FileInfo
+ fs.DirEntry
+ GetGzipContent() ([]byte, bool)
+}
+
+type decompressor interface {
+ io.Reader
+ Close() error
+ Reset(io.Reader) error
+}
+
+type embeddedFileInfo struct {
+ fs *embeddedFS
+ fullName string
+ data []byte
+
+ BaseName string `json:"n"`
+ OriginSize int64 `json:"s,omitempty"`
+ DataBegin int64 `json:"b,omitempty"`
+ DataLen int64 `json:"l,omitempty"`
+ Children []*embeddedFileInfo `json:"c,omitempty"`
+}
+
+func (fi *embeddedFileInfo) GetGzipContent() ([]byte, bool) {
+ // when generating the bindata, if the compressed data equals or is larger than the original data, we store the original data
+ if fi.DataLen == fi.OriginSize {
+ return nil, false
+ }
+ return fi.data, true
+}
+
+type EmbeddedFileBase struct {
+ info *embeddedFileInfo
+ dataReader io.ReadSeeker
+ seekPos int64
+}
+
+func (f *EmbeddedFileBase) ReadDir(n int) ([]fs.DirEntry, error) {
+ // this method is used to satisfy the "func (f ioFile) ReadDir(...)" in httpfs
+ l, err := f.info.fs.ReadDir(f.info.fullName)
+ if err != nil {
+ return nil, err
+ }
+ if n < 0 || n > len(l) {
+ return l, nil
+ }
+ return l[:n], nil
+}
+
+type EmbeddedOriginFile struct {
+ EmbeddedFileBase
+}
+
+type EmbeddedCompressedFile struct {
+ EmbeddedFileBase
+ decompressor decompressor
+ decompressorPos int64
+}
+
+type embeddedFS struct {
+ meta func() *EmbeddedMeta
+
+ files map[string]*embeddedFileInfo
+ filesMu sync.RWMutex
+
+ data []byte
+}
+
+type EmbeddedMeta struct {
+ Root *embeddedFileInfo
+}
+
+func NewEmbeddedFS(data []byte) fs.ReadDirFS {
+ efs := &embeddedFS{data: data, files: make(map[string]*embeddedFileInfo)}
+ efs.meta = sync.OnceValue(func() *EmbeddedMeta {
+ var meta EmbeddedMeta
+ p := bytes.LastIndexByte(data, '\n')
+ if p < 0 {
+ return &meta
+ }
+ if err := json.Unmarshal(data[p+1:], &meta); err != nil {
+ panic("embedded file is not valid")
+ }
+ return &meta
+ })
+ return efs
+}
+
+var _ fs.ReadDirFS = (*embeddedFS)(nil)
+
+func (e *embeddedFS) ReadDir(name string) (l []fs.DirEntry, err error) {
+ fi, err := e.getFileInfo(name)
+ if err != nil {
+ return nil, err
+ }
+ if !fi.IsDir() {
+ return nil, fs.ErrNotExist
+ }
+ l = make([]fs.DirEntry, len(fi.Children))
+ for i, child := range fi.Children {
+ l[i], err = e.getFileInfo(name + "/" + child.BaseName)
+ if err != nil {
+ return nil, err
+ }
+ }
+ return l, nil
+}
+
+func (e *embeddedFS) getFileInfo(fullName string) (*embeddedFileInfo, error) {
+ // no need to do heavy "path.Clean()" because we don't want to support "foo/../bar" or absolute paths
+ fullName = strings.TrimPrefix(fullName, "./")
+ if fullName == "" {
+ fullName = "."
+ }
+
+ e.filesMu.RLock()
+ fi := e.files[fullName]
+ e.filesMu.RUnlock()
+ if fi != nil {
+ return fi, nil
+ }
+
+ fields := strings.Split(fullName, "/")
+ fi = e.meta().Root
+ if fullName != "." {
+ found := true
+ for _, field := range fields {
+ for _, child := range fi.Children {
+ if found = child.BaseName == field; found {
+ fi = child
+ break
+ }
+ }
+ if !found {
+ return nil, fs.ErrNotExist
+ }
+ }
+ }
+
+ e.filesMu.Lock()
+ defer e.filesMu.Unlock()
+ if fi != nil {
+ fi.fs = e
+ fi.fullName = fullName
+ fi.data = e.data[fi.DataBegin : fi.DataBegin+fi.DataLen]
+ e.files[fullName] = fi // do not cache nil, otherwise keeping accessing random non-existing file will cause OOM
+ return fi, nil
+ }
+ return nil, fs.ErrNotExist
+}
+
+func (e *embeddedFS) Open(name string) (fs.File, error) {
+ info, err := e.getFileInfo(name)
+ if err != nil {
+ return nil, err
+ }
+ base := EmbeddedFileBase{info: info}
+ base.dataReader = bytes.NewReader(base.info.data)
+ if info.DataLen != info.OriginSize {
+ decomp, err := gzip.NewReader(base.dataReader)
+ if err != nil {
+ return nil, err
+ }
+ return &EmbeddedCompressedFile{EmbeddedFileBase: base, decompressor: decomp}, nil
+ }
+ return &EmbeddedOriginFile{base}, nil
+}
+
+var (
+ _ EmbeddedFileInfo = (*embeddedFileInfo)(nil)
+ _ EmbeddedFile = (*EmbeddedOriginFile)(nil)
+ _ EmbeddedFile = (*EmbeddedCompressedFile)(nil)
+)
+
+func (f *EmbeddedOriginFile) Read(p []byte) (n int, err error) {
+ return f.dataReader.Read(p)
+}
+
+func (f *EmbeddedCompressedFile) Read(p []byte) (n int, err error) {
+ if f.decompressorPos > f.seekPos {
+ if err = f.decompressor.Reset(bytes.NewReader(f.info.data)); err != nil {
+ return 0, err
+ }
+ f.decompressorPos = 0
+ }
+ if f.decompressorPos < f.seekPos {
+ if _, err = io.CopyN(io.Discard, f.decompressor, f.seekPos-f.decompressorPos); err != nil {
+ return 0, err
+ }
+ f.decompressorPos = f.seekPos
+ }
+ n, err = f.decompressor.Read(p)
+ f.decompressorPos += int64(n)
+ f.seekPos = f.decompressorPos
+ return n, err
+}
+
+func (f *EmbeddedFileBase) Seek(offset int64, whence int) (int64, error) {
+ switch whence {
+ case io.SeekStart:
+ f.seekPos = offset
+ case io.SeekCurrent:
+ f.seekPos += offset
+ case io.SeekEnd:
+ f.seekPos = f.info.OriginSize + offset
+ }
+ return f.seekPos, nil
+}
+
+func (f *EmbeddedFileBase) Stat() (fs.FileInfo, error) {
+ return f.info, nil
+}
+
+func (f *EmbeddedOriginFile) Close() error {
+ return nil
+}
+
+func (f *EmbeddedCompressedFile) Close() error {
+ return f.decompressor.Close()
+}
+
+func (fi *embeddedFileInfo) Name() string {
+ return fi.BaseName
+}
+
+func (fi *embeddedFileInfo) Size() int64 {
+ return fi.OriginSize
+}
+
+func (fi *embeddedFileInfo) Mode() fs.FileMode {
+ return util.Iif(fi.IsDir(), fs.ModeDir|0o555, 0o444)
+}
+
+func (fi *embeddedFileInfo) ModTime() time.Time {
+ return getExecutableModTime()
+}
+
+func (fi *embeddedFileInfo) IsDir() bool {
+ return fi.Children != nil
+}
+
+func (fi *embeddedFileInfo) Sys() any {
+ return nil
+}
+
+func (fi *embeddedFileInfo) Type() fs.FileMode {
+ return util.Iif(fi.IsDir(), fs.ModeDir, 0)
+}
+
+func (fi *embeddedFileInfo) Info() (fs.FileInfo, error) {
+ return fi, nil
+}
+
+// getExecutableModTime returns the modification time of the executable file.
+// In bindata, we can't use the ModTime of the files because we need to make the build reproducible
+var getExecutableModTime = sync.OnceValue(func() (modTime time.Time) {
+ exePath, err := os.Executable()
+ if err != nil {
+ return modTime
+ }
+ exePath, err = filepath.Abs(exePath)
+ if err != nil {
+ return modTime
+ }
+ exePath, err = filepath.EvalSymlinks(exePath)
+ if err != nil {
+ return modTime
+ }
+ st, err := os.Stat(exePath)
+ if err != nil {
+ return modTime
+ }
+ return st.ModTime()
+})
+
+func GenerateEmbedBindata(fsRootPath, outputFile string) error {
+ output, err := os.OpenFile(outputFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.ModePerm)
+ if err != nil {
+ return err
+ }
+ defer output.Close()
+
+ meta := &EmbeddedMeta{}
+ meta.Root = &embeddedFileInfo{}
+ var outputOffset int64
+ var embedFiles func(parent *embeddedFileInfo, fsPath, embedPath string) error
+ embedFiles = func(parent *embeddedFileInfo, fsPath, embedPath string) error {
+ dirEntries, err := os.ReadDir(fsPath)
+ if err != nil {
+ return err
+ }
+ for _, dirEntry := range dirEntries {
+ if err != nil {
+ return err
+ }
+ if dirEntry.IsDir() {
+ child := &embeddedFileInfo{
+ BaseName: dirEntry.Name(),
+ Children: []*embeddedFileInfo{}, // non-nil means it's a directory
+ }
+ parent.Children = append(parent.Children, child)
+ if err = embedFiles(child, filepath.Join(fsPath, dirEntry.Name()), path.Join(embedPath, dirEntry.Name())); err != nil {
+ return err
+ }
+ } else {
+ data, err := os.ReadFile(filepath.Join(fsPath, dirEntry.Name()))
+ if err != nil {
+ return err
+ }
+ var compressed bytes.Buffer
+ gz, _ := gzip.NewWriterLevel(&compressed, gzip.BestCompression)
+ if _, err = gz.Write(data); err != nil {
+ return err
+ }
+ if err = gz.Close(); err != nil {
+ return err
+ }
+
+ // only use the compressed data if it is smaller than the original data
+ outputBytes := util.Iif(len(compressed.Bytes()) < len(data), compressed.Bytes(), data)
+ child := &embeddedFileInfo{
+ BaseName: dirEntry.Name(),
+ OriginSize: int64(len(data)),
+ DataBegin: outputOffset,
+ DataLen: int64(len(outputBytes)),
+ }
+ if _, err = output.Write(outputBytes); err != nil {
+ return err
+ }
+ outputOffset += child.DataLen
+ parent.Children = append(parent.Children, child)
+ }
+ }
+ return nil
+ }
+
+ if err = embedFiles(meta.Root, fsRootPath, ""); err != nil {
+ return err
+ }
+ jsonBuf, err := json.Marshal(meta) // can't use json.NewEncoder here because it writes extra EOL
+ if err != nil {
+ return err
+ }
+ _, _ = output.Write([]byte{'\n'})
+ _, err = output.Write(jsonBuf)
+ return err
+}
diff --git a/modules/assetfs/embed_test.go b/modules/assetfs/embed_test.go
new file mode 100644
index 0000000000..06598da4c4
--- /dev/null
+++ b/modules/assetfs/embed_test.go
@@ -0,0 +1,98 @@
+// Copyright 2025 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package assetfs
+
+import (
+ "bytes"
+ "io/fs"
+ "net/http"
+ "os"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func TestEmbed(t *testing.T) {
+ tmpDir := t.TempDir()
+ tmpDataDir := tmpDir + "/data"
+ _ = os.MkdirAll(tmpDataDir+"/foo/bar", 0o755)
+ _ = os.WriteFile(tmpDataDir+"/a.txt", []byte("a"), 0o644)
+ _ = os.WriteFile(tmpDataDir+"/foo/bar/b.txt", bytes.Repeat([]byte("a"), 1000), 0o644)
+ _ = os.WriteFile(tmpDataDir+"/foo/c.txt", []byte("c"), 0o644)
+ require.NoError(t, GenerateEmbedBindata(tmpDataDir, tmpDir+"/out.dat"))
+
+ data, err := os.ReadFile(tmpDir + "/out.dat")
+ require.NoError(t, err)
+ efs := NewEmbeddedFS(data)
+
+ // test a non-existing file
+ _, err = fs.ReadFile(efs, "not exist")
+ assert.ErrorIs(t, err, fs.ErrNotExist)
+
+ // test a normal file (no compression)
+ content, err := fs.ReadFile(efs, "a.txt")
+ require.NoError(t, err)
+ assert.Equal(t, "a", string(content))
+ fi, err := fs.Stat(efs, "a.txt")
+ require.NoError(t, err)
+ _, ok := fi.(EmbeddedFileInfo).GetGzipContent()
+ assert.False(t, ok)
+
+ // test a compressed file
+ content, err = fs.ReadFile(efs, "foo/bar/b.txt")
+ require.NoError(t, err)
+ assert.Equal(t, bytes.Repeat([]byte("a"), 1000), content)
+ fi, err = fs.Stat(efs, "foo/bar/b.txt")
+ require.NoError(t, err)
+ assert.False(t, fi.Mode().IsDir())
+ assert.True(t, fi.Mode().IsRegular())
+ gzipContent, ok := fi.(EmbeddedFileInfo).GetGzipContent()
+ assert.True(t, ok)
+ assert.Greater(t, len(gzipContent), 1)
+ assert.Less(t, len(gzipContent), 1000)
+
+ // test list root directory
+ entries, err := fs.ReadDir(efs, ".")
+ require.NoError(t, err)
+ assert.Len(t, entries, 2)
+ assert.Equal(t, "a.txt", entries[0].Name())
+ assert.False(t, entries[0].IsDir())
+
+ // test list subdirectory
+ entries, err = fs.ReadDir(efs, "foo")
+ require.NoError(t, err)
+ require.Len(t, entries, 2)
+ assert.Equal(t, "bar", entries[0].Name())
+ assert.True(t, entries[0].IsDir())
+ assert.Equal(t, "c.txt", entries[1].Name())
+ assert.False(t, entries[1].IsDir())
+
+ // test directory mode
+ fi, err = fs.Stat(efs, "foo")
+ require.NoError(t, err)
+ assert.True(t, fi.IsDir())
+ assert.True(t, fi.Mode().IsDir())
+ assert.False(t, fi.Mode().IsRegular())
+
+ // test httpfs
+ hfs := http.FS(efs)
+ hf, err := hfs.Open("foo/bar/b.txt")
+ require.NoError(t, err)
+ hi, err := hf.Stat()
+ require.NoError(t, err)
+ fiEmbedded, ok := hi.(EmbeddedFileInfo)
+ require.True(t, ok)
+ gzipContent, ok = fiEmbedded.GetGzipContent()
+ assert.True(t, ok)
+ assert.Greater(t, len(gzipContent), 1)
+ assert.Less(t, len(gzipContent), 1000)
+
+ // test httpfs directory listing
+ hf, err = hfs.Open("foo")
+ require.NoError(t, err)
+ dirs, err := hf.Readdir(1)
+ require.NoError(t, err)
+ assert.Len(t, dirs, 1)
+}
diff --git a/modules/assetfs/layered.go b/modules/assetfs/layered.go
index 4f3811ba2b..ce55475bd9 100644
--- a/modules/assetfs/layered.go
+++ b/modules/assetfs/layered.go
@@ -52,8 +52,8 @@ func Local(name, base string, sub ...string) *Layer {
}
// Bindata returns a new Layer with the given name, it serves files from the given bindata asset.
-func Bindata(name string, fs http.FileSystem) *Layer {
- return &Layer{name: name, fs: fs}
+func Bindata(name string, fs fs.FS) *Layer {
+ return &Layer{name: name, fs: http.FS(fs)}
}
// LayeredFS is a layered asset file-system. It works like http.FileSystem, but it can have multiple layers.
diff --git a/modules/git/command.go b/modules/git/command.go
index eaaa4969d0..22f1d02339 100644
--- a/modules/git/command.go
+++ b/modules/git/command.go
@@ -47,6 +47,7 @@ type Command struct {
globalArgsLength int
brokenArgs []string
cmd *exec.Cmd // for debug purpose only
+ configArgs []string
}
func logArgSanitize(arg string) string {
@@ -196,6 +197,16 @@ func (c *Command) AddDashesAndList(list ...string) *Command {
return c
}
+func (c *Command) AddConfig(key, value string) *Command {
+ kv := key + "=" + value
+ if !isSafeArgumentValue(kv) {
+ c.brokenArgs = append(c.brokenArgs, key)
+ } else {
+ c.configArgs = append(c.configArgs, "-c", kv)
+ }
+ return c
+}
+
// ToTrustedCmdArgs converts a list of strings (trusted as argument) to TrustedCmdArgs
// In most cases, it shouldn't be used. Use NewCommand().AddXxx() function instead
func ToTrustedCmdArgs(args []string) TrustedCmdArgs {
@@ -321,7 +332,7 @@ func (c *Command) run(ctx context.Context, skip int, opts *RunOpts) error {
startTime := time.Now()
- cmd := exec.CommandContext(ctx, c.prog, c.args...)
+ cmd := exec.CommandContext(ctx, c.prog, append(c.configArgs, c.args...)...)
c.cmd = cmd // for debug purpose only
if opts.Env == nil {
cmd.Env = os.Environ()
diff --git a/modules/git/key.go b/modules/git/key.go
new file mode 100644
index 0000000000..2513c048b7
--- /dev/null
+++ b/modules/git/key.go
@@ -0,0 +1,15 @@
+// Copyright 2025 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package git
+
+// Based on https://git-scm.com/docs/git-config#Documentation/git-config.txt-gpgformat
+const (
+ SigningKeyFormatOpenPGP = "openpgp" // for GPG keys, the expected default of git cli
+ SigningKeyFormatSSH = "ssh"
+)
+
+type SigningKey struct {
+ KeyID string
+ Format string
+}
diff --git a/modules/git/repo.go b/modules/git/repo.go
index 45937a8d5f..239866fe9d 100644
--- a/modules/git/repo.go
+++ b/modules/git/repo.go
@@ -28,6 +28,7 @@ type GPGSettings struct {
Email string
Name string
PublicKeyContent string
+ Format string
}
const prettyLogFormat = `--pretty=format:%H`
diff --git a/modules/git/repo_gpg.go b/modules/git/repo_gpg.go
index 8f91b4dce5..0021a7bda7 100644
--- a/modules/git/repo_gpg.go
+++ b/modules/git/repo_gpg.go
@@ -6,6 +6,7 @@ package git
import (
"fmt"
+ "os"
"strings"
"code.gitea.io/gitea/modules/process"
@@ -13,6 +14,14 @@ import (
// LoadPublicKeyContent will load the key from gpg
func (gpgSettings *GPGSettings) LoadPublicKeyContent() error {
+ if gpgSettings.Format == SigningKeyFormatSSH {
+ content, err := os.ReadFile(gpgSettings.KeyID)
+ if err != nil {
+ return fmt.Errorf("unable to read SSH public key file: %s, %w", gpgSettings.KeyID, err)
+ }
+ gpgSettings.PublicKeyContent = string(content)
+ return nil
+ }
content, stderr, err := process.GetManager().Exec(
"gpg -a --export",
"gpg", "-a", "--export", gpgSettings.KeyID)
@@ -44,6 +53,9 @@ func (repo *Repository) GetDefaultPublicGPGKey(forceUpdate bool) (*GPGSettings,
signingKey, _, _ := NewCommand("config", "--get", "user.signingkey").RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path})
gpgSettings.KeyID = strings.TrimSpace(signingKey)
+ format, _, _ := NewCommand("config", "--default", SigningKeyFormatOpenPGP, "--get", "gpg.format").RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path})
+ gpgSettings.Format = strings.TrimSpace(format)
+
defaultEmail, _, _ := NewCommand("config", "--get", "user.email").RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path})
gpgSettings.Email = strings.TrimSpace(defaultEmail)
diff --git a/modules/git/repo_tree.go b/modules/git/repo_tree.go
index 70e5aee023..309a73d759 100644
--- a/modules/git/repo_tree.go
+++ b/modules/git/repo_tree.go
@@ -15,7 +15,7 @@ import (
type CommitTreeOpts struct {
Parents []string
Message string
- KeyID string
+ Key *SigningKey
NoGPGSign bool
AlwaysSign bool
}
@@ -43,8 +43,13 @@ func (repo *Repository) CommitTree(author, committer *Signature, tree *Tree, opt
_, _ = messageBytes.WriteString(opts.Message)
_, _ = messageBytes.WriteString("\n")
- if opts.KeyID != "" || opts.AlwaysSign {
- cmd.AddOptionFormat("-S%s", opts.KeyID)
+ if opts.Key != nil {
+ if opts.Key.Format != "" {
+ cmd.AddConfig("gpg.format", opts.Key.Format)
+ }
+ cmd.AddOptionFormat("-S%s", opts.Key.KeyID)
+ } else if opts.AlwaysSign {
+ cmd.AddOptionFormat("-S")
}
if opts.NoGPGSign {
diff --git a/modules/migration/schemas_bindata.go b/modules/migration/schemas_bindata.go
index c5db3b3461..695c2c1135 100644
--- a/modules/migration/schemas_bindata.go
+++ b/modules/migration/schemas_bindata.go
@@ -3,6 +3,28 @@
//go:build bindata
+//go:generate go run ../../build/generate-bindata.go ../../modules/migration/schemas bindata.dat
+
package migration
-//go:generate go run ../../build/generate-bindata.go ../../modules/migration/schemas migration bindata.go
+import (
+ "io"
+ "io/fs"
+ "path"
+ "sync"
+
+ _ "embed"
+
+ "code.gitea.io/gitea/modules/assetfs"
+)
+
+//go:embed bindata.dat
+var bindata []byte
+
+var BuiltinAssets = sync.OnceValue(func() fs.FS {
+ return assetfs.NewEmbeddedFS(bindata)
+})
+
+func openSchema(filename string) (io.ReadCloser, error) {
+ return BuiltinAssets().Open(path.Base(filename))
+}
diff --git a/modules/migration/schemas_static.go b/modules/migration/schemas_static.go
deleted file mode 100644
index 8a0c340a65..0000000000
--- a/modules/migration/schemas_static.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2022 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build bindata
-
-package migration
-
-import (
- "io"
- "path"
-)
-
-func openSchema(filename string) (io.ReadCloser, error) {
- return Assets.Open(path.Base(filename))
-}
diff --git a/modules/options/options_bindata.go b/modules/options/options_bindata.go
index 29151cb3cb..b2321d7eb5 100644
--- a/modules/options/options_bindata.go
+++ b/modules/options/options_bindata.go
@@ -3,6 +3,21 @@
//go:build bindata
+//go:generate go run ../../build/generate-bindata.go ../../options bindata.dat
+
package options
-//go:generate go run ../../build/generate-bindata.go ../../options options bindata.go
+import (
+ "sync"
+
+ _ "embed"
+
+ "code.gitea.io/gitea/modules/assetfs"
+)
+
+//go:embed bindata.dat
+var bindata []byte
+
+var BuiltinAssets = sync.OnceValue(func() *assetfs.Layer {
+ return assetfs.Bindata("builtin(bindata)", assetfs.NewEmbeddedFS(bindata))
+})
diff --git a/modules/options/dynamic.go b/modules/options/options_dynamic.go
index 085492d11c..085492d11c 100644
--- a/modules/options/dynamic.go
+++ b/modules/options/options_dynamic.go
diff --git a/modules/options/static.go b/modules/options/static.go
deleted file mode 100644
index 72b28e990e..0000000000
--- a/modules/options/static.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2022 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build bindata
-
-package options
-
-import (
- "code.gitea.io/gitea/modules/assetfs"
-)
-
-func BuiltinAssets() *assetfs.Layer {
- return assetfs.Bindata("builtin(bindata)", Assets)
-}
diff --git a/modules/public/public.go b/modules/public/public.go
index 7f8ce29056..2bc55b7869 100644
--- a/modules/public/public.go
+++ b/modules/public/public.go
@@ -89,19 +89,16 @@ func handleRequest(w http.ResponseWriter, req *http.Request, fs http.FileSystem,
servePublicAsset(w, req, fi, fi.ModTime(), f)
}
-type GzipBytesProvider interface {
- GzipBytes() []byte
-}
-
// servePublicAsset serve http content
func servePublicAsset(w http.ResponseWriter, req *http.Request, fi os.FileInfo, modtime time.Time, content io.ReadSeeker) {
setWellKnownContentType(w, fi.Name())
httpcache.SetCacheControlInHeader(w.Header(), httpcache.CacheControlForPublicStatic())
encodings := parseAcceptEncoding(req.Header.Get("Accept-Encoding"))
- if encodings.Contains("gzip") {
- // try to provide gzip content directly from bindata (provided by vfsgenÛ°CompressedFileInfo)
- if compressed, ok := fi.(GzipBytesProvider); ok {
- rdGzip := bytes.NewReader(compressed.GzipBytes())
+ fiEmbedded, _ := fi.(assetfs.EmbeddedFileInfo)
+ if encodings.Contains("gzip") && fiEmbedded != nil {
+ // try to provide gzip content directly from bindata
+ if gzipBytes, ok := fiEmbedded.GetGzipContent(); ok {
+ rdGzip := bytes.NewReader(gzipBytes)
// all gzipped static files (from bindata) are managed by Gitea, so we can make sure every file has the correct ext name
// then we can get the correct Content-Type, we do not need to do http.DetectContentType on the decompressed data
if w.Header().Get("Content-Type") == "" {
diff --git a/modules/public/public_bindata.go b/modules/public/public_bindata.go
index 4878f88ad1..2dcf3e72e4 100644
--- a/modules/public/public_bindata.go
+++ b/modules/public/public_bindata.go
@@ -5,4 +5,19 @@
package public
-//go:generate go run ../../build/generate-bindata.go ../../public public bindata.go true
+//go:generate go run ../../build/generate-bindata.go ../../public bindata.dat
+
+import (
+ "sync"
+
+ _ "embed"
+
+ "code.gitea.io/gitea/modules/assetfs"
+)
+
+//go:embed bindata.dat
+var bindata []byte
+
+var BuiltinAssets = sync.OnceValue(func() *assetfs.Layer {
+ return assetfs.Bindata("builtin(bindata)", assetfs.NewEmbeddedFS(bindata))
+})
diff --git a/modules/public/serve_dynamic.go b/modules/public/public_dynamic.go
index a668b17c34..a668b17c34 100644
--- a/modules/public/serve_dynamic.go
+++ b/modules/public/public_dynamic.go
diff --git a/modules/public/serve_static.go b/modules/public/serve_static.go
deleted file mode 100644
index e79085021e..0000000000
--- a/modules/public/serve_static.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2016 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build bindata
-
-package public
-
-import (
- "time"
-
- "code.gitea.io/gitea/modules/assetfs"
- "code.gitea.io/gitea/modules/timeutil"
-)
-
-var _ GzipBytesProvider = (*vfsgenÛ°CompressedFileInfo)(nil)
-
-// GlobalModTime provide a global mod time for embedded asset files
-func GlobalModTime(filename string) time.Time {
- return timeutil.GetExecutableModTime()
-}
-
-func BuiltinAssets() *assetfs.Layer {
- return assetfs.Bindata("builtin(bindata)", Assets)
-}
diff --git a/modules/setting/repository.go b/modules/setting/repository.go
index c6bdc65b32..318cf41108 100644
--- a/modules/setting/repository.go
+++ b/modules/setting/repository.go
@@ -100,11 +100,13 @@ var (
SigningKey string
SigningName string
SigningEmail string
+ SigningFormat string
InitialCommit []string
CRUDActions []string `ini:"CRUD_ACTIONS"`
Merges []string
Wiki []string
DefaultTrustModel string
+ TrustedSSHKeys []string `ini:"TRUSTED_SSH_KEYS"`
} `ini:"repository.signing"`
}{
DetectedCharsetsOrder: []string{
@@ -242,20 +244,24 @@ var (
SigningKey string
SigningName string
SigningEmail string
+ SigningFormat string
InitialCommit []string
CRUDActions []string `ini:"CRUD_ACTIONS"`
Merges []string
Wiki []string
DefaultTrustModel string
+ TrustedSSHKeys []string `ini:"TRUSTED_SSH_KEYS"`
}{
SigningKey: "default",
SigningName: "",
SigningEmail: "",
+ SigningFormat: "openpgp", // git.SigningKeyFormatOpenPGP
InitialCommit: []string{"always"},
CRUDActions: []string{"pubkey", "twofa", "parentsigned"},
Merges: []string{"pubkey", "twofa", "basesigned", "commitssigned"},
Wiki: []string{"never"},
DefaultTrustModel: "collaborator",
+ TrustedSSHKeys: []string{},
},
}
RepoRootPath string
diff --git a/modules/templates/static.go b/modules/templates/static.go
deleted file mode 100644
index b5a7e561ec..0000000000
--- a/modules/templates/static.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2016 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build bindata
-
-package templates
-
-import (
- "time"
-
- "code.gitea.io/gitea/modules/assetfs"
- "code.gitea.io/gitea/modules/timeutil"
-)
-
-// GlobalModTime provide a global mod time for embedded asset files
-func GlobalModTime(filename string) time.Time {
- return timeutil.GetExecutableModTime()
-}
-
-func BuiltinAssets() *assetfs.Layer {
- return assetfs.Bindata("builtin(bindata)", Assets)
-}
diff --git a/modules/templates/templates_bindata.go b/modules/templates/templates_bindata.go
index 6f1d3cf539..a919591ecf 100644
--- a/modules/templates/templates_bindata.go
+++ b/modules/templates/templates_bindata.go
@@ -3,6 +3,21 @@
//go:build bindata
+//go:generate go run ../../build/generate-bindata.go ../../templates bindata.dat
+
package templates
-//go:generate go run ../../build/generate-bindata.go ../../templates templates bindata.go true
+import (
+ "sync"
+
+ _ "embed"
+
+ "code.gitea.io/gitea/modules/assetfs"
+)
+
+//go:embed bindata.dat
+var bindata []byte
+
+var BuiltinAssets = sync.OnceValue(func() *assetfs.Layer {
+ return assetfs.Bindata("builtin(bindata)", assetfs.NewEmbeddedFS(bindata))
+})
diff --git a/modules/templates/dynamic.go b/modules/templates/templates_dynamic.go
index e1babd83c9..e1babd83c9 100644
--- a/modules/templates/dynamic.go
+++ b/modules/templates/templates_dynamic.go
diff --git a/modules/timeutil/executable.go b/modules/timeutil/executable.go
deleted file mode 100644
index 57ae8b2a9d..0000000000
--- a/modules/timeutil/executable.go
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2022 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package timeutil
-
-import (
- "os"
- "path/filepath"
- "sync"
- "time"
-
- "code.gitea.io/gitea/modules/log"
-)
-
-var (
- executablModTime = time.Now()
- executablModTimeOnce sync.Once
-)
-
-// GetExecutableModTime get executable file modified time of current process.
-func GetExecutableModTime() time.Time {
- executablModTimeOnce.Do(func() {
- exePath, err := os.Executable()
- if err != nil {
- log.Error("os.Executable: %v", err)
- return
- }
-
- exePath, err = filepath.Abs(exePath)
- if err != nil {
- log.Error("filepath.Abs: %v", err)
- return
- }
-
- exePath, err = filepath.EvalSymlinks(exePath)
- if err != nil {
- log.Error("filepath.EvalSymlinks: %v", err)
- return
- }
-
- st, err := os.Stat(exePath)
- if err != nil {
- log.Error("os.Stat: %v", err)
- return
- }
-
- executablModTime = st.ModTime()
- })
- return executablModTime
-}
diff --git a/modules/zstd/zstd_test.go b/modules/zstd/zstd_test.go
index c3ca8e78f7..7fd30484ca 100644
--- a/modules/zstd/zstd_test.go
+++ b/modules/zstd/zstd_test.go
@@ -16,7 +16,7 @@ import (
)
func TestWriterReader(t *testing.T) {
- testData := prepareTestData(t, 20_000_000)
+ testData := prepareTestData(t, 1_000_000)
result := bytes.NewBuffer(nil)
@@ -64,7 +64,7 @@ func TestWriterReader(t *testing.T) {
}
func TestSeekableWriterReader(t *testing.T) {
- testData := prepareTestData(t, 20_000_000)
+ testData := prepareTestData(t, 2_000_000)
result := bytes.NewBuffer(nil)
@@ -109,7 +109,7 @@ func TestSeekableWriterReader(t *testing.T) {
reader, err := NewSeekableReader(assertReader)
require.NoError(t, err)
- _, err = reader.Seek(10_000_000, io.SeekStart)
+ _, err = reader.Seek(1_000_000, io.SeekStart)
require.NoError(t, err)
data := make([]byte, 1000)
@@ -117,7 +117,7 @@ func TestSeekableWriterReader(t *testing.T) {
require.NoError(t, err)
require.NoError(t, reader.Close())
- assert.Equal(t, testData[10_000_000:10_000_000+1000], data)
+ assert.Equal(t, testData[1_000_000:1_000_000+1000], data)
// Should seek 3 times,
// the first two times are for getting the index,
diff --git a/options/locale/locale_ga-IE.ini b/options/locale/locale_ga-IE.ini
index 79df1d26d0..3804339585 100644
--- a/options/locale/locale_ga-IE.ini
+++ b/options/locale/locale_ga-IE.ini
@@ -1652,6 +1652,7 @@ issues.save=Sábháil
issues.label_title=Ainm
issues.label_description=Cur síos
issues.label_color=Dath
+issues.label_color_invalid=Dath neamhbhailí
issues.label_exclusive=Eisiach
issues.label_archive=Lipéad Cartlann
issues.label_archived_filter=Taispeáin lipéid cartlainne
diff --git a/options/locale/locale_uk-UA.ini b/options/locale/locale_uk-UA.ini
index da38ca30b0..a73322bc2a 100644
--- a/options/locale/locale_uk-UA.ini
+++ b/options/locale/locale_uk-UA.ini
@@ -31,7 +31,7 @@ username=Ім'Ñ ÐºÑ€Ð¸Ñтувача
email=ÐдреÑа електронної пошти
password=Пароль
access_token=Токен доÑтупу
-re_type=ÐŸÑ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ
+re_type=Підтвердити пароль
captcha=CAPTCHA
twofa=Двофакторна автентифікаціÑ
twofa_scratch=Двофакторний одноразовий пароль
@@ -287,48 +287,48 @@ register_confirm=Вимагати Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ ÐµÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð
mail_notify=Увімкнути ÑÐ¿Ð¾Ð²Ñ–Ñ‰ÐµÐ½Ð½Ñ ÐµÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð¾ÑŽ поштою
server_service_title=ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñервера Ñ– Ñторонніх ÑервіÑів
offline_mode=Увімкнути локальний режим
-offline_mode_popup=Відключити Ñторонні мережі доÑтавки контенту Ñ– обÑлуговувати вÑÑ– реÑурÑи локально.
+offline_mode_popup=Вимкнути Ñторонні мережі доÑтавки контенту та обÑлуговувати вÑÑ– реÑурÑи локально.
disable_gravatar=Вимкнути Gravatar
-disable_gravatar_popup=Відключити Gravatar Ñ– Ñторонні джерела аватарів. Якщо кориÑтувач не завантажить аватар локально то за замовчуваннÑм буде викориÑтовуватиÑÑ Ñтандартний аватар.
-federated_avatar_lookup=Увімкнути федеративні аватари
-federated_avatar_lookup_popup=Увімкнути зовнішний Ðватар за допомогою Libravatar.
-disable_registration=Вимкнути ÑамоÑтійну реєÑтрацію
-disable_registration_popup=Вимкнути ÑамоÑтійну реєÑтрацію кориÑтувачів, тільки адмініÑтратор може Ñтворювати нові облікові запиÑи.
+disable_gravatar_popup=Вимкнути Gravatar та Ñторонні джерела аватарок. Якщо кориÑтувач локально не завантажить аватар, буде викориÑтовуватиÑÑ Ñ‚Ð¸Ð¿Ð¾Ð²Ð¸Ð¹ аватар.
+federated_avatar_lookup=Увімкнути зовнішні аватари
+federated_avatar_lookup_popup=Увімкнути пошук об'єднаних аватарів за допомогою Libravatar.
+disable_registration=Вимкнути реєÑтрацію
+disable_registration_popup=Вимкнути реєÑтрацію кориÑтувачів, тільки адмініÑтратор може Ñтворювати нові облікові запиÑи.
allow_only_external_registration_popup=Дозволити реєÑтрацію тільки через Ñторонні ÑервіÑи
-openid_signin=Увімкнути реєÑтрацію за допомогою OpenID
-openid_signin_popup=Увімкнути вхід за допомогою OpenID.
+openid_signin=Увімкнути вхід за допомогою OpenID
+openid_signin_popup=Увімкнути вхід кориÑтувачів за допомогою OpenID.
openid_signup=Увімкнути ÑамоÑтійну реєÑтрацію за допомогою OpenID
openid_signup_popup=Увімкнути ÑамореєÑтрацію кориÑтувачів на оÑнові OpenID.
-enable_captcha=Увімкнути CAPTCHA при реєÑтрації
-enable_captcha_popup=Вимагати перевірку CAPTCHA при ÑамоÑтійній реєÑтрації кориÑтувача.
+enable_captcha=Увімкнути CAPTCHA Ð´Ð»Ñ Ñ€ÐµÑ”Ñтрації
+enable_captcha_popup=Вимагати CAPTCHA Ð´Ð»Ñ ÑамореєÑтрації кориÑтувачів.
require_sign_in_view=Вимагати авторизації Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ³Ð»Ñду Ñторінок
admin_setting_desc=Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ запиÑу адмініÑтратора необов'Ñзково. Перший зареєÑтрований кориÑтувач автоматично Ñтає адмініÑтратором.
admin_title=ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ запиÑу адмініÑтратора
admin_name=Ім'Ñ ÐºÑ€Ð¸Ñтувача ÐдмініÑтратора
admin_password=Пароль
-confirm_password=ÐŸÑ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ
+confirm_password=Підтвердити пароль
admin_email=ÐдреÑа електронної пошти
-install_btn_confirm=Ð’ÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Gitea
-test_git_failed=Ðе в змозі перевірити 'git' команду: %v
+install_btn_confirm=Ð’Ñтановити Gitea
+test_git_failed=Ðе вдалоÑÑ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€Ð¸Ñ‚Ð¸ команду 'git': %v
sqlite3_not_available=Ð¦Ñ Ð²ÐµÑ€ÑÑ–Ñ Gitea не підтримує SQLite3. Будь лаÑка, завантажте офіційну бінарну верÑÑ–ÑŽ з %s (не верÑÑ–ÑŽ gobuild).
-invalid_db_setting=ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð±Ð°Ð·Ð¸ даних Ñ” некоректними: %v
-invalid_db_table=Ð¢Ð°Ð±Ð»Ð¸Ñ†Ñ '%s' бази даних Ñ” недійÑною: %v
-invalid_repo_path=Помилковий шлÑÑ… до ÐºÐ¾Ñ€ÐµÐ½Ñ Ñ€ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ñ–ÑŽ: %v
-invalid_app_data_path=Ðекоректний шлÑÑ… до даних програми: %v
-run_user_not_match=Ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача 'run as' не Ñ” поточним ім'Ñм кориÑтувача: %s -> %s
-internal_token_failed=Ðе вдалоÑÑ Ð·Ð³ÐµÐ½ÐµÑ€ÑƒÐ²Ð°Ñ‚Ð¸ внутрішній токен: %v
-secret_key_failed=Ðе вдалоÑÑ Ð·Ð³ÐµÐ½ÐµÑ€ÑƒÐ²Ð°Ñ‚Ð¸ Ñекретний ключ: %v
-save_config_failed=Ðе в змозі зберегти конфігурацію: %v
-invalid_admin_setting=ÐеприпуÑтимі Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ запиÑу адмініÑтратора: %v
-invalid_log_root_path=ÐеприпуÑтимий шлÑÑ… Ð´Ð»Ñ Ð»Ð¾Ð³Ñ–Ð²: %v
-default_keep_email_private=Приховати адреÑу електронної пошти за замовчуваннÑм
-default_keep_email_private_popup=Приховати адреÑу електронної пошти нових облікових запиÑів за замовчуваннÑм.
-default_allow_create_organization=Дозволити ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¾Ñ€Ð³Ð°Ð½Ñ–Ð·Ð°Ñ†Ñ–Ð¹ за замовчуваннÑм
-default_allow_create_organization_popup=Дозволити новим обліковим запиÑам кориÑтувачів Ñтворювати організації за замовчуваннÑм.
-default_enable_timetracking=Увімкнути відÑÑ‚ÐµÐ¶ÐµÐ½Ð½Ñ Ñ‡Ð°Ñу за замовчуваннÑм
-default_enable_timetracking_popup=Включити відÑÑ‚ÐµÐ¶ÐµÐ½Ð½Ñ Ñ‡Ð°Ñу Ð´Ð»Ñ Ð½Ð¾Ð²Ð¸Ñ… репозиторіїв за замовчуваннÑм.
+invalid_db_setting=ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð±Ð°Ð·Ð¸ даних недійÑні: %v
+invalid_db_table=База даних таблиці "%s" Ñ” недійÑною: %v
+invalid_repo_path=Кореневий шлÑÑ… до Ñховища невірний: %v
+invalid_app_data_path=ШлÑÑ… до даних додатка невірний: %v
+run_user_not_match=Ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача “Виконати Ñк†не Ñ” поточним ім'Ñм кориÑтувача: %s -> %s
+internal_token_failed=Ðе вдалоÑÑ Ñтворити внутрішній токен: %v
+secret_key_failed=Ðе вдалоÑÑ Ñтворити Ñекретний ключ: %v
+save_config_failed=Ðе вдалоÑÑ Ð·Ð±ÐµÑ€ÐµÐ³Ñ‚Ð¸ конфігурацію: %v
+invalid_admin_setting=ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ запиÑу адмініÑтратора Ñ” недійÑним: %v
+invalid_log_root_path=Ðеправильний шлÑÑ… до журналу: %v
+default_keep_email_private=Типово приховувати адреÑи електронної пошти
+default_keep_email_private_popup=Типово приховувати адреÑи електронної пошти нових облікових запиÑів.
+default_allow_create_organization=За замовчуваннÑм дозволити ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¾Ñ€Ð³Ð°Ð½Ñ–Ð·Ð°Ñ†Ñ–Ð¹
+default_allow_create_organization_popup=За замовчуваннÑм дозволити новим кориÑтувачам Ñтворювати організації.
+default_enable_timetracking=За замовчуваннÑм увімкнути відÑÑ‚ÐµÐ¶ÐµÐ½Ð½Ñ Ñ‡Ð°Ñу
+default_enable_timetracking_popup=Увімкнути відÑÑ‚ÐµÐ¶ÐµÐ½Ð½Ñ Ñ‡Ð°Ñу Ð´Ð»Ñ Ð½Ð¾Ð²Ð¸Ñ… Ñховищ за замовчуваннÑм.
no_reply_address=Прихований поштовий домен
-no_reply_address_helper=Доменне ім'Ñ Ð´Ð»Ñ ÐºÐ¾Ñ€Ð¸Ñтувачів із прихованою електронною адреÑою. Ðаприклад, ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача 'joe' буде входити в Git Ñк 'joe@noreply.example.org', Ñкщо Ð´Ð»Ñ Ð¿Ñ€Ð¸Ñ…Ð¾Ð²Ð°Ð½Ð¾Ð³Ð¾ домену електронної пошти вÑтановлено 'noreply.example.org'.
+no_reply_address_helper=Доменне ім'Ñ Ð´Ð»Ñ ÐºÐ¾Ñ€Ð¸Ñтувачів із прихованою електронною адреÑою. Ðаприклад, ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача 'Joe' буде зображатиÑÑ Ð² Git Ñк 'joe@noreply.example.org', Ñкщо прихований домен електронної пошти вÑтановлено 'noreply.example.org'.
password_algorithm=Ðлгоритм Ñ…ÐµÑˆÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ
invalid_password_algorithm=ÐедійÑний хеш-алгоритм паролÑ
enable_update_checker=Увімкнути перевірку оновлень
@@ -338,35 +338,35 @@ config_write_file_prompt=Ці параметри будуть запиÑані Ð
[home]
nav_menu=Меню навігації
-uname_holder=Ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача або Ел. пошта
+uname_holder=Ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача або адреÑа електронної пошти
password_holder=Пароль
switch_dashboard_context=Переключити контекÑÑ‚ панелі управліннÑ
-my_repos=Репозиторії
-show_more_repos=Показати більше репозиторіїв…
-collaborative_repos=Спільні репозиторії
+my_repos=Сховища
+show_more_repos=Показати більше Ñховищ…
+collaborative_repos=Спільні Ñховища
my_orgs=Мої організації
my_mirrors=Мої дзеркала
view_home=ПереглÑнути %s
filter=Інші фільтри
-filter_by_team_repositories=Фільтрувати за репозиторіÑми команд
+filter_by_team_repositories=Фільтрувати за Ñховищами команд
feed_of=`Стрічка "%s"`
show_archived=Ðрхівовані
-show_both_archived_unarchived=Показано архівовані і не архівовані
+show_both_archived_unarchived=Показано архівовані і неархівовані
show_only_archived=Показано тільки архівовані
-show_only_unarchived=Показано тільки не архівовані
+show_only_unarchived=Показано тільки неархівовані
show_private=Приватні
show_both_private_public=Показано публічні та приватні
show_only_private=Показано тільки приватні
show_only_public=Показано тільки публічні
-issues.in_your_repos=Ð’ ваших репозиторіÑÑ…
+issues.in_your_repos=У ваших Ñховищах
guide_title=Жодної активноÑті
[explore]
-repos=Репозиторії
+repos=Сховища
users=КориÑтувачі
organizations=Організації
code=Код
@@ -374,100 +374,100 @@ code_last_indexed_at=ОÑтанні індекÑовані %s
[auth]
create_new_account=РеєÑÑ‚Ñ€Ð°Ñ†Ñ–Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ запиÑу
-disable_register_prompt=Вибачте, можливіÑть реєÑтрації відключена. Будь лаÑка, зв'ÑжітьÑÑ Ð· адмініÑтратором Ñайту.
+disable_register_prompt=РеєÑтрацію вимкнено. Будь лаÑка, зв'ÑжітьÑÑ Ð· адмініÑтратором Ñайту.
disable_register_mail=ÐŸÑ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ñ€ÐµÑ”Ñтрації електронною поштою вимкнено.
remember_me=Запам’Ñтати цей приÑтрій
forgot_password_title=Забув пароль
forgot_password=Забули пароль?
-must_change_password=Оновіть Ñвій пароль
-allow_password_change=Вимагати в кориÑтувача змінити пароль (рекомендуєтьÑÑ)
-reset_password_mail_sent_prompt=Електронний лиÑÑ‚ із підтвердженнÑм надіÑлано <b>%s</b>. Перевірте папку 'Вхідні' в межах наÑтупних %s, щоб завершити Ð¿Ñ€Ð¾Ñ†ÐµÑ Ð²Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ запиÑу.
+must_change_password=Оновити пароль
+allow_password_change=Вимагати від кориÑтувача змінити пароль (рекомендовано)
+reset_password_mail_sent_prompt=Ðа адреÑу <b>%s</b> було надіÑлано лиÑÑ‚ із підтвердженнÑм. Будь лаÑка, перевірте Ñвою поштову Ñкриньку протÑгом наÑтупних %s, щоб завершити Ð¿Ñ€Ð¾Ñ†ÐµÑ Ð²Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ запиÑу.
active_your_account=Ðктивувати обліковий запиÑ
account_activated=Обліковий Ð·Ð°Ð¿Ð¸Ñ Ð°ÐºÑ‚Ð¸Ð²Ð¾Ð²Ð°Ð½Ð¾
-prohibit_login=Вхід заборонений
-resent_limit_prompt=Вибачте, ви вже запроÑили активацію по електронній пошті нещодавно. Будь лаÑка, зачекайте 3 хвилини, а потім Ñпробуйте ще раз.
-has_unconfirmed_mail=Привіт %s, у Ð²Ð°Ñ Ñ” непідтверджена електронна адреÑа (<b>%s </b>). Якщо ви не отримали електронний лиÑÑ‚ із підтвердженнÑм або вам потрібно надіÑлати новий, натиÑніть на кнопку нижче.
-resend_mail=ÐатиÑніть тут, щоб виÑлати лиÑÑ‚ активації знову
-email_not_associate=Ð¦Ñ ÐµÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð° пошта не пов'Ñзана ні з одним обліковим запиÑом.
-send_reset_mail=ÐадіÑлати електронний лиÑÑ‚ Ð´Ð»Ñ Ð²Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ запиÑу
+prohibit_login=Вхід заборонено
+resent_limit_prompt=Ви вже надÑилали запит на активацію нещодавно. Зачекайте 3 хвилини Ñ– Ñпробуйте ще раз.
+has_unconfirmed_mail=
+Привіт %s, у Ð²Ð°Ñ Ð½ÐµÐ¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð° адреÑа електронної пошти (<b>%s</b>). Якщо ви не отримали лиÑта з підтвердженнÑм або вам потрібно надіÑлати новий, будь лаÑка, натиÑніть кнопку нижче.
+resend_mail=ÐатиÑніть тут, щоб повторно надіÑлати лиÑÑ‚ з активацією
+email_not_associate=Ð¦Ñ Ð°Ð´Ñ€ÐµÑа електронної пошти не пов'Ñзана з жодним обліковим запиÑом.
+send_reset_mail=ÐадіÑлати лиÑÑ‚ Ð´Ð»Ñ Ð²Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ запиÑу
reset_password=Ð’Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ запиÑу
-invalid_code=Цей код Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ð½ÐµÐ´Ñ–Ð¹Ñний або закінчивÑÑ.
+invalid_code=Ваш код Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ð½ÐµÐ´Ñ–Ð¹Ñний або його термін дії закінчивÑÑ.
reset_password_helper=Відновити обліковий запиÑ
password_too_short=Довжина Ð¿Ð°Ñ€Ð¾Ð»Ñ Ð½Ðµ може бути меншою за %d Ñимволів.
-non_local_account=Ðелокальні акаунти не можуть змінити пароль через Gitea.
+non_local_account=Ðелокальні кориÑтувачі не можуть оновити Ñвій пароль через Ð²ÐµÐ±Ñ–Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Gitea.
verify=Підтвердити
scratch_code=Одноразовий пароль
-use_scratch_code=ВикориÑтовувати одноразовий пароль
-twofa_scratch_used=Ви викориÑтовували одноразовий пароль. Ви були перенаправлені на Ñторінку налаштувань Ð´Ð»Ñ Ð³ÐµÐ½ÐµÑ€Ð°Ñ†Ñ–Ñ— нового коду або Ð²Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ð´Ð²ÑƒÑ„Ð°ÐºÑ‚Ð¾Ñ€Ð½Ð¾Ñ— автентифікації.
-twofa_passcode_incorrect=Ваш пароль Ñ” невірним. Якщо ви втратили приÑтрій, викориÑтовуйте ваш одноразовий пароль.
+use_scratch_code=СкориÑтатиÑÑŒ одноразовим паролем
+twofa_scratch_used=Ви ÑкориÑталиÑÑ Ð¾Ð´Ð½Ð¾Ñ€Ð°Ð·Ð¾Ð²Ð¸Ð¼ паролем. Ð’Ð°Ñ Ð¿ÐµÑ€ÐµÐ½Ð°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¾ на Ñторінку налаштувань двофакторної автентифікації, щоб видалити приÑтрій або згенерувати новий одноразовий пароль.
+twofa_passcode_incorrect=Ваш пароль неправильний. Якщо ви загубили Ñвій приÑтрій, ÑкориÑтайтеÑÑ Ð¾Ð´Ð½Ð¾Ñ€Ð°Ð·Ð¾Ð²Ð¸Ð¼ паролем.
twofa_scratch_token_incorrect=Ðевірний одноразовий пароль.
login_userpass=Увійти
login_openid=OpenID
oauth_signup_tab=ЗареєÑтрувати обліковий запиÑ
-oauth_signup_title=Повний новий обліковий запиÑ
-oauth_signup_submit=Повний обліковий запиÑ
-oauth_signin_tab=ПоÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° Ñ–Ñнуючий обліковий запиÑ
+oauth_signup_title=Завершити реєÑтрацію облікового запиÑу
+oauth_signup_submit=Поповнити обліковий запиÑ
+oauth_signin_tab=Прив'Ñзати до Ñ–Ñнуючого облікового запиÑу
oauth_signin_title=Увійдіть щоб авторизувати пов'Ñзаний обліковий запиÑ
oauth_signin_submit=Прив'Ñзати обліковий запиÑ
openid_connect_submit=Під’єднатиÑÑ
openid_connect_title=ПідключитиÑÑ Ð´Ð¾ Ñ–Ñнуючого облікового запиÑу
-openid_connect_desc=Вибраний OpenID URI невідомий. Пов'Ñжіть його з новим обліковим запиÑом тут.
+openid_connect_desc=Обраний OpenID URI невідомий. Зв'Ñжіть його тут з новим обліковим запиÑом.
openid_register_title=Створити новий обліковий запиÑ
-openid_register_desc=Вибраний OpenID URI невідомий. Пов'Ñжіть йогоз новим обліковим запиÑом тут.
+openid_register_desc=Обраний OpenID URI невідомий. Зв'Ñжіть його тут з новим обліковим запиÑом.
disable_forgot_password_mail=Ð’Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ запиÑу вимкнено, оÑкільки не налаштована електронна пошта. Будь лаÑка, зв'ÑжітьÑÑ Ð· адмініÑтратором Ñайту.
-disable_forgot_password_mail_admin=Ð’Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ запиÑу доÑтупне лише піÑÐ»Ñ Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÐµÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð¾Ñ— пошти. Будь лаÑка, налаштуйте ел. пошту Ð´Ð»Ñ Ð²Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ запиÑу.
-email_domain_blacklisted=З вказаним email реєÑÑ‚Ñ€Ð°Ñ†Ñ–Ñ Ð½ÐµÐ¼Ð¾Ð¶Ð»Ð¸Ð²Ð°.
+disable_forgot_password_mail_admin=Ð’Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ запиÑу доÑтупне лише за наÑвноÑті електронної пошти. Будь лаÑка, налаштуйте електронну пошту, щоб увімкнути Ð²Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ запиÑу.
+email_domain_blacklisted=Ви не можете зареєÑтруватиÑÑ Ð· адреÑою електронної пошти.
authorize_application=Ðвторизувати програму
authorize_redirect_notice=Ð’Ð°Ñ Ð±ÑƒÐ´Ðµ переадреÑовано до %s, Ñкщо ви авторизуєте цю програму.
authorize_application_created_by=Ð¦Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð° Ñтворена %s.
-authorize_application_description=Якщо ви надаÑте цей доÑтуп, то він матиме доÑтуп до вÑÑ–Ñ… ваших даних облікового запиÑу, включаючи приватні репозиторії та організації.
-authorize_title=Ðвторизуйвати "%s" Ð´Ð»Ñ Ð´Ð¾Ñтупу до вашого облікового запиÑу?
+authorize_application_description=Якщо ви авторизуєте цю програму, їй буде надано дозвіл на Ñ€ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ð½Ð½Ñ Ð°Ð±Ð¾ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð²Ñієї інформації вашого облікового запиÑу, включно з приватними Ñховищами та організаціÑми.
+authorize_title=Ðвторизувати "%s" Ð´Ð»Ñ Ð´Ð¾Ñтупу до вашого облікового запиÑу?
authorization_failed=Помилка авторизації
-sspi_auth_failed=Помилка SSPI-автентифікації
+sspi_auth_failed=Помилка автентифікації SSPI
password_pwned_err=Ðе вдалоÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ‚Ð¸ запит до HaveIBeenPwed
[mail]
view_it_on=ПереглÑнути на %s
reply=або надішліть відповідь безпоÑередньо на цей електронний лиÑÑ‚
-link_not_working_do_paste=Ðе працює? Спробуйте Ñкопіювати та вÑтавити його в Ñвій браузер.
+link_not_working_do_paste=Ðе працює? Спробуйте Ñкопіювати та вÑтавити його у браузер.
hi_user_x=Привіт <b>%s</b>,
activate_account=Будь лаÑка, активуйте ваш обліковий запиÑ
activate_account.title=%s, будь лаÑка, активуйте Ñвій обліковий запиÑ
activate_account.text_1=Привіт, <b>%[1]s</b>, дÑкуємо за реєÑтрацію на %[2]s!
-activate_account.text_2=Перейдіть за цим поÑиланнÑм, щоб активувати ваш обліковий Ð·Ð°Ð¿Ð¸Ñ Ð² <b>%s</b>:
+activate_account.text_2=Будь лаÑка, перейдіть за наÑтупним поÑиланнÑм, щоб активувати Ñвій обліковий Ð·Ð°Ð¿Ð¸Ñ Ð¿Ñ€Ð¾Ñ‚Ñгом <b>%s</b>:
-activate_email=Підтвердить вашу адреÑу електронної пошти
+activate_email=Підтвердіть адреÑу електронної пошти
activate_email.title=%s, будь лаÑка, підтвердіть вашу адреÑу електронної пошти
-activate_email.text=Перейдіть за цим поÑиланнÑм, щоб підтвердити вашу електронну адреÑу в <b>%s</b>:
+activate_email.text=Будь лаÑка, перейдіть за наÑтупним поÑиланнÑм протÑгом <b>%s</b>, щоб підтвердити Ñвою електронну адреÑу:
register_notify.title=%[1]s, лаÑкаво проÑимо до %[2]s
-register_notify.text_1=це ваша е-пошта Ð´Ð»Ñ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ñ€ÐµÑ”Ñтрації Ð´Ð»Ñ %s!
+register_notify.text_1=це лиÑÑ‚ з підтвердженнÑм реєÑтрації на %s!
register_notify.text_2=Тепер ви можете увійти Ñк: %s.
-register_notify.text_3=Якщо цей обліковий Ð·Ð°Ð¿Ð¸Ñ Ð±ÑƒÐ»Ð¾ Ñтворено Ð´Ð»Ñ Ð²Ð°Ñ, будь лаÑка, Ñпочатку <a href="%s">вÑтановіть Ñвій пароль</a>.
+register_notify.text_3=Якщо цей обліковий Ð·Ð°Ð¿Ð¸Ñ Ñтворено Ð´Ð»Ñ Ð²Ð°Ñ, будь лаÑка, Ñпершу <a href="%s">вÑтановіть пароль</a>.
-reset_password=Ð’Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð²Ð°ÑˆÐ¾Ð³Ð¾ облікового запиÑу
-reset_password.title=%s, ви відправили запит на Ð²Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ запиÑу
-reset_password.text=Перейдіть за цим поÑиланнÑм, щоб відновити ваш обліковий Ð·Ð°Ð¿Ð¸Ñ Ð² <b>%s</b>:
+reset_password=Відновити обліковий запиÑ
+reset_password.title=%s, ви надіÑлали запит на Ð²Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ запиÑу
+reset_password.text=Щоб відновити обліковий запиÑ, перейдіть за наÑтупним поÑиланнÑм протÑгом <b>%s</b>:
register_success=РеєÑÑ‚Ñ€Ð°Ñ†Ñ–Ñ ÑƒÑпішна
-issue_assigned.pull=@%[1]s призначив вам запит Ð·Ð»Ð¸Ñ‚Ñ‚Ñ %[2]s в репозиторії %[3]s.
-issue_assigned.issue=@%[1]s призначив вам задачу %[2]s у репозиторії %[3]s.
+issue_assigned.pull=@%[1]s призначив вам запит на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ %[2]s в Ñховищі %[3]s.
+issue_assigned.issue=@%[1]s призначив вам задачу %[2]s в Ñховищі %[3]s.
issue.x_mentioned_you=<b>@%s</b> згадав ваÑ:
-issue.action.force_push=<b>%[1]s</b> force-pushed <b>%[2]s</b> з %[3]s в %[4]s.
-issue.action.push_1=<b>@%[1]s</b> надіÑлав %[3]d коміти %[2]s
-issue.action.push_n=<b>@%[1]s</b> відправив %[3]d коміти до %[2]s
-issue.action.close=<b>@%[1]s</b> закрито #%[2]d.
+issue.action.push_1=<b>@%[1]s</b> надіÑлав %[3]d коміт в %[2]s
+issue.action.push_n=<b>@%[1]s</b> надіÑлав %[3]d коміти до %[2]s
+issue.action.close=<b>@%[1]s</b> закрив #%[2]d.
issue.action.reopen=<b>@%[1]s</b> заново відкрив #%[2]d.
issue.action.merge=<b>@%[1]s</b> об'єднав #%[2]d до %[3]s.
-issue.action.approve=<b>@%[1]s</b> затвердили цей запит на злиттÑ.
-issue.action.reject=<b>@%[1]s</b> запитують зміни на цей запит на злиттÑ.
-issue.action.review=<b>@%[1]s</b> прокоментували цей запит на злиттÑ.
-issue.action.review_dismissed=<b>@%[1]s</b> відхилено оÑтанній відгук від %[2]s Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ запиту на злиттÑ.
-issue.action.ready_for_review=<b>@%[1]s</b> позначили цей запит на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ñк готовий до розглÑду.
-issue.action.new=<b>@%[1]s</b> Ñтворили #%[2]d.
+issue.action.approve=<b>@%[1]s</b> затвердив цей запит на злиттÑ.
+issue.action.reject=<b>@%[1]s</b> запроÑив зміни у цьому запиті на злиттÑ.
+issue.action.review=<b>@%[1]s</b> прокоментував цей запит на злиттÑ.
+issue.action.review_dismissed=<b>@%[1]s</b> відхилив оÑтанній відгук від %[2]s на цей запит на злиттÑ.
+issue.action.ready_for_review=<b>@%[1]s</b> позначив цей запит на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ñк готовий до розглÑду.
+issue.action.new=<b>@%[1]s</b> Ñтворив #%[2]d.
issue.in_tree_path=Ð’ %s:
release.new.subject=%s в %s випущено
@@ -478,13 +478,13 @@ release.downloads=ЗвантаженнÑ:
release.download.zip=Вихідний код (ZIP)
release.download.targz=Вихідний код (TAR.GZ)
-repo.transfer.subject_to=%s бажає передати"%s" в %s
-repo.transfer.subject_to_you=%s бажає передати"%s" вам
+repo.transfer.subject_to=%s хоче перенеÑти "%s" в %s
+repo.transfer.subject_to_you=%s хоче передати"%s" вам
repo.transfer.to_you=вам
repo.transfer.body=Щоб прийнÑти або відхилити перейдіть до %s або проÑто ігноруйте.
repo.collaborator.added.subject=%s додав Ð²Ð°Ñ Ð´Ð¾ %s
-repo.collaborator.added.text=Ви були додані в ÑкоÑті Ñпівавтора репозиторію:
+repo.collaborator.added.text=Ð’Ð°Ñ Ð´Ð¾Ð´Ð°Ð»Ð¸ Ñк Ñпівавтора до Ñховища:
team_invite.subject=%[1]s запрошує Ð²Ð°Ñ Ð¿Ñ€Ð¸Ñ”Ð´Ð½Ð°Ñ‚Ð¸ÑÑ Ð´Ð¾ організації %[2]s
team_invite.text_1=%[1]s запрошує Ð²Ð°Ñ Ð´Ð¾ команди %[2]s в організації %[3]s.
@@ -495,22 +495,22 @@ yes=Так
no=ÐÑ–
confirm=Підтвердити
cancel=Відмінити
-modify=ОновленнÑ
+modify=Оновити
[form]
UserName=Ð†Ð¼â€™Ñ ÐºÐ¾Ñ€Ð¸Ñтувача
-RepoName=Ðазва репозиторію
+RepoName=Ðазва Ñховища
Email=ÐдреÑа електронної пошти
Password=Пароль
-Retype=ÐŸÑ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ
-SSHTitle=Iм'Ñ SSH ключа
+Retype=Підтвердити пароль
+SSHTitle=Ðазва ключа SSH
HttpsUrl=ÐдреÑа HTTPS
PayloadUrl=URL обробника
TeamName=Ðазва команди
AuthName=Ðазва авторизації
-AdminEmail=Email адмініÑтратора
+AdminEmail=ÐдреÑа електронної пошти адмініÑтратора
-NewBranchName=Ім'Ñ Ð½Ð¾Ð²Ð¾Ñ— гілки
+NewBranchName=Ðазва нової гілки
CommitSummary=Резюме коміту
CommitMessage=ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ ÐºÐ¾Ð¼Ñ–Ñ‚Ñƒ
CommitChoice=Вибір коміта
@@ -520,58 +520,58 @@ Content=ЗміÑÑ‚
SSPISeparatorReplacement=Розділювач
SSPIDefaultLanguage=Типова мова
-require_error=` не може бути пуÑтим.`
-alpha_dash_error=` повинен міÑтити тільки літерно-цифрові Ñимволи, Ð´ÐµÑ„Ñ–Ñ ('-') та підкреÑÐ»ÐµÐ½Ð½Ñ ('_'). `
-alpha_dash_dot_error=` повинен міÑтити тільки літерно-цифрові Ñимволи, Ð´ÐµÑ„Ñ–Ñ ('-') , підкреÑÐ»ÐµÐ½Ð½Ñ ('_') та точки ('.'). `
-git_ref_name_error=` повинен бути правильним поÑилальним ім'Ñм Git.`
+require_error=` не може бути порожнім.`
+alpha_dash_error=` повинен міÑтити тільки алфавітно-цифрові Ñимволи, Ð´ÐµÑ„Ñ–Ñ ('-') та підкреÑÐ»ÐµÐ½Ð½Ñ ('_').`
+alpha_dash_dot_error=` повинен міÑтити тільки алфавітно-цифрові Ñимволи, Ð´ÐµÑ„Ñ–Ñ ('-'), підкреÑÐ»ÐµÐ½Ð½Ñ ('_') та крапку ('.').`
+git_ref_name_error=` повинен бути правильно Ñформованим ім'Ñм-поÑиланнÑм на Git.`
size_error=` повинен бути розмір %s.`
-min_size_error=` повинен бути принаймні %s Ñимволів.`
-max_size_error=` повинен бути не більш Ñк %s Ñимволів.`
-email_error=` не Ñ” адреÑою електронної пошти.`
+min_size_error=` має міÑтити принаймні %s Ñимволів.`
+max_size_error=` має міÑтити не більше %s Ñимволів.`
+email_error=` не Ñ” дійÑною адреÑою електронної пошти.`
url_error=`"%s" не Ñ” дійÑною URL-адреÑою.`
include_error=` повинен міÑтити підрÑдок "%s".`
-glob_pattern_error=` неприпуÑтимий шаблон glob: %s.`
-regex_pattern_error=` неприпуÑтимий шаблон regex: %s.`
+glob_pattern_error=` недійÑний шаблон glob: %s.`
+regex_pattern_error=` недійÑний шаблон регулÑрного виразу: %s.`
unknown_error=Ðевідома помилка:
captcha_incorrect=Код CAPTCHA неправильний.
-password_not_match=Паролі не Ñпівпадають.
-lang_select_error=Оберіть мову з переліку.
+password_not_match=Паролі не збігаютьÑÑ.
+lang_select_error=Оберіть мову зі ÑпиÑку.
-username_been_taken=Ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача вже зайнÑто.
-username_change_not_local_user=Ðелокальні кориÑтувачі не можуть змінити Ñвоє ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача.
+username_been_taken=Ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача вже зайнÑте.
+username_change_not_local_user=Ðелокальні кориÑтувачі не можуть змінювати Ñвоє ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача.
username_has_not_been_changed=Ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача не змінено
-repo_name_been_taken=Ім'Ñ Ñ€ÐµÐ¿Ð¾Ð·Ñ–Ñ‚Ð¾Ñ€Ñ–ÑŽ вже викориÑтовуєтьÑÑ.
-repository_files_already_exist=Файли вже Ñ–Ñнують Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ репозитарію. ЗвернітьÑÑ Ð´Ð¾ ÑиÑтемного адмініÑтратора.
-repository_files_already_exist.adopt=Файли вже Ñ–Ñнують Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ репозиторію Ñ– можуть бути лише прийнÑті.
-repository_files_already_exist.delete=Файли вже Ñ–Ñнують Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ Ñховища. Ви повинні видалити Ñ—Ñ….
-repository_files_already_exist.adopt_or_delete=Файли вже Ñ–Ñнують Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ репозиторію. Їх можливо прийнÑти або видалити.
-visit_rate_limit=ÐžÐ±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ ÑˆÐ²Ð¸Ð´ÐºÐ¾Ñті віддаленого доÑтупу.
-2fa_auth_required=Ð”Ð»Ñ Ð²Ñ–Ð´Ð´Ð°Ð»ÐµÐ½Ð¾Ð³Ð¾ доÑтупу необхідна двуфакторна аутентифікаціÑ.
-org_name_been_taken=Ðазва організації вже зайнÑто.
-team_name_been_taken=Ðазва команди вже зайнÑто.
-team_no_units_error=Дозволити доÑтуп до принаймні одного розділу репозитарію.
-email_been_used=Ð¦Ñ ÐµÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð° адреÑа вже викориÑтовуєтьÑÑ.
-email_invalid=ÐдреÑа електронної пошти помилкова.
+repo_name_been_taken=Ðазва Ñховища вже викориÑтовуєтьÑÑ.
+repository_files_already_exist=Ð”Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ Ñховища вже Ñ–Ñнують файли. ЗвернітьÑÑ Ð´Ð¾ ÑиÑтемного адмініÑтратора.
+repository_files_already_exist.adopt=Ð”Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ Ñховища вже Ñ–Ñнують файли, Ñ– Ñ—Ñ… можна лише прийнÑти.
+repository_files_already_exist.delete=Ð”Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ Ñховища вже Ñ–Ñнують файли. Ви повинні видалити Ñ—Ñ….
+repository_files_already_exist.adopt_or_delete=Ð”Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ Ñховища вже Ñ–Ñнують файли. Прийміть Ñ—Ñ… або видаліть.
+visit_rate_limit=Віддалений доÑтуп відхилено у зв'Ñзку з обмеженнÑм кількоÑті Ñпроб.
+2fa_auth_required=Ð”Ð»Ñ Ð²Ñ–Ð´Ð´Ð°Ð»ÐµÐ½Ð¾Ð³Ð¾ доÑтупу необхідна двофакторна автентифікаціÑ.
+org_name_been_taken=Ðазва організації вже зайнÑта.
+team_name_been_taken=Ðазва команди вже зайнÑта.
+team_no_units_error=Дозволити доÑтуп до принаймні одного розділу Ñховища.
+email_been_used=ÐдреÑа електронної пошти вже викориÑтовуєтьÑÑ.
+email_invalid=ÐдреÑа електронної пошти недійÑна.
openid_been_used=ÐдреÑа OpenID '%s' вже викориÑтовуєтьÑÑ.
username_password_incorrect=Ðеправильне ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача або пароль.
-password_complexity=Пароль не відповідає вимогам до ÑкладноÑті:
-password_lowercase_one=Принаймні одна буква в нижньому регіÑтрі
-password_uppercase_one=Принаймні одна буква в верхньому регіÑтрі
+password_complexity=Пароль не відповідає вимогам ÑкладноÑті:
+password_lowercase_one=Принаймні один Ñимвол нижнього регіÑтру
+password_uppercase_one=Принаймні один Ñимвол верхнього регіÑтру
password_digit_one=Принаймні одна цифра
-password_special_one=Принаймні один Ñпеціальний Ñимвол (пунктуаціÑ, дужки, лапки тощо)
-enterred_invalid_repo_name=Ðевірно введено ім'Ñ Ñ€ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ñ–ÑŽ.
-enterred_invalid_org_name=Ðевірно введено ім'Ñ Ð¾Ñ€Ð³Ð°Ð½Ñ–Ð·Ð°Ñ†Ñ–Ñ—.
-enterred_invalid_owner_name=Ім'Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ влаÑника не Ñ” дійÑним.
-enterred_invalid_password=Введений вами пароль некоректний.
+password_special_one=Принаймні один Ñпеціальний Ñимвол (розділові знаки, дужки, лапки тощо)
+enterred_invalid_repo_name=Ви ввели неправильну назву Ñховища.
+enterred_invalid_org_name=Ви ввели неправильну назву організації.
+enterred_invalid_owner_name=Ім'Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ влаÑника недійÑне.
+enterred_invalid_password=Ви ввели неправильний пароль.
unset_password=КориÑтувач не вÑтановив пароль.
-user_not_exist=Даний кориÑтувач не Ñ–Ñнує.
+user_not_exist=КориÑтувач не Ñ–Ñнує.
team_not_exist=Команда не Ñ–Ñнує.
-last_org_owner=Ви не можете видалити оÑтаннього кориÑтувача з команди 'влаÑники'. У кожній команді має бути принаймні один влаÑник.
+last_org_owner=Ви не можете видалити оÑтаннього кориÑтувача з групи 'влаÑників'. Ð’ організації має бути принаймні один влаÑник.
cannot_add_org_to_team=Організацію неможливо додати Ñк учаÑника команди.
-invalid_ssh_key=Ðеможливо перевірити ваш SSH ключ: %s
-invalid_gpg_key=Ðеможливо перевірити ваш GPG ключ: %s
-invalid_ssh_principal=Ðекоректний відповідальний: %s
+invalid_ssh_key=Ðе вдаєтьÑÑ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€Ð¸Ñ‚Ð¸ ключ SSH: %s
+invalid_gpg_key=Ðе вдаєтьÑÑ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€Ð¸Ñ‚Ð¸ ключ GPG: %s
+invalid_ssh_principal=Ðевірна ідентичніÑть: %s
auth_failed=Помилка автентифікації: %v
@@ -581,21 +581,20 @@ target_ref_not_exist=Цільове поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ðµ Ñ–Ñнує %s
admin_cannot_delete_self=Ви не можете видалити Ñебе, допоки ви адмініÑтратор. Будь лаÑка, Ñпочатку видаліть права адмініÑтратора.
[user]
-change_avatar=Змінити Ñвій аватар…
-repositories=Репозиторії
+change_avatar=Змінити аватар…
+repositories=Сховища
activity=Публічна активніÑть
-followers=Читачі
+followers=ПоÑлідовники
show_more=Показати більше
-starred=Обрані Репозиторії
-watched=ВідÑтежувані репозиторії
+starred=Обрані Ñховища
+watched=ВідÑтежувані Ñховища
code=Код
-projects=Проєкт
+projects=Проєкти
overview=ОглÑд
-following=Читає
-follow=ПідпиÑатиÑÑ
-unfollow=ВідпиÑатиÑÑ
+follow=Стежити
+unfollow=Ðе Ñтежити
user_bio=БіографіÑ
-disabled_public_activity=Цей кориÑтувач вимкнув публічний показ діÑльноÑті.
+disabled_public_activity=Цей кориÑтувач вимкнув публічну видиміÑть активноÑті.
show_on_map=Показати це міÑце на карті
settings=ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ¾Ñ€Ð¸Ñтувача
@@ -625,7 +624,7 @@ appearance=Зовнішній виглÑд
password=Пароль
security=Безпека
avatar=Ðватар
-ssh_gpg_keys=SSH / GPG ключі
+ssh_gpg_keys=Ключі SSH / GPG
social=Соціальні облікові запиÑи
applications=Додатки
orgs=ÐšÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð¾Ñ€Ð³Ð°Ð½Ñ–Ð·Ð°Ñ†Ñ–Ñми
@@ -644,7 +643,7 @@ update_profile=Оновити профіль
update_language=Оновити мову
update_language_success=Мову оновлено.
update_profile_success=Профіль уÑпішно оновлено.
-change_username=Ваше Ім'Ñ ÐºÑ€Ð¸Ñтувача було змінено.
+change_username=Ваше ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача змінено.
continue=Продовжити
cancel=Відмінити
language=Мова
@@ -670,13 +669,13 @@ keep_activity_private_popup=Показувати вашу активніÑть Ð
lookup_avatar_by_mail=Знайти Ðватар за адреÑою електронної пошти
federated_avatar_lookup=Знайти зовнішній аватар
-enable_custom_avatar=Увімкнути кориÑтувацькі аватари
-choose_new_avatar=Оберіть новий аватар
+enable_custom_avatar=Увімкнути кориÑтувацький аватар
+choose_new_avatar=Обрати новий аватар
update_avatar=Оновити аватар
delete_current_avatar=Видалити поточний аватар
uploaded_avatar_not_a_image=Завантажений файл не Ñ” зображеннÑм.
uploaded_avatar_is_too_big=Розмір завантаженого файлу (%d KiB) перевищує макÑимальний розмір (%d KiB).
-update_avatar_success=Ваш аватар був змінений.
+update_avatar_success=Ваш аватар оновлено.
update_user_avatar_success=Ðватар кориÑтувача оновлено.
cropper_prompt=Ви можете відредагувати Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð¿ÐµÑ€ÐµÐ´ збереженнÑм. Відредаговане Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð±ÑƒÐ´Ðµ збережено Ñк PNG.
@@ -685,64 +684,64 @@ old_password=Поточний пароль
new_password=Ðовий пароль
retype_new_password=Підтвердити новий пароль
password_incorrect=Поточний пароль неправильний.
-change_password_success=Ваш пароль був оновлений. Тепер увійдіть в ÑиÑтему, викориÑтовуючи новий пароль.
-password_change_disabled=Ðелокальні акаунти не можуть змінити пароль через Gitea.
+change_password_success=Ваш пароль оновлено. Відтепер входьте в ÑиÑтему, викориÑтовуючи новий пароль.
+password_change_disabled=Ðелокальні кориÑтувачі не можуть оновити Ñвій пароль через Ð²ÐµÐ±Ñ–Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Gitea.
emails=ÐдреÑа електронної пошти
-manage_emails=ÐšÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð°Ð´Ñ€ÐµÑами ел. пошти
-manage_themes=Виберіть тему за замовчуваннÑм
-manage_openid=ÐšÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ OpenID
+manage_emails=ÐšÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð°Ð´Ñ€ÐµÑами електронної пошти
+manage_themes=Обрати типову тему
+manage_openid=ÐšÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð°Ð´Ñ€ÐµÑами OpenID
theme_desc=Ð¦Ñ Ñ‚ÐµÐ¼Ð° буде типовою Ð´Ð»Ñ Ð²Ñього Ñайту.
primary=ОÑновний
activated=Ðктивовано
requires_activation=Потрібна активаціÑ
-primary_email=Зробити оÑновним
+primary_email=Зробити оÑновною
activate_email=ÐадіÑлати активацію
-activations_pending=Ðктивації в очікуванні
+activations_pending=ÐžÑ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ñ–Ñ—
delete_email=Видалити
email_deletion=Видалити адреÑу електронної пошти
-email_deletion_desc=Електронна адреÑа та пов'Ñзана з нею Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð±ÑƒÐ´Ðµ видалена з вашого облікового запиÑу. Git коміти, здійÑнені через цю електронну адреÑу, залишитьÑÑ Ð±ÐµÐ· змін. Продовжити?
-email_deletion_success=ÐдреÑу електронної пошти було видалено.
+email_deletion_desc=ÐдреÑа електронної пошти та пов'Ñзана з нею Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð±ÑƒÐ´Ðµ видалена з вашого облікового запиÑу. Коміти Git, здійÑнені через цю адреÑу електронну пошту, залишитьÑÑ Ð±ÐµÐ· змін. Продовжити?
+email_deletion_success=ÐдреÑу електронної пошти видалено.
theme_update_success=Тему оновлено.
-theme_update_error=Вибрана тема не Ñ–Ñнує.
+theme_update_error=Обрана тема не Ñ–Ñнує.
openid_deletion=Видалити адреÑу OpenID
-openid_deletion_desc=Ð’Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ñ†Ñ–Ñ”Ñ— OpenID-адреÑи з вашого облікового запиÑу заборонÑÑ” вам входити з ним. Продовжити?
-openid_deletion_success=ÐдреÑа OpenID була видалена.
+openid_deletion_desc=Ð’Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ñ†Ñ–Ñ”Ñ— адреÑи OpenID не дозволить вам увійти за нею. Продовжити?
+openid_deletion_success=ÐдреÑу OpenID видалено.
add_new_email=Додати нову адреÑу електронної пошти
add_new_openid=Додати новий OpenID URI
add_email=Додати адреÑу електронної пошти
add_openid=Додати OpenID URI
add_email_success=Додано нову адреÑу електронної пошти.
-email_preference_set_success=ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÐµÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð¾Ñ— пошти уÑпішно вÑтановлені.
-add_openid_success=Ðова адреÑа OpenID була додана.
+email_preference_set_success=ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÐµÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð¾Ñ— пошти уÑпішно вÑтановлено.
+add_openid_success=Додано нову адреÑу OpenID.
keep_email_private=Приховати адреÑу електронної пошти
-openid_desc=OpenID дозволÑÑ” делегувати аутентифікацію зовнішньому поÑтачальнику поÑлуг.
+openid_desc=OpenID дозволÑÑ” делегувати автентифікацію зовнішньому поÑтачальнику поÑлуг.
-manage_ssh_keys=Керувати SSH ключами
-manage_ssh_principals=Ð£Ð¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ SSH Ñертифікатами кориÑтувачів
-manage_gpg_keys=Керувати GPG ключами
+manage_ssh_keys=Керувати ключами SSH
+manage_ssh_principals=ÐšÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ñ–Ð´ÐµÐ½Ñ‚Ð¸Ñ‡Ð½Ð¾ÑÑ‚Ñми Ñертифікатів SSH
+manage_gpg_keys=Керувати ключами SSH
add_key=Додати ключ
-ssh_desc=Ці відкриті SSH-ключі пов'Ñзані з вашим обліковим запиÑом. Відповідні приватні ключі дозволÑють отримати повний доÑтуп до ваших репозиторіїв.
-principal_desc=Ці наÑтройки SSH Ñертифікатів вказані у вашому обліковому запиÑÑ– та надають повний доÑтуп до ваших репозиторіїв.
-gpg_desc=Ці публічні ключі GPG пов'Ñзані з вашим обліковим запиÑом. Тримайте Ñвої приватні ключі в безпеці, оÑкільки вони дозволÑють здійÑнювати перевірку комітів.
-ssh_helper=<strong>Потрібна допомога?</strong> ДивітьÑÑ Ð³Ñ–Ð´ на GitHub з <a href="%s"> генерації ключів SSH</a> або Ð²Ð¸Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ <a href="%s">типових неполадок SSH</a>.
-gpg_helper=<strong> Потрібна допомога? </strong> ПереглÑньте поÑібник GitHub <a href="%s"> про GPG </a>.
-add_new_key=Додати SSH ключ
-add_new_gpg_key=Додати GPG ключ
+ssh_desc=Ці публічні ключі SSH пов'Ñзані з вашим обліковим запиÑом. Відповідні приватні ключі надають повний доÑтуп до ваших Ñховищ.
+principal_desc=Ці ідентифікатори Ñертифікатів SSH прив'Ñзані до вашого облікового запиÑу Ñ– надають повний доÑтуп до ваших Ñховищ.
+gpg_desc=Ці публічні ключі GPG пов'Ñзані з вашим обліковим запиÑом. Зберігайте Ñвої приватні ключі в безпеці, оÑкільки вони дозволÑють підтверджувати коміти.
+ssh_helper=<strong>Потрібна допомога?</strong> ОзнайомтеÑÑ Ð· інÑтрукцією GitHub щодо <a href="%s">ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð²Ð»Ð°Ñних ключів SSH</a> або Ð²Ð¸Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ <a href="%s">типових неполадок SSH.</a>
+gpg_helper=<strong>Потрібна допомога?</strong> ПереглÑньте поÑібник GitHub <a href="%s">про GPG</a>.
+add_new_key=Додати ключ SSH
+add_new_gpg_key=Додати ключ GPG
key_content_ssh_placeholder=ПочинаєтьÑÑ Ð· 'ssh-ed25519', 'ssh-rsa', 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384', 'ecdsa-sha2-nistp521', 'sk-ecdsa-sha2-nistp256@openssh.com', або 'sk-ssh-ed25519@openssh.com'
key_content_gpg_placeholder=ПочинаєтьÑÑ Ð· '-----BEGIN PGP PUBLIC KEY BLOCK-----'
-add_new_principal=Додати кориÑтувача
-ssh_key_been_used=Цей SSH ключ вже був додано до Ñервера.
+add_new_principal=Додати ідентичніÑть
+ssh_key_been_used=Цей ключ SSH вже було додано до Ñервера.
ssh_key_name_used=Ключ SSH з таким ім'Ñм вже Ñ–Ñнує у вашому обліковому запиÑÑ–.
-ssh_principal_been_used=Цей кориÑтувач вже був доданий на Ñервер.
+ssh_principal_been_used=Цю ідентичніÑть вже було додано до Ñервера.
gpg_key_id_used=Публічний ключ GPG з таким Ñамим ідентифікатором вже Ñ–Ñнує.
-gpg_no_key_email_found=Цей ключ GPG не відповідає жодній активованій поштовій адреÑÑ–, Ñка пов'Ñзана з вашим обліковим запиÑом. Його вÑе рівно можна додати, Ñкщо ви підпишете наданий токен.
-gpg_key_matched_identities=Відповідні отримувачі:
-gpg_key_matched_identities_long=Вбудовані ідентифікатори цього ключа збігаютьÑÑ Ð· наÑтупними активованими адреÑами електронної пошти вказаного кориÑтувача. Коміти, Ñкі відповідають цим адреÑам, можуть бути підтверджені цим ключем.
+gpg_no_key_email_found=Цей ключ GPG не відповідає жодній активованій адреÑÑ– електронної пошти, пов'Ñзаній з вашим обліковим запиÑом. Його вÑе одно можна додати, Ñкщо ви підпишете наданий токен.
+gpg_key_matched_identities=Відповідні ідентичноÑті:
+gpg_key_matched_identities_long=Вбудовані ідентифікатори цього ключа збігаютьÑÑ Ð· наÑтупними активованими адреÑами електронної пошти цього кориÑтувача. За допомогою цього ключа можна перевірÑти коміти, що відповідають цим адреÑам електронної пошти.
gpg_key_verified=Перевірений ключ
-gpg_key_verified_long=Ключ перевірений за допомогою токена Ñ– може бути викориÑтано Ð´Ð»Ñ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ ÐºÐ¾Ð¼Ñ–Ñ‚Ñ–Ð², Ñкі відповідають будь-Ñкій з активованих Ð°Ð´Ñ€ÐµÑ ÐµÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð¾Ñ— пошти Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ кориÑтувача, на додачу до будь-Ñких відповідних ідентифікацій Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ ключа.
+gpg_key_verified_long=Ключ був перевірений токеном Ñ– може бути викориÑтаний Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€ÐºÐ¸ комітів, що відповідають будь-Ñким активованим адреÑам електронної пошти Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ кориÑтувача, а також будь-Ñких ідентифікаторів, що відповідають цьому ключу.
gpg_key_verify=Підтвердити
-gpg_invalid_token_signature=Ðаданий ключ GPG, Ð¿Ñ–Ð´Ð¿Ð¸Ñ Ñ– токен не Ñпівпадають або токен заÑтарів.
+gpg_invalid_token_signature=Ðадані ключ GPG, Ð¿Ñ–Ð´Ð¿Ð¸Ñ Ñ– токен не збігаютьÑÑ Ð°Ð±Ð¾ токен заÑтарілий.
gpg_token_required=Вам потрібно надати Ð¿Ñ–Ð´Ð¿Ð¸Ñ Ð´Ð»Ñ Ð½Ð¸Ð¶Ñ‡ÐµÐ²ÐºÐ°Ð·Ð°Ð½Ð¾Ð³Ð¾ токена
gpg_token=Токен
gpg_token_help=Ви можете Ñтворити Ð¿Ñ–Ð´Ð¿Ð¸Ñ Ð·Ð° допомогою:
@@ -750,101 +749,101 @@ gpg_token_signature=ТекÑтовий (armored) Ð¿Ñ–Ð´Ð¿Ð¸Ñ GPG
key_signature_gpg_placeholder=`ПочинаєтьÑÑ Ð· "-----BEGIN PGP SIGNATURE-----"`
verify_gpg_key_success=Ключ GPG '%s' перевірено.
ssh_key_verified=Перевірений ключ
-ssh_key_verify=Підтвердити
+ssh_key_verify=Перевірити
ssh_token_required=Вам потрібно надати Ð¿Ñ–Ð´Ð¿Ð¸Ñ Ð´Ð»Ñ Ð½Ð¸Ð¶Ñ‡ÐµÐ²ÐºÐ°Ð·Ð°Ð½Ð¾Ð³Ð¾ токена
ssh_token=Токен
ssh_token_help=Ви можете Ñтворити Ð¿Ñ–Ð´Ð¿Ð¸Ñ Ð·Ð° допомогою:
verify_ssh_key_success=Ключ SSH '%s' перевірено.
subkeys=Підключі
-key_id=ID ключа
-key_name=Ім'Ñ ÐºÐ»ÑŽÑ‡Ð°
+key_id=Ідентифікатор ключа
+key_name=Ðазва ключа
key_content=ЗміÑÑ‚
principal_content=ЗміÑÑ‚
-add_key_success=SSH ключ '%s' додано.
-add_gpg_key_success=GPG ключ '%s' додано.
+add_key_success=Ключ SSH '%s' додано.
+add_gpg_key_success=Ключ GPG '%s' додано.
delete_key=Видалити
-ssh_key_deletion=Видалити SSH ключ
-gpg_key_deletion=Видалити GPG ключ
-ssh_principal_deletion=Видалити SSH Ñертифікат кориÑтувача
+ssh_key_deletion=Видалити ключ SSH
+gpg_key_deletion=Видалити ключ GPG
+ssh_principal_deletion=Видалити ідентичніÑть Ñертифікату SSH
ssh_key_deletion_desc=Ð’Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ ÐºÐ»ÑŽÑ‡Ð° SSH ÑкаÑовує доÑтуп до вашого облікового запиÑу. Продовжити?
-gpg_key_deletion_desc=Ð’Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ GPG ключа ÑкаÑовує перевірку підпиÑаних ним комітів. Продовжити?
-ssh_principal_deletion_desc=Ð’Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ ÐºÐ»ÑŽÑ‡Ð° SSH ÑкаÑовує доÑтуп до вашого облікового запиÑу. Продовжити?
-ssh_key_deletion_success=SSH ключ був видалений.
-gpg_key_deletion_success=GPG було видалено.
-ssh_principal_deletion_success=КориÑтувача видалено.
+gpg_key_deletion_desc=Ð’Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ ÐºÐ»ÑŽÑ‡Ð° GPG ÑкаÑовує перевірку підпиÑаних ним комітів. Продовжити?
+ssh_principal_deletion_desc=Ð’Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ñ–Ð´ÐµÐ½Ñ‚Ð¸Ñ‡Ð½Ð¾Ñті Ñертифіката SSH ÑкаÑовує доÑтуп до вашого облікового запиÑу. Продовжити?
+ssh_key_deletion_success=Ключ SSH видалено.
+gpg_key_deletion_success=Ключ GPG видалено.
+ssh_principal_deletion_success=ІдентичніÑть видалено.
added_on=Додано %s
valid_until_date=ДійÑно до %s
valid_forever=ДійÑний завжди
-last_used=ОÑтаннє викориÑтаннÑ
-no_activity=Жодної діÑльноÑті
-can_read_info=Читати
-can_write_info=ÐапиÑати
-key_state_desc=Цей ключ викориÑтовувавÑÑ Ð² оÑтанні 7 днів
-token_state_desc=Цей токен викориÑтовувавÑÑ Ð² оÑтанні 7 днів
-principal_state_desc=УчаÑтник був на Ñайті в оÑтанні 7 днів
+last_used=ВоÑтаннє викориÑтано
+no_activity=ÐÐµÑ‰Ð¾Ð´Ð°Ð²Ð½Ñ Ð°ÐºÑ‚Ð¸Ð²Ð½Ñ–Ñть відÑутнÑ
+can_read_info=ЧитаннÑ
+can_write_info=ЗапиÑ
+key_state_desc=Цей ключ викориÑтовувавÑÑ Ð¿Ñ€Ð¾Ñ‚Ñгом оÑтанніх 7 днів
+token_state_desc=Цей токен викориÑтовувавÑÑ Ð¿Ñ€Ð¾Ñ‚Ñгом оÑтанніх 7 днів
+principal_state_desc=Ð¦Ñ Ñ–Ð´ÐµÐ½Ñ‚Ð¸Ñ‡Ð½Ñ–Ñть викориÑтовувалаÑÑ Ð¿Ñ€Ð¾Ñ‚Ñгом оÑтанніх 7 днів
show_openid=Показати у профілю
-hide_openid=Ðе показувати у профілі
+hide_openid=Приховати з профілю
ssh_disabled=SSH вимкнено
ssh_signonly=SSH наразі вимкнено, тому ці ключі викориÑтовуютьÑÑ Ð»Ð¸ÑˆÐµ Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€ÐºÐ¸ підпиÑу комітів.
-ssh_externally_managed=Цей ключ SSH має зовнішнє ÑƒÐ¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ кориÑтувача
-manage_social=Керувати зв'Ñзаними обліковими запиÑами Ñоціальних мереж
+ssh_externally_managed=Цей ключ SSH керуєтьÑÑ Ð·Ð·Ð¾Ð²Ð½Ñ– Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ кориÑтувача
+manage_social=Керувати пов'Ñзаними обліковими запиÑами Ñоціальних мереж
unbind=Від'єднати
-manage_access_token=ÐšÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ñ‚Ð¾ÐºÐµÐ½Ð°Ð¼Ð¸ доÑтупу
-generate_new_token=Згенерувати новий токен
-tokens_desc=Ці токени надають доÑтуп до вашого облікового запиÑу за допомогою Gitea API.
-token_name=Ім'Ñ Ñ‚Ð¾ÐºÐµÐ½Ñƒ
+manage_access_token=Керувати токенами доÑтупу
+generate_new_token=Створити новий токен
+tokens_desc=Ці токени надають доÑтуп до вашого облікового запиÑу за допомогою API Gitea.
+token_name=Ðазва токену
generate_token=Згенерувати токен
-generate_token_success=Ваш новий токен був Ñтворений. Скопіюйте його зараз, оÑкільки він не буде показаний знову.
+generate_token_success=Ваш новий токен Ñтворено. Скопіюйте його зараз, оÑкільки він не буде показаний знову.
generate_token_name_duplicate=Ðазва програми <strong>%s</strong> вже викориÑтовуєтьÑÑ. Будь лаÑка, викориÑтайте нову.
delete_token=Видалити
access_token_deletion=Видалити токен доÑтупу
access_token_deletion_cancel_action=Відмінити
access_token_deletion_confirm_action=Видалити
-delete_token_success=Токен був знищений. Програми, що викориÑтовують його, більше не мають доÑтупу до вашого облікового запиÑу.
+delete_token_success=Токен знищено. Додатки, що викориÑтовують його, більше не мають доÑтупу до вашого облікового запиÑу.
permissions_access_all=Ð’ÑÑ– (загальнодоÑтупні, приватні та з обмеженим доÑтупом)
permission_not_set=Ðе вÑтановлено
permission_no_access=Ðемає доÑтупу
permission_read=Прочитані
permission_write=Ð§Ð¸Ñ‚Ð°Ð½Ð½Ñ Ñ– запиÑ
permission_anonymous_read=Ðнонімне читаннÑ
-permission_everyone_read=УÑÑ– читають
-permission_everyone_write=УÑÑ– пишуть
+permission_everyone_read=Ð§Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð´Ð»Ñ Ð²ÑÑ–Ñ…
+permission_everyone_write=Ð—Ð°Ð¿Ð¸Ñ Ð´Ð»Ñ Ð²ÑÑ–Ñ…
permissions_list=Дозволи:
-manage_oauth2_applications=ÐšÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð°Ð¼Ð¸ OAuth2
-edit_oauth2_application=Редагувати програму OAuth2
-oauth2_applications_desc=Програми OAuth2 дають можливіÑть вашим Ñтороннім програмам надійно аутентифікувати кориÑтувачів у цьому екземплÑрі Gitea.
-remove_oauth2_application=Видалити програму OAuth2
-remove_oauth2_application_desc=Ð’Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¸ OAuth2 ÑкаÑовує доÑтуп до вÑÑ–Ñ… підпиÑаних маркерів доÑтупу. Продовжити?
-remove_oauth2_application_success=Програму видалено.
-create_oauth2_application=Створити нову програму OAuth2
-create_oauth2_application_button=Створити програму
+manage_oauth2_applications=ÐšÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð¾Ð´Ð°Ñ‚ÐºÐ°Ð¼Ð¸ OAuth2
+edit_oauth2_application=Редагувати додаток OAuth2
+oauth2_applications_desc=Додатки OAuth2 дозволÑють вашому Ñторонньому додатку безпечно автентифікувати кориÑтувачів у цьому екземплÑрі Gitea.
+remove_oauth2_application=Видалити додаток OAuth2
+remove_oauth2_application_desc=Ð’Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð´Ð¾Ð´Ð°Ñ‚ÐºÐ° OAuth2 ÑкаÑує доÑтуп до вÑÑ–Ñ… підпиÑаних токенів доÑтупу. Продовжити?
+remove_oauth2_application_success=Додаток видалено.
+create_oauth2_application=Створити новий додаток OAuth2
+create_oauth2_application_button=Створити додаток
create_oauth2_application_success=Ви уÑпішно Ñтворили новий додаток OAuth2.
update_oauth2_application_success=Ви уÑпішно оновили додаток OAuth2.
-oauth2_application_name=Ðазва програми
+oauth2_application_name=Ðазва додатка
save_application=Зберегти
-oauth2_client_id=ID Клієнта
+oauth2_client_id=Ідентифікатор клієнта
oauth2_client_secret=Ключ клієнта
oauth2_regenerate_secret=Відновити ключ
-oauth2_regenerate_secret_hint=Ви втратили Ñвій ключ?
+oauth2_regenerate_secret_hint=Втратили ключ?
oauth2_application_edit=Редагувати
oauth2_application_create_description=Програми OAuth2 надають вашим Ñтороннім програмам доÑтуп до облікових запиÑів кориÑтувачів у цьому екземплÑрі.
authorized_oauth2_applications=Ðвторизовані програми OAuth2
revoke_key=Відкликати
revoke_oauth2_grant=СкаÑувати доÑтуп
-revoke_oauth2_grant_description=СкаÑÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð¾Ñтупу Ð´Ð»Ñ Ñ†Ñ–Ñ”Ñ— програми третьої Ñторони не дозволить їй отримувати доÑтуп до ваших даних. Ви впевнені?
+revoke_oauth2_grant_description=СкаÑÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð¾Ñтупу Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ Ñтороннього додатка не дозволить йому отримувати доÑтуп до ваших даних. Ви впевнені?
-twofa_is_enrolled=Ваш обліковий Ð·Ð°Ð¿Ð¸Ñ Ð½Ð° даний Ñ‡Ð°Ñ <strong>викориÑтовує</strong> двофакторну автентифікацію.
-twofa_not_enrolled=Ваш обліковий Ð·Ð°Ð¿Ð¸Ñ Ð½Ð°Ñ€Ð°Ð·Ñ– не викориÑтовує двофакторну автентифікаціїю.
+twofa_is_enrolled=Ваш обліковий Ð·Ð°Ð¿Ð¸Ñ Ð½Ð°Ñ€Ð°Ð·Ñ– <strong>викориÑтовує</strong> двофакторну автентифікацію.
+twofa_not_enrolled=Ваш обліковий Ð·Ð°Ð¿Ð¸Ñ Ð½Ð°Ñ€Ð°Ð·Ñ– не викориÑтовує двофакторну автентифікацію.
twofa_disable=Вимкнути двофакторну автентифікацію
twofa_enroll=Увімкнути двофакторну автентифікацію
-twofa_disable_note=При необхідноÑті можна відключити двофакторну автентифікацію.
+twofa_disable_note=За потреби ви можете вимкнути двофакторну автентифікацію.
twofa_disable_desc=Ð’Ð¸Ð¼ÐºÐ½ÐµÐ½Ð½Ñ Ð´Ð²Ð¾Ñ„Ð°ÐºÑ‚Ð¾Ñ€Ð½Ð¾Ñ— автентифікації зробить ваш обліковий Ð·Ð°Ð¿Ð¸Ñ Ð¼ÐµÐ½Ñˆ безпечним. Продовжити?
-twofa_disabled=Двофакторна Ð°Ð²Ñ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ Ð²Ð¸Ð¼ÐºÐ½ÐµÐ½Ð°.
-scan_this_image=ПроÑкануйте це Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð²Ð°ÑˆÐ¸Ð¼ додатком Ð´Ð»Ñ Ð´Ð²ÑƒÑ„Ð°ÐºÑ‚Ð¾Ñ€Ð½Ð¾Ñ— автентифікації:
-or_enter_secret=Ðбо введіть Ñекрет: %s
+twofa_disabled=Двофакторну автентифікацію вимкнено.
+scan_this_image=ВідÑкануйте це Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð²Ð°ÑˆÐ¸Ð¼ додатком Ð´Ð»Ñ Ð´Ð²Ð¾Ñ„Ð°ÐºÑ‚Ð¾Ñ€Ð½Ð¾Ñ— автентифікації:
+or_enter_secret=Ðбо введіть код: %s
then_enter_passcode=І введіть пароль, Ñкий відображаєтьÑÑ Ð² додатку:
passcode_invalid=Ðекоректний пароль. Спробуй ще раз.
twofa_failed_get_secret=Ðе вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ Ñекрет.
diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini
index 9593e9d442..c90711f903 100644
--- a/options/locale/locale_zh-CN.ini
+++ b/options/locale/locale_zh-CN.ini
@@ -91,7 +91,7 @@ add=添加
add_all=添加所有
remove=移除
remove_all=移除所有
-remove_label_str=删除标签「%sã€
+remove_label_str=删除标记「%sã€
edit=编辑
view=查看
test=测试
@@ -262,7 +262,7 @@ host=æ•°æ®åº“主机
user=用户å
password=æ•°æ®åº“用户密ç 
db_name=æ•°æ®åº“åç§°
-db_schema=Schema
+db_schema=æž¶æž„
db_schema_helper=留空则数æ®åº“中默认值为("public")。
ssl_mode=SSL
path=æ•°æ®åº“文件路径
@@ -637,7 +637,7 @@ unset_password=登录用户没有设置密ç ã€‚
unsupported_login_type=æ­¤ç™»å½•ç±»åž‹ä¸æ”¯æŒæ‰‹åŠ¨åˆ é™¤å¸æˆ·ã€‚
user_not_exist=该用户ä¸å­˜åœ¨
team_not_exist=团队ä¸å­˜åœ¨
-last_org_owner=您ä¸èƒ½ä»Ž "所有者" 团队中删除最åŽä¸€ä¸ªç”¨æˆ·ã€‚组织中必须至少有一个所有者。
+last_org_owner=您ä¸èƒ½ä»Žã€Œæ‰€æœ‰è€…ã€å›¢é˜Ÿä¸­åˆ é™¤æœ€åŽä¸€ä¸ªç”¨æˆ·ã€‚组织中必须至少有一个所有者。
cannot_add_org_to_team=组织ä¸èƒ½åŠ å…¥åˆ°å›¢é˜Ÿä¸­ã€‚
duplicate_invite_to_team=此用户已被邀请为团队æˆå‘˜ã€‚
organization_leave_success=您已æˆåŠŸç¦»å¼€ç»„ç»‡ %s。
@@ -752,11 +752,11 @@ cancel=å–æ¶ˆæ“作
language=界é¢è¯­è¨€
ui=主题
hidden_comment_types=éšè—的评论类型
-hidden_comment_types_description=此处选中的注释类型ä¸ä¼šæ˜¾ç¤ºåœ¨å·¥å•页é¢ä¸­ã€‚比如,勾选「标签ã€åˆ é™¤æ‰€æœ‰ã€Œ{user} 添加/删除的 {label}ã€æ³¨é‡Šã€‚
+hidden_comment_types_description=此处选中的注释类型ä¸ä¼šæ˜¾ç¤ºåœ¨å·¥å•页é¢ä¸­ã€‚比如,勾选「标记ã€åˆ é™¤æ‰€æœ‰ã€Œ{user} 添加/删除的 {label}ã€æ³¨é‡Šã€‚
hidden_comment_types.ref_tooltip=注释此问题在何处被æåŠè¿‡ï¼Œå¦‚å¦ä¸€ä¸ªé—®é¢˜ã€ä»£ç æäº¤ç­‰
hidden_comment_types.issue_ref_tooltip=注释用户在何处更改了与此问题相关è”的分支/标签
comment_type_group_reference=引用
-comment_type_group_label=标签
+comment_type_group_label=标记
comment_type_group_milestone=里程碑
comment_type_group_assignee=被指派人
comment_type_group_title=标题
@@ -801,7 +801,7 @@ manage_openid=ç®¡ç† OpenID 地å€
email_desc=您的主邮箱地å€å°†ç”¨äºŽé€šçŸ¥ã€å¯†ç æ¢å¤ä»¥åŠåŸºäºŽç½‘页的 Git æ“作(如果它未设为éšè—)。
theme_desc=这将是您在整个网站上的默认主题。
theme_colorblindness_help=颜色障ç¢ä¸»é¢˜æ”¯æŒ
-theme_colorblindness_prompt=Gitea åªèƒ½èŽ·å¾—ä¸€äº›åŸºæœ¬çš„é¢œè‰²éšœç¢æ”¯æŒï¼Œè¿™äº›ä¸»é¢˜åªå®šä¹‰äº†å°‘数颜色。 这项工作ä»åœ¨è¿›è¡Œä¸­ï¼Œå¯ä»¥é€šè¿‡åœ¨ä¸»é¢˜çš„ CSS 文件中定义更多颜色æ¥åšæ›´å¤šçš„æ”¹è¿›ã€‚
+theme_colorblindness_prompt=Gitea åªèƒ½èŽ·å¾—ä¸€äº›åŸºæœ¬çš„é¢œè‰²éšœç¢æ”¯æŒï¼Œè¿™äº›ä¸»é¢˜åªå®šä¹‰äº†å°‘数颜色。这项工作ä»åœ¨è¿›è¡Œä¸­ï¼Œå¯ä»¥é€šè¿‡åœ¨ä¸»é¢˜çš„ CSS 文件中定义更多颜色æ¥åšæ›´å¤šçš„æ”¹è¿›ã€‚
primary=主è¦
activated=已激活
requires_activation=éœ€è¦æ¿€æ´»
@@ -817,7 +817,7 @@ theme_update_success=您的主题已更新。
theme_update_error=所选主题ä¸å­˜åœ¨ã€‚
openid_deletion=移除 OpenID 地å€
openid_deletion_desc=删除此 OpenID 地å€å°†ä¼šé˜»æ­¢æ‚¨ä½¿ç”¨å®ƒè¿›è¡Œç™»å½•。您确定è¦ç»§ç»­å—?
-openid_deletion_success=OpenID地å€å·²ç§»é™¤ã€‚
+openid_deletion_success=OpenID 地å€å·²ç§»é™¤ã€‚
add_new_email=添加新的邮箱地å€
add_new_openid=添加新的 OpenID URI
add_email=新增邮箱地å€
@@ -831,23 +831,23 @@ keep_email_private_popup=这将会éšè—您的邮箱地å€ï¼Œä¸ä»…在您的个ä
openid_desc=OpenID 让您å¯ä»¥å°†è®¤è¯è½¬å‘到外部æœåŠ¡ã€‚
manage_ssh_keys=ç®¡ç† SSH 密钥
-manage_ssh_principals=管ç†SSHè¯ä¹¦è§„则
+manage_ssh_principals=ç®¡ç† SSH è¯ä¹¦è§„则
manage_gpg_keys=ç®¡ç† GPG 密钥
add_key=增加密钥
ssh_desc=这些 SSH 公钥已ç»å…³è”到您的账å·ã€‚相应的ç§é’¥æ‹¥æœ‰å®Œå…¨æ“作您仓库的æƒé™ã€‚
-principal_desc=这些SSHè¯ä¹¦è§„则已关è”到您的账å·å°†å…许完全访问您所有仓库。
+principal_desc=这些 SSH è¯ä¹¦è§„则已关è”到您的账å·å°†å…许完全访问您所有仓库。
gpg_desc=这些 GPG 公钥已ç»å…³è”到您的账å·ã€‚请妥善ä¿ç®¡æ‚¨çš„ç§é’¥å› ä¸ºä»–ä»¬å°†è¢«ç”¨äºŽè®¤è¯æäº¤ã€‚
ssh_helper=<strong>需è¦å¸®åŠ©ï¼Ÿ</strong> 请查看有关 <a href="%s">å¦‚ä½•ç”Ÿæˆ SSH 密钥</a> 或 <a href="%s">å¸¸è§ SSH 问题</a> 寻找答案。
-gpg_helper=<strong>需è¦å¸®åŠ©å—?</strong>看一看 GitHub <a href="%s">关于GPG</a> 的指导。
+gpg_helper=<strong>需è¦å¸®åŠ©å—?</strong>看一看 GitHub <a href="%s">关于 GPG</a> 的指导。
add_new_key=增加 SSH 密钥
add_new_gpg_key=添加的 GPG 密钥
key_content_ssh_placeholder=以 'ssh-ed25519'〠'ssh-rsa'〠'ecdsa-sha2-nistp256'ã€'ecdsa-sha2-nistp384'ã€'ecdsa-sha2-nistp521'〠'sk-ecdsa-sha2-nistp256@openssh.com' 或 'sk-ssh-ed25519@openssh.com' 开头
key_content_gpg_placeholder=以 '-----BEGIN PGP PUBLIC KEY BLOCK-----' 开头
add_new_principal=添加规则
ssh_key_been_used=æ­¤ SSH 密钥已添加到æœåŠ¡å™¨ã€‚
-ssh_key_name_used=使用相åŒåç§°çš„SSH公钥已ç»å­˜åœ¨ï¼
+ssh_key_name_used=使用相åŒåç§°çš„ SSH 公钥已ç»å­˜åœ¨ã€‚
ssh_principal_been_used=此规则已ç»åŠ å…¥åˆ°äº†æœåŠ¡å™¨ã€‚
-gpg_key_id_used=使用相åŒåç§°çš„GPG公钥已ç»å­˜åœ¨ï¼
+gpg_key_id_used=使用相åŒåç§°çš„ GPG 公钥已ç»å­˜åœ¨ã€‚
gpg_no_key_email_found=æ­¤ GPG å¯†é’¥ä¸Žæ‚¨å¸æˆ·å…³è”的任何已激活邮箱地å€å‡ä¸åŒ¹é…。如果您已对æä¾›çš„令牌进行签å,ä»å¯æ·»åŠ è¯¥å¯†é’¥ã€‚
gpg_key_matched_identities=匹é…的身份:
gpg_key_matched_identities_long=此密钥中包å«çš„身份信æ¯ä¸Žä»¥ä¸‹æ­¤ç”¨æˆ·å·²æ¿€æ´»é‚®ç®±åœ°å€åŒ¹é…。与这些邮箱地å€ç›¸åŒ¹é…çš„æäº¤å¯é€šè¿‡æ­¤å¯†é’¥è¿›è¡ŒéªŒè¯ã€‚
@@ -872,13 +872,13 @@ ssh_token_signature=增强 SSH ç­¾å
key_signature_ssh_placeholder=以 '-----BEGIN SSH SIGNATURE -----' 开头
verify_ssh_key_success=SSH 密钥「%sã€å·²éªŒè¯ã€‚
subkeys=å­é¡¹
-key_id=é”®ID
+key_id=密钥 ID
key_name=密钥åç§°
key_content=密钥内容
principal_content=内容
add_key_success=SSH 密钥「%sã€æ·»åŠ æˆåŠŸã€‚
add_gpg_key_success=GPG 密钥「%sã€æ·»åŠ æˆåŠŸã€‚
-add_principal_success=SSHè¯ä¹¦è§„则「%sã€æ·»åŠ æˆåŠŸã€‚
+add_principal_success=SSH è¯ä¹¦è§„则「%sã€æ·»åŠ æˆåŠŸã€‚
delete_key=删除
ssh_key_deletion=删除 SSH 密钥
gpg_key_deletion=删除 GPG 密钥
@@ -924,7 +924,7 @@ access_token_deletion_desc=删除令牌将撤销程åºå¯¹æ‚¨è´¦æˆ·çš„访问æƒé™
delete_token_success=令牌已ç»è¢«åˆ é™¤ã€‚使用该令牌的应用将ä¸å†èƒ½å¤Ÿè®¿é—®æ‚¨çš„è´¦å·ã€‚
repo_and_org_access=仓库和组织访问æƒé™
permissions_public_only=仅公开
-permissions_access_all=全部(公开ã€ç§æœ‰å’Œå—é™)
+permissions_access_all=全部(公开ã€ç§æœ‰å’Œå—é™ï¼‰
permission_not_set=未设置
permission_no_access=无访问æƒé™
permission_read=å¯è¯»
@@ -1003,7 +1003,7 @@ remove_account_link=删除已绑定的账å·
remove_account_link_desc=åˆ é™¤å·²ç»‘å®šå¸æˆ·å°†åŠé”€å…¶å¯¹æ‚¨çš„ Gitea 叿ˆ·çš„访问æƒé™ã€‚继续?
remove_account_link_success=已喿¶ˆç»‘å®šå¸æˆ·ã€‚
-hooks.desc=添加 Webhooks,它们将会在您拥有的<strong>所有仓库</strong>上触å‘
+hooks.desc=添加 Web é’©å­ï¼Œå®ƒä»¬å°†ä¼šåœ¨æ‚¨æ‹¥æœ‰çš„<strong>所有仓库</strong>上触å‘。
orgs_none=æ‚¨çŽ°åœ¨è¿˜ä¸æ˜¯ä»»ä½•组织的æˆå‘˜ã€‚
repos_none=æ‚¨å¹¶ä¸æ‹¥æœ‰ä»»ä½•仓库。
@@ -1036,7 +1036,7 @@ owner_helper=由于最大仓库数é‡é™åˆ¶ï¼Œä¸€äº›ç»„织å¯èƒ½ä¸ä¼šæ˜¾ç¤ºåœ¨ä
repo_name=仓库åç§°
repo_name_profile_public_hint=.profile 是一个特殊的仓库,您å¯ä»¥ä½¿ç”¨å®ƒå°† README.md 添加到您的公共组织资料中,任何人都å¯ä»¥çœ‹åˆ°ã€‚请确ä¿å®ƒæ˜¯å…¬å¼€çš„,并使用个人资料目录中的 README 对其进行åˆå§‹åŒ–以开始使用。
repo_name_profile_private_hint=.profile-private 是一个特殊的仓库,您å¯ä»¥ä½¿ç”¨å®ƒå‘您的组织æˆå‘˜ä¸ªäººèµ„料添加 README.md,仅对组织æˆå‘˜å¯è§ã€‚请确ä¿å®ƒæ˜¯ç§æœ‰çš„,并使用个人资料目录中的 README 对其进行åˆå§‹åŒ–以开始使用。
-repo_name_helper=ç†æƒ³çš„仓库åç§°åº”ç”±ç®€çŸ­ã€æœ‰æ„义和独特的关键è¯ç»„æˆã€‚".profile" å’Œ ".profile-private" å¯ç”¨äºŽä¸ºç”¨æˆ·/组织添加 README.md。
+repo_name_helper=ç†æƒ³çš„仓库åç§°åº”ç”±ç®€çŸ­ã€æœ‰æ„义和独特的关键è¯ç»„æˆã€‚「.profileã€å’Œã€Œ.profile-privateã€å¯ç”¨äºŽä¸ºç”¨æˆ·/组织添加 README.md。
repo_size=仓库大å°
template=模æ¿
template_select=选择模æ¿
@@ -1053,7 +1053,7 @@ fork_from=派生自
already_forked=æ‚¨å·²ç»æ´¾ç”Ÿè¿‡ %s
fork_to_different_account=派生到其他账å·
fork_visibility_helper=无法更改派生仓库的å¯è§æ€§ã€‚
-fork_branch=è¦å…‹éš†åˆ° Fork 的分支
+fork_branch=è¦å…‹éš†ä¸ºæ´¾ç”Ÿçš„分支
all_branches=所有分支
view_all_branches=查看所有分支
view_all_tags=查看所有标签
@@ -1066,14 +1066,14 @@ download_tar=下载 TAR.GZ
download_bundle=下载 BUNDLE
generate_repo=生æˆä»“库
generate_from=生æˆè‡ª
-repo_desc=仓库æè¿°
+repo_desc=æè¿°
repo_desc_helper=è¾“å…¥ç®€è¦æè¿° (å¯é€‰)
repo_no_desc=无详细信æ¯
-repo_lang=编程语言
+repo_lang=语言
repo_gitignore_helper=选择 .gitignore 模æ¿ã€‚
repo_gitignore_helper_desc=从常è§è¯­è¨€çš„æ¨¡æ¿åˆ—è¡¨ä¸­é€‰æ‹©å¿½ç•¥è·Ÿè¸ªçš„æ–‡ä»¶ã€‚é»˜è®¤æƒ…å†µä¸‹ï¼Œç”±å¼€å‘æˆ–构建工具生æˆçš„特殊文件都包å«åœ¨ .gitignore 中。
-issue_labels=工啿 ‡ç­¾
-issue_labels_helper=é€‰æ‹©ä¸€ä¸ªå·¥å•æ ‡ç­¾é›†
+issue_labels=工啿 ‡è®°
+issue_labels_helper=é€‰æ‹©ä¸€ä¸ªå·¥å•æ ‡è®°é›†ã€‚
license=授æƒè®¸å¯
license_helper=选择授æƒè®¸å¯æ–‡ä»¶ã€‚
license_helper_desc=许å¯è¯è¯´æ˜Žäº†å…¶ä»–人å¯ä»¥å’Œä¸å¯ä»¥ç”¨æ‚¨çš„代ç åšä»€ä¹ˆã€‚ä¸ç¡®å®šå“ªä¸€ä¸ªé€‚åˆæ‚¨çš„é¡¹ç›®ï¼Ÿè§ <a target="_blank" rel="noopener noreferrer" href="%s">选择一个许å¯è¯</a>
@@ -1083,7 +1083,7 @@ object_format_helper=仓库的对象格å¼ã€‚ä¹‹åŽæ— æ³•更改。SHA1 是最兼
readme=自述
readme_helper=选择自述文件模æ¿ã€‚
readme_helper_desc=这是您å¯ä»¥ä¸ºæ‚¨çš„项目撰写完整æè¿°çš„地方。
-auto_init=åˆå§‹åŒ–仓库(添加. gitignoreã€è®¸å¯è¯å’Œè‡ªè¿°æ–‡ä»¶)
+auto_init=åˆå§‹åŒ–仓库(添加 .gitignoreã€è®¸å¯è¯å’Œè‡ªè¿°æ–‡ä»¶ï¼‰
trust_model_helper=选择签å验è¯çš„信任模型。å¯èƒ½çš„选项是:
trust_model_helper_collaborator=å作者:信任å作者的签å
trust_model_helper_committer=æäº¤è€…:信任与æäº¤è€…相符的签å
@@ -1151,25 +1151,25 @@ desc.archived=已存档
desc.sha256=SHA256
template.items=模æ¿é€‰é¡¹
-template.git_content=Gitæ•°æ®(默认分支)
+template.git_content=Git æ•°æ®ï¼ˆé»˜è®¤åˆ†æ”¯ï¼‰
template.git_hooks=Git é’©å­
-template.git_hooks_tooltip=æ‚¨ç›®å‰æ— æ³•修改或删除被添加过的 Git Hook。仅当您信任模æ¿ä»“库时æ‰å¯ä»¥é€‰æ‹©æ­¤é¡¹ã€‚
+template.git_hooks_tooltip=æ‚¨ç›®å‰æ— æ³•修改或删除被添加过的 Git é’©å­ã€‚仅当您信任模æ¿ä»“库时æ‰å¯ä»¥é€‰æ‹©æ­¤é¡¹ã€‚
template.webhooks=Web é’©å­
template.topics=主题
template.avatar=头åƒ
-template.issue_labels=工啿 ‡ç­¾
+template.issue_labels=工啿 ‡è®°
template.one_item=必须至少选择一个模æ¿é¡¹
template.invalid=必须选择一个模æ¿ä»“库
-archive.title=该仓库已被归档。您å¯ä»¥æŸ¥çœ‹æ–‡ä»¶å’Œå…‹éš†å®ƒï¼Œä½†ä¸èƒ½æŽ¨é€ã€åˆ›å»ºå·¥å•或åˆå¹¶è¯·æ±‚。
-archive.title_date=该仓库已于 %s 归档。您å¯ä»¥æŸ¥çœ‹æ–‡ä»¶æˆ–克隆它,但ä¸èƒ½æŽ¨é€ã€åˆ›å»ºå·¥å•或åˆå¹¶è¯·æ±‚。
+archive.title=该仓库已被归档。您å¯ä»¥æŸ¥çœ‹æ–‡ä»¶å’Œå…‹éš†å®ƒï¼Œä½†ä¸èƒ½æŽ¨é€ã€æ‰“开工啿ˆ–åˆå¹¶è¯·æ±‚。
+archive.title_date=该仓库已于 %s 归档。您å¯ä»¥æŸ¥çœ‹æ–‡ä»¶æˆ–克隆它,但ä¸èƒ½æŽ¨é€ã€æ‰“开工啿ˆ–åˆå¹¶è¯·æ±‚。
archive.issue.nocomment=此仓库已存档,您ä¸èƒ½åœ¨æ­¤å·¥å•添加评论。
archive.pull.nocomment=此仓库已存档,您ä¸èƒ½åœ¨æ­¤åˆå¹¶è¯·æ±‚添加评论。
form.reach_limit_of_creation_1=您已ç»è¾¾åˆ°äº† %d 仓库的上é™ã€‚
form.reach_limit_of_creation_n=您已ç»è¾¾åˆ°äº† %d 个仓库的上é™ã€‚
form.name_reserved=仓库åç§° %s 是ä¿ç•™çš„。
-form.name_pattern_not_allowed=仓库å称中ä¸å…许使用 %s æ ¼å¼ã€‚
+form.name_pattern_not_allowed=仓库å中ä¸å…许使用「%sã€æ ¼å¼ã€‚
need_auth=授æƒ
migrate_options=è¿ç§»é€‰é¡¹
@@ -1183,7 +1183,7 @@ migrate_options_lfs_endpoint.placeholder=如果留空,网å€å°†ä»Žå…‹éš† URL ä
migrate_items=è¿ç§»é¡¹ç›®
migrate_items_wiki=百科
migrate_items_milestones=里程碑
-migrate_items_labels=标签
+migrate_items_labels=标记
migrate_items_issues=å·¥å•
migrate_items_pullrequests=åˆå¹¶è¯·æ±‚
migrate_items_merge_requests=åˆå¹¶è¯·æ±‚
@@ -1222,7 +1222,7 @@ migrate.codecommit.https_git_credentials_password=HTTPS Git 凭æ®å¯†ç 
migrate.migrating_git=è¿ç§»Gitæ•°æ®
migrate.migrating_topics=è¿ç§»ä¸»é¢˜
migrate.migrating_milestones=è¿ç§»é‡Œç¨‹ç¢‘
-migrate.migrating_labels=è¿ç§»æ ‡ç­¾
+migrate.migrating_labels=è¿ç§»æ ‡è®°
migrate.migrating_releases=è¿ç§»å‘布
migrate.migrating_issues=è¿ç§»å·¥å•
migrate.migrating_pulls=è¿ç§»åˆå¹¶è¯·æ±‚
@@ -1261,7 +1261,7 @@ branch=分支
tree=目录树
clear_ref=`清除当å‰å¼•用`
filter_branch_and_tag=过滤分支或标签
-find_tag=查找Git标签
+find_tag=查找标签
branches=分支列表
tags=标签列表
issues=å·¥å•
@@ -1269,8 +1269,8 @@ pulls=åˆå¹¶è¯·æ±‚
projects=项目
packages=软件包
actions=工作æµ
-labels=标签
-org_labels_desc=组织级别的标签,å¯ä»¥è¢«æœ¬ç»„织下的 <strong>所有仓库</strong> 使用
+labels=标记
+org_labels_desc=组织级别的标记,å¯ä»¥è¢«æœ¬ç»„织下的 <strong>所有仓库</strong> 使用
org_labels_desc_manage=管ç†
milestone=里程碑
@@ -1279,7 +1279,7 @@ commits=æäº¤
commit=æäº¤
release=å‘布
releases=å‘布
-tag=Git标签
+tag=标签
released_this=å‘布
tagged_this=已标记
file.title=%s ä½äºŽ %s
@@ -1336,12 +1336,12 @@ editor.cannot_edit_non_text_files=网页ä¸èƒ½ç¼–辑二进制文件。
editor.edit_this_file=编辑文件
editor.this_file_locked=文件已é”定
editor.must_be_on_a_branch=您必须在æŸä¸ªåˆ†æ”¯ä¸Šæ‰èƒ½å¯¹æ­¤æ–‡ä»¶è¿›è¡Œä¿®æ”¹æ“作。
-editor.fork_before_edit=您必须在派生这个仓库æ‰èƒ½å¯¹æ­¤æ–‡ä»¶è¿›è¡Œä¿®æ”¹æ“作
+editor.fork_before_edit=您必须派生这个仓库æ‰èƒ½å¯¹æ­¤æ–‡ä»¶è¿›è¡Œä¿®æ”¹æ“作。
editor.delete_this_file=删除文件
editor.must_have_write_access=您必须具有写æƒé™æ‰èƒ½å¯¹æ­¤æ–‡ä»¶è¿›è¡Œä¿®æ”¹æ“作。
editor.file_delete_success=文件「%sã€å·²åˆ é™¤ã€‚
editor.name_your_file=命忖‡ä»¶...
-editor.filename_help=通过键入åç§°åŽè·Ÿæ–œçº¿ ("/") æ¥æ·»åŠ ç›®å½•ã€‚é€šè¿‡åœ¨è¾“å…¥æ¡†çš„å¼€å¤´é”®å…¥ "退格" æ¥åˆ é™¤ç›®å½•。
+editor.filename_help=通过键入åç§°åŽè·Ÿæ–œçº¿ ("/") æ¥æ·»åŠ ç›®å½•ã€‚é€šè¿‡åœ¨è¾“å…¥æ¡†çš„å¼€å¤´é”®å…¥ã€Œé€€æ ¼ã€æ¥åˆ é™¤ç›®å½•。
editor.or=或
editor.cancel_lower=å–æ¶ˆ
editor.commit_signed_changes=æäº¤å·²ç­¾å的更改
@@ -1359,7 +1359,7 @@ editor.signoff_desc=在æäº¤æ—¥å¿—æ¶ˆæ¯æœ«å°¾æ·»åŠ ç­¾ç½²äººä¿¡æ¯ã€‚
editor.commit_directly_to_this_branch=直接æäº¤è‡³ <strong class="branch-name">%s</strong> 分支。
editor.create_new_branch=为此æäº¤åˆ›å»ºä¸€ä¸ª <strong>新的分支</strong> å¹¶å‘èµ·åˆå¹¶è¯·æ±‚。
editor.create_new_branch_np=为此æäº¤åˆ›å»º <strong>新分支</strong>。
-editor.propose_file_change=æè®®æ–‡ä»¶æ›´æ”¹
+editor.propose_file_change=拟议文件更改
editor.new_branch_name=为这次æäº¤çš„æ–°åˆ†æ”¯å‘½å
editor.new_branch_name_desc=新的分支åç§°...
editor.cancel=å–æ¶ˆ
@@ -1376,15 +1376,15 @@ editor.file_editing_no_longer_exists=正在编辑的文件「%sã€å·²ä¸å­˜åœ¨äº
editor.file_deleting_no_longer_exists=正在删除的文件「%sã€å·²ä¸å­˜åœ¨äºŽæ­¤ä»“库。
editor.file_changed_while_editing=文件内容在您进行编辑时已ç»å‘生å˜åŠ¨ã€‚<a target="_blank" rel="noopener noreferrer" href="%s">å•击此处</a> 查看å˜åŠ¨çš„å…·ä½“å†…å®¹ï¼Œæˆ–è€… <strong>冿¬¡æäº¤</strong> 覆盖已å‘生的å˜åŠ¨ã€‚
editor.file_already_exists=此仓库已ç»å­˜åœ¨å为「%sã€çš„æ–‡ä»¶ã€‚
-editor.commit_id_not_matching=æäº¤ID与您开始编辑时的IDä¸åŒ¹é…。请æäº¤åˆ°è¡¥ä¸åˆ†æ”¯ç„¶åŽåˆå¹¶ã€‚
+editor.commit_id_not_matching=æäº¤ ID 与您开始编辑时的 ID ä¸åŒ¹é…。请æäº¤åˆ°è¡¥ä¸åˆ†æ”¯ç„¶åŽåˆå¹¶ã€‚
editor.push_out_of_date=推é€ä¼¼ä¹Žå·²ç»è¿‡æ—¶ã€‚
editor.commit_empty_file_header=æäº¤ä¸€ä¸ªç©ºæ–‡ä»¶
editor.commit_empty_file_text=æ‚¨è¦æäº¤çš„æ–‡ä»¶æ˜¯ç©ºçš„ï¼Œç»§ç»­å—?
editor.no_changes_to_show=没有å¯ä»¥æ˜¾ç¤ºçš„å˜æ›´ã€‚
editor.fail_to_update_file=æ›´æ–°/创建文件「%sã€å¤±è´¥ã€‚
editor.fail_to_update_file_summary=错误信æ¯ï¼š
-editor.push_rejected_no_message=此修改被æœåŠ¡å™¨æ‹’ç»å¹¶ä¸”没有å馈消æ¯ã€‚请检查 Git Hook。
-editor.push_rejected=此修改被æœåŠ¡å™¨æ‹’ç»ã€‚请检查 Git Hook。
+editor.push_rejected_no_message=此修改被æœåŠ¡å™¨æ‹’ç»å¹¶ä¸”没有å馈消æ¯ã€‚请检查 Git é’©å­ã€‚
+editor.push_rejected=此修改被æœåŠ¡å™¨æ‹’ç»ã€‚请检查 Git é’©å­ã€‚
editor.push_rejected_summary=详细拒ç»ä¿¡æ¯ï¼š
editor.add_subdir=添加目录
editor.unable_to_upload_files=上传文件至「%sã€å¤±è´¥ï¼š%v
@@ -1474,19 +1474,19 @@ issues.desc=组织 bug 报告ã€ä»»åŠ¡å’Œé‡Œç¨‹ç¢‘ã€‚
issues.filter_assignees=筛选指派人
issues.filter_milestones=筛选里程碑
issues.filter_projects=筛选项目
-issues.filter_labels=筛选标签
+issues.filter_labels=筛选标记
issues.filter_reviewers=筛选审核者
issues.filter_no_results=没有结果
issues.filter_no_results_placeholder=请å°è¯•调整您的æœç´¢è¿‡æ»¤å™¨ã€‚
-issues.new=创建工å•
+issues.new=打开工å•
issues.new.title_empty=标题ä¸èƒ½ä¸ºç©º
-issues.new.labels=标签
-issues.new.no_label=未选择标签
-issues.new.clear_labels=清除选中标签
+issues.new.labels=标记
+issues.new.no_label=未选择标记
+issues.new.clear_labels=清除选中标记
issues.new.projects=项目
issues.new.clear_projects=清除项目
issues.new.no_projects=暂无项目
-issues.new.open_projects=å¼€å¯ä¸­çš„项目
+issues.new.open_projects=已打开项目
issues.new.closed_projects=已关闭的项目
issues.new.no_items=æ— å¯é€‰é¡¹
issues.new.milestone=里程碑
@@ -1496,32 +1496,32 @@ issues.new.assignees=指派æˆå‘˜
issues.new.clear_assignees=å–æ¶ˆæŒ‡æ´¾æˆå‘˜
issues.new.no_assignees=未指派æˆå‘˜
issues.new.no_reviewers=无审核者
-issues.new.blocked_user=无法创建工å•,因为您已被仓库所有者å±è”½ã€‚
+issues.new.blocked_user=无法打开工å•,因为您已被仓库所有者å±è”½ã€‚
issues.edit.already_changed=无法ä¿å­˜å¯¹å·¥å•的更改。其内容似乎已被其他用户更改。 请刷新页é¢å¹¶é‡æ–°ç¼–辑以é¿å…覆盖他们的更改
issues.edit.blocked_user=无法编辑内容,因为您已被仓库所有者或工å•创建者å±è”½ã€‚
issues.choose.get_started=开始
-issues.choose.open_external_link=å¼€å¯
+issues.choose.open_external_link=打开
issues.choose.blank=默认模æ¿
issues.choose.blank_about=从默认模æ¿åˆ›å»ºä¸€ä¸ªå·¥å•。
issues.choose.ignore_invalid_templates=已忽略无效模æ¿
issues.choose.invalid_templates=å‘现了 %v 个无效模æ¿
issues.choose.invalid_config=问题é…置包å«é”™è¯¯ï¼š
issues.no_ref=分支/标记未指定
-issues.create=创建工å•
-issues.new_label=创建标签
-issues.new_label_placeholder=标签åç§°
+issues.create=打开工å•
+issues.new_label=创建标记
+issues.new_label_placeholder=标记åç§°
issues.new_label_desc_placeholder=æè¿°
-issues.create_label=创建标签
-issues.label_templates.title=加载预定义的标签模æ¿
-issues.label_templates.info=还没有任何标签。您å¯ä»¥ä½¿ç”¨'创建标签'按钮或者加载预定义的标签集创建标签
-issues.label_templates.helper=选择标签模æ¿
-issues.label_templates.use=使用标签集
-issues.label_templates.fail_to_load_file=åŠ è½½æ ‡ç­¾æ¨¡æ¿æ–‡ä»¶ã€Œ%sã€æ—¶å‘生错误:%v
-issues.add_label=于 %[2]s 添加了标签 %[1]s
-issues.add_labels=于 %[2]s 添加了标签 %[1]s
-issues.remove_label=于 %[2]s 删除了标签 %[1]s
-issues.remove_labels=于 %[2]s 删除了标签 %[1]s
-issues.add_remove_labels=于 %[3]s 添加了标签 %[1]s ,删除了标签 %[2]s
+issues.create_label=创建标记
+issues.label_templates.title=加载预定义的标记模æ¿
+issues.label_templates.info=还没有任何标记。您å¯ä»¥ä½¿ç”¨ã€Œåˆ›å»ºæ ‡è®°ã€æŒ‰é’®æˆ–者加载预定义的标记集创建标记:
+issues.label_templates.helper=选择标记模æ¿
+issues.label_templates.use=使用标记集
+issues.label_templates.fail_to_load_file=åŠ è½½æ ‡è®°æ¨¡æ¿æ–‡ä»¶ã€Œ%sã€æ—¶å‘生错误:%v
+issues.add_label=于 %[2]s 添加了标记 %[1]s
+issues.add_labels=于 %[2]s 添加了标记 %[1]s
+issues.remove_label=于 %[2]s 删除了标记 %[1]s
+issues.remove_labels=于 %[2]s 删除了标记 %[1]s
+issues.add_remove_labels=于 %[3]s 添加了标记 %[1]s ,删除了标记 %[2]s
issues.add_milestone_at=`于 %[2]s 添加了里程碑 <b>%[1]s</b>`
issues.add_project_at=`于 %[2]s 将此添加到 <b>%[1]s</b> 项目`
issues.move_to_column_of_project=`将此对象移至 %s 的 %s 中在 %s 上`
@@ -1540,10 +1540,10 @@ issues.change_ref_at=`将引用从 <b><strike>%s</strike></b> 更改为了 <b>%s
issues.remove_ref_at=`删除了引用 <b>%s</b> %s`
issues.add_ref_at=`添加了引用 <b>%s</b> %s`
issues.delete_branch_at=`于 %[2]s 删除了分支 <b>%[1]s</b>`
-issues.filter_label=标签筛选
-issues.filter_label_exclude=`使用 <code>alt</code> + <code>鼠标左键 / 回车</code> 排除标签`
-issues.filter_label_no_select=所有标签
-issues.filter_label_select_no_label=无标签
+issues.filter_label=标记筛选
+issues.filter_label_exclude=`使用 <code>alt</code> + <code>鼠标左键 / 回车</code> 排除标记`
+issues.filter_label_no_select=所有标记
+issues.filter_label_select_no_label=无标记
issues.filter_milestone=里程碑筛选
issues.filter_milestone_all=所有里程碑
issues.filter_milestone_none=无里程碑
@@ -1579,9 +1579,9 @@ issues.filter_sort.moststars=点赞由多到少
issues.filter_sort.feweststars=点赞由少到多
issues.filter_sort.mostforks=派生由多到少
issues.filter_sort.fewestforks=派生由少到多
-issues.action_open=å¼€å¯
+issues.action_open=打开
issues.action_close=关闭
-issues.action_label=标签
+issues.action_label=标记
issues.action_milestone=里程碑
issues.action_milestone_no_select=无里程碑
issues.action_assignee=指派人筛选
@@ -1596,7 +1596,7 @@ issues.opened_by_fake=由 %[2]s 于 %[1]s 打开
issues.closed_by_fake=由 %[2]s 创建,关闭于 %[1]s
issues.previous=上一页
issues.next=下一页
-issues.open_title=å¼€å¯ä¸­
+issues.open_title=已打开
issues.closed_title=已关闭
issues.draft_title=è‰ç¨¿
issues.num_comments_1=%d 评论
@@ -1613,8 +1613,8 @@ issues.close=关闭工å•
issues.comment_pull_merged_at=å·²åˆå¹¶æäº¤ %[1]s 到 %[2]s %[3]s
issues.comment_manually_pull_merged_at=手动åˆå¹¶æäº¤ %[1]s 到 %[2]s %[3]s
issues.close_comment_issue=评论并关闭
-issues.reopen_issue=釿–°å¼€å¯
-issues.reopen_comment_issue=è¯„è®ºå¹¶é‡æ–°å¼€å¯
+issues.reopen_issue=釿–°æ‰“å¼€
+issues.reopen_comment_issue=è¯„è®ºå¹¶é‡æ–°æ‰“å¼€
issues.create_comment=评论
issues.comment.blocked_user=无法创建或编辑评论,因为您已被仓库所有者或工å•创建者å±è”½ã€‚
issues.closed_at=`于 <a id="%[1]s" href="#%[1]s">%[2]s</a> 关闭此工å•`
@@ -1649,26 +1649,26 @@ issues.sign_in_require_desc=<a href="%s">登录</a> å¹¶å‚与到对è¯ä¸­ã€‚
issues.edit=编辑
issues.cancel=å–æ¶ˆ
issues.save=ä¿å­˜
-issues.label_title=标签åç§°
-issues.label_description=标签æè¿°
-issues.label_color=标签颜色
+issues.label_title=åç§°
+issues.label_description=æè¿°
+issues.label_color=颜色
issues.label_color_invalid=无效的颜色
-issues.label_exclusive=互斥标签
-issues.label_archive=归档标签
-issues.label_archived_filter=显示存档标签
-issues.label_archive_tooltip=在标签æœç´¢æ—¶ï¼Œé»˜è®¤æƒ…况下存档标签将被排除在外。
-issues.label_exclusive_desc=命忠‡ç­¾ä¸º <code>scope/item</code> 以使其与其他以 <code>scope/</code> 开头的标签互斥。
-issues.label_exclusive_warning=åœ¨ç¼–è¾‘å·¥å•æˆ–åˆå¹¶è¯·æ±‚的标签时,任何冲çªçš„范围标签都将被删除。
+issues.label_exclusive=互斥
+issues.label_archive=归档标记
+issues.label_archived_filter=显示已归档标记
+issues.label_archive_tooltip=在标记æœç´¢æ—¶ï¼Œé»˜è®¤æƒ…况下已归档标记将被排除在外。
+issues.label_exclusive_desc=命忠‡è®°ä¸º <code>scope/item</code> 以使其与其他以 <code>scope/</code> 开头的标记互斥。
+issues.label_exclusive_warning=åœ¨ç¼–è¾‘å·¥å•æˆ–åˆå¹¶è¯·æ±‚的标记时,任何冲çªçš„范围标记都将被删除。
issues.label_exclusive_order=排åºé¡ºåº
-issues.label_exclusive_order_tooltip=在åŒä¸€ä¸ªèŒƒå›´å†…的互斥标签将按照这个数字进行排åº
-issues.label_count=%d 个标签
-issues.label_open_issues=%d 个开å¯çš„å·¥å•
+issues.label_exclusive_order_tooltip=在åŒä¸€ä¸ªèŒƒå›´å†…的互斥标记将按照这个数字进行排åºã€‚
+issues.label_count=%d 个标记
+issues.label_open_issues=%d 个已打开工å•/åˆå¹¶è¯·æ±‚
issues.label_edit=编辑
issues.label_delete=删除
-issues.label_modify=编辑标签
-issues.label_deletion=删除标签
-issues.label_deletion_desc=删除标签会将其从所有问题中删除。继续?
-issues.label_deletion_success=该标签已删除。
+issues.label_modify=编辑标记
+issues.label_deletion=删除标记
+issues.label_deletion_desc=删除标记会将其从所有工å•中删除。继续?
+issues.label_deletion_success=该标记已删除。
issues.label.filter_sort.alphabetically=按字æ¯é¡ºåºæŽ’åº
issues.label.filter_sort.reverse_alphabetically=按字æ¯é€†åºæŽ’åº
issues.label.filter_sort.by_size=最å°å°ºå¯¸
@@ -1733,7 +1733,7 @@ issues.time_spent_total=总用时
issues.time_spent_from_all_authors=`总花费时间:%s`
issues.due_date=到期时间
-issues.invalid_due_date_format=到期时间的格å¼å¿…须是 'yyyy-mm-dd' 的形å¼ã€‚
+issues.invalid_due_date_format=到期时间的格å¼å¿…须是「yyyy-mm-ddã€çš„å½¢å¼ã€‚
issues.error_modifying_due_date=修改到期时间失败。
issues.error_removing_due_date=删除到期时间失败。
issues.push_commit_1=于 %[2]s 推é€äº† %[1]d 个æäº¤
@@ -1960,7 +1960,7 @@ pulls.cmd_instruction_merge_title=åˆå¹¶
pulls.cmd_instruction_merge_desc=åˆå¹¶å˜æ›´å¹¶æ›´æ–°åˆ° Gitea 上
pulls.cmd_instruction_merge_warning=警告:此æ“作ä¸èƒ½åˆå¹¶è¯¥åˆå¹¶è¯·æ±‚,因为「自动检测手动åˆå¹¶ã€æœªå¯ç”¨
pulls.clear_merge_message=清除åˆå¹¶ä¿¡æ¯
-pulls.clear_merge_message_hint=清除åˆå¹¶æ¶ˆæ¯åªä¼šåˆ é™¤æäº¤æ¶ˆæ¯å†…容,并ä¿ç•™ç”Ÿæˆçš„ Git 附加内容,如「Co-Authored-By …ã€ã€‚
+pulls.clear_merge_message_hint=清除åˆå¹¶æ¶ˆæ¯åªä¼šåˆ é™¤æäº¤æ¶ˆæ¯å†…容,并ä¿ç•™ç”Ÿæˆçš„ Git 附加内容,如「Co-Authored-By…ã€ã€‚
pulls.auto_merge_button_when_succeed=(当检查æˆåŠŸæ—¶)
pulls.auto_merge_when_succeed=在所有检查æˆåŠŸåŽè‡ªåЍåˆå¹¶
@@ -1975,7 +1975,7 @@ pulls.auto_merge_newly_scheduled_comment=`已于 %[1]s 设置此åˆå¹¶è¯·æ±‚在æ
pulls.auto_merge_canceled_schedule_comment=`已于 %[1]s å–æ¶ˆäº†è‡ªåЍåˆå¹¶è®¾ç½® `
pulls.delete.title=删除此åˆå¹¶è¯·æ±‚?
-pulls.delete.text=您真的è¦åˆ é™¤è¿™ä¸ªåˆå¹¶è¯·æ±‚å—? (这将永久删除所有内容。如果您打算将内容存档,请考虑关闭它)
+pulls.delete.text=您真的è¦åˆ é™¤è¿™ä¸ªåˆå¹¶è¯·æ±‚å—?(这将永久删除所有内容。如果您打算将内容存档,请考虑关闭它)
pulls.recently_pushed_new_branches=您已ç»äºŽ%[2]s推é€äº†åˆ†æ”¯ <strong>%[1]s</strong>
pulls.upstream_diverging_prompt_behind_1=该分支è½åŽäºŽ %[2]s %[1]d 个æäº¤
@@ -1993,7 +1993,7 @@ milestones.new=新的里程碑
milestones.closed=于 %s关闭
milestones.update_ago=已更新 %s
milestones.no_due_date=暂无截止日期
-milestones.open=å¼€å¯
+milestones.open=打开
milestones.close=关闭
milestones.new_subheader=里程碑å¯ä»¥å¸®åŠ©æ‚¨ç»„ç»‡å·¥å•并跟踪其进度。
milestones.completeness=<strong>%d%%</strong> 已完æˆ
@@ -2002,7 +2002,7 @@ milestones.title=标题
milestones.desc=æè¿°
milestones.due_date=截止日期(å¯é€‰ï¼‰
milestones.clear=清除
-milestones.invalid_due_date_format=到期时间的格å¼å¿…须是 'yyyy-mm-dd' 的形å¼ã€‚
+milestones.invalid_due_date_format=到期时间的格å¼å¿…须是「yyyy-mm-ddã€çš„å½¢å¼ã€‚
milestones.create_success=里程碑「%sã€åˆ›å»ºæˆåŠŸã€‚
milestones.edit=编辑里程碑
milestones.edit_subheader=里程碑组织工å•,åˆå¹¶è¯·æ±‚和跟踪进度。
@@ -2020,7 +2020,7 @@ milestones.filter_sort.most_complete=完æˆåº¦ä»Žé«˜åˆ°ä½Ž
milestones.filter_sort.most_issues=å·¥å•从多到少
milestones.filter_sort.least_issues=å·¥å•从少到多
-signing.will_sign=这个æäº¤å°†ç”¨å¯†é’¥ 「%sã€ç­¾å。
+signing.will_sign=这个æäº¤å°†ç”¨å¯†é’¥ã€Œ%sã€ç­¾å。
signing.wont_sign.error=在检查æäº¤æ˜¯å¦å¯ä»¥è¢«ç­¾å时出错。
signing.wont_sign.nokey=没有å¯ç”¨çš„密钥æ¥ç­¾ç½²è¿™ä¸ªæäº¤ã€‚
signing.wont_sign.never=æäº¤ä»Žæœªç­¾å。
@@ -2035,10 +2035,10 @@ signing.wont_sign.approved=åˆå¹¶å°†ä¸ä¼šè¢«ç­¾å,因为åˆå¹¶è¯·æ±‚未被æ‰
signing.wont_sign.not_signed_in=您还没有登录。
ext_wiki=访问外部百科
-ext_wiki.desc=链接到外部 wiki。
+ext_wiki.desc=链接到外部百科。
wiki=百科
-wiki.welcome=欢迎æ¥åˆ°ç™¾ç§‘!
+wiki.welcome=欢迎æ¥åˆ°ç™¾ç§‘。
wiki.welcome_desc=百科å…许您撰写和与å作者分享文档。
wiki.desc=撰写和与å作者分享文档
wiki.create_first_page=创建第一个页é¢
@@ -2061,37 +2061,37 @@ wiki.page_already_exists=相åŒåç§°çš„ Wiki 页é¢å·²ç»å­˜åœ¨ã€‚
wiki.reserved_page=百科页é¢å称「%sã€æ˜¯ä¿ç•™çš„。
wiki.pages=所有页é¢
wiki.last_updated=æœ€åŽæ›´æ–°äºŽ %s
-wiki.page_name_desc=输入此 Wiki 页é¢çš„å称。特殊å称有:'Home', '_Sidebar' å’Œ '_Footer'。
+wiki.page_name_desc=输入此百科页é¢çš„å称。特殊å称有:「Homeã€ï¼Œã€Œ_Sidebarã€å’Œã€Œ_Footerã€ã€‚
wiki.original_git_entry_tooltip=查看原始的 Git æ–‡ä»¶è€Œä¸æ˜¯ä½¿ç”¨å‹å¥½é“¾æŽ¥ã€‚
activity=活动
activity.navbar.pulse=活动
activity.navbar.code_frequency=代ç é¢‘率
activity.navbar.contributors=贡献者
-activity.navbar.recent_commits=最近的æäº¤
+activity.navbar.recent_commits=最近æäº¤
activity.period.filter_label=周期:
activity.period.daily=1 天
activity.period.halfweekly=3 天
-activity.period.weekly=1周
-activity.period.monthly=1 个月
-activity.period.quarterly=3个月
-activity.period.semiyearly=6 个月
-activity.period.yearly=1å¹´
+activity.period.weekly=1 周
+activity.period.monthly=1 月
+activity.period.quarterly=3 月
+activity.period.semiyearly=6 月
+activity.period.yearly=1 å¹´
activity.overview=概览
activity.active_prs_count_1=<strong>%d</strong> 个åˆå¹¶è¯·æ±‚
activity.active_prs_count_n=<strong>%d</strong> 个åˆå¹¶è¯·æ±‚
-activity.merged_prs_count_1=åˆå¹¶è¯·æ±‚
-activity.merged_prs_count_n=åˆå¹¶è¯·æ±‚
-activity.opened_prs_count_1=æ–°åˆå¹¶è¯·æ±‚
-activity.opened_prs_count_n=æ–°åˆå¹¶è¯·æ±‚
+activity.merged_prs_count_1=å·²åˆå¹¶çš„åˆå¹¶è¯·æ±‚
+activity.merged_prs_count_n=å·²åˆå¹¶çš„åˆå¹¶è¯·æ±‚
+activity.opened_prs_count_1=拟议的åˆå¹¶è¯·æ±‚
+activity.opened_prs_count_n=拟议的åˆå¹¶è¯·æ±‚
activity.title.user_1=%d ä½ç”¨æˆ·
activity.title.user_n=%d ä½ç”¨æˆ·
activity.title.prs_1=%d 个åˆå¹¶è¯·æ±‚
activity.title.prs_n=%d 个åˆå¹¶è¯·æ±‚
activity.title.prs_merged_by=%[2]s ç”± %[1]s åˆå¹¶
-activity.title.prs_opened_by=%[2]s 创建了 %[1]s
+activity.title.prs_opened_by=%[2]s 拟议了 %[1]s
activity.merged_prs_label=å·²åˆå¹¶
-activity.opened_prs_label=已创建
+activity.opened_prs_label=拟议中
activity.active_issues_count_1=<strong>%d</strong> å¼ å·¥å•
activity.active_issues_count_n=<strong>%d</strong> å¼ å·¥å•
activity.closed_issues_count_1=已关闭的工å•
@@ -2101,8 +2101,8 @@ activity.title.issues_n=%d å¼ å·¥å•
activity.title.issues_closed_from=%s 从 %s 关闭
activity.title.issues_created_by=%[2]s 创建了 %[1]s
activity.closed_issue_label=已关闭
-activity.new_issues_count_1=创建工å•
-activity.new_issues_count_n=创建工å•
+activity.new_issues_count_1=已打开的工å•
+activity.new_issues_count_n=已打开的工å•
activity.new_issue_label=打开的
activity.title.unresolved_conv_1=%d 未解决的会è¯
activity.title.unresolved_conv_n=%d 未解决的会è¯
@@ -2113,11 +2113,11 @@ activity.title.releases_n=%d 个å‘布
activity.title.releases_published_by=%[2]s å‘布了 %[1]s
activity.published_release_label=å·²å‘布
activity.no_git_activity=在此期间没有任何æäº¤æ´»åŠ¨ã€‚
-activity.git_stats_exclude_merges=排除åˆå¹¶ï¼Œ
+activity.git_stats_exclude_merges=排除åˆå¹¶åŽï¼Œ
activity.git_stats_author_1=%d ä½ä½œè€…
activity.git_stats_author_n=%d ä½ä½œè€…
-activity.git_stats_pushed_1=å·²ç»æŽ¨é€
-activity.git_stats_pushed_n=å·²ç»æŽ¨é€
+activity.git_stats_pushed_1=已推é€
+activity.git_stats_pushed_n=已推é€
activity.git_stats_commit_1=%d 次æäº¤
activity.git_stats_commit_n=%d 次æäº¤
activity.git_stats_push_to_branch=到 %s 和
@@ -2125,14 +2125,14 @@ activity.git_stats_push_to_all_branches=到所有分支。
activity.git_stats_on_default_branch=在 %s 上,
activity.git_stats_file_1=%d 个文件
activity.git_stats_file_n=%d 个文件
-activity.git_stats_files_changed_1=å·²ç»æ”¹å˜
-activity.git_stats_files_changed_n=å·²ç»æ”¹å˜
-activity.git_stats_additions=而且
-activity.git_stats_addition_1=新增 %d 行
-activity.git_stats_addition_n=新增 %d 行
+activity.git_stats_files_changed_1=已修改
+activity.git_stats_files_changed_n=已修改
+activity.git_stats_additions=并且已有
+activity.git_stats_addition_1=%d 行新增
+activity.git_stats_addition_n=%d 行新增
activity.git_stats_and_deletions=和
-activity.git_stats_deletion_1=删除 %d 行
-activity.git_stats_deletion_n=删除 %d 行
+activity.git_stats_deletion_1=%d 行删除
+activity.git_stats_deletion_n=%d 行删除
contributors.contribution_type.filter_label=贡献类型:
contributors.contribution_type.commits=æäº¤
@@ -2196,12 +2196,12 @@ settings.use_internal_wiki=使用内置百科
settings.default_wiki_branch_name=默认百科分支åç§°
settings.failed_to_change_default_wiki_branch=更改百科默认分支失败。
settings.use_external_wiki=使用外部百科
-settings.external_wiki_url=外部 Wiki 链接
+settings.external_wiki_url=外部百科链接
settings.external_wiki_url_error=外部百科链接无效
settings.external_wiki_url_desc=当点击百科标签时,访问者将被é‡å®šå‘到外部百科系统的 URL。
settings.issues_desc=å¯ç”¨å·¥å•系统
-settings.use_internal_issue_tracker=使用内置的轻é‡çº§å·¥å•管ç†ç³»ç»Ÿ
-settings.use_external_issue_tracker=使用外部的工å•管ç†ç³»ç»Ÿ
+settings.use_internal_issue_tracker=使用内置工å•系统
+settings.use_external_issue_tracker=使用外部工å•系统
settings.external_tracker_url=外部工å•系统 URL
settings.external_tracker_url_error=外部百科链接无效
settings.external_tracker_url_desc=å½“ç‚¹å‡»å·¥å•æ ‡ç­¾æ—¶ï¼Œè®¿é—®è€…将被é‡å®šå‘到外部工å•系统的 URL。
@@ -2211,7 +2211,7 @@ settings.tracker_issue_style=外部工å•管ç†ç³»ç»Ÿçš„ç¼–å·æ ¼å¼
settings.tracker_issue_style.numeric=纯数字形å¼
settings.tracker_issue_style.alphanumeric=è‹±æ–‡å­—æ¯æ•°å­—组åˆå½¢å¼
settings.tracker_issue_style.regexp=正则表达å¼
-settings.tracker_issue_style.regexp_pattern=æ­£åˆ™è¡¨è¾¾å¼æ¨¡å¼
+settings.tracker_issue_style.regexp_pattern=正则表达å¼
settings.tracker_issue_style.regexp_pattern_desc=第一个被æ•获的组将å–代 <code>{index}</code>。
settings.tracker_url_format_desc=使用å ä½ç¬¦ <code>{user}</code>, <code>{repo}</code> å’Œ <code>{index}</code> 作为用户åã€ä»“库å和工å•索引。
settings.enable_timetracker=å¯ç”¨æ—¶é—´è·Ÿè¸ª
@@ -2221,7 +2221,7 @@ settings.pulls.ignore_whitespace=忽略空白冲çª
settings.pulls.enable_autodetect_manual_merge=å¯ç”¨è‡ªåŠ¨æ£€æµ‹æ‰‹åŠ¨åˆå¹¶ (注æ„:在æŸäº›ç‰¹æ®Šæƒ…况下å¯èƒ½å‘生错误判断)
settings.pulls.allow_rebase_update=å…许通过å˜åŸºæ›´æ–°åˆå¹¶è¯·æ±‚分支
settings.pulls.default_delete_branch_after_merge=默认åˆå¹¶åŽåˆ é™¤åˆå¹¶è¯·æ±‚分支
-settings.pulls.default_allow_edits_from_maintainers=默认开å¯å…许维护者编辑
+settings.pulls.default_allow_edits_from_maintainers=默认å…许维护者编辑
settings.releases_desc=å¯ç”¨ä»“库å‘布
settings.packages_desc=å¯ç”¨ä»“库软件包注册中心
settings.projects_desc=å¯ç”¨é¡¹ç›®
@@ -2330,10 +2330,10 @@ settings.webhook.response=å“应内容
settings.webhook.headers=头信æ¯
settings.webhook.payload=内容
settings.webhook.body=å“应体
-settings.webhook.replay.description=釿”¾æ­¤ webhook。
+settings.webhook.replay.description=釿”¾æ­¤ Web é’©å­ã€‚
settings.webhook.replay.description_disabled=è‹¥è¦é‡æ–°è¿è¡Œæ­¤ Web é’©å­ï¼Œè¯·æ¿€æ´»å®ƒã€‚
settings.webhook.delivery.success=一个事件已添加到推é€é˜Ÿåˆ—。å¯èƒ½éœ€è¦è¿‡å‡ ç§’é’Ÿæ‰ä¼šæ˜¾ç¤ºåœ¨æŽ¨é€è®°å½•中。
-settings.githooks_desc=Git Hook 是 Git 本身æä¾›çš„功能。您å¯ä»¥åœ¨ä¸‹æ–¹ç¼–辑 hook 文件以设置自定义æ“作。
+settings.githooks_desc=Git é’©å­æ˜¯ Git 本身æä¾›çš„功能。您å¯ä»¥åœ¨ä¸‹æ–¹ç¼–辑 hook 文件以设置自定义æ“作。
settings.githook_edit_desc=å¦‚æžœé’©å­æœªå¯åŠ¨ï¼Œåˆ™ä¼šæ˜¾ç¤ºæ ·ä¾‹æ–‡ä»¶ä¸­çš„å†…å®¹ã€‚å¦‚æžœæƒ³è¦åˆ é™¤æŸä¸ªé’©å­ï¼Œåˆ™æäº¤ç©ºç™½æ–‡æœ¬å³å¯ã€‚
settings.githook_name=é’©å­åç§°
settings.githook_content=é’©å­æ–‡æœ¬
@@ -2341,7 +2341,7 @@ settings.update_githook=æ›´æ–°é’©å­è®¾ç½®
settings.add_webhook_desc=Gitea å°†å‘目标 URL å‘é€å…·æœ‰æŒ‡å®šå†…容类型的 <code>POST</code> 请求。在 <a target="_blank" rel="noopener noreferrer" href="%s">webhooks 指å—</a> 中阅读更多内容。
settings.payload_url=目标 URL
settings.http_method=HTTP 方法
-settings.content_type=POST Content Type
+settings.content_type=POST 内容类型
settings.secret=密钥
settings.slack_username=æœåŠ¡åç§°
settings.slack_icon_url=图标 URL
@@ -2376,7 +2376,7 @@ settings.event_issues_desc=å·¥å•已打开ã€å·²å…³é—­ã€å·²é‡æ–°æ‰“开或已ç¼
settings.event_issue_assign=å·¥å•已指派
settings.event_issue_assign_desc=å·¥å•å·²æŒ‡æ´¾æˆ–å–æ¶ˆæŒ‡æ´¾ã€‚
settings.event_issue_label=已标记工å•
-settings.event_issue_label_desc=工啿 ‡ç­¾å·²æ›´æ–°æˆ–清除。
+settings.event_issue_label_desc=工啿 ‡è®°å·²æ›´æ–°æˆ–清除。
settings.event_issue_milestone=å·¥å•已收入里程碑中
settings.event_issue_milestone_desc=å·¥å•å·²æ”¶å…¥æˆ–å–æ¶ˆæ”¶å…¥é‡Œç¨‹ç¢‘中。
settings.event_issue_comment=å·¥å•评论
@@ -2386,8 +2386,8 @@ settings.event_pull_request=åˆå¹¶è¯·æ±‚
settings.event_pull_request_desc=åˆå¹¶è¯·æ±‚已打开ã€å…³é—­ã€é‡æ–°æ‰“开或编辑。
settings.event_pull_request_assign=åˆå¹¶è¯·æ±‚已指派
settings.event_pull_request_assign_desc=åˆå¹¶è¯·æ±‚å·²æŒ‡æ´¾æˆ–å–æ¶ˆæŒ‡æ´¾ã€‚
-settings.event_pull_request_label=åˆå¹¶è¯·æ±‚已贴上标签
-settings.event_pull_request_label_desc=åˆå¹¶è¯·æ±‚的标签已更新或清除。
+settings.event_pull_request_label=åˆå¹¶è¯·æ±‚已标记
+settings.event_pull_request_label_desc=åˆå¹¶è¯·æ±‚标记已更新或清除。
settings.event_pull_request_milestone=åˆå¹¶è¯·æ±‚已记录于里程碑中
settings.event_pull_request_milestone_desc=åˆå¹¶è¯·æ±‚å·²è®°å½•æˆ–å–æ¶ˆè®°å½•于里程碑中。
settings.event_pull_request_comment=åˆå¹¶è¯·æ±‚已评论
@@ -2406,7 +2406,7 @@ settings.event_workflow_job_desc=Gitea 工作æµé˜Ÿåˆ—中ã€ç­‰å¾…ä¸­ã€æ­£åœ¨è¿
settings.event_package=软件包
settings.event_package_desc=软件包在仓库中已创建或删除。
settings.branch_filter=分支过滤
-settings.branch_filter_desc=推é€ã€åˆ›å»ºï¼Œåˆ é™¤åˆ†æ”¯äº‹ä»¶çš„分支白åå•,使用 glob 模å¼åŒ¹é…指定。若为空或 <code>*</code>ï¼Œåˆ™å°†æŠ¥å‘Šæ‰€æœ‰åˆ†æ”¯çš„äº‹ä»¶ã€‚è¯­æ³•æ–‡æ¡£è§ <a href="%[1]s">%[2]s</a>。示例:<code>master</code>,<code>{master,release*}</code>。
+settings.branch_filter_desc=推é€ã€åˆ›å»ºï¼Œåˆ é™¤åˆ†æ”¯äº‹ä»¶çš„分支白åå•,使用 glob 表达å¼åŒ¹é…指定。若为空或 <code>*</code>ï¼Œåˆ™ä¼šæŠ¥å‘Šæ‰€æœ‰åˆ†æ”¯çš„äº‹ä»¶ã€‚è¯­æ³•æ–‡æ¡£è§ <a href="%[1]s">%[2]s</a>。示例:<code>master</code>,<code>{master,release*}</code>。
settings.authorization_header=æŽˆæƒæ ‡å¤´
settings.authorization_header_desc=å½“å­˜åœ¨æ—¶å°†è¢«ä½œä¸ºæŽˆæƒæ ‡å¤´åŒ…å«åœ¨å†…。例如: %s。
settings.active=激活
@@ -2460,7 +2460,7 @@ settings.protected_branch_can_push_yes=您å¯ä»¥æŽ¨é€
settings.protected_branch_can_push_no=您ä¸èƒ½æŽ¨é€
settings.branch_protection=分支「<b>%s</b>ã€çš„ä¿æŠ¤è§„åˆ™
settings.protect_this_branch=å¯ç”¨åˆ†æ”¯ä¿æŠ¤
-settings.protect_this_branch_desc=阻止删除并é™åˆ¶Git推é€å’Œåˆå¹¶åˆ°åˆ†æ”¯ã€‚
+settings.protect_this_branch_desc=阻止删除并é™åˆ¶ Git 推é€å’Œåˆå¹¶åˆ°åˆ†æ”¯ã€‚
settings.protect_disable_push=ç¦ç”¨æŽ¨é€
settings.protect_disable_push_desc=此分支ä¸å…许推é€ã€‚
settings.protect_disable_force_push=ç¦ç”¨å¼ºåˆ¶æŽ¨é€
@@ -2486,13 +2486,13 @@ settings.protect_merge_whitelist_committers_desc=ä»…å…许白åå•用户或团é
settings.protect_merge_whitelist_users=åˆå¹¶ç™½åå•用户:
settings.protect_merge_whitelist_teams=åˆå¹¶ç™½åå•团队:
settings.protect_check_status_contexts=å¯ç”¨çŠ¶æ€æ£€æŸ¥
-settings.protect_status_check_patterns=çŠ¶æ€æ£€æŸ¥æ¨¡å¼ï¼š
-settings.protect_status_check_patterns_desc=输入模å¼ï¼ŒæŒ‡å®šå“ªäº›çŠ¶æ€æ£€æŸ¥å¿…须通过,æ‰èƒ½å°†åˆ†æ”¯åˆå¹¶åˆ°ç¬¦åˆæ­¤è§„则的分支中去。æ¯ä¸€è¡ŒæŒ‡å®šä¸€ä¸ªæ¨¡å¼ï¼Œæ¨¡å¼ä¸èƒ½ä¸ºç©ºã€‚
+settings.protect_status_check_patterns=çŠ¶æ€æ£€æŸ¥è¡¨è¾¾å¼ï¼š
+settings.protect_status_check_patterns_desc=输入表达å¼ä»¥æŒ‡å®šåœ¨åˆ†æ”¯åˆå¹¶åˆ°åŒ¹é…此规则的分支之å‰å¿…é¡»é€šè¿‡å“ªäº›çŠ¶æ€æ£€æŸ¥ã€‚æ¯ä¸€è¡ŒæŒ‡å®šä¸€ä¸ªè¡¨è¾¾å¼ä¸”表达å¼ä¸èƒ½ä¸ºç©ºã€‚
settings.protect_check_status_contexts_desc=è¦æ±‚çŠ¶æ€æ£€æŸ¥é€šè¿‡æ‰èƒ½åˆå¹¶ã€‚如果å¯ç”¨ï¼Œæäº¤å¿…须先推é€åˆ°å¦ä¸€ä¸ªåˆ†æ”¯ï¼Œç„¶åŽå†åˆå¹¶æˆ–推é€åˆ°åŒ¹é…è¿™äº›ä¿æŠ¤è§„åˆ™çš„åˆ†æ”¯ã€‚å¦‚æžœæ²¡æœ‰é€‰æ‹©å…·ä½“çš„çŠ¶æ€æ£€æŸ¥ä¸Šä¸‹æ–‡ï¼Œåˆ™æ‰€æœ‰çš„çŠ¶æ€æ£€æŸ¥éƒ½é€šè¿‡æ‰èƒ½åˆå¹¶ã€‚
settings.protect_check_status_contexts_list=æ­¤ä»“åº“ä¸Šå‘¨è¿›è¡Œè¿‡çš„çŠ¶æ€æ£€æŸ¥
settings.protect_status_check_matched=匹é…
-settings.protect_invalid_status_check_pattern=æ— æ•ˆçš„çŠ¶æ€æ£€æŸ¥è§„则:「%sã€ã€‚
-settings.protect_no_valid_status_check_patterns=æ²¡æœ‰æœ‰æ•ˆçš„çŠ¶æ€æ£€æŸ¥è§„则。
+settings.protect_invalid_status_check_pattern=æ— æ•ˆçš„çŠ¶æ€æ£€æŸ¥è¡¨è¾¾å¼ï¼šã€Œ%sã€ã€‚
+settings.protect_no_valid_status_check_patterns=æ²¡æœ‰æœ‰æ•ˆçš„çŠ¶æ€æ£€æŸ¥è¡¨è¾¾å¼ã€‚
settings.protect_required_approvals=所需的批准:
settings.protect_required_approvals_desc=åªå…许åˆå¹¶æœ‰è¶³å¤Ÿå®¡æ ¸çš„åˆå¹¶è¯·æ±‚ã€‚è¦æ±‚的审核必须æ¥è‡ªç™½å啿ˆ–者有æƒé™çš„用户或团队。
settings.protect_approvals_whitelist_enabled=仅列入白åå•的用户或团队æ‰å¯æ‰¹å‡†
@@ -2505,13 +2505,13 @@ settings.ignore_stale_approvals=忽略过期批准
settings.ignore_stale_approvals_desc=对旧æäº¤ï¼ˆè¿‡æœŸå®¡æ ¸ï¼‰çš„æ‰¹å‡†å°†ä¸è®¡å…¥ PR 的批准数。如果过期审查已被驳回,则与此无关。
settings.require_signed_commits=需è¦ç­¾åæäº¤
settings.require_signed_commits_desc=æ‹’ç»æŽ¨é€æœªç­¾å或无法验è¯çš„æäº¤åˆ°åˆ†æ”¯
-settings.protect_branch_name_pattern=å—ä¿æŠ¤çš„åˆ†æ”¯å称模å¼
-settings.protect_branch_name_pattern_desc=åˆ†æ”¯ä¿æŠ¤çš„å称匹é…规则。语法请å‚阅 <a href="%s">文档</a> 。如:main, release/**
-settings.protect_patterns=规则
-settings.protect_protected_file_patterns=å—ä¿æŠ¤çš„æ–‡ä»¶æ¨¡å¼(ä½¿ç”¨åˆ†å· ';' 分隔):
-settings.protect_protected_file_patterns_desc=å³ä½¿ç”¨æˆ·æœ‰æƒæ·»åŠ ã€ç¼–辑或删除此分支中的文件,也ä¸å…许直接更改å—ä¿æŠ¤çš„æ–‡ä»¶ã€‚ å¯ä»¥ä½¿ç”¨åˆ†å· (';') 分隔多个模å¼ã€‚ è§<a href='%[1]s'>%[2]s</a>文档了解模å¼è¯­æ³•。例如: <code>.drone.yml</code>, <code>/docs/**/*.txt</code>
-settings.protect_unprotected_file_patterns=ä¸å—ä¿æŠ¤çš„æ–‡ä»¶æ¨¡å¼(ä½¿ç”¨åˆ†å· ';' 分隔):
-settings.protect_unprotected_file_patterns_desc=如果用户有写æƒé™ï¼Œåˆ™å…许直接更改的ä¸å—ä¿æŠ¤çš„æ–‡ä»¶ï¼Œä»¥ç»•è¿‡æŽ¨é€é™åˆ¶ã€‚å¯ä»¥ä½¿ç”¨åˆ†å·åˆ†éš”å¤šä¸ªæ¨¡å¼ (';')。 è§ <a href='%[1]s'>%[2]s</a> 文档了解模å¼è¯­æ³•。例如: <code>.drone.yml</code>, <code>/docs/**/*.txt</code>
+settings.protect_branch_name_pattern=å—ä¿æŠ¤çš„åˆ†æ”¯å称表达å¼
+settings.protect_branch_name_pattern_desc=åˆ†æ”¯ä¿æŠ¤çš„å称匹é…表达å¼ã€‚语法请å‚阅 <a href="%s">文档</a> 。如:main, release/**
+settings.protect_patterns=表达å¼
+settings.protect_protected_file_patterns=å—ä¿æŠ¤çš„æ–‡ä»¶è¡¨è¾¾å¼ï¼ˆä½¿ç”¨åˆ†å·ã€Œ;ã€åˆ†éš”):
+settings.protect_protected_file_patterns_desc=å³ä½¿ç”¨æˆ·æœ‰æƒæ·»åŠ ã€ç¼–辑或删除此分支中的文件,也ä¸å…许直接更改å—ä¿æŠ¤çš„æ–‡ä»¶ã€‚ å¯ä»¥ä½¿ç”¨åˆ†å·ã€Œ;ã€åˆ†éš”多个表达å¼ã€‚ è§<a href='%[1]s'>%[2]s</a>文档了解表达å¼è¯­æ³•。例如: <code>.drone.yml</code>, <code>/docs/**/*.txt</code>。
+settings.protect_unprotected_file_patterns=ä¸å—ä¿æŠ¤çš„æ–‡ä»¶è¡¨è¾¾å¼ï¼ˆä½¿ç”¨åˆ†å·ã€Œ;ã€åˆ†éš”):
+settings.protect_unprotected_file_patterns_desc=如果用户有写æƒé™ï¼Œåˆ™å…许直接更改的ä¸å—ä¿æŠ¤çš„æ–‡ä»¶ï¼Œä»¥ç»•è¿‡æŽ¨é€é™åˆ¶ã€‚å¯ä»¥ä½¿ç”¨åˆ†å·åˆ†éš”多个表达å¼ã€Œ;ã€ã€‚ è§ <a href='%[1]s'>%[2]s</a> 文档了解表达å¼è¯­æ³•。例如: <code>.drone.yml</code>, <code>/docs/**/*.txt</code>。
settings.add_protected_branch=å¯ç”¨ä¿æŠ¤
settings.delete_protected_branch=ç¦ç”¨ä¿æŠ¤
settings.update_protect_branch_success=åˆ†æ”¯ä¿æŠ¤è§„åˆ™ã€Œ%sã€æ›´æ–°æˆåŠŸã€‚
@@ -2537,15 +2537,15 @@ settings.protected_branch_required_rule_name=必须填写规则åç§°
settings.protected_branch_duplicate_rule_name=规则å称已存在
settings.protected_branch_required_approvals_min=所需的审批数ä¸èƒ½ä¸ºè´Ÿæ•°ã€‚
settings.tags=标签
-settings.tags.protection=Gitæ ‡ç­¾ä¿æŠ¤
-settings.tags.protection.pattern=Git标签模å¼
+settings.tags.protection=æ ‡ç­¾ä¿æŠ¤
+settings.tags.protection.pattern=标签表达å¼
settings.tags.protection.allowed=å…许列表
settings.tags.protection.allowed.users=å…许的账å·
settings.tags.protection.allowed.teams=å…许的团队
settings.tags.protection.allowed.noone=æ— 
-settings.tags.protection.create=ä¿æŠ¤Git标签
-settings.tags.protection.none=没有å—ä¿æŠ¤çš„Git标签
-settings.tags.protection.pattern.description=您å¯ä»¥ä½¿ç”¨å•个å称或 glob 模å¼åŒ¹é…æˆ–æ­£åˆ™è¡¨è¾¾å¼æ¥åŒ¹é…多个标签。了解详情请访问 <a target="_blank" rel="noopener" href="%s">ä¿æŠ¤ Git 标签指å—</a>。
+settings.tags.protection.create=ä¿æŠ¤æ ‡ç­¾
+settings.tags.protection.none=没有å—ä¿æŠ¤çš„æ ‡ç­¾ã€‚
+settings.tags.protection.pattern.description=您å¯ä»¥ä½¿ç”¨å•个å称或 glob 表达å¼åŒ¹é…æˆ–æ­£åˆ™è¡¨è¾¾å¼æ¥åŒ¹é…多个标签。了解详情请访问 <a target="_blank" rel="noopener" href="%s">ä¿æŠ¤æ ‡ç­¾æŒ‡å—</a>。
settings.bot_token=Bot 令牌
settings.chat_id=èŠå¤© ID
settings.thread_id=线程 ID
@@ -2571,7 +2571,7 @@ settings.archive.success=仓库已æˆåŠŸå½’æ¡£ã€‚
settings.archive.error=仓库在归档时出现异常。请通过日志获å–详细信æ¯ã€‚
settings.archive.error_ismirror=请ä¸è¦å¯¹é•œåƒä»“库归档,谢谢ï¼
settings.archive.branchsettings_unavailable=已归档仓库无法进行分支设置。
-settings.archive.tagsettings_unavailable=已归档仓库的Git标签设置ä¸å¯ç”¨ã€‚
+settings.archive.tagsettings_unavailable=已归档仓库的标签设置ä¸å¯ç”¨ã€‚
settings.archive.mirrors_unavailable=如果仓库已归档,镜åƒå°†ä¸å¯ç”¨ã€‚
settings.unarchive.button=撤销仓库归档
settings.unarchive.header=撤销此仓库归档
@@ -2672,7 +2672,7 @@ diff.submodule_updated=å­æ¨¡å— %[1]s 已更新:%[2]s
releases.desc=跟踪项目版本和下载。
release.releases=å‘布
release.detail=å‘布详情
-release.tags=Git标签
+release.tags=标签
release.new_release=å‘布新版
release.draft=è‰ç¨¿
release.prerelease=预å‘布
@@ -2701,16 +2701,16 @@ release.publish=å‘布版本
release.save_draft=ä¿å­˜è‰ç¨¿
release.edit_release=ä¿å­˜æ­¤æ¬¡å‘布
release.delete_release=删除å‘布
-release.delete_tag=删除 Git标签
+release.delete_tag=删除标签
release.deletion=删除å‘布
-release.deletion_desc=删除版本å‘布åªä¼šä»Ž Gitea 中移除。这ä¸ä¼šå½±å“ Git çš„æ ‡ç­¾ä»¥åŠæ‚¨ä»“库的内容和历å²ã€‚是å¦ç»§ç»­ï¼Ÿ
+release.deletion_desc=删除å‘布åªä¼šä»Ž Gitea 中移除å‘布。这ä¸ä¼šå½±å“ Git çš„æ ‡ç­¾ä»¥åŠæ‚¨ä»“库的内容和历å²ã€‚是å¦ç»§ç»­ï¼Ÿ
release.deletion_success=该å‘布已删除。
-release.deletion_tag_desc=将从仓库中删除此 Git标签。仓库内容和历å²è®°å½•ä¿æŒä¸å˜ã€‚ç»§ç»­å—?
-release.deletion_tag_success=该 Git标签已删除。
+release.deletion_tag_desc=将从仓库中删除此标签。仓库内容和历å²è®°å½•ä¿æŒä¸å˜ã€‚ç»§ç»­å—?
+release.deletion_tag_success=该标签已删除。
release.tag_name_already_exist=使用此标签åç§°çš„å‘布已ç»å­˜åœ¨ã€‚
release.tag_name_invalid=标签å称无效。
-release.tag_name_protected=Git标签åç§°å·²å—ä¿æŠ¤ã€‚
-release.tag_already_exist=æ­¤ Git标签å称已存在。
+release.tag_name_protected=标签åå·²å—ä¿æŠ¤ã€‚
+release.tag_already_exist=此标签å已存在。
release.downloads=下载附件
release.download_count=下载:%s
release.add_tag_msg=使用å‘布的标题和内容作为标签消æ¯ã€‚
@@ -2809,7 +2809,7 @@ team_unit_desc=å…许访问仓库å•å…ƒ
team_unit_disabled=(å·²ç¦ç”¨)
form.name_reserved=组织å称「%sã€æ˜¯ä¿ç•™çš„。
-form.name_pattern_not_allowed=仓库å称中ä¸å…许使用「%sã€ã€‚
+form.name_pattern_not_allowed=组织å中ä¸å…许使用「%sã€æ ¼å¼ã€‚
form.create_org_not_allowed=此账å·ç¦æ­¢åˆ›å»ºç»„织
settings=组织设置
@@ -2840,7 +2840,7 @@ settings.delete_org_title=删除组织
settings.delete_org_desc=此组织将会永久删除,确认继续å—?
settings.hooks_desc=在此处添加的 Web é’©å­å°†ä¼šåº”用到该组织下的 <strong>所有仓库</strong>。
-settings.labels_desc=添加能够被该组织下的 <strong>所有仓库</strong> 的工å•使用的标签。
+settings.labels_desc=添加能够被该组织下的 <strong>所有仓库</strong> 的工å•使用的标记。
members.membership_visibility=æˆå‘˜å¯è§æ€§ï¼š
members.public=å¯è§
@@ -2960,11 +2960,11 @@ dashboard.task.cancelled=任务: %[1]s 已喿¶ˆ: %[3]s
dashboard.task.error=任务中的错误: %[1]s: %[3]s
dashboard.task.finished=任务: %[2]s å¯åŠ¨çš„ %[1]s 已完æˆ
dashboard.task.unknown=未知任务: %[1]s
-dashboard.cron.started=已开始计划任务:%[1]s
+dashboard.cron.started=计划任务:%[1]s å·²å¯åЍ
dashboard.cron.process=计划任务:%[1]s
-dashboard.cron.cancelled=定时任务: %[1]s 已喿¶ˆ: %[3]s
-dashboard.cron.error=任务中的错误: %s: %[3]s
-dashboard.cron.finished=任务:%[1]s å·²ç»å®Œæˆ
+dashboard.cron.cancelled=计划任务:%[1]s 已喿¶ˆï¼š%[3]s
+dashboard.cron.error=计划任务错误: %s: %[3]s
+dashboard.cron.finished=计划任务:%[1]s 已完æˆ
dashboard.delete_inactive_accounts=åˆ é™¤æ‰€æœ‰æœªæ¿€æ´»çš„å¸æˆ·
dashboard.delete_inactive_accounts.started=删除所有未激活的账户任务已å¯åŠ¨ã€‚
dashboard.delete_repo_archives=删除所有仓库的存档(ZIPã€TARã€GZ等)
@@ -3023,9 +3023,9 @@ dashboard.delete_old_actions.started=已开始从数æ®åº“中删除所有旧工ä
dashboard.update_checker=更新检查器
dashboard.delete_old_system_notices=从数æ®åº“中删除所有旧系统通知
dashboard.gc_lfs=垃圾回收 LFS 元数æ®
-dashboard.stop_zombie_tasks=åœæ­¢åƒµå°¸ä»»åŠ¡
-dashboard.stop_endless_tasks=åœæ­¢æ— é™å¾ªçŽ¯çš„å·¥ä½œæµ
-dashboard.cancel_abandoned_jobs=å–æ¶ˆå·²æ”¾å¼ƒçš„工作æµ
+dashboard.stop_zombie_tasks=åœæ­¢åƒµå°¸å·¥ä½œæµä»»åŠ¡
+dashboard.stop_endless_tasks=åœæ­¢æ— é™å¾ªçŽ¯çš„å·¥ä½œæµä»»åŠ¡
+dashboard.cancel_abandoned_jobs=å–æ¶ˆå·²æ”¾å¼ƒçš„工作æµä»»åŠ¡
dashboard.start_schedule_tasks=å¯åŠ¨å·¥ä½œæµè®¡åˆ’任务
dashboard.sync_branch.started=åˆ†æ”¯åŒæ­¥å·²å¼€å§‹
dashboard.sync_tag.started=æ ‡ç­¾åŒæ­¥å·²å¼€å§‹
@@ -3098,7 +3098,7 @@ emails.filter_sort.email_reverse=邮箱(倒åºï¼‰
emails.filter_sort.name=用户å
emails.filter_sort.name_reverse=用户å(倒åº)
emails.updated=邮箱已更新
-emails.not_updated=无法更新请求的邮箱地å€ï¼š %v
+emails.not_updated=无法更新请求的邮箱地å€ï¼š%v
emails.duplicate_active=此邮箱地å€å·²è¢«å¦ä¸€ä¸ªç”¨æˆ·æ¿€æ´»ä½¿ç”¨ã€‚
emails.change_email_header=更新邮箱属性
emails.change_email_text=æ‚¨ç¡®å®šè¦æ›´æ–°è¯¥é‚®ç®±åœ°å€å—?
@@ -3208,8 +3208,8 @@ auths.openIdConnectAutoDiscoveryURL=OpenID 连接自动å‘现 URL
auths.oauth2_use_custom_url=使用自定义的 URL è€Œä¸æ˜¯é»˜è®¤çš„ URL
auths.oauth2_tokenURL=令牌 URL
auths.oauth2_authURL=æŽˆæƒ URL
-auths.oauth2_profileURL=Profile URL
-auths.oauth2_emailURL=邮件 URL
+auths.oauth2_profileURL=个人资料 URL
+auths.oauth2_emailURL=邮箱 URL
auths.skip_local_two_fa=跳过本地两步验è¯
auths.skip_local_two_fa_helper=ä¸è®¾ç½®æ„味ç€è®¾ç½®äº†ä¸¤æ­¥éªŒè¯çš„æœ¬åœ°ç”¨æˆ·ä»ç„¶éœ€è¦é€šè¿‡ä¸¤æ­¥éªŒè¯æ‰èƒ½ç™»å½•
auths.oauth2_tenant=租户
@@ -3264,7 +3264,7 @@ auths.deletion_success=è®¤è¯æºå·²ç»æ›´æ–°ã€‚
auths.login_source_exist=è®¤è¯æºã€Œ%sã€å·²ç»å­˜åœ¨ã€‚
auths.login_source_of_type_exist=æ­¤ç±»åž‹çš„è®¤è¯æºå·²å­˜åœ¨ã€‚
auths.unable_to_initialize_openid=无法åˆå§‹åŒ– OpenID Connect æä¾›å•†ï¼š%s
-auths.invalid_openIdConnectAutoDiscoveryURL=无效的 Auto Discovery URL (这必须是一个以 http:// 或 https://开头的有效的 URL)
+auths.invalid_openIdConnectAutoDiscoveryURL=无效的自动å‘现 URL(这必须是一个以 http:// 或 https:// 开头的有效的 URL)
config.server_config=æœåС噍é…ç½®
config.app_name=站点åç§°
@@ -3305,7 +3305,7 @@ config.db_type=类型
config.db_host=主机
config.db_name=æ•°æ®åº“åç§°
config.db_user=用户å
-config.db_schema=架构模å¼
+config.db_schema=æž¶æž„
config.db_ssl_mode=SSL
config.db_path=æ•°æ®åº“路径
@@ -3314,7 +3314,7 @@ config.register_email_confirm=需è¦é‚®ä»¶ç¡®è®¤æ³¨å†Œ
config.disable_register=ç¦æ­¢ç”¨æˆ·æ³¨å†Œ
config.allow_only_internal_registration=ä»…å…许通过 Gitea 进行注册
config.allow_only_external_registration=ä»…å…许通过外部æœåŠ¡æ³¨å†Œ
-config.enable_openid_signup=å¯ç”¨ OpenID 自注册
+config.enable_openid_signup=å¯ç”¨ OpenID 自助注册
config.enable_openid_signin=å¯ç”¨ OpenID 登录
config.show_registration_button=显示注册按钮
config.require_sign_in_view=å¯ç”¨ç™»å½•访问é™åˆ¶
@@ -3406,7 +3406,7 @@ config.set_setting_failed=设置 %s 失败
monitor.stats=统计
-monitor.cron=Cron 任务
+monitor.cron=计划任务
monitor.name=任务åç§°
monitor.schedule=任务安排
monitor.next=下次执行时间
@@ -3476,10 +3476,10 @@ rename_repo=é‡å‘½å仓库 <code>%[1]s</code> 为 <a href="%[2]s">%[3]s</a>
commit_repo=推é€åˆ°äº†ä»“库 <a href="%[1]s">%[4]s</a> çš„ <a href="%[2]s">%[3]s</a> 分支
create_issue=`åˆ›å»ºäº†å·¥å• <a href="%[1]s">%[3]s#%[2]s</a>`
close_issue=`å…³é—­äº†å·¥å• <a href="%[1]s">%[3]s#%[2]s</a>`
-reopen_issue=`釿–°å¼€å¯äº†å·¥å• <a href="%[1]s">%[3]s#%[2]s</a>`
+reopen_issue=`釿–°æ‰“å¼€äº†å·¥å• <a href="%[1]s">%[3]s#%[2]s</a>`
create_pull_request=`创建了åˆå¹¶è¯·æ±‚ <a href="%[1]s">%[3]s#%[2]s</a>`
close_pull_request=`关闭了åˆå¹¶è¯·æ±‚ <a href="%[1]s">%[3]s#%[2]s</a>`
-reopen_pull_request=`釿–°å¼€å¯äº†åˆå¹¶è¯·æ±‚ <a href="%[1]s">%[3]s#%[2]s</a>`
+reopen_pull_request=`釿–°æ‰“开了åˆå¹¶è¯·æ±‚ <a href="%[1]s">%[3]s#%[2]s</a>`
comment_issue=`è¯„è®ºäº†å·¥å• <a href="%[1]s">%[3]s#%[2]s</a>`
comment_pull=`评论了åˆå¹¶è¯·æ±‚ <a href="%[1]s">%[3]s#%[2]s</a>`
merge_pull_request=`åˆå¹¶äº†åˆå¹¶è¯·æ±‚ <a href="%[1]s">%[3]s#%[2]s</a>`
@@ -3624,7 +3624,7 @@ container.images=镜åƒ
container.digest=摘è¦
container.multi_arch=OS / Arch
container.layers=镜åƒå±‚
-container.labels=标签
+container.labels=标记
container.labels.key=é”®
container.labels.value=值
cran.registry=在您的 <code>Rprofile.site</code> 文件中设置此注册中心:
@@ -3690,8 +3690,8 @@ settings.delete.error=删除软件包失败。
owner.settings.cargo.title=Cargo 注册中心索引
owner.settings.cargo.initialize=åˆå§‹åŒ–索引
owner.settings.cargo.initialize.description=使用 Cargo 注册中心时需è¦ä¸€ä¸ªç‰¹æ®Šç´¢å¼•çš„ Git ä»“åº“ã€‚ä½¿ç”¨æ­¤é€‰é¡¹å°†ï¼ˆé‡æ–°ï¼‰åˆ›å»ºä»“库并自动é…置它。
-owner.settings.cargo.initialize.error=åˆå§‹åŒ–Cargo索引失败: %v
-owner.settings.cargo.initialize.success=Cargoç´¢å¼•å·²ç»æˆåŠŸåˆ›å»ºã€‚
+owner.settings.cargo.initialize.error=åˆå§‹åŒ– Cargo 索引失败: %v
+owner.settings.cargo.initialize.success=Cargo ç´¢å¼•å·²ç»æˆåŠŸåˆ›å»ºã€‚
owner.settings.cargo.rebuild=é‡å»ºç´¢å¼•
owner.settings.cargo.rebuild.description=如果索引与存储的 Cargo 包ä¸åŒæ­¥ï¼Œé‡å»ºå¯èƒ½ä¼šæœ‰ç”¨ã€‚
owner.settings.cargo.rebuild.error=无法é‡å»º Cargo 索引: %v
@@ -3704,7 +3704,7 @@ owner.settings.cleanuprules.preview=清ç†è§„则预览
owner.settings.cleanuprules.preview.overview=%d 个软件包计划被删除。
owner.settings.cleanuprules.preview.none=清ç†è§„则与任何软件包都ä¸åŒ¹é…。
owner.settings.cleanuprules.enabled=å¯ç”¨
-owner.settings.cleanuprules.pattern_full_match=应用规则到完整软件包åç§°
+owner.settings.cleanuprules.pattern_full_match=应用表达å¼åˆ°å®Œæ•´è½¯ä»¶åŒ…åç§°
owner.settings.cleanuprules.keep.title=与这些规则相匹é…的版本å³ä½¿ä¸Žä¸‹é¢çš„删除规则相匹é…,也将予以ä¿ç•™ã€‚
owner.settings.cleanuprules.keep.count=ä¿ç•™æœ€æ–°çš„
owner.settings.cleanuprules.keep.count.1=æ¯ä¸ªè½¯ä»¶åŒ…1个版本
@@ -3727,8 +3727,8 @@ none=还没有密钥。
; These keys are also for "edit secret", the keys are kept as-is to avoid unnecessary re-translation
creation.description=组织æè¿°
-creation.name_placeholder=ä¸åŒºåˆ†å¤§å°å†™ï¼Œå­—æ¯æ•°å­—或下划线ä¸èƒ½ä»¥ GITEA_ 或 GITHUB_ 开头。
-creation.value_placeholder=输入任何内容,开头和结尾的空白都会被çœç•¥
+creation.name_placeholder=ä¸åŒºåˆ†å¤§å°å†™ï¼Œä»…é™å­—æ¯æ•°å­—或下划线且ä¸èƒ½ä»¥ GITEA_ 或 GITHUB_ 开头
+creation.value_placeholder=输入任何内容,开头和结尾的空白将会被忽略。
creation.description_placeholder=输入简短æè¿°ï¼ˆå¯é€‰ï¼‰ã€‚
save_success=密钥「%sã€ä¿å­˜æˆåŠŸã€‚
@@ -3737,8 +3737,8 @@ save_failed=密钥ä¿å­˜å¤±è´¥ã€‚
add_secret=添加密钥
edit_secret=编辑密钥
deletion=删除密钥
-deletion.description=删除密钥是永久性的,无法撤消。继续å—?
-deletion.success=此密钥已被删除。
+deletion.description=删除密钥是永久性的且无法撤消。继续?
+deletion.success=此密钥已删除。
deletion.failed=删除密钥失败。
management=密钥管ç†
@@ -3765,7 +3765,7 @@ runners.id=ID
runners.name=åç§°
runners.owner_type=类型
runners.description=æè¿°
-runners.labels=标签
+runners.labels=标记
runners.last_online=上次在线时间
runners.runner_title=è¿è¡Œå™¨
runners.task_list=最近在此è¿è¡Œå™¨ä¸Šçš„任务
@@ -3799,7 +3799,7 @@ runs.commit=æäº¤
runs.scheduled=已计划的
runs.pushed_by=推é€è€…
runs.invalid_workflow_helper=工作æµé…置文件无效。请检查您的é…置文件:%s
-runs.no_matching_online_runner_helper=æ²¡æœ‰åŒ¹é… %s 标签的在线è¿è¡Œå™¨
+runs.no_matching_online_runner_helper=æ²¡æœ‰åŒ¹é… %s 标记的在线è¿è¡Œå™¨
runs.no_job_without_needs=工作æµå¿…须包å«è‡³å°‘一个没有ä¾èµ–关系的作业。
runs.no_job=工作æµå¿…须包å«è‡³å°‘一个作业
runs.actor=æ“作者
diff --git a/package-lock.json b/package-lock.json
index 780b95d592..8a2f3e0db7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -37,16 +37,16 @@
"license-checker-webpack-plugin": "0.2.1",
"mermaid": "11.6.0",
"mini-css-extract-plugin": "2.9.2",
- "minimatch": "10.0.1",
+ "minimatch": "10.0.2",
"monaco-editor": "0.52.2",
"monaco-editor-webpack-plugin": "7.1.0",
"pdfobject": "2.3.1",
"perfect-debounce": "1.0.0",
- "postcss": "8.5.4",
+ "postcss": "8.5.5",
"postcss-loader": "8.1.1",
- "postcss-nesting": "13.0.1",
+ "postcss-nesting": "13.0.2",
"sortablejs": "1.15.6",
- "swagger-ui-dist": "5.24.0",
+ "swagger-ui-dist": "5.24.1",
"tailwindcss": "3.4.17",
"throttle-debounce": "5.0.2",
"tinycolor2": "1.6.0",
@@ -66,7 +66,7 @@
},
"devDependencies": {
"@eslint-community/eslint-plugin-eslint-comments": "4.5.0",
- "@playwright/test": "1.52.0",
+ "@playwright/test": "1.53.0",
"@stoplight/spectral-cli": "6.15.0",
"@stylistic/eslint-plugin-js": "3.1.0",
"@stylistic/stylelint-plugin": "3.1.2",
@@ -80,25 +80,25 @@
"@types/throttle-debounce": "5.0.2",
"@types/tinycolor2": "1.4.6",
"@types/toastify-js": "1.12.4",
- "@typescript-eslint/eslint-plugin": "8.33.1",
- "@typescript-eslint/parser": "8.33.1",
+ "@typescript-eslint/eslint-plugin": "8.34.0",
+ "@typescript-eslint/parser": "8.34.0",
"@vitejs/plugin-vue": "5.2.4",
- "@vitest/eslint-plugin": "1.2.1",
+ "@vitest/eslint-plugin": "1.2.2",
"eslint": "8.57.0",
"eslint-import-resolver-typescript": "4.4.3",
"eslint-plugin-array-func": "4.0.0",
"eslint-plugin-github": "5.0.2",
- "eslint-plugin-import-x": "4.15.1",
+ "eslint-plugin-import-x": "4.15.2",
"eslint-plugin-no-jquery": "3.1.1",
"eslint-plugin-no-use-extend-native": "0.5.0",
"eslint-plugin-playwright": "2.2.0",
- "eslint-plugin-regexp": "2.8.0",
+ "eslint-plugin-regexp": "2.9.0",
"eslint-plugin-sonarjs": "3.0.2",
"eslint-plugin-unicorn": "56.0.1",
"eslint-plugin-vue": "10.2.0",
"eslint-plugin-vue-scoped-css": "2.10.0",
"eslint-plugin-wc": "3.0.1",
- "happy-dom": "17.6.3",
+ "happy-dom": "18.0.1",
"markdownlint-cli": "0.45.0",
"material-icon-theme": "5.23.0",
"nolyfill": "1.0.44",
@@ -113,7 +113,7 @@
"type-fest": "4.41.0",
"updates": "16.4.2",
"vite-string-plugin": "1.4.4",
- "vitest": "3.2.2",
+ "vitest": "3.2.3",
"vue-tsc": "2.2.10"
},
"engines": {
@@ -1054,10 +1054,17 @@
"url": "https://github.com/sponsors/epoberezkin"
}
},
+ "node_modules/@eslint/eslintrc/node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@eslint/eslintrc/node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1177,10 +1184,17 @@
"node": ">=10.10.0"
}
},
+ "node_modules/@humanwhocodes/config-array/node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1546,9 +1560,9 @@
}
},
"node_modules/@napi-rs/wasm-runtime": {
- "version": "0.2.10",
- "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.10.tgz",
- "integrity": "sha512-bCsCyeZEwVErsGmyPNSzwfwFn4OdxBj0mmv6hOFucB/k81Ojdu68RbZdxYsRQUPc9l6SU5F/cG+bXgWs3oUgsQ==",
+ "version": "0.2.11",
+ "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.11.tgz",
+ "integrity": "sha512-9DPkXtvHydrcOsopiYpUgPHpmj0HWZKMUnL2dZqpvC42lsratuBG06V5ipyno0fUek5VlFsNQ+AcFATSrJXgMA==",
"dev": true,
"license": "MIT",
"optional": true,
@@ -1624,13 +1638,13 @@
}
},
"node_modules/@playwright/test": {
- "version": "1.52.0",
- "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.52.0.tgz",
- "integrity": "sha512-uh6W7sb55hl7D6vsAeA+V2p5JnlAqzhqFyF0VcJkKZXkgnFcVG9PziERRHQfPLfNGx1C292a4JqbWzhR8L4R1g==",
+ "version": "1.53.0",
+ "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.53.0.tgz",
+ "integrity": "sha512-15hjKreZDcp7t6TL/7jkAo6Df5STZN09jGiv5dbP9A6vMVncXRqE7/B2SncsyOwrkZRBH2i6/TPOL8BVmm3c7w==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "playwright": "1.52.0"
+ "playwright": "1.53.0"
},
"bin": {
"playwright": "cli.js"
@@ -1706,9 +1720,9 @@
"license": "MIT"
},
"node_modules/@rollup/rollup-android-arm-eabi": {
- "version": "4.42.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.42.0.tgz",
- "integrity": "sha512-gldmAyS9hpj+H6LpRNlcjQWbuKUtb94lodB9uCz71Jm+7BxK1VIOo7y62tZZwxhA7j1ylv/yQz080L5WkS+LoQ==",
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.43.0.tgz",
+ "integrity": "sha512-Krjy9awJl6rKbruhQDgivNbD1WuLb8xAclM4IR4cN5pHGAs2oIMMQJEiC3IC/9TZJ+QZkmZhlMO/6MBGxPidpw==",
"cpu": [
"arm"
],
@@ -1720,9 +1734,9 @@
]
},
"node_modules/@rollup/rollup-android-arm64": {
- "version": "4.42.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.42.0.tgz",
- "integrity": "sha512-bpRipfTgmGFdCZDFLRvIkSNO1/3RGS74aWkJJTFJBH7h3MRV4UijkaEUeOMbi9wxtxYmtAbVcnMtHTPBhLEkaw==",
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.43.0.tgz",
+ "integrity": "sha512-ss4YJwRt5I63454Rpj+mXCXicakdFmKnUNxr1dLK+5rv5FJgAxnN7s31a5VchRYxCFWdmnDWKd0wbAdTr0J5EA==",
"cpu": [
"arm64"
],
@@ -1734,9 +1748,9 @@
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
- "version": "4.42.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.42.0.tgz",
- "integrity": "sha512-JxHtA081izPBVCHLKnl6GEA0w3920mlJPLh89NojpU2GsBSB6ypu4erFg/Wx1qbpUbepn0jY4dVWMGZM8gplgA==",
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.43.0.tgz",
+ "integrity": "sha512-eKoL8ykZ7zz8MjgBenEF2OoTNFAPFz1/lyJ5UmmFSz5jW+7XbH1+MAgCVHy72aG59rbuQLcJeiMrP8qP5d/N0A==",
"cpu": [
"arm64"
],
@@ -1748,9 +1762,9 @@
]
},
"node_modules/@rollup/rollup-darwin-x64": {
- "version": "4.42.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.42.0.tgz",
- "integrity": "sha512-rv5UZaWVIJTDMyQ3dCEK+m0SAn6G7H3PRc2AZmExvbDvtaDc+qXkei0knQWcI3+c9tEs7iL/4I4pTQoPbNL2SA==",
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.43.0.tgz",
+ "integrity": "sha512-SYwXJgaBYW33Wi/q4ubN+ldWC4DzQY62S4Ll2dgfr/dbPoF50dlQwEaEHSKrQdSjC6oIe1WgzosoaNoHCdNuMg==",
"cpu": [
"x64"
],
@@ -1762,9 +1776,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-arm64": {
- "version": "4.42.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.42.0.tgz",
- "integrity": "sha512-fJcN4uSGPWdpVmvLuMtALUFwCHgb2XiQjuECkHT3lWLZhSQ3MBQ9pq+WoWeJq2PrNxr9rPM1Qx+IjyGj8/c6zQ==",
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.43.0.tgz",
+ "integrity": "sha512-SV+U5sSo0yujrjzBF7/YidieK2iF6E7MdF6EbYxNz94lA+R0wKl3SiixGyG/9Klab6uNBIqsN7j4Y/Fya7wAjQ==",
"cpu": [
"arm64"
],
@@ -1776,9 +1790,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-x64": {
- "version": "4.42.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.42.0.tgz",
- "integrity": "sha512-CziHfyzpp8hJpCVE/ZdTizw58gr+m7Y2Xq5VOuCSrZR++th2xWAz4Nqk52MoIIrV3JHtVBhbBsJcAxs6NammOQ==",
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.43.0.tgz",
+ "integrity": "sha512-J7uCsiV13L/VOeHJBo5SjasKiGxJ0g+nQTrBkAsmQBIdil3KhPnSE9GnRon4ejX1XDdsmK/l30IYLiAaQEO0Cg==",
"cpu": [
"x64"
],
@@ -1790,9 +1804,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
- "version": "4.42.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.42.0.tgz",
- "integrity": "sha512-UsQD5fyLWm2Fe5CDM7VPYAo+UC7+2Px4Y+N3AcPh/LdZu23YcuGPegQly++XEVaC8XUTFVPscl5y5Cl1twEI4A==",
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.43.0.tgz",
+ "integrity": "sha512-gTJ/JnnjCMc15uwB10TTATBEhK9meBIY+gXP4s0sHD1zHOaIh4Dmy1X9wup18IiY9tTNk5gJc4yx9ctj/fjrIw==",
"cpu": [
"arm"
],
@@ -1804,9 +1818,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
- "version": "4.42.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.42.0.tgz",
- "integrity": "sha512-/i8NIrlgc/+4n1lnoWl1zgH7Uo0XK5xK3EDqVTf38KvyYgCU/Rm04+o1VvvzJZnVS5/cWSd07owkzcVasgfIkQ==",
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.43.0.tgz",
+ "integrity": "sha512-ZJ3gZynL1LDSIvRfz0qXtTNs56n5DI2Mq+WACWZ7yGHFUEirHBRt7fyIk0NsCKhmRhn7WAcjgSkSVVxKlPNFFw==",
"cpu": [
"arm"
],
@@ -1818,9 +1832,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
- "version": "4.42.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.42.0.tgz",
- "integrity": "sha512-eoujJFOvoIBjZEi9hJnXAbWg+Vo1Ov8n/0IKZZcPZ7JhBzxh2A+2NFyeMZIRkY9iwBvSjloKgcvnjTbGKHE44Q==",
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.43.0.tgz",
+ "integrity": "sha512-8FnkipasmOOSSlfucGYEu58U8cxEdhziKjPD2FIa0ONVMxvl/hmONtX/7y4vGjdUhjcTHlKlDhw3H9t98fPvyA==",
"cpu": [
"arm64"
],
@@ -1832,9 +1846,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
- "version": "4.42.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.42.0.tgz",
- "integrity": "sha512-/3NrcOWFSR7RQUQIuZQChLND36aTU9IYE4j+TB40VU78S+RA0IiqHR30oSh6P1S9f9/wVOenHQnacs/Byb824g==",
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.43.0.tgz",
+ "integrity": "sha512-KPPyAdlcIZ6S9C3S2cndXDkV0Bb1OSMsX0Eelr2Bay4EsF9yi9u9uzc9RniK3mcUGCLhWY9oLr6er80P5DE6XA==",
"cpu": [
"arm64"
],
@@ -1846,9 +1860,9 @@
]
},
"node_modules/@rollup/rollup-linux-loongarch64-gnu": {
- "version": "4.42.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.42.0.tgz",
- "integrity": "sha512-O8AplvIeavK5ABmZlKBq9/STdZlnQo7Sle0LLhVA7QT+CiGpNVe197/t8Aph9bhJqbDVGCHpY2i7QyfEDDStDg==",
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.43.0.tgz",
+ "integrity": "sha512-HPGDIH0/ZzAZjvtlXj6g+KDQ9ZMHfSP553za7o2Odegb/BEfwJcR0Sw0RLNpQ9nC6Gy8s+3mSS9xjZ0n3rhcYg==",
"cpu": [
"loong64"
],
@@ -1860,9 +1874,9 @@
]
},
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
- "version": "4.42.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.42.0.tgz",
- "integrity": "sha512-6Qb66tbKVN7VyQrekhEzbHRxXXFFD8QKiFAwX5v9Xt6FiJ3BnCVBuyBxa2fkFGqxOCSGGYNejxd8ht+q5SnmtA==",
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.43.0.tgz",
+ "integrity": "sha512-gEmwbOws4U4GLAJDhhtSPWPXUzDfMRedT3hFMyRAvM9Mrnj+dJIFIeL7otsv2WF3D7GrV0GIewW0y28dOYWkmw==",
"cpu": [
"ppc64"
],
@@ -1874,9 +1888,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
- "version": "4.42.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.42.0.tgz",
- "integrity": "sha512-KQETDSEBamQFvg/d8jajtRwLNBlGc3aKpaGiP/LvEbnmVUKlFta1vqJqTrvPtsYsfbE/DLg5CC9zyXRX3fnBiA==",
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.43.0.tgz",
+ "integrity": "sha512-XXKvo2e+wFtXZF/9xoWohHg+MuRnvO29TI5Hqe9xwN5uN8NKUYy7tXUG3EZAlfchufNCTHNGjEx7uN78KsBo0g==",
"cpu": [
"riscv64"
],
@@ -1888,9 +1902,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-musl": {
- "version": "4.42.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.42.0.tgz",
- "integrity": "sha512-qMvnyjcU37sCo/tuC+JqeDKSuukGAd+pVlRl/oyDbkvPJ3awk6G6ua7tyum02O3lI+fio+eM5wsVd66X0jQtxw==",
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.43.0.tgz",
+ "integrity": "sha512-ruf3hPWhjw6uDFsOAzmbNIvlXFXlBQ4nk57Sec8E8rUxs/AI4HD6xmiiasOOx/3QxS2f5eQMKTAwk7KHwpzr/Q==",
"cpu": [
"riscv64"
],
@@ -1902,9 +1916,9 @@
]
},
"node_modules/@rollup/rollup-linux-s390x-gnu": {
- "version": "4.42.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.42.0.tgz",
- "integrity": "sha512-I2Y1ZUgTgU2RLddUHXTIgyrdOwljjkmcZ/VilvaEumtS3Fkuhbw4p4hgHc39Ypwvo2o7sBFNl2MquNvGCa55Iw==",
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.43.0.tgz",
+ "integrity": "sha512-QmNIAqDiEMEvFV15rsSnjoSmO0+eJLoKRD9EAa9rrYNwO/XRCtOGM3A5A0X+wmG+XRrw9Fxdsw+LnyYiZWWcVw==",
"cpu": [
"s390x"
],
@@ -1916,9 +1930,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
- "version": "4.42.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.42.0.tgz",
- "integrity": "sha512-Gfm6cV6mj3hCUY8TqWa63DB8Mx3NADoFwiJrMpoZ1uESbK8FQV3LXkhfry+8bOniq9pqY1OdsjFWNsSbfjPugw==",
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.43.0.tgz",
+ "integrity": "sha512-jAHr/S0iiBtFyzjhOkAics/2SrXE092qyqEg96e90L3t9Op8OTzS6+IX0Fy5wCt2+KqeHAkti+eitV0wvblEoQ==",
"cpu": [
"x64"
],
@@ -1930,9 +1944,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
- "version": "4.42.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.42.0.tgz",
- "integrity": "sha512-g86PF8YZ9GRqkdi0VoGlcDUb4rYtQKyTD1IVtxxN4Hpe7YqLBShA7oHMKU6oKTCi3uxwW4VkIGnOaH/El8de3w==",
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.43.0.tgz",
+ "integrity": "sha512-3yATWgdeXyuHtBhrLt98w+5fKurdqvs8B53LaoKD7P7H7FKOONLsBVMNl9ghPQZQuYcceV5CDyPfyfGpMWD9mQ==",
"cpu": [
"x64"
],
@@ -1944,9 +1958,9 @@
]
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
- "version": "4.42.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.42.0.tgz",
- "integrity": "sha512-+axkdyDGSp6hjyzQ5m1pgcvQScfHnMCcsXkx8pTgy/6qBmWVhtRVlgxjWwDp67wEXXUr0x+vD6tp5W4x6V7u1A==",
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.43.0.tgz",
+ "integrity": "sha512-wVzXp2qDSCOpcBCT5WRWLmpJRIzv23valvcTwMHEobkjippNf+C3ys/+wf07poPkeNix0paTNemB2XrHr2TnGw==",
"cpu": [
"arm64"
],
@@ -1958,9 +1972,9 @@
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
- "version": "4.42.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.42.0.tgz",
- "integrity": "sha512-F+5J9pelstXKwRSDq92J0TEBXn2nfUrQGg+HK1+Tk7VOL09e0gBqUHugZv7SW4MGrYj41oNCUe3IKCDGVlis2g==",
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.43.0.tgz",
+ "integrity": "sha512-fYCTEyzf8d+7diCw8b+asvWDCLMjsCEA8alvtAutqJOJp/wL5hs1rWSqJ1vkjgW0L2NB4bsYJrpKkiIPRR9dvw==",
"cpu": [
"ia32"
],
@@ -1972,9 +1986,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
- "version": "4.42.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.42.0.tgz",
- "integrity": "sha512-LpHiJRwkaVz/LqjHjK8LCi8osq7elmpwujwbXKNW88bM8eeGxavJIKKjkjpMHAh/2xfnrt1ZSnhTv41WYUHYmA==",
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.43.0.tgz",
+ "integrity": "sha512-SnGhLiE5rlK0ofq8kzuDkM0g7FN1s5VYY+YSMTibP7CqShxCQvqtNxTARS4xX4PFJfHjG0ZQYX9iGzI3FQh5Aw==",
"cpu": [
"x64"
],
@@ -2221,10 +2235,17 @@
"node": "^12.20 || >=14.13"
}
},
+ "node_modules/@stoplight/spectral-core/node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@stoplight/spectral-core/node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3005,12 +3026,12 @@
"license": "MIT"
},
"node_modules/@types/node": {
- "version": "22.15.30",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.30.tgz",
- "integrity": "sha512-6Q7lr06bEHdlfplU6YRbgG1SFBdlsfNC4/lX+SkhiTs0cpJkOElmWls8PxDFv4yY/xKb8Y6SO0OmSX4wgqTZbA==",
+ "version": "24.0.1",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.1.tgz",
+ "integrity": "sha512-MX4Zioh39chHlDJbKmEgydJDS3tspMP/lnQC67G3SWsTnb9NeYVWOjkxpOSy4oMfPs4StcWHwBrvUb4ybfnuaw==",
"license": "MIT",
"dependencies": {
- "undici-types": "~6.21.0"
+ "undici-types": "~7.8.0"
}
},
"node_modules/@types/normalize-package-data": {
@@ -3167,18 +3188,25 @@
"node": ">= 8"
}
},
+ "node_modules/@types/whatwg-mimetype": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@types/whatwg-mimetype/-/whatwg-mimetype-3.0.2.tgz",
+ "integrity": "sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@typescript-eslint/eslint-plugin": {
- "version": "8.33.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.33.1.tgz",
- "integrity": "sha512-TDCXj+YxLgtvxvFlAvpoRv9MAncDLBV2oT9Bd7YBGC/b/sEURoOYuIwLI99rjWOfY3QtDzO+mk0n4AmdFExW8A==",
+ "version": "8.34.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.34.0.tgz",
+ "integrity": "sha512-QXwAlHlbcAwNlEEMKQS2RCgJsgXrTJdjXT08xEgbPFa2yYQgVjBymxP5DrfrE7X7iodSzd9qBUHUycdyVJTW1w==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/regexpp": "^4.10.0",
- "@typescript-eslint/scope-manager": "8.33.1",
- "@typescript-eslint/type-utils": "8.33.1",
- "@typescript-eslint/utils": "8.33.1",
- "@typescript-eslint/visitor-keys": "8.33.1",
+ "@typescript-eslint/scope-manager": "8.34.0",
+ "@typescript-eslint/type-utils": "8.34.0",
+ "@typescript-eslint/utils": "8.34.0",
+ "@typescript-eslint/visitor-keys": "8.34.0",
"graphemer": "^1.4.0",
"ignore": "^7.0.0",
"natural-compare": "^1.4.0",
@@ -3192,7 +3220,7 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "@typescript-eslint/parser": "^8.33.1",
+ "@typescript-eslint/parser": "^8.34.0",
"eslint": "^8.57.0 || ^9.0.0",
"typescript": ">=4.8.4 <5.9.0"
}
@@ -3208,16 +3236,16 @@
}
},
"node_modules/@typescript-eslint/parser": {
- "version": "8.33.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.33.1.tgz",
- "integrity": "sha512-qwxv6dq682yVvgKKp2qWwLgRbscDAYktPptK4JPojCwwi3R9cwrvIxS4lvBpzmcqzR4bdn54Z0IG1uHFskW4dA==",
+ "version": "8.34.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.34.0.tgz",
+ "integrity": "sha512-vxXJV1hVFx3IXz/oy2sICsJukaBrtDEQSBiV48/YIV5KWjX1dO+bcIr/kCPrW6weKXvsaGKFNlwH0v2eYdRRbA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/scope-manager": "8.33.1",
- "@typescript-eslint/types": "8.33.1",
- "@typescript-eslint/typescript-estree": "8.33.1",
- "@typescript-eslint/visitor-keys": "8.33.1",
+ "@typescript-eslint/scope-manager": "8.34.0",
+ "@typescript-eslint/types": "8.34.0",
+ "@typescript-eslint/typescript-estree": "8.34.0",
+ "@typescript-eslint/visitor-keys": "8.34.0",
"debug": "^4.3.4"
},
"engines": {
@@ -3233,14 +3261,14 @@
}
},
"node_modules/@typescript-eslint/project-service": {
- "version": "8.33.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.33.1.tgz",
- "integrity": "sha512-DZR0efeNklDIHHGRpMpR5gJITQpu6tLr9lDJnKdONTC7vvzOlLAG/wcfxcdxEWrbiZApcoBCzXqU/Z458Za5Iw==",
+ "version": "8.34.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.34.0.tgz",
+ "integrity": "sha512-iEgDALRf970/B2YExmtPMPF54NenZUf4xpL3wsCRx/lgjz6ul/l13R81ozP/ZNuXfnLCS+oPmG7JIxfdNYKELw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/tsconfig-utils": "^8.33.1",
- "@typescript-eslint/types": "^8.33.1",
+ "@typescript-eslint/tsconfig-utils": "^8.34.0",
+ "@typescript-eslint/types": "^8.34.0",
"debug": "^4.3.4"
},
"engines": {
@@ -3255,14 +3283,14 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
- "version": "8.33.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.33.1.tgz",
- "integrity": "sha512-dM4UBtgmzHR9bS0Rv09JST0RcHYearoEoo3pG5B6GoTR9XcyeqX87FEhPo+5kTvVfKCvfHaHrcgeJQc6mrDKrA==",
+ "version": "8.34.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.34.0.tgz",
+ "integrity": "sha512-9Ac0X8WiLykl0aj1oYQNcLZjHgBojT6cW68yAgZ19letYu+Hxd0rE0veI1XznSSst1X5lwnxhPbVdwjDRIomRw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "8.33.1",
- "@typescript-eslint/visitor-keys": "8.33.1"
+ "@typescript-eslint/types": "8.34.0",
+ "@typescript-eslint/visitor-keys": "8.34.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -3273,9 +3301,9 @@
}
},
"node_modules/@typescript-eslint/tsconfig-utils": {
- "version": "8.33.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.33.1.tgz",
- "integrity": "sha512-STAQsGYbHCF0/e+ShUQ4EatXQ7ceh3fBCXkNU7/MZVKulrlq1usH7t2FhxvCpuCi5O5oi1vmVaAjrGeL71OK1g==",
+ "version": "8.34.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.34.0.tgz",
+ "integrity": "sha512-+W9VYHKFIzA5cBeooqQxqNriAP0QeQ7xTiDuIOr71hzgffm3EL2hxwWBIIj4GuofIbKxGNarpKqIq6Q6YrShOA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -3290,14 +3318,14 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
- "version": "8.33.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.33.1.tgz",
- "integrity": "sha512-1cG37d9xOkhlykom55WVwG2QRNC7YXlxMaMzqw2uPeJixBFfKWZgaP/hjAObqMN/u3fr5BrTwTnc31/L9jQ2ww==",
+ "version": "8.34.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.34.0.tgz",
+ "integrity": "sha512-n7zSmOcUVhcRYC75W2pnPpbO1iwhJY3NLoHEtbJwJSNlVAZuwqu05zY3f3s2SDWWDSo9FdN5szqc73DCtDObAg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/typescript-estree": "8.33.1",
- "@typescript-eslint/utils": "8.33.1",
+ "@typescript-eslint/typescript-estree": "8.34.0",
+ "@typescript-eslint/utils": "8.34.0",
"debug": "^4.3.4",
"ts-api-utils": "^2.1.0"
},
@@ -3314,9 +3342,9 @@
}
},
"node_modules/@typescript-eslint/types": {
- "version": "8.33.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.33.1.tgz",
- "integrity": "sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==",
+ "version": "8.34.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.34.0.tgz",
+ "integrity": "sha512-9V24k/paICYPniajHfJ4cuAWETnt7Ssy+R0Rbcqo5sSFr3QEZ/8TSoUi9XeXVBGXCaLtwTOKSLGcInCAvyZeMA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -3328,16 +3356,16 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
- "version": "8.33.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.33.1.tgz",
- "integrity": "sha512-+s9LYcT8LWjdYWu7IWs7FvUxpQ/DGkdjZeE/GGulHvv8rvYwQvVaUZ6DE+j5x/prADUgSbbCWZ2nPI3usuVeOA==",
+ "version": "8.34.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.34.0.tgz",
+ "integrity": "sha512-rOi4KZxI7E0+BMqG7emPSK1bB4RICCpF7QD3KCLXn9ZvWoESsOMlHyZPAHyG04ujVplPaHbmEvs34m+wjgtVtg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/project-service": "8.33.1",
- "@typescript-eslint/tsconfig-utils": "8.33.1",
- "@typescript-eslint/types": "8.33.1",
- "@typescript-eslint/visitor-keys": "8.33.1",
+ "@typescript-eslint/project-service": "8.34.0",
+ "@typescript-eslint/tsconfig-utils": "8.34.0",
+ "@typescript-eslint/types": "8.34.0",
+ "@typescript-eslint/visitor-keys": "8.34.0",
"debug": "^4.3.4",
"fast-glob": "^3.3.2",
"is-glob": "^4.0.3",
@@ -3356,6 +3384,23 @@
"typescript": ">=4.8.4 <5.9.0"
}
},
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
"node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
@@ -3373,16 +3418,16 @@
}
},
"node_modules/@typescript-eslint/utils": {
- "version": "8.33.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.33.1.tgz",
- "integrity": "sha512-52HaBiEQUaRYqAXpfzWSR2U3gxk92Kw006+xZpElaPMg3C4PgM+A5LqwoQI1f9E5aZ/qlxAZxzm42WX+vn92SQ==",
+ "version": "8.34.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.34.0.tgz",
+ "integrity": "sha512-8L4tWatGchV9A1cKbjaavS6mwYwp39jql8xUmIIKJdm+qiaeHy5KMKlBrf30akXAWBzn2SqKsNOtSENWUwg7XQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.7.0",
- "@typescript-eslint/scope-manager": "8.33.1",
- "@typescript-eslint/types": "8.33.1",
- "@typescript-eslint/typescript-estree": "8.33.1"
+ "@typescript-eslint/scope-manager": "8.34.0",
+ "@typescript-eslint/types": "8.34.0",
+ "@typescript-eslint/typescript-estree": "8.34.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -3397,13 +3442,13 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
- "version": "8.33.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.33.1.tgz",
- "integrity": "sha512-3i8NrFcZeeDHJ+7ZUuDkGT+UHq+XoFGsymNK2jZCOHcfEzRQ0BdpRtdpSx/Iyf3MHLWIcLS0COuOPibKQboIiQ==",
+ "version": "8.34.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.34.0.tgz",
+ "integrity": "sha512-qHV7pW7E85A0x6qyrFn+O+q1k1p3tQCsqIZ1KZ5ESLXY57aTvUd3/a4rdPTeXisvhXn2VQG0VSKUqs8KHF2zcA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "8.33.1",
+ "@typescript-eslint/types": "8.34.0",
"eslint-visitor-keys": "^4.2.0"
},
"engines": {
@@ -3421,10 +3466,38 @@
"dev": true,
"license": "ISC"
},
+ "node_modules/@unrs/resolver-binding-android-arm-eabi": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.9.0.tgz",
+ "integrity": "sha512-h1T2c2Di49ekF2TE8ZCoJkb+jwETKUIPDJ/nO3tJBKlLFPu+fyd93f0rGP/BvArKx2k2HlRM4kqkNarj3dvZlg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-android-arm64": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.9.0.tgz",
+ "integrity": "sha512-sG1NHtgXtX8owEkJ11yn34vt0Xqzi3k9TJ8zppDmyG8GZV4kVWw44FHwKwHeEFl07uKPeC4ZoyuQaGh5ruJYPA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
"node_modules/@unrs/resolver-binding-darwin-arm64": {
- "version": "1.7.11",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.7.11.tgz",
- "integrity": "sha512-i3/wlWjQJXMh1uiGtiv7k1EYvrrS3L1hdwmWJJiz1D8jWy726YFYPIxQWbEIVPVAgrfRR0XNlLrTQwq17cuCGw==",
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.9.0.tgz",
+ "integrity": "sha512-nJ9z47kfFnCxN1z/oYZS7HSNsFh43y2asePzTEZpEvK7kGyuShSl3RRXnm/1QaqFL+iP+BjMwuB+DYUymOkA5A==",
"cpu": [
"arm64"
],
@@ -3436,9 +3509,9 @@
]
},
"node_modules/@unrs/resolver-binding-darwin-x64": {
- "version": "1.7.11",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.7.11.tgz",
- "integrity": "sha512-8XXyFvc6w6kmMmi6VYchZhjd5CDcp+Lv6Cn1YmUme0ypsZ/0Kzd+9ESrWtDrWibKPTgSteDTxp75cvBOY64FQQ==",
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.9.0.tgz",
+ "integrity": "sha512-TK+UA1TTa0qS53rjWn7cVlEKVGz2B6JYe0C++TdQjvWYIyx83ruwh0wd4LRxYBM5HeuAzXcylA9BH2trARXJTw==",
"cpu": [
"x64"
],
@@ -3450,9 +3523,9 @@
]
},
"node_modules/@unrs/resolver-binding-freebsd-x64": {
- "version": "1.7.11",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.7.11.tgz",
- "integrity": "sha512-0qJBYzP8Qk24CZ05RSWDQUjdiQUeIJGfqMMzbtXgCKl/a5xa6thfC0MQkGIr55LCLd6YmMyO640ifYUa53lybQ==",
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.9.0.tgz",
+ "integrity": "sha512-6uZwzMRFcD7CcCd0vz3Hp+9qIL2jseE/bx3ZjaLwn8t714nYGwiE84WpaMCYjU+IQET8Vu/+BNAGtYD7BG/0yA==",
"cpu": [
"x64"
],
@@ -3464,9 +3537,9 @@
]
},
"node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": {
- "version": "1.7.11",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.7.11.tgz",
- "integrity": "sha512-1sGwpgvx+WZf0GFT6vkkOm6UJ+mlsVnjw+Yv9esK71idWeRAG3bbpkf3AoY8KIqKqmnzJExi0uKxXpakQ5Pcbg==",
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.9.0.tgz",
+ "integrity": "sha512-bPUBksQfrgcfv2+mm+AZinaKq8LCFvt5PThYqRotqSuuZK1TVKkhbVMS/jvSRfYl7jr3AoZLYbDkItxgqMKRkg==",
"cpu": [
"arm"
],
@@ -3478,9 +3551,9 @@
]
},
"node_modules/@unrs/resolver-binding-linux-arm-musleabihf": {
- "version": "1.7.11",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.7.11.tgz",
- "integrity": "sha512-D/1F/2lTe+XAl3ohkYj51NjniVly8sIqkA/n1aOND3ZMO418nl2JNU95iVa1/RtpzaKcWEsNTtHRogykrUflJg==",
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.9.0.tgz",
+ "integrity": "sha512-uT6E7UBIrTdCsFQ+y0tQd3g5oudmrS/hds5pbU3h4s2t/1vsGWbbSKhBSCD9mcqaqkBwoqlECpUrRJCmldl8PA==",
"cpu": [
"arm"
],
@@ -3492,9 +3565,9 @@
]
},
"node_modules/@unrs/resolver-binding-linux-arm64-gnu": {
- "version": "1.7.11",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.7.11.tgz",
- "integrity": "sha512-7vFWHLCCNFLEQlmwKQfVy066ohLLArZl+AV/AdmrD1/pD1FlmqM+FKbtnONnIwbHtgetFUCV/SRi1q4D49aTlw==",
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.9.0.tgz",
+ "integrity": "sha512-vdqBh911wc5awE2bX2zx3eflbyv8U9xbE/jVKAm425eRoOVv/VseGZsqi3A3SykckSpF4wSROkbQPvbQFn8EsA==",
"cpu": [
"arm64"
],
@@ -3506,9 +3579,9 @@
]
},
"node_modules/@unrs/resolver-binding-linux-arm64-musl": {
- "version": "1.7.11",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.7.11.tgz",
- "integrity": "sha512-tYkGIx8hjWPh4zcn17jLEHU8YMmdP2obRTGkdaB3BguGHh31VCS3ywqC4QjTODjmhhNyZYkj/1Dz/+0kKvg9YA==",
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.9.0.tgz",
+ "integrity": "sha512-/8JFZ/SnuDr1lLEVsxsuVwrsGquTvT51RZGvyDB/dOK3oYK2UqeXzgeyq6Otp8FZXQcEYqJwxb9v+gtdXn03eQ==",
"cpu": [
"arm64"
],
@@ -3520,9 +3593,9 @@
]
},
"node_modules/@unrs/resolver-binding-linux-ppc64-gnu": {
- "version": "1.7.11",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.7.11.tgz",
- "integrity": "sha512-6F328QIUev29vcZeRX6v6oqKxfUoGwIIAhWGD8wSysnBYFY0nivp25jdWmAb1GildbCCaQvOKEhCok7YfWkj4Q==",
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.9.0.tgz",
+ "integrity": "sha512-FkJjybtrl+rajTw4loI3L6YqSOpeZfDls4SstL/5lsP2bka9TiHUjgMBjygeZEis1oC8LfJTS8FSgpKPaQx2tQ==",
"cpu": [
"ppc64"
],
@@ -3534,9 +3607,9 @@
]
},
"node_modules/@unrs/resolver-binding-linux-riscv64-gnu": {
- "version": "1.7.11",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.7.11.tgz",
- "integrity": "sha512-NqhWmiGJGdzbZbeucPZIG9Iav4lyYLCarEnxAceguMx9qlpeEF7ENqYKOwB8Zqk7/CeuYMEcLYMaW2li6HyDzQ==",
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.9.0.tgz",
+ "integrity": "sha512-w/NZfHNeDusbqSZ8r/hp8iL4S39h4+vQMc9/vvzuIKMWKppyUGKm3IST0Qv0aOZ1rzIbl9SrDeIqK86ZpUK37w==",
"cpu": [
"riscv64"
],
@@ -3548,9 +3621,9 @@
]
},
"node_modules/@unrs/resolver-binding-linux-riscv64-musl": {
- "version": "1.7.11",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.7.11.tgz",
- "integrity": "sha512-J2RPIFKMdTrLtBdfR1cUMKl8Gcy05nlQ+bEs/6al7EdWLk9cs3tnDREHZ7mV9uGbeghpjo4i8neNZNx3PYUY9w==",
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.9.0.tgz",
+ "integrity": "sha512-bEPBosut8/8KQbUixPry8zg/fOzVOWyvwzOfz0C0Rw6dp+wIBseyiHKjkcSyZKv/98edrbMknBaMNJfA/UEdqw==",
"cpu": [
"riscv64"
],
@@ -3562,9 +3635,9 @@
]
},
"node_modules/@unrs/resolver-binding-linux-s390x-gnu": {
- "version": "1.7.11",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.7.11.tgz",
- "integrity": "sha512-bDpGRerHvvHdhun7MmFUNDpMiYcJSqWckwAVVRTJf8F+RyqYJOp/mx04PDc7DhpNPeWdnTMu91oZRMV+gGaVcQ==",
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.9.0.tgz",
+ "integrity": "sha512-LDtMT7moE3gK753gG4pc31AAqGUC86j3AplaFusc717EUGF9ZFJ356sdQzzZzkBk1XzMdxFyZ4f/i35NKM/lFA==",
"cpu": [
"s390x"
],
@@ -3576,9 +3649,9 @@
]
},
"node_modules/@unrs/resolver-binding-linux-x64-gnu": {
- "version": "1.7.11",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.7.11.tgz",
- "integrity": "sha512-G9U7bVmylzRLma3cK39RBm3guoD1HOvY4o0NS4JNm37AD0lS7/xyMt7kn0JejYyc0Im8J+rH69/dXGM9DAJcSQ==",
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.9.0.tgz",
+ "integrity": "sha512-WmFd5KINHIXj8o1mPaT8QRjA9HgSXhN1gl9Da4IZihARihEnOylu4co7i/yeaIpcfsI6sYs33cNZKyHYDh0lrA==",
"cpu": [
"x64"
],
@@ -3590,9 +3663,9 @@
]
},
"node_modules/@unrs/resolver-binding-linux-x64-musl": {
- "version": "1.7.11",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.7.11.tgz",
- "integrity": "sha512-7qL20SBKomekSunm7M9Fe5L93bFbn+FbHiGJbfTlp0RKhPVoJDP73vOxf1QrmJHyDPECsGWPFnKa/f8fO2FsHw==",
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.9.0.tgz",
+ "integrity": "sha512-CYuXbANW+WgzVRIl8/QvZmDaZxrqvOldOwlbUjIM4pQ46FJ0W5cinJ/Ghwa/Ng1ZPMJMk1VFdsD/XwmCGIXBWg==",
"cpu": [
"x64"
],
@@ -3604,9 +3677,9 @@
]
},
"node_modules/@unrs/resolver-binding-wasm32-wasi": {
- "version": "1.7.11",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.7.11.tgz",
- "integrity": "sha512-jisvIva8MidjI+B1lFRZZMfCPaCISePgTyR60wNT1MeQvIh5Ksa0G3gvI+Iqyj3jqYbvOHByenpa5eDGcSdoSg==",
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.9.0.tgz",
+ "integrity": "sha512-6Rp2WH0OoitMYR57Z6VE8Y6corX8C6QEMWLgOV6qXiJIeZ1F9WGXY/yQ8yDC4iTraotyLOeJ2Asea0urWj2fKQ==",
"cpu": [
"wasm32"
],
@@ -3614,16 +3687,16 @@
"license": "MIT",
"optional": true,
"dependencies": {
- "@napi-rs/wasm-runtime": "^0.2.10"
+ "@napi-rs/wasm-runtime": "^0.2.11"
},
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/@unrs/resolver-binding-win32-arm64-msvc": {
- "version": "1.7.11",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.7.11.tgz",
- "integrity": "sha512-G+H5nQZ8sRZ8ebMY6mRGBBvTEzMYEcgVauLsNHpvTUavZoCCRVP1zWkCZgOju2dW3O22+8seTHniTdl1/uLz3g==",
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.9.0.tgz",
+ "integrity": "sha512-rknkrTRuvujprrbPmGeHi8wYWxmNVlBoNW8+4XF2hXUnASOjmuC9FNF1tGbDiRQWn264q9U/oGtixyO3BT8adQ==",
"cpu": [
"arm64"
],
@@ -3635,9 +3708,9 @@
]
},
"node_modules/@unrs/resolver-binding-win32-ia32-msvc": {
- "version": "1.7.11",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.7.11.tgz",
- "integrity": "sha512-Hfy46DBfFzyv0wgR0MMOwFFib2W2+Btc8oE5h4XlPhpelnSyA6nFxkVIyTgIXYGTdFaLoZFNn62fmqx3rjEg3A==",
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.9.0.tgz",
+ "integrity": "sha512-Ceymm+iBl+bgAICtgiHyMLz6hjxmLJKqBim8tDzpX61wpZOx2bPK6Gjuor7I2RiUynVjvvkoRIkrPyMwzBzF3A==",
"cpu": [
"ia32"
],
@@ -3649,9 +3722,9 @@
]
},
"node_modules/@unrs/resolver-binding-win32-x64-msvc": {
- "version": "1.7.11",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.7.11.tgz",
- "integrity": "sha512-7L8NdsQlCJ8T106Gbz/AjzM4QKWVsoQbKpB9bMBGcIZswUuAnJMHpvbqGW3RBqLHCIwX4XZ5fxSBHEFcK2h9wA==",
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.9.0.tgz",
+ "integrity": "sha512-k59o9ZyeyS0hAlcaKFezYSH2agQeRFEB7KoQLXl3Nb3rgkqT1NY9Vwy+SqODiLmYnEjxWJVRE/yq2jFVqdIxZw==",
"cpu": [
"x64"
],
@@ -3677,9 +3750,9 @@
}
},
"node_modules/@vitest/eslint-plugin": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@vitest/eslint-plugin/-/eslint-plugin-1.2.1.tgz",
- "integrity": "sha512-JQr1jdVcrsoS7Sdzn83h9sq4DvREf9Q/onTZbJCqTVlv/76qb+TZrLv/9VhjnjSMHweQH5FdpMDeCR6aDe2fgw==",
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@vitest/eslint-plugin/-/eslint-plugin-1.2.2.tgz",
+ "integrity": "sha512-R8NwW+VxyKqVGcMfYsUbdThQyMbtNcoeg+jJeTgMHqWdFdcS0nrODAQXhkplvWzgd7jIJ+GQeydGqFLibsxMxg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3700,15 +3773,15 @@
}
},
"node_modules/@vitest/expect": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.2.tgz",
- "integrity": "sha512-ipHw0z669vEMjzz3xQE8nJX1s0rQIb7oEl4jjl35qWTwm/KIHERIg/p/zORrjAaZKXfsv7IybcNGHwhOOAPMwQ==",
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.3.tgz",
+ "integrity": "sha512-W2RH2TPWVHA1o7UmaFKISPvdicFJH+mjykctJFoAkUw+SPTJTGjUNdKscFBrqM7IPnCVu6zihtKYa7TkZS1dkQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/chai": "^5.2.2",
- "@vitest/spy": "3.2.2",
- "@vitest/utils": "3.2.2",
+ "@vitest/spy": "3.2.3",
+ "@vitest/utils": "3.2.3",
"chai": "^5.2.0",
"tinyrainbow": "^2.0.0"
},
@@ -3717,13 +3790,13 @@
}
},
"node_modules/@vitest/mocker": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.2.tgz",
- "integrity": "sha512-jKojcaRyIYpDEf+s7/dD3LJt53c0dPfp5zCPXz9H/kcGrSlovU/t1yEaNzM9oFME3dcd4ULwRI/x0Po1Zf+LTw==",
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.3.tgz",
+ "integrity": "sha512-cP6fIun+Zx8he4rbWvi+Oya6goKQDZK+Yq4hhlggwQBbrlOQ4qtZ+G4nxB6ZnzI9lyIb+JnvyiJnPC2AGbKSPA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@vitest/spy": "3.2.2",
+ "@vitest/spy": "3.2.3",
"estree-walker": "^3.0.3",
"magic-string": "^0.30.17"
},
@@ -3771,9 +3844,9 @@
}
},
"node_modules/@vitest/pretty-format": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.2.tgz",
- "integrity": "sha512-FY4o4U1UDhO9KMd2Wee5vumwcaHw7Vg4V7yR4Oq6uK34nhEJOmdRYrk3ClburPRUA09lXD/oXWZ8y/Sdma0aUQ==",
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.3.tgz",
+ "integrity": "sha512-yFglXGkr9hW/yEXngO+IKMhP0jxyFw2/qys/CK4fFUZnSltD+MU7dVYGrH8rvPcK/O6feXQA+EU33gjaBBbAng==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3784,27 +3857,28 @@
}
},
"node_modules/@vitest/runner": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.2.tgz",
- "integrity": "sha512-GYcHcaS3ejGRZYed2GAkvsjBeXIEerDKdX3orQrBJqLRiea4NSS9qvn9Nxmuy1IwIB+EjFOaxXnX79l8HFaBwg==",
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.3.tgz",
+ "integrity": "sha512-83HWYisT3IpMaU9LN+VN+/nLHVBCSIUKJzGxC5RWUOsK1h3USg7ojL+UXQR3b4o4UBIWCYdD2fxuzM7PQQ1u8w==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@vitest/utils": "3.2.2",
- "pathe": "^2.0.3"
+ "@vitest/utils": "3.2.3",
+ "pathe": "^2.0.3",
+ "strip-literal": "^3.0.0"
},
"funding": {
"url": "https://opencollective.com/vitest"
}
},
"node_modules/@vitest/snapshot": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.2.tgz",
- "integrity": "sha512-aMEI2XFlR1aNECbBs5C5IZopfi5Lb8QJZGGpzS8ZUHML5La5wCbrbhLOVSME68qwpT05ROEEOAZPRXFpxZV2wA==",
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.3.tgz",
+ "integrity": "sha512-9gIVWx2+tysDqUmmM1L0hwadyumqssOL1r8KJipwLx5JVYyxvVRfxvMq7DaWbZZsCqZnu/dZedaZQh4iYTtneA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@vitest/pretty-format": "3.2.2",
+ "@vitest/pretty-format": "3.2.3",
"magic-string": "^0.30.17",
"pathe": "^2.0.3"
},
@@ -3823,9 +3897,9 @@
}
},
"node_modules/@vitest/spy": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.2.tgz",
- "integrity": "sha512-6Utxlx3o7pcTxvp0u8kUiXtRFScMrUg28KjB3R2hon7w4YqOFAEA9QwzPVVS1QNL3smo4xRNOpNZClRVfpMcYg==",
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.3.tgz",
+ "integrity": "sha512-JHu9Wl+7bf6FEejTCREy+DmgWe+rQKbK+y32C/k5f4TBIAlijhJbRBIRIOCEpVevgRsCQR2iHRUH2/qKVM/plw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3836,13 +3910,13 @@
}
},
"node_modules/@vitest/utils": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.2.tgz",
- "integrity": "sha512-qJYMllrWpF/OYfWHP32T31QCaLa3BAzT/n/8mNGhPdVcjY+JYazQFO1nsJvXU12Kp1xMpNY4AGuljPTNjQve6A==",
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.3.tgz",
+ "integrity": "sha512-4zFBCU5Pf+4Z6v+rwnZ1HU1yzOKKvDkMXZrymE2PBlbjKJRlrOxbvpfPSvJTGRIwGoahaOGvp+kbCoxifhzJ1Q==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@vitest/pretty-format": "3.2.2",
+ "@vitest/pretty-format": "3.2.3",
"loupe": "^3.1.3",
"tinyrainbow": "^2.0.0"
},
@@ -3974,6 +4048,23 @@
}
}
},
+ "node_modules/@vue/language-core/node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@vue/language-core/node_modules/brace-expansion": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
"node_modules/@vue/language-core/node_modules/minimatch": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
@@ -4256,9 +4347,9 @@
}
},
"node_modules/acorn": {
- "version": "8.14.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
- "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
+ "version": "8.15.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
+ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
@@ -4622,10 +4713,13 @@
}
},
"node_modules/balanced-match": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
- "license": "MIT"
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-3.0.1.tgz",
+ "integrity": "sha512-vjtV3hiLqYDNRoiAv0zC4QaGAMPomEoq83PRmYIofPswwZurCeWR5LByXm7SyoL0Zh5+2z0+HC7jG8gSZJUh0w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 16"
+ }
},
"node_modules/base64-js": {
"version": "1.5.1",
@@ -4676,12 +4770,15 @@
"license": "ISC"
},
"node_modules/brace-expansion": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
- "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-4.0.1.tgz",
+ "integrity": "sha512-YClrbvTCXGe70pU2JiEiPLYXO9gQkyxYeKpJIQHVS/gOs6EWMQP2RYBwjFLNT322Ji8TOC3IMPfsYCedNpzKfA==",
"license": "MIT",
"dependencies": {
- "balanced-match": "^1.0.0"
+ "balanced-match": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 18"
}
},
"node_modules/braces": {
@@ -4799,9 +4896,9 @@
}
},
"node_modules/cacheable": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-1.9.0.tgz",
- "integrity": "sha512-8D5htMCxPDUULux9gFzv30f04Xo3wCnik0oOxKoRTPIBoqA7HtOcJ87uBhQTs3jCfZZTrUBGsYIZOgE0ZRgMAg==",
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-1.10.0.tgz",
+ "integrity": "sha512-SSgQTAnhd7WlJXnGlIi4jJJOiHzgnM5wRMEPaXAU4kECTAMpBoYKoZ9i5zHmclIEZbxcu3j7yY/CF8DTmwIsHg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4810,9 +4907,9 @@
}
},
"node_modules/cacheable/node_modules/keyv": {
- "version": "5.3.3",
- "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.3.3.tgz",
- "integrity": "sha512-Rwu4+nXI9fqcxiEHtbkvoes2X+QfkTRo1TMkPfwzipGsJlJO/z69vqB4FNl9xJ3xCpAcbkvmEabZfPzrwN3+gQ==",
+ "version": "5.3.4",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.3.4.tgz",
+ "integrity": "sha512-ypEvQvInNpUe+u+w8BIcPkQvEqXquyyibWE/1NB5T2BTzIpS5cGEV1LZskDzPSTvNAaT4+5FutvzlvnkxOSKlw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4838,9 +4935,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001721",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001721.tgz",
- "integrity": "sha512-cOuvmUVtKrtEaoKiO0rSc29jcjwMwX5tOHDy4MgVFEWiUXj4uBMJkwI8MDySkgXidpMiHUcviogAvFi4pA2hDQ==",
+ "version": "1.0.30001722",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001722.tgz",
+ "integrity": "sha512-DCQHBBZtiK6JVkAGw7drvAMK0Q0POD/xZvEmDp6baiMMP6QXXk9HpD6mNYBZWhOPG6LvIDb82ITqtWjhDckHCA==",
"funding": [
{
"type": "opencollective",
@@ -5241,13 +5338,13 @@
"license": "MIT"
},
"node_modules/core-js-compat": {
- "version": "3.42.0",
- "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.42.0.tgz",
- "integrity": "sha512-bQasjMfyDGyaeWKBIu33lHh9qlSR0MFE/Nmc6nMjf/iU9b3rSMdAYz1Baxrv4lPdGUsTqZudHA4jIGSJy0SWZQ==",
+ "version": "3.43.0",
+ "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.43.0.tgz",
+ "integrity": "sha512-2GML2ZsCc5LR7hZYz4AXmjQw8zuy2T//2QntwdnpuYI7jteT6GVYJL7F6C2C57R7gSYrcqVW3lAALefdbhBLDA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "browserslist": "^4.24.4"
+ "browserslist": "^4.25.0"
},
"funding": {
"type": "opencollective",
@@ -6282,9 +6379,9 @@
}
},
"node_modules/electron-to-chromium": {
- "version": "1.5.165",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.165.tgz",
- "integrity": "sha512-naiMx1Z6Nb2TxPU6fiFrUrDTjyPMLdTtaOd2oLmG8zVSg2hCWGkhPyxwk+qRmZ1ytwVqUv0u7ZcDA5+ALhaUtw==",
+ "version": "1.5.166",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.166.tgz",
+ "integrity": "sha512-QPWqHL0BglzPYyJJ1zSSmwFFL6MFXhbACOCcsCdUMCkzPdS9/OIBVxg516X/Ado2qwAq8k0nJJ7phQPCqiaFAw==",
"license": "ISC"
},
"node_modules/emoji-regex": {
@@ -6817,21 +6914,21 @@
}
},
"node_modules/eslint-plugin-import-x": {
- "version": "4.15.1",
- "resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-4.15.1.tgz",
- "integrity": "sha512-JfVpNg1qMkPD66iaSgmMoSYeUCGS8UFSm3GwHV0IbuV3Knar/SyK5qqCct9+AxoMIzaM+KSO7KK5pOeOkC/3GQ==",
+ "version": "4.15.2",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-4.15.2.tgz",
+ "integrity": "sha512-J5gx7sN6DTm0LRT//eP3rVVQ2Yi4hrX0B+DbWxa5er8PZ6JjLo9GUBwogIFvEDdwJaSqZplpQT+haK/cXhb7VQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "^8.33.1",
+ "@typescript-eslint/types": "^8.34.0",
"comment-parser": "^1.4.1",
"debug": "^4.4.1",
- "eslint-import-context": "^0.1.7",
+ "eslint-import-context": "^0.1.8",
"is-glob": "^4.0.3",
"minimatch": "^9.0.3 || ^10.0.1",
"semver": "^7.7.2",
"stable-hash-x": "^0.1.1",
- "unrs-resolver": "^1.7.10"
+ "unrs-resolver": "^1.9.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -6853,10 +6950,17 @@
}
}
},
+ "node_modules/eslint-plugin-import/node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/eslint-plugin-import/node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6940,10 +7044,17 @@
"eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9"
}
},
+ "node_modules/eslint-plugin-jsx-a11y/node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/eslint-plugin-jsx-a11y/node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7051,9 +7162,9 @@
}
},
"node_modules/eslint-plugin-regexp": {
- "version": "2.8.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-2.8.0.tgz",
- "integrity": "sha512-xme90IvkMgdyS+NJC21FM0H6ek4urGsdlIFTXpZRqH2BKJKVSd8hRbyrCpbcqfGBi2jth3eQoLiO3RC1gxZHiw==",
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-2.9.0.tgz",
+ "integrity": "sha512-9WqJMnOq8VlE/cK+YAo9C9YHhkOtcEtEk9d12a+H7OSZFwlpI6stiHmYPGa2VE0QhTzodJyhlyprUaXDZLgHBw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7093,6 +7204,23 @@
"eslint": "^8.0.0 || ^9.0.0"
}
},
+ "node_modules/eslint-plugin-sonarjs/node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/eslint-plugin-sonarjs/node_modules/brace-expansion": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
"node_modules/eslint-plugin-sonarjs/node_modules/minimatch": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
@@ -7260,9 +7388,9 @@
}
},
"node_modules/eslint-visitor-keys": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz",
- "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==",
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+ "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
"dev": true,
"license": "Apache-2.0",
"engines": {
@@ -7289,10 +7417,17 @@
"url": "https://github.com/sponsors/epoberezkin"
}
},
+ "node_modules/eslint/node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/eslint/node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7352,15 +7487,15 @@
}
},
"node_modules/espree": {
- "version": "10.3.0",
- "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz",
- "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==",
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
+ "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
- "acorn": "^8.14.0",
+ "acorn": "^8.15.0",
"acorn-jsx": "^5.3.2",
- "eslint-visitor-keys": "^4.2.0"
+ "eslint-visitor-keys": "^4.2.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -7811,10 +7946,16 @@
"integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
"license": "BSD-2-Clause"
},
+ "node_modules/glob/node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "license": "MIT"
+ },
"node_modules/glob/node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
@@ -7967,19 +8108,37 @@
}
},
"node_modules/happy-dom": {
- "version": "17.6.3",
- "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-17.6.3.tgz",
- "integrity": "sha512-UVIHeVhxmxedbWPCfgS55Jg2rDfwf2BCKeylcPSqazLz5w3Kri7Q4xdBJubsr/+VUzFLh0VjIvh13RaDA2/Xug==",
+ "version": "18.0.1",
+ "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-18.0.1.tgz",
+ "integrity": "sha512-qn+rKOW7KWpVTtgIUi6RVmTBZJSe2k0Db0vh1f7CWrWclkkc7/Q+FrOfkZIb2eiErLyqu5AXEzE7XthO9JVxRA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "webidl-conversions": "^7.0.0",
+ "@types/node": "^20.0.0",
+ "@types/whatwg-mimetype": "^3.0.2",
"whatwg-mimetype": "^3.0.0"
},
"engines": {
"node": ">=20.0.0"
}
},
+ "node_modules/happy-dom/node_modules/@types/node": {
+ "version": "20.19.0",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.0.tgz",
+ "integrity": "sha512-hfrc+1tud1xcdVTABC2JiomZJEklMcXYNTVtZLAeqTVWD+qL5jkHKT+1lOtqDdGxt+mB53DTtiz673vfjU8D1Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~6.21.0"
+ }
+ },
+ "node_modules/happy-dom/node_modules/undici-types": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
+ "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -8880,10 +9039,16 @@
"webpack": "^4.4.0 || ^5.4.0"
}
},
+ "node_modules/license-checker-webpack-plugin/node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "license": "MIT"
+ },
"node_modules/license-checker-webpack-plugin/node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
@@ -9991,12 +10156,12 @@
}
},
"node_modules/minimatch": {
- "version": "10.0.1",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz",
- "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==",
+ "version": "10.0.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.2.tgz",
+ "integrity": "sha512-+9TJCIYXgZ2Dm5LxVCFsa8jOm+evMwXHFI0JM1XROmkfkpz8/iLLDh+TwSmyIBrs6C6Xu9294/fq8cBA+P6AqA==",
"license": "ISC",
"dependencies": {
- "brace-expansion": "^2.0.1"
+ "brace-expansion": "^4.0.1"
},
"engines": {
"node": "20 || >=22"
@@ -10694,13 +10859,13 @@
}
},
"node_modules/playwright": {
- "version": "1.52.0",
- "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.52.0.tgz",
- "integrity": "sha512-JAwMNMBlxJ2oD1kce4KPtMkDeKGHQstdpFPcPH3maElAXon/QZeTvtsfXmTMRyO9TslfoYOXkSsvao2nE1ilTw==",
+ "version": "1.53.0",
+ "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.53.0.tgz",
+ "integrity": "sha512-ghGNnIEYZC4E+YtclRn4/p6oYbdPiASELBIYkBXfaTVKreQUYbMUYQDwS12a8F0/HtIjr/CkGjtwABeFPGcS4Q==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "playwright-core": "1.52.0"
+ "playwright-core": "1.53.0"
},
"bin": {
"playwright": "cli.js"
@@ -10713,9 +10878,9 @@
}
},
"node_modules/playwright-core": {
- "version": "1.52.0",
- "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.52.0.tgz",
- "integrity": "sha512-l2osTgLXSMeuLZOML9qYODUQoPPnUsKsb5/P6LJ2e6uPKXUdPK5WYhN4z03G+YNbWmGDY4YENauNu4ZKczreHg==",
+ "version": "1.53.0",
+ "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.53.0.tgz",
+ "integrity": "sha512-mGLg8m0pm4+mmtB7M89Xw/GSqoNC+twivl8ITteqvAndachozYe2ZA7srU6uleV1vEdAHYqjq+SV8SNxRRFYBw==",
"dev": true,
"license": "Apache-2.0",
"bin": {
@@ -10762,9 +10927,9 @@
}
},
"node_modules/postcss": {
- "version": "8.5.4",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.4.tgz",
- "integrity": "sha512-QSa9EBe+uwlGTFmHsPKokv3B/oEMQZxfqW0QqNCyhpa6mB1afzulwn8hihglqAb2pOw+BJgNlmXQ8la2VeHB7w==",
+ "version": "8.5.5",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.5.tgz",
+ "integrity": "sha512-d/jtm+rdNT8tpXuHY5MMtcbJFBkhXE6593XVR9UoGCH8jSFGci7jGvMGH5RYd5PBJW+00NZQt6gf7CbagJCrhg==",
"funding": [
{
"type": "opencollective",
@@ -10983,9 +11148,9 @@
}
},
"node_modules/postcss-nesting": {
- "version": "13.0.1",
- "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-13.0.1.tgz",
- "integrity": "sha512-VbqqHkOBOt4Uu3G8Dm8n6lU5+9cJFxiuty9+4rcoyRPO9zZS1JIs6td49VIoix3qYqELHlJIn46Oih9SAKo+yQ==",
+ "version": "13.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-13.0.2.tgz",
+ "integrity": "sha512-1YCI290TX+VP0U/K/aFxzHzQWHWURL+CtHMSbex1lCdpXD1SoR2sYuxDu5aNI9lPoXpKTCggFZiDJbwylU0LEQ==",
"funding": [
{
"type": "github",
@@ -10998,7 +11163,7 @@
],
"license": "MIT-0",
"dependencies": {
- "@csstools/selector-resolve-nested": "^3.0.0",
+ "@csstools/selector-resolve-nested": "^3.1.0",
"@csstools/selector-specificity": "^5.0.0",
"postcss-selector-parser": "^7.0.0"
},
@@ -12215,6 +12380,19 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/strip-literal": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.0.0.tgz",
+ "integrity": "sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "js-tokens": "^9.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
"node_modules/style-search": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz",
@@ -12424,25 +12602,25 @@
"license": "MIT"
},
"node_modules/stylelint/node_modules/file-entry-cache": {
- "version": "10.1.0",
- "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-10.1.0.tgz",
- "integrity": "sha512-Et/ex6smi3wOOB+n5mek+Grf7P2AxZR5ueqRUvAAn4qkyatXi3cUC1cuQXVkX0VlzBVsN4BkWJFmY/fYiRTdww==",
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-10.1.1.tgz",
+ "integrity": "sha512-zcmsHjg2B2zjuBgjdnB+9q0+cWcgWfykIcsDkWDB4GTPtl1eXUA+gTI6sO0u01AqK3cliHryTU55/b2Ow1hfZg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "flat-cache": "^6.1.9"
+ "flat-cache": "^6.1.10"
}
},
"node_modules/stylelint/node_modules/flat-cache": {
- "version": "6.1.9",
- "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.9.tgz",
- "integrity": "sha512-DUqiKkTlAfhtl7g78IuwqYM+YqvT+as0mY+EVk6mfimy19U79pJCzDZQsnqk3Ou/T6hFXWLGbwbADzD/c8Tydg==",
+ "version": "6.1.10",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.10.tgz",
+ "integrity": "sha512-B6/v1f0NwjxzmeOhzfXPGWpKBVA207LS7lehaVKQnFrVktcFRfkzjZZ2gwj2i1TkEUMQht7ZMJbABUT5N+V1Nw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "cacheable": "^1.9.0",
+ "cacheable": "^1.10.0",
"flatted": "^3.3.3",
- "hookified": "^1.8.2"
+ "hookified": "^1.9.1"
}
},
"node_modules/stylelint/node_modules/ignore": {
@@ -12565,6 +12743,21 @@
"node": ">=16 || 14 >=14.17"
}
},
+ "node_modules/sucrase/node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "license": "MIT"
+ },
+ "node_modules/sucrase/node_modules/brace-expansion": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
"node_modules/sucrase/node_modules/commander": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
@@ -12779,9 +12972,9 @@
}
},
"node_modules/swagger-ui-dist": {
- "version": "5.24.0",
- "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.24.0.tgz",
- "integrity": "sha512-okwN8vf14TOgBTUyGgCXEAoHnrwwp/042dC00B3kPu2OAe9zD75BtSbLlgAK1Y5e3csJhs+AdnIxJYZN9uvptg==",
+ "version": "5.24.1",
+ "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.24.1.tgz",
+ "integrity": "sha512-ITeWc7CCAfK53u8jnV39UNqStQZjSt+bVYtJHsOEL3vVj/WV9/8HmsF8Ej4oD8r+Xk1HpWyeW/t59r1QNeAcUQ==",
"license": "Apache-2.0",
"dependencies": {
"@scarf/scarf": "=1.4.0"
@@ -12915,9 +13108,9 @@
}
},
"node_modules/terser": {
- "version": "5.41.0",
- "resolved": "https://registry.npmjs.org/terser/-/terser-5.41.0.tgz",
- "integrity": "sha512-H406eLPXpZbAX14+B8psIuvIr8+3c+2hkuYzpMkoE0ij+NdsVATbA78vb8neA/eqrj7rywa2pIkdmWRsXW6wmw==",
+ "version": "5.42.0",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.42.0.tgz",
+ "integrity": "sha512-UYCvU9YQW2f/Vwl+P0GfhxJxbUGLwd+5QrrGgLajzWAtC/23AX0vcise32kkP7Eu0Wu9VlzzHAXkLObgjQfFlQ==",
"license": "BSD-2-Clause",
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
@@ -13046,9 +13239,9 @@
}
},
"node_modules/tinyglobby/node_modules/fdir": {
- "version": "6.4.5",
- "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.5.tgz",
- "integrity": "sha512-4BG7puHpVsIYxZUbiUE3RqGloLaSSwzYie5jvasC4LWuBWzZawynvYouhjbQKw2JuIGYdm0DzIxl8iVidKlUEw==",
+ "version": "6.4.6",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz",
+ "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==",
"dev": true,
"license": "MIT",
"peerDependencies": {
@@ -13268,9 +13461,9 @@
"license": "ISC"
},
"node_modules/undici-types": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
- "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
+ "version": "7.8.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz",
+ "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==",
"license": "MIT"
},
"node_modules/universalify": {
@@ -13284,9 +13477,9 @@
}
},
"node_modules/unrs-resolver": {
- "version": "1.7.11",
- "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.7.11.tgz",
- "integrity": "sha512-OhuAzBImFPjKNgZ2JwHMfGFUA6NSbRegd1+BPjC1Y0E6X9Y/vJ4zKeGmIMqmlYboj6cMNEwKI+xQisrg4J0HaQ==",
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.9.0.tgz",
+ "integrity": "sha512-wqaRu4UnzBD2ABTC1kLfBjAqIDZ5YUTr/MLGa7By47JV1bJDSW7jq/ZSLigB7enLe7ubNaJhtnBXgrc/50cEhg==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
@@ -13297,23 +13490,25 @@
"url": "https://opencollective.com/unrs-resolver"
},
"optionalDependencies": {
- "@unrs/resolver-binding-darwin-arm64": "1.7.11",
- "@unrs/resolver-binding-darwin-x64": "1.7.11",
- "@unrs/resolver-binding-freebsd-x64": "1.7.11",
- "@unrs/resolver-binding-linux-arm-gnueabihf": "1.7.11",
- "@unrs/resolver-binding-linux-arm-musleabihf": "1.7.11",
- "@unrs/resolver-binding-linux-arm64-gnu": "1.7.11",
- "@unrs/resolver-binding-linux-arm64-musl": "1.7.11",
- "@unrs/resolver-binding-linux-ppc64-gnu": "1.7.11",
- "@unrs/resolver-binding-linux-riscv64-gnu": "1.7.11",
- "@unrs/resolver-binding-linux-riscv64-musl": "1.7.11",
- "@unrs/resolver-binding-linux-s390x-gnu": "1.7.11",
- "@unrs/resolver-binding-linux-x64-gnu": "1.7.11",
- "@unrs/resolver-binding-linux-x64-musl": "1.7.11",
- "@unrs/resolver-binding-wasm32-wasi": "1.7.11",
- "@unrs/resolver-binding-win32-arm64-msvc": "1.7.11",
- "@unrs/resolver-binding-win32-ia32-msvc": "1.7.11",
- "@unrs/resolver-binding-win32-x64-msvc": "1.7.11"
+ "@unrs/resolver-binding-android-arm-eabi": "1.9.0",
+ "@unrs/resolver-binding-android-arm64": "1.9.0",
+ "@unrs/resolver-binding-darwin-arm64": "1.9.0",
+ "@unrs/resolver-binding-darwin-x64": "1.9.0",
+ "@unrs/resolver-binding-freebsd-x64": "1.9.0",
+ "@unrs/resolver-binding-linux-arm-gnueabihf": "1.9.0",
+ "@unrs/resolver-binding-linux-arm-musleabihf": "1.9.0",
+ "@unrs/resolver-binding-linux-arm64-gnu": "1.9.0",
+ "@unrs/resolver-binding-linux-arm64-musl": "1.9.0",
+ "@unrs/resolver-binding-linux-ppc64-gnu": "1.9.0",
+ "@unrs/resolver-binding-linux-riscv64-gnu": "1.9.0",
+ "@unrs/resolver-binding-linux-riscv64-musl": "1.9.0",
+ "@unrs/resolver-binding-linux-s390x-gnu": "1.9.0",
+ "@unrs/resolver-binding-linux-x64-gnu": "1.9.0",
+ "@unrs/resolver-binding-linux-x64-musl": "1.9.0",
+ "@unrs/resolver-binding-wasm32-wasi": "1.9.0",
+ "@unrs/resolver-binding-win32-arm64-msvc": "1.9.0",
+ "@unrs/resolver-binding-win32-ia32-msvc": "1.9.0",
+ "@unrs/resolver-binding-win32-x64-msvc": "1.9.0"
}
},
"node_modules/update-browserslist-db": {
@@ -13508,9 +13703,9 @@
}
},
"node_modules/vite-node": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.2.tgz",
- "integrity": "sha512-Xj/jovjZvDXOq2FgLXu8NsY4uHUMWtzVmMC2LkCu9HWdr9Qu1Is5sanX3Z4jOFKdohfaWDnEJWp9pRP0vVpAcA==",
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.3.tgz",
+ "integrity": "sha512-gc8aAifGuDIpZHrPjuHyP4dpQmYXqWw7D1GmDnWeNWP654UEXzVfQ5IHPSK5HaHkwB/+p1atpYpSdw/2kOv8iQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -13545,9 +13740,9 @@
"license": "MIT"
},
"node_modules/vite/node_modules/fdir": {
- "version": "6.4.5",
- "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.5.tgz",
- "integrity": "sha512-4BG7puHpVsIYxZUbiUE3RqGloLaSSwzYie5jvasC4LWuBWzZawynvYouhjbQKw2JuIGYdm0DzIxl8iVidKlUEw==",
+ "version": "6.4.6",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz",
+ "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==",
"dev": true,
"license": "MIT",
"peerDependencies": {
@@ -13588,9 +13783,9 @@
}
},
"node_modules/vite/node_modules/rollup": {
- "version": "4.42.0",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.42.0.tgz",
- "integrity": "sha512-LW+Vse3BJPyGJGAJt1j8pWDKPd73QM8cRXYK1IxOBgL2AGLu7Xd2YOW0M2sLUBCkF5MshXXtMApyEAEzMVMsnw==",
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.43.0.tgz",
+ "integrity": "sha512-wdN2Kd3Twh8MAEOEJZsuxuLKCsBEo4PVNLK6tQWAn10VhsVewQLzcucMgLolRlhFybGxfclbPeEYBaP6RvUFGg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -13604,44 +13799,44 @@
"npm": ">=8.0.0"
},
"optionalDependencies": {
- "@rollup/rollup-android-arm-eabi": "4.42.0",
- "@rollup/rollup-android-arm64": "4.42.0",
- "@rollup/rollup-darwin-arm64": "4.42.0",
- "@rollup/rollup-darwin-x64": "4.42.0",
- "@rollup/rollup-freebsd-arm64": "4.42.0",
- "@rollup/rollup-freebsd-x64": "4.42.0",
- "@rollup/rollup-linux-arm-gnueabihf": "4.42.0",
- "@rollup/rollup-linux-arm-musleabihf": "4.42.0",
- "@rollup/rollup-linux-arm64-gnu": "4.42.0",
- "@rollup/rollup-linux-arm64-musl": "4.42.0",
- "@rollup/rollup-linux-loongarch64-gnu": "4.42.0",
- "@rollup/rollup-linux-powerpc64le-gnu": "4.42.0",
- "@rollup/rollup-linux-riscv64-gnu": "4.42.0",
- "@rollup/rollup-linux-riscv64-musl": "4.42.0",
- "@rollup/rollup-linux-s390x-gnu": "4.42.0",
- "@rollup/rollup-linux-x64-gnu": "4.42.0",
- "@rollup/rollup-linux-x64-musl": "4.42.0",
- "@rollup/rollup-win32-arm64-msvc": "4.42.0",
- "@rollup/rollup-win32-ia32-msvc": "4.42.0",
- "@rollup/rollup-win32-x64-msvc": "4.42.0",
+ "@rollup/rollup-android-arm-eabi": "4.43.0",
+ "@rollup/rollup-android-arm64": "4.43.0",
+ "@rollup/rollup-darwin-arm64": "4.43.0",
+ "@rollup/rollup-darwin-x64": "4.43.0",
+ "@rollup/rollup-freebsd-arm64": "4.43.0",
+ "@rollup/rollup-freebsd-x64": "4.43.0",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.43.0",
+ "@rollup/rollup-linux-arm-musleabihf": "4.43.0",
+ "@rollup/rollup-linux-arm64-gnu": "4.43.0",
+ "@rollup/rollup-linux-arm64-musl": "4.43.0",
+ "@rollup/rollup-linux-loongarch64-gnu": "4.43.0",
+ "@rollup/rollup-linux-powerpc64le-gnu": "4.43.0",
+ "@rollup/rollup-linux-riscv64-gnu": "4.43.0",
+ "@rollup/rollup-linux-riscv64-musl": "4.43.0",
+ "@rollup/rollup-linux-s390x-gnu": "4.43.0",
+ "@rollup/rollup-linux-x64-gnu": "4.43.0",
+ "@rollup/rollup-linux-x64-musl": "4.43.0",
+ "@rollup/rollup-win32-arm64-msvc": "4.43.0",
+ "@rollup/rollup-win32-ia32-msvc": "4.43.0",
+ "@rollup/rollup-win32-x64-msvc": "4.43.0",
"fsevents": "~2.3.2"
}
},
"node_modules/vitest": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.2.tgz",
- "integrity": "sha512-fyNn/Rp016Bt5qvY0OQvIUCwW2vnaEBLxP42PmKbNIoasSYjML+8xyeADOPvBe+Xfl/ubIw4og7Lt9jflRsCNw==",
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.3.tgz",
+ "integrity": "sha512-E6U2ZFXe3N/t4f5BwUaVCKRLHqUpk1CBWeMh78UT4VaTPH/2dyvH6ALl29JTovEPu9dVKr/K/J4PkXgrMbw4Ww==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/chai": "^5.2.2",
- "@vitest/expect": "3.2.2",
- "@vitest/mocker": "3.2.2",
- "@vitest/pretty-format": "^3.2.2",
- "@vitest/runner": "3.2.2",
- "@vitest/snapshot": "3.2.2",
- "@vitest/spy": "3.2.2",
- "@vitest/utils": "3.2.2",
+ "@vitest/expect": "3.2.3",
+ "@vitest/mocker": "3.2.3",
+ "@vitest/pretty-format": "^3.2.3",
+ "@vitest/runner": "3.2.3",
+ "@vitest/snapshot": "3.2.3",
+ "@vitest/spy": "3.2.3",
+ "@vitest/utils": "3.2.3",
"chai": "^5.2.0",
"debug": "^4.4.1",
"expect-type": "^1.2.1",
@@ -13655,7 +13850,7 @@
"tinypool": "^1.1.0",
"tinyrainbow": "^2.0.0",
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0",
- "vite-node": "3.2.2",
+ "vite-node": "3.2.3",
"why-is-node-running": "^2.3.0"
},
"bin": {
@@ -13671,8 +13866,8 @@
"@edge-runtime/vm": "*",
"@types/debug": "^4.1.12",
"@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
- "@vitest/browser": "3.2.2",
- "@vitest/ui": "3.2.2",
+ "@vitest/browser": "3.2.3",
+ "@vitest/ui": "3.2.3",
"happy-dom": "*",
"jsdom": "*"
},
@@ -13846,9 +14041,9 @@
}
},
"node_modules/vue-eslint-parser/node_modules/eslint-scope": {
- "version": "8.3.0",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz",
- "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==",
+ "version": "8.4.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
+ "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
"dev": true,
"license": "BSD-2-Clause",
"peer": true,
@@ -13916,14 +14111,10 @@
}
},
"node_modules/webidl-conversions": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
- "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
- "dev": true,
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=12"
- }
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
+ "license": "BSD-2-Clause"
},
"node_modules/webpack": {
"version": "5.99.9",
@@ -14104,12 +14295,6 @@
"webidl-conversions": "^3.0.0"
}
},
- "node_modules/whatwg-url/node_modules/webidl-conversions": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
- "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
- "license": "BSD-2-Clause"
- },
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
diff --git a/package.json b/package.json
index 0f12b831fa..96ade30f37 100644
--- a/package.json
+++ b/package.json
@@ -36,16 +36,16 @@
"license-checker-webpack-plugin": "0.2.1",
"mermaid": "11.6.0",
"mini-css-extract-plugin": "2.9.2",
- "minimatch": "10.0.1",
+ "minimatch": "10.0.2",
"monaco-editor": "0.52.2",
"monaco-editor-webpack-plugin": "7.1.0",
"pdfobject": "2.3.1",
"perfect-debounce": "1.0.0",
- "postcss": "8.5.4",
+ "postcss": "8.5.5",
"postcss-loader": "8.1.1",
- "postcss-nesting": "13.0.1",
+ "postcss-nesting": "13.0.2",
"sortablejs": "1.15.6",
- "swagger-ui-dist": "5.24.0",
+ "swagger-ui-dist": "5.24.1",
"tailwindcss": "3.4.17",
"throttle-debounce": "5.0.2",
"tinycolor2": "1.6.0",
@@ -65,7 +65,7 @@
},
"devDependencies": {
"@eslint-community/eslint-plugin-eslint-comments": "4.5.0",
- "@playwright/test": "1.52.0",
+ "@playwright/test": "1.53.0",
"@stoplight/spectral-cli": "6.15.0",
"@stylistic/eslint-plugin-js": "3.1.0",
"@stylistic/stylelint-plugin": "3.1.2",
@@ -79,25 +79,25 @@
"@types/throttle-debounce": "5.0.2",
"@types/tinycolor2": "1.4.6",
"@types/toastify-js": "1.12.4",
- "@typescript-eslint/eslint-plugin": "8.33.1",
- "@typescript-eslint/parser": "8.33.1",
+ "@typescript-eslint/eslint-plugin": "8.34.0",
+ "@typescript-eslint/parser": "8.34.0",
"@vitejs/plugin-vue": "5.2.4",
- "@vitest/eslint-plugin": "1.2.1",
+ "@vitest/eslint-plugin": "1.2.2",
"eslint": "8.57.0",
"eslint-import-resolver-typescript": "4.4.3",
"eslint-plugin-array-func": "4.0.0",
"eslint-plugin-github": "5.0.2",
- "eslint-plugin-import-x": "4.15.1",
+ "eslint-plugin-import-x": "4.15.2",
"eslint-plugin-no-jquery": "3.1.1",
"eslint-plugin-no-use-extend-native": "0.5.0",
"eslint-plugin-playwright": "2.2.0",
- "eslint-plugin-regexp": "2.8.0",
+ "eslint-plugin-regexp": "2.9.0",
"eslint-plugin-sonarjs": "3.0.2",
"eslint-plugin-unicorn": "56.0.1",
"eslint-plugin-vue": "10.2.0",
"eslint-plugin-vue-scoped-css": "2.10.0",
"eslint-plugin-wc": "3.0.1",
- "happy-dom": "17.6.3",
+ "happy-dom": "18.0.1",
"markdownlint-cli": "0.45.0",
"material-icon-theme": "5.23.0",
"nolyfill": "1.0.44",
@@ -112,7 +112,7 @@
"type-fest": "4.41.0",
"updates": "16.4.2",
"vite-string-plugin": "1.4.4",
- "vitest": "3.2.2",
+ "vitest": "3.2.3",
"vue-tsc": "2.2.10"
},
"browserslist": [
diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go
index 95512cb9b6..2c138ad61a 100644
--- a/routers/api/v1/api.go
+++ b/routers/api/v1/api.go
@@ -971,7 +971,8 @@ func Routes() *web.Router {
// Misc (public accessible)
m.Group("", func() {
m.Get("/version", misc.Version)
- m.Get("/signing-key.gpg", misc.SigningKey)
+ m.Get("/signing-key.gpg", misc.SigningKeyGPG)
+ m.Get("/signing-key.pub", misc.SigningKeySSH)
m.Post("/markup", reqToken(), bind(api.MarkupOption{}), misc.Markup)
m.Post("/markdown", reqToken(), bind(api.MarkdownOption{}), misc.Markdown)
m.Post("/markdown/raw", reqToken(), misc.MarkdownRaw)
@@ -1427,7 +1428,8 @@ func Routes() *web.Router {
m.Combo("/file-contents", reqRepoReader(unit.TypeCode), context.ReferencesGitRepo()).
Get(repo.GetFileContentsGet).
Post(bind(api.GetFilesOptions{}), repo.GetFileContentsPost) // POST method requires "write" permission, so we also support "GET" method above
- m.Get("/signing-key.gpg", misc.SigningKey)
+ m.Get("/signing-key.gpg", misc.SigningKeyGPG)
+ m.Get("/signing-key.pub", misc.SigningKeySSH)
m.Group("/topics", func() {
m.Combo("").Get(repo.ListTopics).
Put(reqToken(), reqAdmin(), bind(api.RepoTopicOptions{}), repo.UpdateTopics)
diff --git a/routers/api/v1/misc/signing.go b/routers/api/v1/misc/signing.go
index 667396e39c..db70e04b8f 100644
--- a/routers/api/v1/misc/signing.go
+++ b/routers/api/v1/misc/signing.go
@@ -4,14 +4,35 @@
package misc
import (
- "fmt"
-
+ "code.gitea.io/gitea/modules/git"
asymkey_service "code.gitea.io/gitea/services/asymkey"
"code.gitea.io/gitea/services/context"
)
-// SigningKey returns the public key of the default signing key if it exists
-func SigningKey(ctx *context.APIContext) {
+func getSigningKey(ctx *context.APIContext, expectedFormat string) {
+ // if the handler is in the repo's route group, get the repo's signing key
+ // otherwise, get the global signing key
+ path := ""
+ if ctx.Repo != nil && ctx.Repo.Repository != nil {
+ path = ctx.Repo.Repository.RepoPath()
+ }
+ content, format, err := asymkey_service.PublicSigningKey(ctx, path)
+ if err != nil {
+ ctx.APIErrorInternal(err)
+ return
+ }
+ if format == "" {
+ ctx.APIErrorNotFound("no signing key")
+ return
+ } else if format != expectedFormat {
+ ctx.APIErrorNotFound("signing key format is " + format)
+ return
+ }
+ _, _ = ctx.Write([]byte(content))
+}
+
+// SigningKeyGPG returns the public key of the default signing key if it exists
+func SigningKeyGPG(ctx *context.APIContext) {
// swagger:operation GET /signing-key.gpg miscellaneous getSigningKey
// ---
// summary: Get default signing-key.gpg
@@ -44,19 +65,42 @@ func SigningKey(ctx *context.APIContext) {
// description: "GPG armored public key"
// schema:
// type: string
+ getSigningKey(ctx, git.SigningKeyFormatOpenPGP)
+}
- path := ""
- if ctx.Repo != nil && ctx.Repo.Repository != nil {
- path = ctx.Repo.Repository.RepoPath()
- }
+// SigningKeySSH returns the public key of the default signing key if it exists
+func SigningKeySSH(ctx *context.APIContext) {
+ // swagger:operation GET /signing-key.pub miscellaneous getSigningKeySSH
+ // ---
+ // summary: Get default signing-key.pub
+ // produces:
+ // - text/plain
+ // responses:
+ // "200":
+ // description: "ssh public key"
+ // schema:
+ // type: string
- content, err := asymkey_service.PublicSigningKey(ctx, path)
- if err != nil {
- ctx.APIErrorInternal(err)
- return
- }
- _, err = ctx.Write([]byte(content))
- if err != nil {
- ctx.APIErrorInternal(fmt.Errorf("Error writing key content %w", err))
- }
+ // swagger:operation GET /repos/{owner}/{repo}/signing-key.pub repository repoSigningKeySSH
+ // ---
+ // summary: Get signing-key.pub for given repository
+ // produces:
+ // - text/plain
+ // parameters:
+ // - name: owner
+ // in: path
+ // description: owner of the repo
+ // type: string
+ // required: true
+ // - name: repo
+ // in: path
+ // description: name of the repo
+ // type: string
+ // required: true
+ // responses:
+ // "200":
+ // description: "ssh public key"
+ // schema:
+ // type: string
+ getSigningKey(ctx, git.SigningKeyFormatSSH)
}
diff --git a/routers/web/misc/misc.go b/routers/web/misc/misc.go
index d42afafe9e..59b97c1717 100644
--- a/routers/web/misc/misc.go
+++ b/routers/web/misc/misc.go
@@ -20,7 +20,7 @@ func SSHInfo(rw http.ResponseWriter, req *http.Request) {
return
}
rw.Header().Set("content-type", "text/json;charset=UTF-8")
- _, err := rw.Write([]byte(`{"type":"gitea","version":1}`))
+ _, err := rw.Write([]byte(`{"type":"agit","version":1}`))
if err != nil {
log.Error("fail to write result: err: %v", err)
rw.WriteHeader(http.StatusInternalServerError)
diff --git a/routers/web/repo/setting/setting.go b/routers/web/repo/setting/setting.go
index 5552a8726c..6602685e94 100644
--- a/routers/web/repo/setting/setting.go
+++ b/routers/web/repo/setting/setting.go
@@ -62,7 +62,7 @@ func SettingsCtxData(ctx *context.Context) {
ctx.Data["CanConvertFork"] = ctx.Repo.Repository.IsFork && ctx.Doer.CanCreateRepoIn(ctx.Repo.Repository.Owner)
signing, _ := asymkey_service.SigningKey(ctx, ctx.Repo.Repository.RepoPath())
- ctx.Data["SigningKeyAvailable"] = len(signing) > 0
+ ctx.Data["SigningKeyAvailable"] = signing != nil
ctx.Data["SigningSettings"] = setting.Repository.Signing
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
@@ -105,7 +105,7 @@ func SettingsPost(ctx *context.Context) {
ctx.Data["MinimumMirrorInterval"] = setting.Mirror.MinInterval
signing, _ := asymkey_service.SigningKey(ctx, ctx.Repo.Repository.RepoPath())
- ctx.Data["SigningKeyAvailable"] = len(signing) > 0
+ ctx.Data["SigningKeyAvailable"] = signing != nil
ctx.Data["SigningSettings"] = setting.Repository.Signing
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
diff --git a/routers/web/repo/view_file.go b/routers/web/repo/view_file.go
index 3df6051975..f43433fb0d 100644
--- a/routers/web/repo/view_file.go
+++ b/routers/web/repo/view_file.go
@@ -140,13 +140,6 @@ func prepareToRenderFile(ctx *context.Context, entry *git.TreeEntry) {
ctx.Data["LFSLockHint"] = ctx.Tr("repo.editor.this_file_locked")
}
- // Assume file is not editable first.
- if fInfo.isLFSFile {
- ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.cannot_edit_lfs_files")
- } else if !isRepresentableAsText {
- ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.cannot_edit_non_text_files")
- }
-
// read all needed attributes which will be used later
// there should be no performance different between reading 2 or 4 here
attrsMap, err := attribute.CheckAttributes(ctx, ctx.Repo.GitRepo, ctx.Repo.CommitID, attribute.CheckAttributeOpts{
@@ -243,21 +236,6 @@ func prepareToRenderFile(ctx *context.Context, entry *git.TreeEntry) {
ctx.Data["FileContent"] = fileContent
ctx.Data["LineEscapeStatus"] = statuses
}
- if !fInfo.isLFSFile {
- if ctx.Repo.CanEnableEditor(ctx, ctx.Doer) {
- if lfsLock != nil && lfsLock.OwnerID != ctx.Doer.ID {
- ctx.Data["CanEditFile"] = false
- ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.this_file_locked")
- } else {
- ctx.Data["CanEditFile"] = true
- ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.edit_this_file")
- }
- } else if !ctx.Repo.RefFullName.IsBranch() {
- ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.must_be_on_a_branch")
- } else if !ctx.Repo.CanWriteToBranch(ctx, ctx.Doer, ctx.Repo.BranchName) {
- ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.fork_before_edit")
- }
- }
case fInfo.st.IsPDF():
ctx.Data["IsPDFFile"] = true
@@ -307,17 +285,49 @@ func prepareToRenderFile(ctx *context.Context, entry *git.TreeEntry) {
}
}
- if ctx.Repo.CanEnableEditor(ctx, ctx.Doer) {
- if lfsLock != nil && lfsLock.OwnerID != ctx.Doer.ID {
- ctx.Data["CanDeleteFile"] = false
- ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.this_file_locked")
- } else {
- ctx.Data["CanDeleteFile"] = true
- ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.delete_this_file")
- }
- } else if !ctx.Repo.RefFullName.IsBranch() {
+ prepareToRenderButtons(ctx, fInfo.isLFSFile, isRepresentableAsText, lfsLock)
+}
+
+func prepareToRenderButtons(ctx *context.Context, isLFSFile, isRepresentableAsText bool, lfsLock *git_model.LFSLock) {
+ // archived or mirror repository, the buttons should not be shown
+ if ctx.Repo.Repository.IsArchived || !ctx.Repo.Repository.CanEnableEditor() {
+ return
+ }
+
+ // The buttons should not be shown if it's not a branch
+ if !ctx.Repo.RefFullName.IsBranch() {
+ ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.must_be_on_a_branch")
ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.must_be_on_a_branch")
- } else if !ctx.Repo.CanWriteToBranch(ctx, ctx.Doer, ctx.Repo.BranchName) {
+ return
+ }
+
+ if isLFSFile {
+ ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.cannot_edit_lfs_files")
+ } else if !isRepresentableAsText {
+ ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.cannot_edit_non_text_files")
+ }
+
+ if !ctx.Repo.CanWriteToBranch(ctx, ctx.Doer, ctx.Repo.BranchName) {
+ if !isLFSFile { // lfs file cannot be edited after fork
+ ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.fork_before_edit")
+ }
ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.must_have_write_access")
+ return
+ }
+
+ // it's a lfs file and the user is not the owner of the lock
+ if lfsLock != nil && lfsLock.OwnerID != ctx.Doer.ID {
+ ctx.Data["CanEditFile"] = false
+ ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.this_file_locked")
+ ctx.Data["CanDeleteFile"] = false
+ ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.this_file_locked")
+ return
+ }
+
+ if !isLFSFile { // lfs file cannot be edited
+ ctx.Data["CanEditFile"] = true
+ ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.edit_this_file")
}
+ ctx.Data["CanDeleteFile"] = true
+ ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.delete_this_file")
}
diff --git a/services/asymkey/commit.go b/services/asymkey/commit.go
index 105782a93a..148f51fd10 100644
--- a/services/asymkey/commit.go
+++ b/services/asymkey/commit.go
@@ -6,6 +6,7 @@ package asymkey
import (
"context"
"fmt"
+ "slices"
"strings"
asymkey_model "code.gitea.io/gitea/models/asymkey"
@@ -359,24 +360,39 @@ func VerifyWithGPGSettings(ctx context.Context, gpgSettings *git.GPGSettings, si
return nil
}
+func verifySSHCommitVerificationByInstanceKey(c *git.Commit, committerUser, signerUser *user_model.User, committerGitEmail, publicKeyContent string) *asymkey_model.CommitVerification {
+ fingerprint, err := asymkey_model.CalcFingerprint(publicKeyContent)
+ if err != nil {
+ log.Error("Error calculating the fingerprint public key %q, err: %v", publicKeyContent, err)
+ return nil
+ }
+ sshPubKey := &asymkey_model.PublicKey{
+ Verified: true,
+ Content: publicKeyContent,
+ Fingerprint: fingerprint,
+ HasUsed: true,
+ }
+ return verifySSHCommitVerification(c.Signature.Signature, c.Signature.Payload, sshPubKey, committerUser, signerUser, committerGitEmail)
+}
+
// ParseCommitWithSSHSignature check if signature is good against keystore.
-func ParseCommitWithSSHSignature(ctx context.Context, c *git.Commit, committer *user_model.User) *asymkey_model.CommitVerification {
+func ParseCommitWithSSHSignature(ctx context.Context, c *git.Commit, committerUser *user_model.User) *asymkey_model.CommitVerification {
// Now try to associate the signature with the committer, if present
- if committer.ID != 0 {
+ if committerUser.ID != 0 {
keys, err := db.Find[asymkey_model.PublicKey](ctx, asymkey_model.FindPublicKeyOptions{
- OwnerID: committer.ID,
+ OwnerID: committerUser.ID,
NotKeytype: asymkey_model.KeyTypePrincipal,
})
if err != nil { // Skipping failed to get ssh keys of user
log.Error("ListPublicKeys: %v", err)
return &asymkey_model.CommitVerification{
- CommittingUser: committer,
+ CommittingUser: committerUser,
Verified: false,
Reason: "gpg.error.failed_retrieval_gpg_keys",
}
}
- committerEmailAddresses, err := cache.GetWithContextCache(ctx, cachegroup.UserEmailAddresses, committer.ID, user_model.GetEmailAddresses)
+ committerEmailAddresses, err := cache.GetWithContextCache(ctx, cachegroup.UserEmailAddresses, committerUser.ID, user_model.GetEmailAddresses)
if err != nil {
log.Error("GetEmailAddresses: %v", err)
}
@@ -391,7 +407,7 @@ func ParseCommitWithSSHSignature(ctx context.Context, c *git.Commit, committer *
for _, k := range keys {
if k.Verified && activated {
- commitVerification := verifySSHCommitVerification(c.Signature.Signature, c.Signature.Payload, k, committer, committer, c.Committer.Email)
+ commitVerification := verifySSHCommitVerification(c.Signature.Signature, c.Signature.Payload, k, committerUser, committerUser, c.Committer.Email)
if commitVerification != nil {
return commitVerification
}
@@ -399,8 +415,45 @@ func ParseCommitWithSSHSignature(ctx context.Context, c *git.Commit, committer *
}
}
+ // Try the pre-set trusted keys (for key-rotation purpose)
+ // At the moment, we still use the SigningName&SigningEmail for the rotated keys.
+ // Maybe in the future we can extend the key format to "ssh-xxx .... old-user@example.com" to support different signer emails.
+ for _, k := range setting.Repository.Signing.TrustedSSHKeys {
+ signerUser := &user_model.User{
+ Name: setting.Repository.Signing.SigningName,
+ Email: setting.Repository.Signing.SigningEmail,
+ }
+ commitVerification := verifySSHCommitVerificationByInstanceKey(c, committerUser, signerUser, c.Committer.Email, k)
+ if commitVerification != nil && commitVerification.Verified {
+ return commitVerification
+ }
+ }
+
+ // Try the configured instance-wide SSH public key
+ if setting.Repository.Signing.SigningFormat == git.SigningKeyFormatSSH && !slices.Contains([]string{"", "default", "none"}, setting.Repository.Signing.SigningKey) {
+ gpgSettings := git.GPGSettings{
+ Sign: true,
+ KeyID: setting.Repository.Signing.SigningKey,
+ Name: setting.Repository.Signing.SigningName,
+ Email: setting.Repository.Signing.SigningEmail,
+ Format: setting.Repository.Signing.SigningFormat,
+ }
+ signerUser := &user_model.User{
+ Name: gpgSettings.Name,
+ Email: gpgSettings.Email,
+ }
+ if err := gpgSettings.LoadPublicKeyContent(); err != nil {
+ log.Error("Error getting instance-wide SSH signing key %q, err: %v", gpgSettings.KeyID, err)
+ } else {
+ commitVerification := verifySSHCommitVerificationByInstanceKey(c, committerUser, signerUser, gpgSettings.Email, gpgSettings.PublicKeyContent)
+ if commitVerification != nil && commitVerification.Verified {
+ return commitVerification
+ }
+ }
+ }
+
return &asymkey_model.CommitVerification{
- CommittingUser: committer,
+ CommittingUser: committerUser,
Verified: false,
Reason: asymkey_model.NoKeyFound,
}
diff --git a/services/asymkey/commit_test.go b/services/asymkey/commit_test.go
new file mode 100644
index 0000000000..0438209a61
--- /dev/null
+++ b/services/asymkey/commit_test.go
@@ -0,0 +1,54 @@
+// Copyright 2025 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package asymkey
+
+import (
+ "strings"
+ "testing"
+
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/test"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func TestParseCommitWithSSHSignature(t *testing.T) {
+ // Here we only test the TrustedSSHKeys. The complete signing test is in tests/integration/gpg_ssh_git_test.go
+ t.Run("TrustedSSHKey", func(t *testing.T) {
+ defer test.MockVariableValue(&setting.Repository.Signing.SigningName, "gitea")()
+ defer test.MockVariableValue(&setting.Repository.Signing.SigningEmail, "gitea@fake.local")()
+ defer test.MockVariableValue(&setting.Repository.Signing.TrustedSSHKeys, []string{"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH6Y4idVaW3E+bLw1uqoAfJD7o5Siu+HqS51E9oQLPE9"})()
+
+ commit, err := git.CommitFromReader(nil, git.Sha1ObjectFormat.EmptyObjectID(), strings.NewReader(`tree 9a93ffa76e8b72bdb6431910b3a506fa2b39f42e
+author User Two <user2@example.com> 1749230009 +0200
+committer User Two <user2@example.com> 1749230009 +0200
+gpgsig -----BEGIN SSH SIGNATURE-----
+ U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgfpjiJ1VpbcT5svDW6qgB8kPujl
+ KK74epLnUT2hAs8T0AAAADZ2l0AAAAAAAAAAZzaGE1MTIAAABTAAAAC3NzaC1lZDI1NTE5
+ AAAAQDX2t2iHuuLxEWHLJetYXKsgayv3c43r0pJNfAzdLN55Q65pC5M7rG6++gT2bxcpOu
+ Y6EXbpLqia9sunEF3+LQY=
+ -----END SSH SIGNATURE-----
+
+Initial commit with signed file
+`))
+ require.NoError(t, err)
+ committingUser := &user_model.User{
+ ID: 2,
+ Name: "User Two",
+ Email: "user2@example.com",
+ }
+ ret := ParseCommitWithSSHSignature(t.Context(), commit, committingUser)
+ require.NotNil(t, ret)
+ assert.True(t, ret.Verified)
+ assert.False(t, ret.Warning)
+ assert.Equal(t, committingUser, ret.CommittingUser)
+ if assert.NotNil(t, ret.SigningUser) {
+ assert.Equal(t, "gitea", ret.SigningUser.Name)
+ assert.Equal(t, "gitea@fake.local", ret.SigningUser.Email)
+ }
+ })
+}
diff --git a/services/asymkey/sign.go b/services/asymkey/sign.go
index 2216bca54a..f94462ea46 100644
--- a/services/asymkey/sign.go
+++ b/services/asymkey/sign.go
@@ -6,6 +6,7 @@ package asymkey
import (
"context"
"fmt"
+ "os"
"strings"
asymkey_model "code.gitea.io/gitea/models/asymkey"
@@ -85,9 +86,9 @@ func IsErrWontSign(err error) bool {
}
// SigningKey returns the KeyID and git Signature for the repo
-func SigningKey(ctx context.Context, repoPath string) (string, *git.Signature) {
+func SigningKey(ctx context.Context, repoPath string) (*git.SigningKey, *git.Signature) {
if setting.Repository.Signing.SigningKey == "none" {
- return "", nil
+ return nil, nil
}
if setting.Repository.Signing.SigningKey == "default" || setting.Repository.Signing.SigningKey == "" {
@@ -95,53 +96,77 @@ func SigningKey(ctx context.Context, repoPath string) (string, *git.Signature) {
value, _, _ := git.NewCommand("config", "--get", "commit.gpgsign").RunStdString(ctx, &git.RunOpts{Dir: repoPath})
sign, valid := git.ParseBool(strings.TrimSpace(value))
if !sign || !valid {
- return "", nil
+ return nil, nil
}
+ format, _, _ := git.NewCommand("config", "--default", git.SigningKeyFormatOpenPGP, "--get", "gpg.format").RunStdString(ctx, &git.RunOpts{Dir: repoPath})
signingKey, _, _ := git.NewCommand("config", "--get", "user.signingkey").RunStdString(ctx, &git.RunOpts{Dir: repoPath})
signingName, _, _ := git.NewCommand("config", "--get", "user.name").RunStdString(ctx, &git.RunOpts{Dir: repoPath})
signingEmail, _, _ := git.NewCommand("config", "--get", "user.email").RunStdString(ctx, &git.RunOpts{Dir: repoPath})
- return strings.TrimSpace(signingKey), &git.Signature{
- Name: strings.TrimSpace(signingName),
- Email: strings.TrimSpace(signingEmail),
+
+ if strings.TrimSpace(signingKey) == "" {
+ return nil, nil
}
+
+ return &git.SigningKey{
+ KeyID: strings.TrimSpace(signingKey),
+ Format: strings.TrimSpace(format),
+ }, &git.Signature{
+ Name: strings.TrimSpace(signingName),
+ Email: strings.TrimSpace(signingEmail),
+ }
}
- return setting.Repository.Signing.SigningKey, &git.Signature{
- Name: setting.Repository.Signing.SigningName,
- Email: setting.Repository.Signing.SigningEmail,
+ if setting.Repository.Signing.SigningKey == "" {
+ return nil, nil
}
+
+ return &git.SigningKey{
+ KeyID: setting.Repository.Signing.SigningKey,
+ Format: setting.Repository.Signing.SigningFormat,
+ }, &git.Signature{
+ Name: setting.Repository.Signing.SigningName,
+ Email: setting.Repository.Signing.SigningEmail,
+ }
}
// PublicSigningKey gets the public signing key within a provided repository directory
-func PublicSigningKey(ctx context.Context, repoPath string) (string, error) {
+func PublicSigningKey(ctx context.Context, repoPath string) (content, format string, err error) {
signingKey, _ := SigningKey(ctx, repoPath)
- if signingKey == "" {
- return "", nil
+ if signingKey == nil {
+ return "", "", nil
+ }
+ if signingKey.Format == git.SigningKeyFormatSSH {
+ content, err := os.ReadFile(signingKey.KeyID)
+ if err != nil {
+ log.Error("Unable to read SSH public key file in %s: %s, %v", repoPath, signingKey, err)
+ return "", signingKey.Format, err
+ }
+ return string(content), signingKey.Format, nil
}
content, stderr, err := process.GetManager().ExecDir(ctx, -1, repoPath,
- "gpg --export -a", "gpg", "--export", "-a", signingKey)
+ "gpg --export -a", "gpg", "--export", "-a", signingKey.KeyID)
if err != nil {
log.Error("Unable to get default signing key in %s: %s, %s, %v", repoPath, signingKey, stderr, err)
- return "", err
+ return "", signingKey.Format, err
}
- return content, nil
+ return content, signingKey.Format, nil
}
// SignInitialCommit determines if we should sign the initial commit to this repository
-func SignInitialCommit(ctx context.Context, repoPath string, u *user_model.User) (bool, string, *git.Signature, error) {
+func SignInitialCommit(ctx context.Context, repoPath string, u *user_model.User) (bool, *git.SigningKey, *git.Signature, error) {
rules := signingModeFromStrings(setting.Repository.Signing.InitialCommit)
signingKey, sig := SigningKey(ctx, repoPath)
- if signingKey == "" {
- return false, "", nil, &ErrWontSign{noKey}
+ if signingKey == nil {
+ return false, nil, nil, &ErrWontSign{noKey}
}
Loop:
for _, rule := range rules {
switch rule {
case never:
- return false, "", nil, &ErrWontSign{never}
+ return false, nil, nil, &ErrWontSign{never}
case always:
break Loop
case pubkey:
@@ -150,18 +175,18 @@ Loop:
IncludeSubKeys: true,
})
if err != nil {
- return false, "", nil, err
+ return false, nil, nil, err
}
if len(keys) == 0 {
- return false, "", nil, &ErrWontSign{pubkey}
+ return false, nil, nil, &ErrWontSign{pubkey}
}
case twofa:
twofaModel, err := auth.GetTwoFactorByUID(ctx, u.ID)
if err != nil && !auth.IsErrTwoFactorNotEnrolled(err) {
- return false, "", nil, err
+ return false, nil, nil, err
}
if twofaModel == nil {
- return false, "", nil, &ErrWontSign{twofa}
+ return false, nil, nil, &ErrWontSign{twofa}
}
}
}
@@ -169,19 +194,19 @@ Loop:
}
// SignWikiCommit determines if we should sign the commits to this repository wiki
-func SignWikiCommit(ctx context.Context, repo *repo_model.Repository, u *user_model.User) (bool, string, *git.Signature, error) {
+func SignWikiCommit(ctx context.Context, repo *repo_model.Repository, u *user_model.User) (bool, *git.SigningKey, *git.Signature, error) {
repoWikiPath := repo.WikiPath()
rules := signingModeFromStrings(setting.Repository.Signing.Wiki)
signingKey, sig := SigningKey(ctx, repoWikiPath)
- if signingKey == "" {
- return false, "", nil, &ErrWontSign{noKey}
+ if signingKey == nil {
+ return false, nil, nil, &ErrWontSign{noKey}
}
Loop:
for _, rule := range rules {
switch rule {
case never:
- return false, "", nil, &ErrWontSign{never}
+ return false, nil, nil, &ErrWontSign{never}
case always:
break Loop
case pubkey:
@@ -190,35 +215,35 @@ Loop:
IncludeSubKeys: true,
})
if err != nil {
- return false, "", nil, err
+ return false, nil, nil, err
}
if len(keys) == 0 {
- return false, "", nil, &ErrWontSign{pubkey}
+ return false, nil, nil, &ErrWontSign{pubkey}
}
case twofa:
twofaModel, err := auth.GetTwoFactorByUID(ctx, u.ID)
if err != nil && !auth.IsErrTwoFactorNotEnrolled(err) {
- return false, "", nil, err
+ return false, nil, nil, err
}
if twofaModel == nil {
- return false, "", nil, &ErrWontSign{twofa}
+ return false, nil, nil, &ErrWontSign{twofa}
}
case parentSigned:
gitRepo, err := gitrepo.OpenRepository(ctx, repo.WikiStorageRepo())
if err != nil {
- return false, "", nil, err
+ return false, nil, nil, err
}
defer gitRepo.Close()
commit, err := gitRepo.GetCommit("HEAD")
if err != nil {
- return false, "", nil, err
+ return false, nil, nil, err
}
if commit.Signature == nil {
- return false, "", nil, &ErrWontSign{parentSigned}
+ return false, nil, nil, &ErrWontSign{parentSigned}
}
verification := ParseCommitWithSignature(ctx, commit)
if !verification.Verified {
- return false, "", nil, &ErrWontSign{parentSigned}
+ return false, nil, nil, &ErrWontSign{parentSigned}
}
}
}
@@ -226,18 +251,18 @@ Loop:
}
// SignCRUDAction determines if we should sign a CRUD commit to this repository
-func SignCRUDAction(ctx context.Context, repoPath string, u *user_model.User, tmpBasePath, parentCommit string) (bool, string, *git.Signature, error) {
+func SignCRUDAction(ctx context.Context, repoPath string, u *user_model.User, tmpBasePath, parentCommit string) (bool, *git.SigningKey, *git.Signature, error) {
rules := signingModeFromStrings(setting.Repository.Signing.CRUDActions)
signingKey, sig := SigningKey(ctx, repoPath)
- if signingKey == "" {
- return false, "", nil, &ErrWontSign{noKey}
+ if signingKey == nil {
+ return false, nil, nil, &ErrWontSign{noKey}
}
Loop:
for _, rule := range rules {
switch rule {
case never:
- return false, "", nil, &ErrWontSign{never}
+ return false, nil, nil, &ErrWontSign{never}
case always:
break Loop
case pubkey:
@@ -246,35 +271,35 @@ Loop:
IncludeSubKeys: true,
})
if err != nil {
- return false, "", nil, err
+ return false, nil, nil, err
}
if len(keys) == 0 {
- return false, "", nil, &ErrWontSign{pubkey}
+ return false, nil, nil, &ErrWontSign{pubkey}
}
case twofa:
twofaModel, err := auth.GetTwoFactorByUID(ctx, u.ID)
if err != nil && !auth.IsErrTwoFactorNotEnrolled(err) {
- return false, "", nil, err
+ return false, nil, nil, err
}
if twofaModel == nil {
- return false, "", nil, &ErrWontSign{twofa}
+ return false, nil, nil, &ErrWontSign{twofa}
}
case parentSigned:
gitRepo, err := git.OpenRepository(ctx, tmpBasePath)
if err != nil {
- return false, "", nil, err
+ return false, nil, nil, err
}
defer gitRepo.Close()
commit, err := gitRepo.GetCommit(parentCommit)
if err != nil {
- return false, "", nil, err
+ return false, nil, nil, err
}
if commit.Signature == nil {
- return false, "", nil, &ErrWontSign{parentSigned}
+ return false, nil, nil, &ErrWontSign{parentSigned}
}
verification := ParseCommitWithSignature(ctx, commit)
if !verification.Verified {
- return false, "", nil, &ErrWontSign{parentSigned}
+ return false, nil, nil, &ErrWontSign{parentSigned}
}
}
}
@@ -282,16 +307,16 @@ Loop:
}
// SignMerge determines if we should sign a PR merge commit to the base repository
-func SignMerge(ctx context.Context, pr *issues_model.PullRequest, u *user_model.User, tmpBasePath, baseCommit, headCommit string) (bool, string, *git.Signature, error) {
+func SignMerge(ctx context.Context, pr *issues_model.PullRequest, u *user_model.User, tmpBasePath, baseCommit, headCommit string) (bool, *git.SigningKey, *git.Signature, error) {
if err := pr.LoadBaseRepo(ctx); err != nil {
log.Error("Unable to get Base Repo for pull request")
- return false, "", nil, err
+ return false, nil, nil, err
}
repo := pr.BaseRepo
signingKey, signer := SigningKey(ctx, repo.RepoPath())
- if signingKey == "" {
- return false, "", nil, &ErrWontSign{noKey}
+ if signingKey == nil {
+ return false, nil, nil, &ErrWontSign{noKey}
}
rules := signingModeFromStrings(setting.Repository.Signing.Merges)
@@ -302,7 +327,7 @@ Loop:
for _, rule := range rules {
switch rule {
case never:
- return false, "", nil, &ErrWontSign{never}
+ return false, nil, nil, &ErrWontSign{never}
case always:
break Loop
case pubkey:
@@ -311,91 +336,91 @@ Loop:
IncludeSubKeys: true,
})
if err != nil {
- return false, "", nil, err
+ return false, nil, nil, err
}
if len(keys) == 0 {
- return false, "", nil, &ErrWontSign{pubkey}
+ return false, nil, nil, &ErrWontSign{pubkey}
}
case twofa:
twofaModel, err := auth.GetTwoFactorByUID(ctx, u.ID)
if err != nil && !auth.IsErrTwoFactorNotEnrolled(err) {
- return false, "", nil, err
+ return false, nil, nil, err
}
if twofaModel == nil {
- return false, "", nil, &ErrWontSign{twofa}
+ return false, nil, nil, &ErrWontSign{twofa}
}
case approved:
protectedBranch, err := git_model.GetFirstMatchProtectedBranchRule(ctx, repo.ID, pr.BaseBranch)
if err != nil {
- return false, "", nil, err
+ return false, nil, nil, err
}
if protectedBranch == nil {
- return false, "", nil, &ErrWontSign{approved}
+ return false, nil, nil, &ErrWontSign{approved}
}
if issues_model.GetGrantedApprovalsCount(ctx, protectedBranch, pr) < 1 {
- return false, "", nil, &ErrWontSign{approved}
+ return false, nil, nil, &ErrWontSign{approved}
}
case baseSigned:
if gitRepo == nil {
gitRepo, err = git.OpenRepository(ctx, tmpBasePath)
if err != nil {
- return false, "", nil, err
+ return false, nil, nil, err
}
defer gitRepo.Close()
}
commit, err := gitRepo.GetCommit(baseCommit)
if err != nil {
- return false, "", nil, err
+ return false, nil, nil, err
}
verification := ParseCommitWithSignature(ctx, commit)
if !verification.Verified {
- return false, "", nil, &ErrWontSign{baseSigned}
+ return false, nil, nil, &ErrWontSign{baseSigned}
}
case headSigned:
if gitRepo == nil {
gitRepo, err = git.OpenRepository(ctx, tmpBasePath)
if err != nil {
- return false, "", nil, err
+ return false, nil, nil, err
}
defer gitRepo.Close()
}
commit, err := gitRepo.GetCommit(headCommit)
if err != nil {
- return false, "", nil, err
+ return false, nil, nil, err
}
verification := ParseCommitWithSignature(ctx, commit)
if !verification.Verified {
- return false, "", nil, &ErrWontSign{headSigned}
+ return false, nil, nil, &ErrWontSign{headSigned}
}
case commitsSigned:
if gitRepo == nil {
gitRepo, err = git.OpenRepository(ctx, tmpBasePath)
if err != nil {
- return false, "", nil, err
+ return false, nil, nil, err
}
defer gitRepo.Close()
}
commit, err := gitRepo.GetCommit(headCommit)
if err != nil {
- return false, "", nil, err
+ return false, nil, nil, err
}
verification := ParseCommitWithSignature(ctx, commit)
if !verification.Verified {
- return false, "", nil, &ErrWontSign{commitsSigned}
+ return false, nil, nil, &ErrWontSign{commitsSigned}
}
// need to work out merge-base
mergeBaseCommit, _, err := gitRepo.GetMergeBase("", baseCommit, headCommit)
if err != nil {
- return false, "", nil, err
+ return false, nil, nil, err
}
commitList, err := commit.CommitsBeforeUntil(mergeBaseCommit)
if err != nil {
- return false, "", nil, err
+ return false, nil, nil, err
}
for _, commit := range commitList {
verification := ParseCommitWithSignature(ctx, commit)
if !verification.Verified {
- return false, "", nil, &ErrWontSign{commitsSigned}
+ return false, nil, nil, &ErrWontSign{commitsSigned}
}
}
}
diff --git a/services/context/repo.go b/services/context/repo.go
index 61841aa90b..32d54c88ff 100644
--- a/services/context/repo.go
+++ b/services/context/repo.go
@@ -101,7 +101,7 @@ type CanCommitToBranchResults struct {
UserCanPush bool
RequireSigned bool
WillSign bool
- SigningKey string
+ SigningKey *git.SigningKey
WontSignReason string
}
@@ -123,7 +123,8 @@ func (r *Repository) CanCommitToBranch(ctx context.Context, doer *user_model.Use
sign, keyID, _, err := asymkey_service.SignCRUDAction(ctx, r.Repository.RepoPath(), doer, r.Repository.RepoPath(), git.BranchPrefix+r.BranchName)
- canCommit := r.CanEnableEditor(ctx, doer) && userCanPush
+ canEnableEditor := r.CanEnableEditor(ctx, doer)
+ canCommit := canEnableEditor && userCanPush
if requireSigned {
canCommit = canCommit && sign
}
@@ -139,7 +140,7 @@ func (r *Repository) CanCommitToBranch(ctx context.Context, doer *user_model.Use
return CanCommitToBranchResults{
CanCommitToBranch: canCommit,
- EditorEnabled: r.CanEnableEditor(ctx, doer),
+ EditorEnabled: canEnableEditor,
UserCanPush: userCanPush,
RequireSigned: requireSigned,
WillSign: sign,
diff --git a/services/pull/merge.go b/services/pull/merge.go
index 829d4b7ee1..2a2f47e880 100644
--- a/services/pull/merge.go
+++ b/services/pull/merge.go
@@ -432,10 +432,13 @@ func doMergeAndPush(ctx context.Context, pr *issues_model.PullRequest, doer *use
func commitAndSignNoAuthor(ctx *mergeContext, message string) error {
cmdCommit := git.NewCommand("commit").AddOptionFormat("--message=%s", message)
- if ctx.signKeyID == "" {
+ if ctx.signKey == nil {
cmdCommit.AddArguments("--no-gpg-sign")
} else {
- cmdCommit.AddOptionFormat("-S%s", ctx.signKeyID)
+ if ctx.signKey.Format != "" {
+ cmdCommit.AddConfig("gpg.format", ctx.signKey.Format)
+ }
+ cmdCommit.AddOptionFormat("-S%s", ctx.signKey.KeyID)
}
if err := cmdCommit.Run(ctx, ctx.RunOpts()); err != nil {
log.Error("git commit %-v: %v\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String())
diff --git a/services/pull/merge_prepare.go b/services/pull/merge_prepare.go
index 719cc6b965..31a1e13734 100644
--- a/services/pull/merge_prepare.go
+++ b/services/pull/merge_prepare.go
@@ -27,7 +27,7 @@ type mergeContext struct {
doer *user_model.User
sig *git.Signature
committer *git.Signature
- signKeyID string // empty for no-sign, non-empty to sign
+ signKey *git.SigningKey
env []string
}
@@ -99,9 +99,9 @@ func createTemporaryRepoForMerge(ctx context.Context, pr *issues_model.PullReque
mergeCtx.committer = mergeCtx.sig
// Determine if we should sign
- sign, keyID, signer, _ := asymkey_service.SignMerge(ctx, mergeCtx.pr, mergeCtx.doer, mergeCtx.tmpBasePath, "HEAD", trackingBranch)
+ sign, key, signer, _ := asymkey_service.SignMerge(ctx, mergeCtx.pr, mergeCtx.doer, mergeCtx.tmpBasePath, "HEAD", trackingBranch)
if sign {
- mergeCtx.signKeyID = keyID
+ mergeCtx.signKey = key
if pr.BaseRepo.GetTrustModel() == repo_model.CommitterTrustModel || pr.BaseRepo.GetTrustModel() == repo_model.CollaboratorCommitterTrustModel {
mergeCtx.committer = signer
}
diff --git a/services/pull/merge_squash.go b/services/pull/merge_squash.go
index 119b28736c..0049c0b117 100644
--- a/services/pull/merge_squash.go
+++ b/services/pull/merge_squash.go
@@ -71,10 +71,13 @@ func doMergeStyleSquash(ctx *mergeContext, message string) error {
cmdCommit := git.NewCommand("commit").
AddOptionFormat("--author='%s <%s>'", sig.Name, sig.Email).
AddOptionFormat("--message=%s", message)
- if ctx.signKeyID == "" {
+ if ctx.signKey == nil {
cmdCommit.AddArguments("--no-gpg-sign")
} else {
- cmdCommit.AddOptionFormat("-S%s", ctx.signKeyID)
+ if ctx.signKey.Format != "" {
+ cmdCommit.AddConfig("gpg.format", ctx.signKey.Format)
+ }
+ cmdCommit.AddOptionFormat("-S%s", ctx.signKey.KeyID)
}
if err := cmdCommit.Run(ctx, ctx.RunOpts()); err != nil {
log.Error("git commit %-v: %v\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String())
diff --git a/services/repository/files/temp_repo.go b/services/repository/files/temp_repo.go
index 493ff9998d..1cf30edc7b 100644
--- a/services/repository/files/temp_repo.go
+++ b/services/repository/files/temp_repo.go
@@ -293,15 +293,18 @@ func (t *TemporaryUploadRepository) CommitTree(ctx context.Context, opts *Commit
}
var sign bool
- var keyID string
+ var key *git.SigningKey
var signer *git.Signature
if opts.ParentCommitID != "" {
- sign, keyID, signer, _ = asymkey_service.SignCRUDAction(ctx, t.repo.RepoPath(), opts.DoerUser, t.basePath, opts.ParentCommitID)
+ sign, key, signer, _ = asymkey_service.SignCRUDAction(ctx, t.repo.RepoPath(), opts.DoerUser, t.basePath, opts.ParentCommitID)
} else {
- sign, keyID, signer, _ = asymkey_service.SignInitialCommit(ctx, t.repo.RepoPath(), opts.DoerUser)
+ sign, key, signer, _ = asymkey_service.SignInitialCommit(ctx, t.repo.RepoPath(), opts.DoerUser)
}
if sign {
- cmdCommitTree.AddOptionFormat("-S%s", keyID)
+ if key.Format != "" {
+ cmdCommitTree.AddConfig("gpg.format", key.Format)
+ }
+ cmdCommitTree.AddOptionFormat("-S%s", key.KeyID)
if t.repo.GetTrustModel() == repo_model.CommitterTrustModel || t.repo.GetTrustModel() == repo_model.CollaboratorCommitterTrustModel {
if committerSig.Name != authorSig.Name || committerSig.Email != authorSig.Email {
// Add trailers
diff --git a/services/repository/init.go b/services/repository/init.go
index bd777b8a2f..1eeeb4aa4f 100644
--- a/services/repository/init.go
+++ b/services/repository/init.go
@@ -42,9 +42,12 @@ func initRepoCommit(ctx context.Context, tmpPath string, repo *repo_model.Reposi
cmd := git.NewCommand("commit", "--message=Initial commit").
AddOptionFormat("--author='%s <%s>'", sig.Name, sig.Email)
- sign, keyID, signer, _ := asymkey_service.SignInitialCommit(ctx, tmpPath, u)
+ sign, key, signer, _ := asymkey_service.SignInitialCommit(ctx, tmpPath, u)
if sign {
- cmd.AddOptionFormat("-S%s", keyID)
+ if key.Format != "" {
+ cmd.AddConfig("gpg.format", key.Format)
+ }
+ cmd.AddOptionFormat("-S%s", key.KeyID)
if repo.GetTrustModel() == repo_model.CommitterTrustModel || repo.GetTrustModel() == repo_model.CollaboratorCommitterTrustModel {
// need to set the committer to the KeyID owner
diff --git a/services/wiki/wiki.go b/services/wiki/wiki.go
index 9405f7cfc8..0a955406e2 100644
--- a/services/wiki/wiki.go
+++ b/services/wiki/wiki.go
@@ -194,7 +194,7 @@ func updateWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model
sign, signingKey, signer, _ := asymkey_service.SignWikiCommit(ctx, repo, doer)
if sign {
- commitTreeOpts.KeyID = signingKey
+ commitTreeOpts.Key = signingKey
if repo.GetTrustModel() == repo_model.CommitterTrustModel || repo.GetTrustModel() == repo_model.CollaboratorCommitterTrustModel {
committer = signer
}
@@ -316,7 +316,7 @@ func DeleteWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model
sign, signingKey, signer, _ := asymkey_service.SignWikiCommit(ctx, repo, doer)
if sign {
- commitTreeOpts.KeyID = signingKey
+ commitTreeOpts.Key = signingKey
if repo.GetTrustModel() == repo_model.CommitterTrustModel || repo.GetTrustModel() == repo_model.CollaboratorCommitterTrustModel {
committer = signer
}
diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl
index 68b09c484b..cc9abd92bd 100644
--- a/templates/swagger/v1_json.tmpl
+++ b/templates/swagger/v1_json.tmpl
@@ -15164,6 +15164,42 @@
}
}
},
+ "/repos/{owner}/{repo}/signing-key.pub": {
+ "get": {
+ "produces": [
+ "text/plain"
+ ],
+ "tags": [
+ "repository"
+ ],
+ "summary": "Get signing-key.pub for given repository",
+ "operationId": "repoSigningKeySSH",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "owner of the repo",
+ "name": "owner",
+ "in": "path",
+ "required": true
+ },
+ {
+ "type": "string",
+ "description": "name of the repo",
+ "name": "repo",
+ "in": "path",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "ssh public key",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
"/repos/{owner}/{repo}/stargazers": {
"get": {
"produces": [
@@ -16997,6 +17033,26 @@
}
}
},
+ "/signing-key.pub": {
+ "get": {
+ "produces": [
+ "text/plain"
+ ],
+ "tags": [
+ "miscellaneous"
+ ],
+ "summary": "Get default signing-key.pub",
+ "operationId": "getSigningKeySSH",
+ "responses": {
+ "200": {
+ "description": "ssh public key",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
"/teams/{id}": {
"get": {
"produces": [
diff --git a/tests/integration/gpg_git_test.go b/tests/integration/gpg_ssh_git_test.go
index 32de200f63..56f9f87783 100644
--- a/tests/integration/gpg_git_test.go
+++ b/tests/integration/gpg_ssh_git_test.go
@@ -4,7 +4,10 @@
package integration
import (
+ "crypto/ed25519"
+ "crypto/rand"
"encoding/base64"
+ "encoding/pem"
"fmt"
"net/url"
"os"
@@ -23,6 +26,7 @@ import (
"github.com/ProtonMail/go-crypto/openpgp/armor"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+ "golang.org/x/crypto/ssh"
)
func TestGPGGit(t *testing.T) {
@@ -42,6 +46,37 @@ func TestGPGGit(t *testing.T) {
defer test.MockVariableValue(&setting.Repository.Signing.InitialCommit, []string{"never"})()
defer test.MockVariableValue(&setting.Repository.Signing.CRUDActions, []string{"never"})()
+ testGitSigning(t)
+}
+
+func TestSSHGit(t *testing.T) {
+ tmpDir := t.TempDir() // use a temp dir to store the SSH keys
+ err := os.Chmod(tmpDir, 0o700)
+ assert.NoError(t, err)
+
+ pub, priv, err := ed25519.GenerateKey(rand.Reader)
+ require.NoError(t, err, "ed25519.GenerateKey")
+ sshPubKey, err := ssh.NewPublicKey(pub)
+ require.NoError(t, err, "ssh.NewPublicKey")
+
+ err = os.WriteFile(tmpDir+"/id_ed25519.pub", ssh.MarshalAuthorizedKey(sshPubKey), 0o600)
+ require.NoError(t, err, "os.WriteFile id_ed25519.pub")
+ block, err := ssh.MarshalPrivateKey(priv, "")
+ require.NoError(t, err, "ssh.MarshalPrivateKey")
+ err = os.WriteFile(tmpDir+"/id_ed25519", pem.EncodeToMemory(block), 0o600)
+ require.NoError(t, err, "os.WriteFile id_ed25519")
+
+ defer test.MockVariableValue(&setting.Repository.Signing.SigningKey, tmpDir+"/id_ed25519.pub")()
+ defer test.MockVariableValue(&setting.Repository.Signing.SigningName, "gitea")()
+ defer test.MockVariableValue(&setting.Repository.Signing.SigningEmail, "gitea@fake.local")()
+ defer test.MockVariableValue(&setting.Repository.Signing.SigningFormat, "ssh")()
+ defer test.MockVariableValue(&setting.Repository.Signing.InitialCommit, []string{"never"})()
+ defer test.MockVariableValue(&setting.Repository.Signing.CRUDActions, []string{"never"})()
+
+ testGitSigning(t)
+}
+
+func testGitSigning(t *testing.T) {
username := "user2"
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: username})
baseAPITestContext := NewAPITestContext(t, username, "repo1")
diff --git a/web_src/css/markup/content.css b/web_src/css/markup/content.css
index b983855630..8f92a51749 100644
--- a/web_src/css/markup/content.css
+++ b/web_src/css/markup/content.css
@@ -2,7 +2,7 @@
overflow: hidden;
font-size: 16px;
line-height: 1.5 !important;
- overflow-wrap: anywhere;
+ overflow-wrap: break-word;
}
.markup > *:first-child {
diff --git a/web_src/css/repo/home.css b/web_src/css/repo/home.css
index 61b0a1f962..ee371f1b1c 100644
--- a/web_src/css/repo/home.css
+++ b/web_src/css/repo/home.css
@@ -67,6 +67,7 @@
.repo-view-content {
flex: 1;
+ min-width: 0;
}
.language-stats {
diff --git a/web_src/fomantic/build/components/dropdown.js b/web_src/fomantic/build/components/dropdown.js
index 9d0e07b33b..85530c7991 100644
--- a/web_src/fomantic/build/components/dropdown.js
+++ b/web_src/fomantic/build/components/dropdown.js
@@ -525,6 +525,7 @@ $.fn.dropdown = function(parameters) {
return true;
}
if(settings.onShow.call(element) !== false) {
+ settings.onAfterFiltered.call(element); // GITEA-PATCH: callback to correctly handle the filtered items
module.animate.show(function() {
if( module.can.click() ) {
module.bind.intent();
diff --git a/web_src/js/features/common-fetch-action.ts b/web_src/js/features/common-fetch-action.ts
index 2da481e521..a4a69540a8 100644
--- a/web_src/js/features/common-fetch-action.ts
+++ b/web_src/js/features/common-fetch-action.ts
@@ -56,8 +56,12 @@ async function fetchActionDoRequest(actionElem: HTMLElement, url: string, opt: R
actionElem.classList.remove('is-loading', 'loading-icon-2px');
}
-async function formFetchAction(formEl: HTMLFormElement, e: SubmitEvent) {
+async function onFormFetchActionSubmit(formEl: HTMLFormElement, e: SubmitEvent) {
e.preventDefault();
+ await submitFormFetchAction(formEl, submitEventSubmitter(e));
+}
+
+export async function submitFormFetchAction(formEl: HTMLFormElement, formSubmitter?: HTMLElement) {
if (formEl.classList.contains('is-loading')) return;
formEl.classList.add('is-loading');
@@ -68,7 +72,6 @@ async function formFetchAction(formEl: HTMLFormElement, e: SubmitEvent) {
const formMethod = formEl.getAttribute('method') || 'get';
const formActionUrl = formEl.getAttribute('action');
const formData = new FormData(formEl);
- const formSubmitter = submitEventSubmitter(e);
const [submitterName, submitterValue] = [formSubmitter?.getAttribute('name'), formSubmitter?.getAttribute('value')];
if (submitterName) {
formData.append(submitterName, submitterValue || '');
@@ -96,7 +99,7 @@ async function formFetchAction(formEl: HTMLFormElement, e: SubmitEvent) {
await fetchActionDoRequest(formEl, reqUrl, reqOpt);
}
-async function linkAction(el: HTMLElement, e: Event) {
+async function onLinkActionClick(el: HTMLElement, e: Event) {
// A "link-action" can post AJAX request to its "data-url"
// Then the browser is redirected to: the "redirect" in response, or "data-redirect" attribute, or current URL by reloading.
// If the "link-action" has "data-modal-confirm" attribute, a confirm modal dialog will be shown before taking action.
@@ -126,6 +129,6 @@ async function linkAction(el: HTMLElement, e: Event) {
}
export function initGlobalFetchAction() {
- addDelegatedEventListener(document, 'submit', '.form-fetch-action', formFetchAction);
- addDelegatedEventListener(document, 'click', '.link-action', linkAction);
+ addDelegatedEventListener(document, 'submit', '.form-fetch-action', onFormFetchActionSubmit);
+ addDelegatedEventListener(document, 'click', '.link-action', onLinkActionClick);
}
diff --git a/web_src/js/features/comp/LabelEdit.ts b/web_src/js/features/comp/LabelEdit.ts
index a5bb750cdb..141c5eecfe 100644
--- a/web_src/js/features/comp/LabelEdit.ts
+++ b/web_src/js/features/comp/LabelEdit.ts
@@ -1,5 +1,6 @@
import {toggleElem} from '../../utils/dom.ts';
import {fomanticQuery} from '../../modules/fomantic/base.ts';
+import {submitFormFetchAction} from '../common-fetch-action.ts';
function nameHasScope(name: string): boolean {
return /.*[^/]\/[^/].*/.test(name);
@@ -70,7 +71,7 @@ export function initCompLabelEdit(pageSelector: string) {
form.reportValidity();
return false;
}
- form.dispatchEvent(new Event('submit', {bubbles: true}));
+ submitFormFetchAction(form);
},
}).modal('show');
};