diff --git a/.drone.yml b/.drone.yml index 8f06877fbaf88..57c888a7d985d 100644 --- a/.drone.yml +++ b/.drone.yml @@ -25,7 +25,7 @@ steps: - make deps-frontend - name: deps-backend - image: golang:1.18 + image: golang:1.19 pull: always commands: - make deps-backend @@ -88,7 +88,7 @@ steps: depends_on: [deps-frontend] - name: checks-backend - image: golang:1.18 + image: golang:1.19 commands: - make checks-backend depends_on: [deps-backend] @@ -122,7 +122,7 @@ steps: path: /go - name: build-backend-arm64 - image: golang:1.18 + image: golang:1.19 environment: GO111MODULE: on GOPROXY: https://goproxy.io @@ -138,7 +138,7 @@ steps: path: /go - name: build-backend-windows - image: golang:1.18 + image: golang:1.19 environment: GO111MODULE: on GOPROXY: https://goproxy.io @@ -153,7 +153,7 @@ steps: path: /go - name: build-backend-386 - image: golang:1.18 + image: golang:1.19 environment: GO111MODULE: on GOPROXY: https://goproxy.io @@ -243,7 +243,7 @@ steps: - pull_request - name: deps-backend - image: golang:1.18 + image: golang:1.19 pull: always commands: - make deps-backend @@ -360,7 +360,7 @@ steps: path: /go - name: generate-coverage - image: golang:1.18 + image: golang:1.19 commands: - make coverage environment: @@ -436,7 +436,7 @@ steps: - pull_request - name: deps-backend - image: golang:1.18 + image: golang:1.19 pull: always commands: - make deps-backend @@ -578,7 +578,7 @@ trigger: steps: - name: download - image: golang:1.18 + image: golang:1.19 pull: always commands: - timeout -s ABRT 40m make generate-license generate-gitignore @@ -640,7 +640,7 @@ steps: - make deps-frontend - name: deps-backend - image: golang:1.18 + image: golang:1.19 pull: always commands: - make deps-backend @@ -649,10 +649,11 @@ steps: path: /go - name: static - image: techknowlogick/xgo:go-1.18.x + image: techknowlogick/xgo:go-1.19.x pull: always commands: - - curl -sL https://deb.nodesource.com/setup_18.x | bash - && apt-get install -y nodejs + # Upgrade to node 18 once https://github.com/techknowlogick/xgo/issues/163 is resolved + - curl -sL https://deb.nodesource.com/setup_16.x | bash - && apt-get install -y nodejs - export PATH=$PATH:$GOPATH/bin - make release environment: @@ -759,7 +760,7 @@ steps: - make deps-frontend - name: deps-backend - image: golang:1.18 + image: golang:1.19 pull: always commands: - make deps-backend @@ -768,10 +769,11 @@ steps: path: /go - name: static - image: techknowlogick/xgo:go-1.18.x + image: techknowlogick/xgo:go-1.19.x pull: always commands: - - curl -sL https://deb.nodesource.com/setup_18.x | bash - && apt-get install -y nodejs + # Upgrade to node 18 once https://github.com/techknowlogick/xgo/issues/163 is resolved + - curl -sL https://deb.nodesource.com/setup_16.x | bash - && apt-get install -y nodejs - export PATH=$PATH:$GOPATH/bin - make release environment: diff --git a/.editorconfig b/.editorconfig index 0f8603e5a29e7..c0946ac9975cd 100644 --- a/.editorconfig +++ b/.editorconfig @@ -26,6 +26,3 @@ indent_style = tab [*.svg] insert_final_newline = false - -[*.md] -trim_trailing_whitespace = false diff --git a/.eslintrc.yaml b/.eslintrc.yaml index ff62d9cc93b00..4cc4060c5837f 100644 --- a/.eslintrc.yaml +++ b/.eslintrc.yaml @@ -11,12 +11,8 @@ parserOptions: plugins: - eslint-plugin-unicorn - eslint-plugin-import - - eslint-plugin-vue - - eslint-plugin-html - eslint-plugin-jquery - -extends: - - plugin:vue/recommended + - eslint-plugin-sonarjs env: es2022: true @@ -25,23 +21,16 @@ env: globals: __webpack_public_path__: true -settings: - html/html-extensions: [".tmpl"] - overrides: - - files: ["web_src/**/*.js", "web_src/**/*.vue", "templates/**/*.tmpl"] + - files: ["web_src/**/*.js", "docs/**/*.js"] env: browser: true node: false - - files: ["templates/**/*.tmpl"] - rules: - no-tabs: [0] - indent: [2, tab, {SwitchCase: 1}] - files: ["web_src/**/*worker.js"] env: worker: true rules: - no-restricted-globals: [2, addEventListener, blur, close, closed, confirm, defaultStatus, defaultstatus, error, event, external, find, focus, frameElement, frames, history, innerHeight, innerWidth, isFinite, isNaN, length, location, locationbar, menubar, moveBy, moveTo, name, onblur, onerror, onfocus, onload, onresize, onunload, open, opener, opera, outerHeight, outerWidth, pageXOffset, pageYOffset, parent, print, removeEventListener, resizeBy, resizeTo, screen, screenLeft, screenTop, screenX, screenY, scroll, scrollbars, scrollBy, scrollTo, scrollX, scrollY, status, statusbar, stop, toolbar, top] + no-restricted-globals: [2, addEventListener, blur, close, closed, confirm, defaultStatus, defaultstatus, error, event, external, find, focus, frameElement, frames, history, innerHeight, innerWidth, isFinite, isNaN, length, locationbar, menubar, moveBy, moveTo, name, onblur, onerror, onfocus, onload, onresize, onunload, open, opener, opera, outerHeight, outerWidth, pageXOffset, pageYOffset, parent, print, removeEventListener, resizeBy, resizeTo, screen, screenLeft, screenTop, screenX, screenY, scroll, scrollbars, scrollBy, scrollTo, scrollX, scrollY, status, statusbar, stop, toolbar, top] - files: ["build/generate-images.js"] rules: import/no-unresolved: [0] @@ -120,7 +109,7 @@ rules: import/no-extraneous-dependencies: [2] import/no-import-module-exports: [0] import/no-internal-modules: [0] - import/no-mutable-exports: [2] + import/no-mutable-exports: [0] import/no-named-as-default-member: [0] import/no-named-as-default: [2] import/no-named-default: [0] @@ -132,7 +121,7 @@ rules: import/no-restricted-paths: [0] import/no-self-import: [2] import/no-unassigned-import: [0] - import/no-unresolved: [2, {commonjs: true}] + import/no-unresolved: [2, {commonjs: true, ignore: ["\\?.+$"]}] import/no-unused-modules: [2, {unusedExports: true}] import/no-useless-path-segments: [2, {commonjs: true}] import/no-webpack-loader-syntax: [2] @@ -222,7 +211,7 @@ rules: no-compare-neg-zero: [2] no-cond-assign: [2, except-parens] no-confusing-arrow: [0] - no-console: [1, {allow: [info, warn, error]}] + no-console: [1, {allow: [debug, info, warn, error]}] no-const-assign: [2] no-constant-binary-expression: [2] no-constant-condition: [0] @@ -298,7 +287,7 @@ rules: no-redeclare: [2] no-regex-spaces: [2] no-restricted-exports: [0] - no-restricted-globals: [2, addEventListener, blur, close, closed, confirm, defaultStatus, defaultstatus, error, event, external, find, focus, frameElement, frames, history, innerHeight, innerWidth, isFinite, isNaN, length, location, locationbar, menubar, moveBy, moveTo, name, onblur, onerror, onfocus, onload, onresize, onunload, open, opener, opera, outerHeight, outerWidth, pageXOffset, pageYOffset, parent, print, removeEventListener, resizeBy, resizeTo, screen, screenLeft, screenTop, screenX, screenY, scroll, scrollbars, scrollBy, scrollTo, scrollX, scrollY, self, status, statusbar, stop, toolbar, top] + no-restricted-globals: [2, addEventListener, blur, close, closed, confirm, defaultStatus, defaultstatus, error, event, external, find, focus, frameElement, frames, history, innerHeight, innerWidth, isFinite, isNaN, length, location, locationbar, menubar, moveBy, moveTo, name, onblur, onerror, onfocus, onload, onresize, onunload, open, opener, opera, outerHeight, outerWidth, pageXOffset, pageYOffset, parent, print, removeEventListener, resizeBy, resizeTo, screen, screenLeft, screenTop, screenX, screenY, scroll, scrollbars, scrollBy, scrollTo, scrollX, scrollY, self, status, statusbar, stop, toolbar, top, __dirname, __filename] no-restricted-imports: [0] no-restricted-syntax: [2, WithStatement, ForInStatement, LabeledStatement] no-return-assign: [0] @@ -332,7 +321,7 @@ rules: no-unused-labels: [2] no-unused-private-class-members: [2] no-unused-vars: [2, {args: all, argsIgnorePattern: ^_, varsIgnorePattern: ^_, caughtErrorsIgnorePattern: ^_, destructuredArrayIgnorePattern: ^_, ignoreRestSiblings: false}] - no-use-before-define: [2, nofunc] + no-use-before-define: [2, {functions: false, classes: true, variables: true, allowNamedExports: true}] no-useless-backreference: [0] no-useless-call: [2] no-useless-catch: [2] @@ -358,7 +347,7 @@ rules: padded-blocks: [2, never] padding-line-between-statements: [0] prefer-arrow-callback: [2, {allowNamedFunctions: true, allowUnboundThis: true}] - prefer-const: [2, {destructuring: all}] + prefer-const: [2, {destructuring: all, ignoreReadBeforeAssign: true}] prefer-destructuring: [0] prefer-exponentiation-operator: [2] prefer-named-capture-group: [0] @@ -381,6 +370,38 @@ rules: semi-spacing: [2, {before: false, after: true}] semi-style: [2, last] semi: [2, always, {omitLastInOneLineBlock: true}] + sonarjs/cognitive-complexity: [0] + sonarjs/elseif-without-else: [0] + sonarjs/max-switch-cases: [0] + sonarjs/no-all-duplicated-branches: [2] + sonarjs/no-collapsible-if: [0] + sonarjs/no-collection-size-mischeck: [2] + sonarjs/no-duplicate-string: [0] + sonarjs/no-duplicated-branches: [0] + sonarjs/no-element-overwrite: [2] + sonarjs/no-empty-collection: [2] + sonarjs/no-extra-arguments: [0] + sonarjs/no-gratuitous-expressions: [2] + sonarjs/no-identical-conditions: [2] + sonarjs/no-identical-expressions: [0] + sonarjs/no-identical-functions: [0] + sonarjs/no-ignored-return: [2] + sonarjs/no-inverted-boolean-check: [2] + sonarjs/no-nested-switch: [0] + sonarjs/no-nested-template-literals: [0] + sonarjs/no-one-iteration-loop: [2] + sonarjs/no-redundant-boolean: [2] + sonarjs/no-redundant-jump: [0] + sonarjs/no-same-line-conditional: [2] + sonarjs/no-small-switch: [0] + sonarjs/no-unused-collection: [2] + sonarjs/no-use-of-empty-return-value: [2] + sonarjs/no-useless-catch: [0] + sonarjs/non-existent-operator: [2] + sonarjs/prefer-immediate-return: [0] + sonarjs/prefer-object-literal: [0] + sonarjs/prefer-single-boolean-return: [0] + sonarjs/prefer-while: [2] sort-imports: [0] sort-keys: [0] sort-vars: [0] @@ -428,7 +449,7 @@ rules: unicorn/no-new-array: [0] unicorn/no-new-buffer: [0] unicorn/no-null: [0] - unicorn/no-object-as-default-parameter: [2] + unicorn/no-object-as-default-parameter: [0] unicorn/no-process-exit: [0] unicorn/no-reduce: [2] unicorn/no-static-only-class: [2] @@ -454,14 +475,16 @@ rules: unicorn/prefer-array-index-of: [2] unicorn/prefer-array-some: [2] unicorn/prefer-at: [0] - unicorn/prefer-code-point: [2] + unicorn/prefer-code-point: [0] unicorn/prefer-dataset: [2] unicorn/prefer-date-now: [2] unicorn/prefer-default-parameters: [0] unicorn/prefer-event-key: [2] + unicorn/prefer-event-target: [2] unicorn/prefer-export-from: [2] unicorn/prefer-includes: [2] unicorn/prefer-json-parse-buffer: [0] + unicorn/prefer-logical-operator-over-ternary: [2] unicorn/prefer-math-trunc: [2] unicorn/prefer-modern-dom-apis: [0] unicorn/prefer-modern-math-apis: [2] @@ -502,11 +525,6 @@ rules: use-isnan: [2] valid-typeof: [2, {requireStringLiterals: true}] vars-on-top: [0] - vue/attributes-order: [0] - vue/component-definition-name-casing: [0] - vue/html-closing-bracket-spacing: [0] - vue/max-attributes-per-line: [0] - vue/one-component-per-file: [0] wrap-iife: [2, inside] wrap-regex: [0] yield-star-spacing: [2, after] diff --git a/.golangci.yml b/.golangci.yml index 11c58454a0073..6e80af8c0eb29 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -29,7 +29,7 @@ linters: fast: false run: - go: 1.18 + go: 1.19 timeout: 10m skip-dirs: - node_modules @@ -75,7 +75,7 @@ linters-settings: - name: modifies-value-receiver gofumpt: extra-rules: true - lang-version: "1.18" + lang-version: "1.19" depguard: # TODO: use depguard to replace import checks in gitea-vet list-type: denylist diff --git a/.markdownlint.yaml b/.markdownlint.yaml new file mode 100644 index 0000000000000..7ccdd53e89793 --- /dev/null +++ b/.markdownlint.yaml @@ -0,0 +1,18 @@ +commands-show-output: false +fenced-code-language: false +first-line-h1: false +header-increment: false +line-length: {code_blocks: false, tables: false, stern: true, line_length: -1} +no-alt-text: false +no-bare-urls: false +no-blanks-blockquote: false +no-duplicate-header: {allow_different_nesting: true} +no-emphasis-as-header: false +no-empty-links: false +no-hard-tabs: {code_blocks: false} +no-inline-html: false +no-space-in-code: false +no-space-in-emphasis: false +no-trailing-punctuation: false +no-trailing-spaces: {br_spaces: 0} +single-h1: false diff --git a/CHANGELOG.md b/CHANGELOG.md index 454853fe2918c..ea2380d9b1adf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -155,12 +155,12 @@ been added to each release, please refer to the [blog](https://blog.gitea.io). * Don't show context cancelled errors in attribute reader (#19006) (#19027) * Fix update hint bug (#18996) (#19002) * MISC - * Fix potential assignee query for repo (#18994) (#18999) + * Fix potential assignee query for repo (#18994) (#18999) ## [1.16.3](https://github.com/go-gitea/gitea/releases/tag/v1.16.3) - 2022-03-02 * SECURITY - * Git backend ignore replace objects (#18979) (#18980) +* Git backend ignore replace objects (#18979) (#18980) * ENHANCEMENTS * Adjust error for already locked db and prevent level db lock on malformed connstr (#18923) (#18938) * BUGFIXES @@ -193,7 +193,7 @@ been added to each release, please refer to the [blog](https://blog.gitea.io). * Immediately Hammer if second kill is sent (#18823) (#18826) * Allow mermaid render error to wrap (#18791) * BUGFIXES - * Fix ldap user sync missed email in email_address table (#18786) (#18876) + * Fix ldap user sync missed email in email_address table (#18786) (#18876) * Update assignees check to include any writing team and change org sidebar (#18680) (#18873) * Don't report signal: killed errors in serviceRPC (#18850) (#18865) * Fix bug where certain LDAP settings were reverted (#18859) @@ -692,6 +692,7 @@ been added to each release, please refer to the [blog](https://blog.gitea.io). * Fix SVG side by side comparison link (#17375) (#17391) ## [1.15.4](https://github.com/go-gitea/gitea/releases/tag/v1.15.4) - 2021-10-08 + * BUGFIXES * Raw file API: don't try to interpret 40char filenames as commit SHA (#17185) (#17272) * Don't allow merged PRs to be reopened (#17192) (#17271) @@ -1338,7 +1339,7 @@ been added to each release, please refer to the [blog](https://blog.gitea.io). * Add size to Save function (#15264) (#15270) * Monaco improvements (#15333) (#15345) * Support .mailmap in code activity stats (#15009) - * Sort release attachments by name (#15008) + * Sort release attachments by name (#15008) * Add ui.explore settings to control view of explore pages (#14094) * Make internal SSH server host key path configurable (#14918) * Hide resync all ssh principals when using internal ssh server (#14904) @@ -1633,6 +1634,7 @@ been added to each release, please refer to the [blog](https://blog.gitea.io). * Return original URL of Repositories (#13885) (#13886) ## [1.13.0](https://github.com/go-gitea/gitea/releases/tag/v1.13.0) - 2020-12-01 + * SECURITY * Add Allow-/Block-List for Migrate & Mirrors (#13610) (#13776) * Prevent git operations for inactive users (#13527) (#13536) @@ -2546,6 +2548,7 @@ been added to each release, please refer to the [blog](https://blog.gitea.io). * Blacklist manifest.json & milestones user (#10292) (#10293) ## [1.11.0](https://github.com/go-gitea/gitea/releases/tag/v1.11.0) - 2020-02-10 + * BREAKING * Fix followers and following tabs in profile (#10202) (#10203) * Make CertFile and KeyFile relative to CustomPath (#9868) (#9874) @@ -2998,7 +3001,7 @@ been added to each release, please refer to the [blog](https://blog.gitea.io). This is a re-tag version of v1.10.5 and also explicitly built with Go 1.13. -WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be used. +WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should __not__ be used. ## [1.10.5](https://github.com/go-gitea/gitea/releases/tag/v1.10.5) - 2020-03-06 @@ -3019,6 +3022,7 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * Ensure that 2fa is checked on reset-password (#9857) (#9877) ## [1.10.3](https://github.com/go-gitea/gitea/releases/tag/v1.10.3) - 2020-01-17 + * SECURITY * Hide credentials when submitting migration (#9102) (#9704) * Never allow an empty password to validate (#9682) (#9684) @@ -3037,6 +3041,7 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * Branches not at ref commit ID should not be listed as Merged (#9614) (#9639) ## [1.10.2](https://github.com/go-gitea/gitea/releases/tag/v1.10.2) - 2020-01-02 + * BUGFIXES * Allow only specific Columns to be updated on Issue via API (#9539) (#9580) * Add ErrReactionAlreadyExist error (#9550) (#9564) @@ -3057,6 +3062,7 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * Fix File Edit: Author/Committer interchanged (#9297) (#9300) ## [1.10.1](https://github.com/go-gitea/gitea/releases/tag/v1.10.1) - 2019-12-05 + * BUGFIXES * Fix max length check and limit in multiple repo forms (#9148) (#9204) * Properly fix displaying virtual session provider in admin panel (#9137) (#9203) @@ -3078,6 +3084,7 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * Shadow password correctly for session config (#8984) (#9002) ## [1.10.0](https://github.com/go-gitea/gitea/releases/tag/v1.10.0) - 2019-11-13 + * BREAKING * Fix deadline on update issue or PR via API (#8698) * Hide some user information via API if user doesn't have enough permission (#8655) (#8657) @@ -3375,6 +3382,7 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * Fix Statuses API only shows first 10 statuses: Add paging and extend API GetCommitStatuses (#7141) ## [1.9.6](https://github.com/go-gitea/gitea/releases/tag/v1.9.6) - 2019-11-13 + * BUGFIXES * Allow to merge if file path contains " or \ (#8629) (#8772) * Fix 500 when edit hook (#8782) (#8790) @@ -3383,6 +3391,7 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * Add Close() method to gogitRepository (#8901) (#8958) ## [1.9.5](https://github.com/go-gitea/gitea/releases/tag/v1.9.5) - 2019-10-30 + * BREAKING * Hide some user information via API if user doesn't have enough permission (#8655) (#8658) * BUGFIXES @@ -3407,6 +3416,7 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * Update heatmap fixtures to restore tests (#8615) (#8617) ## [1.9.4](https://github.com/go-gitea/gitea/releases/tag/v1.9.4) - 2019-10-08 + * BUGFIXES * Highlight issue references (#8101) (#8404) * Fix bug when migrating a private repository #7917 (#8403) @@ -3433,6 +3443,7 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * Make show private icon when repo avatar set (#8144) (#8175) ## [1.9.3](https://github.com/go-gitea/gitea/releases/tag/v1.9.3) - 2019-09-06 + * BUGFIXES * Fix go get from a private repository with Go 1.13 (#8100) * Strict name matching for Repository.GetTagID() (#8082) @@ -3448,6 +3459,7 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * Keep blame view buttons sequence consistent with normal view when viewing a file (#8007) (#8009) ## [1.9.2](https://github.com/go-gitea/gitea/releases/tag/v1.9.2) - 2019-08-22 + * BUGFIXES * Fix wrong sender when send slack webhook (#7918) (#7924) * Upload support text/plain; charset=utf8 (#7899) @@ -3462,6 +3474,7 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * Drone/docker: prepare multi-arch release + provide arm64 image (#7571) (#7884) ## [1.9.1](https://github.com/go-gitea/gitea/releases/tag/v1.9.1) - 2019-08-14 + * BREAKING * Add pagination for admin api get orgs and fix only list public orgs bug (#7742) (#7752) * SECURITY @@ -3489,6 +3502,7 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * Correct wrong datetime format for git (#7689) (#7690) ## [1.9.0](https://github.com/go-gitea/gitea/releases/tag/v1.9.0) - 2019-07-30 + * BREAKING * Better logging (#6038) (#6095) * SECURITY @@ -3845,6 +3859,7 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * Added docker example for backup (#5846) ## [1.8.3](https://github.com/go-gitea/gitea/releases/tag/v1.8.3) - 2019-06-17 + * BUGFIXES * Always set userID on LFS authentication (#7224) (Part of #6993) * Fix LFS Locks over SSH (#6999) (#7223) @@ -3855,6 +3870,7 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * Fix GCArgs load from ini (#7156) (#7157) ## [1.8.2](https://github.com/go-gitea/gitea/releases/tag/v1.8.2) - 2019-05-29 + * BUGFIXES * Fix possbile mysql invalid connnection error (#7051) (#7071) * Handle invalid administrator username on install page (#7060) (#7063) @@ -3870,6 +3886,7 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * Fix wrong init dependency on markup extensions (#7038) (#7074) ## [1.8.1](https://github.com/go-gitea/gitea/releases/tag/v1.8.1) - 2019-05-08 + * BUGFIXES * Fix 404 when sending pull requests in some situations (#6871) (#6873) * Enforce osusergo build tag for releases (#6862) (#6869) @@ -3896,6 +3913,7 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * Fix config ui error about cache ttl (#6861) (#6865) ## [1.8.0](https://github.com/go-gitea/gitea/releases/tag/v1.8.0) - 2019-04-20 + * SECURITY * Prevent remote code execution vulnerability with mirror repo URL settings (#6593) (#6594) * Resolve 2FA bypass on API (#6676) (#6674) @@ -4130,18 +4148,21 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * Migrate database if app.ini found (#5290) ## [1.7.6](https://github.com/go-gitea/gitea/releases/tag/v1.7.6) - 2019-04-12 + * SECURITY * Prevent remote code execution vulnerability with mirror repo URL settings (#6593) (#6595) * BUGFIXES * Allow resend of confirmation email when logged in (#6482) (#6487) ## [1.7.5](https://github.com/go-gitea/gitea/releases/tag/v1.7.5) - 2019-03-27 + * BUGFIXES * Fix unitTypeCode not being used in accessLevelUnit (#6419) (#6423) * Fix bug where manifest.json was being requested without cookies and continuously creating new sessions (#6372) (#6383) * Fix ParsePatch function to work with quoted diff --git strings (#6323) (#6332) ## [1.7.4](https://github.com/go-gitea/gitea/releases/tag/v1.7.4) - 2019-03-12 + * SECURITY * Fix potential XSS vulnerability in repository description. (#6306) (#6308) * BUGFIXES @@ -4151,6 +4172,7 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * Fix displaying dashboard even if required to change password (#6214) (#6215) ## [1.7.3](https://github.com/go-gitea/gitea/releases/tag/v1.7.3) - 2019-02-27 + * BUGFIXES * Fix server 500 when trying to migrate to an already existing repository (#6188) (#6197) * Load Issue attributes for API /repos/{owner}/{repo}/issues/{index} (#6122) (#6185) @@ -4165,6 +4187,7 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * Recover panic in orgmode.Render if bad orgfile (#4982) (#5903) (#6097) ## [1.7.2](https://github.com/go-gitea/gitea/releases/tag/v1.7.2) - 2019-02-14 + * BUGFIXES * Remove all CommitStatus when a repo is deleted (#5940) (#5941) * Fix notifications on pushing with deploy keys by setting hook environment variables (#5935) (#5944) @@ -4181,6 +4204,7 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * In basic auth check for tokens before call UserSignIn (#5725) (#6083) ## [1.7.1](https://github.com/go-gitea/gitea/releases/tag/v1.7.1) - 2019-01-31 + * SECURITY * Disable redirect for i18n (#5910) (#5916) * Only allow local login if password is non-empty (#5906) (#5908) @@ -4202,6 +4226,7 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * Include Go toolchain to --version (#5832) (#5830) ## [1.7.0](https://github.com/go-gitea/gitea/releases/tag/v1.7.0) - 2019-01-22 + * SECURITY * Do not display the raw OpenID error in the UI (#5705) (#5712) * When redirecting clean the path to avoid redirecting to external site (#5669) (#5679) @@ -4358,18 +4383,21 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * Only chown directories during docker setup if necessary. Fix #4425 (#5064) ## [1.6.4](https://github.com/go-gitea/gitea/releases/tag/v1.6.4) - 2019-01-15 + * BUGFIX * Fix SSH key now can be reused as public key after deleting as deploy key (#5671) (#5685) * When redirecting clean the path to avoid redirecting to external site (#5669) (#5703) * Fix to use correct value for "MSpan Structures Obtained" (#5706) (#5715) ## [1.6.3](https://github.com/go-gitea/gitea/releases/tag/v1.6.3) - 2019-01-04 + * SECURITY * Prevent DeleteFilePost doing arbitrary deletion (#5631) * BUGFIX * Fix wrong text getting saved on editing second comment on an issue (#5608) ## [1.6.2](https://github.com/go-gitea/gitea/releases/tag/v1.6.2) - 2018-12-21 + * SECURITY * Sanitize uploaded file names (#5571) (#5573) * HTMLEncode user added text (#5570) (#5575) @@ -4384,6 +4412,7 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * Fix empty wiki (#5504) (#5508) ## [1.6.1](https://github.com/go-gitea/gitea/releases/tag/v1.6.1) - 2018-12-08 + * BUGFIXES * Fix dependent issue searching when gitea is run in subpath (#5392) (#5400) * API: '/orgs/:org/repos': return private repos with read access (#5393) @@ -4394,6 +4423,7 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * Fix topic name length on database (#5493) (#5495) ## [1.6.0](https://github.com/go-gitea/gitea/releases/tag/v1.6.0) - 2018-11-22 + * BREAKING * Respect email privacy option in user search via API (#4512) * Simply remove tidb and deps (#3993) @@ -4547,10 +4577,12 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * Fix translation (#4355) ## [1.5.3](https://github.com/go-gitea/gitea/releases/tag/v1.5.3) - 2018-10-31 + * SECURITY * Fix remote command execution vulnerability in upstream library (#5177) (#5196) ## [1.5.2](https://github.com/go-gitea/gitea/releases/tag/v1.5.2) - 2018-10-09 + * SECURITY * Enforce token on api routes (#4840) (#4905) * BUGFIXES @@ -4567,6 +4599,7 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * Fix trimming of markup section names (#4864) ## [1.5.1](https://github.com/go-gitea/gitea/releases/tag/v1.5.1) - 2018-09-03 + * SECURITY * Don't disclose emails of all users when sending out emails (#4784) * Improve URL validation for external wiki and external issues (#4710) (#4740) @@ -4581,6 +4614,7 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * Fix incorrect caption of webhook setting (#4701) (#4718) ## [1.5.0](https://github.com/go-gitea/gitea/releases/tag/v1.5.0) - 2018-08-10 + * SECURITY * Check that repositories can only be migrated to own user or organizations (#4366) (#4370) * Limit uploaded avatar image-size to 4096px x 3072px by default (#4353) @@ -4644,6 +4678,7 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * Sign release binaries (#4188) ## [1.4.3](https://github.com/go-gitea/gitea/releases/tag/v1.4.3) - 2018-06-26 + * SECURITY * HTML-escape plain-text READMEs (#4192) (#4214) * Fix open redirect vulnerability on login screen (#4312) (#4312) @@ -4656,6 +4691,7 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * Fix webhook type conflation (#4285) (#4285) ## [1.4.2](https://github.com/go-gitea/gitea/releases/tag/v1.4.2) - 2018-06-04 + * BUGFIXES * Adjust z-index for floating labels (#3939) (#3950) * Add missing token validation on application settings page (#3976) #3978 @@ -4671,6 +4707,7 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * Respository's home page not updated after first push (#4075) ## [1.4.1](https://github.com/go-gitea/gitea/releases/tag/v1.4.1) - 2018-05-03 + * BREAKING * Add "error" as reserved username (#3882) (#3886) * SECURITY @@ -4688,6 +4725,7 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * Show clipboard button if disable HTTP of git protocol (#3773) (#3774) ## [1.4.0](https://github.com/go-gitea/gitea/releases/tag/v1.4.0) - 2018-03-25 + * BREAKING * Drop deprecated GOGS\_WORK\_DIR use (#2946) * Fix API status code for hook creation (#2814) @@ -4807,6 +4845,7 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * Add owner to delete repo message (#2886) ## [1.3.1](https://github.com/go-gitea/gitea/releases/tag/v1.3.1) - 2017-12-08 + * BUGFIXES * Sanitize logs for mirror sync (#3057, #3082) (#3078) * Fix missing branch in release bug (#3108) (#3117) @@ -4817,6 +4856,7 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * Fix missing password length check when change password (#3039) (#3071) ## [1.3.0](https://github.com/go-gitea/gitea/releases/tag/v1.3.0) - 2017-11-29 + * BREAKING * Make URL scheme unambiguous (#2408) * FEATURES @@ -5044,11 +5084,13 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * Added vendor dir for js/css libs; Documented sources (#1484) (#2241) ## [1.2.3](https://github.com/go-gitea/gitea/releases/tag/v1.2.3) - 2017-11-03 + * BUGFIXES * Only require one email when validating GPG key (#2266, #2467, #2663) (#2788) * Fix order of comments (#2835) (#2839) ## [1.2.2](https://github.com/go-gitea/gitea/releases/tag/v1.2.2) - 2017-10-26 + * BUGFIXES * Add checks for commits with missing author and time (#2771) (#2785) * Fix sending mail with a non-latin display name (#2559) (#2783) @@ -5057,6 +5099,7 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * Fix emojify image URL (#2769) (#2773) ## [1.2.1](https://github.com/go-gitea/gitea/releases/tag/v1.2.1) - 2017-10-16 + * BUGFIXES * Fix PR, milestone and label functionality if issue unit is disabled (#2710) (#2714) * Fix plain readme didn't render correctly on repo home page (#2705) (#2712) @@ -5065,6 +5108,7 @@ WARNING: v1.10.5 is incorrectly tagged targeting 1.12-dev and should **not** be * Fix slice out of bounds error in mailer (#2479) (#2696) ## [1.2.0](https://github.com/go-gitea/gitea/releases/tag/v1.2.0) - 2017-10-10 + * SECURITY * Sanitation fix from Gogs (#1461) * BREAKING diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 45344a4d7bbb5..61ab3de4b9487 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -81,12 +81,12 @@ Here's how to run the test suite: |``make lint-frontend`` | lint frontend files | |``make lint-backend`` | lint backend files | -- run test code (Suggest run in Linux) +- run test code (Suggest run in Linux) | | | | :------------------------------------- | :----------------------------------------------- | |``make test[\#TestSpecificName]`` | run unit test | -|``make test-sqlite[\#TestSpecificName]``| run [integration](integrations) test for SQLite | +|``make test-sqlite[\#TestSpecificName]``| run [integration](integrations) test for SQLite | |[More details about integrations](integrations/README.md) | ## Vendoring @@ -127,14 +127,14 @@ the *[How to get faster PR reviews](https://github.com/kubernetes/community/blob it has lots of useful tips for any project you may want to contribute. Some of the key points: -* Make small pull requests. The smaller, the faster to review and the +- Make small pull requests. The smaller, the faster to review and the more likely it will be merged soon. -* Don't make changes unrelated to your PR. Maybe there are typos on +- Don't make changes unrelated to your PR. Maybe there are typos on some comments, maybe refactoring would be welcome on a function... but if that is not related to your PR, please make *another* PR for that. -* Split big pull requests into multiple small ones. An incremental change +- Split big pull requests into multiple small ones. An incremental change will be faster to review than a huge PR. -* Use the first comment as a summary explainer of your PR and you should keep this up-to-date as the PR evolves. +- Use the first comment as a summary explainer of your PR and you should keep this up-to-date as the PR evolves. If your PR could cause a breaking change you must add a BREAKING section to this comment e.g.: @@ -146,7 +146,8 @@ To explain how this could affect users and how to mitigate these changes. ## Styleguide -For imports you should use the following format (_without_ the comments) +For imports you should use the following format (*without* the comments) + ```go import ( // stdlib @@ -181,11 +182,15 @@ To maintain understandable code and avoid circular dependencies it is important ## API v1 The API is documented by [swagger](http://try.gitea.io/api/swagger) and is based on [GitHub API v3](https://developer.github.com/v3/). -Thus, Gitea´s API should use the same endpoints and fields as GitHub´s API as far as possible, unless there are good reasons to deviate. -If Gitea provides functionality that GitHub does not, a new endpoint can be created. + +Thus, Gitea´s API should use the same endpoints and fields as GitHub´s API as far as possible, unless there are good reasons to deviate. + +If Gitea provides functionality that GitHub does not, a new endpoint can be created. + If information is provided by Gitea that is not provided by the GitHub API, a new field can be used that doesn't collide with any GitHub fields. Updating an existing API should not remove existing fields unless there is a really good reason to do so. + The same applies to status responses. If you notice a problem, feel free to leave a comment in the code for future refactoring to APIv2 (which is currently not planned). All expected results (errors, success, fail messages) should be documented @@ -194,28 +199,33 @@ All expected results (errors, success, fail messages) should be documented All JSON input types must be defined as a struct in [modules/structs/](modules/structs/) ([example](https://github.com/go-gitea/gitea/blob/c620eb5b2d0d874da68ebd734d3864c5224f71f7/modules/structs/issue.go#L76-L91)) and referenced in -[routers/api/v1/swagger/options.go](https://github.com/go-gitea/gitea/blob/c620eb5b2d0d874da68ebd734d3864c5224f71f7/routers/api/v1/swagger/options.go). +[routers/api/v1/swagger/options.go](https://github.com/go-gitea/gitea/blob/c620eb5b2d0d874da68ebd734d3864c5224f71f7/routers/api/v1/swagger/options.go). + They can then be used like the following: ([example](https://github.com/go-gitea/gitea/blob/c620eb5b2d0d874da68ebd734d3864c5224f71f7/routers/api/v1/repo/issue.go#L318)). All JSON responses must be defined as a struct in [modules/structs/](modules/structs/) ([example](https://github.com/go-gitea/gitea/blob/c620eb5b2d0d874da68ebd734d3864c5224f71f7/modules/structs/issue.go#L36-L68)) and referenced in its category in [routers/api/v1/swagger/](routers/api/v1/swagger/) -([example](https://github.com/go-gitea/gitea/blob/c620eb5b2d0d874da68ebd734d3864c5224f71f7/routers/api/v1/swagger/issue.go#L11-L16)) +([example](https://github.com/go-gitea/gitea/blob/c620eb5b2d0d874da68ebd734d3864c5224f71f7/routers/api/v1/swagger/issue.go#L11-L16)) + They can be used like the following: ([example](https://github.com/go-gitea/gitea/blob/c620eb5b2d0d874da68ebd734d3864c5224f71f7/routers/api/v1/repo/issue.go#L277-L279)) In general, HTTP methods are chosen as follows: - * **GET** endpoints return requested object and status **OK (200)** - * **DELETE** endpoints return status **No Content (204)** - * **POST** endpoints return status **Created (201)**, used to **create** new objects (e.g. a User) - * **PUT** endpoints return status **No Content (204)**, used to **add/assign** existing Objects (e.g. User) to something (e.g. Org-Team) - * **PATCH** endpoints return changed object and status **OK (200)**, used to **edit/change** an existing object + +- **GET** endpoints return requested object and status **OK (200)** +- **DELETE** endpoints return status **No Content (204)** +- **POST** endpoints return status **Created (201)**, used to **create** new objects (e.g. a User) +- **PUT** endpoints return status **No Content (204)**, used to **add/assign** existing Objects (e.g. User) to something (e.g. Org-Team) +- **PATCH** endpoints return changed object and status **OK (200)**, used to **edit/change** an existing object An endpoint which changes/edits an object expects all fields to be optional (except ones to identify the object, which are required). + ### Endpoints returning lists should - * support pagination (`page` & `limit` options in query) - * set `X-Total-Count` header via **SetTotalCountHeader** ([example](https://github.com/go-gitea/gitea/blob/7aae98cc5d4113f1e9918b7ee7dd09f67c189e3e/routers/api/v1/repo/issue.go#L444)) + +- support pagination (`page` & `limit` options in query) +- set `X-Total-Count` header via **SetTotalCountHeader** ([example](https://github.com/go-gitea/gitea/blob/7aae98cc5d4113f1e9918b7ee7dd09f67c189e3e/routers/api/v1/repo/issue.go#L444)) ## Large Character Comments @@ -368,35 +378,35 @@ and lead the development of Gitea. To honor the past owners, here's the history of the owners and the time they served: -* 2022-01-01 ~ 2022-12-31 - https://github.com/go-gitea/gitea/issues/17872 - * [Lunny Xiao](https://gitea.com/lunny) - * [Matti Ranta](https://gitea.com/techknowlogick) - * [Andrew Thornton](https://gitea.com/zeripath) +- 2022-01-01 ~ 2022-12-31 - https://github.com/go-gitea/gitea/issues/17872 + - [Lunny Xiao](https://gitea.com/lunny) + - [Matti Ranta](https://gitea.com/techknowlogick) + - [Andrew Thornton](https://gitea.com/zeripath) -* 2021-01-01 ~ 2021-12-31 - https://github.com/go-gitea/gitea/issues/13801 - * [Lunny Xiao](https://gitea.com/lunny) - * [Lauris Bukšis-Haberkorns](https://gitea.com/lafriks) - * [Matti Ranta](https://gitea.com/techknowlogick) +- 2021-01-01 ~ 2021-12-31 - https://github.com/go-gitea/gitea/issues/13801 + - [Lunny Xiao](https://gitea.com/lunny) + - [Lauris Bukšis-Haberkorns](https://gitea.com/lafriks) + - [Matti Ranta](https://gitea.com/techknowlogick) -* 2020-01-01 ~ 2020-12-31 - https://github.com/go-gitea/gitea/issues/9230 - * [Lunny Xiao](https://gitea.com/lunny) - * [Lauris Bukšis-Haberkorns](https://gitea.com/lafriks) - * [Matti Ranta](https://gitea.com/techknowlogick) +- 2020-01-01 ~ 2020-12-31 - https://github.com/go-gitea/gitea/issues/9230 + - [Lunny Xiao](https://gitea.com/lunny) + - [Lauris Bukšis-Haberkorns](https://gitea.com/lafriks) + - [Matti Ranta](https://gitea.com/techknowlogick) -* 2019-01-01 ~ 2019-12-31 - https://github.com/go-gitea/gitea/issues/5572 - * [Lunny Xiao](https://github.com/lunny) - * [Lauris Bukšis-Haberkorns](https://github.com/lafriks) - * [Matti Ranta](https://github.com/techknowlogick) +- 2019-01-01 ~ 2019-12-31 - https://github.com/go-gitea/gitea/issues/5572 + - [Lunny Xiao](https://github.com/lunny) + - [Lauris Bukšis-Haberkorns](https://github.com/lafriks) + - [Matti Ranta](https://github.com/techknowlogick) -* 2018-01-01 ~ 2018-12-31 - https://github.com/go-gitea/gitea/issues/3255 - * [Lunny Xiao](https://github.com/lunny) - * [Lauris Bukšis-Haberkorns](https://github.com/lafriks) - * [Kim Carlbäcker](https://github.com/bkcsoft) +- 2018-01-01 ~ 2018-12-31 - https://github.com/go-gitea/gitea/issues/3255 + - [Lunny Xiao](https://github.com/lunny) + - [Lauris Bukšis-Haberkorns](https://github.com/lafriks) + - [Kim Carlbäcker](https://github.com/bkcsoft) -* 2016-11-04 ~ 2017-12-31 - * [Lunny Xiao](https://github.com/lunny) - * [Thomas Boerger](https://github.com/tboerger) - * [Kim Carlbäcker](https://github.com/bkcsoft) +- 2016-11-04 ~ 2017-12-31 + - [Lunny Xiao](https://github.com/lunny) + - [Thomas Boerger](https://github.com/tboerger) + - [Kim Carlbäcker](https://github.com/bkcsoft) ## Versions @@ -413,20 +423,20 @@ be reviewed by two maintainers and must pass the automatic tests. ## Releasing Gitea -* Let $vmaj, $vmin and $vpat be Major, Minor and Patch version numbers, $vpat should be rc1, rc2, 0, 1, ...... $vmaj.$vmin will be kept the same as milestones on github or gitea in future. -* Before releasing, confirm all the version's milestone issues or PRs has been resolved. Then discuss the release on Discord channel #maintainers and get agreed with almost all the owners and mergers. Or you can declare the version and if nobody against in about serval hours. -* If this is a big version first you have to create PR for changelog on branch `main` with PRs with label `changelog` and after it has been merged do following steps: - * Create `-dev` tag as `git tag -s -F release.notes v$vmaj.$vmin.0-dev` and push the tag as `git push origin v$vmaj.$vmin.0-dev`. - * When CI has finished building tag then you have to create a new branch named `release/v$vmaj.$vmin` -* If it is bugfix version create PR for changelog on branch `release/v$vmaj.$vmin` and wait till it is reviewed and merged. -* Add a tag as `git tag -s -F release.notes v$vmaj.$vmin.$`, release.notes file could be a temporary file to only include the changelog this version which you added to `CHANGELOG.md`. -* And then push the tag as `git push origin v$vmaj.$vmin.$`. Drone CI will automatically create a release and upload all the compiled binary. (But currently it doesn't add the release notes automatically. Maybe we should fix that.) -* If needed send a frontport PR for the changelog to branch `main` and update the version in `docs/config.yaml` to refer to the new version. -* Send PR to [blog repository](https://gitea.com/gitea/blog) announcing the release. -* Verify all release assets were correctly published through CI on dl.gitea.io and GitHub releases. Once ACKed: - * bump the version of https://dl.gitea.io/gitea/version.json - * merge the blog post PR - * announce the release in discord `#announcements` +- Let $vmaj, $vmin and $vpat be Major, Minor and Patch version numbers, $vpat should be rc1, rc2, 0, 1, ...... $vmaj.$vmin will be kept the same as milestones on github or gitea in future. +- Before releasing, confirm all the version's milestone issues or PRs has been resolved. Then discuss the release on Discord channel #maintainers and get agreed with almost all the owners and mergers. Or you can declare the version and if nobody against in about serval hours. +- If this is a big version first you have to create PR for changelog on branch `main` with PRs with label `changelog` and after it has been merged do following steps: + - Create `-dev` tag as `git tag -s -F release.notes v$vmaj.$vmin.0-dev` and push the tag as `git push origin v$vmaj.$vmin.0-dev`. + - When CI has finished building tag then you have to create a new branch named `release/v$vmaj.$vmin` +- If it is bugfix version create PR for changelog on branch `release/v$vmaj.$vmin` and wait till it is reviewed and merged. +- Add a tag as `git tag -s -F release.notes v$vmaj.$vmin.$`, release.notes file could be a temporary file to only include the changelog this version which you added to `CHANGELOG.md`. +- And then push the tag as `git push origin v$vmaj.$vmin.$`. Drone CI will automatically create a release and upload all the compiled binary. (But currently it doesn't add the release notes automatically. Maybe we should fix that.) +- If needed send a frontport PR for the changelog to branch `main` and update the version in `docs/config.yaml` to refer to the new version. +- Send PR to [blog repository](https://gitea.com/gitea/blog) announcing the release. +- Verify all release assets were correctly published through CI on dl.gitea.io and GitHub releases. Once ACKed: + - bump the version of https://dl.gitea.io/gitea/version.json + - merge the blog post PR + - announce the release in discord `#announcements` ## Copyright diff --git a/Dockerfile b/Dockerfile index e092b5813be49..d5d98e69a83c6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ #Build stage -FROM golang:1.18-alpine3.16 AS build-env +FROM golang:1.19-alpine3.16 AS build-env ARG GOPROXY ENV GOPROXY ${GOPROXY:-direct} diff --git a/Dockerfile.rootless b/Dockerfile.rootless index c597fb29c856d..8c2b8e98c95ac 100644 --- a/Dockerfile.rootless +++ b/Dockerfile.rootless @@ -1,5 +1,5 @@ #Build stage -FROM golang:1.18-alpine3.16 AS build-env +FROM golang:1.19-alpine3.16 AS build-env ARG GOPROXY ENV GOPROXY ${GOPROXY:-direct} diff --git a/Makefile b/Makefile index 41d39b4c32328..77aac782e1133 100644 --- a/Makefile +++ b/Makefile @@ -23,13 +23,13 @@ SHASUM ?= shasum -a 256 HAS_GO = $(shell hash $(GO) > /dev/null 2>&1 && echo "GO" || echo "NOGO" ) COMMA := , -XGO_VERSION := go-1.18.x +XGO_VERSION := go-1.19.x -AIR_PACKAGE ?= github.com/cosmtrek/air@v1.29.0 -EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/cmd/editorconfig-checker@2.4.0 -ERRCHECK_PACKAGE ?= github.com/kisielk/errcheck@v1.6.0 +AIR_PACKAGE ?= github.com/cosmtrek/air@v1.40.4 +EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/cmd/editorconfig-checker@2.5.0 +ERRCHECK_PACKAGE ?= github.com/kisielk/errcheck@v1.6.1 GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@v0.3.1 -GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@v1.46.0 +GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@v1.47.0 GXZ_PAGAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.10 MISSPELL_PACKAGE ?= github.com/client9/misspell/cmd/misspell@v0.3.4 SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.29.0 @@ -201,9 +201,9 @@ help: .PHONY: go-check go-check: - $(eval MIN_GO_VERSION_STR := $(shell grep -Eo '^go\s+[0-9]+\.[0-9.]+' go.mod | cut -d' ' -f2)) - $(eval MIN_GO_VERSION := $(shell printf "%03d%03d%03d" $(shell echo '$(MIN_GO_VERSION_STR)' | tr '.' ' '))) - $(eval GO_VERSION := $(shell printf "%03d%03d%03d" $(shell $(GO) version | grep -Eo '[0-9]+\.[0-9.]+' | tr '.' ' ');)) + $(eval MIN_GO_VERSION_STR := $(shell grep -Eo '^go\s+[0-9]+\.[0-9]+' go.mod | cut -d' ' -f2)) + $(eval MIN_GO_VERSION := $(shell printf "%03d%03d" $(shell echo '$(MIN_GO_VERSION_STR)' | tr '.' ' '))) + $(eval GO_VERSION := $(shell printf "%03d%03d" $(shell $(GO) version | grep -Eo '[0-9]+\.[0-9]+' | tr '.' ' ');)) @if [ "$(GO_VERSION)" -lt "$(MIN_GO_VERSION)" ]; then \ echo "Gitea requires Go $(MIN_GO_VERSION_STR) or greater to build. You can get it at https://go.dev/dl/"; \ exit 1; \ @@ -310,9 +310,10 @@ lint: lint-frontend lint-backend .PHONY: lint-frontend lint-frontend: node_modules - npx eslint --color --max-warnings=0 web_src/js build templates *.config.js docs/assets/js + npx eslint --color --max-warnings=0 --ext js,vue web_src/js build *.config.js docs/assets/js npx stylelint --color --max-warnings=0 web_src/less npx spectral lint -q -F hint $(SWAGGER_SPEC) + npx markdownlint docs *.md .PHONY: lint-backend lint-backend: golangci-lint vet editorconfig-checker diff --git a/README.md b/README.md index 6c5952894aca9..80f1159aea1fa 100644 --- a/README.md +++ b/README.md @@ -45,21 +45,21 @@

- View the chinese version of this document + View this document in Chinese

## Purpose The goal of this project is to make the easiest, fastest, and most painless way of setting up a self-hosted Git service. -Using Go, this can be done with an independent binary distribution across -**all platforms** which Go supports, including Linux, macOS, and Windows -on x86, amd64, ARM and PowerPC architectures. -Want to try it before doing anything else? -Do it [with the online demo](https://try.gitea.io/)! + +As Gitea is written in Go, it works across **all** the platforms and +architectures that are supported by Go, including Linux, macOS, and +Windows on x86, amd64, ARM and PowerPC architectures. +You can try it out using [the online demo](https://try.gitea.io/). This project has been [forked](https://blog.gitea.io/2016/12/welcome-to-gitea/) from -[Gogs](https://gogs.io) since 2016.11 but changed a lot. +[Gogs](https://gogs.io) since November of 2016, but a lot has changed. ## Building @@ -100,7 +100,7 @@ NOTES: ## Translating -Translations are done through Crowdin. If you want to translate to a new language ask one of the managers in the Crowdin project to add a new language there. +Translations are done through Crowdin. If you want to translate to a new language ask one of the managers in the Crowdin project to add a new language there. You can also just create an issue for adding a language or ask on discord on the #translation channel. If you need context or find some translation issues, you can leave a comment on the string or ask on Discord. For general translation questions there is a section in the docs. Currently a bit empty but we hope to fill it as questions pop up. @@ -113,15 +113,17 @@ https://docs.gitea.io/en-us/translation-guidelines/ For more information and instructions about how to install Gitea, please look at our [documentation](https://docs.gitea.io/en-us/). If you have questions that are not covered by the documentation, you can get in contact with us on our [Discord server](https://discord.gg/Gitea) or create a post in the [discourse forum](https://discourse.gitea.io/). -We maintain a list of Gitea-related projects at [gitea/awesome-gitea](https://gitea.com/gitea/awesome-gitea). -The hugo-based documentation theme is hosted at [gitea/theme](https://gitea.com/gitea/theme). +We maintain a list of Gitea-related projects at [gitea/awesome-gitea](https://gitea.com/gitea/awesome-gitea). + +The Hugo-based documentation theme is hosted at [gitea/theme](https://gitea.com/gitea/theme). + The official Gitea CLI is developed at [gitea/tea](https://gitea.com/gitea/tea). ## Authors -* [Maintainers](https://github.com/orgs/go-gitea/people) -* [Contributors](https://github.com/go-gitea/gitea/graphs/contributors) -* [Translators](options/locale/TRANSLATORS) +- [Maintainers](https://github.com/orgs/go-gitea/people) +- [Contributors](https://github.com/go-gitea/gitea/graphs/contributors) +- [Translators](options/locale/TRANSLATORS) ## Backers @@ -161,6 +163,7 @@ See the [LICENSE](https://github.com/go-gitea/gitea/blob/main/LICENSE) file for the full license text. ## Screenshots + Looking for an overview of the interface? Check it out! |![Dashboard](https://dl.gitea.io/screenshots/home_timeline.png)|![User Profile](https://dl.gitea.io/screenshots/user_profile.png)|![Global Issues](https://dl.gitea.io/screenshots/global_issues.png)| diff --git a/README_ZH.md b/README_ZH.md index 904b3a4fb6373..2be35742672fd 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -45,7 +45,7 @@

- View the english version of this document + View this document in English

## 目标 diff --git a/SECURITY.md b/SECURITY.md index 9795e3168ed52..ef98a2a8ac688 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,6 +1,7 @@ # Reporting security issues -The Gitea maintainers take security seriously. +The Gitea maintainers take security seriously. + If you discover a security issue, please bring it to their attention right away! ## Reporting a Vulnerability @@ -11,12 +12,16 @@ Please **DO NOT** file a public issue, instead send your report privately to `se Due to the sensitive nature of security information, you can use below GPG public key encrypt your mail body. -The PGP key is valid until June 24, 2024. -Key ID: 6FCD2D5B -Key Type: RSA -Expires: 6/24/2024 -Key Size: 4096/4096 -Fingerprint: 3DE0 3D1E 144A 7F06 9359 99DC AAFD 2381 6FCD 2D5B +The PGP key is valid until June 24, 2024. + +``` +Key ID: 6FCD2D5B +Key Type: RSA +Expires: 6/24/2024 +Key Size: 4096/4096 +Fingerprint: 3DE0 3D1E 144A 7F06 9359 99DC AAFD 2381 6FCD 2D5B +``` + UserID: Gitea Security ``` diff --git a/cmd/admin.go b/cmd/admin.go index 32f9a95a66581..6c2a8626c41a4 100644 --- a/cmd/admin.go +++ b/cmd/admin.go @@ -157,6 +157,10 @@ var ( Name: "email,e", Usage: "Email of the user to delete", }, + cli.BoolFlag{ + Name: "purge", + Usage: "Purge user, all their repositories, organizations and comments", + }, }, Action: runDeleteUser, } @@ -410,9 +414,9 @@ var ( Usage: "SMTP Authentication Type (PLAIN/LOGIN/CRAM-MD5) default PLAIN", }, cli.StringFlag{ - Name: "host", + Name: "addr", Value: "", - Usage: "SMTP Host", + Usage: "SMTP Addr", }, cli.IntFlag{ Name: "port", @@ -628,9 +632,10 @@ func runListUsers(c *cli.Context) error { } } } else { - fmt.Fprintf(w, "ID\tUsername\tEmail\tIsActive\tIsAdmin\n") + twofa := user_model.UserList(users).GetTwoFaStatus() + fmt.Fprintf(w, "ID\tUsername\tEmail\tIsActive\tIsAdmin\t2FA\n") for _, u := range users { - fmt.Fprintf(w, "%d\t%s\t%s\t%t\t%t\n", u.ID, u.Name, u.Email, u.IsActive, u.IsAdmin) + fmt.Fprintf(w, "%d\t%s\t%s\t%t\t%t\t%t\n", u.ID, u.Name, u.Email, u.IsActive, u.IsAdmin, twofa[u.ID]) } } @@ -675,7 +680,7 @@ func runDeleteUser(c *cli.Context) error { return fmt.Errorf("The user %s does not match the provided id %d", user.Name, c.Int64("id")) } - return user_service.DeleteUser(user) + return user_service.DeleteUser(ctx, user, c.Bool("purge")) } func runGenerateAccessToken(c *cli.Context) error { @@ -951,8 +956,8 @@ func parseSMTPConfig(c *cli.Context, conf *smtp.Source) error { } conf.Auth = c.String("auth-type") } - if c.IsSet("host") { - conf.Host = c.String("host") + if c.IsSet("addr") { + conf.Addr = c.String("addr") } if c.IsSet("port") { conf.Port = c.Int("port") diff --git a/cmd/dump.go b/cmd/dump.go index d807cb0587c13..73c2251b92bdf 100644 --- a/cmd/dump.go +++ b/cmd/dump.go @@ -92,7 +92,7 @@ func (o outputType) String() string { } var outputTypeEnum = &outputType{ - Enum: []string{"zip", "tar", "tar.sz", "tar.gz", "tar.xz", "tar.bz2", "tar.br", "tar.lz4"}, + Enum: []string{"zip", "tar", "tar.sz", "tar.gz", "tar.xz", "tar.bz2", "tar.br", "tar.lz4", "tar.zst"}, Default: "zip", } diff --git a/cmd/dump_repo.go b/cmd/dump_repo.go index c9d24c6c8367a..72456c61d3398 100644 --- a/cmd/dump_repo.go +++ b/cmd/dump_repo.go @@ -7,6 +7,8 @@ package cmd import ( "context" "errors" + "fmt" + "os" "strings" "code.gitea.io/gitea/modules/convert" @@ -15,6 +17,7 @@ import ( base "code.gitea.io/gitea/modules/migration" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/services/migrations" "github.com/urfave/cli" @@ -159,9 +162,23 @@ func runDumpRepository(ctx *cli.Context) error { } } + // the repo_dir will be removed if error occurs in DumpRepository + // make sure the directory doesn't exist or is empty, prevent from deleting user files + repoDir := ctx.String("repo_dir") + if exists, err := util.IsExist(repoDir); err != nil { + return fmt.Errorf("unable to stat repo_dir %q: %v", repoDir, err) + } else if exists { + if isDir, _ := util.IsDir(repoDir); !isDir { + return fmt.Errorf("repo_dir %q already exists but it's not a directory", repoDir) + } + if dir, _ := os.ReadDir(repoDir); len(dir) > 0 { + return fmt.Errorf("repo_dir %q is not empty", repoDir) + } + } + if err := migrations.DumpRepository( context.Background(), - ctx.String("repo_dir"), + repoDir, ctx.String("owner_name"), opts, ); err != nil { diff --git a/cmd/web.go b/cmd/web.go index 43bb0ada911e7..3bc61b04433f4 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -148,8 +148,9 @@ func runWeb(ctx *cli.Context) error { go func() { http.DefaultServeMux.Handle("/debug/fgprof", fgprof.Handler()) _, _, finished := process.GetManager().AddTypedContext(context.Background(), "Web: PProf Server", process.SystemProcessType, true) + // The pprof server is for debug purpose only, it shouldn't be exposed on public network. At the moment it's not worth to introduce a configurable option for it. log.Info("Starting pprof server on localhost:6060") - log.Info("%v", http.ListenAndServe("localhost:6060", nil)) + log.Info("Stopped pprof server: %v", http.ListenAndServe("localhost:6060", nil)) finished() }() } diff --git a/contrib/systemd/gitea.service b/contrib/systemd/gitea.service index d6a4377ec8091..79c34564bc977 100644 --- a/contrib/systemd/gitea.service +++ b/contrib/systemd/gitea.service @@ -78,6 +78,13 @@ Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/gitea #CapabilityBoundingSet=CAP_NET_BIND_SERVICE #AmbientCapabilities=CAP_NET_BIND_SERVICE ### +# In some cases, when using CapabilityBoundingSet and AmbientCapabilities option, you may want to +# set the following value to false to allow capabilities to be applied on gitea process. The following +# value if set to true sandboxes gitea service and prevent any processes from running with privileges +# in the host user namespace. +### +#PrivateUsers=false +### [Install] WantedBy=multi-user.target diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 08708948940fa..83b3048bc6b5c 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -313,6 +313,7 @@ USER = root ;DB_TYPE = sqlite3 ;PATH= ; defaults to data/gitea.db ;SQLITE_TIMEOUT = ; Query timeout defaults to: 500 +;SQLITE_JOURNAL_MODE = ; defaults to sqlite database default (often DELETE), can be used to enable WAL mode. https://www.sqlite.org/pragma.html#pragma_journal_mode ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; @@ -631,6 +632,7 @@ ROUTER = console ;GC_ARGS = ;; ;; If use git wire protocol version 2 when git version >= 2.18, default is true, set to false when you always want git wire protocol version 1 +;; To enable this for Git over SSH when using a OpenSSH server, add `AcceptEnv GIT_PROTOCOL` to your sshd_config file. ;ENABLE_AUTO_GIT_WIRE_PROTOCOL = true ;; ;; Respond to pushes to a non-default branch with a URL for creating a Pull Request (if the repository has them enabled) @@ -878,6 +880,9 @@ ROUTER = console ;; Allow deletion of unadopted repositories ;ALLOW_DELETION_OF_UNADOPTED_REPOSITORIES = false +;; Don't allow download source archive files from UI +;DISABLE_DOWNLOAD_SOURCE_ARCHIVES = false + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;[repository.editor] @@ -1078,7 +1083,7 @@ ROUTER = console ;EXPLORE_PAGING_NUM = 20 ;; ;; Number of issues that are displayed on one page -;ISSUE_PAGING_NUM = 10 +;ISSUE_PAGING_NUM = 20 ;; ;; Number of maximum commits displayed in one activity feed ;FEED_MAX_COMMIT_NUM = 5 @@ -1499,30 +1504,42 @@ ROUTER = console ;; Prefix displayed before subject in mail ;SUBJECT_PREFIX = ;; -;; Mail server -;; Gmail: smtp.gmail.com:587 -;; QQ: smtp.qq.com:465 -;; As per RFC 8314 using Implicit TLS/SMTPS on port 465 (if supported) is recommended, -;; otherwise STARTTLS on port 587 should be used. -;HOST = -;; -;; Disable HELO operation when hostnames are different. -;DISABLE_HELO = -;; -;; Custom hostname for HELO operation, if no value is provided, one is retrieved from system. +;; Mail server protocol. One of "smtp", "smtps", "smtp+startls", "smtp+unix", "sendmail", "dummy". +;; - sendmail: use the operating system's `sendmail` command instead of SMTP. This is common on Linux systems. +;; - dummy: send email messages to the log as a testing phase. +;; If your provider does not explicitly say which protocol it uses but does provide a port, +;; you can set SMTP_PORT instead and this will be inferred. +;; (Before 1.18, this was controlled via MAILER_TYPE and IS_TLS_ENABLED.) +;PROTOCOL = +;; +;; Mail server address, e.g. smtp.gmail.com. +;; For smtp+unix, this should be a path to a unix socket instead. +;; (Before 1.18, this was combined with SMTP_PORT as HOST.) +;SMTP_ADDR = +;; +;; Mail server port. Common ports are: +;; 25: insecure SMTP +;; 465: SMTP Secure +;; 587: StartTLS +;; If no protocol is specified, it will be inferred by this setting. +;; (Before 1.18, this was combined with SMTP_ADDR as HOST.) +;SMTP_PORT = +;; +;; Enable HELO operation. Defaults to true. +;ENABLE_HELO = true +;; +;; Custom hostname for HELO operation. +;; If no value is provided, one is retrieved from system. ;HELO_HOSTNAME = ;; -;; Whether or not to skip verification of certificates; `true` to disable verification. This option is unsafe. Consider adding the certificate to the system trust store instead. -;SKIP_VERIFY = false -;; -;; Use client certificate -;USE_CERTIFICATE = false -;CERT_FILE = custom/mailer/cert.pem -;KEY_FILE = custom/mailer/key.pem +;; If set to `true`, completely ignores server certificate validation errors. +;; This option is unsafe. Consider adding the certificate to the system trust store instead. +;FORCE_TRUST_SERVER_CERT = false ;; -;; Should SMTP connect with TLS, (if port ends with 465 TLS will always be used.) -;; If this is false but STARTTLS is supported the connection will be upgraded to TLS opportunistically. -;IS_TLS_ENABLED = false +;; Use client certificate in connection. +;USE_CLIENT_CERT = false +;CLIENT_CERT_FILE = custom/mailer/cert.pem +;CLIENT_KEY_FILE = custom/mailer/key.pem ;; ;; Mail from address, RFC 5322. This can be just an email address, or the `"Name" ` format ;FROM = @@ -1530,19 +1547,15 @@ ROUTER = console ;; Sometimes it is helpful to use a different address on the envelope. Set this to use ENVELOPE_FROM as the from on the envelope. Set to `<>` to send an empty address. ;ENVELOPE_FROM = ;; -;; Mailer user name and password -;; Please Note: Authentication is only supported when the SMTP server communication is encrypted with TLS (this can be via STARTTLS) or `HOST=localhost`. +;; Mailer user name and password, if required by provider. ;USER = ;; ;; Use PASSWD = `your password` for quoting if you use special characters in the password. ;PASSWD = ;; -;; Send mails as plain text +;; Send mails only in plain text, without HTML alternative ;SEND_AS_PLAIN_TEXT = false ;; -;; Set Mailer Type (either SMTP, sendmail or dummy to just send to the log) -;MAILER_TYPE = smtp -;; ;; Specify an alternative sendmail binary ;SENDMAIL_PATH = sendmail ;; diff --git a/docs/config.yaml b/docs/config.yaml index 2d15e774eb7ff..88406da5df9da 100644 --- a/docs/config.yaml +++ b/docs/config.yaml @@ -20,7 +20,7 @@ params: website: https://docs.gitea.io version: 1.16.9 minGoVersion: 1.18 - goVersion: 1.18 + goVersion: 1.19 minNodeVersion: 14 outputs: diff --git a/docs/content/doc/advanced/clone-filter.en-us.md b/docs/content/doc/advanced/clone-filter.en-us.md index ba2fdf104cc89..58675d2e941df 100644 --- a/docs/content/doc/advanced/clone-filter.en-us.md +++ b/docs/content/doc/advanced/clone-filter.en-us.md @@ -30,7 +30,6 @@ see Git version of the server. By default, clone filters are enabled, unless `DISABLE_PARTIAL_CLONE` under `[git]` is set to `true`. - See [GitHub blog post: Get up to speed with partial clone](https://github.blog/2020-12-21-get-up-to-speed-with-partial-clone-and-shallow-clone/) for common use cases of clone filters (blobless and treeless clones), and [GitLab docs for partial clone](https://docs.gitlab.com/ee/topics/git/partial_clone.html) diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md index a0e6fb8f13b1b..6b050e12b81ff 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -78,6 +78,7 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`. - `DEFAULT_BRANCH`: **main**: Default branch name of all repositories. - `ALLOW_ADOPTION_OF_UNADOPTED_REPOSITORIES`: **false**: Allow non-admin users to adopt unadopted repositories - `ALLOW_DELETION_OF_UNADOPTED_REPOSITORIES`: **false**: Allow non-admin users to delete unadopted repositories +- `DISABLE_DOWNLOAD_SOURCE_ARCHIVES`: **false**: Don't allow download source archive files from UI ### Repository - Editor (`repository.editor`) @@ -130,9 +131,9 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`. - `always`: Always sign - Options other than `never` and `always` can be combined as a comma separated list. - `DEFAULT_TRUST_MODEL`: **collaborator**: \[collaborator, committer, collaboratorcommitter\]: The default trust model used for verifying commits. - - `collaborator`: Trust signatures signed by keys of collaborators. - - `committer`: Trust signatures that match committers (This matches GitHub and will force Gitea signed commits to have Gitea as the committer). - - `collaboratorcommitter`: Trust signatures signed by keys of collaborators which match the committer. + - `collaborator`: Trust signatures signed by keys of collaborators. + - `committer`: Trust signatures that match committers (This matches GitHub and will force Gitea signed commits to have Gitea as the committer). + - `collaboratorcommitter`: Trust signatures signed by keys of collaborators which match the committer. - `WIKI`: **never**: \[never, pubkey, twofa, always, parentsigned\]: Sign commits to wiki. - `CRUD_ACTIONS`: **pubkey, twofa, parentsigned**: \[never, pubkey, twofa, parentsigned, always\]: Sign CRUD actions. - Options as above, with the addition of: @@ -152,6 +153,7 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`. Configuration for set the expected MIME type based on file extensions of downloadable files. Configuration presents in key-value pairs and file extensions starts with leading `.`. The following configuration set `Content-Type: application/vnd.android.package-archive` header when downloading files with `.apk` file extension. + ```ini .apk=application/vnd.android.package-archive ``` @@ -170,7 +172,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a ## UI (`ui`) - `EXPLORE_PAGING_NUM`: **20**: Number of repositories that are shown in one explore page. -- `ISSUE_PAGING_NUM`: **10**: Number of issues that are shown in one page (for all pages that list issues). +- `ISSUE_PAGING_NUM`: **20**: Number of issues that are shown in one page (for all pages that list issues, milestones, projects). - `MEMBERS_PAGING_NUM`: **20**: Number of members that are shown in organization members. - `FEED_MAX_COMMIT_NUM`: **5**: Number of maximum commits shown in one activity feed. - `FEED_PAGING_NUM`: **20**: Number of items that are displayed in home feed. @@ -248,11 +250,11 @@ The following configuration set `Content-Type: application/vnd.android.package-a Requests are then made as `%(ROOT_URL)s/static/css/index.css` and `https://cdn.example.com/css/index.css` respective. The static files are located in the `public/` directory of the Gitea source repository. - `HTTP_ADDR`: **0.0.0.0**: HTTP listen address. - - If `PROTOCOL` is set to `fcgi`, Gitea will listen for FastCGI requests on TCP socket + - If `PROTOCOL` is set to `fcgi`, Gitea will listen for FastCGI requests on TCP socket defined by `HTTP_ADDR` and `HTTP_PORT` configuration settings. - - If `PROTOCOL` is set to `http+unix` or `fcgi+unix`, this should be the name of the Unix socket file to use. Relative paths will be made absolute against the AppWorkPath. + - If `PROTOCOL` is set to `http+unix` or `fcgi+unix`, this should be the name of the Unix socket file to use. Relative paths will be made absolute against the AppWorkPath. - `HTTP_PORT`: **3000**: HTTP listen port. - - If `PROTOCOL` is set to `fcgi`, Gitea will listen for FastCGI requests on TCP socket + - If `PROTOCOL` is set to `fcgi`, Gitea will listen for FastCGI requests on TCP socket defined by `HTTP_ADDR` and `HTTP_PORT` configuration settings. - `UNIX_SOCKET_PERMISSION`: **666**: Permissions for the Unix socket. - `LOCAL_ROOT_URL`: **%(PROTOCOL)s://%(HTTP_ADDR)s:%(HTTP_PORT)s/**: Local @@ -300,7 +302,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a - `APP_DATA_PATH`: **data** (**/data/gitea** on docker): Default path for application data. - `STATIC_CACHE_TIME`: **6h**: Web browser cache time for static resources on `custom/`, `public/` and all uploaded avatars. Note that this cache is disabled when `RUN_MODE` is "dev". - `ENABLE_GZIP`: **false**: Enable gzip compression for runtime-generated content, static resources excluded. -- `ENABLE_PPROF`: **false**: Application profiling (memory and cpu). For "web" command it listens on localhost:6060. For "serv" command it dumps to disk at `PPROF_DATA_PATH` as `(cpuprofile|memprofile)__` +- `ENABLE_PPROF`: **false**: Application profiling (memory and cpu). For "web" command it listens on `localhost:6060`. For "serv" command it dumps to disk at `PPROF_DATA_PATH` as `(cpuprofile|memprofile)__` - `PPROF_DATA_PATH`: **data/tmp/pprof**: `PPROF_DATA_PATH`, use an absolute path when you start Gitea as service - `LANDING_PAGE`: **home**: Landing page for unauthenticated users \[home, explore, organizations, login, **custom**\]. Where custom would instead be any URL such as "/org/repo" or even `https://anotherwebsite.com` - `LFS_START_SERVER`: **false**: Enables Git LFS support. @@ -370,17 +372,18 @@ The following configuration set `Content-Type: application/vnd.android.package-a (e.g. `ALTER USER user SET SEARCH_PATH = schema_name,"$user",public;`). - `SSL_MODE`: **disable**: SSL/TLS encryption mode for connecting to the database. This option is only applied for PostgreSQL and MySQL. - Valid values for MySQL: - - `true`: Enable TLS with verification of the database server certificate against its root certificate. When selecting this option make sure that the root certificate required to validate the database server certificate (e.g. the CA certificate) is on the system certificate store of both the database and Gitea servers. See your system documentation for instructions on how to add a CA certificate to the certificate store. - - `false`: Disable TLS. - - `disable`: Alias for `false`, for compatibility with PostgreSQL. - - `skip-verify`: Enable TLS without database server certificate verification. Use this option if you have self-signed or invalid certificate on the database server. - - `prefer`: Enable TLS with fallback to non-TLS connection. + - `true`: Enable TLS with verification of the database server certificate against its root certificate. When selecting this option make sure that the root certificate required to validate the database server certificate (e.g. the CA certificate) is on the system certificate store of both the database and Gitea servers. See your system documentation for instructions on how to add a CA certificate to the certificate store. + - `false`: Disable TLS. + - `disable`: Alias for `false`, for compatibility with PostgreSQL. + - `skip-verify`: Enable TLS without database server certificate verification. Use this option if you have self-signed or invalid certificate on the database server. + - `prefer`: Enable TLS with fallback to non-TLS connection. - Valid values for PostgreSQL: - - `disable`: Disable TLS. - - `require`: Enable TLS without any verifications. - - `verify-ca`: Enable TLS with verification of the database server certificate against its root certificate. - - `verify-full`: Enable TLS and verify the database server name matches the given certificate in either the `Common Name` or `Subject Alternative Name` fields. + - `disable`: Disable TLS. + - `require`: Enable TLS without any verifications. + - `verify-ca`: Enable TLS with verification of the database server certificate against its root certificate. + - `verify-full`: Enable TLS and verify the database server name matches the given certificate in either the `Common Name` or `Subject Alternative Name` fields. - `SQLITE_TIMEOUT`: **500**: Query timeout for SQLite3 only. +- `SQLITE_JOURNAL_MODE`: **""**: Change journal mode for SQlite3. Can be used to enable [WAL mode](https://www.sqlite.org/wal.html) when high load causes write congestion. See [SQlite3 docs](https://www.sqlite.org/pragma.html#pragma_journal_mode) for possible values. Defaults to the default for the database file, often DELETE. - `ITERATE_BUFFER_SIZE`: **50**: Internal buffer size for iterating. - `CHARSET`: **utf8mb4**: For MySQL only, either "utf8" or "utf8mb4". NOTICE: for "utf8mb4" you must use MySQL InnoDB > 5.6. Gitea is unable to check this. - `PATH`: **data/gitea.db**: For SQLite3 only, the database file path. @@ -509,11 +512,11 @@ Certain queues have defaults that override the defaults set in `[queue]` (this o - `CSRF_COOKIE_HTTP_ONLY`: **true**: Set false to allow JavaScript to read CSRF cookie. - `MIN_PASSWORD_LENGTH`: **6**: Minimum password length for new users. - `PASSWORD_COMPLEXITY`: **off**: Comma separated list of character classes required to pass minimum complexity. If left empty or no valid values are specified, checking is disabled (off): - - lower - use one or more lower latin characters - - upper - use one or more upper latin characters - - digit - use one or more digits - - spec - use one or more special characters as ``!"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~`` - - off - do not check password complexity + - lower - use one or more lower latin characters + - upper - use one or more upper latin characters + - digit - use one or more digits + - spec - use one or more special characters as ``!"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~`` + - off - do not check password complexity - `PASSWORD_CHECK_PWN`: **false**: Check [HaveIBeenPwned](https://haveibeenpwned.com/Passwords) to see if a password has been exposed. - `SUCCESSFUL_TOKENS_CACHE_SIZE`: **20**: Cache successful token hashes. API tokens are stored in the DB as pbkdf2 hashes however, this means that there is a potentially significant hashing load when there are multiple API operations. This cache will store the successfully hashed tokens in a LRU cache as a balance between performance and security. @@ -535,18 +538,18 @@ Certain queues have defaults that override the defaults set in `[queue]` (this o ## OAuth2 Client (`oauth2_client`) -- `REGISTER_EMAIL_CONFIRM`: *[service]* **REGISTER\_EMAIL\_CONFIRM**: Set this to enable or disable email confirmation of OAuth2 auto-registration. (Overwrites the REGISTER\_EMAIL\_CONFIRM setting of the `[service]` section) +- `REGISTER_EMAIL_CONFIRM`: _[service]_ **REGISTER\_EMAIL\_CONFIRM**: Set this to enable or disable email confirmation of OAuth2 auto-registration. (Overwrites the REGISTER\_EMAIL\_CONFIRM setting of the `[service]` section) - `OPENID_CONNECT_SCOPES`: **\**: List of additional openid connect scopes. (`openid` is implicitly added) - `ENABLE_AUTO_REGISTRATION`: **false**: Automatically create user accounts for new oauth2 users. - `USERNAME`: **nickname**: The source of the username for new oauth2 accounts: - - userid - use the userid / sub attribute - - nickname - use the nickname attribute - - email - use the username part of the email attribute + - userid - use the userid / sub attribute + - nickname - use the nickname attribute + - email - use the username part of the email attribute - `UPDATE_AVATAR`: **false**: Update avatar if available from oauth2 provider. Update will be performed on each login. - `ACCOUNT_LINKING`: **login**: How to handle if an account / email already exists: - - disabled - show an error - - login - show an account linking login - - auto - automatically link with the account (Please be aware that this will grant access to an existing account just because the same username or email is provided. You must make sure that this does not cause issues with your authentication providers.) + - disabled - show an error + - login - show an account linking login + - auto - automatically link with the account (Please be aware that this will grant access to an existing account just because the same username or email is provided. You must make sure that this does not cause issues with your authentication providers.) ## Service (`service`) @@ -644,41 +647,35 @@ Define allowed algorithms and their minimum key length (use -1 to disable a type ## Mailer (`mailer`) - `ENABLED`: **false**: Enable to use a mail service. -- `DISABLE_HELO`: **\**: Disable HELO operation. -- `HELO_HOSTNAME`: **\**: Custom hostname for HELO operation. -- `HOST`: **\**: SMTP mail host address and port (example: smtp.gitea.io:587). - - As per RFC 8314, if supported, Implicit TLS/SMTPS on port 465 is recommended, otherwise opportunistic TLS via STARTTLS on port 587 should be used. -- `IS_TLS_ENABLED` : **false** : Forcibly use TLS to connect even if not on a default SMTPS port. - - Note, if the port ends with `465` Implicit TLS/SMTPS/SMTP over TLS will be used despite this setting. - - Otherwise if `IS_TLS_ENABLED=false` and the server supports `STARTTLS` this will be used. Thus if `STARTTLS` is preferred you should set `IS_TLS_ENABLED=false`. -- `FROM`: **\**: Mail from address, RFC 5322. This can be just an email address, or - the "Name" \ format. -- `ENVELOPE_FROM`: **\**: Address set as the From address on the SMTP mail envelope. Set to `<>` to send an empty address. +- `PROTOCOL`: **\**: Mail server protocol. One of "smtp", "smtps", "smtp+startls", "smtp+unix", "sendmail", "dummy". _Before 1.18, this was inferred from a combination of `MAILER_TYPE` and `IS_TLS_ENABLED`._ + - SMTP family, if your provider does not explicitly say which protocol it uses but does provide a port, you can set SMTP_PORT instead and this will be inferred. + - **sendmail** Use the operating system's `sendmail` command instead of SMTP. This is common on Linux systems. + - **dummy** Send email messages to the log as a testing phase. + - Note that enabling sendmail will ignore all other `mailer` settings except `ENABLED`, `FROM`, `SUBJECT_PREFIX` and `SENDMAIL_PATH`. + - Enabling dummy will ignore all settings except `ENABLED`, `SUBJECT_PREFIX` and `FROM`. +- `SMTP_ADDR`: **\**: Mail server address. e.g. smtp.gmail.com. For smtp+unix, this should be a path to a unix socket instead. _Before 1.18, this was combined with `SMTP_PORT` under the name `HOST`._ +- `SMTP_PORT`: **\**: Mail server port. If no protocol is specified, it will be inferred by this setting. Common ports are listed below. _Before 1.18, this was combined with `SMTP_ADDR` under the name `HOST`._ + - 25: insecure SMTP + - 465: SMTP Secure + - 587: StartTLS +- `USE_CLIENT_CERT`: **false**: Use client certificate for TLS/SSL. +- `CLIENT_CERT_FILE`: **custom/mailer/cert.pem**: Client certificate file. +- `CLIENT_KEY_FILE`: **custom/mailer/key.pem**: Client key file. +- `FORCE_TRUST_SERVER_CERT`: **false**: If set to `true`, completely ignores server certificate validation errors. This option is unsafe. Consider adding the certificate to the system trust store instead. - `USER`: **\**: Username of mailing user (usually the sender's e-mail address). - `PASSWD`: **\**: Password of mailing user. Use \`your password\` for quoting if you use special characters in the password. - - Please note: authentication is only supported when the SMTP server communication is encrypted with TLS (this can be via `STARTTLS`) or `HOST=localhost`. See [Email Setup]({{< relref "doc/usage/email-setup.en-us.md" >}}) for more information. -- `SEND_AS_PLAIN_TEXT`: **false**: Send mails as plain text. -- `SKIP_VERIFY`: **false**: Whether or not to skip verification of certificates; `true` to disable verification. - - **Warning:** This option is unsafe. Consider adding the certificate to the system trust store instead. - - **Note:** Gitea only supports SMTP with STARTTLS. -- `USE_CERTIFICATE`: **false**: Use client certificate. -- `CERT_FILE`: **custom/mailer/cert.pem** -- `KEY_FILE`: **custom/mailer/key.pem** + - Please note: authentication is only supported when the SMTP server communication is encrypted with TLS (this can be via `STARTTLS`) or SMTP host is localhost. See [Email Setup]({{< relref "doc/usage/email-setup.en-us.md" >}}) for more information. +- `ENABLE_HELO`: **true**: Enable HELO operation. +- `HELO_HOSTNAME`: **(retrieved from system)**: HELO hostname. +- `FROM`: **\**: Mail from address, RFC 5322. This can be just an email address, or the "Name" \ format. +- `ENVELOPE_FROM`: **\**: Address set as the From address on the SMTP mail envelope. Set to `<>` to send an empty address. - `SUBJECT_PREFIX`: **\**: Prefix to be placed before e-mail subject lines. -- `MAILER_TYPE`: **smtp**: \[smtp, sendmail, dummy\] - - **smtp** Use SMTP to send mail - - **sendmail** Use the operating system's `sendmail` command instead of SMTP. - This is common on Linux systems. - - **dummy** Send email messages to the log as a testing phase. - - Note that enabling sendmail will ignore all other `mailer` settings except `ENABLED`, - `FROM`, `SUBJECT_PREFIX` and `SENDMAIL_PATH`. - - Enabling dummy will ignore all settings except `ENABLED`, `SUBJECT_PREFIX` and `FROM`. -- `SENDMAIL_PATH`: **sendmail**: The location of sendmail on the operating system (can be - command or full path). -- `SENDMAIL_ARGS`: **_empty_**: Specify any extra sendmail arguments. (NOTE: you should be aware that email addresses can look like options - if your `sendmail` command takes options you must set the option terminator `--`) +- `SENDMAIL_PATH`: **sendmail**: The location of sendmail on the operating system (can be command or full path). +- `SENDMAIL_ARGS`: **\**: Specify any extra sendmail arguments. (NOTE: you should be aware that email addresses can look like options - if your `sendmail` command takes options you must set the option terminator `--`) - `SENDMAIL_TIMEOUT`: **5m**: default timeout for sending email through sendmail - `SENDMAIL_CONVERT_CRLF`: **true**: Most versions of sendmail prefer LF line endings rather than CRLF line endings. Set this to false if your version of sendmail requires CRLF line endings. - `SEND_BUFFER_LEN`: **100**: Buffer length of mailing queue. **DEPRECATED** use `LENGTH` in `[queue.mailer]` +- `SEND_AS_PLAIN_TEXT`: **false**: Send mails only in plain text, without HTML alternative. ## Cache (`cache`) @@ -686,9 +683,9 @@ Define allowed algorithms and their minimum key length (use -1 to disable a type - `ADAPTER`: **memory**: Cache engine adapter, either `memory`, `redis`, `twoqueue` or `memcache`. (`twoqueue` represents a size limited LRU cache.) - `INTERVAL`: **60**: Garbage Collection interval (sec), for memory and twoqueue cache only. - `HOST`: **\**: Connection string for `redis` and `memcache`. For `twoqueue` sets configuration for the queue. - - Redis: `redis://:macaron@127.0.0.1:6379/0?pool_size=100&idle_timeout=180s` - - Memcache: `127.0.0.1:9090;127.0.0.1:9091` - - TwoQueue LRU cache: `{"size":50000,"recent_ratio":0.25,"ghost_ratio":0.5}` or `50000` representing the maximum number of objects stored in the cache. + - Redis: `redis://:macaron@127.0.0.1:6379/0?pool_size=100&idle_timeout=180s` + - Memcache: `127.0.0.1:9090;127.0.0.1:9091` + - TwoQueue LRU cache: `{"size":50000,"recent_ratio":0.25,"ghost_ratio":0.5}` or `50000` representing the maximum number of objects stored in the cache. - `ITEM_TTL`: **16h**: Time to keep items in cache if not used, Setting it to -1 disables caching. ## Cache - LastCommitCache settings (`cache.last_commit`) @@ -731,7 +728,6 @@ Define allowed algorithms and their minimum key length (use -1 to disable a type - image = default image will be used (which is set in `REPOSITORY_AVATAR_FALLBACK_IMAGE`) - `REPOSITORY_AVATAR_FALLBACK_IMAGE`: **/img/repo_default.png**: Image used as default repository avatar (if `REPOSITORY_AVATAR_FALLBACK` is set to image and none was uploaded) - ## Project (`project`) Default templates for project boards: @@ -766,11 +762,13 @@ Default templates for project boards: - `ENABLE_XORM_LOG`: **true**: Set whether to perform XORM logging. Please note SQL statement logging can be disabled by setting `LOG_SQL` to false in the `[database]` section. ### Router Log (`log`) + - `DISABLE_ROUTER_LOG`: **false**: Mute printing of the router log. - `ROUTER`: **console**: The mode or name of the log the router should log to. (If you set this to `,` it will log to default Gitea logger.) NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take effect. Configure each mode in per mode log subsections `\[log.modename.router\]`. ### Access Log (`log`) + - `ENABLE_ACCESS_LOG`: **false**: Creates an access.log in NCSA common log format, or as per the following template - `ACCESS`: **file**: Logging mode for the access logger, use a comma to separate values. Configure each mode in per mode log subsections `\[log.modename.access\]`. By default the file mode will log to `$ROOT_PATH/access.log`. (If you set this to `,` it will log to the default Gitea logger.) - `ACCESS_LOG_TEMPLATE`: **`{{.Ctx.RemoteAddr}} - {{.Identity}} {{.Start.Format "[02/Jan/2006:15:04:05 -0700]" }} "{{.Ctx.Req.Method}} {{.Ctx.Req.URL.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.Referer}}\" \"{{.Ctx.Req.UserAgent}}"`**: Sets the template used to create the access log. @@ -828,9 +826,9 @@ Default templates for project boards: - `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices. - `SCHEDULE` accept formats - - Full crontab specs, e.g. `* * * * * ?` - - Descriptors, e.g. `@midnight`, `@every 1h30m` ... - - See more: [cron decument](https://pkg.go.dev/github.com/gogs/cron@v0.0.0-20171120032916-9f6c956d3e14) + - Full crontab specs, e.g. `* * * * * ?` + - Descriptors, e.g. `@midnight`, `@every 1h30m` ... + - See more: [cron decument](https://pkg.go.dev/github.com/gogs/cron@v0.0.0-20171120032916-9f6c956d3e14) ### Basic cron tasks - enabled by default @@ -887,6 +885,7 @@ Default templates for project boards: ### Extended cron tasks (not enabled by default) #### Cron - Garbage collect all repositories ('cron.git_gc_repos') + - `ENABLED`: **false**: Enable service. - `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED). - `SCHEDULE`: **@every 72h**: Cron syntax for scheduling repository archive cleanup, e.g. `@every 1h`. @@ -895,36 +894,42 @@ Default templates for project boards: - `ARGS`: **\**: Arguments for command `git gc`, e.g. `--aggressive --auto`. The default value is same with [git] -> GC_ARGS #### Cron - Update the '.ssh/authorized_keys' file with Gitea SSH keys ('cron.resync_all_sshkeys') + - `ENABLED`: **false**: Enable service. - `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED). - `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices. - `SCHEDULE`: **@every 72h**: Cron syntax for scheduling repository archive cleanup, e.g. `@every 1h`. #### Cron - Resynchronize pre-receive, update and post-receive hooks of all repositories ('cron.resync_all_hooks') + - `ENABLED`: **false**: Enable service. - `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED). - `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices. - `SCHEDULE`: **@every 72h**: Cron syntax for scheduling repository archive cleanup, e.g. `@every 1h`. #### Cron - Reinitialize all missing Git repositories for which records exist ('cron.reinit_missing_repos') + - `ENABLED`: **false**: Enable service. - `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED). - `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices. - `SCHEDULE`: **@every 72h**: Cron syntax for scheduling repository archive cleanup, e.g. `@every 1h`. #### Cron - Delete all repositories missing their Git files ('cron.delete_missing_repos') + - `ENABLED`: **false**: Enable service. - `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED). - `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices. - `SCHEDULE`: **@every 72h**: Cron syntax for scheduling repository archive cleanup, e.g. `@every 1h`. #### Cron - Delete generated repository avatars ('cron.delete_generated_repository_avatars') + - `ENABLED`: **false**: Enable service. - `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED). - `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices. - `SCHEDULE`: **@every 72h**: Cron syntax for scheduling repository archive cleanup, e.g. `@every 1h`. #### Cron - Delete all old actions from database ('cron.delete_old_actions') + - `ENABLED`: **false**: Enable service. - `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED). - `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices. @@ -932,6 +937,7 @@ Default templates for project boards: - `OLDER_THAN`: **@every 8760h**: any action older than this expression will be deleted from database, suggest using `8760h` (1 year) because that's the max length of heatmap. #### Cron - Check for new Gitea versions ('cron.update_checker') + - `ENABLED`: **false**: Enable service. - `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED). - `ENABLE_SUCCESS_NOTICE`: **true**: Set to false to switch off success notices. @@ -939,6 +945,7 @@ Default templates for project boards: - `HTTP_ENDPOINT`: **https://dl.gitea.io/gitea/version.json**: the endpoint that Gitea will check for newer versions #### Cron - Delete all old system notices from database ('cron.delete_old_system_notices') + - `ENABLED`: **false**: Enable service. - `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED). - `NO_SUCCESS_NOTICE`: **false**: Set to true to switch off success notices. @@ -949,7 +956,7 @@ Default templates for project boards: - `PATH`: **""**: The path of Git executable. If empty, Gitea searches through the PATH environment. - `HOME_PATH`: **%(APP_DATA_PATH)/home**: The HOME directory for Git. - This directory will be used to contain the `.gitconfig` and possible `.gnupg` directories that Gitea's git calls will use. If you can confirm Gitea is the only application running in this environment, you can set it to the normal home directory for Gitea user. + This directory will be used to contain the `.gitconfig` and possible `.gnupg` directories that Gitea's git calls will use. If you can confirm Gitea is the only application running in this environment, you can set it to the normal home directory for Gitea user. - `DISABLE_DIFF_HIGHLIGHT`: **false**: Disables highlight of added and removed changes. - `MAX_GIT_DIFF_LINES`: **1000**: Max number of lines allowed of a single file in diff view. - `MAX_GIT_DIFF_LINE_CHARACTERS`: **5000**: Max character count per line highlighted in diff view. @@ -957,7 +964,8 @@ Default templates for project boards: - `COMMITS_RANGE_SIZE`: **50**: Set the default commits range size - `BRANCHES_RANGE_SIZE`: **20**: Set the default branches range size - `GC_ARGS`: **\**: Arguments for command `git gc`, e.g. `--aggressive --auto`. See more on http://git-scm.com/docs/git-gc/ -- `ENABLE_AUTO_GIT_WIRE_PROTOCOL`: **true**: If use Git wire protocol version 2 when Git version >= 2.18, default is true, set to false when you always want Git wire protocol version 1 +- `ENABLE_AUTO_GIT_WIRE_PROTOCOL`: **true**: If use Git wire protocol version 2 when Git version >= 2.18, default is true, set to false when you always want Git wire protocol version 1. + To enable this for Git over SSH when using a OpenSSH server, add `AcceptEnv GIT_PROTOCOL` to your sshd_config file. - `PULL_REQUEST_PUSH_MESSAGE`: **true**: Respond to pushes to a non-default branch with a URL for creating a Pull Request (if the repository has them enabled) - `VERBOSE_PUSH`: **true**: Print status information about pushes as they are being processed. - `VERBOSE_PUSH_DELAY`: **5s**: Only print verbose information if push takes longer than this delay. @@ -966,6 +974,7 @@ Default templates for project boards: - `DISABLE_PARTIAL_CLONE`: **false** Disable the usage of using partial clones for git. ## Git - Timeout settings (`git.timeout`) + - `DEFAUlT`: **360**: Git operations default timeout seconds. - `MIGRATE`: **600**: Migrate external repositories timeout seconds. - `MIRROR`: **300**: Mirror external repositories timeout seconds. @@ -1032,6 +1041,7 @@ IS_INPUT_FILE = false - iframe: Render the content in a separate standalone page and embed it into current page by iframe. The iframe is in sandbox mode with same-origin disabled, and the JS code are safely isolated from parent page. Two special environment variables are passed to the render command: + - `GITEA_PREFIX_SRC`, which contains the current URL prefix in the `src` path tree. To be used as prefix for links. - `GITEA_PREFIX_RAW`, which contains the current URL prefix in the `raw` path tree. To be used as prefix for image paths. @@ -1047,10 +1057,10 @@ REGEXP = ^\s*((math(\s+|$)|inline(\s+|$)|display(\s+|$)))+ ALLOW_DATA_URI_IMAGES = true ``` - - `ELEMENT`: The element this policy applies to. Must be non-empty. - - `ALLOW_ATTR`: The attribute this policy allows. Must be non-empty. - - `REGEXP`: A regex to match the contents of the attribute against. Must be present but may be empty for unconditional whitelisting of this attribute. - - `ALLOW_DATA_URI_IMAGES`: **false** Allow data uri images (``). +- `ELEMENT`: The element this policy applies to. Must be non-empty. +- `ALLOW_ATTR`: The attribute this policy allows. Must be non-empty. +- `REGEXP`: A regex to match the contents of the attribute against. Must be present but may be empty for unconditional whitelisting of this attribute. +- `ALLOW_DATA_URI_IMAGES`: **false** Allow data uri images (``). Multiple sanitisation rules can be defined by adding unique subsections, e.g. `[markup.sanitizer.TeX-2]`. To apply a sanitisation rules only for a specify external renderer they must use the renderer name, e.g. `[markup.sanitizer.asciidoc.rule-1]`. @@ -1186,6 +1196,7 @@ is `data/repo-archive` and the default of `MINIO_BASE_PATH` is `repo-archive/`. - `PROXY_HOSTS`: **\**: Comma separated list of host names requiring proxy. Glob patterns (*) are accepted; use ** to match all hosts. i.e. + ```ini PROXY_ENABLED = true PROXY_URL = socks://127.0.0.1:1080 diff --git a/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md b/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md index 33c693083d02f..c2dff2aeca371 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md +++ b/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md @@ -173,8 +173,8 @@ menu: - `ADAPTER`: **memory**: 缓存引擎,可以为 `memory`, `redis` 或 `memcache`。 - `INTERVAL`: **60**: 只对内存缓存有效,GC间隔,单位秒。 - `HOST`: **\**: 针对redis和memcache有效,主机地址和端口。 - - Redis: `network=tcp,addr=127.0.0.1:6379,password=macaron,db=0,pool_size=100,idle_timeout=180` - - Memache: `127.0.0.1:9090;127.0.0.1:9091` + - Redis: `network=tcp,addr=127.0.0.1:6379,password=macaron,db=0,pool_size=100,idle_timeout=180` + - Memache: `127.0.0.1:9090;127.0.0.1:9091` - `ITEM_TTL`: **16h**: 缓存项目失效时间,设置为 -1 则禁用缓存。 ## Cache - LastCommitCache settings (`cache.last_commit`) @@ -239,7 +239,6 @@ file -I test01.xls test01.xls: application/vnd.ms-excel; charset=binary ``` - ## Log (`log`) - `ROOT_PATH`: 日志文件根目录。 @@ -251,10 +250,9 @@ test01.xls: application/vnd.ms-excel; charset=binary - `ENABLED`: 是否在后台运行定期任务。 - `RUN_AT_START`: 是否启动时自动运行。 - `SCHEDULE` 所接受的格式 - - 完整 crontab 控制, 例如 `* * * * * ?` - - 描述符, 例如 `@midnight`, `@every 1h30m` ... - - 更多细节参见 [cron api文档](https://pkg.go.dev/github.com/gogs/cron@v0.0.0-20171120032916-9f6c956d3e14) - + - 完整 crontab 控制, 例如 `* * * * * ?` + - 描述符, 例如 `@midnight`, `@every 1h30m` ... + - 更多细节参见 [cron api文档](https://pkg.go.dev/github.com/gogs/cron@v0.0.0-20171120032916-9f6c956d3e14) ### Cron - Update Mirrors (`cron.update_mirrors`) @@ -440,6 +438,7 @@ Repository archive 的存储配置。 如果 `STORAGE_TYPE` 为空,则此配 - `PROXY_HOSTS`: **\**: 逗号分隔的多个需要代理的网址,支持 * 号匹配符号, ** 表示匹配所有网站 i.e. + ```ini PROXY_ENABLED = true PROXY_URL = socks://127.0.0.1:1080 diff --git a/docs/content/doc/advanced/customizing-gitea.en-us.md b/docs/content/doc/advanced/customizing-gitea.en-us.md index 8f23fc33462c1..038ce16a8dde8 100644 --- a/docs/content/doc/advanced/customizing-gitea.en-us.md +++ b/docs/content/doc/advanced/customizing-gitea.en-us.md @@ -149,13 +149,13 @@ copy javascript files from https://gitea.com/davidsvantesson/plantuml-code-highl You can then add blocks like the following to your markdown: - ```plantuml - Alice -> Bob: Authentication Request - Bob --> Alice: Authentication Response +```plantuml +Alice -> Bob: Authentication Request +Bob --> Alice: Authentication Response - Alice -> Bob: Another authentication Request - Alice <-- Bob: Another authentication Response - ``` +Alice -> Bob: Another authentication Request +Alice <-- Bob: Another authentication Response +``` The script will detect tags with `class="language-plantuml"`, but you can change this by providing a second argument to `parsePlantumlCodeBlocks`. diff --git a/docs/content/doc/advanced/environment-variables.zh-cn.md b/docs/content/doc/advanced/environment-variables.zh-cn.md index 63ee4c69357f0..3de8dcfbc7418 100644 --- a/docs/content/doc/advanced/environment-variables.zh-cn.md +++ b/docs/content/doc/advanced/environment-variables.zh-cn.md @@ -25,31 +25,31 @@ GITEA_CUSTOM=/home/gitea/custom ./gitea web 因为 Gitea 使用 Go 语言编写,因此它使用了一些相关的 Go 的配置参数: - * `GOOS` - * `GOARCH` - * [`GOPATH`](https://golang.org/cmd/go/#hdr-GOPATH_environment_variable) +* `GOOS` +* `GOARCH` +* [`GOPATH`](https://golang.org/cmd/go/#hdr-GOPATH_environment_variable) 您可以在[官方文档](https://golang.org/cmd/go/#hdr-Environment_variables)中查阅这些配置参数的详细信息。 ## Gitea 的文件目录 - * `GITEA_WORK_DIR`:工作目录的绝对路径 - * `GITEA_CUSTOM`:默认情况下 Gitea 使用默认目录 `GITEA_WORK_DIR`/custom,您可以使用这个参数来配置 *custom* 目录 - * `GOGS_WORK_DIR`: 已废弃,请使用 `GITEA_WORK_DIR` 替代 - * `GOGS_CUSTOM`: 已废弃,请使用 `GITEA_CUSTOM` 替代 +* `GITEA_WORK_DIR`:工作目录的绝对路径 +* `GITEA_CUSTOM`:默认情况下 Gitea 使用默认目录 `GITEA_WORK_DIR`/custom,您可以使用这个参数来配置 *custom* 目录 +* `GOGS_WORK_DIR`: 已废弃,请使用 `GITEA_WORK_DIR` 替代 +* `GOGS_CUSTOM`: 已废弃,请使用 `GITEA_CUSTOM` 替代 ## 操作系统配置 - * `USER`:Gitea 运行时使用的系统用户,它将作为一些 repository 的访问地址的一部分 - * `USERNAME`: 如果没有配置 `USER`, Gitea 将使用 `USERNAME` - * `HOME`: 用户的 home 目录,在 Windows 中会使用 `USERPROFILE` 环境变量 +* `USER`:Gitea 运行时使用的系统用户,它将作为一些 repository 的访问地址的一部分 +* `USERNAME`: 如果没有配置 `USER`, Gitea 将使用 `USERNAME` +* `HOME`: 用户的 home 目录,在 Windows 中会使用 `USERPROFILE` 环境变量 ### 仅限于 Windows 的配置 - * `USERPROFILE`: 用户的主目录,如果未配置则会使用 `HOMEDRIVE` + `HOMEPATH` - * `HOMEDRIVE`: 用于访问 home 目录的主驱动器路径(C盘) - * `HOMEPATH`:在指定主驱动器下的 home 目录相对路径 +* `USERPROFILE`: 用户的主目录,如果未配置则会使用 `HOMEDRIVE` + `HOMEPATH` +* `HOMEDRIVE`: 用于访问 home 目录的主驱动器路径(C盘) +* `HOMEPATH`:在指定主驱动器下的 home 目录相对路径 ## Miscellaneous - * `SKIP_MINWINSVC`:如果设置为 1,在 Windows 上不会以 service 的形式运行。 +* `SKIP_MINWINSVC`:如果设置为 1,在 Windows 上不会以 service 的形式运行。 diff --git a/docs/content/doc/advanced/external-renderers.en-us.md b/docs/content/doc/advanced/external-renderers.en-us.md index 34329408a1d5b..4e5e72554d9d3 100644 --- a/docs/content/doc/advanced/external-renderers.en-us.md +++ b/docs/content/doc/advanced/external-renderers.en-us.md @@ -127,6 +127,7 @@ ALLOW_ATTR = class ### Example: Office DOCX Display Office DOCX files with [`pandoc`](https://pandoc.org/): + ```ini [markup.docx] ENABLED = true @@ -138,6 +139,7 @@ ALLOW_DATA_URI_IMAGES = true ``` The template file has the following content: + ``` $body$ ``` @@ -145,6 +147,7 @@ $body$ ### Example: Jupyter Notebook Display Jupyter Notebook files with [`nbconvert`](https://github.com/jupyter/nbconvert): + ```ini [markup.jupyter] ENABLED = true @@ -156,9 +159,11 @@ ALLOW_DATA_URI_IMAGES = true ``` ## Customizing CSS -The external renderer is specified in the .ini in the format `[markup.XXXXX]` and the HTML supplied by your external renderer will be wrapped in a `
` with classes `markup` and `XXXXX`. The `markup` class provides out of the box styling (as does `markdown` if `XXXXX` is `markdown`). Otherwise you can use these classes to specifically target the contents of your rendered HTML. + +The external renderer is specified in the .ini in the format `[markup.XXXXX]` and the HTML supplied by your external renderer will be wrapped in a `
` with classes `markup` and `XXXXX`. The `markup` class provides out of the box styling (as does `markdown` if `XXXXX` is `markdown`). Otherwise you can use these classes to specifically target the contents of your rendered HTML. And so you could write some CSS: + ```css .markup.XXXXX html { font-size: 100%; @@ -184,6 +189,7 @@ And so you could write some CSS: ``` Add your stylesheet to your custom directory e.g `custom/public/css/my-style-XXXXX.css` and import it using a custom header file `custom/templates/custom/header.tmpl`: + ```html ``` diff --git a/docs/content/doc/advanced/mail-templates-us.md b/docs/content/doc/advanced/mail-templates-us.md index e73bb01e299db..bd419a617b856 100644 --- a/docs/content/doc/advanced/mail-templates-us.md +++ b/docs/content/doc/advanced/mail-templates-us.md @@ -251,7 +251,7 @@ This template produces something along these lines: > > \_********************************\_******************************** > -> Mike, I think we should tone down the blues a little. +> Mike, I think we should tone down the blues a little. > \_********************************\_******************************** > > [View it on Gitea](#). diff --git a/docs/content/doc/advanced/protected-tags.en-us.md b/docs/content/doc/advanced/protected-tags.en-us.md index 0ddbedd9a14db..8ed2afc418320 100644 --- a/docs/content/doc/advanced/protected-tags.en-us.md +++ b/docs/content/doc/advanced/protected-tags.en-us.md @@ -15,7 +15,7 @@ menu: # Protected tags -Protected tags allow control over who has permission to create or update Git tags. Each rule allows you to match either an individual tag name, or use an appropriate pattern to control multiple tags at once. +Protected tags allow control over who has permission to create or update Git tags. Each rule allows you to match either an individual tag name, or use an appropriate pattern to control multiple tags at once. **Table of Contents** diff --git a/docs/content/doc/advanced/repo-mirror.en-us.md b/docs/content/doc/advanced/repo-mirror.en-us.md index bda5b0fa5594c..c1d794762a170 100644 --- a/docs/content/doc/advanced/repo-mirror.en-us.md +++ b/docs/content/doc/advanced/repo-mirror.en-us.md @@ -37,7 +37,7 @@ For an existing remote repository, you can set up pull mirroring as follows: 3. Enter a repository URL. 4. If the repository needs authentication fill in your authentication information. 5. Check the box **This repository will be a mirror**. -5. Select **Migrate repository** to save the configuration. +6. Select **Migrate repository** to save the configuration. The repository now gets mirrored periodically from the remote repository. You can force a sync by selecting **Synchronize Now** in the repository settings. diff --git a/docs/content/doc/advanced/search-engines-indexation.en-us.md b/docs/content/doc/advanced/search-engines-indexation.en-us.md index 5d5e4dab5a2bf..ec367b74deac9 100644 --- a/docs/content/doc/advanced/search-engines-indexation.en-us.md +++ b/docs/content/doc/advanced/search-engines-indexation.en-us.md @@ -25,7 +25,6 @@ create a file called `robots.txt` in the [`custom` folder or `CustomPath`]({{< r Examples on how to configure the `robots.txt` can be found at [https://moz.com/learn/seo/robotstxt](https://moz.com/learn/seo/robotstxt). - ```txt User-agent: * Disallow: / diff --git a/docs/content/doc/advanced/third-party-tools.zh-cn.md b/docs/content/doc/advanced/third-party-tools.zh-cn.md index d25bc400e46c5..e961e9ec1fa19 100644 --- a/docs/content/doc/advanced/third-party-tools.zh-cn.md +++ b/docs/content/doc/advanced/third-party-tools.zh-cn.md @@ -14,23 +14,26 @@ menu: --- # 第三方工具列表 + **注意:** 这些工具并没有经过Gitea的检验,在这里列出它们只是为了便捷. *此列表并不是完整的列表,可以随时咨询如何添加!* ### 持续集成 -[BuildKite 连接器](https://github.com/techknowlogick/gitea-buildkite-connector) -[Jenkins 插件](https://github.com/jenkinsci/gitea-plugin) -[Gitea搭配Drone](https://docs.drone.io/installation/gitea) +[BuildKite 连接器](https://github.com/techknowlogick/gitea-buildkite-connector) +[Jenkins 插件](https://github.com/jenkinsci/gitea-plugin) +[Gitea搭配Drone](https://docs.drone.io/installation/gitea) ### 迁移 -[Gitea安装脚本](https://git.coolaj86.com/coolaj86/gitea-installer.sh) -[GitHub迁移](https://gitea.com/gitea/migrator) +[Gitea安装脚本](https://git.coolaj86.com/coolaj86/gitea-installer.sh) +[GitHub迁移](https://gitea.com/gitea/migrator) ### 移动端 + [安卓客户端GitNex](https://gitlab.com/mmarif4u/gitnex) -### 编辑器扩展 - - [Gitea的Visual Studio扩展](https://github.com/maikebing/Gitea.VisualStudio) 从 [Visual Studio 扩展市场](https://marketplace.visualstudio.com/items?itemName=MysticBoy.GiteaExtensionforVisualStudio) 下载 +### 编辑器扩展 + +- [Gitea的Visual Studio扩展](https://github.com/maikebing/Gitea.VisualStudio) 从 [Visual Studio 扩展市场](https://marketplace.visualstudio.com/items?itemName=MysticBoy.GiteaExtensionforVisualStudio) 下载 diff --git a/docs/content/doc/developers/api-usage.en-us.md b/docs/content/doc/developers/api-usage.en-us.md index 57702a6ee8554..dd2822e9f1361 100644 --- a/docs/content/doc/developers/api-usage.en-us.md +++ b/docs/content/doc/developers/api-usage.en-us.md @@ -48,7 +48,6 @@ A new token can be generated with a `POST` request to Note that `/users/:name/tokens` is a special endpoint and requires you to authenticate using `BasicAuth` and a password, as follows: - ```sh $ curl -XPOST -H "Content-Type: application/json" -k -d '{"name":"test"}' -u username:password https://gitea.your.host/api/v1/users//tokens {"id":1,"name":"test","sha1":"9fcb1158165773dd010fca5f0cf7174316c3e37d","token_last_eight":"16c3e37d"} diff --git a/docs/content/doc/developers/guidelines-backend.md b/docs/content/doc/developers/guidelines-backend.md index 1248d4143233f..4280aa80fbd0c 100644 --- a/docs/content/doc/developers/guidelines-backend.md +++ b/docs/content/doc/developers/guidelines-backend.md @@ -21,8 +21,8 @@ menu: ## Background -Gitea uses Golang as the backend programming language. It uses many third-party packages and also write some itself. -For example, Gitea uses [Chi](https://github.com/go-chi/chi) as basic web framework. [Xorm](https://xorm.io) is an ORM framework that is used to interact with the database. +Gitea uses Golang as the backend programming language. It uses many third-party packages and also write some itself. +For example, Gitea uses [Chi](https://github.com/go-chi/chi) as basic web framework. [Xorm](https://xorm.io) is an ORM framework that is used to interact with the database. So it's very important to manage these packages. Please take the below guidelines before you start to write backend code. ## Package Design Guideline @@ -43,9 +43,9 @@ To maintain understandable code and avoid circular dependencies it is important - `modules/git`: Package to interactive with `Git` command line or Gogit package. - `public`: Compiled frontend files (javascript, images, css, etc.) - `routers`: Handling of server requests. As it uses other Gitea packages to serve the request, other packages (models, modules or services) must not depend on routers. - - `routers/api` Contains routers for `/api/v1` aims to handle RESTful API requests. - - `routers/install` Could only respond when system is in INSTALL mode (INSTALL_LOCK=false). - - `routers/private` will only be invoked by internal sub commands, especially `serv` and `hooks`. + - `routers/api` Contains routers for `/api/v1` aims to handle RESTful API requests. + - `routers/install` Could only respond when system is in INSTALL mode (INSTALL_LOCK=false). + - `routers/private` will only be invoked by internal sub commands, especially `serv` and `hooks`. - `routers/web` will handle HTTP requests from web browsers or Git SMART HTTP protocols. - `services`: Support functions for common routing operations or command executions. Uses `models` and `modules` to handle the requests. - `templates`: Golang templates for generating the html output. @@ -61,7 +61,7 @@ From left to right, left packages could depend on right packages, but right pack **NOTICE** Why do we need database transactions outside of `models`? And how? -Some actions should allow for rollback when database record insertion/update/deletion failed. +Some actions should allow for rollback when database record insertion/update/deletion failed. So services must be allowed to create a database transaction. Here is some example, ```go @@ -84,7 +84,7 @@ func CreateXXXX() error {\ } ``` -You should **not** use `db.GetEngine(ctx)` in `services` directly, but just write a function under `models/`. +You should **not** use `db.GetEngine(ctx)` in `services` directly, but just write a function under `models/`. If the function will be used in the transaction, just let `context.Context` as the function's first parameter. ```go diff --git a/docs/content/doc/developers/guidelines-frontend.md b/docs/content/doc/developers/guidelines-frontend.md index 0fced64b14cb7..87272d023fd3d 100644 --- a/docs/content/doc/developers/guidelines-frontend.md +++ b/docs/content/doc/developers/guidelines-frontend.md @@ -26,6 +26,7 @@ Gitea uses [Less CSS](https://lesscss.org), [Fomantic-UI](https://fomantic-ui.co The HTML pages are rendered by [Go HTML Template](https://pkg.go.dev/html/template). The source files can be found in the following directories: + * **Less styles:** `web_src/less/` * **JavaScript files:** `web_src/js/` * **Vue components:** `web_src/js/components/` @@ -41,36 +42,37 @@ We recommend [Google HTML/CSS Style Guide](https://google.github.io/styleguide/h 2. HTML ids and classes should use kebab-case. 3. HTML ids and classes used in JavaScript should be unique for the whole project, and should contain 2-3 feature related keywords. We recommend to use the `js-` prefix for classes that are only used in JavaScript. 4. jQuery events across different features could use their own namespaces if there are potential conflicts. -5. CSS styling for classes provided by frameworks should not be overwritten. Always use new class-names with 2-3 feature related keywords to overwrite framework styles. +5. CSS styling for classes provided by frameworks should not be overwritten. Always use new class-names with 2-3 feature related keywords to overwrite framework styles. 6. The backend can pass complex data to the frontend by using `ctx.PageData["myModuleData"] = map[]{}` 7. Simple pages and SEO-related pages use Go HTML Template render to generate static Fomantic-UI HTML output. Complex pages can use Vue2 (or Vue3 in future). - ### Framework Usage Mixing different frameworks together is discouraged, it makes the code difficult to be maintained. A JavaScript module should follow one major framework and follow the framework's best practice. Recommended implementations: + * Vue + Vanilla JS * Fomantic-UI (jQuery) * Vanilla JS Discouraged implementations: + * Vue + Fomantic-UI (jQuery) * jQuery + Vanilla JS To make UI consistent, Vue components can use Fomantic-UI CSS classes. -Although mixing different frameworks is discouraged, -it should also work if the mixing is necessary and the code is well-designed and maintainable. +Although mixing different frameworks is discouraged, +it should also work if the mixing is necessary and the code is well-designed and maintainable. ### `async` Functions -Only mark a function as `async` if and only if there are `await` calls +Only mark a function as `async` if and only if there are `await` calls or `Promise` returns inside the function. It's not recommended to use `async` event listeners, which may lead to problems. -The reason is that the code after await is executed outside the event dispatch. +The reason is that the code after await is executed outside the event dispatch. Reference: https://github.com/github/eslint-plugin-github/blob/main/docs/rules/async-preventdefault.md If we want to call an `async` function in a non-async context, @@ -88,10 +90,9 @@ However, there are still some special cases, so the current guideline is: * `$.data()` can be used to bind some non-string data to elements in rare cases, but it is highly discouraged. * For new code: - * `node.dataset` should not be used, use `node.getAttribute` instead. + * `node.dataset` should not be used, use `node.getAttribute` instead. * never bind any user data to a DOM node, use a suitable design pattern to describe the relation between node and data. - ### Legacy Code A lot of legacy code already existed before this document's written. It's recommended to refactor legacy code to follow the guidelines. diff --git a/docs/content/doc/developers/hacking-on-gitea.en-us.md b/docs/content/doc/developers/hacking-on-gitea.en-us.md index 9d15f66dace10..abefb1ca96b38 100644 --- a/docs/content/doc/developers/hacking-on-gitea.en-us.md +++ b/docs/content/doc/developers/hacking-on-gitea.en-us.md @@ -35,7 +35,7 @@ on the executable path. If you don't add the go bin directory to the executable path you will have to manage this yourself. **Note 2**: Go version {{< min-go-version >}} or higher is required. -Gitea uses `gofmt` to format source code. However, the results of +Gitea uses `gofmt` to format source code. However, the results of `gofmt` can differ by the version of `go`. Therefore it is recommended to install the version of Go that our continuous integration is running. As of last update, the Go version should be {{< go-version >}}. @@ -69,7 +69,7 @@ One of these three distributions of Make will run on Windows: - [32-bits version](http://www.equation.com/ftpdir/make/32/make.exe) - [64-bits version](http://www.equation.com/ftpdir/make/64/make.exe) - [MinGW-w64](https://www.mingw-w64.org) / [MSYS2](https://www.msys2.org/). - - MSYS2 is a collection of tools and libraries providing you with an easy-to-use environment for building, installing and running native Windows software, it includes MinGW-w64. + - MSYS2 is a collection of tools and libraries providing you with an easy-to-use environment for building, installing and running native Windows software, it includes MinGW-w64. - In MingGW-w64, the binary is called `mingw32-make.exe` instead of `make.exe`. Add the `bin` folder to `PATH`. - In MSYS2, you can use `make` directly. See [MSYS2 Porting](https://www.msys2.org/wiki/Porting/). - To compile Gitea with CGO_ENABLED (eg: SQLite3), you might need to use [tdm-gcc](https://jmeubank.github.io/tdm-gcc/) instead of MSYS2 gcc, because MSYS2 gcc headers lack some Windows-only CRT functions like `_beginthread`. @@ -212,7 +212,7 @@ SVG icons are built using the `make svg` target which compiles the icon sources ### Building the Logo -The PNG and SVG versions of the Gitea logo are built from a single SVG source file `assets/logo.svg` using the `TAGS="gitea" make generate-images` target. To run it, Node.js and npm must be available. +The PNG and SVG versions of the Gitea logo are built from a single SVG source file `assets/logo.svg` using the `TAGS="gitea" make generate-images` target. To run it, Node.js and npm must be available. The same process can also be used to generate custom logo PNGs from a SVG source file by updating `assets/logo.svg` and running `make generate-images`. Omitting the `gitea` tag will update only the user-designated logo files. @@ -312,7 +312,6 @@ may need adjustment to the local environment. Take a look at [`integrations/README.md`](https://github.com/go-gitea/gitea/blob/main/integrations/README.md) for more information and how to run a single test. - ### Testing for a PR Our continuous integration will test the code passes its unit tests and that @@ -345,13 +344,13 @@ for more information. ## GoLand -Clicking the `Run Application` arrow on the function `func main()` in `/main.go` +Clicking the `Run Application` arrow on the function `func main()` in `/main.go` can quickly start a debuggable Gitea instance. -The `Output Directory` in `Run/Debug Configuration` MUST be set to the -gitea project directory (which contains `main.go` and `go.mod`), -otherwise, the started instance's working directory is a GoLand's temporary directory -and prevents Gitea from loading dynamic resources (eg: templates) in a development environment. +The `Output Directory` in `Run/Debug Configuration` MUST be set to the +gitea project directory (which contains `main.go` and `go.mod`), +otherwise, the started instance's working directory is a GoLand's temporary directory +and prevents Gitea from loading dynamic resources (eg: templates) in a development environment. To run unit tests with SQLite in GoLand, set `-tags sqlite,sqlite_unlock_notify` in `Go tool arguments` of `Run/Debug Configuration`. diff --git a/docs/content/doc/developers/migrations.en-us.md b/docs/content/doc/developers/migrations.en-us.md index b749f4f604fd0..168af1f7fa00a 100644 --- a/docs/content/doc/developers/migrations.en-us.md +++ b/docs/content/doc/developers/migrations.en-us.md @@ -16,11 +16,11 @@ menu: # Migration Features Complete migrations were introduced in Gitea 1.9.0. It defines two interfaces to support migrating -repository data from other Git host platforms to Gitea or, in the future, migrating Gitea data to other -Git host platforms. +repository data from other Git host platforms to Gitea or, in the future, migrating Gitea data to other Git host platforms. + Currently, migrations from GitHub, GitLab, and other Gitea instances are implemented. -First of all, Gitea defines some standard objects in packages [modules/migration](https://github.com/go-gitea/gitea/tree/main/modules/migration). +First of all, Gitea defines some standard objects in packages [modules/migration](https://github.com/go-gitea/gitea/tree/main/modules/migration). They are `Repository`, `Milestone`, `Release`, `ReleaseAsset`, `Label`, `Issue`, `Comment`, `PullRequest`, `Reaction`, `Review`, `ReviewComment`. ## Downloader Interfaces @@ -29,7 +29,7 @@ To migrate from a new Git host platform, there are two steps to be updated. - You should implement a `Downloader` which will be used to get repository information. - You should implement a `DownloaderFactory` which will be used to detect if the URL matches and create the above `Downloader`. - - You'll need to register the `DownloaderFactory` via `RegisterDownloaderFactory` on `init()`. + - You'll need to register the `DownloaderFactory` via `RegisterDownloaderFactory` on `init()`. You can find these interfaces in [downloader.go](https://github.com/go-gitea/gitea/blob/main/modules/migration/downloader.go). diff --git a/docs/content/doc/developers/migrations.zh-tw.md b/docs/content/doc/developers/migrations.zh-tw.md index 0d892cae91152..173c01a464cd7 100644 --- a/docs/content/doc/developers/migrations.zh-tw.md +++ b/docs/content/doc/developers/migrations.zh-tw.md @@ -18,7 +18,7 @@ menu: 完整的遷移從 Gitea 1.9.0 開始提供。它定義了兩個介面用來從其它 Git 託管平臺遷移儲存庫資料到 Gitea,未來或許會提供遷移到其它 git 託管平臺。 目前已實作了從 Github, Gitlab 和其它 Gitea 遷移資料。 -Gitea 定義了一些基本物件於套件 [modules/migration](https://github.com/go-gitea/gitea/tree/master/modules/migration)。 +Gitea 定義了一些基本物件於套件 [modules/migration](https://github.com/go-gitea/gitea/tree/master/modules/migration)。 分別是 `Repository`, `Milestone`, `Release`, `ReleaseAsset`, `Label`, `Issue`, `Comment`, `PullRequest`, `Reaction`, `Review`, `ReviewComment`。 ## Downloader 介面 diff --git a/docs/content/doc/developers/oauth2-provider.md b/docs/content/doc/developers/oauth2-provider.md index ce6e9aad8cbe5..9e6ab11742fb5 100644 --- a/docs/content/doc/developers/oauth2-provider.md +++ b/docs/content/doc/developers/oauth2-provider.md @@ -34,6 +34,7 @@ Gitea supports acting as an OAuth2 provider to allow third party applications to ## Supported OAuth2 Grants At the moment Gitea only supports the [**Authorization Code Grant**](https://tools.ietf.org/html/rfc6749#section-1.3.1) standard with additional support of the following extensions: + - [Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636) - [OpenID Connect (OIDC)](https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth) diff --git a/docs/content/doc/features/authentication.en-us.md b/docs/content/doc/features/authentication.en-us.md index 4b02679388a36..7d555d1dcc4b0 100644 --- a/docs/content/doc/features/authentication.en-us.md +++ b/docs/content/doc/features/authentication.en-us.md @@ -203,7 +203,7 @@ configure this, set the fields below: - Force SMTPS - - SMTPS will be used by default for connections to port 465, if you wish to use SMTPS + - SMTPS will be used by default for connections to port 465, if you wish to use SMTPS for other ports. Set this value. - Otherwise if the server provides the `STARTTLS` extension this will be used. diff --git a/docs/content/doc/features/comparison.zh-cn.md b/docs/content/doc/features/comparison.zh-cn.md index 98a50f5dc2abd..15ff4a6560841 100644 --- a/docs/content/doc/features/comparison.zh-cn.md +++ b/docs/content/doc/features/comparison.zh-cn.md @@ -46,7 +46,7 @@ _表格中的符号含义:_ | Git 驱动的集成化 wiki | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | | 部署令牌 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | 仓库写权限令牌 | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✓ | -| 内置容器 Registry | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ | +| 内置容器 Registry | ✓ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ | | 外部 Git 镜像 | ✓ | ✓ | ✘ | ✘ | ✓ | ✓ | ✓ | | WebAuthn (2FA) | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ? | | 内置 CI/CD | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ | @@ -62,7 +62,7 @@ _表格中的符号含义:_ | Git LFS 2.0 | ✓ | ✘ | ✓ | ✓ | ✓ | ⁄ | ✓ | | 组织里程碑 | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ | | 细粒度用户角色 (例如 Code, Issues, Wiki) | ✓ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ | -| 提交人的身份验证 | ✘ | ✘ | ? | ✓ | ✓ | ✓ | ✘ | +| 提交人的身份验证 | ⁄ | ✘ | ? | ✓ | ✓ | ✓ | ✘ | | GPG 签名的提交 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ | | SSH 签名的提交 | ✓ | ✘ | ✘ | ✘ | ✘ | ? | ? | | 拒绝未用通过验证的提交 | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✓ | @@ -71,6 +71,7 @@ _表格中的符号含义:_ | 建立新分支 | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ | | 在线代码编辑 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | 提交的统计图表 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ | +| 模板仓库 | ✓ | ✘ | ✓ | ✘ | ✓ | ✓ | ✘ | #### Issue 管理 @@ -84,9 +85,9 @@ _表格中的符号含义:_ | 关联的 issues | ✘ | ✘ | ⁄ | ✘ | ✓ | ✘ | ✘ | | 私密 issues | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ | | 评论反馈 | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ | -| 锁定讨论 | ✘ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ | +| 锁定讨论 | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ | | Issue 批量处理 | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ | -| Issue 看板 | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ | +| Issue 看板 | ✓ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ | | 从 issues 创建分支 | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ | | Issue 搜索 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ | | 全局 Issue 搜索 | ✘ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ | @@ -108,7 +109,7 @@ _表格中的符号含义:_ | 回退某些 commits 或 merge request | ✘ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ | | Pull/Merge requests 模板 | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ | | 查看 Cherry-picking 的更改 | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ | - +| 下载 Patch | ✓ | ✘ | ✓ | ✓ | ✓ | / | ✘ | #### 第三方集成 @@ -125,4 +126,5 @@ _表格中的符号含义:_ | 二次验证 (2FA) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | | 集成 Mattermost/Slack | ✓ | ✓ | ⁄ | ✓ | ✓ | ⁄ | ✓ | | 集成 Discord | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ | +| 集成 Microsoft Teams | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ | | 显示外部 CI/CD 的状态 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ | diff --git a/docs/content/doc/features/localization.en-us.md b/docs/content/doc/features/localization.en-us.md index a5b7a52f89891..e57233a62255c 100644 --- a/docs/content/doc/features/localization.en-us.md +++ b/docs/content/doc/features/localization.en-us.md @@ -26,6 +26,8 @@ For changes to a **non-English** translation, refer to the Crowdin project above Any language listed in the above Crowdin project will be supported as long as 25% or more has been translated. -After a translation has been accepted, it will be reflected in the main repository after the next Crowdin sync, which is generally after any PR is merged. -At the time of writing, this means that a changed translation may not appear until the following Gitea release. +After a translation has been accepted, it will be reflected in the main repository after the next Crowdin sync, which is generally after any PR is merged. + +At the time of writing, this means that a changed translation may not appear until the following Gitea release. + If you use a bleeding edge build, it should appear as soon as you update after the change is synced. diff --git a/docs/content/doc/features/localization.zh-tw.md b/docs/content/doc/features/localization.zh-tw.md index e1000636069ab..7bb3a6e6a2ddf 100644 --- a/docs/content/doc/features/localization.zh-tw.md +++ b/docs/content/doc/features/localization.zh-tw.md @@ -25,6 +25,8 @@ menu: 上述 Crowdin 專案中列出的語言在翻譯超過 25% 後將被支援。 -翻譯被認可後將在下次 Crowdin 同步後進入到主儲存庫,通常是在任何合併請求被合併之後。 -這表示更改的翻譯要到下次 Gitea 發佈後才會出現。 +翻譯被認可後將在下次 Crowdin 同步後進入到主儲存庫,通常是在任何合併請求被合併之後。 + +這表示更改的翻譯要到下次 Gitea 發佈後才會出現。 + 如果您使用的是最新建置,它將會在同步完成、您更新後出現。 diff --git a/docs/content/doc/help/faq.en-us.md b/docs/content/doc/help/faq.en-us.md index a64cccfa66f4c..17983da695389 100644 --- a/docs/content/doc/help/faq.en-us.md +++ b/docs/content/doc/help/faq.en-us.md @@ -15,7 +15,8 @@ menu: # Frequently Asked Questions -This page contains some common questions and answers. +This page contains some common questions and answers. + For more help resources, check all [Support Options]({{< relref "doc/help/seek-help.en-us.md" >}}). **Table of Contents** @@ -24,14 +25,18 @@ For more help resources, check all [Support Options]({{< relref "doc/help/seek-h ## Difference between 1.x and 1.x.x downloads -Version 1.7.x will be used for this example. +Version 1.7.x will be used for this example. + **NOTE:** this example applies to Docker images as well! -On our [downloads page](https://dl.gitea.io/gitea/) you will see a 1.7 directory, as well as directories for 1.7.0, 1.7.1, 1.7.2, 1.7.3, 1.7.4, 1.7.5, and 1.7.6. -The 1.7 and 1.7.0 directories are **not** the same. The 1.7 directory is built on each merged commit to the [`release/v1.7`](https://github.com/go-gitea/gitea/tree/release/v1.7) branch. +On our [downloads page](https://dl.gitea.io/gitea/) you will see a 1.7 directory, as well as directories for 1.7.0, 1.7.1, 1.7.2, 1.7.3, 1.7.4, 1.7.5, and 1.7.6. + +The 1.7 and 1.7.0 directories are **not** the same. The 1.7 directory is built on each merged commit to the [`release/v1.7`](https://github.com/go-gitea/gitea/tree/release/v1.7) branch. + The 1.7.0 directory, however, is a build that was created when the [`v1.7.0`](https://github.com/go-gitea/gitea/releases/tag/v1.7.0) tag was created. -This means that 1.x downloads will change as commits are merged to their respective branch (think of it as a separate "main" branch for each release). +This means that 1.x downloads will change as commits are merged to their respective branch (think of it as a separate "main" branch for each release). + On the other hand, 1.x.x downloads should never change. ## How to migrate from Gogs/GitHub/etc. to Gitea @@ -41,11 +46,14 @@ To migrate from Gogs to Gitea: - [Gogs version 0.9.146 or less]({{< relref "doc/upgrade/from-gogs.en-us.md" >}}) - [Gogs version 0.11.46.0418](https://github.com/go-gitea/gitea/issues/4286) -To migrate from GitHub to Gitea, you can use Gitea's built-in migration form. -In order to migrate items such as issues, pull requests, etc. you will need to input at least your username. +To migrate from GitHub to Gitea, you can use Gitea's built-in migration form. + +In order to migrate items such as issues, pull requests, etc. you will need to input at least your username. + [Example (requires login)](https://try.gitea.io/repo/migrate) -To migrate from GitLab to Gitea, you can use this non-affiliated tool: +To migrate from GitLab to Gitea, you can use this non-affiliated tool: + https://github.com/loganinak/MigrateGitlabToGogs ## Where does Gitea store what file @@ -83,9 +91,9 @@ There are a few places that could make this show incorrectly. If certain clone options aren't showing up (HTTP/S or SSH), the following options can be checked in your `app.ini` -`DISABLE_HTTP_GIT`: if set to true, there will be no HTTP/HTTPS link -`DISABLE_SSH`: if set to true, there will be no SSH link -`SSH_EXPOSE_ANONYMOUS`: if set to false, SSH links will be hidden for anonymous users +- `DISABLE_HTTP_GIT`: if set to true, there will be no HTTP/HTTPS link +- `DISABLE_SSH`: if set to true, there will be no SSH link +- `SSH_EXPOSE_ANONYMOUS`: if set to false, SSH links will be hidden for anonymous users ## File upload fails with: 413 Request Entity Too Large @@ -95,19 +103,21 @@ See the [reverse proxy guide]({{< relref "doc/usage/reverse-proxies.en-us.md" >} ## Custom Templates not loading or working incorrectly -Gitea's custom templates must be added to the correct location or Gitea will not find and use them. +Gitea's custom templates must be added to the correct location or Gitea will not find and use them. + The correct path for the template(s) will be relative to the `CustomPath` 1. To find `CustomPath`, look for Custom File Root Path in Site Administration -> Configuration -- If that doesn't exist, you can try `echo $GITEA_CUSTOM` + If that doesn't exist, you can try `echo $GITEA_CUSTOM` -2. If you are still unable to find a path, the default can be [calculated above](#where-does-gitea-store-x-file) +2. If you are still unable to find a path, the default can be [calculated above](#where-does-gitea-store-what-file) 3. Once you have figured out the correct custom path, you can refer to the [customizing Gitea]({{< relref "doc/advanced/customizing-gitea.en-us.md" >}}) page to add your template to the correct location. ## Active user vs login prohibited user -In Gitea, an "active" user refers to a user that has activated their account via email. +In Gitea, an "active" user refers to a user that has activated their account via email. + A "login prohibited" user is a user that is not allowed to log in to Gitea anymore ## Setting up logging @@ -116,8 +126,10 @@ A "login prohibited" user is a user that is not allowed to log in to Gitea anymo ## What is Swagger? -[Swagger](https://swagger.io/) is what Gitea uses for its API. -All Gitea instances have the built-in API, though it can be disabled by setting `ENABLE_SWAGGER` to `false` in the `api` section of your `app.ini` +[Swagger](https://swagger.io/) is what Gitea uses for its API. + +All Gitea instances have the built-in API, though it can be disabled by setting `ENABLE_SWAGGER` to `false` in the `api` section of your `app.ini` + For more information, refer to Gitea's [API docs]({{< relref "doc/developers/api-usage.en-us.md" >}}) [Swagger Example](https://try.gitea.io/api/swagger) @@ -139,7 +151,8 @@ You can configure `EMAIL_DOMAIN_WHITELIST` or `EMAIL_DOMAIN_BLOCKLIST` in your a ### Only allow/block certain OpenID providers -You can configure `WHITELISTED_URIS` or `BLACKLISTED_URIS` under `[openid]` in your `app.ini` +You can configure `WHITELISTED_URIS` or `BLACKLISTED_URIS` under `[openid]` in your `app.ini` + **NOTE:** whitelisted takes precedence, so if it is non-blank then blacklisted is ignored ### Issue only users @@ -163,38 +176,48 @@ Use [Fail2Ban]({{< relref "doc/usage/fail2ban-setup.en-us.md" >}}) to monitor an Gitea supports three official themes right now, `gitea` (light), `arc-green` (dark), and `auto` (automatically switches between the previous two depending on operating system settings). To add your own theme, currently the only way is to provide a complete theme (not just color overrides) -As an example, let's say our theme is `arc-blue` (this is a real theme, and can be found [in this issue](https://github.com/go-gitea/gitea/issues/6011)) -Name the `.css` file `theme-arc-blue.css` and add it to your custom folder in `custom/public/css` +As an example, let's say our theme is `arc-blue` (this is a real theme, and can be found [in this issue](https://github.com/go-gitea/gitea/issues/6011)) + +Name the `.css` file `theme-arc-blue.css` and add it to your custom folder in `custom/public/css` + Allow users to use it by adding `arc-blue` to the list of `THEMES` in your `app.ini` ## SSHD vs built-in SSH -SSHD is the built-in SSH server on most Unix systems. +SSHD is the built-in SSH server on most Unix systems. + Gitea also provides its own SSH server, for usage when SSHD is not available. ## Gitea is running slow -The most common culprit for this is loading federated avatars. -This can be turned off by setting `ENABLE_FEDERATED_AVATAR` to `false` in your `app.ini` +The most common culprit for this is loading federated avatars. + +This can be turned off by setting `ENABLE_FEDERATED_AVATAR` to `false` in your `app.ini` + Another option that may need to be changed is setting `DISABLE_GRAVATAR` to `true` in your `app.ini` ## Can't create repositories/files -Make sure that Gitea has sufficient permissions to write to its home directory and data directory. -See [AppDataPath and RepoRootPath](#where-does-gitea-store-x-file) +Make sure that Gitea has sufficient permissions to write to its home directory and data directory. + +See [AppDataPath and RepoRootPath](#where-does-gitea-store-what-file) **Note for Arch users:** At the time of writing this, there is an issue with the Arch package's systemd file including this line: -`ReadWritePaths=/etc/gitea/app.ini` + +`ReadWritePaths=/etc/gitea/app.ini` + Which makes all other paths non-writeable to Gitea. ## Translation is incorrect/how to add more translations -Our translations are currently crowd-sourced on our [Crowdin project](https://crowdin.com/project/gitea) +Our translations are currently crowd-sourced on our [Crowdin project](https://crowdin.com/project/gitea) + Whether you want to change a translation or add a new one, it will need to be there as all translations are overwritten in our CI via the Crowdin integration. ## Hooks aren't running -If Gitea is not running hooks, a common cause is incorrect setup of SSH keys. +If Gitea is not running hooks, a common cause is incorrect setup of SSH keys. + See [SSH Issues](#ssh-issues) for more information. You can also try logging into the administration panel and running the `Resynchronize pre-receive, update and post-receive hooks of all repositories.` option. @@ -203,7 +226,8 @@ You can also try logging into the administration panel and running the `Resynchr If you cannot reach repositories over `ssh`, but `https` works fine, consider looking into the following. -First, make sure you can access Gitea via SSH. +First, make sure you can access Gitea via SSH. + `ssh git@myremote.example` If the connection is successful, you should receive an error message like the following: @@ -236,7 +260,8 @@ following things: - On the server: - Make sure the repository exists and is correctly named. - Check the permissions of the `.ssh` directory in the system user's home directory. - - Verify that the correct public keys are added to `.ssh/authorized_keys`. + - Verify that the correct public keys are added to `.ssh/authorized_keys`. + Try to run `Rewrite '.ssh/authorized_keys' file (for Gitea SSH keys)` on the Gitea admin panel. - Read Gitea logs. @@ -289,7 +314,8 @@ Check that you have proper access to the repository error: failed to push some refs to '' ``` -Check the value of `LFS_HTTP_AUTH_EXPIRY` in your `app.ini` file. +Check the value of `LFS_HTTP_AUTH_EXPIRY` in your `app.ini` file. + By default, your LFS token will expire after 20 minutes. If you have a slow connection or a large file (or both), it may not finish uploading within the time limit. You may want to set this value to `60m` or `120m`. @@ -306,17 +332,21 @@ There is no setting for password resets. It is enabled when a [mail service]({{< - As an **admin**, you can change any user's password (and optionally force them to change it on next login)... - By navigating to your `Site Administration -> User Accounts` page and editing a user. - - By using the [admin CLI commands]({{< relref "doc/usage/command-line.en-us.md#admin" >}}). + - By using the [admin CLI commands]({{< relref "doc/usage/command-line.en-us.md#admin" >}}). + Keep in mind most commands will also need a [global flag]({{< relref "doc/usage/command-line.en-us.md#global-options" >}}) to point the CLI at the correct configuration. - As a **user** you can change it... - In your account `Settings -> Account` page (this method **requires** you to know your current password). - - By using the `Forgot Password` link. + - By using the `Forgot Password` link. + If the `Forgot Password/Account Recovery` page is disabled, please contact your administrator to configure a [mail service]({{< relref "doc/usage/email-setup.en-us.md" >}}). ## Why is my markdown broken -In Gitea version `1.11` we moved to [goldmark](https://github.com/yuin/goldmark) for markdown rendering, which is [CommonMark](https://commonmark.org/) compliant. -If you have markdown that worked as you expected prior to version `1.11` and after upgrading it's not working anymore, please look through the CommonMark spec to see whether the problem is due to a bug or non-compliant syntax. +In Gitea version `1.11` we moved to [goldmark](https://github.com/yuin/goldmark) for markdown rendering, which is [CommonMark](https://commonmark.org/) compliant. + +If you have markdown that worked as you expected prior to version `1.11` and after upgrading it's not working anymore, please look through the CommonMark spec to see whether the problem is due to a bug or non-compliant syntax. + If it is the latter, _usually_ there is a compliant alternative listed in the spec. ## Upgrade errors with MySQL @@ -332,8 +362,10 @@ is too small. Gitea requires that the `ROWFORMAT` for its tables is `DYNAMIC`. If you are receiving an error line containing `Error 1071: Specified key was too long; max key length is 1000 bytes...` then you are attempting to run Gitea on tables which use the ISAM engine. While this may have worked by chance in previous versions of Gitea, it has never been officially supported and -you must use InnoDB. You should run `ALTER TABLE table_name ENGINE=InnoDB;` for each table in the database. +you must use InnoDB. You should run `ALTER TABLE table_name ENGINE=InnoDB;` for each table in the database. + If you are using MySQL 5, another possible fix is + ```mysql SET GLOBAL innodb_file_format=Barracuda; SET GLOBAL innodb_file_per_table=1; @@ -403,3 +435,9 @@ gitea doctor recreate-table ``` It is highly recommended to back-up your database before running these commands. + +## Why are tabs/indents wrong when viewing files + +If you are using Cloudflare, turn off the auto-minify option in the dashboard. + +`Speed` -> `Optimization` -> Uncheck `HTML` within the `Auto-Minify` settings. diff --git a/docs/content/doc/help/seek-help.en-us.md b/docs/content/doc/help/seek-help.en-us.md index 3ee160f4316fd..fe898e34b90d9 100644 --- a/docs/content/doc/help/seek-help.en-us.md +++ b/docs/content/doc/help/seek-help.en-us.md @@ -22,9 +22,10 @@ menu: 1. Your `app.ini` (with any sensitive data scrubbed as necessary). 2. The Gitea logs, and any other appropriate log files for the situation. - * The logs are likely to be outputted to console. If you need to collect logs from files, + - The logs are likely to be outputted to console. If you need to collect logs from files, you could copy the following config into your `app.ini` (remove all other `[log]` sections), then you can find the `*.log` files in Gitea's log directory (default: `%(GITEA_WORK_DIR)/log`). + ```ini ; To show all SQL logs, you can also set LOG_SQL=true in the [database] section [log] @@ -38,18 +39,22 @@ menu: FILE_NAME=router.log [log.file.xorm] FILE_NAME=xorm.log - ``` + ``` + 3. Any error messages you are seeing. 4. When possible, try to replicate the issue on [try.gitea.io](https://try.gitea.io) and include steps so that others can reproduce the issue. - * This will greatly improve the chance that the root of the issue can be quickly discovered and resolved. + - This will greatly improve the chance that the root of the issue can be quickly discovered and resolved. 5. If you meet slow/hanging/deadlock problems, please report the stack trace when the problem occurs: 1. Enable pprof in `app.ini` and restart Gitea - ``` - [server] - ENABLE_PPROF = true - ``` - 2. Trigger the bug, when Gitea gets stuck, use curl or browser to visit: `http://127.0.0.1:6060/debug/pprof/goroutine?debug=1` (IP is `127.0.0.1` and port is `6060`) - 3. Report the output (the stack trace doesn't contain sensitive data) + + ```ini + [server] + ENABLE_PPROF = true + ``` + + 2. Trigger the bug, when Gitea gets stuck, use curl or browser to visit: `http://127.0.0.1:6060/debug/pprof/goroutine?debug=1` (IP must be `127.0.0.1` and port must be `6060`). + 3. If you are using Docker, please use `docker exec -it curl "http://127.0.0.1:6060/debug/pprof/goroutine?debug=1"`. + 4. Report the output (the stack trace doesn't contain sensitive data) ## Bugs diff --git a/docs/content/doc/help/seek-help.zh-tw.md b/docs/content/doc/help/seek-help.zh-tw.md index 3d45e6c3b2554..f9107a026b1bd 100644 --- a/docs/content/doc/help/seek-help.zh-tw.md +++ b/docs/content/doc/help/seek-help.zh-tw.md @@ -22,10 +22,10 @@ menu: 1. 您的 `app.ini` (必要時清除掉任何機密資訊) 2. `gitea.log` (以及任何有關的日誌檔案) - * 例:如果錯誤和資料庫相關,提供 `xorm.log` 可能會有幫助 + - 例:如果錯誤和資料庫相關,提供 `xorm.log` 可能會有幫助 3. 您看到的任何錯誤訊息 4. 儘可能地在 [try.gitea.io](https://try.gitea.io) 觸發您的問題並記下步驟,以便其他人能重現那個問題。 - * 這將讓我們更有機會快速地找出問題的根源並解決它。 + - 這將讓我們更有機會快速地找出問題的根源並解決它。 5. 堆棧跟踪,[請參考英文文檔](https://docs.gitea.io/en-us/seek-help/) ## 錯誤回報 diff --git a/docs/content/doc/installation/database-preparation.en-us.md b/docs/content/doc/installation/database-preparation.en-us.md index 13a215d81483c..b8ad5d6859fb0 100644 --- a/docs/content/doc/installation/database-preparation.en-us.md +++ b/docs/content/doc/installation/database-preparation.en-us.md @@ -27,13 +27,13 @@ Note: All steps below requires that the database engine of your choice is instal ## MySQL -1. For remote database setup, you will need to make MySQL listen to your IP address. Edit `bind-address` option on `/etc/mysql/my.cnf` on database instance to: +1. For remote database setup, you will need to make MySQL listen to your IP address. Edit `bind-address` option on `/etc/mysql/my.cnf` on database instance to: ```ini bind-address = 203.0.113.3 ``` -2. On database instance, login to database console as root: +2. On database instance, login to database console as root: ``` mysql -u root -p @@ -41,7 +41,7 @@ Note: All steps below requires that the database engine of your choice is instal Enter the password as prompted. -3. Create database user which will be used by Gitea, authenticated by password. This example uses `'gitea'` as password. Please use a secure password for your instance. +3. Create database user which will be used by Gitea, authenticated by password. This example uses `'gitea'` as password. Please use a secure password for your instance. For local database: @@ -61,7 +61,7 @@ Note: All steps below requires that the database engine of your choice is instal Replace username and password above as appropriate. -4. Create database with UTF-8 charset and collation. Make sure to use `utf8mb4` charset instead of `utf8` as the former supports all Unicode characters (including emojis) beyond _Basic Multilingual Plane_. Also, collation chosen depending on your expected content. When in doubt, use either `unicode_ci` or `general_ci`. +4. Create database with UTF-8 charset and collation. Make sure to use `utf8mb4` charset instead of `utf8` as the former supports all Unicode characters (including emojis) beyond _Basic Multilingual Plane_. Also, collation chosen depending on your expected content. When in doubt, use either `unicode_ci` or `general_ci`. ```sql CREATE DATABASE giteadb CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_unicode_ci'; @@ -69,7 +69,7 @@ Note: All steps below requires that the database engine of your choice is instal Replace database name as appropriate. -5. Grant all privileges on the database to database user created above. +5. Grant all privileges on the database to database user created above. For local database: @@ -85,9 +85,9 @@ Note: All steps below requires that the database engine of your choice is instal FLUSH PRIVILEGES; ``` -6. Quit from database console by `exit`. +6. Quit from database console by `exit`. -7. On your Gitea server, test connection to the database: +7. On your Gitea server, test connection to the database: ``` mysql -u gitea -h 203.0.113.3 -p giteadb @@ -99,13 +99,13 @@ Note: All steps below requires that the database engine of your choice is instal ## PostgreSQL -1. For remote database setup, configure PostgreSQL on database instance to listen to your IP address by editing `listen_addresses` on `postgresql.conf` to: +1. For remote database setup, configure PostgreSQL on database instance to listen to your IP address by editing `listen_addresses` on `postgresql.conf` to: ```ini listen_addresses = 'localhost, 203.0.113.3' ``` -2. PostgreSQL uses `md5` challenge-response encryption scheme for password authentication by default. Nowadays this scheme is not considered secure anymore. Use SCRAM-SHA-256 scheme instead by editing the `postgresql.conf` configuration file on the database server to: +2. PostgreSQL uses `md5` challenge-response encryption scheme for password authentication by default. Nowadays this scheme is not considered secure anymore. Use SCRAM-SHA-256 scheme instead by editing the `postgresql.conf` configuration file on the database server to: ```ini password_encryption = scram-sha-256 @@ -113,13 +113,13 @@ Note: All steps below requires that the database engine of your choice is instal Restart PostgreSQL to apply the setting. -3. On the database server, login to the database console as superuser: +3. On the database server, login to the database console as superuser: ``` su -c "psql" - postgres ``` -4. Create database user (role in PostgreSQL terms) with login privilege and password. Please use a secure, strong password instead of `'gitea'` below: +4. Create database user (role in PostgreSQL terms) with login privilege and password. Please use a secure, strong password instead of `'gitea'` below: ```sql CREATE ROLE gitea WITH LOGIN PASSWORD 'gitea'; @@ -127,7 +127,7 @@ Note: All steps below requires that the database engine of your choice is instal Replace username and password as appropriate. -5. Create database with UTF-8 charset and owned by the database user created earlier. Any `libc` collations can be specified with `LC_COLLATE` and `LC_CTYPE` parameter, depending on expected content: +5. Create database with UTF-8 charset and owned by the database user created earlier. Any `libc` collations can be specified with `LC_COLLATE` and `LC_CTYPE` parameter, depending on expected content: ```sql CREATE DATABASE giteadb WITH OWNER gitea TEMPLATE template0 ENCODING UTF8 LC_COLLATE 'en_US.UTF-8' LC_CTYPE 'en_US.UTF-8'; @@ -135,7 +135,7 @@ Note: All steps below requires that the database engine of your choice is instal Replace database name as appropriate. -6. Allow the database user to access the database created above by adding the following authentication rule to `pg_hba.conf`. +6. Allow the database user to access the database created above by adding the following authentication rule to `pg_hba.conf`. For local database: @@ -155,7 +155,7 @@ Note: All steps below requires that the database engine of your choice is instal Restart PostgreSQL to apply new authentication rules. -7. On your Gitea server, test connection to the database. +7. On your Gitea server, test connection to the database. For local database: @@ -188,13 +188,13 @@ If the communication between Gitea and your database instance is performed throu The PostgreSQL driver used by Gitea supports two-way TLS. In two-way TLS, both database client and server authenticate each other by sending their respective certificates to their respective opposite for validation. In other words, the server verifies client certificate, and the client verifies server certificate. -1. On the server with the database instance, place the following credentials: +1. On the server with the database instance, place the following credentials: - `/path/to/postgresql.crt`: Database instance certificate - `/path/to/postgresql.key`: Database instance private key - `/path/to/root.crt`: CA certificate chain to validate client certificates -2. Add following options to `postgresql.conf`: +2. Add following options to `postgresql.conf`: ```ini ssl = on @@ -204,14 +204,14 @@ The PostgreSQL driver used by Gitea supports two-way TLS. In two-way TLS, both d ssl_min_protocol_version = 'TLSv1.2' ``` -3. Adjust credentials ownership and permission, as required by PostgreSQL: +3. Adjust credentials ownership and permission, as required by PostgreSQL: ``` chown postgres:postgres /path/to/root.crt /path/to/postgresql.crt /path/to/postgresql.key chmod 0600 /path/to/root.crt /path/to/postgresql.crt /path/to/postgresql.key ``` -4. Edit `pg_hba.conf` rule to only allow Gitea database user to connect over SSL, and to require client certificate verification. +4. Edit `pg_hba.conf` rule to only allow Gitea database user to connect over SSL, and to require client certificate verification. For PostgreSQL 12: @@ -227,9 +227,9 @@ The PostgreSQL driver used by Gitea supports two-way TLS. In two-way TLS, both d Replace database name, user, and IP address of Gitea instance as appropriate. -5. Restart PostgreSQL to apply configurations above. +5. Restart PostgreSQL to apply configurations above. -6. On the server running the Gitea instance, place the following credentials under the home directory of the user who runs Gitea (e.g. `git`): +6. On the server running the Gitea instance, place the following credentials under the home directory of the user who runs Gitea (e.g. `git`): - `~/.postgresql/postgresql.crt`: Database client certificate - `~/.postgresql/postgresql.key`: Database client private key @@ -237,14 +237,14 @@ The PostgreSQL driver used by Gitea supports two-way TLS. In two-way TLS, both d Note: Those file names above are hardcoded in PostgreSQL and it is not possible to change them. -7. Adjust credentials, ownership and permission as required: +7. Adjust credentials, ownership and permission as required: ``` chown git:git ~/.postgresql/postgresql.crt ~/.postgresql/postgresql.key ~/.postgresql/root.crt chown 0600 ~/.postgresql/postgresql.crt ~/.postgresql/postgresql.key ~/.postgresql/root.crt ``` -8. Test the connection to the database: +8. Test the connection to the database: ``` psql "postgres://gitea@example.db/giteadb?sslmode=verify-full" @@ -258,13 +258,13 @@ While the MySQL driver used by Gitea also supports two-way TLS, Gitea currently In one-way TLS, the database client verifies the certificate sent from server during the connection handshake, and the server assumes that the connected client is legitimate, since client certificate verification doesn't take place. -1. On the database instance, place the following credentials: +1. On the database instance, place the following credentials: - `/path/to/mysql.crt`: Database instance certificate - `/path/to/mysql.key`: Database instance key - `/path/to/ca.crt`: CA certificate chain. This file isn't used on one-way TLS, but is used to validate client certificates on two-way TLS. -2. Add following options to `my.cnf`: +2. Add following options to `my.cnf`: ```ini [mysqld] @@ -274,16 +274,16 @@ In one-way TLS, the database client verifies the certificate sent from server du tls-version = TLSv1.2,TLSv1.3 ``` -3. Adjust credentials ownership and permission: +3. Adjust credentials ownership and permission: ``` chown mysql:mysql /path/to/ca.crt /path/to/mysql.crt /path/to/mysql.key chmod 0600 /path/to/ca.crt /path/to/mysql.crt /path/to/mysql.key ``` -4. Restart MySQL to apply the setting. +4. Restart MySQL to apply the setting. -5. The database user for Gitea may have been created earlier, but it would authenticate only against the IP addresses of the server running Gitea. To authenticate against its domain name, recreate the user, and this time also set it to require TLS for connecting to the database: +5. The database user for Gitea may have been created earlier, but it would authenticate only against the IP addresses of the server running Gitea. To authenticate against its domain name, recreate the user, and this time also set it to require TLS for connecting to the database: ```sql DROP USER 'gitea'@'192.0.2.10'; @@ -294,9 +294,9 @@ In one-way TLS, the database client verifies the certificate sent from server du Replace database user name, password, and Gitea instance domain as appropriate. -6. Make sure that the CA certificate chain required to validate the database server certificate is on the system certificate store of both the database and Gitea servers. Consult your system documentation for instructions on adding a CA certificate to the certificate store. +6. Make sure that the CA certificate chain required to validate the database server certificate is on the system certificate store of both the database and Gitea servers. Consult your system documentation for instructions on adding a CA certificate to the certificate store. -7. On the server running Gitea, test connection to the database: +7. On the server running Gitea, test connection to the database: ``` mysql -u gitea -h example.db -p --ssl diff --git a/docs/content/doc/installation/from-binary.en-us.md b/docs/content/doc/installation/from-binary.en-us.md index d3486d8150996..f603fe37cfd0a 100644 --- a/docs/content/doc/installation/from-binary.en-us.md +++ b/docs/content/doc/installation/from-binary.en-us.md @@ -24,14 +24,31 @@ embedded assets. This can be different for older releases. ## Download -Choose the file matching the destination platform from the [downloads page](https://dl.gitea.io/gitea/), copy the URL and replace the URL within the commands below: +You can find the file matching your platform from the [downloads page](https://dl.gitea.io/gitea/) after navigating to the version you want to download. + +### Choosing the right file + +**For Linux**, you will likely want `linux-amd64`. It's for 64-bit Intel/AMD platforms, but there are other platforms available, including `arm64` (e.g. Raspberry PI 4), `386` (i.e. 32-bit), `arm-5`, and `arm-6`. + +**For Windows**, you will likely want `windows-4.0-amd64`. It's for all modern versions of Windows, but there is also a `386` platform available designed for older, 32-bit versions of Windows. + +*Note: there is also a `gogit-windows` file available that was created to help with some [performance problems](https://github.com/go-gitea/gitea/pull/15482) reported by some Windows users on older systems/versions. You should consider using this file if you're experiencing performance issues, and let us know if it improves performance.* + +**For macOS**, you should choose `darwin-arm64` if your hardware uses Apple Silicon, or `darwin-amd64` for Intel. + +### Downloading with wget + +Copy the commands below and replace the URL within the one you wish to download. ```sh wget -O gitea https://dl.gitea.io/gitea/{{< version >}}/gitea-{{< version >}}-linux-amd64 chmod +x gitea ``` +Note that the above command will download Gitea {{< version >}} for 64-bit Linux. + ## Verify GPG signature + Gitea signs all binaries with a [GPG key](https://keys.openpgp.org/search?q=teabot%40gitea.io) to prevent against unwanted modification of binaries. To validate the binary, download the signature file which ends in `.asc` for the binary you downloaded and use the GPG command line tool. @@ -56,7 +73,8 @@ Check that Git is installed on the server. If it is not, install it first. Gitea git --version ``` -Create user to run Gitea (ex. `git`) +Create a user to run Gitea (e.g. `git`) + ```sh adduser \ --system \ @@ -79,29 +97,39 @@ chown root:git /etc/gitea chmod 770 /etc/gitea ``` -**NOTE:** `/etc/gitea` is temporary set with write rights for user `git` so that Web installer could write configuration file. After installation is done, it is recommended to set rights to read-only using: -``` +**NOTE:** `/etc/gitea` is temporarily set with write permissions for user `git` so that the web installer can write the configuration file. After the installation is finished, it is recommended to set permissions to read-only using: + +```sh chmod 750 /etc/gitea chmod 640 /etc/gitea/app.ini ``` -If you don't want the web installer to be able to write the config file at all, it is also possible to make the config file read-only for the Gitea user (owner/group `root:git`, mode `0640`), and set `INSTALL_LOCK = true`. In that case all database configuration details must be set beforehand in the config file, as well as the `SECRET_KEY` and `INTERNAL_TOKEN` values. See the [command line documentation]({{< relref "doc/usage/command-line.en-us.md" >}}) for information on using `gitea generate secret INTERNAL_TOKEN`. + +If you don't want the web installer to be able to write to the config file, it is possible to make the config file read-only for the Gitea user (owner/group `root:git`, mode `0640`) however you will need to edit your config file manually to: + +* Set `INSTALL_LOCK= true`, +* Ensure all database configuration details are set correctly +* Ensure that the `SECRET_KEY` and `INTERNAL_TOKEN` values are set. (You may want to use the `gitea generate secret` to generate these secret keys.) +* Ensure that any other secret keys you need are set. + +See the [command line documentation]({{< relref "doc/usage/command-line.en-us.md" >}}) for information on using `gitea generate secret`. ### Configure Gitea's working directory -**NOTE:** If you plan on running Gitea as a Linux service, you can skip this step as the service file allows you to set `WorkingDirectory`. Otherwise, consider setting this environment variable (semi-)permanently so that Gitea consistently uses the correct working directory. -``` +**NOTE:** If you plan on running Gitea as a Linux service, you can skip this step, as the service file allows you to set `WorkingDirectory`. Otherwise, consider setting this environment variable (semi-)permanently so that Gitea consistently uses the correct working directory. + +```sh export GITEA_WORK_DIR=/var/lib/gitea/ ``` -### Copy Gitea binary to global location +### Copy the Gitea binary to a global location -``` +```sh cp gitea /usr/local/bin/gitea ``` ## Running Gitea -After the above steps, two options to run Gitea are: +After you complete the above steps, you can run Gitea two ways: ### 1. Creating a service file to start Gitea automatically (recommended) @@ -109,32 +137,31 @@ See how to create [Linux service]({{< relref "run-as-service-in-ubuntu.en-us.md" ### 2. Running from command-line/terminal -``` +```sh GITEA_WORK_DIR=/var/lib/gitea/ /usr/local/bin/gitea web -c /etc/gitea/app.ini ``` ## Updating to a new version You can update to a new version of Gitea by stopping Gitea, replacing the binary at `/usr/local/bin/gitea` and restarting the instance. -The binary file name should not be changed during the update to avoid problems -in existing repositories. +The binary file name should not be changed during the update to avoid problems in existing repositories. -It is recommended you do a [backup]({{< relref "doc/usage/backup-and-restore.en-us.md" >}}) before updating your installation. +It is recommended that you make a [backup]({{< relref "doc/usage/backup-and-restore.en-us.md" >}}) before updating your installation. If you have carried out the installation steps as described above, the binary should have the generic name `gitea`. Do not change this, i.e. to include the version number. ### 1. Restarting Gitea with systemd (recommended) -As explained before, we recommend to use systemd as service manager. In this case ```systemctl restart gitea``` should be enough. +As we explained before, we recommend to use systemd as the service manager. In this case, `systemctl restart gitea` should be fine. ### 2. Restarting Gitea without systemd -To restart your Gitea instance, we recommend to use SIGHUP signal. If you know your Gitea PID use ```kill -1 $GITEA_PID``` otherwise you can use ```killall -1 gitea``` or ```pkill -1 gitea``` +To restart your Gitea instance, we recommend to use SIGHUP signal. If you know your Gitea PID, use `kill -1 $GITEA_PID`, otherwise you can use `killall -1 gitea`. -To gracefully stop the Gitea instance, a simple ```kill $GITEA_PID``` or ```killall gitea``` is enough. +To gracefully stop the Gitea instance, a simple `kill $GITEA_PID` or `killall gitea` is enough. -**NOTE:** We don't recommend to use SIGKILL signal (know also as `-9`), you may be forcefully stopping some of Gitea internal tasks and it will not gracefully stop (tasks in queues, indexers processes, etc.) +**NOTE:** We don't recommend to use the SIGKILL signal (`-9`); you may be forcefully stopping some of Gitea's internal tasks, and it will not gracefully stop (tasks in queues, indexers, etc.) See below for troubleshooting instructions to repair broken repositories after an update of your Gitea version. @@ -144,31 +171,31 @@ an update of your Gitea version. ### Old glibc versions Older Linux distributions (such as Debian 7 and CentOS 6) may not be able to load the -Gitea binary, usually producing an error such as ```./gitea: /lib/x86_64-linux-gnu/libc.so.6: -version `GLIBC\_2.14' not found (required by ./gitea)```. This is due to the integrated +Gitea binary, usually producing an error such as `./gitea: /lib/x86_64-linux-gnu/libc.so.6: +version 'GLIBC\_2.14' not found (required by ./gitea)`. This is due to the integrated SQLite support in the binaries provided by dl.gitea.io. In this situation, it is usually -possible to [install from source]({{< relref "from-source.en-us.md" >}}) without SQLite -support. +possible to [install from source]({{< relref "from-source.en-us.md" >}}), without including +SQLite support. ### Running Gitea on another port For errors like `702 runWeb()] [E] Failed to start server: listen tcp 0.0.0.0:3000: -bind: address already in use` Gitea needs to be started on another free port. This +bind: address already in use`, Gitea needs to be started on another free port. This is possible using `./gitea web -p $PORT`. It's possible another instance of Gitea is already running. ### Running Gitea on Raspbian -As of v1.8, there is a problem with the arm7 version of Gitea and it doesn't run on Raspberry Pi and similar devices. +As of v1.8, there is a problem with the arm7 version of Gitea, and it doesn't run on Raspberry Pis and similar devices. -It is therefore recommended to switch to the arm6 version which has been tested and shown to work on Raspberry Pi and similar devices. +It is recommended to switch to the arm6 version, which has been tested and shown to work on Raspberry Pis and similar devices. ### Git error after updating to a new version of Gitea -If the binary file name has been changed during the update to a new version of Gitea, +If during the update, the binary file name has been changed to a new version of Gitea, Git Hooks in existing repositories will not work any more. In that case, a Git error will be displayed when pushing to the repository. @@ -181,9 +208,9 @@ binary. To solve this, go to the admin options and run the task `Resynchronize pre-receive, update and post-receive hooks of all repositories` to update all hooks to contain -the new binary path. Please note that this overwrite all Git Hooks including ones +the new binary path. Please note that this overwrites all Git Hooks, including ones with customizations made. -If you aren't using the built-in to Gitea SSH server you will also need to re-write +If you aren't using the Gitea built-in SSH server, you will also need to re-write the authorized key file by running the `Update the '.ssh/authorized_keys' file with Gitea SSH keys.` task in the admin options. diff --git a/docs/content/doc/installation/from-package.en-us.md b/docs/content/doc/installation/from-package.en-us.md index e4081024bd0e7..3f75f26a53d0a 100644 --- a/docs/content/doc/installation/from-package.en-us.md +++ b/docs/content/doc/installation/from-package.en-us.md @@ -47,13 +47,13 @@ pacman -S gitea There is a [Gitea Snap](https://snapcraft.io/gitea) package which follows the latest stable version. -``sh +```sh snap install gitea -`` +``` ## SUSE and openSUSE -OpenSUSE build service provides packages for [openSUSE and SLE](https://software.opensuse.org/download/package?package=gitea&project=devel%3Atools%3Ascm) +OpenSUSE build service provides packages for [openSUSE and SLE](https://software.opensuse.org/download/package?package=gitea&project=devel%3Atools%3Ascm) in the Development Software Configuration Management Repository ## Windows diff --git a/docs/content/doc/installation/from-source.en-us.md b/docs/content/doc/installation/from-source.en-us.md index 54e79769ea143..660f996b1e707 100644 --- a/docs/content/doc/installation/from-source.en-us.md +++ b/docs/content/doc/installation/from-source.en-us.md @@ -101,7 +101,7 @@ Depending on requirements, the following build tags can be included. - `pam`: Enable support for PAM (Linux Pluggable Authentication Modules). Can be used to authenticate local users or extend authentication to methods available to PAM. -* `gogit`: (EXPERIMENTAL) Use go-git variants of Git commands. +- `gogit`: (EXPERIMENTAL) Use go-git variants of Git commands. Bundling assets into the binary using the `bindata` build tag is recommended for production deployments. It is possible to serve the static assets directly via a reverse proxy, diff --git a/docs/content/doc/installation/from-source.fr-fr.md b/docs/content/doc/installation/from-source.fr-fr.md index 4afbd137731ef..00f67eab55f2f 100644 --- a/docs/content/doc/installation/from-source.fr-fr.md +++ b/docs/content/doc/installation/from-source.fr-fr.md @@ -30,7 +30,6 @@ cd $GOPATH/src/code.gitea.io/gitea Maintenant, il est temps de décider quelle version de Gitea vous souhaitez compiler et installer. Actuellement, ils existent plusieurs options possibles. Si vous voulez compiler notre branche `master`, vous pouvez directement passer à la [section compilation](#compilation), cette branche représente la dernière version en cours de développement et n'a pas vocation à être utiliser en production. - Si vous souhaitez compiler la dernière version stable, utilisez les étiquettes ou les différentes branches disponibles. Vous pouvez voir les branches disponibles et comment utiliser cette branche avec ces commandes: ``` diff --git a/docs/content/doc/installation/from-source.zh-cn.md b/docs/content/doc/installation/from-source.zh-cn.md index 7d08033603d65..275b0c2f74799 100644 --- a/docs/content/doc/installation/from-source.zh-cn.md +++ b/docs/content/doc/installation/from-source.zh-cn.md @@ -26,7 +26,7 @@ go get -d -u code.gitea.io/gitea cd $GOPATH/src/code.gitea.io/gitea ``` -然后你可以选择编译和安装的版本,当前你有多个选择。如果你想编译 `master` 版本,你可以直接跳到 [编译](#build) 部分,这是我们的开发分支,虽然也很稳定但不建议您在正式产品中使用。 +然后你可以选择编译和安装的版本,当前你有多个选择。如果你想编译 `master` 版本,你可以直接跳到 [编译](#编译) 部分,这是我们的开发分支,虽然也很稳定但不建议您在正式产品中使用。 如果你想编译最新稳定分支,你可以执行以下命令签出源码: @@ -55,9 +55,9 @@ git checkout v{{< version >}} 按照您的编译需求,以下 tags 可以使用: -* `bindata`: 这个编译选项将会把运行Gitea所需的所有外部资源都打包到可执行文件中,这样部署将非常简单因为除了可执行程序将不再需要任何其他文件。 -* `sqlite sqlite_unlock_notify`: 这个编译选项将启用SQLite3数据库的支持,建议只在少数人使用时使用这个模式。 -* `pam`: 这个编译选项将会启用 PAM (Linux Pluggable Authentication Modules) 认证,如果你使用这一认证模式的话需要开启这个选项。 +- `bindata`: 这个编译选项将会把运行Gitea所需的所有外部资源都打包到可执行文件中,这样部署将非常简单因为除了可执行程序将不再需要任何其他文件。 +- `sqlite sqlite_unlock_notify`: 这个编译选项将启用SQLite3数据库的支持,建议只在少数人使用时使用这个模式。 +- `pam`: 这个编译选项将会启用 PAM (Linux Pluggable Authentication Modules) 认证,如果你使用这一认证模式的话需要开启这个选项。 使用 bindata 可以打包资源文件到二进制可以使开发和测试更容易,你可以根据自己的需求决定是否打包资源文件。 要包含资源文件,请使用 `bindata` tag: diff --git a/docs/content/doc/installation/from-source.zh-tw.md b/docs/content/doc/installation/from-source.zh-tw.md index 39c9878309452..2b65d554ab7f0 100644 --- a/docs/content/doc/installation/from-source.zh-tw.md +++ b/docs/content/doc/installation/from-source.zh-tw.md @@ -26,7 +26,7 @@ go get -d -u code.gitea.io/gitea cd $GOPATH/src/code.gitea.io/gitea ``` -現在該決定您要編譯或安裝的 Gitea 版本,您有很多可以選擇。如果您想編譯 `master` 版本,你可以直接跳到[編譯章節](#build),這是我們開發分支,雖然很穩定,但是不建議用在正式環境。 +現在該決定您要編譯或安裝的 Gitea 版本,您有很多可以選擇。如果您想編譯 `master` 版本,你可以直接跳到[編譯章節](#編譯),這是我們開發分支,雖然很穩定,但是不建議用在正式環境。 假如您想要編譯最新穩定版本,可以執行底下命令切換到正確版本: diff --git a/docs/content/doc/installation/on-kubernetes.zh-tw.md b/docs/content/doc/installation/on-kubernetes.zh-tw.md index 5ea412aa000d3..345ff7ac2c300 100644 --- a/docs/content/doc/installation/on-kubernetes.zh-tw.md +++ b/docs/content/doc/installation/on-kubernetes.zh-tw.md @@ -26,7 +26,7 @@ helm install gitea gitea-charts/gitea 若您想自訂安裝(包括使用 kubernetes ingress),請前往完整的 [Gitea helm chart configuration details](https://gitea.com/gitea/helm-chart/) -##運行狀況檢查終端節點 +## 運行狀況檢查終端節點 Gitea 附帶了一個運行狀況檢查端點 `/api/healthz`,你可以像這樣在 kubernetes 中配置它: diff --git a/docs/content/doc/installation/run-as-service-in-ubuntu.en-us.md b/docs/content/doc/installation/run-as-service-in-ubuntu.en-us.md index 471377e9fcf64..9f65eaca9f9a8 100644 --- a/docs/content/doc/installation/run-as-service-in-ubuntu.en-us.md +++ b/docs/content/doc/installation/run-as-service-in-ubuntu.en-us.md @@ -27,12 +27,14 @@ Change the user, home directory, and other required startup values. Change the PORT or remove the -p flag if default port is used. Enable and start Gitea at boot: + ``` sudo systemctl enable gitea sudo systemctl start gitea ``` If you have systemd version 220 or later, you can enable and immediately start Gitea at once by: + ``` sudo systemctl enable gitea --now ``` @@ -40,11 +42,13 @@ sudo systemctl enable gitea --now #### Using supervisor Install supervisor by running below command in terminal: + ``` sudo apt install supervisor ``` Create a log dir for the supervisor logs: + ``` # assuming Gitea is installed in /home/git/gitea/ mkdir /home/git/gitea/log/supervisor @@ -58,12 +62,14 @@ Using your favorite editor, change the user (`git`) and home or remove the -p flag if default port is used. Lastly enable and start supervisor at boot: + ``` sudo systemctl enable supervisor sudo systemctl start supervisor ``` If you have systemd version 220 or later, you can enable and immediately start supervisor by: + ``` sudo systemctl enable supervisor --now ``` diff --git a/docs/content/doc/installation/run-as-service-in-ubuntu.zh-cn.md b/docs/content/doc/installation/run-as-service-in-ubuntu.zh-cn.md index 02cd032b67738..c76350ecdcfb4 100644 --- a/docs/content/doc/installation/run-as-service-in-ubuntu.zh-cn.md +++ b/docs/content/doc/installation/run-as-service-in-ubuntu.zh-cn.md @@ -18,6 +18,7 @@ menu: #### systemd 方式 在 terminal 中执行以下命令: + ``` sudo vim /etc/systemd/system/gitea.service ``` @@ -27,26 +28,29 @@ sudo vim /etc/systemd/system/gitea.service 修改 user,home 目录以及其他必须的初始化参数,如果使用自定义端口,则需修改 PORT 参数,反之如果使用默认端口则需删除 -p 标记。 激活 gitea 并将它作为系统自启动服务: + ``` sudo systemctl enable gitea sudo systemctl start gitea ``` - #### 使用 supervisor 在 terminal 中执行以下命令安装 supervisor: + ``` sudo apt install supervisor ``` 为 supervisor 配置日志路径: + ``` # assuming gitea is installed in /home/git/gitea/ mkdir /home/git/gitea/log/supervisor ``` 在文件编辑器中打开 supervisor 的配置文件: + ``` sudo vim /etc/supervisor/supervisord.conf ``` @@ -57,6 +61,7 @@ sudo vim /etc/supervisor/supervisord.conf 将 user(git) 和 home(/home/git) 设置为与上文部署中匹配的值。如果使用自定义端口,则需修改 PORT 参数,反之如果使用默认端口则需删除 -p 标记。 最后激活 supervisor 并将它作为系统自启动服务: + ``` sudo systemctl enable supervisor sudo systemctl start supervisor diff --git a/docs/content/doc/installation/with-docker-rootless.en-us.md b/docs/content/doc/installation/with-docker-rootless.en-us.md index 634e08a72ec42..3cae65c2b2fc2 100644 --- a/docs/content/doc/installation/with-docker-rootless.en-us.md +++ b/docs/content/doc/installation/with-docker-rootless.en-us.md @@ -247,6 +247,7 @@ files; for named volumes, this is done through another container or by direct ac :exclamation::exclamation: **Make sure you have volumed data to somewhere outside Docker container** :exclamation::exclamation: To upgrade your installation to the latest release: + ``` # Edit `docker-compose.yml` to update the version, if you have one specified # Pull new images diff --git a/docs/content/doc/installation/with-docker.en-us.md b/docs/content/doc/installation/with-docker.en-us.md index c2e7a817c932a..895f04804e2bc 100644 --- a/docs/content/doc/installation/with-docker.en-us.md +++ b/docs/content/doc/installation/with-docker.en-us.md @@ -255,7 +255,7 @@ favorite browser to finalize the installation. Visit http://server-ip:3000 and f installation wizard. If the database was started with the `docker-compose` setup as documented above, please note that `db` must be used as the database hostname. -## Configure the user inside Gitea using environment variables +## Configure the user inside Gitea using environment variables - `USER`: **git**: The username of the user that runs Gitea within the container. - `USER_UID`: **1000**: The UID (Unix user ID) of the user that runs Gitea within the container. Match this to the UID of the owner of the `/data` volume if using host volumes (this is not necessary with named volumes). @@ -303,12 +303,30 @@ services: - GITEA__mailer__PASSWD="""${GITEA__mailer__PASSWD:?GITEA__mailer__PASSWD not set}""" ``` -To set required TOKEN and SECRET values, consider using Gitea's built-in [generate utility functions](https://docs.gitea.io/en-us/command-line/#generate). +Gitea will generate new secrets/tokens for every new installation automatically and write them into the app.ini. If you want to set the secrets/tokens manually, you can use the following docker commands to use of Gitea's built-in [generate utility functions](https://docs.gitea.io/en-us/command-line/#generate). Do not lose/change your SECRET_KEY after the installation, otherwise the encrypted data can not be decrypted anymore. + +The following commands will output a new `SECRET_KEY` and `INTERNAL_TOKEN` to `stdout`, which you can then place in your environment variables. + +```bash +docker run -it --rm gitea/gitea:1 gitea generate secret SECRET_KEY +docker run -it --rm gitea/gitea:1 gitea generate secret INTERNAL_TOKEN +``` + +```yaml +... +services: + server: + environment: + - GITEA__security__SECRET_KEY=[value returned by generate secret SECRET_KEY] + - GITEA__security__INTERNAL_TOKEN=[value returned by generate secret INTERNAL_TOKEN] +``` ## SSH Container Passthrough Since SSH is running inside the container, SSH needs to be passed through from the host to the container if SSH support is desired. One option would be to run the container SSH on a non-standard port (or moving the host port to a non-standard port). Another option which might be more straightforward is for Gitea users to ssh to a Gitea user on the host which will then relay those connections to the docker. +### Understanding SSH access to Gitea (without passthrough) + To understand what needs to happen, you first need to understand what happens without passthrough. So we will try to explain this: 1. The client adds their SSH public key to Gitea using the webpage. @@ -392,9 +410,9 @@ In this option, the idea is that the host simply uses the `authorized_keys` that Here is a detailed explanation what is happening when a SSH request is made: 1. The client adds their SSH public key to Gitea using the webpage. -2. Gitea in the container will add an entry for this key to the `.ssh/authorized_keys` file of its running user, `git`. +2. Gitea in the container will add an entry for this key to the `.ssh/authorized_keys` file of its running user, `git`. - However, because `/home/git/.ssh/` on the host is mounted as `/data/git/.ssh` this means that the key has been added to the host `git` user's `authorized_keys` file too. -3. This entry has the public key, but also has a `command=` option. +3. This entry has the public key, but also has a `command=` option. - This command matches the location of the Gitea binary on the container, but also the location of the shim on the host. 4. The client then makes an SSH request to the host SSH server using the `git` user, e.g. `git clone git@domain:user/repo.git`. 5. The client will attempt to authenticate with the server, passing one or more public keys in turn to the host. @@ -439,7 +457,7 @@ we create a new shell for the git user. As an administrative user on the host ru Here is a detailed explanation what is happening when a SSH request is made: 1. The client adds their SSH public key to Gitea using the webpage. -2. Gitea in the container will add an entry for this key to the `.ssh/authorized_keys` file of its running user, `git`. +2. Gitea in the container will add an entry for this key to the `.ssh/authorized_keys` file of its running user, `git`. - However, because `/home/git/.ssh/` on the host is mounted as `/data/git/.ssh` this means that the key has been added to the host `git` user's `authorized_keys` file too. 3. This entry has the public key, but also has a `command=` option. - This command matches the location of the Gitea binary on the container. @@ -480,7 +498,7 @@ sudo usermod -s /home/git/docker-shell git Here is a detailed explanation what is happening when a SSH request is made: 1. The client adds their SSH public key to Gitea using the webpage. -2. Gitea in the container will add an entry for this key to the `.ssh/authorized_keys` file of its running user, `git`. +2. Gitea in the container will add an entry for this key to the `.ssh/authorized_keys` file of its running user, `git`. - However, because `/home/git/.ssh/` on the host is mounted as `/data/git/.ssh` this means that the key has been added to the host `git` user's `authorized_keys` file too. 3. This entry has the public key, but also has a `command=` option. - This command matches the location of the Gitea binary on the container. @@ -529,7 +547,7 @@ In this option, the idea is that the host SSH uses an `AuthorizedKeysCommand` in Now all attempts to login as the `git` user on the host will be forwarded to the docker - including the `SSH_ORIGINAL_COMMAND`. We now need to set-up SSH authentication on the host. -We will do this by leveraging the [SSH AuthorizedKeysCommand](https://docs.gitea.io/en-us/command-line/#keys) to match the keys against those accepted by Gitea. +We will do this by leveraging the [SSH AuthorizedKeysCommand](https://docs.gitea.io/en-us/command-line/#keys) to match the keys against those accepted by Gitea. Add the following block to `/etc/ssh/sshd_config`, on the host: diff --git a/docs/content/doc/installation/with-docker.zh-cn.md b/docs/content/doc/installation/with-docker.zh-cn.md index 9122ee84264f7..91892fdaf95c0 100644 --- a/docs/content/doc/installation/with-docker.zh-cn.md +++ b/docs/content/doc/installation/with-docker.zh-cn.md @@ -301,7 +301,7 @@ volumes: sudo -u git ssh-keygen -t rsa -b 4096 -C "Gitea Host Key" ``` -在下一步中,需要在主机上创建一个名为 `/user/local/bin/gitea` 的文件(具有可执行权限)。该文件将发出从主机到容器的 SSH 转发。将以下内容添加到 `/user/local/bin/gitea`: +在下一步中,需要在主机上创建一个名为 `/usr/local/bin/gitea` 的文件(具有可执行权限)。该文件将发出从主机到容器的 SSH 转发。将以下内容添加到 `/usr/local/bin/gitea`: ```bash ssh -p 2222 -o StrictHostKeyChecking=no git@127.0.0.1 "SSH_ORIGINAL_COMMAND=\"$SSH_ORIGINAL_COMMAND\" $0 $@" @@ -324,14 +324,14 @@ ports: ssh-rsa # other keys from users -command="/user/local/bin/gitea --config=/data/gitea/conf/app.ini serv key-1",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty +command="/usr/local/bin/gitea --config=/data/gitea/conf/app.ini serv key-1",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ``` 这是详细的说明,当发出 SSH 请求时会发生什么: 1. 使用 `git` 用户向主机发出 SSH 请求,例如 `git clone git@domain:user/repo.git`。 -2. 在 `/home/git/.ssh/authorized_keys` 中,该命令执行 `/user/local/bin/gitea` 脚本。 -3. `/user/local/bin/gitea` 将 SSH 请求转发到端口 2222,该端口已映射到容器的 SSH 端口(22)。 +2. 在 `/home/git/.ssh/authorized_keys` 中,该命令执行 `/usr/local/bin/gitea` 脚本。 +3. `/usr/local/bin/gitea` 将 SSH 请求转发到端口 2222,该端口已映射到容器的 SSH 端口(22)。 4. 由于 `/home/git/.ssh/authorized_keys` 中存在 `git` 用户的公钥,因此身份验证主机 → 容器成功,并且 SSH 请求转发到在 docker 容器中运行的 Gitea。 如果在 Gitea Web 界面中添加了新的 SSH 密钥,它将以与现有密钥相同的方式附加到 `.ssh/authorized_keys` 中。 diff --git a/docs/content/doc/packages/composer.en-us.md b/docs/content/doc/packages/composer.en-us.md index 2502ee45b509b..47b03781f06e5 100644 --- a/docs/content/doc/packages/composer.en-us.md +++ b/docs/content/doc/packages/composer.en-us.md @@ -60,6 +60,8 @@ curl --user your_username:your_password_or_token \ https://gitea.example.com/api/packages/testuser/composer?version=1.0.3 ``` +If you are using 2FA or OAuth use a [personal access token]({{< relref "doc/developers/api-usage.en-us.md#authentication" >}}) instead of the password. + The server responds with the following HTTP Status codes. | HTTP Status Code | Meaning | diff --git a/docs/content/doc/packages/conan.en-us.md b/docs/content/doc/packages/conan.en-us.md index c650e9d7ea491..fb104f34f43b2 100644 --- a/docs/content/doc/packages/conan.en-us.md +++ b/docs/content/doc/packages/conan.en-us.md @@ -37,7 +37,7 @@ conan user --remote {remote} --password {password} {username} | -----------| ----------- | | `remote` | The remote name. | | `username` | Your Gitea username. | -| `password` | Your Gitea password or a personal access token. | +| `password` | Your Gitea password. If you are using 2FA or OAuth use a [personal access token]({{< relref "doc/developers/api-usage.en-us.md#authentication" >}}) instead of the password. | | `owner` | The owner of the package. | For example: diff --git a/docs/content/doc/packages/container.en-us.md b/docs/content/doc/packages/container.en-us.md index 28559eb22b8d5..77dbbafd02cb5 100644 --- a/docs/content/doc/packages/container.en-us.md +++ b/docs/content/doc/packages/container.en-us.md @@ -34,6 +34,8 @@ To push an image or if the image is in a private registry, you have to authentic docker login gitea.example.com ``` +If you are using 2FA or OAuth use a [personal access token]({{< relref "doc/developers/api-usage.en-us.md#authentication" >}}) instead of the password. + ## Image naming convention Images must follow this naming convention: diff --git a/docs/content/doc/packages/generic.en-us.md b/docs/content/doc/packages/generic.en-us.md index afef323938d4f..a82058da8ac5c 100644 --- a/docs/content/doc/packages/generic.en-us.md +++ b/docs/content/doc/packages/generic.en-us.md @@ -37,7 +37,7 @@ PUT https://gitea.example.com/api/packages/{owner}/generic/{package_name}/{packa | ----------------- | ----------- | | `owner` | The owner of the package. | | `package_name` | The package name. It can contain only lowercase letters (`a-z`), uppercase letter (`A-Z`), numbers (`0-9`), dots (`.`), hyphens (`-`), or underscores (`_`). | -| `package_version` | The package version as described in the [SemVer](https://semver.org/) spec. | +| `package_version` | The package version, a non-empty string. | | `file_name` | The filename. It can contain only lowercase letters (`a-z`), uppercase letter (`A-Z`), numbers (`0-9`), dots (`.`), hyphens (`-`), or underscores (`_`). | Example request using HTTP Basic authentication: @@ -48,6 +48,8 @@ curl --user your_username:your_password_or_token \ https://gitea.example.com/api/packages/testuser/generic/test_package/1.0.0/file.bin ``` +If you are using 2FA or OAuth use a [personal access token]({{< relref "doc/developers/api-usage.en-us.md#authentication" >}}) instead of the password. + The server reponds with the following HTTP Status codes. | HTTP Status Code | Meaning | diff --git a/docs/content/doc/packages/helm.en-us.md b/docs/content/doc/packages/helm.en-us.md index 9c43b08bf4298..89b929f9bc848 100644 --- a/docs/content/doc/packages/helm.en-us.md +++ b/docs/content/doc/packages/helm.en-us.md @@ -42,7 +42,7 @@ helm cm-push ./{chart_file}.tgz {repo} | Parameter | Description | | ------------ | ----------- | | `username` | Your Gitea username. | -| `password` | Your Gitea password or a personal access token. | +| `password` | Your Gitea password. If you are using 2FA or OAuth use a [personal access token]({{< relref "doc/developers/api-usage.en-us.md#authentication" >}}) instead of the password. | | `repo` | The name for the repository. | | `chart_file` | The Helm Chart archive. | | `owner` | The owner of the package. | diff --git a/docs/content/doc/packages/maven.en-us.md b/docs/content/doc/packages/maven.en-us.md index 837c8434ae4d5..22da3c16d2945 100644 --- a/docs/content/doc/packages/maven.en-us.md +++ b/docs/content/doc/packages/maven.en-us.md @@ -81,6 +81,16 @@ To publish a package simply run: mvn deploy ``` +If you want to publish a prebuild package to the registry, you can use [`mvn deploy:deploy-file`](https://maven.apache.org/plugins/maven-deploy-plugin/deploy-file-mojo.html): + +```shell +mvn deploy:deploy-file -Durl=https://gitea.example.com/api/packages/{owner}/maven -DrepositoryId=gitea -Dfile=/path/to/package.jar +``` + +| Parameter | Description | +| -------------- | ----------- | +| `owner` | The owner of the package. | + You cannot publish a package if a package of the same name and version already exists. You must delete the existing package first. ## Install a package @@ -107,4 +117,4 @@ mvn install mvn install mvn deploy mvn dependency:get: -``` \ No newline at end of file +``` diff --git a/docs/content/doc/packages/nuget.en-us.md b/docs/content/doc/packages/nuget.en-us.md index 421faf9ee6503..a4435fa99f01a 100644 --- a/docs/content/doc/packages/nuget.en-us.md +++ b/docs/content/doc/packages/nuget.en-us.md @@ -38,7 +38,7 @@ dotnet nuget add source --name {source_name} --username {username} --password {p | ------------- | ----------- | | `source_name` | The desired source name. | | `username` | Your Gitea username. | -| `password` | Your Gitea password or a personal access token. | +| `password` | Your Gitea password. If you are using 2FA or OAuth use a [personal access token]({{< relref "doc/developers/api-usage.en-us.md#authentication" >}}) instead of the password. | | `owner` | The owner of the package. | For example: diff --git a/docs/content/doc/packages/overview.en-us.md b/docs/content/doc/packages/overview.en-us.md index 81575b9ade7c7..5e03b710170f1 100644 --- a/docs/content/doc/packages/overview.en-us.md +++ b/docs/content/doc/packages/overview.en-us.md @@ -34,6 +34,7 @@ The following package managers are currently supported: | [Maven]({{< relref "doc/packages/maven.en-us.md" >}}) | Java | `mvn`, `gradle` | | [npm]({{< relref "doc/packages/npm.en-us.md" >}}) | JavaScript | `npm`, `yarn` | | [NuGet]({{< relref "doc/packages/nuget.en-us.md" >}}) | .NET | `nuget` | +| [Pub]({{< relref "doc/packages/pub.en-us.md" >}}) | Dart | `dart`, `flutter` | | [PyPI]({{< relref "doc/packages/pypi.en-us.md" >}}) | Python | `pip`, `twine` | | [RubyGems]({{< relref "doc/packages/rubygems.en-us.md" >}}) | Ruby | `gem`, `Bundler` | diff --git a/docs/content/doc/packages/pub.en-us.md b/docs/content/doc/packages/pub.en-us.md new file mode 100644 index 0000000000000..4d37662208332 --- /dev/null +++ b/docs/content/doc/packages/pub.en-us.md @@ -0,0 +1,83 @@ +--- +date: "2022-07-31T00:00:00+00:00" +title: "Pub Packages Repository" +slug: "packages/pub" +draft: false +toc: false +menu: + sidebar: + parent: "packages" + name: "Pub" + weight: 90 + identifier: "pub" +--- + +# Pub Packages Repository + +Publish [Pub](https://dart.dev/guides/packages) packages for your user or organization. + +**Table of Contents** + +{{< toc >}} + +## Requirements + +To work with the Pub package registry, you need to use the tools [dart](https://dart.dev/tools/dart-tool) and/or [flutter](https://docs.flutter.dev/reference/flutter-cli). + +The following examples use dart. + +## Configuring the package registry + +To register the package registry and provide credentials, execute: + +```shell +dart pub token add https://gitea.example.com/api/packages/{owner}/pub +``` + +| Placeholder | Description | +| ------------ | ----------- | +| `owner` | The owner of the package. | + +You need to provide your [personal access token]({{< relref "doc/developers/api-usage.en-us.md#authentication" >}}). + +## Publish a package + +To publish a package, edit the `pubspec.yaml` and add the following line: + +```yaml +publish_to: https://gitea.example.com/api/packages/{owner}/pub +``` + +| Placeholder | Description | +| ------------ | ----------- | +| `owner` | The owner of the package. | + +Now you can publish the package by running the following command: + +```shell +dart pub publish +``` + +You cannot publish a package if a package of the same name and version already exists. You must delete the existing package first. + +## Install a package + +To install a Pub package from the package registry, execute the following command: + +```shell +dart pub add {package_name} --hosted-url=https://gitea.example.com/api/packages/{owner}/pub/ +``` + +| Parameter | Description | +| ----------------- | ----------- | +| `owner` | The owner of the package. | +| `package_name` | The package name. | + +For example: + +```shell +# use latest version +dart pub add mypackage --hosted-url=https://gitea.example.com/api/packages/testuser/pub/ +# specify version +dart pub add mypackage:1.0.8 --hosted-url=https://gitea.example.com/api/packages/testuser/pub/ +``` diff --git a/docs/content/doc/packages/pypi.en-us.md b/docs/content/doc/packages/pypi.en-us.md index d9f4872dca4c8..588df71d60c27 100644 --- a/docs/content/doc/packages/pypi.en-us.md +++ b/docs/content/doc/packages/pypi.en-us.md @@ -8,7 +8,7 @@ menu: sidebar: parent: "packages" name: "PyPI" - weight: 90 + weight: 100 identifier: "pypi" --- @@ -42,7 +42,7 @@ password = {password} | ------------ | ----------- | | `owner` | The owner of the package. | | `username` | Your Gitea username. | -| `password` | Your Gitea password or a [personal access token]({{< relref "doc/developers/api-usage.en-us.md#authentication" >}}). | +| `password` | Your Gitea password. If you are using 2FA or OAuth use a [personal access token]({{< relref "doc/developers/api-usage.en-us.md#authentication" >}}) instead of the password. | ## Publish a package @@ -82,4 +82,4 @@ pip install --index-url https://testuser:password123@gitea.example.com/api/packa ``` pip install twine upload -``` \ No newline at end of file +``` diff --git a/docs/content/doc/packages/rubygems.en-us.md b/docs/content/doc/packages/rubygems.en-us.md index 9d9ce09b1c6da..d4ae30bbcecc1 100644 --- a/docs/content/doc/packages/rubygems.en-us.md +++ b/docs/content/doc/packages/rubygems.en-us.md @@ -8,7 +8,7 @@ menu: sidebar: parent: "packages" name: "RubyGems" - weight: 100 + weight: 110 identifier: "rubygems" --- @@ -36,7 +36,7 @@ https://gitea.example.com/api/packages/{owner}/rubygems: Bearer {token} | Parameter | Description | | ------------- | ----------- | | `owner` | The owner of the package. | -| `token` | Your personal access token. | +| `token` | Your [personal access token]({{< relref "doc/developers/api-usage.en-us.md#authentication" >}}). | For example: @@ -124,4 +124,4 @@ gem install --host https://gitea.example.com/api/packages/testuser/rubygems test gem install bundle install gem push -``` \ No newline at end of file +``` diff --git a/docs/content/doc/translation/guidelines.de-de.md b/docs/content/doc/translation/guidelines.de-de.md index 9f4b84ca9b3ed..eee031a54ed11 100644 --- a/docs/content/doc/translation/guidelines.de-de.md +++ b/docs/content/doc/translation/guidelines.de-de.md @@ -15,10 +15,12 @@ menu: ## Allgemeines Anrede: Wenig förmlich: + * "Du"-Form * Keine "Amtsdeusch"-Umschreibungen, einfach so als ob man den Nutzer direkt persönlich ansprechen würde Genauer definiert: + * "falsch" anstatt "nicht korrekt/inkorrekt" * Benutzerkonto oder Konto? Oder Account? * "Wende dich an ..." anstatt "kontaktiere ..." diff --git a/docs/content/doc/upgrade/from-gitea.en-us.md b/docs/content/doc/upgrade/from-gitea.en-us.md index 2f64e0fac6bf6..0d22a32439c85 100644 --- a/docs/content/doc/upgrade/from-gitea.en-us.md +++ b/docs/content/doc/upgrade/from-gitea.en-us.md @@ -20,14 +20,20 @@ menu: {{< toc >}} To update Gitea, download a newer version, stop the old one, perform a backup, and run the new one. -Every time a Gitea instance starts up, it checks whether a database migration should be run. +Every time a Gitea instance starts up, it checks whether a database migration should be run. If a database migration is required, Gitea will take some time to complete the upgrade and then serve. +## Check the Changelog for breaking changes + +To make Gitea better, some breaking changes are unavoidable, especially for big milestone releases. +Before upgrade, please read the [Changelog on Gitea blog](https://blog.gitea.io/) +and check whether the breaking changes affect your Gitea instance. + ## Backup for downgrade -Gitea keeps compatibility for patch versions whose first two fields are the same (`a.b.x` -> `a.b.y`), -these patch versions can be upgraded and downgraded with the same database structure. -Otherwise (`a.b.?` -> `a.c.?`), a newer Gitea version will upgrade the old database +Gitea keeps compatibility for patch versions whose first two fields are the same (`a.b.x` -> `a.b.y`), +these patch versions can be upgraded and downgraded with the same database structure. +Otherwise (`a.b.?` -> `a.c.?`), a newer Gitea version will upgrade the old database to a new structure that may differ from the old version. For example: @@ -39,8 +45,8 @@ For example: | 1.4.x | 1.5.y | ✅ Database gets upgraded. You can upgrade from 1.4.x to the latest 1.5.y directly. | | 1.5.y | 1.4.x | ❌ Database already got upgraded and can not be used for an old Gitea, use a backup to downgrade. | -**Since you can not run an old Gitea with an upgraded database, -a backup should always be made before a database upgrade.** +**Since you can not run an old Gitea with an upgraded database, +a backup should always be made before a database upgrade.** If you use Gitea in production, it's always highly recommended to make a backup before upgrade, even if the upgrade is between patch versions. @@ -56,7 +62,6 @@ Backup steps: If you are using cloud services or filesystems with snapshot feature, a snapshot for the Gitea data volume and related object storage is more convenient. - ## Upgrade with Docker * `docker pull` the latest Gitea release. @@ -73,16 +78,16 @@ a snapshot for the Gitea data volume and related object storage is more convenie * Download the latest Gitea binary to a temporary directory. * Stop the running instance, backup data. -* Replace the installed Gitea binary with the downloaded one. +* Replace the installed Gitea binary with the downloaded one. * Start the Gitea instance. A script automating these steps for a deployment on Linux can be found at [`contrib/upgrade.sh` in Gitea's source tree](https://github.com/go-gitea/gitea/blob/main/contrib/upgrade.sh). ## Take care about customized templates -Gitea's template structure and variables may change between releases, if you are using customized templates, -do pay attention if your templates are compatible with the Gitea you are using. +Gitea's template structure and variables may change between releases, if you are using customized templates, +do pay attention if your templates are compatible with the Gitea you are using. -If the customized templates don't match Gitea version, you may experience: -`50x` server error, page components missing or malfunctioning, strange page layout, ... +If the customized templates don't match Gitea version, you may experience: +`50x` server error, page components missing or malfunctioning, strange page layout, ... Remove or update the incompatible templates and Gitea web will work again. diff --git a/docs/content/doc/usage/backup-and-restore.en-us.md b/docs/content/doc/usage/backup-and-restore.en-us.md index 95e6d376d09d2..c9c41c413c771 100644 --- a/docs/content/doc/usage/backup-and-restore.en-us.md +++ b/docs/content/doc/usage/backup-and-restore.en-us.md @@ -74,7 +74,7 @@ The command has to be executed with the `RUN_USER = ` specified in Example: ```none -docker exec -u -it -w <--tempdir> $(docker ps -qf 'name=^$') bash -c '/user/local/bin/gitea dump -c ' +docker exec -u -it -w <--tempdir> $(docker ps -qf 'name=^$') bash -c '/usr/local/bin/gitea dump -c ' ``` \*Note: `--tempdir` refers to the temporary directory of the docker environment used by Gitea; if you have not specified a custom `--tempdir`, then Gitea uses `/tmp` or the `TMPDIR` environment variable of the docker container. For `--tempdir` adjust your `docker exec` command options accordingly. diff --git a/docs/content/doc/usage/backup-and-restore.zh-tw.md b/docs/content/doc/usage/backup-and-restore.zh-tw.md index 152d0a19b730c..18e244b19c69d 100644 --- a/docs/content/doc/usage/backup-and-restore.zh-tw.md +++ b/docs/content/doc/usage/backup-and-restore.zh-tw.md @@ -45,6 +45,7 @@ Gitea 目前支援 `dump` 指令,用來將資料備份成 zip 檔案,後續 持續更新中: 此文件尚未完成. 例: + ```sh unzip gitea-dump-1610949662.zip cd gitea-dump-1610949662 diff --git a/docs/content/doc/usage/command-line.en-us.md b/docs/content/doc/usage/command-line.en-us.md index 8cc420ed11b1f..5f05bc4c3be3e 100644 --- a/docs/content/doc/usage/command-line.en-us.md +++ b/docs/content/doc/usage/command-line.en-us.md @@ -364,7 +364,7 @@ NB: Gitea must be running for this command to succeed. ### migrate -Migrates the database. This command can be used to run other commands before starting the server for the first time. +Migrates the database. This command can be used to run other commands before starting the server for the first time. This command is idempotent. ### convert @@ -522,7 +522,7 @@ Dump-repo dumps repository data from Git/GitHub/Gitea/GitLab: - Options: - `--git_service service` : Git service, it could be `git`, `github`, `gitea`, `gitlab`, If clone_addr could be recognized, this could be ignored. - - `--repo_dir dir`, `-r dir`: Repository dir path to store the data + - `--repo_dir dir`, `-r dir`: Repository dir path to store the data - `--clone_addr addr`: The URL will be clone, currently could be a git/github/gitea/gitlab http/https URL. i.e. https://github.com/lunny/tango.git - `--auth_username lunny`: The username to visit the clone_addr - `--auth_password `: The password to visit the clone_addr diff --git a/docs/content/doc/usage/email-setup.en-us.md b/docs/content/doc/usage/email-setup.en-us.md index df1b8545af5dc..533e0fe1a8f9c 100644 --- a/docs/content/doc/usage/email-setup.en-us.md +++ b/docs/content/doc/usage/email-setup.en-us.md @@ -60,9 +60,10 @@ To send a test email to validate the settings, go to Gitea > Site Administration For the full list of options check the [Config Cheat Sheet]({{< relref "doc/advanced/config-cheat-sheet.en-us.md" >}}) Please note: authentication is only supported when the SMTP server communication is encrypted with TLS or `HOST=localhost`. TLS encryption can be through: - - STARTTLS (also known as Opportunistic TLS) via port 587. Initial connection is done over cleartext, but then be upgraded over TLS if the server supports it. - - SMTPS connection (SMTP over TLS) via the default port 465. Connection to the server use TLS from the beginning. - - Forced SMTPS connection with `IS_TLS_ENABLED=true`. (These are both known as Implicit TLS.) + +- STARTTLS (also known as Opportunistic TLS) via port 587. Initial connection is done over cleartext, but then be upgraded over TLS if the server supports it. +- SMTPS connection (SMTP over TLS) via the default port 465. Connection to the server use TLS from the beginning. +- Forced SMTPS connection with `IS_TLS_ENABLED=true`. (These are both known as Implicit TLS.) This is due to protections imposed by the Go internal libraries against STRIPTLS attacks. Note that Implicit TLS is recommended by [RFC8314](https://tools.ietf.org/html/rfc8314#section-3) since 2018. @@ -82,4 +83,3 @@ MAILER_TYPE = smtp IS_TLS_ENABLED = true HELO_HOSTNAME = example.com ``` - diff --git a/docs/content/doc/usage/fail2ban-setup.en-us.md b/docs/content/doc/usage/fail2ban-setup.en-us.md index d1ff633246e40..f00551e3efa92 100644 --- a/docs/content/doc/usage/fail2ban-setup.en-us.md +++ b/docs/content/doc/usage/fail2ban-setup.en-us.md @@ -29,31 +29,37 @@ on a bad authentication from the web or CLI using SSH or HTTP respectively: ```log 2020/10/15 16:05:09 modules/ssh/ssh.go:143:publicKeyHandler() [W] Failed authentication attempt from xxx.xxx.xxx.xxx ``` + (DEPRECATED: This may be a false positive as the user may still go on to correctly authenticate.) ```log 2020/10/15 16:05:09 modules/ssh/ssh.go:155:publicKeyHandler() [W] Failed authentication attempt from xxx.xxx.xxx.xxx ``` + (DEPRECATED: This may be a false positive as the user may still go on to correctly authenticate.) ```log 2020/10/15 16:05:09 modules/ssh/ssh.go:198:publicKeyHandler() [W] Failed authentication attempt from xxx.xxx.xxx.xxx ``` + (DEPRECATED: This may be a false positive as the user may still go on to correctly authenticate.) ```log 2020/10/15 16:05:09 modules/ssh/ssh.go:213:publicKeyHandler() [W] Failed authentication attempt from xxx.xxx.xxx.xxx ``` + (DEPRECATED: This may be a false positive as the user may still go on to correctly authenticate.) ```log 2020/10/15 16:05:09 modules/ssh/ssh.go:227:publicKeyHandler() [W] Failed authentication attempt from xxx.xxx.xxx.xxx ``` + (DEPRECATED: This may be a false positive as the user may still go on to correctly authenticate.) ```log 2020/10/15 16:05:09 modules/ssh/ssh.go:249:sshConnectionFailed() [W] Failed authentication attempt from xxx.xxx.xxx.xxx ``` + (From 1.15 this new message will available and doesn't have any of the false positive results that above messages from publicKeyHandler do. This will only be logged if the user has completely failed authentication.) ```log diff --git a/docs/content/doc/usage/fail2ban-setup.zh-cn.md b/docs/content/doc/usage/fail2ban-setup.zh-cn.md new file mode 100644 index 0000000000000..446d192aa619f --- /dev/null +++ b/docs/content/doc/usage/fail2ban-setup.zh-cn.md @@ -0,0 +1,92 @@ +--- +date: "2022-08-01T00:00:00+00:00" +title: "使用: 设置 Fail2ban" +slug: "fail2ban-setup" +weight: 16 +toc: false +draft: false +menu: + sidebar: + parent: "usage" + name: "设置 Fail2ban" + weight: 16 + identifier: "fail2ban-setup" +--- + +# 使用 Fail2ban 阻止攻击者的暴力登录 + +**Fail2ban 检查客户端登录日志,将多次登录失败的客户端识别为攻击者并在一段时间内阻止其访问服务。如果你的实例是公开的,这一点尤其重要。请管理员仔细设置 fail2ban,错误的配置将导致防火墙阻止你访问自己的服务器。** + +Gitea 会在日志文件 `log/gitea.log` 中记录登录失败的 CLI、SSH 或 HTTP 客户端 IP 地址,而你需要将 Gitea 的日志输出模式从默认的 `console` 更改为 `file`。这表示将日志输出到文件,使得 fail2ban 可以定期扫描日志内容。 + +当用户的身份验证失败时,日志中会记录此类信息: + +```log +2018/04/26 18:15:54 [I] Failed authentication attempt for user from xxx.xxx.xxx.xxx +``` + +```log +2020/10/15 16:08:44 [E] invalid credentials from xxx.xxx.xxx.xxx +``` + +## 设置 Fail2ban + +添加日志过滤器规则到配置文件 `/etc/fail2ban/filter.d/gitea.conf`: + +```ini +[Definition] +failregex = .*(Failed authentication attempt|invalid credentials|Attempted access of unknown user).* from +ignoreregex = +``` + +添加监狱规则到配置文件 `/etc/fail2ban/jail.d/gitea.conf`: + +```ini +[gitea] +enabled = true +filter = gitea +logpath = /var/lib/gitea/log/gitea.log +maxretry = 10 +findtime = 3600 +bantime = 900 +action = iptables-allports +``` + +如果你的 Gitea 实例运行在 Docker 容器中,并且直接将容器端口暴露到外部网络, +你还需要添加 `chain="FORWARD"` 到监狱规则配置文件 `/etc/fail2ban/jail.d/gitea-docker.conf` +以适应 Docker 的网络转发规则。但如果你在容器的宿主机上使用 Nginx 反向代理连接到 Gitea 则无需这样配置。 + +```ini +[gitea-docker] +enabled = true +filter = gitea +logpath = /var/lib/gitea/log/gitea.log +maxretry = 10 +findtime = 3600 +bantime = 900 +action = iptables-allports[chain="FORWARD"] +``` + +最后,运行 `systemctl restart fail2ban` 即可应用更改。现在,你可以使用 `systemctl status fail2ban` 检查 fail2ban 运行状态。 + +上述规则规定客户端在 1 小时内,如果登录失败的次数达到 10 次,则通过 iptables 锁定该客户端 IP 地址 15 分钟。 + +## 设置反向代理 + +如果你使用 Nginx 反向代理到 Gitea 实例,你还需要设置 Nginx 的 HTTP 头部值 `X-Real-IP` 将真实的客户端 IP 地址传递给 Gitea。否则 Gitea 程序会将客户端地址错误解析为反向代理服务器的地址,例如回环地址 `127.0.0.1`。 + +``` +proxy_set_header X-Real-IP $remote_addr; +``` + +额外注意,在 Gitea 的配置文件 `app.ini` 中存在下列默认值: + +``` +REVERSE_PROXY_LIMIT = 1 +REVERSE_PROXY_TRUSTED_PROXIES = 127.0.0.0/8,::1/128 +``` + +`REVERSE_PROXY_LIMIT` 限制反向代理服务器的层数,设置为 `0` 表示不使用这些标头。 +`REVERSE_PROXY_TRUSTED_PROXIES` 表示受信任的反向代理服务器网络地址, +经过该网络地址转发来的流量会经过解析 `X-Real-IP` 头部得到真实客户端地址。 +(参考 [configuration cheat sheet](https://docs.gitea.io/en-us/config-cheat-sheet/#security-security)) diff --git a/docs/content/doc/usage/https-support.md b/docs/content/doc/usage/https-support.md index 756e11fd03e29..783d6d803774f 100644 --- a/docs/content/doc/usage/https-support.md +++ b/docs/content/doc/usage/https-support.md @@ -60,6 +60,7 @@ If you are using Docker, make sure that this port is configured in your `docker- [ACME](https://tools.ietf.org/html/rfc8555) is a Certificate Authority standard protocol that allows you to automatically request and renew SSL/TLS certificates. [Let's Encrypt](https://letsencrypt.org/) is a free publicly trusted Certificate Authority server using this standard. Only `HTTP-01` and `TLS-ALPN-01` challenges are implemented. In order for ACME challenges to pass and verify your domain ownership, external traffic to the gitea domain on port `80` (`HTTP-01`) or port `443` (`TLS-ALPN-01`) has to be served by the gitea instance. Setting up [HTTP redirection](#setting-up-http-redirection) and port-forwards might be needed for external traffic to route correctly. Normal traffic to port `80` will otherwise be automatically redirected to HTTPS. **You must consent** to the ACME provider's terms of service (default Let's Encrypt's [terms of service](https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf)). Minimum setup using the default Let's Encrypt: + ```ini [server] PROTOCOL=https @@ -72,6 +73,7 @@ ACME_EMAIL=email@example.com ``` Minimumg setup using a [smallstep CA](https://github.com/smallstep/certificates), refer to [their tutorial](https://smallstep.com/docs/tutorials/acme-challenge) for more information. + ```ini [server] PROTOCOL=https diff --git a/docs/content/doc/usage/issue-pull-request-templates.zh-cn.md b/docs/content/doc/usage/issue-pull-request-templates.zh-cn.md index 1d2539b7bd19f..db69f3e5ce6cb 100644 --- a/docs/content/doc/usage/issue-pull-request-templates.zh-cn.md +++ b/docs/content/doc/usage/issue-pull-request-templates.zh-cn.md @@ -26,7 +26,6 @@ menu: * .github/ISSUE_TEMPLATE.md * .github/issue_template.md - 以下罗列了一些可供参考的 PR 模板: * PULL_REQUEST_TEMPLATE.md diff --git a/docs/content/doc/usage/permissions.en-us.md b/docs/content/doc/usage/permissions.en-us.md index 0c3dc9e09e736..013dbfabd4570 100644 --- a/docs/content/doc/usage/permissions.en-us.md +++ b/docs/content/doc/usage/permissions.en-us.md @@ -55,7 +55,7 @@ And there are some differences for permissions between individual repositories a ## Individual Repository -For individual repositories, the creators are the only owners of repositories and have no limit to change anything of this +For individual repositories, the creators are the only owners of repositories and have no limit to change anything of this repository or delete it. Repositories owners could add collaborators to help maintain the repositories. Collaborators could have `Read`, `Write` and `Admin` permissions. ## Organization Repository diff --git a/docs/content/doc/usage/push-options.en-us.md b/docs/content/doc/usage/push-options.en-us.md index 6539c9d7cd527..8d7de19609c83 100644 --- a/docs/content/doc/usage/push-options.en-us.md +++ b/docs/content/doc/usage/push-options.en-us.md @@ -18,14 +18,16 @@ menu: In Gitea `1.13`, support for some [push options](https://git-scm.com/docs/git-push#Documentation/git-push.txt--oltoptiongt) were added. - ## Supported Options -- `repo.private` (true|false) - Change the repository's visibility. -This is particularly useful when combined with push-to-create. +- `repo.private` (true|false) - Change the repository's visibility. + + This is particularly useful when combined with push-to-create. + - `repo.template` (true|false) - Change whether the repository is a template. -Example of changing a repository's visibility to public: +Example of changing a repository's visibility to public: + ```shell git push -o repo.private=false -u origin master ``` diff --git a/docs/content/doc/usage/push-options.zh-tw.md b/docs/content/doc/usage/push-options.zh-tw.md index b0fc75ac24129..d6ffbe695b401 100644 --- a/docs/content/doc/usage/push-options.zh-tw.md +++ b/docs/content/doc/usage/push-options.zh-tw.md @@ -20,8 +20,10 @@ Gitea 從 `1.13` 版開始支援某些 [push options](https://git-scm.com/docs/g ## 支援的 Options -- `repo.private` (true|false) - 修改儲存庫的可見性。 +- `repo.private` (true|false) - 修改儲存庫的可見性。 + 與 push-to-create 一起使用時特別有用。 + - `repo.template` (true|false) - 修改儲存庫是否為範本儲存庫。 以下範例修改儲存庫的可見性為公開: diff --git a/docs/content/doc/usage/reverse-proxies.en-us.md b/docs/content/doc/usage/reverse-proxies.en-us.md index 9e903f4259436..5797d8e5eb8f0 100644 --- a/docs/content/doc/usage/reverse-proxies.en-us.md +++ b/docs/content/doc/usage/reverse-proxies.en-us.md @@ -138,7 +138,6 @@ In your nginx config file containing your Gitea proxy directive, find the `locat `client_max_body_size 16M;` to set this limit to 16 megabytes or any other number of choice. If you use Git LFS, this will also limit the size of the largest file you will be able to push. - ## Apache HTTPD If you want Apache HTTPD to serve your Gitea instance, you can add the following to your Apache HTTPD configuration (usually located at `/etc/apache2/httpd.conf` in Ubuntu): @@ -307,6 +306,7 @@ If you wish to run Gitea with IIS. You will need to setup IIS with URL Rewrite a If you want HAProxy to serve your Gitea instance, you can add the following to your HAProxy configuration add an acl in the frontend section to redirect calls to gitea.example.com to the correct backend + ``` frontend http-in ... @@ -316,6 +316,7 @@ frontend http-in ``` add the previously defined backend section + ``` backend gitea server localhost:3000 check @@ -338,6 +339,7 @@ frontend http-in With that configuration http://example.com/gitea/ will redirect to your Gitea instance. then for the backend section + ``` backend gitea http-request replace-path /gitea\/?(.*) \/\1 diff --git a/docs/content/doc/usage/reverse-proxies.zh-cn.md b/docs/content/doc/usage/reverse-proxies.zh-cn.md index 88db0c3790306..722b9c7c9db91 100644 --- a/docs/content/doc/usage/reverse-proxies.zh-cn.md +++ b/docs/content/doc/usage/reverse-proxies.zh-cn.md @@ -121,4 +121,4 @@ gitea: - "traefik.http.services.gitea-websecure.loadbalancer.server.port=3000" ``` -这份配置假设您使用 traefik 来处理 HTTPS 服务,并在其和 Gitea 之间使用 HTTP 进行通信。 \ No newline at end of file +这份配置假设您使用 traefik 来处理 HTTPS 服务,并在其和 Gitea 之间使用 HTTP 进行通信。 diff --git a/docs/content/doc/usage/template-repositories.md b/docs/content/doc/usage/template-repositories.md index 24fdf28ee091f..9a2a23ed2b032 100644 --- a/docs/content/doc/usage/template-repositories.md +++ b/docs/content/doc/usage/template-repositories.md @@ -19,8 +19,10 @@ menu: {{< toc >}} -Gitea `1.11.0` and above includes template repositories, and one feature implemented with them is auto-expansion of specific variables within your template files. -To tell Gitea which files to expand, you must include a `template` file inside the `.gitea` directory of the template repository. +Gitea `1.11.0` and above includes template repositories, and one feature implemented with them is auto-expansion of specific variables within your template files. + +To tell Gitea which files to expand, you must include a `template` file inside the `.gitea` directory of the template repository. + Gitea uses [gobwas/glob](https://github.com/gobwas/glob) for its glob syntax. It closely resembles a traditional `.gitignore`, however there may be slight differences. ## Example `.gitea/template` file @@ -45,7 +47,8 @@ a/b/c/d.json ## Variable Expansion -In any file matched by the above globs, certain variables will be expanded. +In any file matched by the above globs, certain variables will be expanded. + All variables must be of the form `$VAR` or `${VAR}`. To escape an expansion, use a double `$$`, such as `$$VAR` or `$${VAR}` | Variable | Expands To | Transformable | @@ -65,7 +68,8 @@ All variables must be of the form `$VAR` or `${VAR}`. To escape an expansion, us ## Transformers :robot: -Gitea `1.12.0` adds a few transformers to some of the applicable variables above. +Gitea `1.12.0` adds a few transformers to some of the applicable variables above. + For example, to get `REPO_NAME` in `PASCAL`-case, your template would use `${REPO_NAME_PASCAL}` Feeding `go-sdk` to the available transformers yields... diff --git a/docs/content/page/index.de-de.md b/docs/content/page/index.de-de.md index e901702969f66..8f8f264ed12ab 100644 --- a/docs/content/page/index.de-de.md +++ b/docs/content/page/index.de-de.md @@ -10,27 +10,28 @@ draft: false # Was ist Gitea? -Gitea ist ein einfacher, selbst gehosteter Git-Service. Änlich wie GitHub, Bitbucket oder GitLab. +Gitea ist ein einfacher, selbst gehosteter Git-Service. Änlich wie GitHub, Bitbucket oder GitLab. + Gitea ist ein [Gogs](http://gogs.io)-Fork. ## Ziele - * Einfach zu installieren - * Plattformübergreifend - * Leichtgewichtig - * Quelloffen +* Einfach zu installieren +* Plattformübergreifend +* Leichtgewichtig +* Quelloffen ## System Voraussetzungen -- Ein Raspberry Pi 3 ist leistungsstark genug, um Gitea für kleine Belastungen laufen zu lassen. -- 2 CPU Kerne und 1GB RAM sind für kleine Teams/Projekte ausreichend. -- Gitea sollte unter einem seperaten nicht-root Account auf UNIX-Systemen ausgeführt werden. - - Achtung: Gitea verwaltet die `~/.ssh/authorized_keys` Datei. Gitea unter einem normalen Benutzer auszuführen könnte dazu führen, dass dieser sich nicht mehr anmelden kann. -- [Git](https://git-scm.com/) Version 2.0 oder später wird benötigt. - - Wenn git >= 2.1.2. und [Git large file storage](https://git-lfs.github.com/) aktiviert ist, dann wird es auch in Gitea verwendbar sein. - - Wenn git >= 2.18, dann wird das Rendern von Commit-Graphen automatisch aktiviert. +* Ein Raspberry Pi 3 ist leistungsstark genug, um Gitea für kleine Belastungen laufen zu lassen. +* 2 CPU Kerne und 1GB RAM sind für kleine Teams/Projekte ausreichend. +* Gitea sollte unter einem seperaten nicht-root Account auf UNIX-Systemen ausgeführt werden. + * Achtung: Gitea verwaltet die `~/.ssh/authorized_keys` Datei. Gitea unter einem normalen Benutzer auszuführen könnte dazu führen, dass dieser sich nicht mehr anmelden kann. +* [Git](https://git-scm.com/) Version 2.0 oder später wird benötigt. + * Wenn git >= 2.1.2. und [Git large file storage](https://git-lfs.github.com/) aktiviert ist, dann wird es auch in Gitea verwendbar sein. + * Wenn git >= 2.18, dann wird das Rendern von Commit-Graphen automatisch aktiviert. ## Browser Unterstützung -- Letzten 2 Versions von Chrome, Firefox, Safari und Edge -- Firefox ESR +* Letzten 2 Versions von Chrome, Firefox, Safari und Edge +* Firefox ESR diff --git a/docs/content/page/index.en-us.md b/docs/content/page/index.en-us.md index c3a43cd029dbf..8e2e36223ad00 100644 --- a/docs/content/page/index.en-us.md +++ b/docs/content/page/index.en-us.md @@ -17,50 +17,53 @@ blog post to read about the justification for a fork. ## Purpose The goal of this project is to provide the easiest, fastest, and most painless way of setting -up a self-hosted Git service. With Go, this can be done with an independent binary distribution -across all platforms and architectures that Go supports. This support includes Linux, macOS, and -Windows, on architectures like amd64, i386, ARM, PowerPC, and others. +up a self-hosted Git service. + +With Go, this can be done platform-independently across +**all platforms** which Go supports, including Linux, macOS, and Windows, +on x86, amd64, ARM and PowerPC architectures. +You can try it out using [the online demo](https://try.gitea.io/). ## Features - User Dashboard - - Context switcher (organization or current user) - - Activity timeline - - Commits - - Issues - - Pull requests - - Repository creation - - Searchable repository list - - List of organizations - - A list of mirror repositories + - Context switcher (organization or current user) + - Activity timeline + - Commits + - Issues + - Pull requests + - Repository creation + - Searchable repository list + - List of organizations + - A list of mirror repositories - Issues dashboard - - Context switcher (organization or current user) - - Filter by - - Open - - Closed - - Your repositories - - Assigned issues - - Your issues - - Repository - - Sort by - - Oldest - - Last updated - - Number of comments + - Context switcher (organization or current user) + - Filter by + - Open + - Closed + - Your repositories + - Assigned issues + - Your issues + - Repository + - Sort by + - Oldest + - Last updated + - Number of comments - Pull request dashboard - - Same as issue dashboard + - Same as issue dashboard - Repository types - - Mirror - - Normal - - Migrated + - Mirror + - Normal + - Migrated - Notifications (email and web) - - Read - - Unread - - Pin + - Read + - Unread + - Pin - Explore page - - Users - - Repos - - Organizations - - Search + - Users + - Repos + - Organizations + - Search - Custom templates - Override public files (logo, css, etc) - CSRF and XSS protection @@ -68,187 +71,187 @@ Windows, on architectures like amd64, i386, ARM, PowerPC, and others. - Set allowed upload sizes and types - Logging - Configuration - - Databases - - MySQL (>=5.7) - - PostgreSQL (>=10) - - SQLite3 - - MSSQL (>=2008R2 SP3) - - TiDB (MySQL protocol) - - Configuration file - - [app.ini](https://github.com/go-gitea/gitea/blob/main/custom/conf/app.example.ini) - - Admin panel - - Statistics - - Actions - - Delete inactive accounts - - Delete cached repository archives - - Delete repositories records which are missing their files - - Run garbage collection on repositories - - Rewrite SSH keys - - Resync hooks - - Recreate repositories which are missing - - Server status - - Uptime - - Memory - - Current # of goroutines - - And more - - User management - - Search - - Sort - - Last login - - Authentication source - - Maximum repositories - - Disable account - - Admin permissions - - Permission to create Git Hooks - - Permission to create organizations - - Permission to import repositories - - Organization management - - People - - Teams - - Avatar - - Hooks - - Repository management - - See all repository information and manage repositories - - Authentication sources - - OAuth - - PAM - - LDAP - - SMTP - - Configuration viewer - - Everything in config file - - System notices - - When something unexpected happens - - Monitoring - - Current processes - - Cron jobs - - Update mirrors - - Repository health check - - Check repository statistics - - Clean up old archives - - Environment variables - - Command line options + - Databases + - MySQL (>=5.7) + - PostgreSQL (>=10) + - SQLite3 + - MSSQL (>=2008R2 SP3) + - TiDB (MySQL protocol) + - Configuration file + - [app.ini](https://github.com/go-gitea/gitea/blob/main/custom/conf/app.example.ini) + - Admin panel + - Statistics + - Actions + - Delete inactive accounts + - Delete cached repository archives + - Delete repositories records which are missing their files + - Run garbage collection on repositories + - Rewrite SSH keys + - Resync hooks + - Recreate repositories which are missing + - Server status + - Uptime + - Memory + - Current # of goroutines + - And more + - User management + - Search + - Sort + - Last login + - Authentication source + - Maximum repositories + - Disable account + - Admin permissions + - Permission to create Git Hooks + - Permission to create organizations + - Permission to import repositories + - Organization management + - People + - Teams + - Avatar + - Hooks + - Repository management + - See all repository information and manage repositories + - Authentication sources + - OAuth + - PAM + - LDAP + - SMTP + - Configuration viewer + - Everything in config file + - System notices + - When something unexpected happens + - Monitoring + - Current processes + - Cron jobs + - Update mirrors + - Repository health check + - Check repository statistics + - Clean up old archives + - Environment variables + - Command line options - Multi-language support ([21 languages](https://github.com/go-gitea/gitea/tree/main/options/locale)) - [Mermaid](https://mermaidjs.github.io/) Diagram support - Mail service - - Notifications - - Registration confirmation - - Password reset + - Notifications + - Registration confirmation + - Password reset - Reverse proxy support - - Includes subpaths + - Includes subpaths - Users - - Profile - - Name - - Username - - Email - - Website - - Join date - - Followers and following - - Organizations - - Repositories - - Activity - - Starred repositories - - Settings - - Same as profile and more below - - Keep email private - - Avatar - - Gravatar - - Libravatar - - Custom - - Password - - Multiple email addresses - - SSH Keys - - Connected applications - - Two factor authentication - - Linked OAuth2 sources - - Delete account + - Profile + - Name + - Username + - Email + - Website + - Join date + - Followers and following + - Organizations + - Repositories + - Activity + - Starred repositories + - Settings + - Same as profile and more below + - Keep email private + - Avatar + - Gravatar + - Libravatar + - Custom + - Password + - Multiple email addresses + - SSH Keys + - Connected applications + - Two factor authentication + - Linked OAuth2 sources + - Delete account - Repositories - - Clone with SSH/HTTP/HTTPS - - Git LFS - - Watch, Star, Fork - - View watchers, stars, and forks - - Code - - Branch browser - - Web based file upload and creation - - Clone urls - - Download - - ZIP - - TAR.GZ - - Web based editor - - Markdown editor - - Plain text editor - - Syntax highlighting - - Diff preview - - Preview - - Choose where to commit to - - View file history - - Delete file - - View raw - - Issues - - Issue templates - - Milestones - - Labels - - Assign issues - - Track time - - Reactions - - Filter - - Open - - Closed - - Assigned person - - Created by you - - Mentioning you - - Sort - - Oldest - - Last updated - - Number of comments - - Search - - Comments - - Attachments - - Pull requests - - Same features as issues - - Commits - - Commit graph - - Commits by branch - - Search - - Search in all branches - - View diff - - View SHA - - View author - - Browse files in commit - - Releases - - Attachments - - Title - - Content - - Delete - - Mark as pre-release - - Choose branch - - Wiki - - Import - - Markdown editor - - Settings - - Options - - Name - - Description - - Private/Public - - Website - - Wiki - - Enabled/disabled - - Internal/external - - Issues - - Enabled/disabled - - Internal/external - - External supports url rewriting for better integration - - Enable/disable pull requests - - Transfer repository - - Delete wiki - - Delete repository - - Collaboration - - Read/write/admin - - Branches - - Default branch - - Branch protection - - Webhooks - - Git Hooks - - Deploy keys + - Clone with SSH/HTTP/HTTPS + - Git LFS + - Watch, Star, Fork + - View watchers, stars, and forks + - Code + - Branch browser + - Web based file upload and creation + - Clone urls + - Download + - ZIP + - TAR.GZ + - Web based editor + - Markdown editor + - Plain text editor + - Syntax highlighting + - Diff preview + - Preview + - Choose where to commit to + - View file history + - Delete file + - View raw + - Issues + - Issue templates + - Milestones + - Labels + - Assign issues + - Track time + - Reactions + - Filter + - Open + - Closed + - Assigned person + - Created by you + - Mentioning you + - Sort + - Oldest + - Last updated + - Number of comments + - Search + - Comments + - Attachments + - Pull requests + - Same features as issues + - Commits + - Commit graph + - Commits by branch + - Search + - Search in all branches + - View diff + - View SHA + - View author + - Browse files in commit + - Releases + - Attachments + - Title + - Content + - Delete + - Mark as pre-release + - Choose branch + - Wiki + - Import + - Markdown editor + - Settings + - Options + - Name + - Description + - Private/Public + - Website + - Wiki + - Enabled/disabled + - Internal/external + - Issues + - Enabled/disabled + - Internal/external + - External supports url rewriting for better integration + - Enable/disable pull requests + - Transfer repository + - Delete wiki + - Delete repository + - Collaboration + - Read/write/admin + - Branches + - Default branch + - Branch protection + - Webhooks + - Git Hooks + - Deploy keys - Package Registries - Composer - Conan @@ -266,10 +269,10 @@ Windows, on architectures like amd64, i386, ARM, PowerPC, and others. - A Raspberry Pi 3 is powerful enough to run Gitea for small workloads. - 2 CPU cores and 1GB RAM is typically sufficient for small teams/projects. - Gitea should be run with a dedicated non-root system account on UNIX-type systems. - - Note: Gitea manages the `~/.ssh/authorized_keys` file. Running Gitea as a regular user could break that user's ability to log in. + - Note: Gitea manages the `~/.ssh/authorized_keys` file. Running Gitea as a regular user could break that user's ability to log in. - [Git](https://git-scm.com/) version 2.0.0 or later is required. - - [Git Large File Storage](https://git-lfs.github.com/) will be available if enabled when Git >= 2.1.2. - - Git commit-graph rendering will be enabled automatically when Git >= 2.18. + - [Git Large File Storage](https://git-lfs.github.com/) will be available if enabled and if your Git version is >= 2.1.2 + - Git commit-graph rendering will be enabled automatically if your Git version is >= 2.18 ## Browser Support @@ -278,22 +281,22 @@ Windows, on architectures like amd64, i386, ARM, PowerPC, and others. ## Components -* Web server framework: [Chi](http://github.com/go-chi/chi) -* ORM: [XORM](https://xorm.io) -* UI frameworks: - * [jQuery](https://jquery.com) - * [Fomantic UI](https://fomantic-ui.com) - * [Vue2](https://vuejs.org) - * and various components (see package.json) -* Editors: - * [CodeMirror](https://codemirror.net) - * [EasyMDE](https://github.com/Ionaru/easy-markdown-editor) - * [Monaco Editor](https://microsoft.github.io/monaco-editor) -* Database drivers: - * [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql) - * [github.com/lib/pq](https://github.com/lib/pq) - * [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3) - * [github.com/denisenkom/go-mssqldb](https://github.com/denisenkom/go-mssqldb) +- Web server framework: [Chi](http://github.com/go-chi/chi) +- ORM: [XORM](https://xorm.io) +- UI frameworks: + - [jQuery](https://jquery.com) + - [Fomantic UI](https://fomantic-ui.com) + - [Vue2](https://vuejs.org) + - and various components (see package.json) +- Editors: + - [CodeMirror](https://codemirror.net) + - [EasyMDE](https://github.com/Ionaru/easy-markdown-editor) + - [Monaco Editor](https://microsoft.github.io/monaco-editor) +- Database drivers: + - [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql) + - [github.com/lib/pq](https://github.com/lib/pq) + - [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3) + - [github.com/denisenkom/go-mssqldb](https://github.com/denisenkom/go-mssqldb) ## Software and Service Support diff --git a/docs/content/page/index.fr-fr.md b/docs/content/page/index.fr-fr.md index b3828c7141330..39d7ff8df388c 100755 --- a/docs/content/page/index.fr-fr.md +++ b/docs/content/page/index.fr-fr.md @@ -19,43 +19,43 @@ Le but de ce projet est de fournir de la manière la plus simple, la plus rapide ## Fonctionalités - Tableau de bord de l'utilisateur - - Choix du contexte (organisation ou utilisateur actuel) - - Chronologie de l'activité - - Révisions (_Commits_) - - Tickets - - Demande d'ajout (_Pull request_) - - Création de dépôts - - Liste des dépôts - - Liste de vos organisations - - Liste des dépôts miroires + - Choix du contexte (organisation ou utilisateur actuel) + - Chronologie de l'activité + - Révisions (_Commits_) + - Tickets + - Demande d'ajout (_Pull request_) + - Création de dépôts + - Liste des dépôts + - Liste de vos organisations + - Liste des dépôts miroires - Tableau de bord des tickets - - Choix du contexte (organisation ou utilisateur actuel) - - Filtres - - Ouvert - - Fermé - - Vos dépôts - - Tickets assignés - - Vos tickets - - Dépôts - - Options de tri - - Plus vieux - - Dernière mise à jour - - Nombre de commentaires + - Choix du contexte (organisation ou utilisateur actuel) + - Filtres + - Ouvert + - Fermé + - Vos dépôts + - Tickets assignés + - Vos tickets + - Dépôts + - Options de tri + - Plus vieux + - Dernière mise à jour + - Nombre de commentaires - Tableau de bord des demandes d'ajout - - Identique au tableau de bord des tickets + - Identique au tableau de bord des tickets - Types de dépôt - - Miroire - - Normal - - Migré + - Miroire + - Normal + - Migré - Notifications (courriel et web) - - Lu - - Non lu - - Épinglé + - Lu + - Non lu + - Épinglé - Page d'exploration - - Utilisateurs - - Dépôts - - Organisations - - Moteur de recherche + - Utilisateurs + - Dépôts + - Organisations + - Moteur de recherche - Interface personnalisables - Fichiers publiques remplaçables (logo, css, etc) - Protection CSRF et XSS @@ -63,183 +63,183 @@ Le but de ce projet est de fournir de la manière la plus simple, la plus rapide - Configuration des types et de la taille maximale des fichiers téléversés - Journalisation (_Log_) - Configuration - - Base de données - - MySQL - - PostgreSQL - - SQLite3 - - MSSQL - - [TiDB](https://github.com/pingcap/tidb) (MySQL protocol) - - Fichier de configuration - - Voir [ici](https://github.com/go-gitea/gitea/blob/master/custom/conf/app.example.ini) - - Panel d'administration - - Statistiques - - Actions - - Suppression des comptes inactifs - - Suppression des dépôts archivés - - Suppression des dépôts pour lesquels il manque leurs fichiers - - Exécution du _garbage collector_ sur les dépôts - - Ré-écriture des clefs SSH - - Resynchronisation des hooks - - Recreation des dépôts manquants - - Status du server - - Temps de disponibilité - - Mémoire - - Nombre de goroutines - - et bien plus... - - Gestion des utilisateurs - - Recherche - - Tri - - Dernière connexion - - Méthode d'authentification - - Nombre maximum de dépôts - - Désactivation du compte - - Permissions d'administration - - Permission pour crééer des hooks - - Permission pour crééer des organisations - - Permission pour importer des dépôts - - Gestion des organisations - - Membres - - Équipes - - Avatar - - Hooks - - Gestion des depôts - - Voir toutes les informations pour un dépôt donné et gérer tous les dépôts - - Méthodes d'authentification - - OAuth - - PAM - - LDAP - - SMTP - - Visualisation de la configuration - - Tout ce que contient le fichier de configuration - - Alertes du système - - Quand quelque chose d'inattendu survient - - Surveillance - - Processus courrants - - Tâches CRON - - Mise à jour des dépôts miroires - - Vérification de l'état des dépôts - - Vérification des statistiques des dépôts - - Nettoyage des anciennes archives - - Variables d'environement - - Options de ligne de commande + - Base de données + - MySQL + - PostgreSQL + - SQLite3 + - MSSQL + - [TiDB](https://github.com/pingcap/tidb) (MySQL protocol) + - Fichier de configuration + - Voir [ici](https://github.com/go-gitea/gitea/blob/master/custom/conf/app.example.ini) + - Panel d'administration + - Statistiques + - Actions + - Suppression des comptes inactifs + - Suppression des dépôts archivés + - Suppression des dépôts pour lesquels il manque leurs fichiers + - Exécution du _garbage collector_ sur les dépôts + - Ré-écriture des clefs SSH + - Resynchronisation des hooks + - Recreation des dépôts manquants + - Status du server + - Temps de disponibilité + - Mémoire + - Nombre de goroutines + - et bien plus... + - Gestion des utilisateurs + - Recherche + - Tri + - Dernière connexion + - Méthode d'authentification + - Nombre maximum de dépôts + - Désactivation du compte + - Permissions d'administration + - Permission pour crééer des hooks + - Permission pour crééer des organisations + - Permission pour importer des dépôts + - Gestion des organisations + - Membres + - Équipes + - Avatar + - Hooks + - Gestion des depôts + - Voir toutes les informations pour un dépôt donné et gérer tous les dépôts + - Méthodes d'authentification + - OAuth + - PAM + - LDAP + - SMTP + - Visualisation de la configuration + - Tout ce que contient le fichier de configuration + - Alertes du système + - Quand quelque chose d'inattendu survient + - Surveillance + - Processus courrants + - Tâches CRON + - Mise à jour des dépôts miroires + - Vérification de l'état des dépôts + - Vérification des statistiques des dépôts + - Nettoyage des anciennes archives + - Variables d'environement + - Options de ligne de commande - Internationalisation ([21 langues](https://github.com/go-gitea/gitea/tree/master/options/locale)) - Courriel - - Notifications - - Confirmation d'inscription - - Ré-initialisation du mot de passe + - Notifications + - Confirmation d'inscription + - Ré-initialisation du mot de passe - Support de _reverse proxy_ - - _subpaths_ inclus + - _subpaths_ inclus - Utilisateurs - - Profil - - Nom - - Prénom - - Courriel - - Site internet - - Date de création - - Abonnés et abonnements - - Organisations - - Dépôts - - Activité - - Dépôts suivis - - Paramètres - - Identiques au profil avec en plus les éléments ci-dessous - - Rendre l'adresse de courriel privée - - Avatar - - Gravatar - - Libravatar - - Personnalisé - - Mot de passe - - Courriels multiples - - Clefs SSH - - Applications connectées - - Authentification à double facteurs - - Identités OAuth2 attachées - - Suppression du compte + - Profil + - Nom + - Prénom + - Courriel + - Site internet + - Date de création + - Abonnés et abonnements + - Organisations + - Dépôts + - Activité + - Dépôts suivis + - Paramètres + - Identiques au profil avec en plus les éléments ci-dessous + - Rendre l'adresse de courriel privée + - Avatar + - Gravatar + - Libravatar + - Personnalisé + - Mot de passe + - Courriels multiples + - Clefs SSH + - Applications connectées + - Authentification à double facteurs + - Identités OAuth2 attachées + - Suppression du compte - Dépôts - - Clone à partir de SSH / HTTP / HTTPS - - Git LFS - - Suivre, Voter, Fork - - Voir les personnes qui suivent, les votes et les forks - - Code - - Navigation entre les branches - - Création ou téléversement de fichier depuis le navigateur - - URLs pour clôner le dépôt - - Téléchargement - - ZIP - - TAR.GZ - - Édition en ligne - - Éditeur Markdown - - Éditeur de texte - - Coloration syntaxique - - Visualisation des Diffs - - Visualisation - - Possibilité de choisir où sauvegarder la révision - - Historiques des fichiers - - Suppression de fichiers - - Voir le fichier brut - - Tickets - - Modèle de ticket - - Jalons - - Étiquettes - - Affecter des tickets - - Filtres - - Ouvert - - Ferme - - Personne assignée - - Créer par vous - - Qui vous mentionne - - Tri - - Plus vieux - - Dernière mise à jour - - Nombre de commentaires - - Moteur de recherche - - Commentaires - - Joindre des fichiers - - Demande d’ajout (_Pull request_) - - Les mêmes fonctionnalités que pour les tickets - - Révisions (_Commits_) - - Representation graphique des révisions - - Révisions par branches - - Moteur de recherche - - Voir les différences - - Voir les numéro de révision SHA - - Voir l'auteur - - Naviguer dans les fichiers d'une révision donnée - - Publication - - Pièces jointes - - Titre - - Contenu - - Suppression - - Définir comme une pré-publication - - Choix de la branche - - Wiki - - Import - - Éditeur Markdown - - Paramètres - - Options - - Nom - - Description - - Privé / Publique - - Site internet - - Wiki - - Activé / Désactivé - - Interne / externe - - Tickets - - Activé / Désactivé - - Interne / externe - - URL personnalisable pour une meilleur intégration avec un gestionnaire de tickets externe - - Activer / désactiver les demandes d'ajout (_Pull request_) - - Transfert du dépôt - - Suppression du wiki - - Suppression du dépôt - - Collaboration - - Lecture / Écriture / Administration - - Branches - - Branche par défaut - - Protection - - Webhooks - - Git hooks - - Clefs de déploiement + - Clone à partir de SSH / HTTP / HTTPS + - Git LFS + - Suivre, Voter, Fork + - Voir les personnes qui suivent, les votes et les forks + - Code + - Navigation entre les branches + - Création ou téléversement de fichier depuis le navigateur + - URLs pour clôner le dépôt + - Téléchargement + - ZIP + - TAR.GZ + - Édition en ligne + - Éditeur Markdown + - Éditeur de texte + - Coloration syntaxique + - Visualisation des Diffs + - Visualisation + - Possibilité de choisir où sauvegarder la révision + - Historiques des fichiers + - Suppression de fichiers + - Voir le fichier brut + - Tickets + - Modèle de ticket + - Jalons + - Étiquettes + - Affecter des tickets + - Filtres + - Ouvert + - Ferme + - Personne assignée + - Créer par vous + - Qui vous mentionne + - Tri + - Plus vieux + - Dernière mise à jour + - Nombre de commentaires + - Moteur de recherche + - Commentaires + - Joindre des fichiers + - Demande d’ajout (_Pull request_) + - Les mêmes fonctionnalités que pour les tickets + - Révisions (_Commits_) + - Representation graphique des révisions + - Révisions par branches + - Moteur de recherche + - Voir les différences + - Voir les numéro de révision SHA + - Voir l'auteur + - Naviguer dans les fichiers d'une révision donnée + - Publication + - Pièces jointes + - Titre + - Contenu + - Suppression + - Définir comme une pré-publication + - Choix de la branche + - Wiki + - Import + - Éditeur Markdown + - Paramètres + - Options + - Nom + - Description + - Privé / Publique + - Site internet + - Wiki + - Activé / Désactivé + - Interne / externe + - Tickets + - Activé / Désactivé + - Interne / externe + - URL personnalisable pour une meilleur intégration avec un gestionnaire de tickets externe + - Activer / désactiver les demandes d'ajout (_Pull request_) + - Transfert du dépôt + - Suppression du wiki + - Suppression du dépôt + - Collaboration + - Lecture / Écriture / Administration + - Branches + - Branche par défaut + - Protection + - Webhooks + - Git hooks + - Clefs de déploiement ## Configuration requise @@ -253,21 +253,21 @@ Le but de ce projet est de fournir de la manière la plus simple, la plus rapide ## Composants -* Framework web : [Chi](http://github.com/go-chi/chi) -* ORM: [XORM](https://xorm.io) -* Interface graphique : - * [jQuery](https://jquery.com) - * [Fomantic UI](https://fomantic-ui.com) - * [Vue2](https://vuejs.org) - * [CodeMirror](https://codemirror.net) - * [EasyMDE](https://github.com/Ionaru/easy-markdown-editor) - * [Monaco Editor](https://microsoft.github.io/monaco-editor) - * ... (package.json) -* Connecteurs de base de données : - * [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql) - * [github.com/lib/pq](https://github.com/lib/pq) - * [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3) - * [github.com/denisenkom/go-mssqldb](https://github.com/denisenkom/go-mssqldb) +- Framework web : [Chi](http://github.com/go-chi/chi) +- ORM: [XORM](https://xorm.io) +- Interface graphique : + - [jQuery](https://jquery.com) + - [Fomantic UI](https://fomantic-ui.com) + - [Vue2](https://vuejs.org) + - [CodeMirror](https://codemirror.net) + - [EasyMDE](https://github.com/Ionaru/easy-markdown-editor) + - [Monaco Editor](https://microsoft.github.io/monaco-editor) + - ... (package.json) +- Connecteurs de base de données : + - [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql) + - [github.com/lib/pq](https://github.com/lib/pq) + - [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3) + - [github.com/denisenkom/go-mssqldb](https://github.com/denisenkom/go-mssqldb) ## Logiciels et services diff --git a/docs/content/page/index.zh-cn.md b/docs/content/page/index.zh-cn.md index d364edb2d7673..1c94f8ea788a4 100644 --- a/docs/content/page/index.zh-cn.md +++ b/docs/content/page/index.zh-cn.md @@ -47,22 +47,22 @@ Gitea的首要目标是创建一个极易安装,运行非常快速,安装和 ## 组件 -* Web框架: [Chi](http://github.com/go-chi/chi) -* ORM: [XORM](https://xorm.io) -* UI 框架: - * [jQuery](https://jquery.com) - * [Fomantic UI](https://fomantic-ui.com) - * [Vue2](https://vuejs.org) - * 更多组件参见 package.json -* 编辑器: - * [CodeMirror](https://codemirror.net) - * [EasyMDE](https://github.com/Ionaru/easy-markdown-editor) - * [Monaco Editor](https://microsoft.github.io/monaco-editor) -* 数据库驱动: - * [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql) - * [github.com/lib/pq](https://github.com/lib/pq) - * [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3) - * [github.com/denisenkom/go-mssqldb](https://github.com/denisenkom/go-mssqldb) +- Web框架: [Chi](http://github.com/go-chi/chi) +- ORM: [XORM](https://xorm.io) +- UI 框架: + - [jQuery](https://jquery.com) + - [Fomantic UI](https://fomantic-ui.com) + - [Vue2](https://vuejs.org) + - 更多组件参见 package.json +- 编辑器: + - [CodeMirror](https://codemirror.net) + - [EasyMDE](https://github.com/Ionaru/easy-markdown-editor) + - [Monaco Editor](https://microsoft.github.io/monaco-editor) +- 数据库驱动: + - [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql) + - [github.com/lib/pq](https://github.com/lib/pq) + - [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3) + - [github.com/denisenkom/go-mssqldb](https://github.com/denisenkom/go-mssqldb) ## 软件及服务支持 diff --git a/docs/content/page/index.zh-tw.md b/docs/content/page/index.zh-tw.md index 0c67ef0b28a40..3dde97a9431e9 100644 --- a/docs/content/page/index.zh-tw.md +++ b/docs/content/page/index.zh-tw.md @@ -10,7 +10,7 @@ draft: false # 關於 Gitea -Gitea 是一個可自行託管的 Git 服務。你可以拿 GitHub、Bitbucket 或 Gitlab 來比較看看。 +Gitea 是一個可自行託管的 Git 服務。你可以拿 GitHub、Bitbucket 或 Gitlab 來比較看看。 Gitea 是從 [Gogs](http://gogs.io) Fork 出來的,請閱讀部落格文章 [Gitea 公告](https://blog.gitea.io/2016/12/welcome-to-gitea/)以了解我們 Fork 的理由。 ## 目標 @@ -269,19 +269,18 @@ Gitea 是從 [Gogs](http://gogs.io) Fork 出來的,請閱讀部落格文章 [G - Web 框架: [Chi](http://github.com/go-chi/chi) - ORM: [XORM](https://xorm.io) - UI 元件: - * [jQuery](https://jquery.com) - * [Fomantic UI](https://fomantic-ui.com) - * [Vue2](https://vuejs.org) - * [CodeMirror](https://codemirror.net) - * [EasyMDE](https://github.com/Ionaru/easy-markdown-editor) - * [Monaco Editor](https://microsoft.github.io/monaco-editor) - * ... (package.json) + - [jQuery](https://jquery.com) + - [Fomantic UI](https://fomantic-ui.com) + - [Vue2](https://vuejs.org) + - [CodeMirror](https://codemirror.net) + - [EasyMDE](https://github.com/Ionaru/easy-markdown-editor) + - [Monaco Editor](https://microsoft.github.io/monaco-editor) + - ... (package.json) - 資料庫驅動程式: - * [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql) - * [github.com/lib/pq](https://github.com/lib/pq) - * [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3) - * [github.com/denisenkom/go-mssqldb](https://github.com/denisenkom/go-mssqldb) - + - [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql) + - [github.com/lib/pq](https://github.com/lib/pq) + - [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3) + - [github.com/denisenkom/go-mssqldb](https://github.com/denisenkom/go-mssqldb) ## 軟體和服務支援 diff --git a/go.mod b/go.mod index 026c5723c38d7..6d41af507d351 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( gitea.com/go-chi/cache v0.2.0 gitea.com/go-chi/captcha v0.0.0-20211013065431-70641c1a35d5 gitea.com/go-chi/session v0.0.0-20211218221615-e3605d8b28b8 - gitea.com/lunny/levelqueue v0.4.1 + gitea.com/lunny/levelqueue v0.4.2-0.20220729054728-f020868cc2f7 github.com/42wim/sshsig v0.0.0-20211121163825-841cf5bbc121 github.com/NYTimes/gziphandler v1.1.1 github.com/PuerkitoBio/goquery v1.8.0 @@ -104,7 +104,7 @@ require ( mvdan.cc/xurls/v2 v2.4.0 strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251 xorm.io/builder v0.3.11 - xorm.io/xorm v1.3.1 + xorm.io/xorm v1.3.2-0.20220714055524-c3bce556200f ) require ( diff --git a/go.sum b/go.sum index 103206980776e..124e65a727ad9 100644 --- a/go.sum +++ b/go.sum @@ -80,8 +80,8 @@ gitea.com/go-chi/captcha v0.0.0-20211013065431-70641c1a35d5 h1:J/1i8u40TbcLP/w2w gitea.com/go-chi/captcha v0.0.0-20211013065431-70641c1a35d5/go.mod h1:hQ9SYHKdOX968wJglb/NMQ+UqpOKwW4L+EYdvkWjHSo= gitea.com/go-chi/session v0.0.0-20211218221615-e3605d8b28b8 h1:tJQRXgZigkLeeW9LPlps9G9aMoE6LAmqigLA+wxmd1Q= gitea.com/go-chi/session v0.0.0-20211218221615-e3605d8b28b8/go.mod h1:fc/pjt5EqNKgqQXYzcas1Z5L5whkZHyOvTA7OzWVJck= -gitea.com/lunny/levelqueue v0.4.1 h1:RZ+AFx5gBsZuyqCvofhAkPQ9uaVDPJnsULoJZIYaJNw= -gitea.com/lunny/levelqueue v0.4.1/go.mod h1:HBqmLbz56JWpfEGG0prskAV97ATNRoj5LDmPicD22hU= +gitea.com/lunny/levelqueue v0.4.2-0.20220729054728-f020868cc2f7 h1:Zc3RQWC2xOVglLciQH/ZIC5IqSk3Jn96LflGQLv18Rg= +gitea.com/lunny/levelqueue v0.4.2-0.20220729054728-f020868cc2f7/go.mod h1:HBqmLbz56JWpfEGG0prskAV97ATNRoj5LDmPicD22hU= gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s= gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU= gitee.com/travelliu/dm v1.8.11192/go.mod h1:DHTzyhCrM843x9VdKVbZ+GKXGRbKM2sJ4LxihRxShkE= @@ -2423,5 +2423,5 @@ strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251/go.mod h1: xorm.io/builder v0.3.11-0.20220531020008-1bd24a7dc978/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE= xorm.io/builder v0.3.11 h1:naLkJitGyYW7ZZdncsh/JW+HF4HshmvTHTyUyPwJS00= xorm.io/builder v0.3.11/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE= -xorm.io/xorm v1.3.1 h1:z5egKrDoOLqZFhMjcGF4FBHiTmE5/feQoHclfhNidfM= -xorm.io/xorm v1.3.1/go.mod h1:9NbjqdnjX6eyjRRhh01GHm64r6N9shTb/8Ak3YRt8Nw= +xorm.io/xorm v1.3.2-0.20220714055524-c3bce556200f h1:3NvNsM4lnttTsHpk8ODHqrwN1MCEjsO3bD/rpd8A47k= +xorm.io/xorm v1.3.2-0.20220714055524-c3bce556200f/go.mod h1:9NbjqdnjX6eyjRRhh01GHm64r6N9shTb/8Ak3YRt8Nw= diff --git a/integrations/admin_user_test.go b/integrations/admin_user_test.go index 59adac7ecc65b..a2020652b747f 100644 --- a/integrations/admin_user_test.go +++ b/integrations/admin_user_test.go @@ -76,7 +76,7 @@ func TestAdminDeleteUser(t *testing.T) { req := NewRequestWithValues(t, "POST", "/admin/users/8/delete", map[string]string{ "_csrf": csrf, }) - session.MakeRequest(t, req, http.StatusOK) + session.MakeRequest(t, req, http.StatusSeeOther) assertUserDeleted(t, 8) unittest.CheckConsistencyFor(t, &user_model.User{}) diff --git a/integrations/api_issue_test.go b/integrations/api_issue_test.go index 5c802e8d20df7..bb4e2f0c72dac 100644 --- a/integrations/api_issue_test.go +++ b/integrations/api_issue_test.go @@ -16,6 +16,7 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "github.com/stretchr/testify/assert" @@ -171,19 +172,21 @@ func TestAPISearchIssues(t *testing.T) { token := getUserToken(t, "user2") + // as this API was used in the frontend, it uses UI page size + expectedIssueCount := 15 // from the fixtures + if expectedIssueCount > setting.UI.IssuePagingNum { + expectedIssueCount = setting.UI.IssuePagingNum + } + link, _ := url.Parse("/api/v1/repos/issues/search") - req := NewRequest(t, "GET", link.String()+"?token="+token) - resp := MakeRequest(t, req, http.StatusOK) + query := url.Values{"token": {getUserToken(t, "user1")}} var apiIssues []*api.Issue - DecodeJSON(t, resp, &apiIssues) - assert.Len(t, apiIssues, 10) - query := url.Values{"token": {token}} link.RawQuery = query.Encode() - req = NewRequest(t, "GET", link.String()) - resp = MakeRequest(t, req, http.StatusOK) + req := NewRequest(t, "GET", link.String()) + resp := MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiIssues) - assert.Len(t, apiIssues, 10) + assert.Len(t, apiIssues, expectedIssueCount) since := "2000-01-01T00%3A50%3A01%2B00%3A00" // 946687801 before := time.Unix(999307200, 0).Format(time.RFC3339) @@ -211,14 +214,15 @@ func TestAPISearchIssues(t *testing.T) { resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiIssues) assert.EqualValues(t, "17", resp.Header().Get("X-Total-Count")) - assert.Len(t, apiIssues, 10) // there are more but 10 is page item limit + assert.Len(t, apiIssues, 17) - query.Add("limit", "20") + query.Add("limit", "10") link.RawQuery = query.Encode() req = NewRequest(t, "GET", link.String()) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiIssues) - assert.Len(t, apiIssues, 17) + assert.EqualValues(t, "17", resp.Header().Get("X-Total-Count")) + assert.Len(t, apiIssues, 10) query = url.Values{"assigned": {"true"}, "state": {"all"}, "token": {token}} link.RawQuery = query.Encode() @@ -266,23 +270,21 @@ func TestAPISearchIssues(t *testing.T) { func TestAPISearchIssuesWithLabels(t *testing.T) { defer prepareTestEnv(t)() - token := getUserToken(t, "user1") + // as this API was used in the frontend, it uses UI page size + expectedIssueCount := 15 // from the fixtures + if expectedIssueCount > setting.UI.IssuePagingNum { + expectedIssueCount = setting.UI.IssuePagingNum + } link, _ := url.Parse("/api/v1/repos/issues/search") - req := NewRequest(t, "GET", link.String()+"?token="+token) - resp := MakeRequest(t, req, http.StatusOK) + query := url.Values{"token": {getUserToken(t, "user1")}} var apiIssues []*api.Issue - DecodeJSON(t, resp, &apiIssues) - - assert.Len(t, apiIssues, 10) - query := url.Values{} - query.Add("token", token) link.RawQuery = query.Encode() - req = NewRequest(t, "GET", link.String()) - resp = MakeRequest(t, req, http.StatusOK) + req := NewRequest(t, "GET", link.String()) + resp := MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiIssues) - assert.Len(t, apiIssues, 10) + assert.Len(t, apiIssues, expectedIssueCount) query.Add("labels", "label1") link.RawQuery = query.Encode() diff --git a/integrations/api_packages_container_test.go b/integrations/api_packages_container_test.go index 1ed80dfd02277..5e073f313f7ae 100644 --- a/integrations/api_packages_container_test.go +++ b/integrations/api_packages_container_test.go @@ -20,12 +20,14 @@ import ( container_module "code.gitea.io/gitea/modules/packages/container" "code.gitea.io/gitea/modules/packages/container/oci" "code.gitea.io/gitea/modules/setting" + api "code.gitea.io/gitea/modules/structs" "github.com/stretchr/testify/assert" ) func TestPackageContainer(t *testing.T) { defer prepareTestEnv(t)() + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) has := func(l packages_model.PackagePropertyList, name string) bool { @@ -36,6 +38,15 @@ func TestPackageContainer(t *testing.T) { } return false } + getAllByName := func(l packages_model.PackagePropertyList, name string) []string { + values := make([]string, 0, len(l)) + for _, pp := range l { + if pp.Name == name { + values = append(values, pp.Value) + } + } + return values + } images := []string{"test", "te/st"} tags := []string{"latest", "main"} @@ -66,7 +77,7 @@ func TestPackageContainer(t *testing.T) { Token string `json:"token"` } - authenticate := []string{`Bearer realm="` + setting.AppURL + `v2/token"`} + authenticate := []string{`Bearer realm="` + setting.AppURL + `v2/token",service="container_registry",scope="*"`} t.Run("Anonymous", func(t *testing.T) { defer PrintCurrentTest(t)() @@ -236,7 +247,8 @@ func TestPackageContainer(t *testing.T) { assert.Nil(t, pd.SemVer) assert.Equal(t, image, pd.Package.Name) assert.Equal(t, tag, pd.Version.Version) - assert.True(t, has(pd.Properties, container_module.PropertyManifestTagged)) + assert.ElementsMatch(t, []string{strings.ToLower(user.LowerName + "/" + image)}, getAllByName(pd.PackageProperties, container_module.PropertyRepository)) + assert.True(t, has(pd.VersionProperties, container_module.PropertyManifestTagged)) assert.IsType(t, &container_module.Metadata{}, pd.Metadata) metadata := pd.Metadata.(*container_module.Metadata) @@ -330,7 +342,8 @@ func TestPackageContainer(t *testing.T) { assert.Nil(t, pd.SemVer) assert.Equal(t, image, pd.Package.Name) assert.Equal(t, untaggedManifestDigest, pd.Version.Version) - assert.False(t, has(pd.Properties, container_module.PropertyManifestTagged)) + assert.ElementsMatch(t, []string{strings.ToLower(user.LowerName + "/" + image)}, getAllByName(pd.PackageProperties, container_module.PropertyRepository)) + assert.False(t, has(pd.VersionProperties, container_module.PropertyManifestTagged)) assert.IsType(t, &container_module.Metadata{}, pd.Metadata) @@ -362,18 +375,10 @@ func TestPackageContainer(t *testing.T) { assert.Nil(t, pd.SemVer) assert.Equal(t, image, pd.Package.Name) assert.Equal(t, multiTag, pd.Version.Version) - assert.True(t, has(pd.Properties, container_module.PropertyManifestTagged)) + assert.ElementsMatch(t, []string{strings.ToLower(user.LowerName + "/" + image)}, getAllByName(pd.PackageProperties, container_module.PropertyRepository)) + assert.True(t, has(pd.VersionProperties, container_module.PropertyManifestTagged)) - getAllByName := func(l packages_model.PackagePropertyList, name string) []string { - values := make([]string, 0, len(l)) - for _, pp := range l { - if pp.Name == name { - values = append(values, pp.Value) - } - } - return values - } - assert.ElementsMatch(t, []string{manifestDigest, untaggedManifestDigest}, getAllByName(pd.Properties, container_module.PropertyManifestReference)) + assert.ElementsMatch(t, []string{manifestDigest, untaggedManifestDigest}, getAllByName(pd.VersionProperties, container_module.PropertyManifestReference)) assert.IsType(t, &container_module.Metadata{}, pd.Metadata) metadata := pd.Metadata.(*container_module.Metadata) @@ -487,6 +492,13 @@ func TestPackageContainer(t *testing.T) { assert.Equal(t, c.ExpectedTags, tagList.Tags) assert.Equal(t, c.ExpectedLink, resp.Header().Get("Link")) } + + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s?type=container&q=%s", user.Name, image)) + resp := MakeRequest(t, req, http.StatusOK) + + var apiPackages []*api.Package + DecodeJSON(t, resp, &apiPackages) + assert.Len(t, apiPackages, 4) // "latest", "main", "multi", "sha256:..." }) t.Run("Delete", func(t *testing.T) { @@ -528,4 +540,56 @@ func TestPackageContainer(t *testing.T) { }) }) } + + t.Run("OwnerNameChange", func(t *testing.T) { + defer PrintCurrentTest(t)() + + checkCatalog := func(owner string) func(t *testing.T) { + return func(t *testing.T) { + defer PrintCurrentTest(t)() + + req := NewRequest(t, "GET", fmt.Sprintf("%sv2/_catalog", setting.AppURL)) + addTokenAuthHeader(req, userToken) + resp := MakeRequest(t, req, http.StatusOK) + + type RepositoryList struct { + Repositories []string `json:"repositories"` + } + + repoList := &RepositoryList{} + DecodeJSON(t, resp, &repoList) + + assert.Len(t, repoList.Repositories, len(images)) + names := make([]string, 0, len(images)) + for _, image := range images { + names = append(names, strings.ToLower(owner+"/"+image)) + } + assert.ElementsMatch(t, names, repoList.Repositories) + } + } + + t.Run(fmt.Sprintf("Catalog[%s]", user.LowerName), checkCatalog(user.LowerName)) + + session := loginUser(t, user.Name) + + newOwnerName := "newUsername" + + req := NewRequestWithValues(t, "POST", "/user/settings", map[string]string{ + "_csrf": GetCSRF(t, session, "/user/settings"), + "name": newOwnerName, + "email": "user2@example.com", + "language": "en-US", + }) + session.MakeRequest(t, req, http.StatusSeeOther) + + t.Run(fmt.Sprintf("Catalog[%s]", newOwnerName), checkCatalog(newOwnerName)) + + req = NewRequestWithValues(t, "POST", "/user/settings", map[string]string{ + "_csrf": GetCSRF(t, session, "/user/settings"), + "name": user.Name, + "email": "user2@example.com", + "language": "en-US", + }) + session.MakeRequest(t, req, http.StatusSeeOther) + }) } diff --git a/integrations/api_packages_generic_test.go b/integrations/api_packages_generic_test.go index c507702eaafd1..adaf99e981ae9 100644 --- a/integrations/api_packages_generic_test.go +++ b/integrations/api_packages_generic_test.go @@ -42,7 +42,6 @@ func TestPackageGeneric(t *testing.T) { pd, err := packages.GetPackageDescriptor(db.DefaultContext, pvs[0]) assert.NoError(t, err) - assert.NotNil(t, pd.SemVer) assert.Nil(t, pd.Metadata) assert.Equal(t, packageName, pd.Package.Name) assert.Equal(t, packageVersion, pd.Version.Version) diff --git a/integrations/api_packages_maven_test.go b/integrations/api_packages_maven_test.go index c7c45426859e7..e7ab3bfe4b640 100644 --- a/integrations/api_packages_maven_test.go +++ b/integrations/api_packages_maven_test.go @@ -42,6 +42,7 @@ func TestPackageMaven(t *testing.T) { defer PrintCurrentTest(t)() putFile(t, fmt.Sprintf("/%s/%s", packageVersion, filename), "test", http.StatusCreated) + putFile(t, fmt.Sprintf("/%s/%s", packageVersion, filename), "test", http.StatusBadRequest) putFile(t, "/maven-metadata.xml", "test", http.StatusOK) pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeMaven) @@ -135,12 +136,14 @@ func TestPackageMaven(t *testing.T) { pfs, err := packages.GetFilesByVersionID(db.DefaultContext, pvs[0].ID) assert.NoError(t, err) assert.Len(t, pfs, 2) - i := 0 - if strings.HasSuffix(pfs[1].Name, ".pom") { - i = 1 + for _, pf := range pfs { + if strings.HasSuffix(pf.Name, ".pom") { + assert.Equal(t, filename+".pom", pf.Name) + assert.True(t, pf.IsLead) + } else { + assert.False(t, pf.IsLead) + } } - assert.Equal(t, filename+".pom", pfs[i].Name) - assert.True(t, pfs[i].IsLead) }) t.Run("DownloadPOM", func(t *testing.T) { @@ -202,4 +205,13 @@ func TestPackageMaven(t *testing.T) { assert.Equal(t, checksum, resp.Body.String()) } }) + + t.Run("UploadSnapshot", func(t *testing.T) { + snapshotVersion := packageVersion + "-SNAPSHOT" + + putFile(t, fmt.Sprintf("/%s/%s", snapshotVersion, filename), "test", http.StatusCreated) + putFile(t, "/maven-metadata.xml", "test", http.StatusOK) + putFile(t, fmt.Sprintf("/%s/maven-metadata.xml", snapshotVersion), "test", http.StatusCreated) + putFile(t, fmt.Sprintf("/%s/maven-metadata.xml", snapshotVersion), "test-overwrite", http.StatusCreated) + }) } diff --git a/integrations/api_packages_npm_test.go b/integrations/api_packages_npm_test.go index 28a3711939828..ad88ac5da6764 100644 --- a/integrations/api_packages_npm_test.go +++ b/integrations/api_packages_npm_test.go @@ -85,9 +85,9 @@ func TestPackageNpm(t *testing.T) { assert.IsType(t, &npm.Metadata{}, pd.Metadata) assert.Equal(t, packageName, pd.Package.Name) assert.Equal(t, packageVersion, pd.Version.Version) - assert.Len(t, pd.Properties, 1) - assert.Equal(t, npm.TagProperty, pd.Properties[0].Name) - assert.Equal(t, packageTag, pd.Properties[0].Value) + assert.Len(t, pd.VersionProperties, 1) + assert.Equal(t, npm.TagProperty, pd.VersionProperties[0].Name) + assert.Equal(t, packageTag, pd.VersionProperties[0].Value) pfs, err := packages.GetFilesByVersionID(db.DefaultContext, pvs[0].ID) assert.NoError(t, err) diff --git a/integrations/api_packages_nuget_test.go b/integrations/api_packages_nuget_test.go index e69dd0ff9b669..346f391f82fcc 100644 --- a/integrations/api_packages_nuget_test.go +++ b/integrations/api_packages_nuget_test.go @@ -122,7 +122,7 @@ func TestPackageNuGet(t *testing.T) { req = NewRequestWithBody(t, "PUT", url, bytes.NewReader(content)) req = AddBasicAuthHeader(req, user.Name) - MakeRequest(t, req, http.StatusBadRequest) + MakeRequest(t, req, http.StatusConflict) }) t.Run("SymbolPackage", func(t *testing.T) { @@ -208,7 +208,7 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`) req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/symbolpackage", url), createPackage(packageName, "SymbolsPackage")) req = AddBasicAuthHeader(req, user.Name) - MakeRequest(t, req, http.StatusBadRequest) + MakeRequest(t, req, http.StatusConflict) }) }) @@ -352,7 +352,7 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`) req := NewRequest(t, "DELETE", fmt.Sprintf("%s/%s/%s", url, packageName, packageVersion)) req = AddBasicAuthHeader(req, user.Name) - MakeRequest(t, req, http.StatusOK) + MakeRequest(t, req, http.StatusNoContent) pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeNuGet) assert.NoError(t, err) diff --git a/integrations/api_packages_pub_test.go b/integrations/api_packages_pub_test.go new file mode 100644 index 0000000000000..d64f88def747a --- /dev/null +++ b/integrations/api_packages_pub_test.go @@ -0,0 +1,179 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package integrations + +import ( + "archive/tar" + "bytes" + "compress/gzip" + "fmt" + "io" + "mime/multipart" + "net/http" + "net/http/httptest" + "testing" + "time" + + "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/models/packages" + "code.gitea.io/gitea/models/unittest" + user_model "code.gitea.io/gitea/models/user" + pub_module "code.gitea.io/gitea/modules/packages/pub" + + "github.com/stretchr/testify/assert" +) + +func TestPackagePub(t *testing.T) { + defer prepareTestEnv(t)() + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + + token := "Bearer " + getUserToken(t, user.Name) + + packageName := "test_package" + packageVersion := "1.0.1" + packageDescription := "Test Description" + + filename := fmt.Sprintf("%s.tar.gz", packageVersion) + + pubspecContent := `name: ` + packageName + ` +version: ` + packageVersion + ` +description: ` + packageDescription + + var buf bytes.Buffer + zw := gzip.NewWriter(&buf) + archive := tar.NewWriter(zw) + archive.WriteHeader(&tar.Header{ + Name: "pubspec.yaml", + Mode: 0o600, + Size: int64(len(pubspecContent)), + }) + archive.Write([]byte(pubspecContent)) + archive.Close() + zw.Close() + content := buf.Bytes() + + root := fmt.Sprintf("/api/packages/%s/pub", user.Name) + + t.Run("Upload", func(t *testing.T) { + defer PrintCurrentTest(t)() + + uploadURL := root + "/api/packages/versions/new" + + req := NewRequest(t, "GET", uploadURL) + MakeRequest(t, req, http.StatusUnauthorized) + + req = NewRequest(t, "GET", uploadURL) + addTokenAuthHeader(req, token) + resp := MakeRequest(t, req, http.StatusOK) + + type UploadRequest struct { + URL string `json:"url"` + Fields map[string]string `json:"fields"` + } + + var result UploadRequest + DecodeJSON(t, resp, &result) + + assert.Empty(t, result.Fields) + + uploadFile := func(t *testing.T, url string, content []byte, expectedStatus int) *httptest.ResponseRecorder { + body := &bytes.Buffer{} + writer := multipart.NewWriter(body) + part, _ := writer.CreateFormFile("file", "dummy.tar.gz") + _, _ = io.Copy(part, bytes.NewReader(content)) + + _ = writer.Close() + + req := NewRequestWithBody(t, "POST", url, body) + req.Header.Add("Content-Type", writer.FormDataContentType()) + addTokenAuthHeader(req, token) + return MakeRequest(t, req, expectedStatus) + } + + resp = uploadFile(t, result.URL, content, http.StatusNoContent) + + req = NewRequest(t, "GET", resp.Header().Get("Location")) + addTokenAuthHeader(req, token) + MakeRequest(t, req, http.StatusOK) + + pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypePub) + assert.NoError(t, err) + assert.Len(t, pvs, 1) + + pd, err := packages.GetPackageDescriptor(db.DefaultContext, pvs[0]) + assert.NoError(t, err) + assert.NotNil(t, pd.SemVer) + assert.IsType(t, &pub_module.Metadata{}, pd.Metadata) + assert.Equal(t, packageName, pd.Package.Name) + assert.Equal(t, packageVersion, pd.Version.Version) + + pfs, err := packages.GetFilesByVersionID(db.DefaultContext, pvs[0].ID) + assert.NoError(t, err) + assert.Len(t, pfs, 1) + assert.Equal(t, filename, pfs[0].Name) + assert.True(t, pfs[0].IsLead) + + pb, err := packages.GetBlobByID(db.DefaultContext, pfs[0].BlobID) + assert.NoError(t, err) + assert.Equal(t, int64(len(content)), pb.Size) + + resp = uploadFile(t, result.URL, content, http.StatusBadRequest) + }) + + t.Run("Download", func(t *testing.T) { + defer PrintCurrentTest(t)() + + req := NewRequest(t, "GET", fmt.Sprintf("%s/api/packages/%s/%s", root, packageName, packageVersion)) + resp := MakeRequest(t, req, http.StatusOK) + + type VersionMetadata struct { + Version string `json:"version"` + ArchiveURL string `json:"archive_url"` + Published time.Time `json:"published"` + Pubspec interface{} `json:"pubspec,omitempty"` + } + + var result VersionMetadata + DecodeJSON(t, resp, &result) + + assert.Equal(t, packageVersion, result.Version) + assert.NotNil(t, result.Pubspec) + + req = NewRequest(t, "GET", result.ArchiveURL) + resp = MakeRequest(t, req, http.StatusOK) + + assert.Equal(t, content, resp.Body.Bytes()) + }) + + t.Run("EnumeratePackageVersions", func(t *testing.T) { + defer PrintCurrentTest(t)() + + req := NewRequest(t, "GET", fmt.Sprintf("%s/api/packages/%s", root, packageName)) + resp := MakeRequest(t, req, http.StatusOK) + + type VersionMetadata struct { + Version string `json:"version"` + ArchiveURL string `json:"archive_url"` + Published time.Time `json:"published"` + Pubspec interface{} `json:"pubspec,omitempty"` + } + + type PackageVersions struct { + Name string `json:"name"` + Latest *VersionMetadata `json:"latest"` + Versions []*VersionMetadata `json:"versions"` + } + + var result PackageVersions + DecodeJSON(t, resp, &result) + + assert.Equal(t, packageName, result.Name) + assert.NotNil(t, result.Latest) + assert.Len(t, result.Versions, 1) + assert.Equal(t, result.Latest.Version, result.Versions[0].Version) + assert.Equal(t, packageVersion, result.Latest.Version) + assert.NotNil(t, result.Latest.Pubspec) + }) +} diff --git a/integrations/api_repo_file_create_test.go b/integrations/api_repo_file_create_test.go index eb550f1d28d74..fd460ce5643fc 100644 --- a/integrations/api_repo_file_create_test.go +++ b/integrations/api_repo_file_create_test.go @@ -50,7 +50,7 @@ func getCreateFileOptions() api.CreateFileOptions { } } -func getExpectedFileResponseForCreate(repoFullName, commitID, treePath string) *api.FileResponse { +func getExpectedFileResponseForCreate(repoFullName, commitID, treePath, latestCommitSHA string) *api.FileResponse { sha := "a635aa942442ddfdba07468cf9661c08fbdf0ebf" encoding := "base64" content := "VGhpcyBpcyBuZXcgdGV4dA==" @@ -60,17 +60,18 @@ func getExpectedFileResponseForCreate(repoFullName, commitID, treePath string) * downloadURL := setting.AppURL + repoFullName + "/raw/branch/master/" + treePath return &api.FileResponse{ Content: &api.ContentsResponse{ - Name: filepath.Base(treePath), - Path: treePath, - SHA: sha, - Size: 16, - Type: "file", - Encoding: &encoding, - Content: &content, - URL: &selfURL, - HTMLURL: &htmlURL, - GitURL: &gitURL, - DownloadURL: &downloadURL, + Name: filepath.Base(treePath), + Path: treePath, + SHA: sha, + LastCommitSHA: latestCommitSHA, + Size: 16, + Type: "file", + Encoding: &encoding, + Content: &content, + URL: &selfURL, + HTMLURL: &htmlURL, + GitURL: &gitURL, + DownloadURL: &downloadURL, Links: &api.FileLinksResponse{ Self: &selfURL, GitURL: &gitURL, @@ -170,7 +171,8 @@ func TestAPICreateFile(t *testing.T) { resp := session.MakeRequest(t, req, http.StatusCreated) gitRepo, _ := git.OpenRepository(stdCtx.Background(), repo1.RepoPath()) commitID, _ := gitRepo.GetBranchCommitID(createFileOptions.NewBranchName) - expectedFileResponse := getExpectedFileResponseForCreate("user2/repo1", commitID, treePath) + latestCommit, _ := gitRepo.GetCommitByPath(treePath) + expectedFileResponse := getExpectedFileResponseForCreate("user2/repo1", commitID, treePath, latestCommit.ID.String()) var fileResponse api.FileResponse DecodeJSON(t, resp, &fileResponse) assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content) @@ -289,7 +291,8 @@ func TestAPICreateFile(t *testing.T) { emptyRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerName: "user2", Name: "empty-repo"}).(*repo_model.Repository) // public repo gitRepo, _ := git.OpenRepository(stdCtx.Background(), emptyRepo.RepoPath()) commitID, _ := gitRepo.GetBranchCommitID(createFileOptions.NewBranchName) - expectedFileResponse := getExpectedFileResponseForCreate("user2/empty-repo", commitID, treePath) + latestCommit, _ := gitRepo.GetCommitByPath(treePath) + expectedFileResponse := getExpectedFileResponseForCreate("user2/empty-repo", commitID, treePath, latestCommit.ID.String()) DecodeJSON(t, resp, &fileResponse) assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content) assert.EqualValues(t, expectedFileResponse.Commit.SHA, fileResponse.Commit.SHA) diff --git a/integrations/api_repo_file_update_test.go b/integrations/api_repo_file_update_test.go index 0c9c0763f4671..e39d83e49e13d 100644 --- a/integrations/api_repo_file_update_test.go +++ b/integrations/api_repo_file_update_test.go @@ -48,7 +48,7 @@ func getUpdateFileOptions() *api.UpdateFileOptions { } } -func getExpectedFileResponseForUpdate(commitID, treePath string) *api.FileResponse { +func getExpectedFileResponseForUpdate(commitID, treePath, lastCommitSHA string) *api.FileResponse { sha := "08bd14b2e2852529157324de9c226b3364e76136" encoding := "base64" content := "VGhpcyBpcyB1cGRhdGVkIHRleHQ=" @@ -58,17 +58,18 @@ func getExpectedFileResponseForUpdate(commitID, treePath string) *api.FileRespon downloadURL := setting.AppURL + "user2/repo1/raw/branch/master/" + treePath return &api.FileResponse{ Content: &api.ContentsResponse{ - Name: filepath.Base(treePath), - Path: treePath, - SHA: sha, - Type: "file", - Size: 20, - Encoding: &encoding, - Content: &content, - URL: &selfURL, - HTMLURL: &htmlURL, - GitURL: &gitURL, - DownloadURL: &downloadURL, + Name: filepath.Base(treePath), + Path: treePath, + SHA: sha, + LastCommitSHA: lastCommitSHA, + Type: "file", + Size: 20, + Encoding: &encoding, + Content: &content, + URL: &selfURL, + HTMLURL: &htmlURL, + GitURL: &gitURL, + DownloadURL: &downloadURL, Links: &api.FileLinksResponse{ Self: &selfURL, GitURL: &gitURL, @@ -137,7 +138,8 @@ func TestAPIUpdateFile(t *testing.T) { resp := session.MakeRequest(t, req, http.StatusOK) gitRepo, _ := git.OpenRepository(stdCtx.Background(), repo1.RepoPath()) commitID, _ := gitRepo.GetBranchCommitID(updateFileOptions.NewBranchName) - expectedFileResponse := getExpectedFileResponseForUpdate(commitID, treePath) + lasCommit, _ := gitRepo.GetCommitByPath(treePath) + expectedFileResponse := getExpectedFileResponseForUpdate(commitID, treePath, lasCommit.ID.String()) var fileResponse api.FileResponse DecodeJSON(t, resp, &fileResponse) assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content) diff --git a/integrations/api_repo_get_contents_list_test.go b/integrations/api_repo_get_contents_list_test.go index 42227a9c4b723..97b152bf1b34d 100644 --- a/integrations/api_repo_get_contents_list_test.go +++ b/integrations/api_repo_get_contents_list_test.go @@ -21,7 +21,7 @@ import ( "github.com/stretchr/testify/assert" ) -func getExpectedContentsListResponseForContents(ref, refType string) []*api.ContentsResponse { +func getExpectedContentsListResponseForContents(ref, refType, lastCommitSHA string) []*api.ContentsResponse { treePath := "README.md" sha := "4b4851ad51df6a7d9f25c979345979eaeb5b349f" selfURL := setting.AppURL + "api/v1/repos/user2/repo1/contents/" + treePath + "?ref=" + ref @@ -30,15 +30,16 @@ func getExpectedContentsListResponseForContents(ref, refType string) []*api.Cont downloadURL := setting.AppURL + "user2/repo1/raw/" + refType + "/" + ref + "/" + treePath return []*api.ContentsResponse{ { - Name: filepath.Base(treePath), - Path: treePath, - SHA: sha, - Type: "file", - Size: 30, - URL: &selfURL, - HTMLURL: &htmlURL, - GitURL: &gitURL, - DownloadURL: &downloadURL, + Name: filepath.Base(treePath), + Path: treePath, + SHA: sha, + LastCommitSHA: lastCommitSHA, + Type: "file", + Size: 30, + URL: &selfURL, + HTMLURL: &htmlURL, + GitURL: &gitURL, + DownloadURL: &downloadURL, Links: &api.FileLinksResponse{ Self: &selfURL, GitURL: &gitURL, @@ -94,7 +95,9 @@ func testAPIGetContentsList(t *testing.T, u *url.URL) { var contentsListResponse []*api.ContentsResponse DecodeJSON(t, resp, &contentsListResponse) assert.NotNil(t, contentsListResponse) - expectedContentsListResponse := getExpectedContentsListResponseForContents(ref, refType) + lastCommit, err := gitRepo.GetCommitByPath("README.md") + assert.NoError(t, err) + expectedContentsListResponse := getExpectedContentsListResponseForContents(ref, refType, lastCommit.ID.String()) assert.EqualValues(t, expectedContentsListResponse, contentsListResponse) // No ref @@ -103,17 +106,22 @@ func testAPIGetContentsList(t *testing.T, u *url.URL) { resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &contentsListResponse) assert.NotNil(t, contentsListResponse) - expectedContentsListResponse = getExpectedContentsListResponseForContents(repo1.DefaultBranch, refType) + + expectedContentsListResponse = getExpectedContentsListResponseForContents(repo1.DefaultBranch, refType, lastCommit.ID.String()) assert.EqualValues(t, expectedContentsListResponse, contentsListResponse) - // ref is the branch we created above in setup + // ref is the branch we created above in setup ref = newBranch refType = "branch" req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s?ref=%s", user2.Name, repo1.Name, treePath, ref) resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &contentsListResponse) assert.NotNil(t, contentsListResponse) - expectedContentsListResponse = getExpectedContentsListResponseForContents(ref, refType) + branchCommit, err := gitRepo.GetBranchCommit(ref) + assert.NoError(t, err) + lastCommit, err = branchCommit.GetCommitByPath("README.md") + assert.NoError(t, err) + expectedContentsListResponse = getExpectedContentsListResponseForContents(ref, refType, lastCommit.ID.String()) assert.EqualValues(t, expectedContentsListResponse, contentsListResponse) // ref is the new tag we created above in setup @@ -123,7 +131,11 @@ func testAPIGetContentsList(t *testing.T, u *url.URL) { resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &contentsListResponse) assert.NotNil(t, contentsListResponse) - expectedContentsListResponse = getExpectedContentsListResponseForContents(ref, refType) + tagCommit, err := gitRepo.GetTagCommit(ref) + assert.NoError(t, err) + lastCommit, err = tagCommit.GetCommitByPath("README.md") + assert.NoError(t, err) + expectedContentsListResponse = getExpectedContentsListResponseForContents(ref, refType, lastCommit.ID.String()) assert.EqualValues(t, expectedContentsListResponse, contentsListResponse) // ref is a commit @@ -133,7 +145,7 @@ func testAPIGetContentsList(t *testing.T, u *url.URL) { resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &contentsListResponse) assert.NotNil(t, contentsListResponse) - expectedContentsListResponse = getExpectedContentsListResponseForContents(ref, refType) + expectedContentsListResponse = getExpectedContentsListResponseForContents(ref, refType, commitID) assert.EqualValues(t, expectedContentsListResponse, contentsListResponse) // Test file contents a file with a bad ref diff --git a/integrations/api_repo_get_contents_test.go b/integrations/api_repo_get_contents_test.go index 67f2cb83625a0..56f5336b7bd94 100644 --- a/integrations/api_repo_get_contents_test.go +++ b/integrations/api_repo_get_contents_test.go @@ -20,7 +20,7 @@ import ( "github.com/stretchr/testify/assert" ) -func getExpectedContentsResponseForContents(ref, refType string) *api.ContentsResponse { +func getExpectedContentsResponseForContents(ref, refType, lastCommitSHA string) *api.ContentsResponse { treePath := "README.md" sha := "4b4851ad51df6a7d9f25c979345979eaeb5b349f" encoding := "base64" @@ -30,17 +30,18 @@ func getExpectedContentsResponseForContents(ref, refType string) *api.ContentsRe gitURL := setting.AppURL + "api/v1/repos/user2/repo1/git/blobs/" + sha downloadURL := setting.AppURL + "user2/repo1/raw/" + refType + "/" + ref + "/" + treePath return &api.ContentsResponse{ - Name: treePath, - Path: treePath, - SHA: sha, - Type: "file", - Size: 30, - Encoding: &encoding, - Content: &content, - URL: &selfURL, - HTMLURL: &htmlURL, - GitURL: &gitURL, - DownloadURL: &downloadURL, + Name: treePath, + Path: treePath, + SHA: sha, + LastCommitSHA: lastCommitSHA, + Type: "file", + Size: 30, + Encoding: &encoding, + Content: &content, + URL: &selfURL, + HTMLURL: &htmlURL, + GitURL: &gitURL, + DownloadURL: &downloadURL, Links: &api.FileLinksResponse{ Self: &selfURL, GitURL: &gitURL, @@ -96,7 +97,8 @@ func testAPIGetContents(t *testing.T, u *url.URL) { var contentsResponse api.ContentsResponse DecodeJSON(t, resp, &contentsResponse) assert.NotNil(t, contentsResponse) - expectedContentsResponse := getExpectedContentsResponseForContents(ref, refType) + lastCommit, _ := gitRepo.GetCommitByPath("README.md") + expectedContentsResponse := getExpectedContentsResponseForContents(ref, refType, lastCommit.ID.String()) assert.EqualValues(t, *expectedContentsResponse, contentsResponse) // No ref @@ -105,7 +107,7 @@ func testAPIGetContents(t *testing.T, u *url.URL) { resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &contentsResponse) assert.NotNil(t, contentsResponse) - expectedContentsResponse = getExpectedContentsResponseForContents(repo1.DefaultBranch, refType) + expectedContentsResponse = getExpectedContentsResponseForContents(repo1.DefaultBranch, refType, lastCommit.ID.String()) assert.EqualValues(t, *expectedContentsResponse, contentsResponse) // ref is the branch we created above in setup @@ -115,7 +117,9 @@ func testAPIGetContents(t *testing.T, u *url.URL) { resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &contentsResponse) assert.NotNil(t, contentsResponse) - expectedContentsResponse = getExpectedContentsResponseForContents(ref, refType) + branchCommit, _ := gitRepo.GetBranchCommit(ref) + lastCommit, _ = branchCommit.GetCommitByPath("README.md") + expectedContentsResponse = getExpectedContentsResponseForContents(ref, refType, lastCommit.ID.String()) assert.EqualValues(t, *expectedContentsResponse, contentsResponse) // ref is the new tag we created above in setup @@ -125,7 +129,9 @@ func testAPIGetContents(t *testing.T, u *url.URL) { resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &contentsResponse) assert.NotNil(t, contentsResponse) - expectedContentsResponse = getExpectedContentsResponseForContents(ref, refType) + tagCommit, _ := gitRepo.GetTagCommit(ref) + lastCommit, _ = tagCommit.GetCommitByPath("README.md") + expectedContentsResponse = getExpectedContentsResponseForContents(ref, refType, lastCommit.ID.String()) assert.EqualValues(t, *expectedContentsResponse, contentsResponse) // ref is a commit @@ -135,7 +141,7 @@ func testAPIGetContents(t *testing.T, u *url.URL) { resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &contentsResponse) assert.NotNil(t, contentsResponse) - expectedContentsResponse = getExpectedContentsResponseForContents(ref, refType) + expectedContentsResponse = getExpectedContentsResponseForContents(ref, refType, commitID) assert.EqualValues(t, *expectedContentsResponse, contentsResponse) // Test file contents a file with a bad ref diff --git a/integrations/api_repo_raw_test.go b/integrations/api_repo_raw_test.go index 2a77d1ba630dc..258b409befb87 100644 --- a/integrations/api_repo_raw_test.go +++ b/integrations/api_repo_raw_test.go @@ -10,6 +10,8 @@ import ( "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" + + "github.com/stretchr/testify/assert" ) func TestAPIReposRaw(t *testing.T) { @@ -25,9 +27,11 @@ func TestAPIReposRaw(t *testing.T) { "65f1bf27bc3bf70f64657658635e66094edbcb4d", // Commit } { req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/raw/%s/README.md?token="+token, user.Name, ref) - session.MakeRequest(t, req, http.StatusOK) + resp := session.MakeRequest(t, req, http.StatusOK) + assert.EqualValues(t, "file", resp.Header().Get("x-gitea-object-type")) } // Test default branch req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/raw/README.md?token="+token, user.Name) - session.MakeRequest(t, req, http.StatusOK) + resp := session.MakeRequest(t, req, http.StatusOK) + assert.EqualValues(t, "file", resp.Header().Get("x-gitea-object-type")) } diff --git a/integrations/integration_test.go b/integrations/integration_test.go index 8a43de7c45fa9..230f780175c9c 100644 --- a/integrations/integration_test.go +++ b/integrations/integration_test.go @@ -188,8 +188,13 @@ func initIntegrationTest() { switch { case setting.Database.UseMySQL: - db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s)/", - setting.Database.User, setting.Database.Passwd, setting.Database.Host)) + connType := "tcp" + if len(setting.Database.Host) > 0 && setting.Database.Host[0] == '/' { // looks like a unix socket + connType = "unix" + } + + db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@%s(%s)/", + setting.Database.User, setting.Database.Passwd, connType, setting.Database.Host)) defer db.Close() if err != nil { log.Fatal("sql.Open: %v", err) diff --git a/integrations/issue_test.go b/integrations/issue_test.go index 7d30d657f5589..e1d3b1b21e2af 100644 --- a/integrations/issue_test.go +++ b/integrations/issue_test.go @@ -356,17 +356,17 @@ func TestSearchIssues(t *testing.T) { session := loginUser(t, "user2") + expectedIssueCount := 15 // from the fixtures + if expectedIssueCount > setting.UI.IssuePagingNum { + expectedIssueCount = setting.UI.IssuePagingNum + } + link, _ := url.Parse("/issues/search") req := NewRequest(t, "GET", link.String()) resp := session.MakeRequest(t, req, http.StatusOK) var apiIssues []*api.Issue DecodeJSON(t, resp, &apiIssues) - assert.Len(t, apiIssues, 10) - - req = NewRequest(t, "GET", link.String()) - resp = session.MakeRequest(t, req, http.StatusOK) - DecodeJSON(t, resp, &apiIssues) - assert.Len(t, apiIssues, 10) + assert.Len(t, apiIssues, expectedIssueCount) since := "2000-01-01T00%3A50%3A01%2B00%3A00" // 946687801 before := time.Unix(999307200, 0).Format(time.RFC3339) @@ -394,14 +394,15 @@ func TestSearchIssues(t *testing.T) { resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiIssues) assert.EqualValues(t, "17", resp.Header().Get("X-Total-Count")) - assert.Len(t, apiIssues, 10) // there are more but 10 is page item limit + assert.Len(t, apiIssues, 17) - query.Add("limit", "20") + query.Add("limit", "5") link.RawQuery = query.Encode() req = NewRequest(t, "GET", link.String()) resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiIssues) - assert.Len(t, apiIssues, 17) + assert.EqualValues(t, "17", resp.Header().Get("X-Total-Count")) + assert.Len(t, apiIssues, 5) query = url.Values{"assigned": {"true"}, "state": {"all"}} link.RawQuery = query.Encode() @@ -449,29 +450,26 @@ func TestSearchIssues(t *testing.T) { func TestSearchIssuesWithLabels(t *testing.T) { defer prepareTestEnv(t)() - token := getUserToken(t, "user1") + expectedIssueCount := 15 // from the fixtures + if expectedIssueCount > setting.UI.IssuePagingNum { + expectedIssueCount = setting.UI.IssuePagingNum + } - link, _ := url.Parse("/api/v1/repos/issues/search?token=" + token) - req := NewRequest(t, "GET", link.String()) - resp := MakeRequest(t, req, http.StatusOK) + session := loginUser(t, "user1") + link, _ := url.Parse("/issues/search") + query := url.Values{} var apiIssues []*api.Issue - DecodeJSON(t, resp, &apiIssues) - - assert.Len(t, apiIssues, 10) - query := url.Values{ - "token": []string{token}, - } link.RawQuery = query.Encode() - req = NewRequest(t, "GET", link.String()) - resp = MakeRequest(t, req, http.StatusOK) + req := NewRequest(t, "GET", link.String()) + resp := session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiIssues) - assert.Len(t, apiIssues, 10) + assert.Len(t, apiIssues, expectedIssueCount) query.Add("labels", "label1") link.RawQuery = query.Encode() req = NewRequest(t, "GET", link.String()) - resp = MakeRequest(t, req, http.StatusOK) + resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiIssues) assert.Len(t, apiIssues, 2) @@ -479,7 +477,7 @@ func TestSearchIssuesWithLabels(t *testing.T) { query.Set("labels", "label1,label2") link.RawQuery = query.Encode() req = NewRequest(t, "GET", link.String()) - resp = MakeRequest(t, req, http.StatusOK) + resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiIssues) assert.Len(t, apiIssues, 2) @@ -487,7 +485,7 @@ func TestSearchIssuesWithLabels(t *testing.T) { query.Set("labels", "orglabel4") link.RawQuery = query.Encode() req = NewRequest(t, "GET", link.String()) - resp = MakeRequest(t, req, http.StatusOK) + resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiIssues) assert.Len(t, apiIssues, 1) @@ -496,7 +494,7 @@ func TestSearchIssuesWithLabels(t *testing.T) { query.Add("state", "all") link.RawQuery = query.Encode() req = NewRequest(t, "GET", link.String()) - resp = MakeRequest(t, req, http.StatusOK) + resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiIssues) assert.Len(t, apiIssues, 2) @@ -504,7 +502,7 @@ func TestSearchIssuesWithLabels(t *testing.T) { query.Set("labels", "label1,orglabel4") link.RawQuery = query.Encode() req = NewRequest(t, "GET", link.String()) - resp = MakeRequest(t, req, http.StatusOK) + resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiIssues) assert.Len(t, apiIssues, 2) } diff --git a/integrations/mirror_push_test.go b/integrations/mirror_push_test.go index a73b69e7869dd..3a22b0075423b 100644 --- a/integrations/mirror_push_test.go +++ b/integrations/mirror_push_test.go @@ -13,6 +13,7 @@ import ( "testing" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -47,7 +48,7 @@ func testMirrorPush(t *testing.T, u *url.URL) { doCreatePushMirror(ctx, fmt.Sprintf("%s%s/%s", u.String(), url.PathEscape(ctx.Username), url.PathEscape(mirrorRepo.Name)), user.LowerName, userPassword)(t) - mirrors, err := repo_model.GetPushMirrorsByRepoID(srcRepo.ID) + mirrors, _, err := repo_model.GetPushMirrorsByRepoID(db.DefaultContext, srcRepo.ID, db.ListOptions{}) assert.NoError(t, err) assert.Len(t, mirrors, 1) @@ -72,7 +73,7 @@ func testMirrorPush(t *testing.T, u *url.URL) { // Cleanup doRemovePushMirror(ctx, fmt.Sprintf("%s%s/%s", u.String(), url.PathEscape(ctx.Username), url.PathEscape(mirrorRepo.Name)), user.LowerName, userPassword, int(mirrors[0].ID))(t) - mirrors, err = repo_model.GetPushMirrorsByRepoID(srcRepo.ID) + mirrors, _, err = repo_model.GetPushMirrorsByRepoID(db.DefaultContext, srcRepo.ID, db.ListOptions{}) assert.NoError(t, err) assert.Len(t, mirrors, 0) } diff --git a/integrations/org_test.go b/integrations/org_test.go index d755385726a55..d787e6f79100d 100644 --- a/integrations/org_test.go +++ b/integrations/org_test.go @@ -116,6 +116,24 @@ func TestPrivateOrg(t *testing.T) { session.MakeRequest(t, req, http.StatusOK) } +func TestOrgMembers(t *testing.T) { + defer prepareTestEnv(t)() + + // not logged in user + req := NewRequest(t, "GET", "/org/org25/members") + MakeRequest(t, req, http.StatusOK) + + // org member + session := loginUser(t, "user24") + req = NewRequest(t, "GET", "/org/org25/members") + session.MakeRequest(t, req, http.StatusOK) + + // site admin + session = loginUser(t, "user1") + req = NewRequest(t, "GET", "/org/org25/members") + session.MakeRequest(t, req, http.StatusOK) +} + func TestOrgRestrictedUser(t *testing.T) { defer prepareTestEnv(t)() diff --git a/integrations/repofiles_update_test.go b/integrations/repofiles_update_test.go index 2add99cc86ff9..ac9b0509eae40 100644 --- a/integrations/repofiles_update_test.go +++ b/integrations/repofiles_update_test.go @@ -47,7 +47,7 @@ func getUpdateRepoFileOptions(repo *repo_model.Repository) *files_service.Update } } -func getExpectedFileResponseForRepofilesCreate(commitID string) *api.FileResponse { +func getExpectedFileResponseForRepofilesCreate(commitID, lastCommitSHA string) *api.FileResponse { treePath := "new/file.txt" encoding := "base64" content := "VGhpcyBpcyBhIE5FVyBmaWxl" @@ -57,17 +57,18 @@ func getExpectedFileResponseForRepofilesCreate(commitID string) *api.FileRespons downloadURL := setting.AppURL + "user2/repo1/raw/branch/master/" + treePath return &api.FileResponse{ Content: &api.ContentsResponse{ - Name: filepath.Base(treePath), - Path: treePath, - SHA: "103ff9234cefeee5ec5361d22b49fbb04d385885", - Type: "file", - Size: 18, - Encoding: &encoding, - Content: &content, - URL: &selfURL, - HTMLURL: &htmlURL, - GitURL: &gitURL, - DownloadURL: &downloadURL, + Name: filepath.Base(treePath), + Path: treePath, + SHA: "103ff9234cefeee5ec5361d22b49fbb04d385885", + LastCommitSHA: lastCommitSHA, + Type: "file", + Size: 18, + Encoding: &encoding, + Content: &content, + URL: &selfURL, + HTMLURL: &htmlURL, + GitURL: &gitURL, + DownloadURL: &downloadURL, Links: &api.FileLinksResponse{ Self: &selfURL, GitURL: &gitURL, @@ -115,7 +116,7 @@ func getExpectedFileResponseForRepofilesCreate(commitID string) *api.FileRespons } } -func getExpectedFileResponseForRepofilesUpdate(commitID, filename string) *api.FileResponse { +func getExpectedFileResponseForRepofilesUpdate(commitID, filename, lastCommitSHA string) *api.FileResponse { encoding := "base64" content := "VGhpcyBpcyBVUERBVEVEIGNvbnRlbnQgZm9yIHRoZSBSRUFETUUgZmlsZQ==" selfURL := setting.AppURL + "api/v1/repos/user2/repo1/contents/" + filename + "?ref=master" @@ -124,17 +125,18 @@ func getExpectedFileResponseForRepofilesUpdate(commitID, filename string) *api.F downloadURL := setting.AppURL + "user2/repo1/raw/branch/master/" + filename return &api.FileResponse{ Content: &api.ContentsResponse{ - Name: filename, - Path: filename, - SHA: "dbf8d00e022e05b7e5cf7e535de857de57925647", - Type: "file", - Size: 43, - Encoding: &encoding, - Content: &content, - URL: &selfURL, - HTMLURL: &htmlURL, - GitURL: &gitURL, - DownloadURL: &downloadURL, + Name: filename, + Path: filename, + SHA: "dbf8d00e022e05b7e5cf7e535de857de57925647", + LastCommitSHA: lastCommitSHA, + Type: "file", + Size: 43, + Encoding: &encoding, + Content: &content, + URL: &selfURL, + HTMLURL: &htmlURL, + GitURL: &gitURL, + DownloadURL: &downloadURL, Links: &api.FileLinksResponse{ Self: &selfURL, GitURL: &gitURL, @@ -206,7 +208,8 @@ func TestCreateOrUpdateRepoFileForCreate(t *testing.T) { defer gitRepo.Close() commitID, _ := gitRepo.GetBranchCommitID(opts.NewBranch) - expectedFileResponse := getExpectedFileResponseForRepofilesCreate(commitID) + lastCommit, _ := gitRepo.GetCommitByPath("new/file.txt") + expectedFileResponse := getExpectedFileResponseForRepofilesCreate(commitID, lastCommit.ID.String()) assert.NotNil(t, expectedFileResponse) if expectedFileResponse != nil { assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content) @@ -241,8 +244,9 @@ func TestCreateOrUpdateRepoFileForUpdate(t *testing.T) { gitRepo, _ := git.OpenRepository(git.DefaultContext, repo.RepoPath()) defer gitRepo.Close() - commitID, _ := gitRepo.GetBranchCommitID(opts.NewBranch) - expectedFileResponse := getExpectedFileResponseForRepofilesUpdate(commitID, opts.TreePath) + commit, _ := gitRepo.GetBranchCommit(opts.NewBranch) + lastCommit, _ := commit.GetCommitByPath(opts.TreePath) + expectedFileResponse := getExpectedFileResponseForRepofilesUpdate(commit.ID.String(), opts.TreePath, lastCommit.ID.String()) assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content) assert.EqualValues(t, expectedFileResponse.Commit.SHA, fileResponse.Commit.SHA) assert.EqualValues(t, expectedFileResponse.Commit.HTMLURL, fileResponse.Commit.HTMLURL) @@ -277,7 +281,8 @@ func TestCreateOrUpdateRepoFileForUpdateWithFileMove(t *testing.T) { defer gitRepo.Close() commit, _ := gitRepo.GetBranchCommit(opts.NewBranch) - expectedFileResponse := getExpectedFileResponseForRepofilesUpdate(commit.ID.String(), opts.TreePath) + lastCommit, _ := commit.GetCommitByPath(opts.TreePath) + expectedFileResponse := getExpectedFileResponseForRepofilesUpdate(commit.ID.String(), opts.TreePath, lastCommit.ID.String()) // assert that the old file no longer exists in the last commit of the branch fromEntry, err := commit.GetTreeEntryByPath(opts.FromTreePath) switch err.(type) { @@ -326,8 +331,9 @@ func TestCreateOrUpdateRepoFileWithoutBranchNames(t *testing.T) { gitRepo, _ := git.OpenRepository(git.DefaultContext, repo.RepoPath()) defer gitRepo.Close() - commitID, _ := gitRepo.GetBranchCommitID(repo.DefaultBranch) - expectedFileResponse := getExpectedFileResponseForRepofilesUpdate(commitID, opts.TreePath) + commit, _ := gitRepo.GetBranchCommit(repo.DefaultBranch) + lastCommit, _ := commit.GetCommitByPath(opts.TreePath) + expectedFileResponse := getExpectedFileResponseForRepofilesUpdate(commit.ID.String(), opts.TreePath, lastCommit.ID.String()) assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content) }) } diff --git a/main.go b/main.go index ac60f85a6680b..0e550f05ebca2 100644 --- a/main.go +++ b/main.go @@ -171,9 +171,9 @@ func setAppHelpTemplates() { } func adjustHelpTemplate(originalTemplate string) string { - overrided := "" + overridden := "" if _, ok := os.LookupEnv("GITEA_CUSTOM"); ok { - overrided = "(GITEA_CUSTOM)" + overridden = "(GITEA_CUSTOM)" } return fmt.Sprintf(`%s @@ -183,7 +183,7 @@ DEFAULT CONFIGURATION: AppPath: %s AppWorkPath: %s -`, originalTemplate, setting.CustomPath, overrided, setting.CustomConf, setting.AppPath, setting.AppWorkPath) +`, originalTemplate, setting.CustomPath, overridden, setting.CustomConf, setting.AppPath, setting.AppWorkPath) } func formatBuiltWith() string { diff --git a/models/auth/webauthn.go b/models/auth/webauthn.go index 2dc3043780101..d3062342f545b 100644 --- a/models/auth/webauthn.go +++ b/models/auth/webauthn.go @@ -6,7 +6,6 @@ package auth import ( "context" - "encoding/base32" "fmt" "strings" @@ -20,14 +19,14 @@ import ( // ErrWebAuthnCredentialNotExist represents a "ErrWebAuthnCRedentialNotExist" kind of error. type ErrWebAuthnCredentialNotExist struct { ID int64 - CredentialID string + CredentialID []byte } func (err ErrWebAuthnCredentialNotExist) Error() string { - if err.CredentialID == "" { + if len(err.CredentialID) == 0 { return fmt.Sprintf("WebAuthn credential does not exist [id: %d]", err.ID) } - return fmt.Sprintf("WebAuthn credential does not exist [credential_id: %s]", err.CredentialID) + return fmt.Sprintf("WebAuthn credential does not exist [credential_id: %x]", err.CredentialID) } // IsErrWebAuthnCredentialNotExist checks if an error is a ErrWebAuthnCredentialNotExist. @@ -43,7 +42,7 @@ type WebAuthnCredential struct { Name string LowerName string `xorm:"unique(s)"` UserID int64 `xorm:"INDEX unique(s)"` - CredentialID string `xorm:"INDEX VARCHAR(410)"` + CredentialID []byte `xorm:"INDEX VARBINARY(1024)"` PublicKey []byte AttestationType string AAGUID []byte @@ -94,9 +93,8 @@ type WebAuthnCredentialList []*WebAuthnCredential func (list WebAuthnCredentialList) ToCredentials() []webauthn.Credential { creds := make([]webauthn.Credential, 0, len(list)) for _, cred := range list { - credID, _ := base32.HexEncoding.DecodeString(cred.CredentialID) creds = append(creds, webauthn.Credential{ - ID: credID, + ID: cred.CredentialID, PublicKey: cred.PublicKey, AttestationType: cred.AttestationType, Authenticator: webauthn.Authenticator{ @@ -164,11 +162,11 @@ func HasWebAuthnRegistrationsByUID(uid int64) (bool, error) { } // GetWebAuthnCredentialByCredID returns WebAuthn credential by credential ID -func GetWebAuthnCredentialByCredID(userID int64, credID string) (*WebAuthnCredential, error) { +func GetWebAuthnCredentialByCredID(userID int64, credID []byte) (*WebAuthnCredential, error) { return getWebAuthnCredentialByCredID(db.DefaultContext, userID, credID) } -func getWebAuthnCredentialByCredID(ctx context.Context, userID int64, credID string) (*WebAuthnCredential, error) { +func getWebAuthnCredentialByCredID(ctx context.Context, userID int64, credID []byte) (*WebAuthnCredential, error) { cred := new(WebAuthnCredential) if found, err := db.GetEngine(ctx).Where("user_id = ? AND credential_id = ?", userID, credID).Get(cred); err != nil { return nil, err @@ -187,7 +185,7 @@ func createCredential(ctx context.Context, userID int64, name string, cred *weba c := &WebAuthnCredential{ UserID: userID, Name: name, - CredentialID: base32.HexEncoding.EncodeToString(cred.ID), + CredentialID: cred.ID, PublicKey: cred.PublicKey, AttestationType: cred.AttestationType, AAGUID: cred.Authenticator.AAGUID, diff --git a/models/auth/webauthn_test.go b/models/auth/webauthn_test.go index 216bf110806eb..cc39691ce2d36 100644 --- a/models/auth/webauthn_test.go +++ b/models/auth/webauthn_test.go @@ -5,7 +5,6 @@ package auth import ( - "encoding/base32" "testing" "code.gitea.io/gitea/models/unittest" @@ -61,9 +60,7 @@ func TestCreateCredential(t *testing.T) { res, err := CreateCredential(1, "WebAuthn Created Credential", &webauthn.Credential{ID: []byte("Test")}) assert.NoError(t, err) assert.Equal(t, "WebAuthn Created Credential", res.Name) - bs, err := base32.HexEncoding.DecodeString(res.CredentialID) - assert.NoError(t, err) - assert.Equal(t, []byte("Test"), bs) + assert.Equal(t, []byte("Test"), res.CredentialID) unittest.AssertExistsIf(t, true, &WebAuthnCredential{Name: "WebAuthn Created Credential", UserID: 1}) } diff --git a/models/db/common.go b/models/db/common.go new file mode 100644 index 0000000000000..1a59a8b5c697f --- /dev/null +++ b/models/db/common.go @@ -0,0 +1,23 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package db + +import ( + "strings" + + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/util" + + "xorm.io/builder" +) + +// BuildCaseInsensitiveLike returns a condition to check if the given value is like the given key case-insensitively. +// Handles especially SQLite correctly as UPPER there only transforms ASCII letters. +func BuildCaseInsensitiveLike(key, value string) builder.Cond { + if setting.Database.UseSQLite3 { + return builder.Like{"UPPER(" + key + ")", util.ToUpperASCII(value)} + } + return builder.Like{"UPPER(" + key + ")", strings.ToUpper(value)} +} diff --git a/models/issues/issue.go b/models/issues/issue.go index 064f0d22abd01..5bdb60f7c08c5 100644 --- a/models/issues/issue.go +++ b/models/issues/issue.go @@ -27,7 +27,6 @@ import ( "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/references" - "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" @@ -1903,23 +1902,17 @@ func GetRepoIssueStats(repoID, uid int64, filterMode int, isPull bool) (numOpen, func SearchIssueIDsByKeyword(ctx context.Context, kw string, repoIDs []int64, limit, start int) (int64, []int64, error) { repoCond := builder.In("repo_id", repoIDs) subQuery := builder.Select("id").From("issue").Where(repoCond) - // SQLite's UPPER function only transforms ASCII letters. - if setting.Database.UseSQLite3 { - kw = util.ToUpperASCII(kw) - } else { - kw = strings.ToUpper(kw) - } cond := builder.And( repoCond, builder.Or( - builder.Like{"UPPER(name)", kw}, - builder.Like{"UPPER(content)", kw}, + db.BuildCaseInsensitiveLike("name", kw), + db.BuildCaseInsensitiveLike("content", kw), builder.In("id", builder.Select("issue_id"). From("comment"). Where(builder.And( builder.Eq{"type": CommentTypeComment}, builder.In("issue_id", subQuery), - builder.Like{"UPPER(content)", kw}, + db.BuildCaseInsensitiveLike("content", kw), )), ), ), diff --git a/models/issues/issue_list.go b/models/issues/issue_list.go index 20e9949b66202..874f2a6368156 100644 --- a/models/issues/issue_list.go +++ b/models/issues/issue_list.go @@ -9,6 +9,7 @@ import ( "fmt" "code.gitea.io/gitea/models/db" + project_model "code.gitea.io/gitea/models/project" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/container" @@ -222,6 +223,46 @@ func (issues IssueList) loadMilestones(ctx context.Context) error { return nil } +func (issues IssueList) getProjectIDs() []int64 { + ids := make(map[int64]struct{}, len(issues)) + for _, issue := range issues { + projectID := issue.ProjectID() + if _, ok := ids[projectID]; !ok { + ids[projectID] = struct{}{} + } + } + return container.KeysInt64(ids) +} + +func (issues IssueList) loadProjects(ctx context.Context) error { + projectIDs := issues.getProjectIDs() + if len(projectIDs) == 0 { + return nil + } + + projectMaps := make(map[int64]*project_model.Project, len(projectIDs)) + left := len(projectIDs) + for left > 0 { + limit := db.DefaultMaxInSize + if left < limit { + limit = left + } + err := db.GetEngine(ctx). + In("id", projectIDs[:limit]). + Find(&projectMaps) + if err != nil { + return err + } + left -= limit + projectIDs = projectIDs[limit:] + } + + for _, issue := range issues { + issue.Project = projectMaps[issue.ProjectID()] + } + return nil +} + func (issues IssueList) loadAssignees(ctx context.Context) error { if len(issues) == 0 { return nil @@ -242,7 +283,7 @@ func (issues IssueList) loadAssignees(ctx context.Context) error { } rows, err := db.GetEngine(ctx).Table("issue_assignees"). Join("INNER", "`user`", "`user`.id = `issue_assignees`.assignee_id"). - In("`issue_assignees`.issue_id", issueIDs[:limit]). + In("`issue_assignees`.issue_id", issueIDs[:limit]).OrderBy(user_model.GetOrderByName()). Rows(new(AssigneeIssue)) if err != nil { return err @@ -495,6 +536,10 @@ func (issues IssueList) loadAttributes(ctx context.Context) error { return fmt.Errorf("issue.loadAttributes: loadMilestones: %v", err) } + if err := issues.loadProjects(ctx); err != nil { + return fmt.Errorf("issue.loadAttributes: loadProjects: %v", err) + } + if err := issues.loadAssignees(ctx); err != nil { return fmt.Errorf("issue.loadAttributes: loadAssignees: %v", err) } diff --git a/models/issues/milestone.go b/models/issues/milestone.go index c49799f391dc3..1021938b205ae 100644 --- a/models/issues/milestone.go +++ b/models/issues/milestone.go @@ -361,7 +361,7 @@ func (opts GetMilestonesOption) toCond() builder.Cond { } if len(opts.Name) != 0 { - cond = cond.And(builder.Like{"UPPER(name)", strings.ToUpper(opts.Name)}) + cond = cond.And(db.BuildCaseInsensitiveLike("name", opts.Name)) } return cond diff --git a/models/issues/review.go b/models/issues/review.go index 1cb99dc3373ff..5835900801778 100644 --- a/models/issues/review.go +++ b/models/issues/review.go @@ -19,6 +19,7 @@ import ( "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/modules/util" "xorm.io/builder" ) @@ -474,6 +475,35 @@ func SubmitReview(doer *user_model.User, issue *Issue, reviewType ReviewType, co return review, comm, committer.Commit() } +// GetReviewOptions represent filter options for GetReviews +type GetReviewOptions struct { + IssueID int64 + ReviewerID int64 + Dismissed util.OptionalBool +} + +// GetReviews return reviews based on GetReviewOptions +func GetReviews(ctx context.Context, opts *GetReviewOptions) ([]*Review, error) { + if opts == nil { + return nil, fmt.Errorf("opts are nil") + } + + sess := db.GetEngine(ctx) + + if opts.IssueID != 0 { + sess = sess.Where("issue_id=?", opts.IssueID) + } + if opts.ReviewerID != 0 { + sess = sess.Where("reviewer_id=?", opts.ReviewerID) + } + if !opts.Dismissed.IsNone() { + sess = sess.Where("dismissed=?", opts.Dismissed.IsTrue()) + } + + reviews := make([]*Review, 0, 4) + return reviews, sess.Find(&reviews) +} + // GetReviewersByIssueID gets the latest review of each reviewer for a pull request func GetReviewersByIssueID(issueID int64) ([]*Review, error) { reviews := make([]*Review, 0, 10) diff --git a/models/migrations/fixtures/Test_storeWebauthnCredentialIDAsBytes/expected_webauthn_credential.yml b/models/migrations/fixtures/Test_storeWebauthnCredentialIDAsBytes/expected_webauthn_credential.yml new file mode 100644 index 0000000000000..55a237a0d633d --- /dev/null +++ b/models/migrations/fixtures/Test_storeWebauthnCredentialIDAsBytes/expected_webauthn_credential.yml @@ -0,0 +1,9 @@ +- + id: 1 + credential_id: "TVHE44TOH7DF7V48SEAIT3EMMJ7TGBOQ289E5AQB34S98LFCUFJ7U2NAVI8RJG6K2F4TC8AQ8KBNO7AGEOQOL9NE43GR63HTEHJSLOG=" +- + id: 2 + credential_id: "051CLMMKB62S6M9M2A4H54K7MMCQALFJ36G4TGB2S9A47APLTILU6C6744CEBG4EKCGV357N21BSLH8JD33GQMFAR6DQ70S76P34J6FR=" +- + id: 4 + credential_id: "APU4B1NDTEVTEM60V4T0FRL7SRJMO9KIE2AKFQ8JDGTQ7VHFI41FDEFTDLBVQEAE4ER49QV2GTGVFDNBO31BPOA3OQN6879OT6MTU3G=" diff --git a/models/migrations/fixtures/Test_storeWebauthnCredentialIDAsBytes/webauthn_credential.yml b/models/migrations/fixtures/Test_storeWebauthnCredentialIDAsBytes/webauthn_credential.yml new file mode 100644 index 0000000000000..c02a76e3742a9 --- /dev/null +++ b/models/migrations/fixtures/Test_storeWebauthnCredentialIDAsBytes/webauthn_credential.yml @@ -0,0 +1,31 @@ +- + id: 1 + lower_name: "u2fkey-correctly-migrated" + name: "u2fkey-correctly-migrated" + user_id: 1 + credential_id: "TVHE44TOH7DF7V48SEAIT3EMMJ7TGBOQ289E5AQB34S98LFCUFJ7U2NAVI8RJG6K2F4TC8AQ8KBNO7AGEOQOL9NE43GR63HTEHJSLOG=" + public_key: 0x040d0967a2cad045011631187576492a0beb5b377954b4f694c5afc8bdf25270f87f09a9ab6ce9c282f447ba71b2f2bae2105b32b847e0704f310f48644e3eddf2 + attestation_type: 'fido-u2f' + sign_count: 1 + clone_warning: false +- + id: 2 + lower_name: "non-u2f-key" + name: "non-u2f-key" + user_id: 1 + credential_id: "051CLMMKB62S6M9M2A4H54K7MMCQALFJ36G4TGB2S9A47APLTILU6C6744CEBG4EKCGV357N21BSLH8JD33GQMFAR6DQ70S76P34J6FR" + public_key: 0x040d0967a2cad045011631187576492a0beb5b377954b4f694c5afc8bdf25270f87f09a9ab6ce9c282f447ba71b2f2bae2105b32b847e0704f310f48644e3eddf2 + attestation_type: 'none' + sign_count: 1 + clone_warning: false +- + id: 4 + lower_name: "packed-key" + name: "packed-key" + user_id: 1 + credential_id: "APU4B1NDTEVTEM60V4T0FRL7SRJMO9KIE2AKFQ8JDGTQ7VHFI41FDEFTDLBVQEAE4ER49QV2GTGVFDNBO31BPOA3OQN6879OT6MTU3G=" + public_key: 0x040d0967a2cad045011631187576492a0beb5b377954b4f694c5afc8bdf25270f87f09a9ab6ce9c282f447ba71b2f2bae2105b32b847e0704f310f48644e3eddf2 + attestation_type: 'fido-u2f' + sign_count: 1 + clone_warning: false + diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index 1b2a743b6d357..2719f45efbbbc 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -398,6 +398,14 @@ var migrations = []Migration{ NewMigration("Improve Action table indices v2", improveActionTableIndices), // v219 -> v220 NewMigration("Add sync_on_commit column to push_mirror table", addSyncOnCommitColForPushMirror), + // v220 -> v221 + NewMigration("Add container repository property", addContainerRepositoryProperty), + // v221 -> v222 + NewMigration("Store WebAuthentication CredentialID as bytes and increase size to at least 1024", storeWebauthnCredentialIDAsBytes), + // v222 -> v223 + NewMigration("Drop old CredentialID column", dropOldCredentialIDColumn), + // v223 -> v224 + NewMigration("Rename CredentialIDBytes column to CredentialID", renameCredentialIDBytes), } // GetCurrentDBVersion returns the current db version diff --git a/models/migrations/v219.go b/models/migrations/v219.go index 7b2eaa3292704..7b4f34b704033 100644 --- a/models/migrations/v219.go +++ b/models/migrations/v219.go @@ -9,6 +9,7 @@ import ( "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/timeutil" + "xorm.io/xorm" ) diff --git a/models/migrations/v220.go b/models/migrations/v220.go new file mode 100644 index 0000000000000..8138bc5bb1499 --- /dev/null +++ b/models/migrations/v220.go @@ -0,0 +1,28 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package migrations + +import ( + packages_model "code.gitea.io/gitea/models/packages" + container_module "code.gitea.io/gitea/modules/packages/container" + + "xorm.io/xorm" + "xorm.io/xorm/schemas" +) + +func addContainerRepositoryProperty(x *xorm.Engine) (err error) { + switch x.Dialect().URI().DBType { + case schemas.SQLITE: + _, err = x.Exec("INSERT INTO package_property (ref_type, ref_id, name, value) SELECT ?, p.id, ?, u.lower_name || '/' || p.lower_name FROM package p JOIN `user` u ON p.owner_id = u.id WHERE p.type = ?", + packages_model.PropertyTypePackage, container_module.PropertyRepository, packages_model.TypeContainer) + case schemas.MSSQL: + _, err = x.Exec("INSERT INTO package_property (ref_type, ref_id, name, value) SELECT ?, p.id, ?, u.lower_name + '/' + p.lower_name FROM package p JOIN `user` u ON p.owner_id = u.id WHERE p.type = ?", + packages_model.PropertyTypePackage, container_module.PropertyRepository, packages_model.TypeContainer) + default: + _, err = x.Exec("INSERT INTO package_property (ref_type, ref_id, name, value) SELECT ?, p.id, ?, CONCAT(u.lower_name, '/', p.lower_name) FROM package p JOIN `user` u ON p.owner_id = u.id WHERE p.type = ?", + packages_model.PropertyTypePackage, container_module.PropertyRepository, packages_model.TypeContainer) + } + return err +} diff --git a/models/migrations/v221.go b/models/migrations/v221.go new file mode 100644 index 0000000000000..f3bcfcdf1de20 --- /dev/null +++ b/models/migrations/v221.go @@ -0,0 +1,75 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package migrations + +import ( + "encoding/base32" + "fmt" + + "code.gitea.io/gitea/modules/timeutil" + + "xorm.io/xorm" +) + +func storeWebauthnCredentialIDAsBytes(x *xorm.Engine) error { + // Create webauthnCredential table + type webauthnCredential struct { + ID int64 `xorm:"pk autoincr"` + Name string + LowerName string `xorm:"unique(s)"` + UserID int64 `xorm:"INDEX unique(s)"` + CredentialID string `xorm:"INDEX VARCHAR(410)"` + // Note the lack of INDEX here - these will be created once the column is renamed in v223.go + CredentialIDBytes []byte `xorm:"VARBINARY(1024)"` // CredentialID is at most 1023 bytes as per spec released 20 July 2022 + PublicKey []byte + AttestationType string + AAGUID []byte + SignCount uint32 `xorm:"BIGINT"` + CloneWarning bool + CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` + UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` + } + if err := x.Sync2(&webauthnCredential{}); err != nil { + return err + } + + var start int + creds := make([]*webauthnCredential, 0, 50) + for { + err := x.Select("id, credential_id").OrderBy("id").Limit(50, start).Find(&creds) + if err != nil { + return err + } + + err = func() error { + sess := x.NewSession() + defer sess.Close() + if err := sess.Begin(); err != nil { + return fmt.Errorf("unable to allow start session. Error: %w", err) + } + for _, cred := range creds { + cred.CredentialIDBytes, err = base32.HexEncoding.DecodeString(cred.CredentialID) + if err != nil { + return fmt.Errorf("unable to parse credential id %s for credential[%d]: %w", cred.CredentialID, cred.ID, err) + } + count, err := sess.ID(cred.ID).Cols("credential_id_bytes").Update(cred) + if count != 1 || err != nil { + return fmt.Errorf("unable to update credential id bytes for credential[%d]: %d,%w", cred.ID, count, err) + } + } + return sess.Commit() + }() + if err != nil { + return err + } + + if len(creds) < 50 { + break + } + start += 50 + creds = creds[:0] + } + return nil +} diff --git a/models/migrations/v221_test.go b/models/migrations/v221_test.go new file mode 100644 index 0000000000000..c50ca5c873291 --- /dev/null +++ b/models/migrations/v221_test.go @@ -0,0 +1,65 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package migrations + +import ( + "encoding/base32" + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_storeWebauthnCredentialIDAsBytes(t *testing.T) { + // Create webauthnCredential table + type WebauthnCredential struct { + ID int64 `xorm:"pk autoincr"` + Name string + LowerName string `xorm:"unique(s)"` + UserID int64 `xorm:"INDEX unique(s)"` + CredentialID string `xorm:"INDEX VARCHAR(410)"` + PublicKey []byte + AttestationType string + AAGUID []byte + SignCount uint32 `xorm:"BIGINT"` + CloneWarning bool + } + + type ExpectedWebauthnCredential struct { + ID int64 `xorm:"pk autoincr"` + CredentialID string // CredentialID is at most 1023 bytes as per spec released 20 July 2022 + } + + type ConvertedWebauthnCredential struct { + ID int64 `xorm:"pk autoincr"` + CredentialIDBytes []byte `xorm:"VARBINARY(1024)"` // CredentialID is at most 1023 bytes as per spec released 20 July 2022 + } + + // Prepare and load the testing database + x, deferable := prepareTestEnv(t, 0, new(WebauthnCredential), new(ExpectedWebauthnCredential)) + defer deferable() + if x == nil || t.Failed() { + return + } + + if err := storeWebauthnCredentialIDAsBytes(x); err != nil { + assert.NoError(t, err) + return + } + + expected := []ExpectedWebauthnCredential{} + if err := x.Table("expected_webauthn_credential").Asc("id").Find(&expected); !assert.NoError(t, err) { + return + } + + got := []ConvertedWebauthnCredential{} + if err := x.Table("webauthn_credential").Select("id, credential_id_bytes").Asc("id").Find(&got); !assert.NoError(t, err) { + return + } + + for i, e := range expected { + credIDBytes, _ := base32.HexEncoding.DecodeString(e.CredentialID) + assert.Equal(t, credIDBytes, got[i].CredentialIDBytes) + } +} diff --git a/models/migrations/v222.go b/models/migrations/v222.go new file mode 100644 index 0000000000000..99acdfd20608a --- /dev/null +++ b/models/migrations/v222.go @@ -0,0 +1,64 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package migrations + +import ( + "context" + "fmt" + + "code.gitea.io/gitea/modules/timeutil" + + "xorm.io/xorm" +) + +func dropOldCredentialIDColumn(x *xorm.Engine) error { + // This migration maybe rerun so that we should check if it has been run + credentialIDExist, err := x.Dialect().IsColumnExist(x.DB(), context.Background(), "webauthn_credential", "credential_id") + if err != nil { + return err + } + if !credentialIDExist { + // Column is already non-extant + return nil + } + credentialIDBytesExists, err := x.Dialect().IsColumnExist(x.DB(), context.Background(), "webauthn_credential", "credential_id_bytes") + if err != nil { + return err + } + if !credentialIDBytesExists { + // looks like 221 hasn't properly run + return fmt.Errorf("webauthn_credential does not have a credential_id_bytes column... it is not safe to run this migration") + } + + // Create webauthnCredential table + type webauthnCredential struct { + ID int64 `xorm:"pk autoincr"` + Name string + LowerName string `xorm:"unique(s)"` + UserID int64 `xorm:"INDEX unique(s)"` + CredentialID string `xorm:"INDEX VARCHAR(410)"` + // Note the lack of the INDEX on CredentialIDBytes - we will add this in v223.go + CredentialIDBytes []byte `xorm:"VARBINARY(1024)"` // CredentialID is at most 1023 bytes as per spec released 20 July 2022 + PublicKey []byte + AttestationType string + AAGUID []byte + SignCount uint32 `xorm:"BIGINT"` + CloneWarning bool + CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` + UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` + } + if err := x.Sync2(&webauthnCredential{}); err != nil { + return err + } + + // Drop the old credential ID + sess := x.NewSession() + defer sess.Close() + + if err := dropTableColumns(sess, "webauthn_credential", "credential_id"); err != nil { + return fmt.Errorf("unable to drop old credentialID column: %w", err) + } + return sess.Commit() +} diff --git a/models/migrations/v223.go b/models/migrations/v223.go new file mode 100644 index 0000000000000..d7ee4812b8264 --- /dev/null +++ b/models/migrations/v223.go @@ -0,0 +1,103 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package migrations + +import ( + "context" + "fmt" + + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/timeutil" + + "xorm.io/xorm" +) + +func renameCredentialIDBytes(x *xorm.Engine) error { + // This migration maybe rerun so that we should check if it has been run + credentialIDExist, err := x.Dialect().IsColumnExist(x.DB(), context.Background(), "webauthn_credential", "credential_id") + if err != nil { + return err + } + if credentialIDExist { + credentialIDBytesExists, err := x.Dialect().IsColumnExist(x.DB(), context.Background(), "webauthn_credential", "credential_id_bytes") + if err != nil { + return err + } + if !credentialIDBytesExists { + return nil + } + } + + err = func() error { + // webauthnCredential table + type webauthnCredential struct { + ID int64 `xorm:"pk autoincr"` + Name string + LowerName string `xorm:"unique(s)"` + UserID int64 `xorm:"INDEX unique(s)"` + // Note the lack of INDEX here + CredentialIDBytes []byte `xorm:"VARBINARY(1024)"` // CredentialID is at most 1023 bytes as per spec released 20 July 2022 + PublicKey []byte + AttestationType string + AAGUID []byte + SignCount uint32 `xorm:"BIGINT"` + CloneWarning bool + CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` + UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` + } + sess := x.NewSession() + defer sess.Close() + if err := sess.Begin(); err != nil { + return err + } + + if err := sess.Sync2(new(webauthnCredential)); err != nil { + return fmt.Errorf("error on Sync2: %v", err) + } + + if credentialIDExist { + // if both errors and message exist, drop message at first + if err := dropTableColumns(sess, "webauthn_credential", "credential_id"); err != nil { + return err + } + } + + switch { + case setting.Database.UseMySQL: + if _, err := sess.Exec("ALTER TABLE `webauthn_credential` CHANGE credential_id_bytes credential_id VARBINARY(1024)"); err != nil { + return err + } + case setting.Database.UseMSSQL: + if _, err := sess.Exec("sp_rename 'webauthn_credential.credential_id_bytes', 'credential_id', 'COLUMN'"); err != nil { + return err + } + default: + if _, err := sess.Exec("ALTER TABLE `webauthn_credential` RENAME COLUMN credential_id_bytes TO credential_id"); err != nil { + return err + } + } + return sess.Commit() + }() + if err != nil { + return err + } + + // Create webauthnCredential table + type webauthnCredential struct { + ID int64 `xorm:"pk autoincr"` + Name string + LowerName string `xorm:"unique(s)"` + UserID int64 `xorm:"INDEX unique(s)"` + CredentialID []byte `xorm:"INDEX VARBINARY(1024)"` // CredentialID is at most 1023 bytes as per spec released 20 July 2022 + PublicKey []byte + AttestationType string + AAGUID []byte + SignCount uint32 `xorm:"BIGINT"` + CloneWarning bool + CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` + UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` + } + return x.Sync2(&webauthnCredential{}) +} diff --git a/models/organization/team_repo.go b/models/organization/team_repo.go index fb3f267f817af..3ac4fa926b839 100644 --- a/models/organization/team_repo.go +++ b/models/organization/team_repo.go @@ -81,5 +81,6 @@ func GetTeamsWithAccessToRepo(ctx context.Context, orgID, repoID int64, mode per Join("INNER", "team_repo", "team_repo.team_id = team.id"). And("team_repo.org_id = ?", orgID). And("team_repo.repo_id = ?", repoID). + OrderBy("name"). Find(&teams) } diff --git a/models/packages/container/search.go b/models/packages/container/search.go index 972cac9528f86..a3409fe743117 100644 --- a/models/packages/container/search.go +++ b/models/packages/container/search.go @@ -12,6 +12,7 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/packages" + user_model "code.gitea.io/gitea/models/user" container_module "code.gitea.io/gitea/modules/packages/container" "xorm.io/builder" @@ -210,6 +211,7 @@ func SearchImageTags(ctx context.Context, opts *ImageTagsSearchOptions) ([]*pack return pvs, count, err } +// SearchExpiredUploadedBlobs gets all uploaded blobs which are older than specified func SearchExpiredUploadedBlobs(ctx context.Context, olderThan time.Duration) ([]*packages.PackageFile, error) { var cond builder.Cond = builder.Eq{ "package_version.is_internal": true, @@ -225,3 +227,37 @@ func SearchExpiredUploadedBlobs(ctx context.Context, olderThan time.Duration) ([ Where(cond). Find(&pfs) } + +// GetRepositories gets a sorted list of all repositories +func GetRepositories(ctx context.Context, actor *user_model.User, n int, last string) ([]string, error) { + var cond builder.Cond = builder.Eq{ + "package.type": packages.TypeContainer, + "package_property.ref_type": packages.PropertyTypePackage, + "package_property.name": container_module.PropertyRepository, + } + + cond = cond.And(builder.Exists( + builder. + Select("package_version.id"). + Where(builder.Eq{"package_version.is_internal": false}.And(builder.Expr("package.id = package_version.package_id"))). + From("package_version"), + )) + + if last != "" { + cond = cond.And(builder.Gt{"package_property.value": strings.ToLower(last)}) + } + + cond = cond.And(user_model.BuildCanSeeUserCondition(actor)) + + sess := db.GetEngine(ctx). + Table("package"). + Select("package_property.value"). + Join("INNER", "user", "`user`.id = package.owner_id"). + Join("INNER", "package_property", "package_property.ref_id = package.id"). + Where(cond). + Asc("package_property.value"). + Limit(n) + + repositories := make([]string, 0, n) + return repositories, sess.Find(&repositories) +} diff --git a/models/packages/descriptor.go b/models/packages/descriptor.go index fbdc40f37fbb2..dc753421d0210 100644 --- a/models/packages/descriptor.go +++ b/models/packages/descriptor.go @@ -19,6 +19,7 @@ import ( "code.gitea.io/gitea/modules/packages/maven" "code.gitea.io/gitea/modules/packages/npm" "code.gitea.io/gitea/modules/packages/nuget" + "code.gitea.io/gitea/modules/packages/pub" "code.gitea.io/gitea/modules/packages/pypi" "code.gitea.io/gitea/modules/packages/rubygems" @@ -40,15 +41,16 @@ func (l PackagePropertyList) GetByName(name string) string { // PackageDescriptor describes a package type PackageDescriptor struct { - Package *Package - Owner *user_model.User - Repository *repo_model.Repository - Version *PackageVersion - SemVer *version.Version - Creator *user_model.User - Properties PackagePropertyList - Metadata interface{} - Files []*PackageFileDescriptor + Package *Package + Owner *user_model.User + Repository *repo_model.Repository + Version *PackageVersion + SemVer *version.Version + Creator *user_model.User + PackageProperties PackagePropertyList + VersionProperties PackagePropertyList + Metadata interface{} + Files []*PackageFileDescriptor } // PackageFileDescriptor describes a package file @@ -102,6 +104,10 @@ func GetPackageDescriptor(ctx context.Context, pv *PackageVersion) (*PackageDesc return nil, err } } + pps, err := GetProperties(ctx, PropertyTypePackage, p.ID) + if err != nil { + return nil, err + } pvps, err := GetProperties(ctx, PropertyTypeVersion, pv.ID) if err != nil { return nil, err @@ -138,6 +144,8 @@ func GetPackageDescriptor(ctx context.Context, pv *PackageVersion) (*PackageDesc metadata = &npm.Metadata{} case TypeMaven: metadata = &maven.Metadata{} + case TypePub: + metadata = &pub.Metadata{} case TypePyPI: metadata = &pypi.Metadata{} case TypeRubyGems: @@ -152,15 +160,16 @@ func GetPackageDescriptor(ctx context.Context, pv *PackageVersion) (*PackageDesc } return &PackageDescriptor{ - Package: p, - Owner: o, - Repository: repository, - Version: pv, - SemVer: semVer, - Creator: creator, - Properties: PackagePropertyList(pvps), - Metadata: metadata, - Files: pfds, + Package: p, + Owner: o, + Repository: repository, + Version: pv, + SemVer: semVer, + Creator: creator, + PackageProperties: PackagePropertyList(pps), + VersionProperties: PackagePropertyList(pvps), + Metadata: metadata, + Files: pfds, }, nil } diff --git a/models/packages/package.go b/models/packages/package.go index bdb535492bb40..39b1c83cfabf6 100644 --- a/models/packages/package.go +++ b/models/packages/package.go @@ -39,6 +39,7 @@ const ( TypeMaven Type = "maven" TypeNpm Type = "npm" TypeNuGet Type = "nuget" + TypePub Type = "pub" TypePyPI Type = "pypi" TypeRubyGems Type = "rubygems" ) @@ -62,6 +63,8 @@ func (pt Type) Name() string { return "npm" case TypeNuGet: return "NuGet" + case TypePub: + return "Pub" case TypePyPI: return "PyPI" case TypeRubyGems: @@ -89,6 +92,8 @@ func (pt Type) SVGName() string { return "gitea-npm" case TypeNuGet: return "gitea-nuget" + case TypePub: + return "gitea-pub" case TypePyPI: return "gitea-python" case TypeRubyGems: @@ -131,6 +136,12 @@ func TryInsertPackage(ctx context.Context, p *Package) (*Package, error) { return p, nil } +// DeletePackageByID deletes a package by id +func DeletePackageByID(ctx context.Context, packageID int64) error { + _, err := db.GetEngine(ctx).ID(packageID).Delete(&Package{}) + return err +} + // SetRepositoryLink sets the linked repository func SetRepositoryLink(ctx context.Context, packageID, repoID int64) error { _, err := db.GetEngine(ctx).ID(packageID).Cols("repo_id").Update(&Package{RepoID: repoID}) @@ -192,21 +203,20 @@ func GetPackagesByType(ctx context.Context, ownerID int64, packageType Type) ([] Find(&ps) } -// DeletePackagesIfUnreferenced deletes a package if there are no associated versions -func DeletePackagesIfUnreferenced(ctx context.Context) error { +// FindUnreferencedPackages gets all packages without associated versions +func FindUnreferencedPackages(ctx context.Context) ([]*Package, error) { in := builder. Select("package.id"). From("package"). LeftJoin("package_version", "package_version.package_id = package.id"). Where(builder.Expr("package_version.id IS NULL")) - _, err := db.GetEngine(ctx). + ps := make([]*Package, 0, 10) + return ps, db.GetEngine(ctx). // double select workaround for MySQL // https://stackoverflow.com/questions/4471277/mysql-delete-from-with-subquery-as-condition Where(builder.In("package.id", builder.Select("id").From(in, "temp"))). - Delete(&Package{}) - - return err + Find(&ps) } // HasOwnerPackages tests if a user/org has packages diff --git a/models/packages/package_property.go b/models/packages/package_property.go index bf7dc346c6c97..fc10713801947 100644 --- a/models/packages/package_property.go +++ b/models/packages/package_property.go @@ -21,9 +21,11 @@ const ( PropertyTypeVersion PropertyType = iota // 0 // PropertyTypeFile means the reference is a package file PropertyTypeFile // 1 + // PropertyTypePackage means the reference is a package + PropertyTypePackage // 2 ) -// PackageProperty represents a property of a package version or file +// PackageProperty represents a property of a package, version or file type PackageProperty struct { ID int64 `xorm:"pk autoincr"` RefType PropertyType `xorm:"INDEX NOT NULL"` @@ -68,3 +70,9 @@ func DeletePropertyByID(ctx context.Context, propertyID int64) error { _, err := db.GetEngine(ctx).ID(propertyID).Delete(&PackageProperty{}) return err } + +// DeletePropertyByName deletes properties by name +func DeletePropertyByName(ctx context.Context, refType PropertyType, refID int64, name string) error { + _, err := db.GetEngine(ctx).Where("ref_type = ? AND ref_id = ? AND name = ?", refType, refID, name).Delete(&PackageProperty{}) + return err +} diff --git a/models/packages/package_version.go b/models/packages/package_version.go index 583f832e5eec8..5479bae1c29fc 100644 --- a/models/packages/package_version.go +++ b/models/packages/package_version.go @@ -107,7 +107,7 @@ func getVersionByNameAndVersion(ctx context.Context, ownerID int64, packageType ExactMatch: true, Value: version, }, - IsInternal: isInternal, + IsInternal: util.OptionalBoolOf(isInternal), Paginator: db.NewAbsoluteListOptions(0, 1), }) if err != nil { @@ -122,8 +122,9 @@ func getVersionByNameAndVersion(ctx context.Context, ownerID int64, packageType // GetVersionsByPackageType gets all versions of a specific type func GetVersionsByPackageType(ctx context.Context, ownerID int64, packageType Type) ([]*PackageVersion, error) { pvs, _, err := SearchVersions(ctx, &PackageSearchOptions{ - OwnerID: ownerID, - Type: packageType, + OwnerID: ownerID, + Type: packageType, + IsInternal: util.OptionalBoolFalse, }) return pvs, err } @@ -137,6 +138,7 @@ func GetVersionsByPackageName(ctx context.Context, ownerID int64, packageType Ty ExactMatch: true, Value: name, }, + IsInternal: util.OptionalBoolFalse, }) return pvs, err } @@ -171,7 +173,7 @@ type PackageSearchOptions struct { Name SearchValue // only results with the specific name are found Version SearchValue // only results with the specific version are found Properties map[string]string // only results are found which contain all listed version properties with the specific value - IsInternal bool + IsInternal util.OptionalBool HasFileWithName string // only results are found which are associated with a file with the specific name HasFiles util.OptionalBool // only results are found which have associated files Sort string @@ -179,7 +181,10 @@ type PackageSearchOptions struct { } func (opts *PackageSearchOptions) toConds() builder.Cond { - var cond builder.Cond = builder.Eq{"package_version.is_internal": opts.IsInternal} + cond := builder.NewCond() + if !opts.IsInternal.IsNone() { + cond = builder.Eq{"package_version.is_internal": opts.IsInternal.IsTrue()} + } if opts.OwnerID != 0 { cond = cond.And(builder.Eq{"package.owner_id": opts.OwnerID}) diff --git a/models/project/project.go b/models/project/project.go index 0aa37cc5c9071..86a77947d8838 100644 --- a/models/project/project.go +++ b/models/project/project.go @@ -330,3 +330,40 @@ func DeleteProjectByIDCtx(ctx context.Context, id int64) error { return updateRepositoryProjectCount(ctx, p.RepoID) } + +func DeleteProjectByRepoIDCtx(ctx context.Context, repoID int64) error { + switch { + case setting.Database.UseSQLite3: + if _, err := db.GetEngine(ctx).Exec("DELETE FROM project_issue WHERE project_issue.id IN (SELECT project_issue.id FROM project_issue INNER JOIN project WHERE project.id = project_issue.project_id AND project.repo_id = ?)", repoID); err != nil { + return err + } + if _, err := db.GetEngine(ctx).Exec("DELETE FROM project_board WHERE project_board.id IN (SELECT project_board.id FROM project_board INNER JOIN project WHERE project.id = project_board.project_id AND project.repo_id = ?)", repoID); err != nil { + return err + } + if _, err := db.GetEngine(ctx).Table("project").Where("repo_id = ? ", repoID).Delete(&Project{}); err != nil { + return err + } + case setting.Database.UsePostgreSQL: + if _, err := db.GetEngine(ctx).Exec("DELETE FROM project_issue USING project WHERE project.id = project_issue.project_id AND project.repo_id = ? ", repoID); err != nil { + return err + } + if _, err := db.GetEngine(ctx).Exec("DELETE FROM project_board USING project WHERE project.id = project_board.project_id AND project.repo_id = ? ", repoID); err != nil { + return err + } + if _, err := db.GetEngine(ctx).Table("project").Where("repo_id = ? ", repoID).Delete(&Project{}); err != nil { + return err + } + default: + if _, err := db.GetEngine(ctx).Exec("DELETE project_issue FROM project_issue INNER JOIN project ON project.id = project_issue.project_id WHERE project.repo_id = ? ", repoID); err != nil { + return err + } + if _, err := db.GetEngine(ctx).Exec("DELETE project_board FROM project_board INNER JOIN project ON project.id = project_board.project_id WHERE project.repo_id = ? ", repoID); err != nil { + return err + } + if _, err := db.GetEngine(ctx).Table("project").Where("repo_id = ? ", repoID).Delete(&Project{}); err != nil { + return err + } + } + + return updateRepositoryProjectCount(ctx, repoID) +} diff --git a/models/repo.go b/models/repo.go index ca83b03e42ca1..66ef51473950f 100644 --- a/models/repo.go +++ b/models/repo.go @@ -342,16 +342,8 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error { } } - projects, _, err := project_model.GetProjects(ctx, project_model.SearchOptions{ - RepoID: repoID, - }) - if err != nil { - return fmt.Errorf("get projects: %v", err) - } - for i := range projects { - if err := project_model.DeleteProjectByIDCtx(ctx, projects[i].ID); err != nil { - return fmt.Errorf("delete project [%d]: %v", projects[i].ID, err) - } + if err := project_model.DeleteProjectByRepoIDCtx(ctx, repoID); err != nil { + return fmt.Errorf("unable to delete projects for repo[%d]: %v", repoID, err) } // Remove LFS objects diff --git a/models/repo/pushmirror.go b/models/repo/pushmirror.go index 0a7dea79c93b3..02ffcbee76a50 100644 --- a/models/repo/pushmirror.go +++ b/models/repo/pushmirror.go @@ -5,12 +5,15 @@ package repo import ( + "context" "errors" "time" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/timeutil" + + "xorm.io/builder" ) // ErrPushMirrorNotExist mirror does not exist error @@ -29,6 +32,25 @@ type PushMirror struct { LastUpdateUnix timeutil.TimeStamp `xorm:"INDEX last_update"` LastError string `xorm:"text"` } +type PushMirrorOptions struct { + ID int64 + RepoID int64 + RemoteName string +} + +func (opts *PushMirrorOptions) toConds() builder.Cond { + cond := builder.NewCond() + if opts.RepoID > 0 { + cond = cond.And(builder.Eq{"repo_id": opts.RepoID}) + } + if opts.RemoteName != "" { + cond = cond.And(builder.Eq{"remote_name": opts.RemoteName}) + } + if opts.ID > 0 { + cond = cond.And(builder.Eq{"id": opts.ID}) + } + return cond +} func init() { db.RegisterModel(new(PushMirror)) @@ -53,45 +75,48 @@ func (m *PushMirror) GetRemoteName() string { } // InsertPushMirror inserts a push-mirror to database -func InsertPushMirror(m *PushMirror) error { - _, err := db.GetEngine(db.DefaultContext).Insert(m) +func InsertPushMirror(ctx context.Context, m *PushMirror) error { + _, err := db.GetEngine(ctx).Insert(m) return err } // UpdatePushMirror updates the push-mirror -func UpdatePushMirror(m *PushMirror) error { - _, err := db.GetEngine(db.DefaultContext).ID(m.ID).AllCols().Update(m) - return err -} - -// DeletePushMirrorByID deletes a push-mirrors by ID -func DeletePushMirrorByID(ID int64) error { - _, err := db.GetEngine(db.DefaultContext).ID(ID).Delete(&PushMirror{}) +func UpdatePushMirror(ctx context.Context, m *PushMirror) error { + _, err := db.GetEngine(ctx).ID(m.ID).AllCols().Update(m) return err } -// DeletePushMirrorsByRepoID deletes all push-mirrors by repoID -func DeletePushMirrorsByRepoID(repoID int64) error { - _, err := db.GetEngine(db.DefaultContext).Delete(&PushMirror{RepoID: repoID}) - return err +func DeletePushMirrors(ctx context.Context, opts PushMirrorOptions) error { + if opts.RepoID > 0 { + _, err := db.GetEngine(ctx).Where(opts.toConds()).Delete(&PushMirror{}) + return err + } + return errors.New("repoID required and must be set") } -// GetPushMirrorByID returns push-mirror information. -func GetPushMirrorByID(ID int64) (*PushMirror, error) { - m := &PushMirror{} - has, err := db.GetEngine(db.DefaultContext).ID(ID).Get(m) +func GetPushMirror(ctx context.Context, opts PushMirrorOptions) (*PushMirror, error) { + mirror := &PushMirror{} + exist, err := db.GetEngine(ctx).Where(opts.toConds()).Get(mirror) if err != nil { return nil, err - } else if !has { + } else if !exist { return nil, ErrPushMirrorNotExist } - return m, nil + return mirror, nil } // GetPushMirrorsByRepoID returns push-mirror information of a repository. -func GetPushMirrorsByRepoID(repoID int64) ([]*PushMirror, error) { +func GetPushMirrorsByRepoID(ctx context.Context, repoID int64, listOptions db.ListOptions) ([]*PushMirror, int64, error) { + sess := db.GetEngine(ctx).Where("repo_id = ?", repoID) + if listOptions.Page != 0 { + sess = db.SetSessionPagination(sess, &listOptions) + mirrors := make([]*PushMirror, 0, listOptions.PageSize) + count, err := sess.FindAndCount(&mirrors) + return mirrors, count, err + } mirrors := make([]*PushMirror, 0, 10) - return mirrors, db.GetEngine(db.DefaultContext).Where("repo_id=?", repoID).Find(&mirrors) + count, err := sess.FindAndCount(&mirrors) + return mirrors, count, err } // GetPushMirrorsSyncedOnCommit returns push-mirrors for this repo that should be updated by new commits @@ -103,8 +128,8 @@ func GetPushMirrorsSyncedOnCommit(repoID int64) ([]*PushMirror, error) { } // PushMirrorsIterate iterates all push-mirror repositories. -func PushMirrorsIterate(limit int, f func(idx int, bean interface{}) error) error { - return db.GetEngine(db.DefaultContext). +func PushMirrorsIterate(ctx context.Context, limit int, f func(idx int, bean interface{}) error) error { + return db.GetEngine(ctx). Where("last_update + (`interval` / ?) <= ?", time.Second, time.Now().Unix()). And("`interval` != 0"). OrderBy("last_update ASC"). diff --git a/models/repo/pushmirror_test.go b/models/repo/pushmirror_test.go index d36a48547e1c6..5087e30095773 100644 --- a/models/repo/pushmirror_test.go +++ b/models/repo/pushmirror_test.go @@ -8,6 +8,7 @@ import ( "testing" "time" + "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/timeutil" @@ -20,20 +21,20 @@ func TestPushMirrorsIterate(t *testing.T) { now := timeutil.TimeStampNow() - repo_model.InsertPushMirror(&repo_model.PushMirror{ + repo_model.InsertPushMirror(db.DefaultContext, &repo_model.PushMirror{ RemoteName: "test-1", LastUpdateUnix: now, Interval: 1, }) long, _ := time.ParseDuration("24h") - repo_model.InsertPushMirror(&repo_model.PushMirror{ + repo_model.InsertPushMirror(db.DefaultContext, &repo_model.PushMirror{ RemoteName: "test-2", LastUpdateUnix: now, Interval: long, }) - repo_model.InsertPushMirror(&repo_model.PushMirror{ + repo_model.InsertPushMirror(db.DefaultContext, &repo_model.PushMirror{ RemoteName: "test-3", LastUpdateUnix: now, Interval: 0, @@ -41,7 +42,7 @@ func TestPushMirrorsIterate(t *testing.T) { time.Sleep(1 * time.Millisecond) - repo_model.PushMirrorsIterate(1, func(idx int, bean interface{}) error { + repo_model.PushMirrorsIterate(db.DefaultContext, 1, func(idx int, bean interface{}) error { m, ok := bean.(*repo_model.PushMirror) assert.True(t, ok) assert.Equal(t, "test-1", m.RemoteName) diff --git a/models/repo/repo_list.go b/models/repo/repo_list.go index a70fc8efd409a..9de76fa5ffa14 100644 --- a/models/repo/repo_list.go +++ b/models/repo/repo_list.go @@ -6,6 +6,7 @@ package repo import ( "context" + "errors" "fmt" "strings" @@ -695,6 +696,9 @@ func GetUserRepositories(opts *SearchRepoOptions) (RepositoryList, int64, error) } cond := builder.NewCond() + if opts.Actor == nil { + return nil, 0, errors.New("GetUserRepositories: Actor is needed but not given") + } cond = cond.And(builder.Eq{"owner_id": opts.Actor.ID}) if !opts.Private { cond = cond.And(builder.Eq{"is_private": false}) diff --git a/models/repo/user_repo.go b/models/repo/user_repo.go index e697505b81e4e..71e0c57550c56 100644 --- a/models/repo/user_repo.go +++ b/models/repo/user_repo.go @@ -109,7 +109,7 @@ func GetRepoAssignees(ctx context.Context, repo *Repository) (_ []*user_model.Us // and just waste 1 unit is cheaper than re-allocate memory once. users := make([]*user_model.User, 0, len(userIDs)+1) if len(userIDs) > 0 { - if err = e.In("id", userIDs).Find(&users); err != nil { + if err = e.In("id", userIDs).OrderBy(user_model.GetOrderByName()).Find(&users); err != nil { return nil, err } } @@ -168,5 +168,5 @@ func GetReviewers(ctx context.Context, repo *Repository, doerID, posterID int64) } users := make([]*user_model.User, 0, 8) - return users, db.GetEngine(ctx).Where(cond).OrderBy("name").Find(&users) + return users, db.GetEngine(ctx).Where(cond).OrderBy(user_model.GetOrderByName()).Find(&users) } diff --git a/models/user.go b/models/user.go index 49374014aa7db..86a714e746bb2 100644 --- a/models/user.go +++ b/models/user.go @@ -27,7 +27,7 @@ import ( ) // DeleteUser deletes models associated to an user. -func DeleteUser(ctx context.Context, u *user_model.User) (err error) { +func DeleteUser(ctx context.Context, u *user_model.User, purge bool) (err error) { e := db.GetEngine(ctx) // ***** START: Watch ***** @@ -95,8 +95,8 @@ func DeleteUser(ctx context.Context, u *user_model.User) (err error) { return err } - if setting.Service.UserDeleteWithCommentsMaxTime != 0 && - u.CreatedUnix.AsTime().Add(setting.Service.UserDeleteWithCommentsMaxTime).After(time.Now()) { + if purge || (setting.Service.UserDeleteWithCommentsMaxTime != 0 && + u.CreatedUnix.AsTime().Add(setting.Service.UserDeleteWithCommentsMaxTime).After(time.Now())) { // Delete Comments const batchSize = 50 diff --git a/models/user/search.go b/models/user/search.go index 1b65dcb12d46c..f8e6c89f06804 100644 --- a/models/user/search.go +++ b/models/user/search.go @@ -58,31 +58,7 @@ func (opts *SearchUserOptions) toSearchQueryBase() *xorm.Session { cond = cond.And(builder.In("visibility", opts.Visible)) } - if opts.Actor != nil { - exprCond := builder.Expr("org_user.org_id = `user`.id") - - // If Admin - they see all users! - if !opts.Actor.IsAdmin { - // Force visibility for privacy - var accessCond builder.Cond - if !opts.Actor.IsRestricted { - accessCond = builder.Or( - builder.In("id", builder.Select("org_id").From("org_user").LeftJoin("`user`", exprCond).Where(builder.And(builder.Eq{"uid": opts.Actor.ID}, builder.Eq{"visibility": structs.VisibleTypePrivate}))), - builder.In("visibility", structs.VisibleTypePublic, structs.VisibleTypeLimited)) - } else { - // restricted users only see orgs they are a member of - accessCond = builder.In("id", builder.Select("org_id").From("org_user").LeftJoin("`user`", exprCond).Where(builder.And(builder.Eq{"uid": opts.Actor.ID}))) - } - // Don't forget about self - accessCond = accessCond.Or(builder.Eq{"id": opts.Actor.ID}) - cond = cond.And(accessCond) - } - - } else { - // Force visibility for privacy - // Not logged in - only public users - cond = cond.And(builder.In("visibility", structs.VisibleTypePublic)) - } + cond = cond.And(BuildCanSeeUserCondition(opts.Actor)) if opts.UID > 0 { cond = cond.And(builder.Eq{"id": opts.UID}) @@ -170,3 +146,26 @@ func IterateUser(f func(user *User) error) error { } } } + +// BuildCanSeeUserCondition creates a condition which can be used to restrict results to users/orgs the actor can see +func BuildCanSeeUserCondition(actor *User) builder.Cond { + if actor != nil { + // If Admin - they see all users! + if !actor.IsAdmin { + // Users can see an organization they are a member of + cond := builder.In("`user`.id", builder.Select("org_id").From("org_user").Where(builder.Eq{"uid": actor.ID})) + if !actor.IsRestricted { + // Not-Restricted users can see public and limited users/organizations + cond = cond.Or(builder.In("`user`.visibility", structs.VisibleTypePublic, structs.VisibleTypeLimited)) + } + // Don't forget about self + return cond.Or(builder.Eq{"`user`.id": actor.ID}) + } + + return nil + } + + // Force visibility for privacy + // Not logged in - only public users + return builder.In("`user`.visibility", structs.VisibleTypePublic) +} diff --git a/models/user/user.go b/models/user/user.go index 125c643f3ee88..91eeeb8962526 100644 --- a/models/user/user.go +++ b/models/user/user.go @@ -64,12 +64,14 @@ var AvailableHashAlgorithms = []string{ } const ( - // EmailNotificationsEnabled indicates that the user would like to receive all email notifications + // EmailNotificationsEnabled indicates that the user would like to receive all email notifications except your own EmailNotificationsEnabled = "enabled" // EmailNotificationsOnMention indicates that the user would like to be notified via email when mentioned. EmailNotificationsOnMention = "onmention" // EmailNotificationsDisabled indicates that the user would not like to be notified via email. EmailNotificationsDisabled = "disabled" + // EmailNotificationsEnabled indicates that the user would like to receive all email notifications and your own + EmailNotificationsAndYourOwn = "andyourown" ) // User represents the object of individual and member of organization. @@ -1045,7 +1047,7 @@ func GetMaileableUsersByIDs(ids []int64, isMention bool) ([]*User, error) { Where("`type` = ?", UserTypeIndividual). And("`prohibit_login` = ?", false). And("`is_active` = ?", true). - And("`email_notifications_preference` IN ( ?, ?)", EmailNotificationsEnabled, EmailNotificationsOnMention). + In("`email_notifications_preference`", EmailNotificationsEnabled, EmailNotificationsOnMention, EmailNotificationsAndYourOwn). Find(&ous) } @@ -1053,7 +1055,7 @@ func GetMaileableUsersByIDs(ids []int64, isMention bool) ([]*User, error) { Where("`type` = ?", UserTypeIndividual). And("`prohibit_login` = ?", false). And("`is_active` = ?", true). - And("`email_notifications_preference` = ?", EmailNotificationsEnabled). + In("`email_notifications_preference`", EmailNotificationsEnabled, EmailNotificationsAndYourOwn). Find(&ous) } @@ -1314,3 +1316,10 @@ func IsUserVisibleToViewer(ctx context.Context, u, viewer *User) bool { } return false } + +func GetOrderByName() string { + if setting.UI.DefaultShowFullName { + return "full_name, name" + } + return "name" +} diff --git a/models/user/user_test.go b/models/user/user_test.go index 4994ac53ab3df..489ee3b05da35 100644 --- a/models/user/user_test.go +++ b/models/user/user_test.go @@ -153,6 +153,9 @@ func TestEmailNotificationPreferences(t *testing.T) { assert.NoError(t, user_model.SetEmailNotifications(user, user_model.EmailNotificationsDisabled)) assert.Equal(t, user_model.EmailNotificationsDisabled, user.EmailNotifications()) + + assert.NoError(t, user_model.SetEmailNotifications(user, user_model.EmailNotificationsAndYourOwn)) + assert.Equal(t, user_model.EmailNotificationsAndYourOwn, user.EmailNotifications()) } } diff --git a/models/webhook/webhook.go b/models/webhook/webhook.go index 1b79a414ade52..478a6a29ff236 100644 --- a/models/webhook/webhook.go +++ b/models/webhook/webhook.go @@ -399,6 +399,10 @@ func CreateWebhook(ctx context.Context, w *Webhook) error { // CreateWebhooks creates multiple web hooks func CreateWebhooks(ctx context.Context, ws []*Webhook) error { + // xorm returns err "no element on slice when insert" for empty slices. + if len(ws) == 0 { + return nil + } for i := 0; i < len(ws); i++ { ws[i].Type = strings.TrimSpace(ws[i].Type) } diff --git a/modules/context/api.go b/modules/context/api.go index 558a9f51ee34f..b9d130e2a8ac0 100644 --- a/modules/context/api.go +++ b/modules/context/api.go @@ -16,6 +16,7 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/cache" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/httpcache" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/web/middleware" @@ -268,6 +269,7 @@ func APIContexter() func(http.Handler) http.Handler { } } + httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 0, "no-transform") ctx.Resp.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions) ctx.Data["Context"] = &ctx diff --git a/modules/context/context.go b/modules/context/context.go index 68f8a1b408c1f..8824911619921 100644 --- a/modules/context/context.go +++ b/modules/context/context.go @@ -28,6 +28,7 @@ import ( "code.gitea.io/gitea/modules/base" mc "code.gitea.io/gitea/modules/cache" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/httpcache" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" @@ -767,6 +768,7 @@ func Contexter() func(next http.Handler) http.Handler { } } + httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 0, "no-transform") ctx.Resp.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions) ctx.Data["CsrfToken"] = ctx.csrf.GetToken() diff --git a/modules/context/org.go b/modules/context/org.go index 9f4ce485e5ee7..d020befa40165 100644 --- a/modules/context/org.go +++ b/modules/context/org.go @@ -12,6 +12,7 @@ import ( "code.gitea.io/gitea/models/perm" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/structs" ) // Organization contains organization context @@ -69,6 +70,20 @@ func HandleOrgAssignment(ctx *Context, args ...bool) { return } org := ctx.Org.Organization + + // Handle Visibility + if org.Visibility != structs.VisibleTypePublic && !ctx.IsSigned { + // We must be signed in to see limited or private organizations + ctx.NotFound("OrgAssignment", err) + return + } + + if org.Visibility == structs.VisibleTypePrivate { + requireMember = true + } else if ctx.IsSigned && ctx.Doer.IsRestricted { + requireMember = true + } + ctx.ContextUser = org.AsUser() ctx.Data["Org"] = org diff --git a/modules/context/package.go b/modules/context/package.go index 4c52907dc529c..92a97831ddc0b 100644 --- a/modules/context/package.go +++ b/modules/context/package.go @@ -11,6 +11,7 @@ import ( "code.gitea.io/gitea/models/organization" packages_model "code.gitea.io/gitea/models/packages" "code.gitea.io/gitea/models/perm" + "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/structs" ) @@ -52,14 +53,30 @@ func packageAssignment(ctx *Context, errCb func(int, string, interface{})) { } if ctx.Package.Owner.IsOrganization() { + org := organization.OrgFromUser(ctx.Package.Owner) + // 1. Get user max authorize level for the org (may be none, if user is not member of the org) if ctx.Doer != nil { var err error - ctx.Package.AccessMode, err = organization.OrgFromUser(ctx.Package.Owner).GetOrgUserMaxAuthorizeLevel(ctx.Doer.ID) + ctx.Package.AccessMode, err = org.GetOrgUserMaxAuthorizeLevel(ctx.Doer.ID) if err != nil { errCb(http.StatusInternalServerError, "GetOrgUserMaxAuthorizeLevel", err) return } + // If access mode is less than write check every team for more permissions + if ctx.Package.AccessMode < perm.AccessModeWrite { + teams, err := organization.GetUserOrgTeams(ctx, org.ID, ctx.Doer.ID) + if err != nil { + errCb(http.StatusInternalServerError, "GetUserOrgTeams", err) + return + } + for _, t := range teams { + perm := t.UnitAccessModeCtx(ctx, unit.TypePackages) + if ctx.Package.AccessMode < perm { + ctx.Package.AccessMode = perm + } + } + } } // 2. If authorize level is none, check if org is visible to user if ctx.Package.AccessMode == perm.AccessModeNone && organization.HasOrgOrUserVisible(ctx, ctx.Package.Owner, ctx.Doer) { diff --git a/modules/context/repo.go b/modules/context/repo.go index 183637391862e..ea40542069991 100644 --- a/modules/context/repo.go +++ b/modules/context/repo.go @@ -393,7 +393,7 @@ func repoAssignment(ctx *Context, repo *repo_model.Repository) { } } - pushMirrors, err := repo_model.GetPushMirrorsByRepoID(repo.ID) + pushMirrors, _, err := repo_model.GetPushMirrorsByRepoID(ctx, repo.ID, db.ListOptions{}) if err != nil { ctx.ServerError("GetPushMirrorsByRepoID", err) return @@ -1001,6 +1001,8 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context return } ctx.Data["CommitsCount"] = ctx.Repo.CommitsCount + ctx.Repo.GitRepo.LastCommitCache = git.NewLastCommitCache(ctx.Repo.CommitsCount, ctx.Repo.Repository.FullName(), ctx.Repo.GitRepo, cache.GetCache()) + return cancel } } diff --git a/modules/convert/mirror.go b/modules/convert/mirror.go new file mode 100644 index 0000000000000..b2414f46774cc --- /dev/null +++ b/modules/convert/mirror.go @@ -0,0 +1,39 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package convert + +import ( + repo_model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/modules/git" + api "code.gitea.io/gitea/modules/structs" +) + +// ToPushMirror convert from repo_model.PushMirror and remoteAddress to api.TopicResponse +func ToPushMirror(pm *repo_model.PushMirror) (*api.PushMirror, error) { + repo := pm.GetRepository() + remoteAddress, err := getRemoteAddress(repo, pm.RemoteName) + if err != nil { + return nil, err + } + return &api.PushMirror{ + RepoName: repo.Name, + RemoteName: pm.RemoteName, + RemoteAddress: remoteAddress, + CreatedUnix: pm.CreatedUnix.FormatLong(), + LastUpdateUnix: pm.LastUpdateUnix.FormatLong(), + LastError: pm.LastError, + Interval: pm.Interval.String(), + }, nil +} + +func getRemoteAddress(repo *repo_model.Repository, remoteName string) (string, error) { + url, err := git.GetRemoteURL(git.DefaultContext, repo.RepoPath(), remoteName) + if err != nil { + return "", err + } + // remove confidential information + url.User = nil + return url.String(), nil +} diff --git a/modules/convert/repository.go b/modules/convert/repository.go index eb6bb37707391..d333c124b54c6 100644 --- a/modules/convert/repository.go +++ b/modules/convert/repository.go @@ -78,6 +78,8 @@ func innerToRepo(repo *repo_model.Repository, mode perm.AccessMode, isParent boo allowRebase := false allowRebaseMerge := false allowSquash := false + allowRebaseUpdate := false + defaultDeleteBranchAfterMerge := false defaultMergeStyle := repo_model.MergeStyleMerge if unit, err := repo.GetUnit(unit_model.TypePullRequests); err == nil { config := unit.PullRequestsConfig() @@ -87,6 +89,8 @@ func innerToRepo(repo *repo_model.Repository, mode perm.AccessMode, isParent boo allowRebase = config.AllowRebase allowRebaseMerge = config.AllowRebaseMerge allowSquash = config.AllowSquash + allowRebaseUpdate = config.AllowRebaseUpdate + defaultDeleteBranchAfterMerge = config.DefaultDeleteBranchAfterMerge defaultMergeStyle = config.GetDefaultMergeStyle() } hasProjects := false @@ -133,54 +137,56 @@ func innerToRepo(repo *repo_model.Repository, mode perm.AccessMode, isParent boo repoAPIURL := repo.APIURL() return &api.Repository{ - ID: repo.ID, - Owner: ToUserWithAccessMode(repo.Owner, mode), - Name: repo.Name, - FullName: repo.FullName(), - Description: repo.Description, - Private: repo.IsPrivate, - Template: repo.IsTemplate, - Empty: repo.IsEmpty, - Archived: repo.IsArchived, - Size: int(repo.Size / 1024), - Fork: repo.IsFork, - Parent: parent, - Mirror: repo.IsMirror, - HTMLURL: repo.HTMLURL(), - SSHURL: cloneLink.SSH, - CloneURL: cloneLink.HTTPS, - OriginalURL: repo.SanitizedOriginalURL(), - Website: repo.Website, - Language: language, - LanguagesURL: repoAPIURL + "/languages", - Stars: repo.NumStars, - Forks: repo.NumForks, - Watchers: repo.NumWatches, - OpenIssues: repo.NumOpenIssues, - OpenPulls: repo.NumOpenPulls, - Releases: int(numReleases), - DefaultBranch: repo.DefaultBranch, - Created: repo.CreatedUnix.AsTime(), - Updated: repo.UpdatedUnix.AsTime(), - Permissions: permission, - HasIssues: hasIssues, - ExternalTracker: externalTracker, - InternalTracker: internalTracker, - HasWiki: hasWiki, - HasProjects: hasProjects, - ExternalWiki: externalWiki, - HasPullRequests: hasPullRequests, - IgnoreWhitespaceConflicts: ignoreWhitespaceConflicts, - AllowMerge: allowMerge, - AllowRebase: allowRebase, - AllowRebaseMerge: allowRebaseMerge, - AllowSquash: allowSquash, - DefaultMergeStyle: string(defaultMergeStyle), - AvatarURL: repo.AvatarLink(), - Internal: !repo.IsPrivate && repo.Owner.Visibility == api.VisibleTypePrivate, - MirrorInterval: mirrorInterval, - MirrorUpdated: mirrorUpdated, - RepoTransfer: transfer, + ID: repo.ID, + Owner: ToUserWithAccessMode(repo.Owner, mode), + Name: repo.Name, + FullName: repo.FullName(), + Description: repo.Description, + Private: repo.IsPrivate, + Template: repo.IsTemplate, + Empty: repo.IsEmpty, + Archived: repo.IsArchived, + Size: int(repo.Size / 1024), + Fork: repo.IsFork, + Parent: parent, + Mirror: repo.IsMirror, + HTMLURL: repo.HTMLURL(), + SSHURL: cloneLink.SSH, + CloneURL: cloneLink.HTTPS, + OriginalURL: repo.SanitizedOriginalURL(), + Website: repo.Website, + Language: language, + LanguagesURL: repoAPIURL + "/languages", + Stars: repo.NumStars, + Forks: repo.NumForks, + Watchers: repo.NumWatches, + OpenIssues: repo.NumOpenIssues, + OpenPulls: repo.NumOpenPulls, + Releases: int(numReleases), + DefaultBranch: repo.DefaultBranch, + Created: repo.CreatedUnix.AsTime(), + Updated: repo.UpdatedUnix.AsTime(), + Permissions: permission, + HasIssues: hasIssues, + ExternalTracker: externalTracker, + InternalTracker: internalTracker, + HasWiki: hasWiki, + HasProjects: hasProjects, + ExternalWiki: externalWiki, + HasPullRequests: hasPullRequests, + IgnoreWhitespaceConflicts: ignoreWhitespaceConflicts, + AllowMerge: allowMerge, + AllowRebase: allowRebase, + AllowRebaseMerge: allowRebaseMerge, + AllowSquash: allowSquash, + AllowRebaseUpdate: allowRebaseUpdate, + DefaultDeleteBranchAfterMerge: defaultDeleteBranchAfterMerge, + DefaultMergeStyle: string(defaultMergeStyle), + AvatarURL: repo.AvatarLink(), + Internal: !repo.IsPrivate && repo.Owner.Visibility == api.VisibleTypePrivate, + MirrorInterval: mirrorInterval, + MirrorUpdated: mirrorUpdated, + RepoTransfer: transfer, } } diff --git a/modules/convert/user.go b/modules/convert/user.go index 2b07d21838d71..093994856cae7 100644 --- a/modules/convert/user.go +++ b/modules/convert/user.go @@ -73,6 +73,7 @@ func toUser(user *user_model.User, signed, authed bool) *api.User { // only site admin will get these information and possibly user himself if authed { result.IsAdmin = user.IsAdmin + result.LoginName = user.LoginName result.LastLogin = user.LastLoginUnix.AsTime() result.Language = user.Language result.IsActive = user.IsActive diff --git a/modules/git/command.go b/modules/git/command.go index a1bacbb707a25..b24d32dbe8743 100644 --- a/modules/git/command.go +++ b/modules/git/command.go @@ -95,14 +95,15 @@ func (c *Command) AddArguments(args ...string) *Command { return c } -// RunOpts represents parameters to run the command +// RunOpts represents parameters to run the command. If UseContextTimeout is specified, then Timeout is ignored. type RunOpts struct { - Env []string - Timeout time.Duration - Dir string - Stdout, Stderr io.Writer - Stdin io.Reader - PipelineFunc func(context.Context, context.CancelFunc) error + Env []string + Timeout time.Duration + UseContextTimeout bool + Dir string + Stdout, Stderr io.Writer + Stdin io.Reader + PipelineFunc func(context.Context, context.CancelFunc) error } func commonBaseEnvs() []string { @@ -171,7 +172,15 @@ func (c *Command) Run(opts *RunOpts) error { desc = fmt.Sprintf("%s %s [repo_path: %s]", c.name, strings.Join(args, " "), opts.Dir) } - ctx, cancel, finished := process.GetManager().AddContextTimeout(c.parentContext, opts.Timeout, desc) + var ctx context.Context + var cancel context.CancelFunc + var finished context.CancelFunc + + if opts.UseContextTimeout { + ctx, cancel, finished = process.GetManager().AddContext(c.parentContext, desc) + } else { + ctx, cancel, finished = process.GetManager().AddContextTimeout(c.parentContext, opts.Timeout, desc) + } defer finished() cmd := exec.CommandContext(ctx, c.name, c.args...) diff --git a/modules/git/commit.go b/modules/git/commit.go index 82712dd1ef3f1..32589f534980c 100644 --- a/modules/git/commit.go +++ b/modules/git/commit.go @@ -80,6 +80,9 @@ func (c *Commit) ParentCount() int { // GetCommitByPath return the commit of relative path object. func (c *Commit) GetCommitByPath(relpath string) (*Commit, error) { + if c.repo.LastCommitCache != nil { + return c.repo.LastCommitCache.GetCommitByPath(c.ID.String(), relpath) + } return c.repo.getCommitByPathWithID(c.ID, relpath) } diff --git a/modules/git/commit_info_gogit.go b/modules/git/commit_info_gogit.go index 91a1804db5cff..341698ab34fe0 100644 --- a/modules/git/commit_info_gogit.go +++ b/modules/git/commit_info_gogit.go @@ -17,7 +17,7 @@ import ( ) // GetCommitsInfo gets information of all commits that are corresponding to these entries -func (tes Entries) GetCommitsInfo(ctx context.Context, commit *Commit, treePath string, cache *LastCommitCache) ([]CommitInfo, *Commit, error) { +func (tes Entries) GetCommitsInfo(ctx context.Context, commit *Commit, treePath string) ([]CommitInfo, *Commit, error) { entryPaths := make([]string, len(tes)+1) // Get the commit for the treePath itself entryPaths[0] = "" @@ -35,15 +35,15 @@ func (tes Entries) GetCommitsInfo(ctx context.Context, commit *Commit, treePath return nil, nil, err } - var revs map[string]*object.Commit - if cache != nil { + var revs map[string]*Commit + if commit.repo.LastCommitCache != nil { var unHitPaths []string - revs, unHitPaths, err = getLastCommitForPathsByCache(commit.ID.String(), treePath, entryPaths, cache) + revs, unHitPaths, err = getLastCommitForPathsByCache(commit.ID.String(), treePath, entryPaths, commit.repo.LastCommitCache) if err != nil { return nil, nil, err } if len(unHitPaths) > 0 { - revs2, err := GetLastCommitForPaths(ctx, cache, c, treePath, unHitPaths) + revs2, err := GetLastCommitForPaths(ctx, commit.repo.LastCommitCache, c, treePath, unHitPaths) if err != nil { return nil, nil, err } @@ -68,8 +68,7 @@ func (tes Entries) GetCommitsInfo(ctx context.Context, commit *Commit, treePath } // Check if we have found a commit for this entry in time - if rev, ok := revs[entry.Name()]; ok { - entryCommit := convertCommit(rev) + if entryCommit, ok := revs[entry.Name()]; ok { commitsInfo[i].Commit = entryCommit } @@ -96,10 +95,10 @@ func (tes Entries) GetCommitsInfo(ctx context.Context, commit *Commit, treePath // get it for free during the tree traversal and it's used for listing // pages to display information about newest commit for a given path. var treeCommit *Commit + var ok bool if treePath == "" { treeCommit = commit - } else if rev, ok := revs[""]; ok { - treeCommit = convertCommit(rev) + } else if treeCommit, ok = revs[""]; ok { treeCommit.repo = commit.repo } return commitsInfo, treeCommit, nil @@ -155,16 +154,16 @@ func getFileHashes(c cgobject.CommitNode, treePath string, paths []string) (map[ return hashes, nil } -func getLastCommitForPathsByCache(commitID, treePath string, paths []string, cache *LastCommitCache) (map[string]*object.Commit, []string, error) { +func getLastCommitForPathsByCache(commitID, treePath string, paths []string, cache *LastCommitCache) (map[string]*Commit, []string, error) { var unHitEntryPaths []string - results := make(map[string]*object.Commit) + results := make(map[string]*Commit) for _, p := range paths { lastCommit, err := cache.Get(commitID, path.Join(treePath, p)) if err != nil { return nil, nil, err } if lastCommit != nil { - results[p] = lastCommit.(*object.Commit) + results[p] = lastCommit continue } @@ -175,7 +174,7 @@ func getLastCommitForPathsByCache(commitID, treePath string, paths []string, cac } // GetLastCommitForPaths returns last commit information -func GetLastCommitForPaths(ctx context.Context, cache *LastCommitCache, c cgobject.CommitNode, treePath string, paths []string) (map[string]*object.Commit, error) { +func GetLastCommitForPaths(ctx context.Context, cache *LastCommitCache, c cgobject.CommitNode, treePath string, paths []string) (map[string]*Commit, error) { refSha := c.ID().String() // We do a tree traversal with nodes sorted by commit time @@ -293,13 +292,13 @@ heaploop: } // Post-processing - result := make(map[string]*object.Commit) + result := make(map[string]*Commit) for path, commitNode := range resultNodes { - var err error - result[path], err = commitNode.Commit() + commit, err := commitNode.Commit() if err != nil { return nil, err } + result[path] = convertCommit(commit) } return result, nil diff --git a/modules/git/commit_info_nogogit.go b/modules/git/commit_info_nogogit.go index ceab11adbb8c6..d7bca3b9486a6 100644 --- a/modules/git/commit_info_nogogit.go +++ b/modules/git/commit_info_nogogit.go @@ -17,7 +17,7 @@ import ( ) // GetCommitsInfo gets information of all commits that are corresponding to these entries -func (tes Entries) GetCommitsInfo(ctx context.Context, commit *Commit, treePath string, cache *LastCommitCache) ([]CommitInfo, *Commit, error) { +func (tes Entries) GetCommitsInfo(ctx context.Context, commit *Commit, treePath string) ([]CommitInfo, *Commit, error) { entryPaths := make([]string, len(tes)+1) // Get the commit for the treePath itself entryPaths[0] = "" @@ -28,15 +28,15 @@ func (tes Entries) GetCommitsInfo(ctx context.Context, commit *Commit, treePath var err error var revs map[string]*Commit - if cache != nil { + if commit.repo.LastCommitCache != nil { var unHitPaths []string - revs, unHitPaths, err = getLastCommitForPathsByCache(ctx, commit.ID.String(), treePath, entryPaths, cache) + revs, unHitPaths, err = getLastCommitForPathsByCache(ctx, commit.ID.String(), treePath, entryPaths, commit.repo.LastCommitCache) if err != nil { return nil, nil, err } if len(unHitPaths) > 0 { sort.Strings(unHitPaths) - commits, err := GetLastCommitForPaths(ctx, cache, commit, treePath, unHitPaths) + commits, err := GetLastCommitForPaths(ctx, commit, treePath, unHitPaths) if err != nil { return nil, nil, err } @@ -47,7 +47,7 @@ func (tes Entries) GetCommitsInfo(ctx context.Context, commit *Commit, treePath } } else { sort.Strings(entryPaths) - revs, err = GetLastCommitForPaths(ctx, nil, commit, treePath, entryPaths) + revs, err = GetLastCommitForPaths(ctx, commit, treePath, entryPaths) } if err != nil { return nil, nil, err @@ -99,18 +99,15 @@ func (tes Entries) GetCommitsInfo(ctx context.Context, commit *Commit, treePath } func getLastCommitForPathsByCache(ctx context.Context, commitID, treePath string, paths []string, cache *LastCommitCache) (map[string]*Commit, []string, error) { - wr, rd, cancel := cache.repo.CatFileBatch(ctx) - defer cancel() - var unHitEntryPaths []string results := make(map[string]*Commit) for _, p := range paths { - lastCommit, err := cache.Get(commitID, path.Join(treePath, p), wr, rd) + lastCommit, err := cache.Get(commitID, path.Join(treePath, p)) if err != nil { return nil, nil, err } if lastCommit != nil { - results[p] = lastCommit.(*Commit) + results[p] = lastCommit continue } @@ -121,9 +118,9 @@ func getLastCommitForPathsByCache(ctx context.Context, commitID, treePath string } // GetLastCommitForPaths returns last commit information -func GetLastCommitForPaths(ctx context.Context, cache *LastCommitCache, commit *Commit, treePath string, paths []string) (map[string]*Commit, error) { +func GetLastCommitForPaths(ctx context.Context, commit *Commit, treePath string, paths []string) (map[string]*Commit, error) { // We read backwards from the commit to obtain all of the commits - revs, err := WalkGitLog(ctx, cache, commit.repo, commit, treePath, paths...) + revs, err := WalkGitLog(ctx, commit.repo, commit, treePath, paths...) if err != nil { return nil, err } diff --git a/modules/git/commit_info_test.go b/modules/git/commit_info_test.go index 49845522a9d53..a12452c4040bc 100644 --- a/modules/git/commit_info_test.go +++ b/modules/git/commit_info_test.go @@ -91,7 +91,7 @@ func testGetCommitsInfo(t *testing.T, repo1 *Repository) { } // FIXME: Context.TODO() - if graceful has started we should use its Shutdown context otherwise use install signals in TestMain. - commitsInfo, treeCommit, err := entries.GetCommitsInfo(context.TODO(), commit, testCase.Path, nil) + commitsInfo, treeCommit, err := entries.GetCommitsInfo(context.TODO(), commit, testCase.Path) assert.NoError(t, err, "Unable to get commit information for entries of subtree: %s in commit: %s from testcase due to error: %v", testCase.Path, testCase.CommitID, err) if err != nil { t.FailNow() @@ -170,7 +170,7 @@ func BenchmarkEntries_GetCommitsInfo(b *testing.B) { b.ResetTimer() b.Run(benchmark.name, func(b *testing.B) { for i := 0; i < b.N; i++ { - _, _, err := entries.GetCommitsInfo(context.Background(), commit, "", nil) + _, _, err := entries.GetCommitsInfo(context.Background(), commit, "") if err != nil { b.Fatal(err) } diff --git a/modules/git/git.go b/modules/git/git.go index 3bc08ff93b5fa..b8317396c0150 100644 --- a/modules/git/git.go +++ b/modules/git/git.go @@ -20,6 +20,7 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "github.com/hashicorp/go-version" ) diff --git a/modules/git/last_commit_cache.go b/modules/git/last_commit_cache.go index d4ec517b51025..2b51d5972086f 100644 --- a/modules/git/last_commit_cache.go +++ b/modules/git/last_commit_cache.go @@ -9,6 +9,7 @@ import ( "fmt" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" ) // Cache represents a caching interface @@ -19,16 +20,96 @@ type Cache interface { Get(key string) interface{} } -func (c *LastCommitCache) getCacheKey(repoPath, ref, entryPath string) string { - hashBytes := sha256.Sum256([]byte(fmt.Sprintf("%s:%s:%s", repoPath, ref, entryPath))) +func getCacheKey(repoPath, commitID, entryPath string) string { + hashBytes := sha256.Sum256([]byte(fmt.Sprintf("%s:%s:%s", repoPath, commitID, entryPath))) return fmt.Sprintf("last_commit:%x", hashBytes) } +// LastCommitCache represents a cache to store last commit +type LastCommitCache struct { + repoPath string + ttl func() int64 + repo *Repository + commitCache map[string]*Commit + cache Cache +} + +// NewLastCommitCache creates a new last commit cache for repo +func NewLastCommitCache(count int64, repoPath string, gitRepo *Repository, cache Cache) *LastCommitCache { + if cache == nil { + return nil + } + if !setting.CacheService.LastCommit.Enabled || count < setting.CacheService.LastCommit.CommitsCount { + return nil + } + + return &LastCommitCache{ + repoPath: repoPath, + repo: gitRepo, + ttl: setting.LastCommitCacheTTLSeconds, + cache: cache, + } +} + // Put put the last commit id with commit and entry path func (c *LastCommitCache) Put(ref, entryPath, commitID string) error { if c == nil || c.cache == nil { return nil } log.Debug("LastCommitCache save: [%s:%s:%s]", ref, entryPath, commitID) - return c.cache.Put(c.getCacheKey(c.repoPath, ref, entryPath), commitID, c.ttl()) + return c.cache.Put(getCacheKey(c.repoPath, ref, entryPath), commitID, c.ttl()) +} + +// Get gets the last commit information by commit id and entry path +func (c *LastCommitCache) Get(ref, entryPath string) (*Commit, error) { + if c == nil || c.cache == nil { + return nil, nil + } + + commitID, ok := c.cache.Get(getCacheKey(c.repoPath, ref, entryPath)).(string) + if !ok || commitID == "" { + return nil, nil + } + + log.Debug("LastCommitCache hit level 1: [%s:%s:%s]", ref, entryPath, commitID) + if c.commitCache != nil { + if commit, ok := c.commitCache[commitID]; ok { + log.Debug("LastCommitCache hit level 2: [%s:%s:%s]", ref, entryPath, commitID) + return commit, nil + } + } + + commit, err := c.repo.GetCommit(commitID) + if err != nil { + return nil, err + } + if c.commitCache == nil { + c.commitCache = make(map[string]*Commit) + } + c.commitCache[commitID] = commit + return commit, nil +} + +// GetCommitByPath gets the last commit for the entry in the provided commit +func (c *LastCommitCache) GetCommitByPath(commitID, entryPath string) (*Commit, error) { + sha1, err := NewIDFromString(commitID) + if err != nil { + return nil, err + } + + lastCommit, err := c.Get(sha1.String(), entryPath) + if err != nil || lastCommit != nil { + return lastCommit, err + } + + lastCommit, err = c.repo.getCommitByPathWithID(sha1, entryPath) + if err != nil { + return nil, err + } + + if err := c.Put(commitID, entryPath, lastCommit.ID.String()); err != nil { + log.Error("Unable to cache %s as the last commit for %q in %s %s. Error %v", lastCommit.ID.String(), entryPath, commitID, c.repoPath, err) + } + + return lastCommit, nil } diff --git a/modules/git/last_commit_cache_gogit.go b/modules/git/last_commit_cache_gogit.go index 8897000350db0..82c76bad20a49 100644 --- a/modules/git/last_commit_cache_gogit.go +++ b/modules/git/last_commit_cache_gogit.go @@ -9,71 +9,25 @@ package git import ( "context" - "code.gitea.io/gitea/modules/log" - - "github.com/go-git/go-git/v5/plumbing/object" cgobject "github.com/go-git/go-git/v5/plumbing/object/commitgraph" ) -// LastCommitCache represents a cache to store last commit -type LastCommitCache struct { - repoPath string - ttl func() int64 - repo *Repository - commitCache map[string]*object.Commit - cache Cache -} - -// NewLastCommitCache creates a new last commit cache for repo -func NewLastCommitCache(repoPath string, gitRepo *Repository, ttl func() int64, cache Cache) *LastCommitCache { - if cache == nil { +// CacheCommit will cache the commit from the gitRepository +func (c *Commit) CacheCommit(ctx context.Context) error { + if c.repo.LastCommitCache == nil { return nil } - return &LastCommitCache{ - repoPath: repoPath, - repo: gitRepo, - commitCache: make(map[string]*object.Commit), - ttl: ttl, - cache: cache, - } -} - -// Get get the last commit information by commit id and entry path -func (c *LastCommitCache) Get(ref, entryPath string) (interface{}, error) { - v := c.cache.Get(c.getCacheKey(c.repoPath, ref, entryPath)) - if vs, ok := v.(string); ok { - log.Debug("LastCommitCache hit level 1: [%s:%s:%s]", ref, entryPath, vs) - if commit, ok := c.commitCache[vs]; ok { - log.Debug("LastCommitCache hit level 2: [%s:%s:%s]", ref, entryPath, vs) - return commit, nil - } - id, err := c.repo.ConvertToSHA1(vs) - if err != nil { - return nil, err - } - commit, err := c.repo.GoGitRepo().CommitObject(id) - if err != nil { - return nil, err - } - c.commitCache[vs] = commit - return commit, nil - } - return nil, nil -} - -// CacheCommit will cache the commit from the gitRepository -func (c *LastCommitCache) CacheCommit(ctx context.Context, commit *Commit) error { - commitNodeIndex, _ := commit.repo.CommitNodeIndex() + commitNodeIndex, _ := c.repo.CommitNodeIndex() - index, err := commitNodeIndex.Get(commit.ID) + index, err := commitNodeIndex.Get(c.ID) if err != nil { return err } - return c.recursiveCache(ctx, index, &commit.Tree, "", 1) + return c.recursiveCache(ctx, index, &c.Tree, "", 1) } -func (c *LastCommitCache) recursiveCache(ctx context.Context, index cgobject.CommitNode, tree *Tree, treePath string, level int) error { +func (c *Commit) recursiveCache(ctx context.Context, index cgobject.CommitNode, tree *Tree, treePath string, level int) error { if level == 0 { return nil } @@ -90,7 +44,7 @@ func (c *LastCommitCache) recursiveCache(ctx context.Context, index cgobject.Com entryMap[entry.Name()] = entry } - commits, err := GetLastCommitForPaths(ctx, c, index, treePath, entryPaths) + commits, err := GetLastCommitForPaths(ctx, c.repo.LastCommitCache, index, treePath, entryPaths) if err != nil { return err } diff --git a/modules/git/last_commit_cache_nogogit.go b/modules/git/last_commit_cache_nogogit.go index 030d5486b6302..1f4d693a262d9 100644 --- a/modules/git/last_commit_cache_nogogit.go +++ b/modules/git/last_commit_cache_nogogit.go @@ -7,67 +7,18 @@ package git import ( - "bufio" "context" - - "code.gitea.io/gitea/modules/log" ) -// LastCommitCache represents a cache to store last commit -type LastCommitCache struct { - repoPath string - ttl func() int64 - repo *Repository - commitCache map[string]*Commit - cache Cache -} - -// NewLastCommitCache creates a new last commit cache for repo -func NewLastCommitCache(repoPath string, gitRepo *Repository, ttl func() int64, cache Cache) *LastCommitCache { - if cache == nil { +// CacheCommit will cache the commit from the gitRepository +func (c *Commit) CacheCommit(ctx context.Context) error { + if c.repo.LastCommitCache == nil { return nil } - return &LastCommitCache{ - repoPath: repoPath, - repo: gitRepo, - commitCache: make(map[string]*Commit), - ttl: ttl, - cache: cache, - } -} - -// Get get the last commit information by commit id and entry path -func (c *LastCommitCache) Get(ref, entryPath string, wr WriteCloserError, rd *bufio.Reader) (interface{}, error) { - v := c.cache.Get(c.getCacheKey(c.repoPath, ref, entryPath)) - if vs, ok := v.(string); ok { - log.Debug("LastCommitCache hit level 1: [%s:%s:%s]", ref, entryPath, vs) - if commit, ok := c.commitCache[vs]; ok { - log.Debug("LastCommitCache hit level 2: [%s:%s:%s]", ref, entryPath, vs) - return commit, nil - } - id, err := c.repo.ConvertToSHA1(vs) - if err != nil { - return nil, err - } - if _, err := wr.Write([]byte(vs + "\n")); err != nil { - return nil, err - } - commit, err := c.repo.getCommitFromBatchReader(rd, id) - if err != nil { - return nil, err - } - c.commitCache[vs] = commit - return commit, nil - } - return nil, nil -} - -// CacheCommit will cache the commit from the gitRepository -func (c *LastCommitCache) CacheCommit(ctx context.Context, commit *Commit) error { - return c.recursiveCache(ctx, commit, &commit.Tree, "", 1) + return c.recursiveCache(ctx, &c.Tree, "", 1) } -func (c *LastCommitCache) recursiveCache(ctx context.Context, commit *Commit, tree *Tree, treePath string, level int) error { +func (c *Commit) recursiveCache(ctx context.Context, tree *Tree, treePath string, level int) error { if level == 0 { return nil } @@ -82,7 +33,7 @@ func (c *LastCommitCache) recursiveCache(ctx context.Context, commit *Commit, tr entryPaths[i] = entry.Name() } - _, err = WalkGitLog(ctx, c, commit.repo, commit, treePath, entryPaths...) + _, err = WalkGitLog(ctx, c.repo, c, treePath, entryPaths...) if err != nil { return err } @@ -94,7 +45,7 @@ func (c *LastCommitCache) recursiveCache(ctx context.Context, commit *Commit, tr if err != nil { return err } - if err := c.recursiveCache(ctx, commit, subTree, treeEntry.Name(), level-1); err != nil { + if err := c.recursiveCache(ctx, subTree, treeEntry.Name(), level-1); err != nil { return err } } diff --git a/modules/git/log_name_status.go b/modules/git/log_name_status.go index e1e117ff4b842..80f1602708471 100644 --- a/modules/git/log_name_status.go +++ b/modules/git/log_name_status.go @@ -281,7 +281,7 @@ func (g *LogNameStatusRepoParser) Close() { } // WalkGitLog walks the git log --name-status for the head commit in the provided treepath and files -func WalkGitLog(ctx context.Context, cache *LastCommitCache, repo *Repository, head *Commit, treepath string, paths ...string) (map[string]string, error) { +func WalkGitLog(ctx context.Context, repo *Repository, head *Commit, treepath string, paths ...string) (map[string]string, error) { headRef := head.ID.String() tree, err := head.SubTree(treepath) @@ -374,14 +374,14 @@ heaploop: changed[i] = false if results[i] == "" { results[i] = current.CommitID - if err := cache.Put(headRef, path.Join(treepath, paths[i]), current.CommitID); err != nil { + if err := repo.LastCommitCache.Put(headRef, path.Join(treepath, paths[i]), current.CommitID); err != nil { return nil, err } delete(path2idx, paths[i]) remaining-- if results[0] == "" { results[0] = current.CommitID - if err := cache.Put(headRef, treepath, current.CommitID); err != nil { + if err := repo.LastCommitCache.Put(headRef, treepath, current.CommitID); err != nil { return nil, err } delete(path2idx, "") diff --git a/modules/git/notes_gogit.go b/modules/git/notes_gogit.go index 76bc828957b3d..fe6d1f1e580c8 100644 --- a/modules/git/notes_gogit.go +++ b/modules/git/notes_gogit.go @@ -83,7 +83,7 @@ func GetNote(ctx context.Context, repo *Repository, commitID string, note *Note) log.Error("Unable to get the commit for the path %q. Error: %v", path, err) return err } - note.Commit = convertCommit(lastCommits[path]) + note.Commit = lastCommits[path] return nil } diff --git a/modules/git/notes_nogogit.go b/modules/git/notes_nogogit.go index 1476805dcdc03..ba216ce3e4a41 100644 --- a/modules/git/notes_nogogit.go +++ b/modules/git/notes_nogogit.go @@ -81,7 +81,7 @@ func GetNote(ctx context.Context, repo *Repository, commitID string, note *Note) path = path[idx+1:] } - lastCommits, err := GetLastCommitForPaths(ctx, nil, notes, treePath, []string{path}) + lastCommits, err := GetLastCommitForPaths(ctx, notes, treePath, []string{path}) if err != nil { log.Error("Unable to get the commit for the path %q. Error: %v", treePath, err) return err diff --git a/modules/git/repo_base_gogit.go b/modules/git/repo_base_gogit.go index cd2ca25dfbadf..8fe9c404c3dbb 100644 --- a/modules/git/repo_base_gogit.go +++ b/modules/git/repo_base_gogit.go @@ -31,7 +31,8 @@ type Repository struct { gogitStorage *filesystem.Storage gpgSettings *GPGSettings - Ctx context.Context + Ctx context.Context + LastCommitCache *LastCommitCache } // openRepositoryWithDefaultContext opens the repository at the given path with DefaultContext. @@ -79,6 +80,8 @@ func (repo *Repository) Close() (err error) { if err := repo.gogitStorage.Close(); err != nil { gitealog.Error("Error closing storage: %v", err) } + repo.LastCommitCache = nil + repo.tagCache = nil return } diff --git a/modules/git/repo_base_nogogit.go b/modules/git/repo_base_nogogit.go index 63c278c26137a..56af2c640fd4a 100644 --- a/modules/git/repo_base_nogogit.go +++ b/modules/git/repo_base_nogogit.go @@ -32,7 +32,8 @@ type Repository struct { checkReader *bufio.Reader checkWriter WriteCloserError - Ctx context.Context + Ctx context.Context + LastCommitCache *LastCommitCache } // openRepositoryWithDefaultContext opens the repository at the given path with DefaultContext. @@ -101,5 +102,7 @@ func (repo *Repository) Close() (err error) { repo.checkReader = nil repo.checkWriter = nil } + repo.LastCommitCache = nil + repo.tagCache = nil return err } diff --git a/modules/git/repo_branch.go b/modules/git/repo_branch.go index 8e455480e7279..17d243808e9c0 100644 --- a/modules/git/repo_branch.go +++ b/modules/git/repo_branch.go @@ -7,6 +7,7 @@ package git import ( "context" + "errors" "fmt" "strings" ) @@ -72,7 +73,14 @@ func (repo *Repository) SetDefaultBranch(name string) error { // GetDefaultBranch gets default branch of repository. func (repo *Repository) GetDefaultBranch() (string, error) { stdout, _, err := NewCommand(repo.Ctx, "symbolic-ref", "HEAD").RunStdString(&RunOpts{Dir: repo.Path}) - return stdout, err + if err != nil { + return "", err + } + stdout = strings.TrimSpace(stdout) + if !strings.HasPrefix(stdout, BranchPrefix) { + return "", errors.New("the HEAD is not a branch: " + stdout) + } + return strings.TrimPrefix(stdout, BranchPrefix), nil } // GetBranch returns a branch by it's name diff --git a/modules/git/repo_commit.go b/modules/git/repo_commit.go index e6fec4d1a32e2..7ff23af42eb84 100644 --- a/modules/git/repo_commit.go +++ b/modules/git/repo_commit.go @@ -11,6 +11,7 @@ import ( "strconv" "strings" + "code.gitea.io/gitea/modules/cache" "code.gitea.io/gitea/modules/setting" ) @@ -434,3 +435,20 @@ func (repo *Repository) IsCommitInBranch(commitID, branch string) (r bool, err e } return len(stdout) > 0, err } + +func (repo *Repository) AddLastCommitCache(cacheKey, fullName, sha string) error { + if repo.LastCommitCache == nil { + commitsCount, err := cache.GetInt64(cacheKey, func() (int64, error) { + commit, err := repo.GetCommit(sha) + if err != nil { + return 0, err + } + return commit.CommitsCount() + }) + if err != nil { + return err + } + repo.LastCommitCache = NewLastCommitCache(commitsCount, fullName, repo, cache.GetCache()) + } + return nil +} diff --git a/modules/highlight/highlight.go b/modules/highlight/highlight.go index acd3bebb9f408..af3376e8d7127 100644 --- a/modules/highlight/highlight.go +++ b/modules/highlight/highlight.go @@ -10,6 +10,7 @@ import ( "bytes" "fmt" gohtml "html" + "io" "path/filepath" "strings" "sync" @@ -26,7 +27,7 @@ import ( ) // don't index files larger than this many bytes for performance purposes -const sizeLimit = 1000000 +const sizeLimit = 1024 * 1024 var ( // For custom user mapping @@ -40,11 +41,12 @@ var ( // NewContext loads custom highlight map from local config func NewContext() { once.Do(func() { - keys := setting.Cfg.Section("highlight.mapping").Keys() - for i := range keys { - highlightMapping[keys[i].Name()] = keys[i].Value() + if setting.Cfg != nil { + keys := setting.Cfg.Section("highlight.mapping").Keys() + for i := range keys { + highlightMapping[keys[i].Name()] = keys[i].Value() + } } - // The size 512 is simply a conservative rule of thumb c, err := lru.New2Q(512) if err != nil { @@ -58,7 +60,7 @@ func NewContext() { func Code(fileName, language, code string) string { NewContext() - // diff view newline will be passed as empty, change to literal \n so it can be copied + // diff view newline will be passed as empty, change to literal '\n' so it can be copied // preserve literal newline in blame view if code == "" || code == "\n" { return "\n" @@ -126,36 +128,32 @@ func CodeFromLexer(lexer chroma.Lexer, code string) string { return code } - htmlw.Flush() + _ = htmlw.Flush() // Chroma will add newlines for certain lexers in order to highlight them properly - // Once highlighted, strip them here so they don't cause copy/paste trouble in HTML output + // Once highlighted, strip them here, so they don't cause copy/paste trouble in HTML output return strings.TrimSuffix(htmlbuf.String(), "\n") } -// File returns a slice of chroma syntax highlighted lines of code -func File(numLines int, fileName, language string, code []byte) []string { +// File returns a slice of chroma syntax highlighted HTML lines of code +func File(fileName, language string, code []byte) ([]string, error) { NewContext() if len(code) > sizeLimit { - return plainText(string(code), numLines) + return PlainText(code), nil } + formatter := html.New(html.WithClasses(true), html.WithLineNumbers(false), html.PreventSurroundingPre(true), ) - if formatter == nil { - log.Error("Couldn't create chroma formatter") - return plainText(string(code), numLines) - } - - htmlbuf := bytes.Buffer{} - htmlw := bufio.NewWriter(&htmlbuf) + htmlBuf := bytes.Buffer{} + htmlWriter := bufio.NewWriter(&htmlBuf) var lexer chroma.Lexer // provided language overrides everything - if len(language) > 0 { + if language != "" { lexer = lexers.Get(language) } @@ -166,9 +164,9 @@ func File(numLines int, fileName, language string, code []byte) []string { } if lexer == nil { - language := analyze.GetCodeLanguage(fileName, code) + guessLanguage := analyze.GetCodeLanguage(fileName, code) - lexer = lexers.Get(language) + lexer = lexers.Get(guessLanguage) if lexer == nil { lexer = lexers.Match(fileName) if lexer == nil { @@ -179,54 +177,43 @@ func File(numLines int, fileName, language string, code []byte) []string { iterator, err := lexer.Tokenise(nil, string(code)) if err != nil { - log.Error("Can't tokenize code: %v", err) - return plainText(string(code), numLines) + return nil, fmt.Errorf("can't tokenize code: %w", err) } - err = formatter.Format(htmlw, styles.GitHub, iterator) + err = formatter.Format(htmlWriter, styles.GitHub, iterator) if err != nil { - log.Error("Can't format code: %v", err) - return plainText(string(code), numLines) + return nil, fmt.Errorf("can't format code: %w", err) } - htmlw.Flush() - finalNewLine := false - if len(code) > 0 { - finalNewLine = code[len(code)-1] == '\n' - } + _ = htmlWriter.Flush() - m := make([]string, 0, numLines) - for _, v := range strings.SplitN(htmlbuf.String(), "\n", numLines) { - content := v - // need to keep lines that are only \n so copy/paste works properly in browser - if content == "" { - content = "\n" - } else if content == `` { - content += "\n" - } else if content == `` { - content += "\n" - } - content = strings.TrimSuffix(content, ``) - content = strings.TrimPrefix(content, ``) - m = append(m, content) + // at the moment, Chroma generates stable output `...\n` for each line + htmlStr := htmlBuf.String() + lines := strings.Split(htmlStr, ``) + m := make([]string, 0, len(lines)) + for i := 1; i < len(lines); i++ { + line := lines[i] + line = strings.TrimSuffix(line, "") + m = append(m, line) } - if finalNewLine { - m = append(m, "\n") - } - - return m + return m, nil } -// return unhiglighted map -func plainText(code string, numLines int) []string { - m := make([]string, 0, numLines) - for _, v := range strings.SplitN(code, "\n", numLines) { - content := v - // need to keep lines that are only \n so copy/paste works properly in browser - if content == "" { - content = "\n" +// PlainText returns non-highlighted HTML for code +func PlainText(code []byte) []string { + r := bufio.NewReader(bytes.NewReader(code)) + m := make([]string, 0, bytes.Count(code, []byte{'\n'})+1) + for { + content, err := r.ReadString('\n') + if err != nil && err != io.EOF { + log.Error("failed to read string from buffer: %v", err) + break + } + if content == "" && err == io.EOF { + break } - m = append(m, gohtml.EscapeString(content)) + s := gohtml.EscapeString(content) + m = append(m, s) } return m } diff --git a/modules/highlight/highlight_test.go b/modules/highlight/highlight_test.go index e5dfedd2b3c8e..8f83f4a2f6128 100644 --- a/modules/highlight/highlight_test.go +++ b/modules/highlight/highlight_test.go @@ -8,97 +8,146 @@ import ( "strings" "testing" - "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/util" - "github.com/stretchr/testify/assert" - "gopkg.in/ini.v1" ) +func lines(s string) []string { + return strings.Split(strings.ReplaceAll(strings.TrimSpace(s), `\n`, "\n"), "\n") +} + func TestFile(t *testing.T) { - setting.Cfg = ini.Empty() tests := []struct { - name string - numLines int - fileName string - code string - want string + name string + code string + want []string }{ { - name: ".drone.yml", - numLines: 12, - fileName: ".drone.yml", - code: util.Dedent(` - kind: pipeline - name: default + name: "empty.py", + code: "", + want: lines(""), + }, + { + name: "tags.txt", + code: "<>", + want: lines("<>"), + }, + { + name: "tags.py", + code: "<>", + want: lines(`<>`), + }, + { + name: "eol-no.py", + code: "a=1", + want: lines(`a=1`), + }, + { + name: "eol-newline1.py", + code: "a=1\n", + want: lines(`a=1\n`), + }, + { + name: "eol-newline2.py", + code: "a=1\n\n", + want: lines(` +a=1\n +\n + `, + ), + }, + { + name: "empty-line-with-space.py", + code: strings.ReplaceAll(strings.TrimSpace(` +def: + a=1 - steps: - - name: test - image: golang:1.13 - environment: - GOPROXY: https://goproxy.cn - commands: - - go get -u - - go build -v - - go test -v -race -coverprofile=coverage.txt -covermode=atomic - `), - want: util.Dedent(` - kind: pipeline - name: default - - steps: - - name: test - image: golang:1.13 - environment: - GOPROXY: https://goproxy.cn - commands: - - go get -u - - go build -v - - go test -v -race -coverprofile=coverage.txt -covermode=atomic +b='' +{space} +c=2 + `), "{space}", " "), + want: lines(` +def:\n + a=1\n +\n +b=''\n + \n +c=2`, + ), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + out, err := File(tt.name, "", []byte(tt.code)) + assert.NoError(t, err) + expected := strings.Join(tt.want, "\n") + actual := strings.Join(out, "\n") + assert.Equal(t, strings.Count(actual, "")) + assert.EqualValues(t, expected, actual) + }) + } +} + +func TestPlainText(t *testing.T) { + tests := []struct { + name string + code string + want []string + }{ + { + name: "empty.py", + code: "", + want: lines(""), + }, + { + name: "tags.py", + code: "<>", + want: lines("<>"), + }, + { + name: "eol-no.py", + code: "a=1", + want: lines(`a=1`), + }, + { + name: "eol-newline1.py", + code: "a=1\n", + want: lines(`a=1\n`), + }, + { + name: "eol-newline2.py", + code: "a=1\n\n", + want: lines(` +a=1\n +\n `), }, { - name: ".drone.yml - trailing space", - numLines: 13, - fileName: ".drone.yml", - code: strings.Replace(util.Dedent(` - kind: pipeline - name: default + name: "empty-line-with-space.py", + code: strings.ReplaceAll(strings.TrimSpace(` +def: + a=1 - steps: - - name: test - image: golang:1.13 - environment: - GOPROXY: https://goproxy.cn - commands: - - go get -u - - go build -v - - go test -v -race -coverprofile=coverage.txt -covermode=atomic - `)+"\n", "name: default", "name: default ", 1), - want: util.Dedent(` - kind: pipeline - name: default - - steps: - - name: test - image: golang:1.13 - environment: - GOPROXY: https://goproxy.cn - commands: - - go get -u - - go build -v - - go test -v -race -coverprofile=coverage.txt -covermode=atomic - - - - `), +b='' +{space} +c=2 + `), "{space}", " "), + want: lines(` +def:\n + a=1\n +\n +b=''\n + \n +c=2`), }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got := strings.Join(File(tt.numLines, tt.fileName, "", []byte(tt.code)), "\n") - assert.Equal(t, tt.want, got) + out := PlainText([]byte(tt.code)) + expected := strings.Join(tt.want, "\n") + actual := strings.Join(out, "\n") + assert.EqualValues(t, expected, actual) }) } } diff --git a/modules/httpcache/httpcache.go b/modules/httpcache/httpcache.go index 5797e981cf80f..750233d4a71c2 100644 --- a/modules/httpcache/httpcache.go +++ b/modules/httpcache/httpcache.go @@ -17,16 +17,23 @@ import ( ) // AddCacheControlToHeader adds suitable cache-control headers to response -func AddCacheControlToHeader(h http.Header, d time.Duration) { +func AddCacheControlToHeader(h http.Header, maxAge time.Duration, additionalDirectives ...string) { + directives := make([]string, 0, 2+len(additionalDirectives)) + if setting.IsProd { - h.Set("Cache-Control", "private, max-age="+strconv.Itoa(int(d.Seconds()))) + if maxAge == 0 { + directives = append(directives, "no-store") + } else { + directives = append(directives, "private", "max-age="+strconv.Itoa(int(maxAge.Seconds()))) + } } else { - h.Set("Cache-Control", "no-store") + directives = append(directives, "no-store") + // to remind users they are using non-prod setting. - // some users may be confused by "Cache-Control: no-store" in their setup if they did wrong to `RUN_MODE` in `app.ini`. h.Add("X-Gitea-Debug", "RUN_MODE="+setting.RunMode) - h.Add("X-Gitea-Debug", "CacheControl=no-store") } + + h.Set("Cache-Control", strings.Join(append(directives, additionalDirectives...), ", ")) } // generateETag generates an ETag based on size, filename and file modification time diff --git a/modules/lfs/content_store.go b/modules/lfs/content_store.go index c794a1feccc6f..0eedf4de1798b 100644 --- a/modules/lfs/content_store.go +++ b/modules/lfs/content_store.go @@ -8,7 +8,6 @@ import ( "crypto/sha256" "encoding/hex" "errors" - "fmt" "hash" "io" "os" @@ -24,21 +23,6 @@ var ( ErrSizeMismatch = errors.New("Content size does not match") ) -// ErrRangeNotSatisfiable represents an error which request range is not satisfiable. -type ErrRangeNotSatisfiable struct { - FromByte int64 -} - -// IsErrRangeNotSatisfiable returns true if the error is an ErrRangeNotSatisfiable -func IsErrRangeNotSatisfiable(err error) bool { - _, ok := err.(ErrRangeNotSatisfiable) - return ok -} - -func (err ErrRangeNotSatisfiable) Error() string { - return fmt.Sprintf("Requested range %d is not satisfiable", err.FromByte) -} - // ContentStore provides a simple file system based storage. type ContentStore struct { storage.ObjectStorage diff --git a/modules/markup/html.go b/modules/markup/html.go index 6071180501c42..a5606dbb516ad 100644 --- a/modules/markup/html.go +++ b/modules/markup/html.go @@ -1176,7 +1176,7 @@ func genDefaultLinkProcessor(defaultLink string) processor { node.DataAtom = atom.A node.Attr = []html.Attribute{ {Key: "href", Val: defaultLink}, - {Key: "class", Val: "default-link"}, + {Key: "class", Val: "default-link muted"}, } node.FirstChild, node.LastChild = ch, ch } diff --git a/modules/markup/renderer.go b/modules/markup/renderer.go index e88fa311875d5..5f69dc72354f0 100644 --- a/modules/markup/renderer.go +++ b/modules/markup/renderer.go @@ -310,14 +310,9 @@ func IsMarkupFile(name, markup string) bool { } // IsReadmeFile reports whether name looks like a README file -// based on its name. If an extension is provided, it will strictly -// match that extension. -// Note that the '.' should be provided in ext, e.g ".md" -func IsReadmeFile(name string, ext ...string) bool { +// based on its name. +func IsReadmeFile(name string) bool { name = strings.ToLower(name) - if len(ext) > 0 { - return name == "readme"+ext[0] - } if len(name) < 6 { return false } else if len(name) == 6 { @@ -325,3 +320,29 @@ func IsReadmeFile(name string, ext ...string) bool { } return name[:7] == "readme." } + +// IsReadmeFileExtension reports whether name looks like a README file +// based on its name. It will look through the provided extensions and check if the file matches +// one of the extensions and provide the index in the extension list. +// If the filename is `readme.` with an unmatched extension it will match with the index equaling +// the length of the provided extension list. +// Note that the '.' should be provided in ext, e.g ".md" +func IsReadmeFileExtension(name string, ext ...string) (int, bool) { + name = strings.ToLower(name) + if len(name) < 6 || name[:6] != "readme" { + return 0, false + } + + for i, extension := range ext { + extension = strings.ToLower(extension) + if name[6:] == extension { + return i, true + } + } + + if name[6] == '.' { + return len(ext), true + } + + return 0, false +} diff --git a/modules/markup/renderer_test.go b/modules/markup/renderer_test.go index 4cfa022463190..950ee15b91072 100644 --- a/modules/markup/renderer_test.go +++ b/modules/markup/renderer_test.go @@ -40,24 +40,57 @@ func TestMisc_IsReadmeFile(t *testing.T) { assert.False(t, IsReadmeFile(testCase)) } - trueTestCasesStrict := [][]string{ - {"readme", ""}, - {"readme.md", ".md"}, - {"readme.txt", ".txt"}, - } - falseTestCasesStrict := [][]string{ - {"readme", ".md"}, - {"readme.md", ""}, - {"readme.md", ".txt"}, - {"readme.md", "md"}, - {"readmee.md", ".md"}, - {"readme.i18n.md", ".md"}, + type extensionTestcase struct { + name string + expected bool + idx int } - for _, testCase := range trueTestCasesStrict { - assert.True(t, IsReadmeFile(testCase[0], testCase[1])) + exts := []string{".md", ".txt", ""} + testCasesExtensions := []extensionTestcase{ + { + name: "readme", + expected: true, + idx: 2, + }, + { + name: "readme.md", + expected: true, + idx: 0, + }, + { + name: "README.md", + expected: true, + idx: 0, + }, + { + name: "ReAdMe.Md", + expected: true, + idx: 0, + }, + { + name: "readme.txt", + expected: true, + idx: 1, + }, + { + name: "readme.doc", + expected: true, + idx: 3, + }, + { + name: "readmee.md", + }, + { + name: "readme..", + expected: true, + idx: 3, + }, } - for _, testCase := range falseTestCasesStrict { - assert.False(t, IsReadmeFile(testCase[0], testCase[1])) + + for _, testCase := range testCasesExtensions { + idx, ok := IsReadmeFileExtension(testCase.name, exts...) + assert.Equal(t, testCase.expected, ok) + assert.Equal(t, testCase.idx, idx) } } diff --git a/modules/markup/sanitizer.go b/modules/markup/sanitizer.go index 388af567123dc..57e88fdabc816 100644 --- a/modules/markup/sanitizer.go +++ b/modules/markup/sanitizer.go @@ -85,6 +85,12 @@ func createDefaultPolicy() *bluemonday.Policy { // Allow icons, emojis, chroma syntax and keyword markup on span policy.AllowAttrs("class").Matching(regexp.MustCompile(`^((icon(\s+[\p{L}\p{N}_-]+)+)|(emoji))$|^([a-z][a-z0-9]{0,2})$|^` + keywordClass + `$`)).OnElements("span") + // Allow 'style' attribute on text elements. + policy.AllowAttrs("style").OnElements("span", "p") + + // Allow 'color' property for the style attribute on text elements. + policy.AllowStyles("color").OnElements("span", "p") + // Allow generally safe attributes generalSafeAttrs := []string{ "abbr", "accept", "accept-charset", diff --git a/modules/markup/sanitizer_test.go b/modules/markup/sanitizer_test.go index 7dfca7a468dbe..b3b07404b451b 100644 --- a/modules/markup/sanitizer_test.go +++ b/modules/markup/sanitizer_test.go @@ -45,6 +45,14 @@ func Test_Sanitizer(t *testing.T) { `unchecked`, `unchecked`, `NAUGHTY`, `NAUGHTY`, `contents`, `contents`, + + // Color property + `Hello World`, `Hello World`, + `

Hello World

`, `

Hello World

`, + `Hello World`, `Hello World`, + `Hello World`, `Hello World`, + `

Hello World

`, `

Hello World

`, + `Hello World`, `Hello World`, } for i := 0; i < len(testCases); i += 2 { diff --git a/modules/notification/mail/mail.go b/modules/notification/mail/mail.go index 1f217304b0638..5085656c14a4f 100644 --- a/modules/notification/mail/mail.go +++ b/modules/notification/mail/mail.go @@ -126,7 +126,7 @@ func (m *mailNotifier) NotifyPullRequestCodeComment(pr *issues_model.PullRequest func (m *mailNotifier) NotifyIssueChangeAssignee(doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment) { // mail only sent to added assignees and not self-assignee - if !removed && doer.ID != assignee.ID && (assignee.EmailNotifications() == user_model.EmailNotificationsEnabled || assignee.EmailNotifications() == user_model.EmailNotificationsOnMention) { + if !removed && doer.ID != assignee.ID && assignee.EmailNotifications() != user_model.EmailNotificationsDisabled { ct := fmt.Sprintf("Assigned #%d.", issue.Index) if err := mailer.SendIssueAssignedMail(issue, doer, ct, comment, []*user_model.User{assignee}); err != nil { log.Error("Error in SendIssueAssignedMail for issue[%d] to assignee[%d]: %v", issue.ID, assignee.ID, err) @@ -135,7 +135,7 @@ func (m *mailNotifier) NotifyIssueChangeAssignee(doer *user_model.User, issue *i } func (m *mailNotifier) NotifyPullReviewRequest(doer *user_model.User, issue *issues_model.Issue, reviewer *user_model.User, isRequest bool, comment *issues_model.Comment) { - if isRequest && doer.ID != reviewer.ID && (reviewer.EmailNotifications() == user_model.EmailNotificationsEnabled || reviewer.EmailNotifications() == user_model.EmailNotificationsOnMention) { + if isRequest && doer.ID != reviewer.ID && reviewer.EmailNotifications() != user_model.EmailNotificationsDisabled { ct := fmt.Sprintf("Requested to review %s.", issue.HTMLURL()) if err := mailer.SendIssueAssignedMail(issue, doer, ct, comment, []*user_model.User{reviewer}); err != nil { log.Error("Error in SendIssueAssignedMail for issue[%d] to reviewer[%d]: %v", issue.ID, reviewer.ID, err) diff --git a/modules/packages/conan/reference.go b/modules/packages/conan/reference.go index c43446e6e5bda..49236981b67f8 100644 --- a/modules/packages/conan/reference.go +++ b/modules/packages/conan/reference.go @@ -8,10 +8,9 @@ import ( "errors" "fmt" "regexp" + "strings" "code.gitea.io/gitea/modules/log" - - goversion "github.com/hashicorp/go-version" ) const ( @@ -56,7 +55,9 @@ func NewRecipeReference(name, version, user, channel, revision string) (*RecipeR if !namePattern.MatchString(name) { return nil, ErrValidation } - if _, err := goversion.NewSemver(version); err != nil { + + v := strings.TrimSpace(version) + if v == "" { return nil, ErrValidation } if user != "" && !namePattern.MatchString(user) { @@ -69,7 +70,7 @@ func NewRecipeReference(name, version, user, channel, revision string) (*RecipeR return nil, ErrValidation } - return &RecipeReference{name, version, user, channel, revision}, nil + return &RecipeReference{name, v, user, channel, revision}, nil } func (r *RecipeReference) RevisionOrDefault() string { diff --git a/modules/packages/conan/reference_test.go b/modules/packages/conan/reference_test.go index 29ba3a543bf2d..98eb2c847843d 100644 --- a/modules/packages/conan/reference_test.go +++ b/modules/packages/conan/reference_test.go @@ -34,6 +34,7 @@ func TestNewRecipeReference(t *testing.T) { {"name", "1.0", "_", "_", "", true}, {"name", "1.0", "_", "_", "0", true}, {"name", "1.0", "", "", "0", true}, + {"name", "1.0.0q", "", "", "0", true}, {"name", "1.0", "", "", "000000000000000000000000000000000000000000000000000000000000", false}, } diff --git a/modules/packages/container/metadata.go b/modules/packages/container/metadata.go index 087d38e5bd142..4222cdb30a781 100644 --- a/modules/packages/container/metadata.go +++ b/modules/packages/container/metadata.go @@ -16,6 +16,7 @@ import ( ) const ( + PropertyRepository = "container.repository" PropertyDigest = "container.digest" PropertyMediaType = "container.mediatype" PropertyManifestTagged = "container.manifest.tagged" diff --git a/modules/packages/hashed_buffer_test.go b/modules/packages/hashed_buffer_test.go new file mode 100644 index 0000000000000..e21ec67e1fed2 --- /dev/null +++ b/modules/packages/hashed_buffer_test.go @@ -0,0 +1,47 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package packages + +import ( + "fmt" + "io" + "strings" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestHashedBuffer(t *testing.T) { + cases := []struct { + MaxMemorySize int + Data string + HashMD5 string + HashSHA1 string + HashSHA256 string + HashSHA512 string + }{ + {5, "test", "098f6bcd4621d373cade4e832627b4f6", "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08", "ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff"}, + {5, "testtest", "05a671c66aefea124cc08b76ea6d30bb", "51abb9636078defbf888d8457a7c76f85c8f114c", "37268335dd6931045bdcdf92623ff819a64244b53d0e746d438797349d4da578", "125d6d03b32c84d492747f79cf0bf6e179d287f341384eb5d6d3197525ad6be8e6df0116032935698f99a09e265073d1d6c32c274591bf1d0a20ad67cba921bc"}, + } + + for _, c := range cases { + buf, err := CreateHashedBufferFromReader(strings.NewReader(c.Data), c.MaxMemorySize) + assert.NoError(t, err) + + assert.EqualValues(t, len(c.Data), buf.Size()) + + data, err := io.ReadAll(buf) + assert.NoError(t, err) + assert.Equal(t, c.Data, string(data)) + + hashMD5, hashSHA1, hashSHA256, hashSHA512 := buf.Sums() + assert.Equal(t, c.HashMD5, fmt.Sprintf("%x", hashMD5)) + assert.Equal(t, c.HashSHA1, fmt.Sprintf("%x", hashSHA1)) + assert.Equal(t, c.HashSHA256, fmt.Sprintf("%x", hashSHA256)) + assert.Equal(t, c.HashSHA512, fmt.Sprintf("%x", hashSHA512)) + + assert.NoError(t, buf.Close()) + } +} diff --git a/modules/packages/pub/metadata.go b/modules/packages/pub/metadata.go new file mode 100644 index 0000000000000..1fc4908b91212 --- /dev/null +++ b/modules/packages/pub/metadata.go @@ -0,0 +1,154 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package pub + +import ( + "archive/tar" + "compress/gzip" + "errors" + "io" + "regexp" + "strings" + + "code.gitea.io/gitea/modules/validation" + + "github.com/hashicorp/go-version" + "gopkg.in/yaml.v2" +) + +var ( + ErrMissingPubspecFile = errors.New("Pubspec file is missing") + ErrPubspecFileTooLarge = errors.New("Pubspec file is too large") + ErrInvalidName = errors.New("Package name is invalid") + ErrInvalidVersion = errors.New("Package version is invalid") +) + +var namePattern = regexp.MustCompile(`\A[a-zA-Z_][a-zA-Z0-9_]*\z`) + +// https://github.com/dart-lang/pub-dev/blob/4d582302a8d10152a5cd6129f65bf4f4dbca239d/pkg/pub_package_reader/lib/pub_package_reader.dart#L143 +const maxPubspecFileSize = 128 * 1024 + +// Package represents a Pub package +type Package struct { + Name string + Version string + Metadata *Metadata +} + +// Metadata represents the metadata of a Pub package +type Metadata struct { + Description string `json:"description,omitempty"` + ProjectURL string `json:"project_url,omitempty"` + RepositoryURL string `json:"repository_url,omitempty"` + DocumentationURL string `json:"documentation_url,omitempty"` + Readme string `json:"readme,omitempty"` + Pubspec interface{} `json:"pubspec"` +} + +type pubspecPackage struct { + Name string `yaml:"name"` + Version string `yaml:"version"` + Description string `yaml:"description"` + Homepage string `yaml:"homepage"` + Repository string `yaml:"repository"` + Documentation string `yaml:"documentation"` +} + +// ParsePackage parses the Pub package file +func ParsePackage(r io.Reader) (*Package, error) { + gzr, err := gzip.NewReader(r) + if err != nil { + return nil, err + } + defer gzr.Close() + + var p *Package + var readme string + + tr := tar.NewReader(gzr) + for { + hd, err := tr.Next() + if err == io.EOF { + break + } + if err != nil { + return nil, err + } + + if hd.Typeflag != tar.TypeReg { + continue + } + + if hd.Name == "pubspec.yaml" { + if hd.Size > maxPubspecFileSize { + return nil, ErrPubspecFileTooLarge + } + p, err = ParsePubspecMetadata(tr) + if err != nil { + return nil, err + } + } else if strings.ToLower(hd.Name) == "readme.md" { + data, err := io.ReadAll(tr) + if err != nil { + return nil, err + } + readme = string(data) + } + } + + if p == nil { + return nil, ErrMissingPubspecFile + } + + p.Metadata.Readme = readme + + return p, nil +} + +// ParsePubspecMetadata parses a Pubspec file to retrieve the metadata of a Pub package +func ParsePubspecMetadata(r io.Reader) (*Package, error) { + buf, err := io.ReadAll(io.LimitReader(r, maxPubspecFileSize)) + if err != nil { + return nil, err + } + + var p pubspecPackage + if err := yaml.Unmarshal(buf, &p); err != nil { + return nil, err + } + + if !namePattern.MatchString(p.Name) { + return nil, ErrInvalidName + } + + v, err := version.NewSemver(p.Version) + if err != nil { + return nil, ErrInvalidVersion + } + + if !validation.IsValidURL(p.Homepage) { + p.Homepage = "" + } + if !validation.IsValidURL(p.Repository) { + p.Repository = "" + } + + var pubspec interface{} + if err := yaml.Unmarshal(buf, &pubspec); err != nil { + return nil, err + } + + return &Package{ + Name: p.Name, + Version: v.String(), + Metadata: &Metadata{ + Description: p.Description, + ProjectURL: p.Homepage, + RepositoryURL: p.Repository, + DocumentationURL: p.Documentation, + Pubspec: pubspec, + }, + }, nil +} diff --git a/modules/packages/pub/metadata_test.go b/modules/packages/pub/metadata_test.go new file mode 100644 index 0000000000000..e43ed64fc6cd6 --- /dev/null +++ b/modules/packages/pub/metadata_test.go @@ -0,0 +1,136 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package pub + +import ( + "archive/tar" + "bytes" + "compress/gzip" + "io" + "strings" + "testing" + + "github.com/stretchr/testify/assert" +) + +const ( + packageName = "gitea" + packageVersion = "1.0.1" + description = "Package Description" + projectURL = "https://gitea.io" + repositoryURL = "https://gitea.io/gitea/gitea" + documentationURL = "https://docs.gitea.io" +) + +const pubspecContent = `name: ` + packageName + ` +version: ` + packageVersion + ` +description: ` + description + ` +homepage: ` + projectURL + ` +repository: ` + repositoryURL + ` +documentation: ` + documentationURL + ` + +environment: + sdk: '>=2.16.0 <3.0.0' + +dependencies: + flutter: + sdk: flutter + path: '>=1.8.0 <3.0.0' + +dev_dependencies: + http: '>=0.13.0'` + +func TestParsePackage(t *testing.T) { + createArchive := func(files map[string][]byte) io.Reader { + var buf bytes.Buffer + zw := gzip.NewWriter(&buf) + tw := tar.NewWriter(zw) + for filename, content := range files { + hdr := &tar.Header{ + Name: filename, + Mode: 0o600, + Size: int64(len(content)), + } + tw.WriteHeader(hdr) + tw.Write(content) + } + tw.Close() + zw.Close() + return &buf + } + + t.Run("MissingPubspecFile", func(t *testing.T) { + data := createArchive(map[string][]byte{"dummy.txt": {}}) + + pp, err := ParsePackage(data) + assert.Nil(t, pp) + assert.ErrorIs(t, err, ErrMissingPubspecFile) + }) + + t.Run("PubspecFileTooLarge", func(t *testing.T) { + data := createArchive(map[string][]byte{"pubspec.yaml": make([]byte, 200*1024)}) + + pp, err := ParsePackage(data) + assert.Nil(t, pp) + assert.ErrorIs(t, err, ErrPubspecFileTooLarge) + }) + + t.Run("InvalidPubspecFile", func(t *testing.T) { + data := createArchive(map[string][]byte{"pubspec.yaml": {}}) + + pp, err := ParsePackage(data) + assert.Nil(t, pp) + assert.Error(t, err) + }) + + t.Run("Valid", func(t *testing.T) { + data := createArchive(map[string][]byte{"pubspec.yaml": []byte(pubspecContent)}) + + pp, err := ParsePackage(data) + assert.NoError(t, err) + assert.NotNil(t, pp) + assert.Empty(t, pp.Metadata.Readme) + }) + + t.Run("ValidWithReadme", func(t *testing.T) { + data := createArchive(map[string][]byte{"pubspec.yaml": []byte(pubspecContent), "README.md": []byte("readme")}) + + pp, err := ParsePackage(data) + assert.NoError(t, err) + assert.NotNil(t, pp) + assert.Equal(t, "readme", pp.Metadata.Readme) + }) +} + +func TestParsePubspecMetadata(t *testing.T) { + t.Run("InvalidName", func(t *testing.T) { + for _, name := range []string{"123abc", "ab-cd"} { + pp, err := ParsePubspecMetadata(strings.NewReader(`name: ` + name)) + assert.Nil(t, pp) + assert.ErrorIs(t, err, ErrInvalidName) + } + }) + + t.Run("InvalidVersion", func(t *testing.T) { + pp, err := ParsePubspecMetadata(strings.NewReader(`name: dummy +version: invalid`)) + assert.Nil(t, pp) + assert.ErrorIs(t, err, ErrInvalidVersion) + }) + + t.Run("Valid", func(t *testing.T) { + pp, err := ParsePubspecMetadata(strings.NewReader(pubspecContent)) + assert.NoError(t, err) + assert.NotNil(t, pp) + + assert.Equal(t, packageName, pp.Name) + assert.Equal(t, packageVersion, pp.Version) + assert.Equal(t, description, pp.Metadata.Description) + assert.Equal(t, projectURL, pp.Metadata.ProjectURL) + assert.Equal(t, repositoryURL, pp.Metadata.RepositoryURL) + assert.Equal(t, documentationURL, pp.Metadata.DocumentationURL) + assert.NotNil(t, pp.Metadata.Pubspec) + }) +} diff --git a/modules/packages/rubygems/metadata.go b/modules/packages/rubygems/metadata.go index 942f205fc3157..05c1a8a719cbe 100644 --- a/modules/packages/rubygems/metadata.go +++ b/modules/packages/rubygems/metadata.go @@ -80,7 +80,6 @@ type gemspec struct { VersionRequirements requirement `yaml:"version_requirements"` } `yaml:"dependencies"` Description string `yaml:"description"` - Email string `yaml:"email"` Executables []string `yaml:"executables"` Extensions []interface{} `yaml:"extensions"` ExtraRdocFiles []string `yaml:"extra_rdoc_files"` diff --git a/modules/repository/hooks.go b/modules/repository/hooks.go index c2eb3a7c75f75..7bc77552bd051 100644 --- a/modules/repository/hooks.go +++ b/modules/repository/hooks.go @@ -8,6 +8,7 @@ import ( "fmt" "os" "path/filepath" + "runtime" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/setting" @@ -153,6 +154,10 @@ func createDelegateHooks(repoPath string) (err error) { } func checkExecutable(filename string) bool { + // windows has no concept of a executable bit + if runtime.GOOS == "windows" { + return true + } fileInfo, err := os.Stat(filename) if err != nil { return false diff --git a/modules/setting/database.go b/modules/setting/database.go index 8fdd5f2bcb2ff..af4e780d76bd4 100644 --- a/modules/setting/database.go +++ b/modules/setting/database.go @@ -39,6 +39,7 @@ var ( LogSQL bool Charset string Timeout int // seconds + SQLiteJournalMode string UseSQLite3 bool UseMySQL bool UseMSSQL bool @@ -91,6 +92,8 @@ func InitDBConfig() { Database.Path = sec.Key("PATH").MustString(filepath.Join(AppDataPath, "gitea.db")) Database.Timeout = sec.Key("SQLITE_TIMEOUT").MustInt(500) + Database.SQLiteJournalMode = sec.Key("SQLITE_JOURNAL_MODE").MustString("") + Database.MaxIdleConns = sec.Key("MAX_IDLE_CONNS").MustInt(2) if Database.UseMySQL { Database.ConnMaxLifetime = sec.Key("CONN_MAX_LIFETIME").MustDuration(3 * time.Second) @@ -136,7 +139,12 @@ func DBConnStr() (string, error) { if err := os.MkdirAll(path.Dir(Database.Path), os.ModePerm); err != nil { return "", fmt.Errorf("Failed to create directories: %v", err) } - connStr = fmt.Sprintf("file:%s?cache=shared&mode=rwc&_busy_timeout=%d&_txlock=immediate", Database.Path, Database.Timeout) + journalMode := "" + if Database.SQLiteJournalMode != "" { + journalMode = "&_journal_mode=" + Database.SQLiteJournalMode + } + connStr = fmt.Sprintf("file:%s?cache=shared&mode=rwc&_busy_timeout=%d&_txlock=immediate%s", + Database.Path, Database.Timeout, journalMode) default: return "", fmt.Errorf("Unknown database type: %s", Database.Type) } diff --git a/modules/setting/mailer.go b/modules/setting/mailer.go index 8a26f8b0c49f8..d6f1dae0f7156 100644 --- a/modules/setting/mailer.go +++ b/modules/setting/mailer.go @@ -5,7 +5,9 @@ package setting import ( + "net" "net/mail" + "strings" "time" "code.gitea.io/gitea/modules/log" @@ -23,18 +25,19 @@ type Mailer struct { FromName string FromEmail string SendAsPlainText bool - MailerType string SubjectPrefix string // SMTP sender - Host string - User, Passwd string - DisableHelo bool - HeloHostname string - SkipVerify bool - UseCertificate bool - CertFile, KeyFile string - IsTLSEnabled bool + Protocol string + SMTPAddr string + SMTPPort string + User, Passwd string + EnableHelo bool + HeloHostname string + ForceTrustServerCert bool + UseClientCert bool + ClientCertFile string + ClientKeyFile string // Sendmail sender SendmailPath string @@ -56,19 +59,19 @@ func newMailService() { MailService = &Mailer{ Name: sec.Key("NAME").MustString(AppName), SendAsPlainText: sec.Key("SEND_AS_PLAIN_TEXT").MustBool(false), - MailerType: sec.Key("MAILER_TYPE").In("", []string{"smtp", "sendmail", "dummy"}), - - Host: sec.Key("HOST").String(), - User: sec.Key("USER").String(), - Passwd: sec.Key("PASSWD").String(), - DisableHelo: sec.Key("DISABLE_HELO").MustBool(), - HeloHostname: sec.Key("HELO_HOSTNAME").String(), - SkipVerify: sec.Key("SKIP_VERIFY").MustBool(), - UseCertificate: sec.Key("USE_CERTIFICATE").MustBool(), - CertFile: sec.Key("CERT_FILE").String(), - KeyFile: sec.Key("KEY_FILE").String(), - IsTLSEnabled: sec.Key("IS_TLS_ENABLED").MustBool(), - SubjectPrefix: sec.Key("SUBJECT_PREFIX").MustString(""), + + Protocol: sec.Key("PROTOCOL").In("", []string{"smtp", "smtps", "smtp+startls", "smtp+unix", "sendmail", "dummy"}), + SMTPAddr: sec.Key("SMTP_ADDR").String(), + SMTPPort: sec.Key("SMTP_PORT").String(), + User: sec.Key("USER").String(), + Passwd: sec.Key("PASSWD").String(), + EnableHelo: sec.Key("ENABLE_HELO").MustBool(true), + HeloHostname: sec.Key("HELO_HOSTNAME").String(), + ForceTrustServerCert: sec.Key("FORCE_TRUST_SERVER_CERT").MustBool(false), + UseClientCert: sec.Key("USE_CLIENT_CERT").MustBool(false), + ClientCertFile: sec.Key("CLIENT_CERT_FILE").String(), + ClientKeyFile: sec.Key("CLIENT_KEY_FILE").String(), + SubjectPrefix: sec.Key("SUBJECT_PREFIX").MustString(""), SendmailPath: sec.Key("SENDMAIL_PATH").MustString("sendmail"), SendmailTimeout: sec.Key("SENDMAIL_TIMEOUT").MustDuration(5 * time.Minute), @@ -77,26 +80,123 @@ func newMailService() { MailService.From = sec.Key("FROM").MustString(MailService.User) MailService.EnvelopeFrom = sec.Key("ENVELOPE_FROM").MustString("") - // FIXME: DEPRECATED to be removed in v1.18.0 - deprecatedSetting("mailer", "ENABLE_HTML_ALTERNATIVE", "mailer", "SEND_AS_PLAIN_TEXT") - if sec.HasKey("ENABLE_HTML_ALTERNATIVE") { - MailService.SendAsPlainText = !sec.Key("ENABLE_HTML_ALTERNATIVE").MustBool(false) + // FIXME: DEPRECATED to be removed in v1.19.0 + deprecatedSetting("mailer", "MAILER_TYPE", "mailer", "PROTOCOL") + if sec.HasKey("MAILER_TYPE") && !sec.HasKey("PROTOCOL") { + if sec.Key("MAILER_TYPE").String() == "sendmail" { + MailService.Protocol = "sendmail" + } } - // FIXME: DEPRECATED to be removed in v1.18.0 - deprecatedSetting("mailer", "USE_SENDMAIL", "mailer", "MAILER_TYPE") - if sec.HasKey("USE_SENDMAIL") { - if MailService.MailerType == "" && sec.Key("USE_SENDMAIL").MustBool(false) { - MailService.MailerType = "sendmail" + // FIXME: DEPRECATED to be removed in v1.19.0 + deprecatedSetting("mailer", "HOST", "mailer", "SMTP_ADDR") + if sec.HasKey("HOST") && !sec.HasKey("SMTP_ADDR") { + givenHost := sec.Key("HOST").String() + addr, port, err := net.SplitHostPort(givenHost) + if err != nil { + log.Fatal("Invalid mailer.HOST (%s): %v", givenHost, err) } + MailService.SMTPAddr = addr + MailService.SMTPPort = port } - parsed, err := mail.ParseAddress(MailService.From) - if err != nil { - log.Fatal("Invalid mailer.FROM (%s): %v", MailService.From, err) + // FIXME: DEPRECATED to be removed in v1.19.0 + deprecatedSetting("mailer", "IS_TLS_ENABLED", "mailer", "PROTOCOL") + if sec.HasKey("IS_TLS_ENABLED") && !sec.HasKey("PROTOCOL") { + if sec.Key("IS_TLS_ENABLED").MustBool() { + MailService.Protocol = "smtps" + } else { + MailService.Protocol = "smtp+startls" + } + } + + if MailService.SMTPPort == "" { + switch MailService.Protocol { + case "smtp": + MailService.SMTPPort = "25" + case "smtps": + MailService.SMTPPort = "465" + case "smtp+startls": + MailService.SMTPPort = "587" + } + } + + if MailService.Protocol == "" { + if strings.ContainsAny(MailService.SMTPAddr, "/\\") { + MailService.Protocol = "smtp+unix" + } else { + switch MailService.SMTPPort { + case "25": + MailService.Protocol = "smtp" + case "465": + MailService.Protocol = "smtps" + case "587": + MailService.Protocol = "smtp+startls" + default: + log.Error("unable to infer unspecified mailer.PROTOCOL from mailer.SMTP_PORT = %q, assume using smtps", MailService.SMTPPort) + MailService.Protocol = "smtps" + } + } + } + + // we want to warn if users use SMTP on a non-local IP; + // we might as well take the opportunity to check that it has an IP at all + ips := tryResolveAddr(MailService.SMTPAddr) + if MailService.Protocol == "smtp" { + for _, ip := range ips { + if !ip.IsLoopback() { + log.Warn("connecting over insecure SMTP protocol to non-local address is not recommended") + break + } + } + } + + // FIXME: DEPRECATED to be removed in v1.19.0 + deprecatedSetting("mailer", "DISABLE_HELO", "mailer", "ENABLE_HELO") + if sec.HasKey("DISABLE_HELO") && !sec.HasKey("ENABLE_HELO") { + MailService.EnableHelo = !sec.Key("DISABLE_HELO").MustBool() + } + + // FIXME: DEPRECATED to be removed in v1.19.0 + deprecatedSetting("mailer", "SKIP_VERIFY", "mailer", "FORCE_TRUST_SERVER_CERT") + if sec.HasKey("SKIP_VERIFY") && !sec.HasKey("FORCE_TRUST_SERVER_CERT") { + MailService.ForceTrustServerCert = sec.Key("SKIP_VERIFY").MustBool() + } + + // FIXME: DEPRECATED to be removed in v1.19.0 + deprecatedSetting("mailer", "USE_CERTIFICATE", "mailer", "USE_CLIENT_CERT") + if sec.HasKey("USE_CERTIFICATE") && !sec.HasKey("USE_CLIENT_CERT") { + MailService.UseClientCert = sec.Key("USE_CLIENT_CERT").MustBool() + } + + // FIXME: DEPRECATED to be removed in v1.19.0 + deprecatedSetting("mailer", "CERT_FILE", "mailer", "CLIENT_CERT_FILE") + if sec.HasKey("CERT_FILE") && !sec.HasKey("CLIENT_CERT_FILE") { + MailService.ClientCertFile = sec.Key("CERT_FILE").String() + } + + // FIXME: DEPRECATED to be removed in v1.19.0 + deprecatedSetting("mailer", "KEY_FILE", "mailer", "CLIENT_KEY_FILE") + if sec.HasKey("KEY_FILE") && !sec.HasKey("CLIENT_KEY_FILE") { + MailService.ClientKeyFile = sec.Key("KEY_FILE").String() + } + + // FIXME: DEPRECATED to be removed in v1.19.0 + deprecatedSetting("mailer", "ENABLE_HTML_ALTERNATIVE", "mailer", "SEND_AS_PLAIN_TEXT") + if sec.HasKey("ENABLE_HTML_ALTERNATIVE") && !sec.HasKey("SEND_AS_PLAIN_TEXT") { + MailService.SendAsPlainText = !sec.Key("ENABLE_HTML_ALTERNATIVE").MustBool(false) + } + + if MailService.From != "" { + parsed, err := mail.ParseAddress(MailService.From) + if err != nil { + log.Fatal("Invalid mailer.FROM (%s): %v", MailService.From, err) + } + MailService.FromName = parsed.Name + MailService.FromEmail = parsed.Address + } else { + log.Error("no mailer.FROM provided, email system may not work.") } - MailService.FromName = parsed.Name - MailService.FromEmail = parsed.Address switch MailService.EnvelopeFrom { case "": @@ -105,7 +205,7 @@ func newMailService() { MailService.EnvelopeFrom = "" MailService.OverrideEnvelopeFrom = true default: - parsed, err = mail.ParseAddress(MailService.EnvelopeFrom) + parsed, err := mail.ParseAddress(MailService.EnvelopeFrom) if err != nil { log.Fatal("Invalid mailer.ENVELOPE_FROM (%s): %v", MailService.EnvelopeFrom, err) } @@ -113,11 +213,8 @@ func newMailService() { MailService.EnvelopeFrom = parsed.Address } - if MailService.MailerType == "" { - MailService.MailerType = "smtp" - } - - if MailService.MailerType == "sendmail" { + if MailService.Protocol == "sendmail" { + var err error MailService.SendmailArgs, err = shellquote.Split(sec.Key("SENDMAIL_ARGS").String()) if err != nil { log.Error("Failed to parse Sendmail args: %s with error %v", CustomConf, err) @@ -148,3 +245,21 @@ func newNotifyMailService() { Service.EnableNotifyMail = true log.Info("Notify Mail Service Enabled") } + +func tryResolveAddr(addr string) []net.IP { + if strings.HasPrefix(addr, "[") && strings.HasSuffix(addr, "]") { + addr = addr[1 : len(addr)-1] + } + ip := net.ParseIP(addr) + if ip != nil { + ips := make([]net.IP, 1) + ips[0] = ip + return ips + } + ips, err := net.LookupIP(addr) + if err != nil { + log.Warn("could not look up mailer.SMTP_ADDR: %v", err) + return make([]net.IP, 0) + } + return ips +} diff --git a/modules/setting/repository.go b/modules/setting/repository.go index 733bc6d90e600..d0406dbf90284 100644 --- a/modules/setting/repository.go +++ b/modules/setting/repository.go @@ -48,6 +48,7 @@ var ( DefaultBranch string AllowAdoptionOfUnadoptedRepositories bool AllowDeleteOfUnadoptedRepositories bool + DisableDownloadSourceArchives bool // Repository editor settings Editor struct { diff --git a/modules/setting/setting.go b/modules/setting/setting.go index 23e3280dc9f10..465dc75cad16e 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -262,8 +262,8 @@ var ( }{ ExplorePagingNum: 20, SitemapPagingNum: 20, - IssuePagingNum: 10, - RepoSearchPagingNum: 10, + IssuePagingNum: 20, + RepoSearchPagingNum: 20, MembersPagingNum: 20, FeedMaxCommitNum: 5, FeedPagingNum: 20, diff --git a/modules/ssh/ssh.go b/modules/ssh/ssh.go index 2affeb781a998..6b601c008fe9e 100644 --- a/modules/ssh/ssh.go +++ b/modules/ssh/ssh.go @@ -11,6 +11,7 @@ import ( "crypto/rsa" "crypto/x509" "encoding/pem" + "errors" "fmt" "io" "net" @@ -74,11 +75,20 @@ func sessionHandler(session ssh.Session) { ctx, cancel := context.WithCancel(session.Context()) defer cancel() + gitProtocol := "" + for _, env := range session.Environ() { + if strings.HasPrefix(env, "GIT_PROTOCOL=") { + _, gitProtocol, _ = strings.Cut(env, "=") + break + } + } + cmd := exec.CommandContext(ctx, setting.AppPath, args...) cmd.Env = append( os.Environ(), "SSH_ORIGINAL_COMMAND="+command, "SKIP_MINWINSVC=1", + "GIT_PROTOCOL="+gitProtocol, ) stdout, err := cmd.StdoutPipe() @@ -142,10 +152,14 @@ func sessionHandler(session ssh.Session) { // Wait for the command to exit and log any errors we get err = cmd.Wait() if err != nil { - log.Error("SSH: Wait: %v", err) + // Cannot use errors.Is here because ExitError doesn't implement Is + // Thus errors.Is will do equality test NOT type comparison + if _, ok := err.(*exec.ExitError); !ok { + log.Error("SSH: Wait: %v", err) + } } - if err := session.Exit(getExitStatusFromError(err)); err != nil { + if err := session.Exit(getExitStatusFromError(err)); err != nil && !errors.Is(err, io.EOF) { log.Error("Session failed to exit. %s", err) } } diff --git a/modules/structs/mirror.go b/modules/structs/mirror.go new file mode 100644 index 0000000000000..8e8a8a2705d2f --- /dev/null +++ b/modules/structs/mirror.go @@ -0,0 +1,25 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package structs + +// CreatePushMirrorOption represents need information to create a push mirror of a repository. +type CreatePushMirrorOption struct { + RemoteAddress string `json:"remote_address"` + RemoteUsername string `json:"remote_username"` + RemotePassword string `json:"remote_password"` + Interval string `json:"interval"` +} + +// PushMirror represents information of a push mirror +// swagger:model +type PushMirror struct { + RepoName string `json:"repo_name"` + RemoteName string `json:"remote_name"` + RemoteAddress string `json:"remote_address"` + CreatedUnix string `json:"created"` + LastUpdateUnix string `json:"last_update"` + LastError string `json:"last_error"` + Interval string `json:"interval"` +} diff --git a/modules/structs/pull_review.go b/modules/structs/pull_review.go index 6544604acbaed..7c9360a0c2200 100644 --- a/modules/structs/pull_review.go +++ b/modules/structs/pull_review.go @@ -97,6 +97,7 @@ type SubmitPullReviewOptions struct { // DismissPullReviewOptions are options to dismiss a pull review type DismissPullReviewOptions struct { Message string `json:"message"` + Priors bool `json:"priors"` } // PullReviewRequestOptions are options to add or remove pull review requests diff --git a/modules/structs/repo.go b/modules/structs/repo.go index ef247ebc9ce3a..6a5736898d139 100644 --- a/modules/structs/repo.go +++ b/modules/structs/repo.go @@ -77,24 +77,26 @@ type Repository struct { // swagger:strfmt date-time Created time.Time `json:"created_at"` // swagger:strfmt date-time - Updated time.Time `json:"updated_at"` - Permissions *Permission `json:"permissions,omitempty"` - HasIssues bool `json:"has_issues"` - InternalTracker *InternalTracker `json:"internal_tracker,omitempty"` - ExternalTracker *ExternalTracker `json:"external_tracker,omitempty"` - HasWiki bool `json:"has_wiki"` - ExternalWiki *ExternalWiki `json:"external_wiki,omitempty"` - HasPullRequests bool `json:"has_pull_requests"` - HasProjects bool `json:"has_projects"` - IgnoreWhitespaceConflicts bool `json:"ignore_whitespace_conflicts"` - AllowMerge bool `json:"allow_merge_commits"` - AllowRebase bool `json:"allow_rebase"` - AllowRebaseMerge bool `json:"allow_rebase_explicit"` - AllowSquash bool `json:"allow_squash_merge"` - DefaultMergeStyle string `json:"default_merge_style"` - AvatarURL string `json:"avatar_url"` - Internal bool `json:"internal"` - MirrorInterval string `json:"mirror_interval"` + Updated time.Time `json:"updated_at"` + Permissions *Permission `json:"permissions,omitempty"` + HasIssues bool `json:"has_issues"` + InternalTracker *InternalTracker `json:"internal_tracker,omitempty"` + ExternalTracker *ExternalTracker `json:"external_tracker,omitempty"` + HasWiki bool `json:"has_wiki"` + ExternalWiki *ExternalWiki `json:"external_wiki,omitempty"` + HasPullRequests bool `json:"has_pull_requests"` + HasProjects bool `json:"has_projects"` + IgnoreWhitespaceConflicts bool `json:"ignore_whitespace_conflicts"` + AllowMerge bool `json:"allow_merge_commits"` + AllowRebase bool `json:"allow_rebase"` + AllowRebaseMerge bool `json:"allow_rebase_explicit"` + AllowSquash bool `json:"allow_squash_merge"` + AllowRebaseUpdate bool `json:"allow_rebase_update"` + DefaultDeleteBranchAfterMerge bool `json:"default_delete_branch_after_merge"` + DefaultMergeStyle string `json:"default_merge_style"` + AvatarURL string `json:"avatar_url"` + Internal bool `json:"internal"` + MirrorInterval string `json:"mirror_interval"` // swagger:strfmt date-time MirrorUpdated time.Time `json:"mirror_updated,omitempty"` RepoTransfer *RepoTransfer `json:"repo_transfer"` diff --git a/modules/structs/repo_file.go b/modules/structs/repo_file.go index 135e6484cd69b..ce1a9fe4be365 100644 --- a/modules/structs/repo_file.go +++ b/modules/structs/repo_file.go @@ -87,9 +87,10 @@ type FileLinksResponse struct { // ContentsResponse contains information about a repo's entry's (dir, file, symlink, submodule) metadata and content type ContentsResponse struct { - Name string `json:"name"` - Path string `json:"path"` - SHA string `json:"sha"` + Name string `json:"name"` + Path string `json:"path"` + SHA string `json:"sha"` + LastCommitSHA string `json:"last_commit_sha"` // `type` will be `file`, `dir`, `symlink`, or `submodule` Type string `json:"type"` Size int64 `json:"size"` diff --git a/modules/structs/user.go b/modules/structs/user.go index 431e230fac038..81516894a58f9 100644 --- a/modules/structs/user.go +++ b/modules/structs/user.go @@ -17,6 +17,9 @@ type User struct { ID int64 `json:"id"` // the user's username UserName string `json:"login"` + // the user's authentication sign-in name. + // default: empty + LoginName string `json:"login_name"` // the user's full name FullName string `json:"full_name"` // swagger:strfmt email diff --git a/modules/templates/base.go b/modules/templates/base.go index 282019f826c1d..9563650e127b7 100644 --- a/modules/templates/base.go +++ b/modules/templates/base.go @@ -35,10 +35,11 @@ func BaseVars() Vars { "IsLandingPageExplore": setting.LandingPageURL == setting.LandingPageExplore, "IsLandingPageOrganizations": setting.LandingPageURL == setting.LandingPageOrganizations, - "ShowRegistrationButton": setting.Service.ShowRegistrationButton, - "ShowMilestonesDashboardPage": setting.Service.ShowMilestonesDashboardPage, - "ShowFooterBranding": setting.ShowFooterBranding, - "ShowFooterVersion": setting.ShowFooterVersion, + "ShowRegistrationButton": setting.Service.ShowRegistrationButton, + "ShowMilestonesDashboardPage": setting.Service.ShowMilestonesDashboardPage, + "ShowFooterBranding": setting.ShowFooterBranding, + "ShowFooterVersion": setting.ShowFooterVersion, + "DisableDownloadSourceArchives": setting.Repository.DisableDownloadSourceArchives, "EnableSwagger": setting.API.EnableSwagger, "EnableOpenIDSignIn": setting.Service.EnableOpenIDSignIn, diff --git a/modules/typesniffer/typesniffer.go b/modules/typesniffer/typesniffer.go index b6a6646d50ce9..e50928e8c260a 100644 --- a/modules/typesniffer/typesniffer.go +++ b/modules/typesniffer/typesniffer.go @@ -70,6 +70,16 @@ func (ct SniffedType) IsRepresentableAsText() bool { return ct.IsText() || ct.IsSvgImage() } +// IsBrowsableType returns whether a non-text type can be displayed in a browser +func (ct SniffedType) IsBrowsableBinaryType() bool { + return ct.IsImage() || ct.IsSvgImage() || ct.IsPDF() || ct.IsVideo() || ct.IsAudio() +} + +// GetMimeType returns the mime type +func (ct SniffedType) GetMimeType() string { + return strings.SplitN(ct.contentType, ";", 2)[0] +} + // DetectContentType extends http.DetectContentType with more content types. Defaults to text/unknown if input is empty. func DetectContentType(data []byte) SniffedType { if len(data) == 0 { diff --git a/modules/util/filebuffer/file_backed_buffer.go b/modules/util/filebuffer/file_backed_buffer.go index 128030b4c5c1b..8e3e138e04b77 100644 --- a/modules/util/filebuffer/file_backed_buffer.go +++ b/modules/util/filebuffer/file_backed_buffer.go @@ -103,35 +103,45 @@ func (b *FileBackedBuffer) Size() int64 { return b.size } -func (b *FileBackedBuffer) switchToReader() { +func (b *FileBackedBuffer) switchToReader() error { if b.reader != nil { - return + return nil } if b.file != nil { + if _, err := b.file.Seek(0, io.SeekStart); err != nil { + return err + } b.reader = b.file } else { b.reader = bytes.NewReader(b.buffer.Bytes()) } + return nil } // Read implements io.Reader func (b *FileBackedBuffer) Read(p []byte) (int, error) { - b.switchToReader() + if err := b.switchToReader(); err != nil { + return 0, err + } return b.reader.Read(p) } // ReadAt implements io.ReaderAt func (b *FileBackedBuffer) ReadAt(p []byte, off int64) (int, error) { - b.switchToReader() + if err := b.switchToReader(); err != nil { + return 0, err + } return b.reader.ReadAt(p, off) } // Seek implements io.Seeker func (b *FileBackedBuffer) Seek(offset int64, whence int) (int64, error) { - b.switchToReader() + if err := b.switchToReader(); err != nil { + return 0, err + } return b.reader.Seek(offset, whence) } diff --git a/modules/util/filebuffer/file_backed_buffer_test.go b/modules/util/filebuffer/file_backed_buffer_test.go new file mode 100644 index 0000000000000..83ef58561de53 --- /dev/null +++ b/modules/util/filebuffer/file_backed_buffer_test.go @@ -0,0 +1,36 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package filebuffer + +import ( + "io" + "strings" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestFileBackedBuffer(t *testing.T) { + cases := []struct { + MaxMemorySize int + Data string + }{ + {5, "test"}, + {5, "testtest"}, + } + + for _, c := range cases { + buf, err := CreateFromReader(strings.NewReader(c.Data), c.MaxMemorySize) + assert.NoError(t, err) + + assert.EqualValues(t, len(c.Data), buf.Size()) + + data, err := io.ReadAll(buf) + assert.NoError(t, err) + assert.Equal(t, c.Data, string(data)) + + assert.NoError(t, buf.Close()) + } +} diff --git a/modules/util/sec_to_time.go b/modules/util/sec_to_time.go index 9ce6fe1a13eb5..13461915e6f35 100644 --- a/modules/util/sec_to_time.go +++ b/modules/util/sec_to_time.go @@ -18,10 +18,22 @@ import ( // 45677465s -> 1 year 6 months func SecToTime(duration int64) string { formattedTime := "" - years := duration / (3600 * 24 * 7 * 4 * 12) - months := (duration / (3600 * 24 * 30)) % 12 - weeks := (duration / (3600 * 24 * 7)) % 4 - days := (duration / (3600 * 24)) % 7 + + // The following four variables are calculated by taking + // into account the previously calculated variables, this avoids + // pitfalls when using remainders. As that could lead to incorrect + // results when the calculated number equals the quotient number. + remainingDays := duration / (60 * 60 * 24) + years := remainingDays / 365 + remainingDays -= years * 365 + months := remainingDays * 12 / 365 + remainingDays -= months * 365 / 12 + weeks := remainingDays / 7 + remainingDays -= weeks * 7 + days := remainingDays + + // The following three variables are calculated without depending + // on the previous calculated variables. hours := (duration / 3600) % 24 minutes := (duration / 60) % 60 seconds := duration % 60 diff --git a/modules/util/sec_to_time_test.go b/modules/util/sec_to_time_test.go index 854190462bc37..1e256aa8650cf 100644 --- a/modules/util/sec_to_time_test.go +++ b/modules/util/sec_to_time_test.go @@ -11,10 +11,21 @@ import ( ) func TestSecToTime(t *testing.T) { - assert.Equal(t, SecToTime(66), "1 minute 6 seconds") - assert.Equal(t, SecToTime(52410), "14 hours 33 minutes") - assert.Equal(t, SecToTime(563418), "6 days 12 hours") - assert.Equal(t, SecToTime(1563418), "2 weeks 4 days") - assert.Equal(t, SecToTime(3937125), "1 month 2 weeks") - assert.Equal(t, SecToTime(45677465), "1 year 5 months") + second := int64(1) + minute := 60 * second + hour := 60 * minute + day := 24 * hour + year := 365 * day + + assert.Equal(t, "1 minute 6 seconds", SecToTime(minute+6*second)) + assert.Equal(t, "1 hour", SecToTime(hour)) + assert.Equal(t, "1 hour", SecToTime(hour+second)) + assert.Equal(t, "14 hours 33 minutes", SecToTime(14*hour+33*minute+30*second)) + assert.Equal(t, "6 days 12 hours", SecToTime(6*day+12*hour+30*minute+18*second)) + assert.Equal(t, "2 weeks 4 days", SecToTime((2*7+4)*day+2*hour+16*minute+58*second)) + assert.Equal(t, "4 weeks", SecToTime(4*7*day)) + assert.Equal(t, "4 weeks 1 day", SecToTime((4*7+1)*day)) + assert.Equal(t, "1 month 2 weeks", SecToTime((6*7+3)*day+13*hour+38*minute+45*second)) + assert.Equal(t, "11 months", SecToTime(year-25*day)) + assert.Equal(t, "1 year 5 months", SecToTime(year+163*day+10*hour+11*minute+5*second)) } diff --git a/options/gitignore/Bazel b/options/gitignore/Bazel index 4e1d5a2ba0a42..bc3afc20ba696 100644 --- a/options/gitignore/Bazel +++ b/options/gitignore/Bazel @@ -6,7 +6,7 @@ /bazel-* # Directories for the Bazel IntelliJ plugin containing the generated -# IntelliJ project files and plugin configuration. Separate directories are +# IntelliJ project files and plugin configuration. Seperate directories are # for the IntelliJ, Android Studio and CLion versions of the plugin. /.ijwb/ /.aswb/ diff --git a/options/license/CC-BY-3.0-IGO b/options/license/CC-BY-3.0-IGO new file mode 100644 index 0000000000000..13ab9536e1792 --- /dev/null +++ b/options/license/CC-BY-3.0-IGO @@ -0,0 +1,101 @@ +Creative Commons Attribution 3.0 IGO + +CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM ITS USE. THE LICENSOR IS NOT NECESSARILY AN INTERGOVERNMENTAL ORGANIZATION (IGO), AS DEFINED IN THE LICENSE BELOW. + +License + +THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("LICENSE"). THE LICENSOR (DEFINED BELOW) HOLDS COPYRIGHT AND OTHER RIGHTS IN THE WORK. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE IS PROHIBITED. + +BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION FOR YOUR ACCEPTANCE AND AGREEMENT TO THE TERMS OF THE LICENSE. + +1. Definitions + + a. "IGO" means, solely and exclusively for purposes of this License, an organization established by a treaty or other instrument governed by international law and possessing its own international legal personality. Other organizations established to carry out activities across national borders and that accordingly enjoy immunity from legal process are also IGOs for the sole and exclusive purposes of this License. IGOs may include as members, in addition to states, other entities. + + b. "Work" means the literary and/or artistic work eligible for copyright protection, whatever may be the mode or form of its expression including digital form, and offered under the terms of this License. It is understood that a database, which by reason of the selection and arrangement of its contents constitutes an intellectual creation, is considered a Work. + + c. "Licensor" means the individual, individuals, entity or entities that offer(s) the Work under the terms of this License and may be, but is not necessarily, an IGO. + + d. "You" means an individual or entity exercising rights under this License. + + e. "Reproduce" means to make a copy of the Work in any manner or form, and by any means. + + f. "Distribute" means the activity of making publicly available the Work or Adaptation (or copies of the Work or Adaptation), as applicable, by sale, rental, public lending or any other known form of transfer of ownership or possession of the Work or copy of the Work. + + g. "Publicly Perform" means to perform public recitations of the Work and to communicate to the public those public recitations, by any means or process, including by wire or wireless means or public digital performances; to make available to the public Works in such a way that members of the public may access these Works from a place and at a place individually chosen by them; to perform the Work to the public by any means or process and the communication to the public of the performances of the Work, including by public digital performance; to broadcast and rebroadcast the Work by any means including signs, sounds or images. + + h. "Adaptation" means a work derived from or based upon the Work, or upon the Work and other pre-existing works. Adaptations may include works such as translations, derivative works, or any alterations and arrangements of any kind involving the Work. For purposes of this License, where the Work is a musical work, performance, or phonogram, the synchronization of the Work in timed-relation with a moving image is an Adaptation. For the avoidance of doubt, including the Work in a Collection is not an Adaptation. + + i. "Collection" means a collection of literary or artistic works or other works or subject matter other than works listed in Section 1(b) which by reason of the selection and arrangement of their contents, constitute intellectual creations, in which the Work is included in its entirety in unmodified form along with one or more other contributions, each constituting separate and independent works in themselves, which together are assembled into a collective whole. For the avoidance of doubt, a Collection will not be considered as an Adaptation. + +2. Scope of this License. Nothing in this License is intended to reduce, limit, or restrict any uses free from copyright protection. + +3. License Grant. Subject to the terms and conditions of this License, the Licensor hereby grants You a worldwide, royalty-free, non-exclusive license to exercise the rights in the Work as follows: + + a. to Reproduce, Distribute and Publicly Perform the Work, to incorporate the Work into one or more Collections, and to Reproduce, Distribute and Publicly Perform the Work as incorporated in the Collections; and, + + b. to create, Reproduce, Distribute and Publicly Perform Adaptations, provided that You clearly label, demarcate or otherwise identify that changes were made to the original Work. + + c. For the avoidance of doubt: + + i. Non-waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; + + ii. Waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor waives the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; and, + + iii. Voluntary License Schemes. To the extent possible, the Licensor waives the right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary licensing scheme. + +This License lasts for the duration of the term of the copyright in the Work licensed by the Licensor. The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. All rights not expressly granted by the Licensor are hereby reserved. + +4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions: + + a. You may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work (see section 8(a)). You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from a Licensor You must, to the extent practicable, remove from the Collection any credit (inclusive of any logo, trademark, official mark or official emblem) as required by Section 4(b), as requested. If You create an Adaptation, upon notice from a Licensor You must, to the extent practicable, remove from the Adaptation any credit (inclusive of any logo, trademark, official mark or official emblem) as required by Section 4(b), as requested. + + b. If You Distribute, or Publicly Perform the Work or any Adaptations or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) any attributions that the Licensor indicates be associated with the Work as indicated in a copyright notice, (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that the Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and, (iv) consistent with Section 3(b), in the case of an Adaptation, a credit identifying the use of the Work in the Adaptation. The credit required by this Section 4(b) may be implemented in any reasonable manner; provided, however, that in the case of an Adaptation or Collection, at a minimum such credit will appear, if a credit for all contributors to the Adaptation or Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Licensor or others designated for attribution, of You or Your use of the Work, without the separate, express prior written permission of the Licensor or such others. + + c. Except as otherwise agreed in writing by the Licensor, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Adaptations or Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the honor or reputation of the Licensor where moral rights apply. + +5. Representations, Warranties and Disclaimer + +THE LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. + +6. Limitation on Liability + +IN NO EVENT WILL THE LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF THE LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. Termination + + a. Subject to the terms and conditions set forth in this License, the license granted here lasts for the duration of the term of the copyright in the Work licensed by the Licensor as stated in Section 3. Notwithstanding the above, the Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated below. + + b. If You fail to comply with this License, then this License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Adaptations or Collections from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License. Notwithstanding the foregoing, this License reinstates automatically as of the date the violation is cured, provided it is cured within 30 days of You discovering the violation, or upon express reinstatement by the Licensor. For the avoidance of doubt, this Section 7(b) does not affect any rights the Licensor may have to seek remedies for violations of this License by You. + +8. Miscellaneous + + a. Each time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License. + + b. Each time You Distribute or Publicly Perform an Adaptation, the Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License. + + c. If any provision of this License is invalid or unenforceable, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. + + d. No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the Licensor. + + e. This License constitutes the entire agreement between You and the Licensor with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. The Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You. + + f. The rights granted under, and the subject matter referenced, in this License were drafted utilizing the terminology of the Berne Convention for the Protection of Literary and Artistic Works (as amended on September 28, 1979), the Rome Convention of 1961, the WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and the Universal Copyright Convention (as revised on July 24, 1971). Interpretation of the scope of the rights granted by the Licensor and the conditions imposed on You under this License, this License, and the rights and conditions set forth herein shall be made with reference to copyright as determined in accordance with general principles of international law, including the above mentioned conventions. + + g. Nothing in this License constitutes or may be interpreted as a limitation upon or waiver of any privileges and immunities that may apply to the Licensor or You, including immunity from the legal processes of any jurisdiction, national court or other authority. + + h. Where the Licensor is an IGO, any and all disputes arising under this License that cannot be settled amicably shall be resolved in accordance with the following procedure: + + i. Pursuant to a notice of mediation communicated by reasonable means by either You or the Licensor to the other, the dispute shall be submitted to non-binding mediation conducted in accordance with rules designated by the Licensor in the copyright notice published with the Work, or if none then in accordance with those communicated in the notice of mediation. The language used in the mediation proceedings shall be English unless otherwise agreed. + + ii. If any such dispute has not been settled within 45 days following the date on which the notice of mediation is provided, either You or the Licensor may, pursuant to a notice of arbitration communicated by reasonable means to the other, elect to have the dispute referred to and finally determined by arbitration. The arbitration shall be conducted in accordance with the rules designated by the Licensor in the copyright notice published with the Work, or if none then in accordance with the UNCITRAL Arbitration Rules as then in force. The arbitral tribunal shall consist of a sole arbitrator and the language of the proceedings shall be English unless otherwise agreed. The place of arbitration shall be where the Licensor has its headquarters. The arbitral proceedings shall be conducted remotely (e.g., via telephone conference or written submissions) whenever practicable. + + iii. Interpretation of this License in any dispute submitted to mediation or arbitration shall be as set forth in Section 8(f), above. + +Creative Commons Notice + +Creative Commons is not a party to this License, and makes no warranty whatsoever in connection with the Work. Creative Commons will not be liable to You or any party on any legal theory for any damages whatsoever, including without limitation any general, special, incidental or consequential damages arising in connection to this license. Notwithstanding the foregoing two (2) sentences, if Creative Commons has expressly identified itself as the Licensor hereunder, it shall have all rights and obligations of the Licensor. + +Except for the limited purpose of indicating to the public that the Work is licensed under the CCPL, Creative Commons does not authorize the use by either party of the trademark "Creative Commons" or any related trademark or logo of Creative Commons without the prior written consent of Creative Commons. Any permitted use will be in compliance with Creative Commons' then-current trademark usage guidelines, as may be published on its website or otherwise made available upon request from time to time. For the avoidance of doubt, this trademark restriction does not form part of this License. + +Creative Commons may be contacted at https://creativecommons.org/. diff --git a/options/license/GStreamer-exception-2005 b/options/license/GStreamer-exception-2005 new file mode 100644 index 0000000000000..95ff750da3259 --- /dev/null +++ b/options/license/GStreamer-exception-2005 @@ -0,0 +1 @@ +The Totem project hereby grant permission for non-gpl compatible GStreamer plugins to be used and distributed together with GStreamer and Totem. This permission are above and beyond the permissions granted by the GPL license Totem is covered by. diff --git a/options/license/GStreamer-exception-2008 b/options/license/GStreamer-exception-2008 new file mode 100644 index 0000000000000..28927e533ef7b --- /dev/null +++ b/options/license/GStreamer-exception-2008 @@ -0,0 +1 @@ +This project hereby grants permission for non-GPL compatible GStreamer plugins to be used and distributed together with GStreamer and this project. This permission is above and beyond the permissions granted by the GPL license by which this project is covered. If you modify this code, you may extend this exception to your version of the code, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. diff --git a/options/license/LZMA-SDK-9.11-to-9.20 b/options/license/LZMA-SDK-9.11-to-9.20 new file mode 100644 index 0000000000000..5da25bf883ce6 --- /dev/null +++ b/options/license/LZMA-SDK-9.11-to-9.20 @@ -0,0 +1,8 @@ +LICENSE +------- + +LZMA SDK is written and placed in the public domain by Igor Pavlov. + +Some code in LZMA is based on public domain code from another developers: + 1) PPMd var.H (2001): Dmitry Shkarin + 2) SHA-256: Wei Dai (Crypto++ library) diff --git a/options/license/LZMA-SDK-9.22 b/options/license/LZMA-SDK-9.22 new file mode 100644 index 0000000000000..ef4768d2a7228 --- /dev/null +++ b/options/license/LZMA-SDK-9.22 @@ -0,0 +1,15 @@ +LICENSE +------- + +LZMA SDK is written and placed in the public domain by Igor Pavlov. + +Some code in LZMA SDK is based on public domain code from another developers: + 1) PPMd var.H (2001): Dmitry Shkarin + 2) SHA-256: Wei Dai (Crypto++ library) + +Anyone is free to copy, modify, publish, use, compile, sell, or distribute the +original LZMA SDK code, either in source code form or as a compiled binary, for +any purpose, commercial or non-commercial, and by any means. + +LZMA SDK code is compatible with open source licenses, for example, you can +include it to GNU GPL or GNU LGPL code. diff --git a/options/license/MS-LPL b/options/license/MS-LPL new file mode 100644 index 0000000000000..ea8bffcaae217 --- /dev/null +++ b/options/license/MS-LPL @@ -0,0 +1,24 @@ +Microsoft Limited Public License (Ms-LPL) + +This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software. + +1. Definitions +The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. A "contribution" is the original software, or any additions or changes to the software. A "contributor" is any person that distributes its contribution under this license. "Licensed patents" are a contributor's patent claims that read directly on its contribution. + +2. Grant of Rights + (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. + + (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. + +3. Conditions and Limitations + (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks. + + (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. + + (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. + + (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. + + (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees, or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. + + (F) Platform Limitation- The licenses granted in sections 2(A) & 2(B) extend only to the software or derivative works that you create that run on a Microsoft Windows operating system product. diff --git a/options/license/Minpack b/options/license/Minpack new file mode 100644 index 0000000000000..132cc3f33fa7f --- /dev/null +++ b/options/license/Minpack @@ -0,0 +1,51 @@ +Minpack Copyright Notice (1999) University of Chicago. All rights reserved + +Redistribution and use in source and binary forms, with or +without modification, are permitted provided that the +following conditions are met: + +1. Redistributions of source code must retain the above +copyright notice, this list of conditions and the following +disclaimer. + +2. Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following +disclaimer in the documentation and/or other materials +provided with the distribution. + +3. The end-user documentation included with the +redistribution, if any, must include the following +acknowledgment: + + "This product includes software developed by the + University of Chicago, as Operator of Argonne National + Laboratory. + +Alternately, this acknowledgment may appear in the software +itself, if and wherever such third-party acknowledgments +normally appear. + +4. WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" +WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDER, THE +UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND +THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE +OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY +OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR +USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF +THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4) +DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION +UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL +BE CORRECTED. + +5. LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT +HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF +ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, +INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF +ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF +PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER +SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT +(INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, +EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE +POSSIBILITY OF SUCH LOSS OR DAMAGES. diff --git a/options/license/NICTA-1.0 b/options/license/NICTA-1.0 new file mode 100644 index 0000000000000..04622e308d1af --- /dev/null +++ b/options/license/NICTA-1.0 @@ -0,0 +1,61 @@ +NICTA Public Software Licence +Version 1.0 + +Copyright © 2004 National ICT Australia Ltd + +All rights reserved. + +By this licence, National ICT Australia Ltd (NICTA) grants permission, +free of charge, to any person who obtains a copy of this software +and any associated documentation files ("the Software") to use and +deal with the Software in source code and binary forms without +restriction, with or without modification, and to permit persons +to whom the Software is furnished to do so, provided that the +following conditions are met: + +- Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimers. +- Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimers in + the documentation and/or other materials provided with the + distribution. +- The name of NICTA may not be used to endorse or promote products + derived from this Software without specific prior written permission. + +EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT +PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS" AND +NICTA MAKES NO REPRESENTATIONS, WARRANTIES OR CONDITIONS OF ANY +KIND, EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, ANY +REPRESENTATIONS, WARRANTIES OR CONDITIONS REGARDING THE CONTENTS +OR ACCURACY OF THE SOFTWARE, OR OF TITLE, MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, THE ABSENCE OF LATENT +OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR +NOT DISCOVERABLE. + +TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT WILL +NICTA BE LIABLE ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, +NEGLIGENCE) FOR ANY LOSS OR DAMAGE WHATSOEVER, INCLUDING (WITHOUT +LIMITATION) LOSS OF PRODUCTION OR OPERATION TIME, LOSS, DAMAGE OR +CORRUPTION OF DATA OR RECORDS; OR LOSS OF ANTICIPATED SAVINGS, +OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR OTHER ECONOMIC LOSS; +OR ANY SPECIAL, INCIDENTAL, INDIRECT, CONSEQUENTIAL, PUNITIVE OR +EXEMPLARY DAMAGES ARISING OUT OF OR IN CONNECTION WITH THIS LICENCE, +THE SOFTWARE OR THE USE OF THE SOFTWARE, EVEN IF NICTA HAS BEEN +ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +If applicable legislation implies warranties or conditions, or +imposes obligations or liability on NICTA in respect of the Software +that cannot be wholly or partly excluded, restricted or modified, +NICTA's liability is limited, to the full extent permitted by the +applicable legislation, at its option, to: + +a. in the case of goods, any one or more of the following: + i. the replacement of the goods or the supply of equivalent goods; + ii. the repair of the goods; + iii. the payment of the cost of replacing the goods or of acquiring + equivalent goods; + iv. the payment of the cost of having the goods repaired; or +b. in the case of services: + i. the supplying of the services again; or + ii. the payment of the cost of having the services supplied + again. diff --git a/options/locale/locale_bg-BG.ini b/options/locale/locale_bg-BG.ini index c6faee5cf6054..532bb4626f71d 100644 --- a/options/locale/locale_bg-BG.ini +++ b/options/locale/locale_bg-BG.ini @@ -129,7 +129,6 @@ log_root_path_helper=Директория, в която да се съхран optional_title=Опционални настройки email_title=Имейл настройки -smtp_host=SMTP сървър smtp_from=Изпрати имейл като smtp_from_helper=E-mail адрес, който да се използва от Gitea. Въведете само E-mail адреса или име и E-mail във формат "Name ". mailer_user=SMTP потребител @@ -1151,9 +1150,7 @@ config.queue_length=Дължина на опашка config.deliver_timeout=Време за отказ при изпращане config.mailer_enabled=Активен -config.mailer_disable_helo=Изключи HELO config.mailer_name=Име -config.mailer_host=Сървър config.mailer_user=Потребител config.oauth_config=OAuth конфигурация diff --git a/options/locale/locale_cs-CZ.ini b/options/locale/locale_cs-CZ.ini index 4cdc4d9874495..389a259628b84 100644 --- a/options/locale/locale_cs-CZ.ini +++ b/options/locale/locale_cs-CZ.ini @@ -176,7 +176,6 @@ log_root_path_helper=Soubory protokolu budou zapsány do tohoto adresáře. optional_title=Dodatečná nastavení email_title=Nastavení e-mailu -smtp_host=Server SMTP smtp_from=Odeslat e-mail jako smtp_from_helper=E-mailová adresa, kterou bude Gitea používat. Zadejte běžnou e-mailovou adresu, nebo použijte formát "Jméno". mailer_user=Uživatelské jméno SMTP @@ -1356,7 +1355,6 @@ issues.due_date_form_remove=Odstranit issues.due_date_not_writer=Potřebujete práva na zápis do repozitáře pro úpravy termínu dokončení úkolu. issues.due_date_not_set=Žádný termín dokončení. issues.due_date_added=přidal/a termín dokončení %s %s -issues.due_date_modified=upravil/a termín dokončení z %s na %s %s issues.due_date_remove=odstranil/a termín dokončení %s %s issues.due_date_overdue=Zpožděné issues.due_date_invalid=Termín dokončení není platný nebo je mimo rozsah. Použijte prosím formát „rrrr-mm-dd“. @@ -1461,7 +1459,6 @@ pulls.remove_prefix=Odstranit prefix %s pulls.data_broken=Tento požadavek na natažení je rozbitý kvůli chybějícím informacím o rozštěpení. pulls.files_conflicted=Tento požadavek na natažení obsahuje změny, které kolidují s cílovou větví. pulls.is_checking=Právě probíhá kontrola konfliktů při sloučení. Zkuste to za chvíli. -pulls.is_empty=Tato větev je stejná jako cílová větev. pulls.required_status_check_failed=Některé požadované kontroly nebyly úspěšné. pulls.required_status_check_missing=Některé požadované kontroly chybí. pulls.required_status_check_administrator=Jako administrátor stále můžete sloučit tento požadavek na natažení. @@ -1693,10 +1690,6 @@ settings.mirror_settings.push_mirror.remote_url=URL vzdáleného Git repozitář settings.mirror_settings.push_mirror.add=Přidat zrcadlo pro nahrání settings.sync_mirror=Synchronizovat nyní settings.mirror_sync_in_progress=Právě probíhá synchronizace zrcadla. Zkuste to za chvíli. -settings.email_notifications.enable=Povolit e-mailová oznámení -settings.email_notifications.onmention=E-mail pouze při zmínce -settings.email_notifications.disable=Zakázat e-mailová oznámení -settings.email_notifications.submit=Nastavit předvolby e-mailu settings.site=Webová stránka settings.update_settings=Aktualizovat nastavení settings.branches.update_default_branch=Aktualizovat výchozí větev @@ -2667,11 +2660,8 @@ config.queue_length=Délka fronty config.deliver_timeout=Časový limit doručení config.skip_tls_verify=Přeskočit verifikaci TLS -config.mailer_config=Konfigurace služby SMTP config.mailer_enabled=Zapnutý -config.mailer_disable_helo=Zakázat HELO config.mailer_name=Název -config.mailer_host=Server config.mailer_user=Uživatel config.mailer_use_sendmail=Použít Sendmail config.mailer_sendmail_path=Cesta k Sendmail diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini index 496c4e6d9899d..fa8b470a0f9d1 100644 --- a/options/locale/locale_de-DE.ini +++ b/options/locale/locale_de-DE.ini @@ -179,7 +179,6 @@ log_root_path_helper=Log-Dateien werden in diesem Verzeichnis gespeichert. optional_title=Optionale Einstellungen email_title=E-Mail-Einstellungen -smtp_host=SMTP-Server smtp_from=E-Mail senden als smtp_from_helper=E-Mail-Adresse, die von Gitea genutzt werden soll. Bitte gib die E-Mail-Adresse im Format „"Name" “ ein. mailer_user=SMTP-Benutzername @@ -799,6 +798,7 @@ email_notifications.enable=E-Mail Benachrichtigungen aktivieren email_notifications.onmention=Nur E-Mail bei Erwähnung email_notifications.disable=E-Mail Benachrichtigungen deaktivieren email_notifications.submit=E-Mail-Einstellungen festlegen +email_notifications.andyourown=Und deine Eigenen Benachrichtigungen visibility=Nutzer Sichtbarkeit visibility.public=Öffentlich @@ -930,6 +930,7 @@ form.name_pattern_not_allowed='%s' ist nicht erlaubt für Repository-Namen. need_auth=Authentifizierung migrate_options=Migrationsoptionen migrate_service=Migrationsdienst +migrate_options_mirror_helper=Dieses Repository wird ein Spiegel sein migrate_options_lfs=LFS-Dateien migrieren migrate_options_lfs_endpoint.label=LFS-Endpunkt migrate_options_lfs_endpoint.description=Migration wird versuchen, über den entfernten Git-Server den LFS-Server zu bestimmen. Du kannst auch einen eigenen Endpunkt angeben, wenn die LFS-Dateien woanders gespeichert werden. @@ -1300,6 +1301,7 @@ issues.previous=Vorherige issues.next=Nächste issues.open_title=Offen issues.closed_title=Geschlossen +issues.draft_title=Entwurf issues.num_comments=%d Kommentare issues.commented_at=`hat %s kommentiert` issues.delete_comment_confirm=Bist du sicher dass du diesen Kommentar löschen möchtest? @@ -1416,7 +1418,7 @@ issues.due_date_form_remove=Entfernen issues.due_date_not_writer=Du musst Schreibrechte in diesem Repository haben, um das Fälligkeitsdatum zu ändern. issues.due_date_not_set=Kein Fälligkeitsdatum gesetzt. issues.due_date_added=hat %[2]s das Fälligkeitsdatum %[1]s hinzugefügt -issues.due_date_modified=hat %[3]s das Fälligkeitsdatum von %[2]s zu %[1]s geändert +issues.due_date_modified=ändert das Abgabedatum von %[2]s auf %[1]s %[3]s s issues.due_date_remove=hat %[2]s das Fälligkeitsdatum %[1]s entfernt issues.due_date_overdue=Überfällig issues.due_date_invalid=Das Fälligkeitsdatum ist ungültig oder außerhalb des zulässigen Bereichs. Bitte verwende das Format „jjjj-mm-tt“. @@ -1528,7 +1530,7 @@ pulls.remove_prefix=%s Präfix entfernen pulls.data_broken=Dieser Pull-Requests ist kaputt, da Fork-Informationen gelöscht wurden. pulls.files_conflicted=Dieser Pull-Request hat Änderungen, die im Widerspruch zum Ziel-Branch stehen. pulls.is_checking=Die Konfliktprüfung läuft noch. Bitte aktualisiere die Seite in wenigen Augenblicken. -pulls.is_empty=Dieser Branch ist gleich mit dem Zielbranch. +pulls.is_ancestor=Dieser Branch ist bereits im Zielbranch enthalten. Es gibt nichts zu mergen. pulls.required_status_check_failed=Einige erforderliche Prüfungen waren nicht erfolgreich. pulls.required_status_check_missing=Einige erforderliche Prüfungen fehlen. pulls.required_status_check_administrator=Als Administrator kannst du diesen Pull-Request weiterhin zusammenführen. @@ -1607,6 +1609,8 @@ pulls.auto_merge_canceled_schedule=Der Automerge dieses Pull-Requests wurde abge pulls.auto_merge_newly_scheduled_comment=`hat einen Automerge für diesen Pull-Request %[1]s geplant` pulls.auto_merge_canceled_schedule_comment=`hat den Automerge für diesen Pull-Request %[1]s abgebrochen` +pulls.delete.title=Diesen Pull-Request löschen? +pulls.delete.text=Willst du diesen Pull-Request wirklich löschen? (Dies wird den Inhalt unwiderruflich löschen. Überlege, ob du ihn nicht lieber schließen willst, um ihn zu archivieren) milestones.new=Neuer Meilenstein milestones.closed=Geschlossen %s @@ -1777,10 +1781,6 @@ settings.mirror_settings.push_mirror.remote_url=URL zum Git-Remote-Repository settings.mirror_settings.push_mirror.add=Push-Mirror hinzufügen settings.sync_mirror=Jetzt synchronisieren settings.mirror_sync_in_progress=Mirror-Synchronisierung wird zurzeit ausgeführt. Komm in ein paar Minuten zurück. -settings.email_notifications.enable=E-Mail Benachrichtigungen aktivieren -settings.email_notifications.onmention=E-Mail-Benachrichtigungen nur bei Erwähnung -settings.email_notifications.disable=E-Mail Benachrichtigungen deaktivieren -settings.email_notifications.submit=E-Mail-Einstellungen festlegen settings.site=Webseite settings.update_settings=Einstellungen speichern settings.branches.update_default_branch=Standardbranch aktualisieren @@ -2789,11 +2789,8 @@ config.queue_length=Warteschlangenlänge config.deliver_timeout=Zeitlimit für Zustellung config.skip_tls_verify=TLS-Verifikation überspringen -config.mailer_config=SMTP-Mailer-Konfiguration config.mailer_enabled=Aktiviert -config.mailer_disable_helo=HELO deaktivieren config.mailer_name=Name -config.mailer_host=Host config.mailer_user=Benutzer config.mailer_use_sendmail=Sendmail benutzen config.mailer_sendmail_path=Sendmail-Pfad diff --git a/options/locale/locale_el-GR.ini b/options/locale/locale_el-GR.ini index 21b2d4a5b3c6c..94b8eb9a15a96 100644 --- a/options/locale/locale_el-GR.ini +++ b/options/locale/locale_el-GR.ini @@ -179,7 +179,6 @@ log_root_path_helper=Τα αρχεία καταγραφής θα γράφοντ optional_title=Προαιρετικές Ρυθμίσεις email_title=Ρυθμίσεις Email -smtp_host=Διακομιστής SMTP smtp_from=Αποστολή Email Ως smtp_from_helper=Η διεύθυνση email που θα χρησιμοποιεί το Gitea. Εισάγετε μια απλή διεύθυνση ηλεκτρονικού ταχυδρομείου ή χρησιμοποιήστε τη μορφή "Όνομα" . mailer_user=Όνομα Χρήστη SMTP @@ -861,7 +860,9 @@ default_branch=Προεπιλεγμένος Κλάδος default_branch_helper=Ο προεπιλεγμένος κλάδος είναι ο βασικός κλάδος για pull requests και υποβολές κώδικα. mirror_prune=Καθαρισμός mirror_prune_desc=Αφαίρεση παρωχημένων αναφορών απομακρυσμένης-παρακολούθησης +mirror_interval=Διάστημα ανανέωσης ειδώλου (έγκυρες μονάδες ώρας είναι 'h', 'm', 's'). 0 για απενεργοποίηση του αυτόματου συγχρονισμού. (Ελάχιστο διάστημα: %s) mirror_interval_invalid=Το χρονικό διάστημα του ειδώλου δεν είναι έγκυρο. +mirror_sync_on_commit=Συγχρονισμός κατά την ώθηση mirror_address=Κλωνοποίηση Από Το URL mirror_address_desc=Τοποθετήστε όλα τα απαιτούμενα διαπιστευτήρια στην ενότητα Εξουσιοδότηση. mirror_address_url_invalid=Η διεύθυνση url που δώσατε δεν είναι έγκυρη. Πρέπει να μεταφράσετε όλα τα στοιχεία του url σωστά. @@ -930,6 +931,7 @@ form.name_pattern_not_allowed=Το μοτίβο '%s' δεν επιτρέπετα need_auth=Εξουσιοδότηση migrate_options=Επιλογές Μεταφοράς migrate_service=Υπηρεσία Μεταφοράς +migrate_options_mirror_helper=Αυτό το αποθετήριο θα είναι είδωλο migrate_options_lfs=Μεταφορά αρχείων LFS migrate_options_lfs_endpoint.label=LFS Endpoint migrate_options_lfs_endpoint.description=Η μεταφορά θα προσπαθήσει να χρησιμοποιήσει το Git remote για να καθορίσει τον διακομιστή LFS. Μπορείτε επίσης να καθορίσετε ένα δικό σας endpoint αν τα δεδομένα LFS του αποθετηρίου αποθηκεύονται κάπου αλλού. @@ -1174,7 +1176,7 @@ projects.type.basic_kanban=Βασικό Kanban projects.type.bug_triage=Διαλογή Σφαλμάτων projects.template.desc=Πρότυπο έργου projects.template.desc_helper=Επιλέξτε ένα πρότυπο έργου για να ξεκινήσετε -projects.type.uncategorized=Αταξινόμητο +projects.type.uncategorized=Χωρίς Κατηγορία projects.board.edit=Επεξεργασία πίνακα projects.board.edit_title=Νέο Όνομα Πίνακα projects.board.new_title=Νέο Όνομα Πίνακα @@ -1183,7 +1185,7 @@ projects.board.new=Νέος Πίνακας projects.board.set_default=Ορισμός Προεπιλογής projects.board.set_default_desc=Ορίστε αυτόν τον πίνακα ως προεπιλογή για μη κατηγοριοποιημένα ζητήματα και pull requests projects.board.delete=Διαγραφή Πίνακα -projects.board.deletion_desc=Η διαγραφή ενός πίνακα έργου μετακινεί όλα τα σχετιζόμενα ζητήματα σε 'Αταξινόμητα'. Συνέχεια; +projects.board.deletion_desc=Η διαγραφή ενός πίνακα έργου μετακινεί όλα τα σχετιζόμενα ζητήματα σε 'Χωρίς Κατηγορία'. Συνέχεια; projects.board.color=Χρώμα projects.open=Άνοιγμα projects.close=Κλείσιμο @@ -1300,6 +1302,7 @@ issues.previous=Προηγούμενο issues.next=Επόμενο issues.open_title=Ανοιχτό issues.closed_title=Κλειστό +issues.draft_title=Προσχέδιο issues.num_comments=%d σχόλια issues.commented_at=`σχολίασε %s` issues.delete_comment_confirm=Θέλετε σίγουρα να διαγράψετε αυτό το σχόλιο; @@ -1416,7 +1419,7 @@ issues.due_date_form_remove=Διαγραφή issues.due_date_not_writer=Χρειάζεστε πρόσβαση εγγραφής στο αποθετήριο για να ενημερώσετε την ημερομηνία λήξης ενός ζητήματος. issues.due_date_not_set=Δεν ορίστηκε ημερομηνία παράδοσης. issues.due_date_added=πρόσθεσε την ημερομηνία παράδοσης %s %s -issues.due_date_modified=τροποποίησε την ημερομηνία παράδοσης σε %s από %s %s +issues.due_date_modified=τροποποίησε την ημερομηνία παράδοσης από %[2]s σε %[1]s %[3]s issues.due_date_remove=αφαίρεσε την ημερομηνία παράδοσης %s %s issues.due_date_overdue=Εκπρόθεσμο issues.due_date_invalid=Η ημερομηνία παράδοσης δεν είναι έγκυρη ή εκτός εύρους. Παρακαλούμε χρησιμοποιήστε τη μορφή 'εεεε-μμ-ηη'. @@ -1528,7 +1531,8 @@ pulls.remove_prefix=Αφαίρεση %s προθέματος pulls.data_broken=Αυτό το pull request είναι κατεστραμμένο λόγω των πληροφοριών του fork που λείπουν. pulls.files_conflicted=Αυτό το pull request περιέχει αλλαγές που συγκρούονται με το κλάδο προορισμού. pulls.is_checking=Ο έλεγχος συγκρούσεων κατά την συγχώνευση είναι σε εξέλιξη. Δοκιμάστε ξανά σε λίγα λεπτά. -pulls.is_empty=Αυτός ο κλάδος είναι ίσος με τον κλάδο-στόχο. +pulls.is_ancestor=Αυτός ο κλάδος περιλαμβάνεται ήδη στον κλάδο προορισμού. Δεν υπάρχει τίποτα για συγχώνευση. +pulls.is_empty=Οι αλλαγές σε αυτόν τον κλάδο είναι ήδη στον κλάδο προορισμού. Θα είναι μια κενή υποβολή. pulls.required_status_check_failed=Ορισμένοι απαιτούμενοι έλεγχοι δεν ήταν επιτυχείς. pulls.required_status_check_missing=Λείπουν ορισμένοι απαιτούμενοι έλεγχοι. pulls.required_status_check_administrator=Ως διαχειριστής, μπορείτε ακόμα να συγχωνεύσετε αυτό το pull request. @@ -1779,10 +1783,6 @@ settings.mirror_settings.push_mirror.remote_url=URL Απομακρυσμένου settings.mirror_settings.push_mirror.add=Προσθήκη Είδωλου Push settings.sync_mirror=Συγχρονισμός Τώρα settings.mirror_sync_in_progress=Ο συγχρονισμός ειδώλου είναι σε εξέλιξη. Ελέγξτε ξανά σε λίγο. -settings.email_notifications.enable=Ενεργοποίηση Ειδοποιήσεων Email -settings.email_notifications.onmention=Email Μόνο σε Αναφορά -settings.email_notifications.disable=Απενεργοποίηση Ειδοποιήσεων Email -settings.email_notifications.submit=Ορισμός Προτίμησης Email settings.site=Ιστοσελίδα settings.update_settings=Ενημέρωση Ρυθμίσεων settings.branches.update_default_branch=Ενημέρωση Προεπιλεγμένου Κλάδου @@ -2535,6 +2535,8 @@ users.delete_account=Διαγραφή Λογαριασμού Χρήστη users.cannot_delete_self=Δεν μπορείτε να διαγράψετε τον εαυτό σας users.still_own_repo=Αυτός ο χρήστης εξακολουθεί να κατέχει ένα ή περισσότερα αποθετήρια. Διαγράψτε ή μεταφέρετε αυτά τα αποθετήρια πρώτα. users.still_has_org=Αυτός ο χρήστης είναι μέλος ενός οργανισμού. Αφαιρέστε πρώτα τον χρήστη από οποιονδήποτε οργανισμό. +users.purge=Εκκαθάριση Χρήστη +users.purge_help=Αναγκαστική διαγραφή χρήστη και των αποθετηρίων, οργανισμών και πακέτων που του ανήκουν. Όλα τα σχόλια επίσης θα διαγραφούν. users.still_own_packages=Αυτός ο χρήστης εξακολουθεί να κατέχει ένα ή περισσότερα πακέτα. Διαγράψτε πρώτα αυτά τα πακέτα. users.deletion_success=Ο λογαριασμός χρήστη έχει διαγραφεί. users.reset_2fa=Επαναφορά 2FA @@ -2791,11 +2793,8 @@ config.queue_length=Μέγεθος Ουράς config.deliver_timeout=Χρονικό Όριο Παράδοσης config.skip_tls_verify=Παράλειψη Επαλήθευσης TLS -config.mailer_config=Ρυθμίσεις SMTP Mailer config.mailer_enabled=Ενεργοποιημένο -config.mailer_disable_helo=Απενεργοποίηση HELO config.mailer_name=Όνομα -config.mailer_host=Διακομιστής config.mailer_user=Χρήστης config.mailer_use_sendmail=Χρήση Sendmail config.mailer_sendmail_path=Διαδρομή Sendmail diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 9e8a0303393b6..783783617b6aa 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -179,7 +179,8 @@ log_root_path_helper = Log files will be written to this directory. optional_title = Optional Settings email_title = Email Settings -smtp_host = SMTP Host +smtp_addr = SMTP Host +smtp_port = SMTP Port smtp_from = Send Email As smtp_from_helper = Email address Gitea will use. Enter a plain email address or use the "Name" format. mailer_user = SMTP Username @@ -799,6 +800,7 @@ email_notifications.enable = Enable Email Notifications email_notifications.onmention = Only Email on Mention email_notifications.disable = Disable Email Notifications email_notifications.submit = Set Email Preference +email_notifications.andyourown = And Your Own Notifications visibility = User visibility visibility.public = Public @@ -1061,6 +1063,7 @@ normal_view = Normal View line = line lines = lines +editor.add_file = Add File editor.new_file = New File editor.upload_file = Upload File editor.edit_file = Edit File @@ -1420,7 +1423,7 @@ issues.due_date_form_remove = "Remove" issues.due_date_not_writer = "You need repository write access to update an issue's due date." issues.due_date_not_set = "No due date set." issues.due_date_added = "added the due date %s %s" -issues.due_date_modified = "modified the due date to %s from %s %s" +issues.due_date_modified = "modified the due date from %[2]s to %[1]s %[3]s" issues.due_date_remove = "removed the due date %s %s" issues.due_date_overdue = "Overdue" issues.due_date_invalid = "The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'." @@ -1784,10 +1787,6 @@ settings.mirror_settings.push_mirror.remote_url = Git Remote Repository URL settings.mirror_settings.push_mirror.add = Add Push Mirror settings.sync_mirror = Synchronize Now settings.mirror_sync_in_progress = Mirror synchronization is in progress. Check back in a minute. -settings.email_notifications.enable = Enable Email Notifications -settings.email_notifications.onmention = Only Email on Mention -settings.email_notifications.disable = Disable Email Notifications -settings.email_notifications.submit = Set Email Preference settings.site = Website settings.update_settings = Update Settings settings.branches.update_default_branch = Update Default Branch @@ -2540,6 +2539,8 @@ users.delete_account = Delete User Account users.cannot_delete_self = "You cannot delete yourself" users.still_own_repo = This user still owns one or more repositories. Delete or transfer these repositories first. users.still_has_org = This user is a member of an organization. Remove the user from any organizations first. +users.purge = Purge User +users.purge_help = Forcibly delete user and any repositories, organizations, and packages owned by the user. All comments will be deleted too. users.still_own_packages = This user still owns one or more packages. Delete these packages first. users.deletion_success = The user account has been deleted. users.reset_2fa = Reset 2FA @@ -2796,16 +2797,19 @@ config.queue_length = Queue Length config.deliver_timeout = Deliver Timeout config.skip_tls_verify = Skip TLS Verification -config.mailer_config = SMTP Mailer Configuration +config.mailer_config = Mailer Configuration config.mailer_enabled = Enabled -config.mailer_disable_helo = Disable HELO +config.mailer_enable_helo = Enable HELO config.mailer_name = Name -config.mailer_host = Host +config.mailer_protocol = Protocol +config.mailer_smtp_addr = SMTP Addr +config.mailer_smtp_port = SMTP Port config.mailer_user = User config.mailer_use_sendmail = Use Sendmail config.mailer_sendmail_path = Sendmail Path config.mailer_sendmail_args = Extra Arguments to Sendmail config.mailer_sendmail_timeout = Sendmail Timeout +config.mailer_use_dummy = Dummy config.test_email_placeholder = Email (e.g. test@example.com) config.send_test_mail = Send Testing Email config.test_mail_failed = Failed to send a testing email to '%s': %v @@ -3042,6 +3046,7 @@ title = Packages desc = Manage repository packages. empty = There are no packages yet. empty.documentation = For more information on the package registry, see the documentation. +empty.repo = Did you upload a package, but it's not shown here? Go to package settings and link it to this repo. filter.type = Type filter.type.all = All filter.no_result = Your filter produced no results. @@ -3107,6 +3112,10 @@ npm.dependencies.development = Development Dependencies npm.dependencies.peer = Peer Dependencies npm.dependencies.optional = Optional Dependencies npm.details.tag = Tag +pub.install = To install the package using Dart, run the following command: +pub.documentation = For more information on the Pub registry, see the documentation. +pub.details.repository_site = Repository Site +pub.details.documentation_site = Documentation Site pypi.requires = Requires Python pypi.install = To install the package using pip, run the following command: pypi.documentation = For more information on the PyPI registry, see the documentation. diff --git a/options/locale/locale_es-ES.ini b/options/locale/locale_es-ES.ini index 724d354670443..15222272b3341 100644 --- a/options/locale/locale_es-ES.ini +++ b/options/locale/locale_es-ES.ini @@ -179,7 +179,6 @@ log_root_path_helper=Archivos de registro se escribirán en este directorio. optional_title=Configuración opcional email_title=Configuración de Correo -smtp_host=Servidor SMTP smtp_from=Enviar correos electrónicos como smtp_from_helper=Dirección de correo electrónico que utilizará Gitea. Introduzca una dirección de correo electrónico normal o utilice el formato "Nombre" . mailer_user=Nombre de usuario SMTP @@ -799,6 +798,7 @@ email_notifications.enable=Habilitar notificaciones por correo electrónico email_notifications.onmention=Enviar correo sólo al ser mencionado email_notifications.disable=Deshabilitar las notificaciones por correo electrónico email_notifications.submit=Establecer preferencias de correo electrónico +email_notifications.andyourown=Y sus propias notificaciones visibility=Visibilidad del usuario visibility.public=Público @@ -932,6 +932,7 @@ form.name_pattern_not_allowed=El patrón '%s' no está permitido en un nombre de need_auth=Autorización migrate_options=Opciones de migración migrate_service=Servicio de Migración +migrate_options_mirror_helper=Este repositorio será una réplica migrate_options_lfs=Migrar archivos LFS migrate_options_lfs_endpoint.label=Punto final de LFS migrate_options_lfs_endpoint.description=Migración intentará usar su mando Git para determinar el servidor LFS. También puede especificar un punto final personalizado si los datos LFS del repositorio se almacenan en otro lugar. @@ -1302,6 +1303,7 @@ issues.previous=Página Anterior issues.next=Página Siguiente issues.open_title=Abierta issues.closed_title=Cerrada +issues.draft_title=Borrador issues.num_comments=%d comentarios issues.commented_at=`comentado %s` issues.delete_comment_confirm=¿Seguro que deseas eliminar este comentario? @@ -1418,7 +1420,7 @@ issues.due_date_form_remove=Eliminar issues.due_date_not_writer=Necesita acceso de escritura al repositorio para actualizar la fecha de vencimiento de un issue. issues.due_date_not_set=Sin fecha de vencimiento. issues.due_date_added=añadió la fecha de vencimiento %s %s -issues.due_date_modified=modificó la fecha de vencimiento a %s de %s %s +issues.due_date_modified=modificó la fecha de vencimiento de %[2]s a %[1]s %[3]s issues.due_date_remove=eliminó la fecha de vencimiento %s %s issues.due_date_overdue=Vencido issues.due_date_invalid=La fecha de vencimiento es inválida o está fuera de rango. Por favor utilice el formato 'aaaa-mm-dd'. @@ -1530,7 +1532,8 @@ pulls.remove_prefix=Eliminar prefijo %s pulls.data_broken=Este pull request está rota debido a que falta información del fork. pulls.files_conflicted=Este pull request tiene cambios en conflicto con la rama de destino. pulls.is_checking=La comprobación de conflicto de fusión está en progreso. Inténtalo de nuevo en unos momentos. -pulls.is_empty=Esta rama es igual a la rama objetivo. +pulls.is_ancestor=Esta rama ya está incluida en la rama de destino. No hay nada que fusionar. +pulls.is_empty=Los cambios en esta rama ya están en la rama de destino. Esto será un commit vacío. pulls.required_status_check_failed=Algunos controles requeridos no han tenido éxito. pulls.required_status_check_missing=Faltan algunos controles necesarios. pulls.required_status_check_administrator=Como administrador, aún puede fusionar este Pull Request. @@ -1781,10 +1784,6 @@ settings.mirror_settings.push_mirror.remote_url=URL del repositorio remoto de Gi settings.mirror_settings.push_mirror.add=Añadir Réplica de Push settings.sync_mirror=Sincronizar ahora settings.mirror_sync_in_progress=La sincronización del repositorio replicado está en curso. Vuelva a intentarlo más tarde. -settings.email_notifications.enable=Habilitar las notificaciones por correo electrónico -settings.email_notifications.onmention=Enviar correo sólo al mencionar -settings.email_notifications.disable=Deshabilitar las notificaciones por correo electrónico -settings.email_notifications.submit=Establecer Preferencia de correo electrónico settings.site=Sitio web settings.update_settings=Actualizar configuración settings.branches.update_default_branch=Actualizar rama por defecto @@ -2537,6 +2536,8 @@ users.delete_account=Eliminar Cuenta de Usuario users.cannot_delete_self=No puedes eliminarte a ti mismo users.still_own_repo=Este usuario todavía posee uno o más depósitos. Eliminar o transferir estos repositorios primero. users.still_has_org=Este usuario es un miembro de una organización. Primero retire el usuario de cualquier organización. +users.purge=Borrar usuario +users.purge_help=Borrar forzosamente el usuario y cualquier repositorio, organización y paquete propiedad del usuario. Todos los comentarios también serán borrados. users.still_own_packages=Este usuario todavía posee uno o más paquetes. Elimine estos paquetes primero. users.deletion_success=La cuenta de usuario ha sido eliminada. users.reset_2fa=Reiniciar 2FA @@ -2793,11 +2794,8 @@ config.queue_length=Tamaño de Cola de Envío config.deliver_timeout=Timeout de Entrega config.skip_tls_verify=Saltar verificación TLS -config.mailer_config=Configuración del servidor de correo config.mailer_enabled=Activado -config.mailer_disable_helo=Desactivar HELO config.mailer_name=Nombre -config.mailer_host=Servidor config.mailer_user=Usuario config.mailer_use_sendmail=Usar Sendmail config.mailer_sendmail_path=Ruta de Sendmail @@ -3039,6 +3037,7 @@ title=Paquetes desc=Administrar paquetes del repositorio. empty=Todavía no hay paquetes. empty.documentation=Para más información sobre el registro de paquetes, consulte la documentación. +empty.repo=¿Has subido un paquete, pero no se muestra aquí? Ve a la configuración del paquete y añade el link a este repositorio. filter.type=Tipo filter.type.all=Todo filter.no_result=El filtro no produjo ningún resultado. diff --git a/options/locale/locale_fa-IR.ini b/options/locale/locale_fa-IR.ini index c7488cf0e91a9..5595de24c34e6 100644 --- a/options/locale/locale_fa-IR.ini +++ b/options/locale/locale_fa-IR.ini @@ -158,7 +158,6 @@ log_root_path_helper=فایل‌های گزارش روی این مسیر ذخی optional_title=تنظیمات اختیاری email_title=تنظیمات ایمیل -smtp_host=میزبان SMTP smtp_from=ارسال ایمیل به عنوان smtp_from_helper=آدرس ایمیلی که گیتی استفاده میکند. یک ایمیل وارد کنید یا به "Name" شکل استفاده کنید. mailer_user=نام کاربری SMTP @@ -1309,7 +1308,6 @@ issues.due_date_form_remove=حذف/ساقط کردن issues.due_date_not_writer=شما نیازمند دسترسی نوشتن به این مخزن را برای تغییر موعد مقرر این مسئله را دارید. issues.due_date_not_set=هیچ موعد مقرری ثبت نشده. issues.due_date_added=موعد مقرر اضافه شد %s %s -issues.due_date_modified=موعد مقرر از %s به %s %s تغییر کرد. issues.due_date_remove=موعد مقرر %s %s حذف شد issues.due_date_overdue=تاریخ گذشته issues.due_date_invalid=موعد مقرر نامعتبر است یا خارج از محدوده. لطفاً از قالب 'yyy-mm-dd' استفاده کنید. @@ -1410,7 +1408,6 @@ pulls.remove_prefix=حذف پیشوند %s pulls.data_broken=این تقاضای واکشی به دلیل از دست رفتن اطلاعات انشعاب با شکست مواجه شد. pulls.files_conflicted=این تقاضای واکشی دارای تغییراتی است که با شاخه هدف تداخل دارد. pulls.is_checking=در حال پردازش تداخل در ادغام می‌باشد. لطفاً لحظاتی بعد امتحان کنید. -pulls.is_empty=این شاخه با شاخه مقصد برابر است. pulls.required_status_check_failed=برخی بررسی های ضروری موفقیت آمیز نبود. pulls.required_status_check_missing=برخی بررسی های موردنیاز از قلم افتاده است. pulls.required_status_check_administrator=مثل یک مدیر، ممکن است شما این تقاضای واکشی را مسکوت بگذارید. @@ -1644,10 +1641,6 @@ settings.mirror_settings.push_mirror.remote_url=Git Remote Repository URL settings.mirror_settings.push_mirror.add=اضافه کردن Push Mirror settings.sync_mirror=همگام سازی کن settings.mirror_sync_in_progress=همگام سازی قرینه در حالت پردازش است. یک دقیقه دیگر مجددا بررسی کنید. -settings.email_notifications.enable=فعال‌سازی اعلان‌های ایمیل -settings.email_notifications.onmention=تنها یادوآری از طریق ایمیل -settings.email_notifications.disable=غیرفعال‌ کردن اعلان‌های ایمیل -settings.email_notifications.submit=ثبت اولویت ایمیل settings.site=تارنما settings.update_settings=به‌ روزرسانی تنظیمات settings.branches.update_default_branch=بروزرسانی شاخه پیش فرض @@ -2582,11 +2575,8 @@ config.queue_length=طول صف config.deliver_timeout=مهلت تحویل config.skip_tls_verify=صرف نظر از اعتبارسنجی TLS -config.mailer_config=پیکربندی سامانه ایمیلی SMTP config.mailer_enabled=فعال شده -config.mailer_disable_helo=غیر فعال کردن HELO config.mailer_name=نام -config.mailer_host=میزبان config.mailer_user=کاربر config.mailer_use_sendmail=استفاده از ارسال رایانامه (ایمیل) مستقیم config.mailer_sendmail_path=مسیر ارسال ایمیل مستقیم diff --git a/options/locale/locale_fi-FI.ini b/options/locale/locale_fi-FI.ini index 2699598ed9b2c..4f47d8afa64a6 100644 --- a/options/locale/locale_fi-FI.ini +++ b/options/locale/locale_fi-FI.ini @@ -2,6 +2,7 @@ home=Etusivu dashboard=Kojelauta explore=Tutki help=Apua +logo=Logo sign_in=Kirjaudu sisään sign_in_with=Kirjaudu sisään tunnuksilla sign_out=Kirjaudu ulos @@ -21,16 +22,28 @@ signed_in_as=Kirjautuneena käyttäjänä enable_javascript=Tämä sivusto toimii paremmin JavaScriptillä. toc=Sisällysluettelo licenses=Lisenssit +return_to_gitea=Palaa Giteaan username=Käyttäjätunnus email=Sähköpostiosoite password=Salasana +access_token=Pääsymerkki re_type=Kirjoita salasana uudelleen captcha=CAPTCHA twofa=Kaksivaiheinen todennus twofa_scratch=Kaksivaiheinen kertakäyttöinen koodi passcode=Tunnuskoodi +webauthn_insert_key=Aseta turva-avaimesi +webauthn_press_button=Paina turva-avaimesi painiketta… +webauthn_error=Turva-avainta ei voitu lukea. +webauthn_unsupported_browser=Selaimesi ei tällä hetkellä tue WebAuthnia. +webauthn_error_insecure=WebAuthn tukee vain suojattuja yhteyksiä. Testaukseen HTTP:n yli, voit käyttää osoitetta "localhost" tai "127.0.0.1" +webauthn_error_unable_to_process=Palvelin ei pystynyt toteuttamaan kutsua. +webauthn_error_duplicated=Turva-avainta ei ole sallittu tässä pyynnössä. Varmista, ettei avainta ole jo rekisteröity. +webauthn_error_empty=Sinun täytyy asettaa nimi tälle avaimelle. +webauthn_error_timeout=Aikakatkaisu saavutettu ennenkuin avaintasi on voitu lukea. Lataa tämä sivu uudelleen ja yritä uudelleen. +webauthn_reload=Päivitä repository=Repo organization=Organisaatio @@ -40,6 +53,7 @@ new_migrate=Uusi migraatio new_mirror=Uusi peilaus new_fork=Uusi repositorio new_org=Uusi organisaatio +new_project=Uusi projekti manage_org=Ylläpidä organisaatioita admin_panel=Sivuston ylläpito account_settings=Tilin asetukset @@ -59,28 +73,47 @@ pull_requests=Pull requestit issues=Ongelmat milestones=Merkkipaalut +ok=OK cancel=Peruuta save=Tallenna add=Lisää add_all=Lisää kaikki remove=Poista remove_all=Poista kaikki +edit=Muokkaa +copy=Kopioi +copy_url=Kopioi osoite +copy_branch=Kopioi haaran nimi +copy_success=Kopioitu! +copy_error=Kopiointi epäonnistui write=Kirjoita preview=Esikatselu loading=Ladataan… +step1=Vaihe 1: +step2=Vaihe 2: +error=Virhe error404=Sivu, jota yrität nähdä, joko ei löydy tai et ole oikeutettu katsomaan sitä. +never=Ei koskaan +rss_feed=RSS-syöte [error] +occurred=Virhe tapahtui +report_message=Jos olet varma, että tämä on ongelma Giteassa, etsi ongelmaa GitHubista tai avaa uusi ongelma tarvittaessa. +missing_csrf=Virheellinen pyyntö: CSRF-tunnusta ei ole olemassa +invalid_csrf=Virheellinen pyyntö: Virheellinen CSRF-tunniste +not_found=Kohdetta ei löytynyt. +network_error=Verkkovirhe [startpage] app_desc=Kivuton, itsehostattu Git-palvelu install=Helppo asentaa +install_desc=Yksinkertaisesti aja binääri alustallasi, toimita se Dockerilla, tai saa se pakettina. platform=Alustariippumaton platform_desc=Gitea käy missä tahansa alustassa, johon Go kykenee kääntämään. Windows, macOS, Linux, ARM, jne. Valitse omasi! lightweight=Kevyt @@ -92,6 +125,7 @@ license_desc=Mene osoitteeseen ohjeet ennen minkään asetuksen muuttamista. +require_db_desc=Gitea tarvitsee toimiakseen MySQL, PostgreSQL, MSSQL, SQLite3 tai TiDB (MySQL protokolla) tietokannan. db_title=Tietokanta asetukset db_type=Tietokanta tyyppi host=Isäntä @@ -99,10 +133,16 @@ user=Käyttäjätunnus password=Salasana db_name=Tietokannan nimi db_helper=Huomautus MySQL-käyttäjille: käytä InnoDB-tallennusmoottoria, ja jos käytät "utf8mb4" merkistöä, InnoDB-version on oltava yli 5.6. +db_schema=Skeema ssl_mode=SSL charset=Merkistö path=Polku sqlite_helper=SQLite3-tietokannan tiedostopolku.
Syötä absoluuttinen polku, jos ajat Giteaa palveluna. +reinstall_error=Yrität asentaa olemassa olevaan Gitea tietokantaan +reinstall_confirm_message=Asentaminen uudelleen olemassa olevalla Gitea-tietokannalla voi aiheuttaa useita ongelmia. Useimmissa tapauksissa sinun pitäisi käyttää olemassa olevia "app.ini" asetuksia Gitean käyttöön. Jos tiedät mitä teet, vahvista seuraavat seikat: +reinstall_confirm_check_1=Tiedot, jotka on salattu SECRET_KEY:llä app.ini:ssä saatetaan menettää: käyttäjät eivät ehkä voi kirjautua sisään 2FA/OTP:lla ja peilit eivät välttämättä toimi oikein. Ruksaamalla tämän vahvistat, että nykyinen app.ini -tiedosto sisältää oikean SECRET_KEY:n. +reinstall_confirm_check_2=Repot ja asetukset saattaa olla tarpeen uudelleensynkronoida. Valitsemalla tämän vahvistat, että uudelleensynkronoit repojen koukut ja authorized_keys -tiedoston manuaalisesti. Varmistat, että repon ja peilin asetukset ovat oikeat. +reinstall_confirm_check_3=Vahvistat, että olet täysin varma siitä, että tämä Gitea toimii oikealla app.ini sijainnilla ja että olet varma, että sinun täytyy asentaa uudelleen. Vahvistat, että tunnustat edellä mainitut riskit. err_empty_db_path=SQLite3-tietokannan polku ei voi olla tyhjä. no_admin_and_disable_registration=Et voi kytkeä rekisteröintiä pois luomatta sitä ennen ylläpitotiliä. err_empty_admin_password=Ylläpitäjän salasana ei voi olla tyhjä. @@ -119,6 +159,7 @@ lfs_path=Git LFS -juuripolku lfs_path_helper=Git LFS:n ylläpitämät tiedostot tullaan tallentamaan tähän hakemistoon. Jätä tyhjäksi kytkeäksesi toiminnon pois. run_user=Aja käyttäjänä run_user_helper=Anna käyttäjätunnus, jona Giteaa ajetaan. Käyttäjällä on oltava oikeudet repositorioiden juuripolkuun. +domain=Palvelimen verkkotunnus ssh_port=SSH-palvelimen portti ssh_port_helper=Porttinumero, jossa SSH-palvelimesi kuuntelee. Jätä tyhjäksi kytkeäksesi pois. http_port=Gitean HTTP-kuunteluportti @@ -130,7 +171,6 @@ log_root_path_helper=Lokitiedostot kirjoitetaan tähän kansioon. optional_title=Valinnaiset asetukset email_title=Sähköpostiasetukset -smtp_host=SMTP isäntä smtp_from=Lähetä sähköpostit osoitteella smtp_from_helper=Sähköpostiosoite, jota Gitea käyttää. Kirjoita osoite ”nimi” -muodossa. mailer_user=SMTP-käyttäjätunnus @@ -151,6 +191,7 @@ openid_signin=Ota OpenID kirjautuminen käyttöön openid_signin_popup=Ota käyttöön kirjautuminen OpenID:n kautta. openid_signup=Ota käyttöön OpenID itse-rekisteröinti openid_signup_popup=Ota käyttöön OpenID-pohjainen käyttäjän itse-rekisteröinti. +enable_captcha=Ota käyttöön CAPTCHA rekisteröityessä enable_captcha_popup=Pakollinen captcha käyttäjän itse rekisteröityessä. require_sign_in_view=Vaadi sisäänkirjautuminen sivujen näkemiseksi require_sign_in_view_popup=Rajoita pääsy vain kirjautuneille käyttäjille. Vierailijat näkevät vain 'kirjaudu sisään' ja rekisteröidy -sivut. @@ -165,22 +206,41 @@ test_git_failed=Epäonnistui testata 'git' komentoa: %v sqlite3_not_available=Tämä Gitea versio ei tue SQLite3. Lataa virallinen binääriversio kohteesta %s (ei 'gobuild' versio). invalid_db_setting=Tietokanta-asetukset ovat väärin: %v invalid_repo_path=Repojen juuri polku on virheellinen: %v +invalid_app_data_path=Sovelluksen datapolku on virheellinen: %v +internal_token_failed=Sisäisen pääsymerkin luonti epäonnistui: %v save_config_failed=Asetusten tallentaminen epäonnistui: %v install_success=Tervetuloa! Kiitos kun valitsit Gitean. Pidä hauskaa! +default_keep_email_private=Piilota sähköpostiosoitteet oletuksena +default_enable_timetracking=Ota ajan seuranta oletusarvoisesti käyttöön +default_enable_timetracking_popup=Ota käyttöön uusien repojen aikaseuranta oletusarvoisesti. +no_reply_address=Piilotettu sähköpostin verkkotunnus +no_reply_address_helper=Verkkotunnuksen nimi käyttäjille, joilla on piilotettu sähköpostiosoite. Esimerkiksi käyttäjätunnus 'joe' kirjataan Git nimellä 'joe@noreply.example.org' jos piilotettu sähköpostiosoite on asetettu 'noreply.example.org'. +password_algorithm=Salasanan hajautusalgoritmi +password_algorithm_helper=Aseta salasanan hajautusalgoritmi. Algoritmeillä on eri vaatimukset ja vahvuudet. `argon2`, vaikka sillä on hyvät ominaisuudet, käyttää paljon muistia ja voi olla sopimaton pienille järjestelmille. [home] uname_holder=Käyttäjätunnus tai sähköpostiosoite password_holder=Salasana switch_dashboard_context=Vaihda kojelaudan kontekstia my_repos=Repot +show_more_repos=Näytä lisää repoja… collaborative_repos=Yhteistyö repot my_orgs=Organisaationi my_mirrors=Peilini view_home=Näytä %s search_repos=Etsi repo… +filter=Muut suodattimet +filter_by_team_repositories=Suodata tiimin repojen mukaan +feed_of=Syöte "%s" +show_archived=Arkistoidut +show_both_archived_unarchived=Näytetään arkistoidut ja arkistoimattomat +show_only_archived=Näytetään vain arkistoidut +show_only_unarchived=Näytetään vain arkistoimattomat show_private=Yksityinen +show_only_private=Näytetään vain yksityiset +show_only_public=Näytetään vain julkiset issues.in_your_repos=Repoissasi @@ -190,6 +250,7 @@ users=Käyttäjät organizations=Organisaatiot search=Hae code=Koodi +search.match=Osuma repo_no_results=Vastaavia repoja ei löydy. user_no_results=Vastaavia käyttäjiä ei löytynyt. org_no_results=Ei löytynyt vastaavia organisaatioita. @@ -203,6 +264,7 @@ register_helper_msg=On jo tili? Kirjaudu sisään nyt! social_register_helper_msg=Onko sinulla jo tili? Linkitä se nyt! disable_register_prompt=Rekisteröinti on estetty. Ota yhteys ylläpitäjääsi. disable_register_mail=Sähköpostivahvistus rekisteröinnille on estetty. +remember_me=Muista tämä laite forgot_password_title=Unohtuiko salasana forgot_password=Unohtuiko salasana? sign_up_now=Tarvitsetko tilin? Rekisteröidy nyt. @@ -210,6 +272,7 @@ sign_up_successful=Tilin luonti onnistui. confirmation_mail_sent_prompt=Uusi varmistussähköposti on lähetetty osoitteeseen %s, ole hyvä ja tarkista saapuneet seuraavan %s tunnin sisällä saadaksesi rekisteröintiprosessin valmiiksi. must_change_password=Vaihda salasanasi allow_password_change=Vaadi käyttäjää vaihtamaan salasanansa (suositeltava) +reset_password_mail_sent_prompt=Varmistussähköposti on lähetetty osoitteeseen %s. Tarkista saapuneet seuraavan %s tunnin sisällä saadaksesi tilin palauttamisen valmiiksi. active_your_account=Aktivoi tilisi account_activated=Tili on aktivoitu prohibit_login=Kirjautuminen estetty @@ -218,9 +281,11 @@ resent_limit_prompt=Olet jo tilannut aktivointisähköpostin hetki sitten. Ole h has_unconfirmed_mail=Hei %s, sinulla on varmistamaton sähköposti osoite (%s). Jos et ole saanut varmistus sähköpostia tai tarvitset uudelleenlähetyksen, ole hyvä ja klikkaa allaolevaa painiketta. resend_mail=Klikkaa tästä uudelleenlähettääksesi aktivointi sähköpostisi email_not_associate=Tätä sähköpostiosoitetta ei ole liitetty mihinkään tiliin. +send_reset_mail=Lähetä tilin palautussähköposti reset_password=Tilin palautus invalid_code=Vahvistusavain on virheellinen tai vanhentunut. reset_password_helper=Palauta käyttäjätili +reset_password_wrong_user=Olet kirjautunut sisään nimellä %s, mutta tilin palautuslinkki on tarkoitettu kohteelle %s password_too_short=Salasanan pituus ei voi olla vähemmän kuin %d merkkiä. non_local_account=Ei-lokaalit käyttäjät eivät voi päivittää salasanojaan Gitean web-käyttöliittymän kautta. verify=Vahvista @@ -232,10 +297,12 @@ twofa_scratch_token_incorrect=Kertakäyttökoodisi on virheellinen. login_userpass=Kirjaudu sisään login_openid=OpenID oauth_signup_tab=Rekisteröi uusi tili +oauth_signup_title=Viimeistele tili oauth_signup_submit=Viimeistele tili oauth_signin_tab=Linkitä olemassa olevaan tiliin oauth_signin_title=Kirjaudu sisään valtuuttaaksesi linkitetyn tilin oauth_signin_submit=Yhdistä tiliin +oauth.signin.error.access_denied=Valtuutuspyyntö on evätty. openid_connect_submit=Connect openid_connect_title=Yhdistä olemassaolevaan tiliin openid_connect_desc=Valittu OpenID-osoite on tuntematon. Liitä se uuteen tiliin täällä. @@ -251,22 +318,38 @@ authorize_title=Valtuutatko "%s" pääsemään tilillesi? authorization_failed=Käyttöoikeuden varmistus epäonnistui authorization_failed_desc=Käyttöoikeuden varmistus epäonnistui virheellisen pyynnön takia. Ota yhteyttä sovelluksen ylläpitäjään, jonka olet yrittänyt valtuuttaa. sspi_auth_failed=SSPI todennus epäonnistui +password_pwned=Valitsemasi salasana on varastettujen salasanojen luettelossa, joka on aiemmin paljastunut julkisissa tietorikkomuksissa. Yritä uudelleen toisella salasanalla. [mail] +view_it_on=Näytä %s +link_not_working_do_paste=Eikö toimi? Yritä kopioida ja liittää se selaimeesi. +hi_user_x=Hei %s, activate_account=Ole hyvä ja aktivoi tilisi activate_email=Vahvista sähköpostiosoitteesi +activate_email.title=%s, vahvista sähköpostiosoitteesi register_notify=Tervetuloa Giteaan +register_notify.text_2=Voit nyt kirjautua käyttäjätunnuksella: %s. reset_password=Palauta käyttäjätili +reset_password.title=%s, olet pyytänyt tilisi palauttamista register_success=Rekisteröinti onnistui +issue.x_mentioned_you=@%s mainitsi sinut: +issue.action.push_1=@%[1]s työnsi %[3]d commitin kohteeseen %[2]s +issue.action.push_n=@%[1]s työnsi %[3]d committia kohteeseen %[2]s +release.title=Otsikko: %s +release.note=Huomautus: +release.downloads=Lataukset: +release.download.zip=Lähdekoodi (ZIP) +release.download.targz=Lähdekoodi (TAR.GZ) +repo.transfer.to_you=sinä [modal] @@ -287,6 +370,7 @@ AuthName=Luvan nimi AdminEmail=Ylläpito sähköposti NewBranchName=Uuden haaran nimi +CommitSummary=Commitin yhteenveto CommitMessage=Commitin viesti CommitChoice=Commitin valinta TreeName=Tiedostopolku @@ -302,17 +386,24 @@ max_size_error=` täytyy sisältää enintään %s merkkiä.` email_error=` ei ole kelvollinen sähköpostiosoite.` include_error=` täytyy sisältää tekstiosa '%s'.` unknown_error=Tuntematon virhe: +captcha_incorrect=CAPTCHA koodi on virheellinen. password_not_match=Salasanat eivät täsmää. +lang_select_error=Valitse kieli listalta. username_been_taken=Käyttäjätunnus on jo varattu. +repo_name_been_taken=Repon nimi on jo käytössä. +repository_force_private=Pakotettu yksityisyys käytössä: yksityisiä repoja ei voida muuttaa julkisiksi. org_name_been_taken=Organisaation nimi on jo käytössä. team_name_been_taken=Tiimin nimi on jo varattu. email_been_used=Sähköpostiosoite on jo käytössä. +email_invalid=Sähköpostiosoite on virheellinen. +openid_been_used=OpenID-osoite '%s' on jo käytössä. username_password_incorrect=Käyttäjätunnus tai salasana on virheellinen. password_lowercase_one=Ainakin yksi pieni kirjan password_uppercase_one=Ainakin yksi iso kirjain password_digit_one=Ainakin yksi numero password_special_one=Ainakin yksi erikoismerkki (välimerkki, sulut, lainausmerkit, jne.) +enterred_invalid_org_name=Antamasi organisaation nimi on virheellinen. enterred_invalid_password=Syöttämäsi salasana oli väärä. user_not_exist=Käyttäjää ei ole olemassa. team_not_exist=Tiimiä ei ole olemassa. @@ -333,16 +424,20 @@ repositories=Repot activity=Julkinen toiminta followers=Seuraajat starred=Tähdelliset repot +projects=Projektit following=Seurataan follow=Seuraa unfollow=Lopeta seuraaminen +heatmap.loading=Ladataan lämpökarttaa… user_bio=Elämäkerta form.name_reserved=Käyttäjätunnus '%s' on varattu. +form.name_chars_not_allowed=Käyttäjänimi '%s' sisältää virheellisiä merkkejä. [settings] profile=Profiili account=Tili +appearance=Ulkoasu password=Salasana security=Turvallisuus avatar=Profiilikuva @@ -356,8 +451,10 @@ twofa=Kaksivaiheinen todennus account_link=Linkitetyt tilit organization=Organisaatiot uid=Käyttäjä ID +webauthn=Turva-avaimet public_profile=Julkinen profiili +biography_placeholder=Kerro itsestäsi profile_desc=Sähköpostiosoitettasi käytetään ilmoituksiin ja muihin toimintoihin. password_username_disabled=Ei-paikalliset käyttäjät eivät voi muuttaa käyttäjätunnustaan. Ole hyvä ja ota yhteyttä sivuston ylläpitäjään saadaksesi lisätietoa. full_name=Kokonimi @@ -365,6 +462,9 @@ website=Nettisivut location=Sijainti update_theme=Päivitä teema update_profile=Päivitä profiili +update_language=Päivitä kieli +update_language_not_found=Kieli '%s' ei ole käytettävissä. +update_language_success=Kieli on päivitetty. update_profile_success=Profiilisi on päivitetty. change_username=Käyttäjätunnuksesi on muutettu. change_username_prompt=Huomio: käyttäjätunnuksen muutos muuttaa myös tilisi URL:n. @@ -372,6 +472,23 @@ continue=Jatka cancel=Peruuta language=Kieli ui=Teema +hidden_comment_types=Piilotetut kommenttityypit +comment_type_group_reference=Viittaus +comment_type_group_label=Tunniste +comment_type_group_milestone=Merkkipaalu +comment_type_group_assignee=Osoitettu henkilölle +comment_type_group_title=Otsikko +comment_type_group_branch=Haara +comment_type_group_time_tracking=Ajan seuranta +comment_type_group_deadline=Määräaika +comment_type_group_dependency=Riippuvuus +comment_type_group_lock=Lukituksen tila +comment_type_group_review_request=Arviointipyyntö +comment_type_group_pull_request_push=Lisätyt commitit +comment_type_group_project=Projekti +saved_successfully=Asetuksesi tallennettiin onnistuneesti. +privacy=Yksityisyys +keep_activity_private=Piilota toiminta profiilisivulta lookup_avatar_by_mail=Hae profiilikuva sähköpostin perusteella federated_avatar_lookup=Ulkopuolinen profiilikuvan haku @@ -398,17 +515,23 @@ primary=Ensisijainen activated=Aktivoitu requires_activation=Vaatii aktivoinnin primary_email=Tee ensisijainen +activate_email=Lähetä aktivointi +activations_pending=Odottaa aktivointia delete_email=Poista email_deletion=Poista sähköpostiosoite email_deletion_desc=Sähköpostiosoite ja siihen liittyvät tiedot poistetaan tililtäsi. Kyseisen sähköpostiosoitteen sisältävät commitit pysyvät muuttumattomia. Jatketaanko? email_deletion_success=Sähköpostiosoite on poistettu. theme_update_success=Teemasi on päivitetty. theme_update_error=Valittua teemaa ei löydy. +openid_deletion=Poista OpenID-osoite +openid_deletion_success=OpenID-osoite on poistettu. add_new_email=Lisää uusi sähköpostiosoite add_new_openid=Lisää uusi OpenID URI add_email=Lisää sähköpostiosoite add_openid=Lisää OpenID URI add_email_success=Uusi sähköpostiosoite on lisätty. +email_preference_set_success=Sähköpostin asetukset on asetettu onnistuneesti. +add_openid_success=Uusi OpenID-osoite on lisätty. keep_email_private=Piilota sähköpostiosoite keep_email_private_popup=Sähköpostiosoitteesi on piilotettu muilta käyttäjiltä. openid_desc=OpenID mahdollistaa todentamisen delegoinnin ulkopuoliselle palvelun tarjoajalle. @@ -422,10 +545,35 @@ ssh_helper=Tarvitsetko apua? Tutustu GitHubin oppaaseen Tarvitsetko apua? Katso GitHubin opas GPG:stä. add_new_key=Lisää SSH avain add_new_gpg_key=Lisää GPG-avain +key_content_ssh_placeholder=Alkaa sanoilla 'ssh-ed25519', 'ssh-rsa', 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384', 'ecdsa-sha2-nistp521', 'sk-ecdsa-sha2-nistp256@openssh.com', tai 'sk-ssh-ed25519@openssh.com' +key_content_gpg_placeholder=Alkaa sanoilla '-----BEGIN PGP PUBLIC KEY BLOCK-----' +ssh_key_name_used=Samanniminen SSH avain on jo olemassa tililläsi. +gpg_key_id_used=Julkinen GPG-avain samalla tunnuksella on jo olemassa. +gpg_no_key_email_found=Tämä GPG-avain ei vastaa mitään tiliisi liitettyä aktivoitua sähköpostiosoitetta. Se voidaan silti lisätä, jos allekirjoitat annetun pääsymerkin. +gpg_key_verified=Vahvistettu avain +gpg_key_verified_long=Avain on vahvistettu pääsymerkillä ja sitä voidaan käyttää todentamaan commitit, jotka vastaavat tämän käyttäjän aktivoituja sähköpostiosoitteita tämän avaimen kaikkien vastaavien identiteettien lisäksi. +gpg_key_verify=Vahvista +gpg_token_required=Sinun täytyy antaa allekirjoitus alla olevalle pääsymerkille +gpg_token=Pääsymerkki +gpg_token_help=Voit luoda allekirjoituksen käyttäen: +gpg_token_code=echo "%s" | gpg -a --default-key %s --detach-sig +gpg_token_signature=Panssaroitu GPG-allekirjoitus +key_signature_gpg_placeholder=Alkaa sanoilla '-----BEGIN PGP SIGNATURE-----' +verify_gpg_key_success=GPG-avain '%s' on vahvistettu. +ssh_key_verified=Vahvistettu avain +ssh_key_verified_long=Avain on vahvistettu pääsymerkillä ja sitä voidaan käyttää todentamaan commitit, jotka vastaavat tämän käyttäjän aktivoituja sähköpostiosoitteita. +ssh_key_verify=Vahvista +ssh_token_required=Sinun täytyy antaa allekirjoitus alla olevalle pääsymerkille +ssh_token=Pääsymerkki +ssh_token_help=Voit luoda allekirjoituksen käyttäen: +ssh_token_signature=Panssaroitu SSH-allekirjoitus +key_signature_ssh_placeholder=Alkaa sanoilla '-----BEGIN SSH SIGNATURE-----' +verify_ssh_key_success=SSH avain '%s' on vahvistettu. subkeys=Aliavaimet key_id=Avain ID key_name=Avaimen nimi key_content=Sisältö +principal_content=Sisältö add_key_success=SSH-avain '%s' on lisätty. add_gpg_key_success=GPG-avain '%s' lisättiin. delete_key=Poista @@ -435,13 +583,22 @@ gpg_key_deletion_desc=GPG-avaimen poistaminen peruuttaa sillä allekirjoitettuje gpg_key_deletion_success=GPG-avain on poistettu. add_on=Lisätty valid_until=Vanhenee +valid_forever=Voimassa ikuisesti last_used=Käytetty viimeksi no_activity=Ei viimeaikaista toimintaa +can_read_info=Luku +can_write_info=Kirjoitus +show_openid=Näytä profiilissa +hide_openid=Piilota profiilista +ssh_disabled=SSH pois käytöstä manage_social=Hallitse liitettyjä sosiaalisia tilejä +manage_access_token=Hallitse pääsymerkkejä generate_new_token=Luo uusi pääsymerkki +new_token_desc=Pääsymerkkiä käyttävillä sovelluksilla on täysi pääsy tiliisi. token_name=Pääsymerkin nimi generate_token=Luo pääsymerkki +generate_token_success=Uusi pääsymerkkisi on nyt luotu. Kopioi se nyt, koska sitä ei näytetä enää uudelleen. delete_token=Poista access_token_deletion=Poista pääsymerkki @@ -459,8 +616,15 @@ oauth2_application_edit=Muokkaa twofa_desc=Kaksivaiheinen todennus parantaa tilisi turvallisuutta. +twofa_is_enrolled=Tilisi käyttää kaksivaiheista vahvistusta. +twofa_not_enrolled=Tilisi ei tällä hetkellä käytä kaksivaiheista vahvistusta. +twofa_enroll=Ota kaksivaiheinen vahvistus käyttöön twofa_disabled=Kaksivaiheinen todennus on otettu pois käytöstä. +scan_this_image=Skannaa tämä kuva tunnistautumissovelluksellasi: +or_enter_secret=Tai kirjoita salainen avain: %s +twofa_enrolled=Tiliisi on otettu käyttöön kaksivaiheinen vahvistus. Ota palautustunnus (%s) talteen turvalliseen paikkaan, sillä se näytetään vain kerran! +webauthn_nickname=Nimimerkki manage_account_links=Hallitse linkitettyjä tilejä manage_account_links_desc=Nämä ulkoiset tilit on linkitetty Gitea tiliisi. @@ -476,37 +640,59 @@ delete_prompt=Tämä toiminto poistaa käyttäjätilisi pysyvästi. Toimintoa Voit siirtää repon. owner=Omistaja +owner_helper=Jotkin organisaatiot eivät välttämättä näy pudotusvalikossa, koska repojen maksimimäärää on rajoitettu. repo_name=Repon nimi repo_name_helper=Hyvä repon nimi on lyhyt, mieleenpainuva ja yksilöllinen. +repo_size=Repon koko template=Malli template_select=Valitse malli. +template_helper=Tee reposta mallipohja visibility=Näkyvyys visibility_description=Vain omistaja tai organisaation jäsenet, jos heillä on oikeudet, voivat nähdä sen. visibility_helper=Tee reposta yksityinen fork_repo=Forkkaa repo fork_from=Forkkaa lähteestä fork_visibility_helper=Forkatun repon näkyvyyttä ei voi muuttaa. +download_zip=Lataa ZIP +download_tar=Lataa TAR.GZ repo_desc=Kuvaus repo_lang=Kieli repo_gitignore_helper=Valitse .gitignore mallit. issue_labels=Ongelmien tunnisteet +issue_labels_helper=Valitse pohja ongelmien nimilapuille. license=Lisenssi license_helper=Valitse lisenssitiedosto. readme=README auto_init=Alusta repo (Luo .gitignore, License ja README) create_repo=Luo repo default_branch=Oletus branch +mirror_prune=Karsi watchers=Tarkkailijat stargazers=Tähtiharrastajat forks=Haarat pick_reaction=Valitse reaktiosi +delete_preexisting_label=Poista +desc.private=Yksityinen +desc.public=Julkinen +desc.private_template=Yksityinen malli +desc.public_template=Malli +desc.internal=Sisäinen +template.git_hooks=Git-koukut +template.webhooks=Webkoukut template.topics=Aiheet template.avatar=Profiilikuva template.issue_labels=Ongelmien tunnisteet @@ -522,15 +708,18 @@ migrate_items_pullrequests=Vetopyynnöt migrate_items_releases=Julkaisut migrate_repo=Siirrä repo migrate.clone_address=Migraation / Kloonaa URL osoitteesta +migrate.github_token_desc=Voit laittaa yhden tai useamman pääsymerkin pilkulla erotellen tähän nopeuttaaksesi migraatiota GitHub APIn vauhtirajojen takia. VAROITUS: Tämän ominaisuuden väärinkäyttö voi rikkoa palveluntarjoajan ehtoja ja johtaa tilin estämiseen. migrate.permission_denied=Sinun ei sallita tuovan paikallisia repoja. migrate.failed=Siirto epäonnistui: %v +migrate.migrate_items_options=Pääsymerkki vaaditaan lisäkohteiden siirtämiseen +migrate.migrating_failed.error=Virhe: %s mirror_from=peilaus alkaen forked_from=forkattu lähteestä unwatch=Lopeta tarkkailu watch=Tarkkaile -unstar=Peru ääni -star=Äänestä +unstar=Poista tähti +star=Tähti download_archive=Lataa varasto no_desc=Ei kuvausta @@ -550,7 +739,10 @@ labels=Tunnisteet milestones=Merkkipaalut commits=Commitit +commit=Commit releases=Julkaisut +tag=Tagi +released_this=julkaisi tämän file_raw=Raaka file_history=Historia file_view_raw=Näytä raaka @@ -558,6 +750,8 @@ file_permalink=Pysyvä linkki video_not_supported_in_browser=Selaimesi ei tue HTML5 video-tagia. audio_not_supported_in_browser=Selaimesi ei tue HTML5 audio-tagia. +blame=Selitys +download_file=Lataa tiedosto normal_view=Normaali näkymä line=rivi lines=rivejä @@ -586,6 +780,7 @@ editor.create_new_branch_np=Luo uusi haara tälle commitille. editor.cancel=Peruuta editor.filename_cannot_be_empty=Tiedostonimi ei voi olla tyhjä. editor.filename_is_invalid=Tiedostonnimi on epäkelpo: '%s'. +editor.branch_already_exists=Haara '%s' on jo olemassa tässä repossa. editor.no_changes_to_show=Ei muutoksia näytettäväksi. editor.add_subdir=Lisää hakemisto… editor.unable_to_upload_files=Tiedostojen lataaminen kohteeseen '%s' epäonnistui virheellä: %v @@ -601,9 +796,19 @@ commits.date=Päivämäärä commits.older=Vanhemmat commits.newer=Uudemmat commits.signed_by=Allekirjoittanut +commits.gpg_key_id=GPG avaimen ID +commits.ssh_key_fingerprint=SSH avaimen sormenjälki +projects.description_placeholder=Kuvaus +projects.create=Luo projekti +projects.title=Otsikko +projects.new=Uusi projekti +projects.deletion=Poista projekti +projects.type.basic_kanban=Yksinkertainen Kanban +projects.board.new=Uusi taulu +projects.board.delete=Poista taulu issues.desc=Ongelmien, tehtävien ja merkkipaalujen hallinta. issues.filter_milestones=Suodata merkkipaalu @@ -620,12 +825,14 @@ issues.new.closed_milestone=Suljetut merkkipaalut issues.new.assignees=Käsittelijä issues.new.clear_assignees=Tyhjennä käsittelijä issues.new.no_assignees=Ei käsittelijää +issues.choose.blank=Oletus issues.no_ref=Haaraa/tagia ei määritelty issues.create=Ilmoita ongelma issues.new_label=Uusi tunniste issues.new_label_placeholder=Tunnisteen nimi issues.new_label_desc_placeholder=Kuvaus issues.create_label=Luo tunniste +issues.label_templates.helper=Valitse tunnistejoukko issues.add_milestone_at=`lisäsi tämän merkkipaaluun %s %s` issues.deleted_milestone=`(poistettu)` issues.self_assign_at=`itse otti tämän käsittelyyn %s` @@ -641,6 +848,7 @@ issues.filter_type.all_issues=Kaikki ongelmat issues.filter_type.assigned_to_you=Osoitettu sinulle issues.filter_type.created_by_you=Ilmoittamasi issues.filter_type.mentioning_you=Jotka mainitsee sinut +issues.filter_type.review_requested=Arvostelua pyydetty issues.filter_sort=Lajittele issues.filter_sort.latest=Uusin issues.filter_sort.oldest=Vanhin @@ -658,6 +866,7 @@ issues.action_open=Avaa issues.action_close=Sulje issues.action_label=Tunniste issues.action_milestone=Merkkipaalu +issues.action_milestone_no_select=Ei merkkipaalua issues.opened_by=%[1]s avasi %[3]s issues.previous=Edellinen issues.next=Seuraava @@ -725,9 +934,11 @@ issues.add_time_minutes=Minuuttia issues.add_time_sum_to_small=Aikaa ei syötetty. issues.time_spent_from_all_authors=`Käytetty kokonaisaika: %s` issues.due_date=Määräpäivä +issues.due_date_form=vvvv-kk-pp issues.due_date_form_edit=Muokkaa issues.due_date_form_remove=Poista issues.due_date_not_set=Määräpäivää ei asetettu. +issues.due_date_overdue=Myöhässä issues.dependency.title=Riippuvuudet issues.dependency.add=Lisää riippuvuus… issues.dependency.cancel=Peru @@ -735,6 +946,12 @@ issues.dependency.remove=Poista issues.dependency.remove_info=Poistä tämä riippuvuus issues.review.self.approval=Et voi hyväksyä omia vetopyyntöjä. issues.review.approve=hyväksyi nämä muutokset %s +issues.review.left_comment=jätti kommentin +issues.review.pending=Odottaa +issues.reference_issue.body=Kuvaus +issues.content_history.deleted=poistettu +issues.content_history.edited=muokattu +issues.content_history.created=luotu pulls.new=Uusi pull pyyntö @@ -776,12 +993,17 @@ milestones.edit_success=Merkkipaalu '%s' on päivitetty. milestones.filter_sort.most_issues=Eniten ongelmia milestones.filter_sort.least_issues=Vähiten ongelmia +signing.wont_sign.always=Commitit ovat aina allekirjoitettuja wiki=Wiki +wiki.welcome=Tervetuloa Wikiin. +wiki.welcome_desc=Wikissä voit kirjoittaa ja jakaa dokumentaatiota käyttäjien kesken. +wiki.create_first_page=Luo ensimmäinen sivu wiki.page=Sivu wiki.filter_page=Suodatin sivu wiki.new_page=Sivu +wiki.default_commit_message=Kirjoita muistiinpano tästä päivityksestä (valinnainen). wiki.save_page=Tallenna sivu wiki.last_commit_info=%s muokkasi tätä sivua %s wiki.edit_page_button=Muokkaa @@ -814,6 +1036,7 @@ activity.new_issues_count_n=Uutta ongelmaa activity.new_issue_label=Avoinna activity.unresolved_conv_label=Auki activity.published_release_label=Julkaistu +activity.git_stats_pushed_1=on työntänyt activity.git_stats_file_1=%d tiedosto activity.git_stats_file_n=%d tiedostoa activity.git_stats_addition_1=%d lisäys @@ -882,6 +1105,7 @@ settings.discord_username=Käyttäjätunnus settings.event_create=Luo settings.event_delete=Poista settings.event_release_desc=Julkaisu julkaistu, päivitetty tai poistettu varastosta. +settings.event_push=Työnnä settings.event_repository=Repo settings.event_issue_comment_desc=Ongelman kommentti luotu, muokattu tai poistettu. settings.event_pull_request=Vetopyyntö @@ -905,12 +1129,19 @@ settings.protect_merge_whitelist_committers_desc=Salli vain listaan merkittyjen settings.protect_merge_whitelist_users=Lista käyttäjistä joilla yhdistämis-oikeus: settings.protect_required_approvals=Vaadittavat hyväksynnät: settings.protect_approvals_whitelist_users=Sallittujen tarkastajien lista: +settings.protect_protected_file_patterns_desc=Suojatut tiedostot, joita ei voi muuttaa suoraan, vaikka käyttäjällä olisi oikeudet lisätä, muokata tai poistaa tiedostoja tässä haarassa. Useita malleja voidaan erottaa puolipisteellä ('\;'). Katso github.com/gobwas/glob dokumentaatio mallisyntaksille. Esimerkkejä: .drone.yml, /docs/**/*.txt. +settings.protect_unprotected_file_patterns_desc=Suojaamattomat tiedostot, joita voidaan muuttaa suoraan, jos käyttäjällä on kirjoitusoikeudet, ohittaen push-rajoituksen. Useita kuvioita voidaan erottaa puolipisteellä ('\;'). Katso github.com/gobwas/glob dokumentaatio kuviosyntaksille. Esimerkkejä: .drone.yml, /docs/**/*.txt. settings.update_protect_branch_success=Haaran '%s' suojaus on päivitetty. settings.remove_protected_branch_success=Haaran '%s' suojaus on poistettu käytöstä. settings.choose_branch=Valitse haara… settings.no_protected_branch=Suojattuja haaroja ei ole. settings.edit_protected_branch=Muokkaa settings.protected_branch_required_approvals_min=Vaadittavat hyväksynnät ei voi olla negatiivinen. +settings.tags=Tagit +settings.tags.protection.pattern=Tagin kuvio +settings.tags.protection.pattern.description=Voit käyttää yhtä nimeä tai glob-kuviota tai säännöllistä lauseketta, joka täsmää useisiin tageihin. Lue lisää suojatut tagit oppaasta. +settings.bot_token=Botti pääsymerkki +settings.matrix.access_token=Pääsymerkki settings.archive.button=Arkistoi repo settings.archive.header=Arkistoi tämä repo settings.lfs=LFS @@ -918,7 +1149,9 @@ settings.lfs_pointers.oid=OID diff.browse_source=Selaa lähdekoodia diff.parent=vanhempi +diff.commit=commit diff.git-notes=Muistiinpanot +diff.options_button=Vertailun asetukset diff.show_split_view=Jaettu näkymä diff.show_unified_view=Yhdistetty näkymä diff.whitespace_button=Tyhjämerkki @@ -938,6 +1171,7 @@ diff.review.comment=Kommentoi diff.review.approve=Hyväksy release.releases=Julkaisut +release.tags=Tagit release.new_release=Uusi julkaisu release.draft=Työversio release.prerelease=Esiversio @@ -964,6 +1198,7 @@ release.downloads=Lataukset branch.name=Haaran nimi branch.delete_head=Poista branch.delete=Poista haara '%s' +branch.create_branch=Luo haara %s @@ -1003,7 +1238,9 @@ settings.permission=Käyttöoikeudet settings.visibility=Näkyvyys settings.visibility.public=Julkinen settings.visibility.limited=Rajoitettu (näkyvä vain kirjautuneille käyttäjille) +settings.visibility.limited_shortname=Rajattu settings.visibility.private=Yksityinen (näkyvä vain organisaation jäsenille) +settings.visibility.private_shortname=Yksityinen settings.update_settings=Päivitä asetukset settings.delete=Poista organisaatio @@ -1054,6 +1291,7 @@ users=Käyttäjätilit organizations=Organisaatiot repositories=Repot authentication=Todennuslähteet +emails=Käyttäjien sähköpostit config=Asetukset notices=Järjestelmän ilmoitukset monitor=Valvonta @@ -1062,10 +1300,13 @@ last_page=Viimeisin total=Yhteensä: %d dashboard.statistic=Yhteenveto +dashboard.operations=Huoltotoimet dashboard.system_status=Järjestelmän tila dashboard.operation_name=Toiminnon nimi dashboard.operation_switch=Vaihda dashboard.operation_run=Suorita +dashboard.delete_inactive_accounts=Poista kaikki aktivoimattomat käyttäjät +dashboard.delete_repo_archives=Poista kaikki repojen arkistot (ZIP, TAR.GZ, jne..) dashboard.server_uptime=Palvelimen Uptime dashboard.current_goroutine=Nykyiset Goroutinet dashboard.current_memory_usage=Nykyinen muistinkäyttö @@ -1100,23 +1341,38 @@ users.name=Käyttäjätunnus users.full_name=Kokonimi users.activated=Aktivoitu users.admin=Ylläpito +users.restricted=Rajoitettu +users.2fa=2FA users.repos=Repot users.created=Luotu users.last_login=Viimeksi kirjautunut +users.never_login=Ei koskaan kirjautunut users.edit=Muokkaa users.auth_source=Todennuslähde users.local=Paikallinen users.password_helper=Jätä salasanakenttä tyhjäksi jos haluat pitää sen muuttamattomana. users.update_profile_success=Käyttäjän tili on päivitetty. users.edit_account=Muokkaa käyttäjän tiliä +users.max_repo_creation_desc=(Aseta -1 käyttääksesi globaalia oletusrajaa.) +users.is_activated=Käyttäjätili on aktivoitu +users.prohibit_login=Ota sisäänkirjautuminen pois käytöstä +users.is_admin=Ylläpitäjä +users.is_restricted=Rajoitettu tili +users.allow_git_hook=Voi luoda Git koukkuja +users.allow_create_organization=Voi luoda organisaatioita users.update_profile=Päivitä käyttäjän tili users.delete_account=Poista käyttäjän tili +users.list_status_filter.is_restricted=Rajoitettu +users.list_status_filter.not_restricted=Ei rajoitettu emails.email_manage_panel=Käyttäjien sähköpostien hallinta emails.primary=Ensisijainen emails.activated=Aktivoitu emails.filter_sort.email=Sähköposti +emails.filter_sort.email_reverse=Sähköposti (käänteinen) emails.filter_sort.name=Käyttäjänimi +emails.filter_sort.name_reverse=Käyttäjänimi (käänteinen) +emails.duplicate_active=Tämä sähköpostiosoite on jo käytössä toisella käyttäjällä. orgs.org_manage_panel=Organisaatioiden hallinta orgs.name=Nimi @@ -1129,7 +1385,7 @@ repos.owner=Omistaja repos.name=Nimi repos.private=Yksityinen repos.watches=Tarkkailijat -repos.stars=Äänet +repos.stars=Tähdet repos.forks=Haarat repos.issues=Ongelmat repos.size=Koko @@ -1155,12 +1411,14 @@ auths.user_dn=Käyttäjä DN auths.search_page_size=Sivukoko auths.filter=Käyttäjäsuodatin auths.admin_filter=Ylläpitosuodatin +auths.restricted_filter=Rajoitettu suodatin auths.smtp_auth=SMTP todennustyyppi auths.smtphost=SMTP isäntä auths.smtpport=SMTP portti auths.allowed_domains=Sallitut verkkotunnukset auths.skip_tls_verify=Ohita TLS tarkistaminen auths.pam_service_name=PAM palvelun nimi +auths.oauth2_tokenURL=Pääsymerkki URL auths.enable_auto_register=Ota käyttöön automaattinen rekisteröinti auths.tips=Vinkit auths.tips.oauth2.general=OAuth2-autentikointi @@ -1217,9 +1475,7 @@ config.queue_length=Jonon pituus config.deliver_timeout=Toimitus aikakatkaisu config.mailer_enabled=Käytössä -config.mailer_disable_helo=Poista käytöstä HELO config.mailer_name=Nimi -config.mailer_host=Isäntä config.mailer_user=Käyttäjä config.oauth_config=OAuth asetukset @@ -1285,6 +1541,8 @@ notices.op=Toiminta create_repo=luotu repo %s rename_repo=uudelleennimetty repo %[1]s nimelle %[3]s transfer_repo=siirretty repo %s kohteeseen %s +push_tag=työnsi tagin %[3]s kohteeseen %[4]s +compare_commits_general=Vertaa committeja [tool] ago=%s sitten @@ -1324,8 +1582,29 @@ mark_as_unread=Merkitse lukemattomaksi mark_all_as_read=Merkitse kaikki luetuiksi [gpg] +error.no_committer_account=Committaajan sähköpostiosoitteeseen ei ole linkitetty tiliä +error.not_signed_commit=Ei allekirjoitettu committi [units] [packages] +title=Paketit +desc=Hallitse repon paketteja. +empty=Täällä ei vielä ole paketteja. +empty.documentation=Lisätietoa pakettirekisteristä löydät dokumentaatiosta. +filter.type=Tyyppi +filter.type.all=Kaikki +filter.no_result=Suodattimesi ei tuottanut tuloksia. +installation=Asennus +details.author=Tekijä +composer.documentation=Lisätietoa Composer-rekisteristä löydät dokumentaatiosta. +conan.documentation=Lisätietoa Conan-rekisteristä löydät dokumentaatiosta. +container.documentation=Lisätietoa Container-rekisteristä löydätdokumentaatiosta. +generic.documentation=Lisätietoa yleisestä pakettirekisteristä löydät dokumentaatiosta. +helm.documentation=Lisätietoa Helm-rekisteristä löydät dokumentaatiosta. +maven.documentation=Lisätietoa Maven-rekisteristä löydät dokumentaatiosta. +nuget.documentation=Lisätietoa NuGet-rekisteristä löydät dokumentaatiosta. +npm.documentation=Lisätietoa npm-rekisteristä löydät dokumentaatiosta. +pypi.documentation=Lisätietoa PyPI-rekisteristä löydät dokumentaatiosta. +rubygems.documentation=Lisätietoa RubyGems-rekisteristä löydät dokumentaatiosta. diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini index 396ad2900b930..ac1d95053464d 100644 --- a/options/locale/locale_fr-FR.ini +++ b/options/locale/locale_fr-FR.ini @@ -2,6 +2,7 @@ home=Accueil dashboard=Tableau de bord explore=Explorateur help=Aide +logo=Logo sign_in=Connexion sign_in_with=Se connecter avec sign_out=Déconnexion @@ -35,6 +36,13 @@ twofa_scratch=Code de secours pour l'authentification à deux facteurs passcode=Code d'accès webauthn_insert_key=Insérez votre clé de sécurité +webauthn_sign_in=Appuyez sur le bouton de votre clé de sécurité. Si votre clé de sécurité n'a pas de bouton, réinsérez-la. +webauthn_press_button=Veuillez appuyer sur le bouton de votre clé de sécurité… +webauthn_use_twofa=Utilisez l'authentification à deux facteurs avec votre téléphone +webauthn_error=Impossible de lire votre clé de sécurité. +webauthn_unsupported_browser=Votre navigateur ne prend actuellement pas en charge WebAuthn. +webauthn_error_unknown=Une erreur indéterminée s'est produite. Veuillez réessayer. +webauthn_error_insecure=WebAuthn ne prend en charge que les connexions sécurisées. Pour les tests via HTTP, vous pouvez utiliser l'origine "localhost" ou "127.0.0.1" repository=Dépôt organization=Organisation @@ -156,12 +164,11 @@ http_port=Port d'écoute HTTP de Gitea http_port_helper=Port sur lequel le serveur web Gitea attendra des requêtes. app_url=URL de base de Gitea app_url_helper=Adresse HTTP(S) de base pour les clones git et les notifications par e-mail. -log_root_path=Chemin des fichiers log +log_root_path=Chemin des journaux log_root_path_helper=Les fichiers de journalisation seront écrits dans ce répertoire. optional_title=Paramètres facultatifs email_title=Paramètres E-mail -smtp_host=Hôte SMTP smtp_from=Envoyer les e-mails en tant que smtp_from_helper=Adresse e-mail utilisée par Gitea. Veuillez entrer votre e-mail directement ou sous la forme . mailer_user=Utilisateur SMTP @@ -183,7 +190,7 @@ openid_signin_popup=Activer l'authentification via OpenID. openid_signup=Activer l'inscription OpenID openid_signup_popup=Activer l'inscription avec OpenID. enable_captcha=Activer le CAPTCHA d'inscription -enable_captcha_popup=Demander un Captcha à l'inscription. +enable_captcha_popup=Demander un CAPTCHA à l'inscription. require_sign_in_view=Exiger la connexion à un compte pour afficher les pages require_sign_in_view_popup=Limiter l'accès aux pages aux utilisateurs connectés. Les visiteurs ne verront que les pages de connexion et d'inscription. admin_setting_desc=La création d'un compte administrateur est facultative. Le premier utilisateur enregistré deviendra automatiquement un administrateur le cas échéant. @@ -608,6 +615,7 @@ ssh_key_name_used=Une clé SSH avec le même nom existe déjà sur votre compte. ssh_principal_been_used=Ce principal a déjà été ajouté au serveur. gpg_key_id_used=Une clef GPG publique avec le même identifiant existe déjà. gpg_key_verified=Clé vérifiée +gpg_key_verify=Vérifier gpg_invalid_token_signature=La clé GPG fournie, la signature et le jeton ne correspondent pas ou le jeton n'est pas à jour. gpg_token_required=Vous devez fournir une signature pour le jeton ci-dessous gpg_token=Jeton @@ -619,6 +627,7 @@ ssh_token_required=Vous devez fournir une signature pour le jeton ci-dessous ssh_token=Jeton ssh_token_help=Vous pouvez générer une signature en utilisant : ssh_token_signature=Signature SSH renforcée +verify_ssh_key_success=La clef SSH '%s' a été vérifiée. subkeys=Sous-clés key_id=Clé ID key_name=Nom de la Clé @@ -666,6 +675,8 @@ generate_token_success=Votre nouveau jeton a été généré. Copiez-le maintena generate_token_name_duplicate=%s a déjà été utilisé comme nom d'application. Veuillez en utiliser un nouveau. delete_token=Supprimer access_token_deletion=Suppression de jetons d'accès +access_token_deletion_cancel_action=Annuler +access_token_deletion_confirm_action=Supprimer delete_token_success=Ce jeton a été supprimé. Les applications l'utilisant n'ont plus accès à votre compte. manage_oauth2_applications=Gérer les applications OAuth2 @@ -1033,6 +1044,7 @@ editor.cannot_commit_to_protected_branch=Impossible de créer une révision sur editor.no_commit_to_branch=Impossible d'enregistrer la révisions directement sur la branche parce que : editor.user_no_push_to_branch=L'utilisateur ne peut pas pousser vers la branche editor.require_signed_commit=Cette branche nécessite une révision signée +editor.revert=Rétablir %s sur: commits.desc=Naviguer dans l'historique des modifications. commits.commits=Révisions @@ -1119,12 +1131,12 @@ issues.new.assignees=Affecté à issues.new.add_assignees_title=Assigner des utilisateurs issues.new.clear_assignees=Supprimer les affectations issues.new.no_assignees=Pas d'assignataires -issues.new.no_reviewers=Pas de relecteur +issues.new.no_reviewers=Aucune évaluation issues.new.add_reviewer_title=Demander une revue issues.choose.get_started=Démarrons issues.choose.blank=Par défaut issues.choose.blank_about=Créer un ticket à partir du modèle par défaut. -issues.no_ref=Aucune branche/tag spécifiés +issues.no_ref=Aucune branche/étiquette spécifiées issues.create=Créer un ticket issues.new_label=Nouvelle étiquette issues.new_label_placeholder=Nom de l'étiquette @@ -1306,7 +1318,6 @@ issues.due_date_form_remove=Supprimer issues.due_date_not_writer=Vous devez avoir accès au dépôt en écriture pour mettre à jour l'échéance d'un ticket. issues.due_date_not_set=Aucune échéance n'a été définie. issues.due_date_added=a ajouté l'échéance %s %s -issues.due_date_modified=a modifié l'échéance de %[2]s vers %[1]s %[3]s issues.due_date_remove=a supprimé l'échéance %s %s issues.due_date_overdue=En retard issues.due_date_invalid=La date d’échéance est invalide ou hors plage. Veuillez utiliser le format 'aaaa-mm-dd'. @@ -1404,7 +1415,6 @@ pulls.remove_prefix=Enlever le préfixe %s pulls.data_broken=Cette demande de fusion est impossible par manque d'informations de bifurcation. pulls.files_conflicted=Cette demande d'ajout contient des modifications en conflit avec la branche ciblée. pulls.is_checking=Vérification des conflits de fusion en cours. Réessayez dans quelques instants. -pulls.is_empty=Cette branche est identique à la branche cible. pulls.required_status_check_failed=Certains contrôles requis n'ont pas réussi. pulls.required_status_check_missing=Certains contrôles requis sont manquants. pulls.required_status_check_administrator=En tant qu'administrateur, vous pouvez toujours fusionner cette requête de pull. @@ -1627,10 +1637,6 @@ settings.mirror_settings.last_update=Dernière mise à jour settings.mirror_settings.push_mirror.remote_url=URL du dépôt distant Git settings.sync_mirror=Synchroniser maintenant settings.mirror_sync_in_progress=La synchronisation est en cours. Revenez dans une minute. -settings.email_notifications.enable=Activer les notifications par e-mail -settings.email_notifications.onmention=N'envoyer un e-mail que si vous êtes mentionné -settings.email_notifications.disable=Désactiver les notifications par e-mail -settings.email_notifications.submit=Définir la préférence e-mail settings.site=Site Web settings.update_settings=Valider settings.branches.update_default_branch=Changer la Branche par Défaut @@ -2487,11 +2493,8 @@ config.queue_length=Longueur de la file d'attente config.deliver_timeout=Expiration d'Envoi config.skip_tls_verify=Passer la vérification TLS -config.mailer_config=Configuration du service SMTP config.mailer_enabled=Activé -config.mailer_disable_helo=Désactiver HELO config.mailer_name=Nom -config.mailer_host=Hôte config.mailer_user=Utilisateur config.mailer_use_sendmail=Utiliser Sendmail config.mailer_sendmail_path=Chemin d’accès à Sendmail @@ -2697,4 +2700,5 @@ error.no_unit_allowed_repo=Vous n'êtes pas autorisé à accéder à n'importe q error.unit_not_allowed=Vous n'êtes pas autorisé à accéder à cette section du dépôt. [packages] +empty.repo=Avez-vous téléchargé un paquet, mais il n'est pas affiché ici? Allez dans les paramètres du paquet et liez le à ce dépôt. diff --git a/options/locale/locale_hu-HU.ini b/options/locale/locale_hu-HU.ini index ed99432dff035..b09ffdba113af 100644 --- a/options/locale/locale_hu-HU.ini +++ b/options/locale/locale_hu-HU.ini @@ -135,7 +135,6 @@ log_root_path_helper=A naplófájlok ebbe a mappába fognak íródni. optional_title=További beállítások email_title=E-mail beállítások -smtp_host=SMTP kiszolgáló smtp_from=E-mail küldése mint smtp_from_helper=Az E-mail cím a mit a Gitea használni fog. Megadhatja sima email címként vagy "Név" formátumban. mailer_user=SMTP-felhasználónév @@ -922,7 +921,6 @@ issues.due_date_form_add=Határidő hozzáadása issues.due_date_form_edit=Szerkesztés issues.due_date_form_remove=Eltávolítás issues.due_date_not_set=Nincs beállítva határidő. -issues.due_date_modified=határidő módosítva %s-ről %s %s-re issues.due_date_remove=%s %s-es határidő eltávolítva issues.due_date_overdue=Lejárt issues.dependency.title=Függőségek @@ -1105,10 +1103,6 @@ settings.basic_settings=Alap beállítások settings.mirror_settings=Tükrözési beállítások settings.sync_mirror=Szinkronizálás most settings.mirror_sync_in_progress=Tükör szinkronizálása folyamatban. Kérem várjon. -settings.email_notifications.enable=Email értesítések engedélyezése -settings.email_notifications.onmention=Email küldése csak megjelölés esetén -settings.email_notifications.disable=Email értesítés kikapcsolása -settings.email_notifications.submit=E-mail beállítások megadása settings.site=Weboldal settings.update_settings=Beállítások frissítése settings.advanced_settings=Haladó beállítások @@ -1630,11 +1624,8 @@ config.queue_length=Várakozási Sor Hossza config.deliver_timeout=Kézbesítési Időtúllépés config.skip_tls_verify=A TLS Hitelesítés Kihagyása -config.mailer_config=SMTP levelező Beállítások config.mailer_enabled=Engedélyezett -config.mailer_disable_helo=HELO Letiltása config.mailer_name=Név -config.mailer_host=Kiszolgáló config.mailer_user=Felhasználó config.mailer_use_sendmail=Sendmail Használata config.mailer_sendmail_path=Sendmail Elérési Útja diff --git a/options/locale/locale_id-ID.ini b/options/locale/locale_id-ID.ini index 34c7db6b23eac..bfd7e6f31d85d 100644 --- a/options/locale/locale_id-ID.ini +++ b/options/locale/locale_id-ID.ini @@ -131,7 +131,6 @@ log_root_path_helper=Berkas log akan ditulis ke direktori ini. optional_title=Pengaturan Opsional email_title=Pengaturan Surel -smtp_host=Host SMTP smtp_from=Kirim Surel sebagai smtp_from_helper=Alamat surel Gitea akan digunakan. Masukkan alamat surel atau gunakan fomat "Nama" . mailer_user=Nama Pengguna SMTP @@ -1235,11 +1234,8 @@ config.queue_length=Panjang antrian config.deliver_timeout=Berikan waktu habis config.skip_tls_verify=Melewatkan verifikasi TLS -config.mailer_config=Pengaturan SMTP Mailer config.mailer_enabled=Diaktifkan -config.mailer_disable_helo=Nonaktifkan HELO config.mailer_name=Nama -config.mailer_host=Host config.mailer_user=Pengguna config.mailer_use_sendmail=Menggunakan Sendmail config.mailer_sendmail_path=Jalur Sendmail diff --git a/options/locale/locale_is-IS.ini b/options/locale/locale_is-IS.ini index c56b14f907747..f41fab0f52715 100644 --- a/options/locale/locale_is-IS.ini +++ b/options/locale/locale_is-IS.ini @@ -177,7 +177,6 @@ log_root_path_helper=Annálaskrár verða skrifaðar í þessa möppu. optional_title=Valfrjálsar Stillingar email_title=Tölvupóstsstillingar -smtp_host=SMTP Hýsill smtp_from=Senda Tölvupóst Sem smtp_from_helper=Netfang sem Gitea mun nota. Sláðu inn venjulegt netfang eða notaðu „Nafn“ sniðið. mailer_user=SMTP Notandanafn @@ -1026,10 +1025,6 @@ settings.mirror_settings.direction.pull=Pull settings.mirror_settings.direction.push=Push settings.mirror_settings.last_update=Síðasta uppfærsla settings.mirror_settings.push_mirror.remote_url=Vefslóð Git Fjarhugbúnaðarsafns -settings.email_notifications.enable=Virkja Tölvupósttilkynningar -settings.email_notifications.onmention=Aðeins Tölvupóst Þegar Minnst Er á Mig -settings.email_notifications.disable=Óvirkja Tölvupósttilkynningar -settings.email_notifications.submit=Stilla Val á Tölvupósti settings.site=Vefsíða settings.update_settings=Uppfæra Stillingar settings.branches.update_default_branch=Uppfæra Sjálfgefna Grein @@ -1269,7 +1264,6 @@ config.db_path=Slóð config.mailer_name=Heiti -config.mailer_host=Hýsill config.mailer_user=Notandi diff --git a/options/locale/locale_it-IT.ini b/options/locale/locale_it-IT.ini index 7087416f91b93..6e7e64d2a3ee7 100644 --- a/options/locale/locale_it-IT.ini +++ b/options/locale/locale_it-IT.ini @@ -2,6 +2,7 @@ home=Home dashboard=Pannello di controllo explore=Esplora help=Aiuto +logo=Logo sign_in=Accedi sign_in_with=Accedi con sign_out=Esci @@ -34,6 +35,19 @@ twofa=Verifica in due passaggi twofa_scratch=Codice di recupero per la verifica in due passaggi passcode=Codice di sicurezza +webauthn_insert_key=Inserisci la tua chiave di sicurezza +webauthn_sign_in=Premere il pulsante sul tasto di sicurezza. Se il tasto di sicurezza non ha pulsante, reinseriscilo. +webauthn_press_button=Si prega di premere il pulsante sul tasto di sicurezza… +webauthn_use_twofa=Usa un codice a due fattori dal tuo telefono +webauthn_error=Impossibile leggere la tua chiave di sicurezza. +webauthn_unsupported_browser=Il tuo browser al momento non supporta WebAuthn. +webauthn_error_unknown=Si è verificato un errore sconosciuto. Riprova. +webauthn_error_insecure=WebAuthn supporta solo connessioni sicure. Per il test su HTTP, è possibile utilizzare l'origine "localhost" o "127.0.0.1" +webauthn_error_unable_to_process=Il server non può elaborare la richiesta. +webauthn_error_duplicated=La chiave di sicurezza non è consentita per questa richiesta. Assicurati che la chiave non sia già registrata. +webauthn_error_empty=Devi impostare un nome per questa chiave. +webauthn_error_timeout=Timeout raggiunto prima che la tua chiave possa essere letta. Ricarica la pagina e riprova. +webauthn_reload=Ricarica repository=Repository organization=Organizzazione @@ -71,7 +85,13 @@ add=Aggiungi add_all=Aggiungi tutti remove=Rimuovi remove_all=Rimuovi tutti +edit=Modifica +copy=Copia +copy_url=Copia URL +copy_branch=Copia nome del ramo +copy_success=Copiato! +copy_error=Copia fallita write=Scrivi preview=Anteprima @@ -80,11 +100,20 @@ loading=Caricamento… step1=Passo 1: step2=Passo 2: +error=Errore error404=La pagina che stai cercando di raggiungere non esiste oppure non sei autorizzato a visualizzarla. +never=Mai +rss_feed=Feed RSS [error] +occurred=Si è verificato un errore +report_message=Se sei sicuro che questo sia un bug Gitea, cerca i problemi su GitHub o apri un nuovo problema se necessario. +missing_csrf=Richiesta errata: nessun token CSRF presente +invalid_csrf=Richiesta errata: token CSRF non valido +not_found=Il bersaglio non è stato trovato. +network_error=Errore di rete [startpage] app_desc=Un servizio auto-ospitato per Git pronto all'uso @@ -101,6 +130,7 @@ license_desc=Ottieni la documentazione prima di cambiare qualsiasi impostazione. +require_db_desc=Gitea requires MySQL, PostgreSQL, MSSQL, SQLite3 or TiDB (MySQL protocol). db_title=Impostazioni Database db_type=Tipo di database host=Host @@ -114,6 +144,11 @@ ssl_mode=SSL charset=Charset path=Percorso sqlite_helper=Percorso file del database SQLite3.
Inserisci un percorso assoluto se stai usando Gitea come servizio. +reinstall_error=Stai cercando di installare in un database Gitea esistente +reinstall_confirm_message=La reinstallazione con un database Gitea esistente può causare problemi multipli. Nella maggior parte dei casi, dovresti usare il tuo "app.ini" esistente per eseguire Gitea. Se sai cosa stai facendo, confermi quanto segue: +reinstall_confirm_check_1=I dati crittografati da SECRET_KEY nell'app. ni potrebbe essere perso: gli utenti potrebbero non essere in grado di accedere con 2FA/OTP & mirror potrebbe non funzionare correttamente. Selezionando questa casella confermi che il file attuale app.ini contiene il corretto SECRET_KEY. +reinstall_confirm_check_2=I repository e le impostazioni potrebbero avere bisogno di essere ri-sincronizzati. Selezionando questa casella confermi che potrai risincronizzare manualmente gli hook per i repository e il file authorized_keys. Confermi che assicurerai che le impostazioni del repository e del mirror siano corrette. +reinstall_confirm_check_3=Confermi di essere assolutamente sicuro che questo Gitea è in esecuzione con l'app corretta. ni posizione e che sei sicuro di dover reinstallare. Confermi di aver riconosciuto i rischi di cui sopra. err_empty_db_path=Il percorso del database SQLite3 non può essere vuoto. no_admin_and_disable_registration=Non puoi disabilitare l'auto-registrazione degli utenti senza creare un account amministratore. err_empty_admin_password=La password dell'amministratore non può essere vuota. @@ -131,6 +166,8 @@ lfs_path=Percorso radice di Git LFS lfs_path_helper=I file trovati da Git LFS saranno salvati in questa directory. Lasciare vuoto per disattivare. run_user=Esegui come Nome utente run_user_helper=Inserisci il nome utente del sistema operativo su cui Gitea viene eseguito. Nota che l'utente deve avere accesso al percorso radice dei repository. +domain=Dominio Server +domain_helper=Dominio o indirizzo host per il server. ssh_port=Porta Server SSH ssh_port_helper=Numero di porta in ascolto sul server SSH. Lasciare vuoto per disattivare. http_port=Porta in ascolto HTTP Gitea @@ -142,7 +179,8 @@ log_root_path_helper=I file di log saranno scritti in questa directory. optional_title=Impostazioni Facoltative email_title=Impostazioni Email -smtp_host=Host SMTP +smtp_addr=Host SMTP +smtp_port=Porta SMTP smtp_from=Invia Email come smtp_from_helper=Indirizzo Email che Gitea utilizzerà. Inserisci un indirizzo email o usa il formato "Name" . mailer_user=Nome utente SMTP @@ -177,8 +215,12 @@ install_btn_confirm=Installare Gitea test_git_failed=Fallito il test del comando git: %v sqlite3_not_available=Questa versione di Gitea non supporta SQLite3. Si prega di scaricare la versione binaria ufficiale da %s (not the 'gobuild' version). invalid_db_setting=Le impostazioni del database sono invalide: %v +invalid_db_table=La tabella del database '%s' non è valida: %v invalid_repo_path=Il percorso radice del Repository è invalido: %v +invalid_app_data_path=Il percorso dati dell'app non è valido: %v run_user_not_match=Il nome utente 'esegui come' non è il nome utente attuale: %s -> %s +internal_token_failed=Generazione del token interno non riuscita: %v +secret_key_failed=Generazione della chiave segreta non riuscita: %v save_config_failed=Salvataggio della configurazione non riuscito: %v invalid_admin_setting=Le impostazioni dell'account amministratore sono invalide: %v install_success=Benvenuto! Grazie per aver scelto Gitea. Attenzione e buon divertimento! @@ -207,6 +249,7 @@ view_home=Vedi %s search_repos=Trova un repository… filter=Altro filtri filter_by_team_repositories=Filtra per repository del team +feed_of=Feed di "%s" show_archived=Archiviato show_both_archived_unarchived=Mostra sia gli archiviati che i non archiviati @@ -228,6 +271,7 @@ search=Cerca code=Codice search.fuzzy=Fuzzy search.match=Corrispondenze +code_search_unavailable=Attualmente la ricerca di codice non è disponibile. Contatta l'amministratore del sito. repo_no_results=Nessuna repository corrispondente. user_no_results=Nessun utente corrispondente. org_no_results=Nessun'organizzazione corrispondente trovata. @@ -241,6 +285,7 @@ register_helper_msg=Hai già un account? Accedi ora! social_register_helper_msg=Hai già un account? Accedi ora! disable_register_prompt=La registrazione è disabilitata. Si prega di contattare l'amministratore del sito. disable_register_mail=Email di conferma per la registrazione disabilitata. +manual_activation_only=Contatta l'amministratore del sito per completare l'attivazione. remember_me=Ricorda questo dispositivo forgot_password_title=Password Dimenticata forgot_password=Password dimenticata? @@ -279,12 +324,17 @@ oauth_signup_submit=Completa l'Account oauth_signin_tab=Collegamento ad un Account Esistente oauth_signin_title=Accedi per autorizzare l' Account collegato oauth_signin_submit=Collega Account +oauth.signin.error=Si è verificato un errore nell'elaborazione della richiesta di autorizzazione. Se questo errore persiste, si prega di contattare l'amministratore del sito. +oauth.signin.error.access_denied=La richiesta di autorizzazione è stata negata. +oauth.signin.error.temporarily_unavailable=Autorizzazione non riuscita perché il server di autenticazione non è temporaneamente disponibile. Riprova più tardi. openid_connect_submit=Connetti openid_connect_title=Connetti a una conta esistente openid_connect_desc=L'URI OpenID scelto è sconosciuto. Qui puoi associarlo a un nuovo account. openid_register_title=Crea Nuovo Account openid_register_desc=L'URI OpenID scelto è sconosciuto. Qui puoi associarlo a un nuovo account. openid_signin_desc=Inserisci il tuo URI OpenID. Ad esempio: https://anne.me, bob.openid.org.cn o gnusocial.net/carry. +disable_forgot_password_mail=Il recupero dell'account è disabilitato perché non è stata impostata alcuna email. Contatta l'amministratore del sito. +disable_forgot_password_mail_admin=Il recupero dell'account è disponibile solo quando l'email è impostata. Si prega di impostare un'email per abilitare il recupero dell'account. email_domain_blacklisted=Non è possibile registrarsi con il proprio indirizzo email. authorize_application=Autorizza applicazione authorize_redirect_notice=Verrai reindirizzato a %s se autorizzi questa applicazione. @@ -298,21 +348,64 @@ password_pwned=La password che hai scelto è in una lista %s, activate_account=Per favore attiva il tuo account +activate_account.title=%s, si prega di attivare il tuo account +activate_account.text_1=Ciao %[1]s, grazie per essersi registrato al %[2]s! +activate_account.text_2=Clicca sul seguente link per attivare il tuo account entro %s: activate_email=Verifica il tuo indirizzo e-mail +activate_email.title=%s, verifica il tuo indirizzo e-mail +activate_email.text=Clicca sul seguente link per verificare il tuo indirizzo email entro %s: register_notify=Benvenuto su Gitea +register_notify.title=%[1]s, benvenuto in %[2]s +register_notify.text_1=questa è la tua email di conferma di registrazione per %s! +register_notify.text_2=Ora è possibile accedere tramite nome utente: %s. +register_notify.text_3=Se questo account è stato creato per te, per favore imposta prima la tua password. reset_password=Recupera il tuo account +reset_password.title=%s, hai richiesto di recuperare il tuo account +reset_password.text=Clicca sul seguente link per recuperare il tuo account entro %s: register_success=Registrazione completata con successo - - - - +issue_assigned.pull=@%[1]s ti ha assegnato il Problema %[2]s nel repository %[3]s. +issue_assigned.issue=@%[1]s ti ha assegnato il Problema %[2]s nel repository %[3]s. + +issue.x_mentioned_you=@%s ti ha menzionato: +issue.action.force_push=%[1]s force-pushed il %[2]s da %[3]s a %[4]s. +issue.action.push_1=@%[1]s ha spinto %[3]d commit a %[2]s +issue.action.push_n=@%[1]s ha spinto %[3]d commit a %[2]s +issue.action.close=@%[1]s chiuso #%[2]d. +issue.action.reopen=@%[1]s riaperto #%[2]d. +issue.action.merge=@%[1]s unito #%[2]d in %[3]s. +issue.action.approve=@%[1]s ha approvato questa pull request. +issue.action.reject=@%[1]s ha richiesto modifiche su questa pull request. +issue.action.review=@%[1]s ha commentato questa pull request. +issue.action.review_dismissed=@%[1]s ha respinto l'ultima recensione da %[2]s per questa pull request. +issue.action.ready_for_review=@%[1]s ha contrassegnato questa pull request pronta per la revisione. +issue.action.new=@%[1]s creato #%[2]d. +issue.in_tree_path=In %s: + +release.new.subject=%s in %s rilasciato +release.new.text=@%[1]s rilasciato %[2]s in %[3]s +release.title=Titolo: %s +release.note=Nota: +release.downloads=Scaricamenti: +release.download.zip=Codice Sorgente (Zip) +release.download.targz=Codice Sorgente (Tar.Gz) + +repo.transfer.subject_to=%s vorrebbe trasferire "%s" a %s +repo.transfer.subject_to_you=%s vorrebbe trasferire "%s" a te +repo.transfer.to_you=tu +repo.transfer.body=Per accettare o respingerla visita %s o semplicemente ignorarla. + +repo.collaborator.added.subject=%s ti ha aggiunto a %s +repo.collaborator.added.text=Sei stato aggiunto come collaboratore del repository: [modal] yes=Sì @@ -350,8 +443,10 @@ size_error='deve essere %s.' min_size_error=` deve contenere almeno %s caratteri.` max_size_error=` deve contenere massimo %s caratteri.` email_error=` non è un indirizzo e-mail valido.` +url_error=%s" non è un URL valido. include_error=` deve contenere la stringa '%s'.` glob_pattern_error=` il pattern glob non è valido: %s.` +regex_pattern_error=` modello regex non valido: %s.` unknown_error=Errore sconosciuto: captcha_incorrect=Il codice CAPTCHA non è corretto. password_not_match=Le password non corrispondono. @@ -360,6 +455,7 @@ lang_select_error=Selezionare una lingua dall'elenco. username_been_taken=Il Nome utente esiste già. username_change_not_local_user=Gli utenti non locali non sono autorizzati a modificare il proprio nome utente. repo_name_been_taken=Il nome del repository esiste già. +repository_force_private=Force Private è abilitato: i repository privati non possono essere resi pubblici. repository_files_already_exist=File già esistenti per questo repository. Contatta l'amministratore di sistema. repository_files_already_exist.adopt=I file esistono già per questo repository e possono essere solo Adottati. repository_files_already_exist.delete=I file esistono già per questo repository. È necessario eliminarli. @@ -389,12 +485,15 @@ cannot_add_org_to_team=Un'organizzazione non può essere aggiunto come membro de invalid_ssh_key=Impossibile verificare la tua chiave SSH: %s invalid_gpg_key=Impossibile verificare la tua chiave GPG: %s +invalid_ssh_principal=Principal non valido: %s unable_verify_ssh_key=Impossibile verificare la tua chiave SSH; si prega di ricontrollarla per verificare eventuali errori. auth_failed=Autenticazione non riuscita: %v still_own_repo=Il tuo account possiede una o più repositories; rimuovile o trasferiscile per proseguire. still_has_org=Il tuo account è un membro di una o più organizzazioni; abbandonali prima di proseguire. +still_own_packages=Il tuo account possiede uno o più pacchetti; eliminali prima. org_still_own_repo=Questa organizzazione possiede ancora una o più repositories, rimuoverle o trasferirle per continuare. +org_still_own_packages=Questa organizzazione possiede ancora uno o più pacchetti; eliminarli prima. target_branch_not_exist=Il ramo (branch) di destinazione non esiste. @@ -405,6 +504,7 @@ repositories=Repository activity=Attività pubblica followers=Seguaci starred=Repositories votate +watched=Repository Osservate projects=Progetti following=Seguiti follow=Segui @@ -420,6 +520,7 @@ form.name_chars_not_allowed=Il nome utente '%s' contiene caratteri non validi. [settings] profile=Profilo account=Account +appearance=Aspetto password=Password security=Sicurezza avatar=Avatar @@ -433,6 +534,7 @@ twofa=Verifica in due passaggi account_link=Account collegati organization=Organizzazioni uid=Uid +webauthn=Chiavi Di Sicurezza public_profile=Profilo pubblico biography_placeholder=Raccontaci un po' di te @@ -443,7 +545,9 @@ website=Sito web location=Posizione update_theme=Aggiorna tema update_profile=Aggiorna Profilo +update_language=Aggiorna Lingua update_language_not_found=La lingua '%s' non è disponibile. +update_language_success=La lingua è stata aggiornata. update_profile_success=Il tuo profilo è stato aggiornato. change_username=Il tuo nome utente è stato modificato. change_username_prompt=Nota: i cambiamenti al nome utente vanno a modificare anche l'URL del tuo account. @@ -452,6 +556,22 @@ continue=Continua cancel=Annulla language=Lingua ui=Tema +hidden_comment_types=Tipi di commenti nascosti +comment_type_group_reference=Riferimento +comment_type_group_label=Etichetta +comment_type_group_milestone=Traguardo +comment_type_group_assignee=Assegnatario +comment_type_group_title=Titolo +comment_type_group_branch=Ramo +comment_type_group_time_tracking=Cronografo +comment_type_group_deadline=Scadenza +comment_type_group_dependency=Dipendenza +comment_type_group_lock=Stato Blocco +comment_type_group_review_request=Richiesta di revisione +comment_type_group_pull_request_push=Aggiunti commit +comment_type_group_project=Progetto +comment_type_group_issue_ref=Riferimento del problema +saved_successfully=Le impostazioni sono state salvate correttamente. privacy=Privacy keep_activity_private=Nascondi l'attività dal profilo keep_activity_private_popup=Rendi l'attività visibile solo da te e dagli amministratori @@ -465,6 +585,7 @@ delete_current_avatar=Elimina Avatar attuale uploaded_avatar_not_a_image=Il file caricato non è un'immagine. uploaded_avatar_is_too_big=Il file inviato eccede le dimensioni massime. update_avatar_success=Il tuo avatar è stato aggiornato. +update_user_avatar_success=L'avatar dell'utente è stato aggiornato. change_password=Aggiorna Password old_password=Password attuale @@ -508,6 +629,7 @@ keep_email_private_popup=Il tuo indirizzo email sarà nascosto agli altri utenti openid_desc=OpenID consente di delegare l'autenticazione ad un provider esterno. manage_ssh_keys=Gestisci chiavi SSH +manage_ssh_principals=Gestisci i Certificati SSH manage_gpg_keys=Gestisci Chiavi GPG add_key=Aggiungi Chiave ssh_desc=Queste chiavi SSH pubbliche sono associate con il tuo account. Le corrispondenti chiavi private consentono l'accesso completo alle tue repositories. @@ -519,10 +641,35 @@ add_new_key=Aggiungi Chiave SSH add_new_gpg_key=Aggiungi Chiave GPG key_content_ssh_placeholder=Inizia con 'ssh-ed25519', 'ssh-rsa', 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384', 'ecdsa-sha2-nistp521', 'sk-ecdsa-sha2-nistp256@openssh.com', o 'sk-ssh-ed25519@openssh.com' key_content_gpg_placeholder=Comincia con '-----BEGIN PGP PUBLIC KEY BLOCK-----' +add_new_principal=Aggiungi Principal ssh_key_been_used=Questa chiave SSH è già stata aggiunta al server. ssh_key_name_used=Una chiave SSH con lo stesso nome esiste già sul tuo account. ssh_principal_been_used=Questa chiave SSH è già stata aggiunta al server. gpg_key_id_used=Esiste già una chiave GPG pubblica con lo stesso ID. +gpg_no_key_email_found=Questa chiave GPG non corrisponde a nessun indirizzo email attivato associato al tuo account. Potrebbe essere ancora aggiunto se firmi il token fornito. +gpg_key_matched_identities=Identità Corrispondenti: +gpg_key_matched_identities_long=Le identità incorporate in questa chiave corrispondono ai seguenti indirizzi email attivati per questo utente. I commit che corrispondono a questi indirizzi email possono essere verificati con questa chiave. +gpg_key_verified=Chiave Verificata +gpg_key_verified_long=La chiave è stata verificata con un token e può essere utilizzata per verificare che i commit corrispondano a tutti gli indirizzi email attivati per questo utente oltre a qualsiasi identità corrispondente per questa chiave. +gpg_key_verify=Verifica +gpg_invalid_token_signature=La chiave GPG fornita, la firma e il token non corrispondono o il token è obsoleto. +gpg_token_required=Devi fornire una firma per il token sottostante +gpg_token=Token +gpg_token_help=È possibile generare una firma utilizzando: +gpg_token_code=echo "%s" | gpg -a --default-key %s --detach-sig +gpg_token_signature=Firma GPG corazzata +key_signature_gpg_placeholder=Comincia con '-----BEGIN PGP SIGNATURE-----' +verify_gpg_key_success=La chiave GPG '%s' è stata verificata. +ssh_key_verified=Chiave Verificata +ssh_key_verified_long=La chiave è stata verificata con un token e può essere utilizzata per verificare che i commit corrispondano a tutti gli indirizzi email attivati per questo utente. +ssh_key_verify=Verifica +ssh_invalid_token_signature=La chiave SSH fornita, la firma o il token non corrispondono o il token è obsoleto. +ssh_token_required=Devi fornire una firma per il token sottostante +ssh_token=Token +ssh_token_help=È possibile generare una firma utilizzando: +ssh_token_signature=Firma SSH corazzata +key_signature_ssh_placeholder=Comincia con '-----BEGIN SSH SIGNATURE-----' +verify_ssh_key_success=La chiave SSH '%s' è stata verificata. subkeys=Sottochiavi key_id=ID chiave key_name=Nome della Chiave @@ -537,8 +684,10 @@ gpg_key_deletion=Rimuovi chiave GPG ssh_principal_deletion=Rimuovi certificato SSH principale ssh_key_deletion_desc=Rimuovere una chiave SSH ne revoca l'accesso al tuo account. Continuare? gpg_key_deletion_desc=La rimozione di una chiave GPG invalida i commits firmati da essa. Continuare? +ssh_principal_deletion_desc=Rimuovere un Certificato Utente SSH ne revoca l'accesso al tuo account. Continuare? ssh_key_deletion_success=La chiave SSH è stata rimossa. gpg_key_deletion_success=La chiave GPG è stata rimossa. +ssh_principal_deletion_success=Il principale è stato rimosso. add_on=Aggiunto il valid_until=Valido fino al valid_forever=Valido per sempre @@ -548,6 +697,7 @@ can_read_info=Letto can_write_info=Scrivere key_state_desc=Questa chiave è stata utilizzata negli ultimi 7 giorni token_state_desc=Questo token è stato utilizzato negli ultimi 7 giorni +principal_state_desc=Questo principal è stato utilizzato negli ultimi 7 giorni show_openid=Mostra nel profilo hide_openid=Nascondi dal profilo ssh_disabled=SSH disabilitato @@ -567,6 +717,9 @@ generate_token_success=Il nuovo token è stato generato. Copia ora in quanto non generate_token_name_duplicate=%s è già stato utilizzato come nome dell'applicazione. Si prega di usarne uno nuovo. delete_token=Elimina access_token_deletion=Elimina token di accesso +access_token_deletion_cancel_action=Annulla +access_token_deletion_confirm_action=Elimina +access_token_deletion_desc=L'eliminazione di un token annullerà l'accesso al tuo account per le applicazioni che lo utilizzano. Questo non può essere annullato. Continuare? delete_token_success=Il token è stato eliminato. Le applicazioni che lo utilizzavano non hanno più accesso al tuo account. manage_oauth2_applications=Gestisci applicazioni OAuth2 @@ -619,10 +772,16 @@ passcode_invalid=Il codice di accesso non è corretto. Riprova. twofa_enrolled=Il tuo account è stato registrato alla verifica in due passaggi. Conserva il token di sicurezza (%s) in un luogo sicuro in quanto viene visualizzato sono una volta! twofa_failed_get_secret=Impossibile ottenere il segreto. +webauthn_desc=Le chiavi di sicurezza sono dispositivi hardware contenenti chiavi crittografiche. Possono essere utilizzate per l'autenticazione a due fattori. Le chiavi di sicurezza devono supportare lo standard WebAuthenticator di WebAuthn. +webauthn_register_key=Aggiungi Chiave Di Sicurezza +webauthn_nickname=Soprannome +webauthn_delete_key=Rimuovi Chiave Di Sicurezza +webauthn_delete_key_desc=Se si rimuove una chiave di sicurezza non è più possibile accedere con esso. Continuare? manage_account_links=Gestisci gli account collegati manage_account_links_desc=Questi account esterni sono collegati al tuo account Gitea. account_links_not_available=Attualmente non è collegato alcun account esterno al tuo account Gitea. +link_account=Collega Account remove_account_link=Rimuovi account collegato remove_account_link_desc=Rimuovere un account collegato ne revoca l'accesso al tuo account Gitea. Continuare? remove_account_link_success=L'account collegato è stato rimosso. @@ -632,6 +791,7 @@ repos_none=Non possiedi alcun repository delete_account=Elimina Account delete_prompt=Questa operazione eliminerà permanentemente il tuo account utente. NON PUÒ essere annullata. +delete_with_all_comments=Il tuo account è più recente di %s giorni. Per evitare commenti fantasma, tutti i commenti relativi a issue/PR verranno eliminati con esso. confirm_delete_account=Conferma Eliminazione delete_account_title=Elimina account utente delete_account_desc=Sei sicuro di voler rimuovere questo account utente permanentemente? @@ -640,10 +800,20 @@ email_notifications.enable=Abilita Notifiche Email email_notifications.onmention=Solo email su Menzione email_notifications.disable=Disabilita notifiche email email_notifications.submit=Imposta Preferenze Email +email_notifications.andyourown=E Le Tue Notifiche +visibility=Visibilità utente +visibility.public=Pubblico +visibility.public_tooltip=Visibile a tutti gli utenti +visibility.limited=Limitato +visibility.limited_tooltip=Visibile solo agli utenti registrati +visibility.private=Privato +visibility.private_tooltip=Visibile solo ai membri dell'organizzazione [repo] +new_repo_helper=Un repository contiene tutti i file del progetto, inclusa la cronologia delle revisioni. Lo hai già altrove? Migrare il repository. owner=Proprietario +owner_helper=Alcune organizzazioni potrebbero non essere visualizzate nel menu a discesa a causa di un limite massimo al numero di repository. repo_name=Nome Repository repo_name_helper=Un buon nome per un repository è costituito da parole chiave corte, facili da ricordare e uniche. repo_size=Dimensione repository @@ -659,33 +829,55 @@ visibility_fork_helper=(Questa modifica avrà effetto su tutti i fork) clone_helper=Hai bisogno di aiuto per la clonazione? Visita Help. fork_repo=Forka Repository fork_from=Forka da +already_forked=Hai già fatto il fork di %s +fork_to_different_account=Fai Fork a un account diverso fork_visibility_helper=La visibilità di un repository forkato non può essere modificata. use_template=Usa questo modello +clone_in_vsc=Clona nel codice VS +download_zip=Scarica ZIP +download_tar=Scarica TAR.GZ +download_bundle=Scarica BUNDLE generate_repo=Genera repository generate_from=Genera da repo_desc=Descrizione repo_desc_helper=Inserisci una breve descrizione (opzionale) repo_lang=Lingua repo_gitignore_helper=Seleziona i template di .gitignore. +repo_gitignore_helper_desc=Scegli di quali file non tenere traccia da un elenco di modelli per le lingue comuni. Gli artefatti tipici generati dagli strumenti di build di ogni lingua sono inclusi su .gitignore per impostazione predefinita. issue_labels=Etichette Issue issue_labels_helper=Seleziona un set di etichette per problemi. license=Licenza license_helper=Seleziona un file di licenza. +license_helper_desc=Una licenza governa ciò che gli altri possono e non possono fare con il tuo codice. Non sei sicuro di chi è giusto per il tuo progetto? Vedi Scegli una licenza. readme=LEGGIMI readme_helper=Seleziona un template per il file LEGGIMI. readme_helper_desc=Qui puoi scrivere una descrizione completa del progetto. auto_init=Inizializza Repository (Aggiungi .gitignore, Licenza e LEGGIMI) trust_model_helper=Seleziona il modello di fiducia per la verifica della firma. Le opzioni possibili sono: trust_model_helper_collaborator=Collaboratore: Fidati delle firme da parte dei collaboratori +trust_model_helper_committer=Committer: Fidati delle Firme che corrispondono ai committenti +trust_model_helper_collaborator_committer=Collaboratore+Committer: Fidati delle firme da parte dei collaboratori che corrispondono al committer +trust_model_helper_default=Predefinito: utilizzare il modello di trust predefinito per questa installazione create_repo=Crea Repository default_branch=Ramo (Branch) predefinito +default_branch_helper=Il ramo predefinito è il ramo base per le richieste di pull e i commit di codice. mirror_prune=Rimuovi mirror_prune_desc=Rimuovi i riferimenti di puntamento-remoto obsoleti +mirror_interval=Intervallo di specchio (le unità di tempo valide sono 'h', 'm', 's'). 0 per disabilitare la sincronizzazione periodica. (Intervallo minimo: %s) mirror_interval_invalid=L'intervallo di aggiornamento dei mirror non è valido. +mirror_sync_on_commit=Sincronizzazione quando i commit vengono premuti mirror_address=Clona da URL +mirror_address_desc=Metti tutte le credenziali richieste nella sezione Autorizzazione. mirror_address_url_invalid=L'url fornito non è valido. Devi effettuare l'escape completo tutti i componenti dell'Url. mirror_address_protocol_invalid=L'url fornito non è valido. Solo dai link http(s):// o git:// possono essere replicate. +mirror_lfs=Large File Storage (LFS) +mirror_lfs_desc=Attiva il mirroring dei dati LFS. +mirror_lfs_endpoint=Punto d'accesso LFS +mirror_lfs_endpoint_desc=La sincronizzazione tenterà di utilizzare l'url clone per determinare il server LFS. È inoltre possibile specificare un endpoint personalizzato se il repository dati LFS è memorizzato da qualche altra parte. mirror_last_synced=Ultima sincronizzazione +mirror_password_placeholder=(Inmodificato) +mirror_password_blank_placeholder=(Disattivato) +mirror_password_help=Cambia il nome utente per cancellare una password memorizzata. watchers=Osservatori stargazers=Fan forks=Fork @@ -702,12 +894,14 @@ delete_preexisting_label=Elimina delete_preexisting=Elimina file preesistenti delete_preexisting_content=Elimina file in %s delete_preexisting_success=Eliminato file non adottati in %s +blame_prior=Visualizza la colpa prima di questa modifica transfer.accept=Accetta trasferimento transfer.accept_desc=Trasferisci a "%s" transfer.reject=Rifiuta trasferimento transfer.reject_desc=Annulla il trasferimento a "%s" transfer.no_permission_to_accept=Non hai i permessi per accettare +transfer.no_permission_to_reject=Non hai i permessi per rifiutare desc.private=Privato desc.public=Pubblico @@ -720,6 +914,7 @@ desc.archived=Archiviato template.items=Elementi del modello template.git_content=Contenuto di Git (Ramo predefinito) template.git_hooks=Git Hooks +template.git_hooks_tooltip=Al momento non sei in grado di modificare o rimuovere Git Hooks una volta aggiunto. Selezionare questa opzione solo se ti fidi del template repository. template.webhooks=Webhooks template.topics=Argomenti template.avatar=Avatar @@ -731,11 +926,20 @@ archive.title=Questo repository è archiviato. Puoi vedere i file e clonarli, ma archive.issue.nocomment=Questo repository è archiviato. Non puoi commentare i problemi. archive.pull.nocomment=Questo repository è archiviato. Non puoi commentare le richieste di pull. +form.reach_limit_of_creation_1=Hai già raggiunto il tuo limite di %d repository. +form.reach_limit_of_creation_n=Hai già raggiunto il tuo limite di %d repository. form.name_reserved=Il nome repository '%s' è riservato. form.name_pattern_not_allowed=Il modello '%s' non è consentito come nome di un repository. +need_auth=Autorizzazione migrate_options=Opzioni di migrazione migrate_service=Servizio migrazione +migrate_options_mirror_helper=Questo repository sarà un mirror +migrate_options_lfs=Migra file LFS +migrate_options_lfs_endpoint.label=Punto d'accesso LFS +migrate_options_lfs_endpoint.description=La migrazione tenterà di utilizzare il tuo Git remote per determinare il server LFS. È inoltre possibile specificare un endpoint personalizzato se il repository dati LFS è memorizzato da qualche altra parte. +migrate_options_lfs_endpoint.description.local=È supportato anche un percorso server locale. +migrate_options_lfs_endpoint.placeholder=Lascia vuoto per derivare dall'URL della clonazione migrate_items=Elementi di migrazione migrate_items_wiki=Wiki migrate_items_milestones=Milestone @@ -747,9 +951,12 @@ migrate_items_releases=Rilasci migrate_repo=Migra Repository migrate.clone_address=Migra / Clona da URL migrate.clone_address_desc=URL HTTP (S) o Git 'clone' di un repository esistente +migrate.github_token_desc=È possibile mettere uno o più token con virgola separati qui per rendere la migrazione più veloce a causa del limite di velocità API GitHub. ATTENZIONE: L'abuso di questa funzione potrebbe violare la politica del fornitore di servizi e portare al blocco dell'account. migrate.clone_local_path=o un percorso del server locale migrate.permission_denied=Non è consentito importare repository locali. +migrate.permission_denied_blocked=Non è possibile importare da host non consentiti, si prega di chiedere all'amministratore di controllare ALLOWED_DOMAINS/ALLOW_LOCALNETWORKS/BLOCKED_DOMAINS impostazioni. migrate.invalid_local_path=Percorso locale non valido, non esiste o non è una cartella. +migrate.invalid_lfs_endpoint=Il punto d'accesso LFS non è valido. migrate.failed=Migrazione non riuscita: %v migrate.migrate_items_options=Il Token di accesso è richiesto per migrare elementi aggiuntivi migrated_from=Migrato da %[2]s @@ -757,6 +964,23 @@ migrated_from_fake=Migrato da %[1]s migrate.migrate=Migra da %s migrate.migrating=Migrazione da %s... migrate.migrating_failed=Migrazione da %s fallita. +migrate.migrating_failed.error=Errore: %s +migrate.migrating_failed_no_addr=Migrazione non riuscita. +migrate.github.description=Migrare i dati da github.com o da altre istanze di GitHub. +migrate.git.description=Migra un repository solo da qualsiasi servizio Git. +migrate.gitlab.description=Migrare i dati da gitlab.com o da altre istanze di GitLab. +migrate.gitea.description=Migrare i dati da gitea.com o altre istanze di Gitea. +migrate.gogs.description=Migrare i dati da notabug.org o da altre istanze Gogs. +migrate.onedev.description=Migrare i dati da code.onedev.io o da altre istanze OneDev. +migrate.codebase.description=Migrare i dati da codebasehq.com. +migrate.gitbucket.description=Migra i dati dalle istanze di GitBucket. +migrate.migrating_git=Migrazione dei Dati Git +migrate.migrating_topics=Migrazione dei topic +migrate.migrating_milestones=Migrazione dei traguardi +migrate.migrating_labels=Migrazione delle etichette +migrate.migrating_releases=Migrazione delle uscite +migrate.migrating_issues=Migrazione dei problemi +migrate.migrating_pulls=Migrazione delle Pull Request mirror_from=mirror da forked_from=forkato da @@ -778,6 +1002,7 @@ clone_this_repo=Clona questo repository create_new_repo_command=Creazione di un nuovo repository da riga di comando push_exist_repo=Push di un repository esistente da riga di comando empty_message=Questo repository non contiene alcun contenuto. +broken_message=I dati Git sottostanti a questo repository non possono essere letti. Contattare l'amministratore di questa istanza o eliminare questo repository. code=Codice code.desc=Accedi al codice sorgente, file, commits e branches. @@ -785,11 +1010,13 @@ branch=Ramo (Branch) tree=Albero (Tree) clear_ref=`Cancella il riferimento corrente` filter_branch_and_tag=Filtra per branch o tag +find_tag=Trova etichetta branches=Rami (Branch) tags=Tag issues=Problemi pulls=Pull Requests project_board=Progetti +packages=Pacchetti labels=Etichette org_labels_desc=Etichette a livello di organizzazione che possono essere utilizzate con tutti i repository sotto questa organizzazione org_labels_desc_manage=gestisci @@ -800,21 +1027,38 @@ commit=Commit release=Rilascio releases=Rilasci tag=Etichetta +released_this=ha rilasciato questo +file.title=%s a %s file_raw=Originale file_history=Cronologia file_view_source=Visualizza sorgente +file_view_rendered=Visualizza Renderizzato file_view_raw=Vedi originale file_permalink=Permalink file_too_large=Il file è troppo grande per essere visualizzato. - +bidi_bad_header=`Questo file contiene caratteri Unicode Bidirezionali inattesi!` +bidi_bad_description=`Questo file contiene caratteri inaspettati Bidirezionali Unicode che possono essere elaborati in modo diverso da quello che appare di seguito. Se il tuo caso di utilizzo è intenzionale e legittimo, puoi tranquillamente ignorare questo avviso. Usa il pulsante Escape per rivelare caratteri nascosti.` +bidi_bad_description_escaped=`Questo file contiene caratteri Unicode bidirezionali inattesi. I caratteri unicode nascosti sono sfuggiti qui sotto. Usa il pulsante Unescape per mostrare come render.` +unicode_header=`Questo file contiene caratteri Unicode nascosti!` +unicode_description=`Questo file contiene caratteri Unicode nascosti che possono essere elaborati in modo diverso da quello che appare di seguito. Se il tuo caso di utilizzo è intenzionale e legittimo, puoi tranquillamente ignorare questo avviso. Usa il pulsante Escape per rivelare caratteri nascosti.` +unicode_description_escaped=`Questo file contiene caratteri Unicode nascosti. I caratteri unicode nascosti sono fuggiti qui sotto. Usa il pulsante Unescape per mostrare come render.` +line_unicode=`Questa riga ha caratteri unicode nascosti` + +escape_control_characters=Fuga +unescape_control_characters=Unescape +file_copy_permalink=Copia Permalink +view_git_blame=Visualizza Git Blame video_not_supported_in_browser=Il tuo browser non supporta i tag "video" di HTML5. audio_not_supported_in_browser=Il tuo browser non supporta il tag "video" di HTML5. stored_lfs=Memorizzati con Git LFS symbolic_link=Link Simbolico commit_graph=Grafico dei commit commit_graph.select=Seleziona rami +commit_graph.hide_pr_refs=Nascondi Pull Requests commit_graph.monochrome=Mono +commit_graph.color=Colore blame=Blame +download_file=Scarica file normal_view=Vista normale line=riga lines=righe @@ -842,7 +1086,12 @@ editor.add_tmpl=Aggiungi '' editor.add=Aggiungi '%s' editor.update=Aggiornare '%s' editor.delete=Eliminare '%s' +editor.patch=Applica Patch +editor.patching=Patching: +editor.fail_to_apply_patch=Impossibile applicare la patch '%s' +editor.new_patch=Nuova Patch editor.commit_message_desc=Aggiungi una descrizione estesa facoltativa… +editor.signoff_desc=Aggiungi "firmato da" dal committer alla fine del messaggio di log di commit. editor.commit_directly_to_this_branch=Impegnarsi direttamente con il %s branch. editor.create_new_branch=Creare un nuovo branch per questo commit e inizia una pull request. editor.create_new_branch_np=Crea un nuovo ramo per questo commit. @@ -863,7 +1112,11 @@ editor.file_already_exists=Un file di nome '%s' esiste già in questo repository editor.commit_empty_file_header=Commit di un file vuoto editor.commit_empty_file_text=Il file che stai per effettuare il commit è vuoto. Procedere? editor.no_changes_to_show=Non ci sono cambiamenti da mostrare. +editor.fail_to_update_file=Impossibile aggiornare/creare il file '%s'. editor.fail_to_update_file_summary=Messaggio d'errore: +editor.push_rejected_no_message=La modifica è stata rifiutata dal server senza un messaggio. Controlla Git Hooks. +editor.push_rejected=La modifica è stata rifiutata dal server. Controlla Git Hooks. +editor.push_rejected_summary=Messaggio Di Rifiuto Completo: editor.add_subdir=Aggiungi una directory… editor.unable_to_upload_files=Impossibile caricare i file su '%s' con errore:%v editor.upload_file_is_locked=Il file '%s' è bloccato da %s. @@ -872,10 +1125,13 @@ editor.cannot_commit_to_protected_branch=Impossibile eseguire un commit sul bran editor.no_commit_to_branch=Impossibile effettuare il commit direttamente sul branch perché: editor.user_no_push_to_branch=L'utente non può effettuare il push sul branch editor.require_signed_commit=Il branch richiede un commit firmato +editor.cherry_pick=Cherry-pick %s suto: +editor.revert=Ripristina %s su: commits.desc=Sfoglia la cronologia di modifiche del codice rogente. commits.commits=Commit commits.no_commits=Nessun commit in comune. '%s' e '%s' hanno storie completamente diverse. +commits.nothing_to_compare=Questi rami sono uguali. commits.search=Ricerca commits… commits.search.tooltip=Puoi anteporre le parole chiave con "author:", "committer:", "after:", o "before:", o "revert author:Alice before:2019-04-01". commits.find=Cerca @@ -889,11 +1145,21 @@ commits.signed_by=Firmato da commits.signed_by_untrusted_user=Firmato da un utente non attendibile commits.signed_by_untrusted_user_unmatched=Firmato da un utente non attendibile che non corrisponde al committer commits.gpg_key_id=ID Chiave GPG +commits.ssh_key_fingerprint=Impronta Digitale Chiave SSH +commit.actions=Azioni +commit.revert=Ripristina +commit.revert-header=Ripristina: %s +commit.revert-content=Selezionare il ramo su cui ripristinare: +commit.cherry-pick=Cherry-pick +commit.cherry-pick-header=Cherry-pick: %s +commit.cherry-pick-content=Seleziona il ramo su cui scegliere: +ext_issues=Accesso ai Problemi Esterni ext_issues.desc=Collegamento al puntatore di una issue esterna. projects=Progetti +projects.desc=Gestisci problemi e pull nelle schede di progetto. projects.description=Descrizione (opzionale) projects.description_placeholder=Descrizione projects.create=Crea un progetto @@ -920,10 +1186,13 @@ projects.board.new_title=Nuovo Nome Della Scheda projects.board.new_submit=Invia projects.board.new=Nuova Scheda projects.board.set_default=Imposta come predefinito +projects.board.set_default_desc=Imposta questa scheda come predefinita per problemi non categorizzati e pull projects.board.delete=Elimina Scheda projects.board.deletion_desc=L'eliminazione di una scheda di progetto sposta tutti i problemi correlati a 'Uncategorized'. Continuare? +projects.board.color=Colore projects.open=Apri projects.close=Chiudi +projects.board.assigned_to=Assegnato a issues.desc=Organizza le segnalazioni di bug, attività e pietre miliari. issues.filter_assignees=Filtra assegnatario @@ -970,6 +1239,11 @@ issues.label_templates.info=Non esistono etichette. Crea una etichetta con 'Nuov issues.label_templates.helper=Scegli un set di etichette issues.label_templates.use=Usa Set Etichette issues.label_templates.fail_to_load_file=Impossibile caricare il file template di etichetta '%s': %v +issues.add_label=ha aggiunto l'etichetta %s %s +issues.add_labels=ha aggiunto le %s etichette %s +issues.remove_label=rimosso l'etichetta %s %s +issues.remove_labels=rimosso le %s etichette %s +issues.add_remove_labels=aggiunto %s e rimosso %s etichette %s issues.add_milestone_at=`aggiunta alle pietre miliari %s %s` issues.add_project_at=`aggiunto questo al progetto %s %s` issues.change_milestone_at=`pietra miliare modificata da %s a %s %s` @@ -983,6 +1257,9 @@ issues.add_assignee_at=`è stato assegnato da %s %s` issues.remove_assignee_at=`è stato rimosso da %s %s` issues.remove_self_assignment=`Rimosso il loro incarico %s` issues.change_title_at=`Titolo modificato da %s a %s %s` +issues.change_ref_at=`ha cambiato il riferimento da %s a %s %s` +issues.remove_ref_at=`riferimento rimosso %s %s` +issues.add_ref_at=`aggiunto riferimento %s %s` issues.delete_branch_at=`branch %s eliminato %s` issues.filter_label=Etichetta issues.filter_label_exclude=`Usa alt + click/enter per escludere le etichette` @@ -1010,6 +1287,7 @@ issues.filter_sort.moststars=Più favoriti issues.filter_sort.feweststars=Meno favoriti issues.filter_sort.mostforks=Maggior numero di fork issues.filter_sort.fewestforks=Minor numero di fork +issues.keyword_search_unavailable=Attualmente la ricerca per parola chiave non è disponibile. Contatta l'amministratore del sito. issues.action_open=Aperto issues.action_close=Chiuso issues.action_label=Etichetta @@ -1018,19 +1296,28 @@ issues.action_milestone_no_select=Nessuna pietra miliare issues.action_assignee=Assegnatario issues.action_assignee_no_select=Nessun assegnatario issues.opened_by=aperto %[1]s da %[3]s +pulls.merged_by=di %[3]s è stato fuso %[1]s +pulls.merged_by_fake=di %[2]s è stato fuso %[1]s +issues.closed_by=di %[3]s è stato chiuso %[1]s +issues.opened_by_fake=aperto %[1]s da %[2]s +issues.closed_by_fake=di %[2]s è stato chiuso %[1]s issues.previous=Pagina precedente issues.next=Pagina successiva issues.open_title=Aperto issues.closed_title=Chiuso +issues.draft_title=Bozza issues.num_comments=%d commenti issues.commented_at=`%s ha commentato` issues.delete_comment_confirm=Sei sicuro/a di voler eliminare questo commento? issues.context.copy_link=Copia link issues.context.quote_reply=Quota risposta +issues.context.reference_issue=Fai riferimento in un nuovo problema issues.context.edit=Modifica issues.context.delete=Elimina issues.no_content=Non ci sono ancora contenuti. issues.close_issue=Chiudi +issues.pull_merged_at=`merged commit %[2]s in %[3]s %[4]s` +issues.manually_pull_merged_at=`merged commit %[2]s in %[3]s manualmente %[4]s` issues.close_comment_issue=Commenta e Chiudi issues.reopen_issue=Riapri issues.reopen_comment_issue=Commenta e Riapri @@ -1052,6 +1339,8 @@ issues.re_request_review=Revisione ri-richiesta issues.is_stale=Ci sono stati cambiamenti a questa PR da questa revisione issues.remove_request_review=Elimina richiesta revisione issues.remove_request_review_block=Impossibile rimuovere la richiesta di revisione +issues.dismiss_review=Respingi Recensione +issues.dismiss_review_warning=Sei sicuro di voler respingere questa recensione? issues.sign_in_require_desc=Effettua l'accesso per partecipare alla conversazione. issues.edit=Modifica issues.cancel=Annulla @@ -1095,13 +1384,21 @@ issues.lock.reason=Motivo per il blocco issues.lock.title=Blocca la conversazione su questa issue. issues.unlock.title=Sblocca la conversazione su questa issue. issues.comment_on_locked=Non puoi commentare un problema bloccato. +issues.delete=Elimina +issues.delete.title=Eliminare questo problema? +issues.delete.text=Vuoi davvero eliminare questo problema? (Questo rimuoverà permanentemente tutti i contenuti. Considera invece di chiuderlo, se vuoi tenerlo archiviato) issues.tracker=Cronografo +issues.start_tracking_short=Avvia timer issues.start_tracking=Avvia cronografo issues.start_tracking_history='ha iniziato a lavorare %s` issues.tracker_auto_close=Il timer verrà interrotto automaticamente una volta che il problema verrá chiuso +issues.tracking_already_started=`Hai già avviato il monitoraggio del tempo su un altro problema!` +issues.stop_tracking=Ferma timer issues.stop_tracking_history=`ha smesso di funzionare %s` +issues.cancel_tracking=Scarta issues.cancel_tracking_history=`ha cancellato il cronografo %s` issues.add_time=Aggiungi Tempo manualmente +issues.del_time=Elimina questo registro di tempo issues.add_time_short=Aggiungi tempo issues.add_time_cancel=Annulla issues.add_time_history=`aggiunto tempo trascorso %s` @@ -1117,6 +1414,7 @@ issues.error_modifying_due_date=Impossibile modificare la data di scadenza. issues.error_removing_due_date=Impossibile rimuovere la data di scadenza. issues.push_commit_1=aggiunto %d commit %s issues.push_commits_n=aggiunto %d commit %s +issues.force_push_codes=`force-pushed %[1]s from %[2]s to %[4]s %[6]s` issues.due_date_form=yyyy-mm-dd issues.due_date_form_add=Aggiungi data di scadenza issues.due_date_form_edit=Modifica @@ -1124,17 +1422,21 @@ issues.due_date_form_remove=Rimuovi issues.due_date_not_writer=E' necessario l'accesso di scrittura del repository per aggiornare la data di una sua issue. issues.due_date_not_set=Nessuna data di scadenza impostata. issues.due_date_added=la data di scadenza %s è stata aggiunta %s -issues.due_date_modified=data di scadenza modificata da %s a %s %s +issues.due_date_modified=ha modificato la data di scadenza da %[2]s a %[1]s %[3]s s issues.due_date_remove=rimossa la data di scadenza %s %s issues.due_date_overdue=Scaduto issues.due_date_invalid=La data di scadenza non è valida o fuori intervallo. Si prega di utilizzare il formato 'aaaa-mm-dd'. issues.dependency.title=Dipendenze +issues.dependency.issue_no_dependencies=Nessuna dipendenza impostata. +issues.dependency.pr_no_dependencies=Nessuna dipendenza impostata. issues.dependency.add=Aggiungi dipendenza… issues.dependency.cancel=Annulla issues.dependency.remove=Rimuovi issues.dependency.remove_info=Rimuovi questa dipendenza issues.dependency.added_dependency=`ha aggiunto una nuova dipendenza %s` issues.dependency.removed_dependency=`ha rimosso una dipendenza %s` +issues.dependency.pr_closing_blockedby=La chiusura di questa pull request è bloccata dai seguenti problemi +issues.dependency.issue_closing_blockedby=La chiusura di questo problema è bloccata dai seguenti problemi issues.dependency.issue_close_blocks=Questo problema impedisce la chiusura dei seguenti problemi issues.dependency.pr_close_blocks=Questa richiesta di pull impedisce la chiusura dei seguenti problemi issues.dependency.issue_close_blocked=Devi chiudere tutte le anomalie che bloiccano questo problema prima di chiudelo. @@ -1155,6 +1457,8 @@ issues.review.self.approval=Non puoi approvare la tua pull request. issues.review.self.rejection=Non puoi richiedere modifiche sulla tua pull request. issues.review.approve=hanno approvato queste modifiche %s issues.review.comment=revisionato %s +issues.review.dismissed=recensione %s di %s respinta +issues.review.dismissed_label=Respinta issues.review.left_comment=lascia un commento issues.review.content.empty=Devi lasciare un commento che indichi la modifica richiesta. issues.review.reject=richieste modifiche %s @@ -1163,8 +1467,10 @@ issues.review.add_review_request=recensione richiesta da %s %s issues.review.remove_review_request=ha rimosso la richiesta di revisione per %s %s issues.review.remove_review_request_self=ha rifiutato di rivedere %s issues.review.pending=In sospeso +issues.review.pending.tooltip=Questo commento non è attualmente visibile ad altri utenti. Per inviare i tuoi commenti in sospeso, seleziona '%s' -> '%s/%s/%s' nella parte superiore della pagina. issues.review.review=Revisiona issues.review.reviewers=Revisori +issues.review.outdated=Scaduto issues.review.show_outdated=Visualizza obsoleti issues.review.hide_outdated=Nascondere obsoleti issues.review.show_resolved=Mostra risolti @@ -1173,17 +1479,38 @@ issues.review.resolve_conversation=Risolvi la conversazione issues.review.un_resolve_conversation=Segnala la conversazione come non risolta issues.review.resolved_by=ha contrassegnato questa conversazione come risolta issues.assignee.error=Non tutte le assegnazioni sono state aggiunte a causa di un errore imprevisto. - +issues.reference_issue.body=Corpo +issues.content_history.deleted=eliminato +issues.content_history.edited=modificato +issues.content_history.created=creato +issues.content_history.delete_from_history=Elimina dalla cronologia +issues.content_history.delete_from_history_confirm=Eliminare dalla cronologia? +issues.content_history.options=Opzioni +issues.reference_link=Riferimento: %s + +compare.compare_base=base +compare.compare_head=confronta pulls.desc=Attiva pull request e revisioni di codice. pulls.new=Nuova Pull Request +pulls.view=Visualizza Pull Request pulls.compare_changes=Nuova Pull Request +pulls.allow_edits_from_maintainers=Consenti modifiche dai manutentori +pulls.allow_edits_from_maintainers_desc=Gli utenti con accesso in scrittura al ramo base possono anche inviare a questo ramo +pulls.allow_edits_from_maintainers_err=Aggiornamento non riuscito pulls.compare_changes_desc=Selezione il branch su cui eseguire il merge e il branch da cui eseguire il pull. +pulls.has_viewed_file=Visualizzato +pulls.has_changed_since_last_review=Modificato dalla tua ultima recensione +pulls.viewed_files_label=%[1]d / %[2]d file visti pulls.compare_base=unisci a pulls.compare_compare=esegui un pull da +pulls.switch_comparison_type=Cambia tipo di confronto +pulls.switch_head_and_base=Testa e base di commutazione pulls.filter_branch=Filtra branch pulls.no_results=Nessun risultato trovato. pulls.nothing_to_compare=Questi rami sono uguali. Non c'è alcuna necessità di creare una pull request. +pulls.nothing_to_compare_and_allow_empty_pr=Questi rami sono uguali. Questa PR sarà vuota. +pulls.has_pull_request=`Una pull request tra questi rami esiste già: %[2]s#%[3]d` pulls.create=Crea Pull Request pulls.title_desc=vorrebbe unire %[1]d commit da %[2]s a %[3]s pulls.merged_title_desc=ha unito %[1]d commit da %[2]s a %[3]s %[4]s @@ -1196,18 +1523,28 @@ pulls.cant_reopen_deleted_branch=Questa pull request non può essere riaperta pe pulls.merged=Unito pulls.merged_as=La pull request è stata unita come %[2]s. pulls.manually_merged=Unito manualmente +pulls.manually_merged_as=La pull request è stata unita manualmente come %[2]s. pulls.is_closed=La pull request è stata chiusa. pulls.has_merged=La pull request è stata unita. pulls.title_wip_desc=`Inizia il titolo con %s per evitare che la pull request venga unita accidentalmente.` +pulls.cannot_merge_work_in_progress=Questa pull request è contrassegnata come un lavoro in corso. +pulls.still_in_progress=Ancora in corso? +pulls.add_prefix=Aggiungi prefisso %s +pulls.remove_prefix=Rimuovi il prefisso %s pulls.data_broken=Questa pull request è rovinata a causa di informazioni mancanti del fork. pulls.files_conflicted=Questa pull request ha modifiche in conflitto con il branch di destinazione. pulls.is_checking=Verifica dei conflitti di merge in corso. Riprova tra qualche istante. +pulls.is_ancestor=Questo ramo è già incluso nel ramo di destinazione. Non c'è nulla da unire. +pulls.is_empty=Le modifiche di questo ramo sono già nel ramo di destinazione. Questo sarà un commit vuoto. pulls.required_status_check_failed=Alcuni controlli richiesti non hanno avuto successo. pulls.required_status_check_missing=Mancano alcuni controlli richiesti. pulls.required_status_check_administrator=Come amministratore, puoi ancora unire questa pull request. pulls.blocked_by_approvals=La richiesta Pull non ha abbastanza approvazioni. %d di %d approvazioni concesse. pulls.blocked_by_rejection=Questa Pull Request ha delle modifiche richieste da un revisore. +pulls.blocked_by_official_review_requests=Questa richiesta Pull ha richieste di recensione ufficiale. pulls.blocked_by_outdated_branch=Questa Pull Request è bloccata perché obsoleta. +pulls.blocked_by_changed_protected_files_1=Questa richiesta Pull è bloccata perché modifica un file protetto: +pulls.blocked_by_changed_protected_files_n=Questa richiesta Pull è bloccata perché modifica file protetti: pulls.can_auto_merge_desc=La pull request può essere unita automaticamente. pulls.cannot_auto_merge_desc=Questa pull request non può essere unita automaticamente a causa di conflitti. pulls.cannot_auto_merge_helper=Unire manualmente per risolvere i conflitti. @@ -1219,19 +1556,33 @@ pulls.reject_count_1=%d richiesta di cambiamento pulls.reject_count_n=%d richieste di cambiamento pulls.waiting_count_1=%d in attesa di revisione pulls.waiting_count_n=%d in attesa di revisione +pulls.wrong_commit_id=l'id del commit deve essere un id del commit nel branch di destinazione pulls.no_merge_desc=Questa pull request non può essere unita perché tutte le opzioni di merge del repository sono disattivate. pulls.no_merge_helper=Attiva le opzioni di merge nelle impostazioni del repository o unisci la pull request manualmente. pulls.no_merge_wip=Questa pull request non può essere unita perché è contrassegnata come un lavoro in corso. pulls.no_merge_not_ready=Questa pull request non è pronta per il merge, controlla lo stato della revisione e i controlli di stato. pulls.no_merge_access=Non sei autorizzato ad effettuare il merge su questa pull request. +pulls.merge_pull_request=Crea commit unito +pulls.rebase_merge_pull_request=Ricostruisci poi manda avanti +pulls.rebase_merge_commit_pull_request=Ricostruisci quindi crea commit unito +pulls.squash_merge_pull_request=Crea commit mescolato +pulls.merge_manually=Unito manualmente +pulls.merge_commit_id=L'ID del commit di merge pulls.require_signed_wont_sign=Il branch richiede commit firmati ma questo merge non verrà firmato pulls.invalid_merge_option=Non puoi utilizzare questa opzione di merge per questa pull request. +pulls.merge_conflict=Unione non riuscita: C'è stato un conflitto durante l'operazione. Suggerimento: Prova una strategia diversa pulls.merge_conflict_summary=Messaggio d'errore +pulls.rebase_conflict=Merge non riuscito: c'è stato un conflitto durante il rebase dell'commit: %[1]s. Suggerimento: Prova una strategia diversa +pulls.rebase_conflict_summary=Messaggio d'Errore ; %[2]s
%[3]s
pulls.unrelated_histories=Unione fallita: gli Head del ramo da unire e la base non condividono una storia cronologica in comune. Suggerimento: prova una strategia diversa pulls.merge_out_of_date=Unione fallita: Durante la generazione del merge, la base è stata aggiornata. Suggerimento: Riprova. +pulls.head_out_of_date=Unione non riuscita: durante la generazione della fusione, la testa è stata aggiornata. Suggerimento: Riprova. +pulls.push_rejected=Unisci non riuscito: il push è stato rifiutato. Rivedi gli Hooks Git per questo repository. +pulls.push_rejected_summary=Messaggio Di Rifiuto Completo +pulls.push_rejected_no_message=Unione non riuscita: il push è stato rifiutato ma non c'è stato un messaggio remoto.
Controlla gli Hooks di Git per questo repository pulls.open_unmerged_pull_exists=`Non è possibile riaprire questa pull request perché ne esiste un'altra (#%d) con proprietà identiche.` pulls.status_checking=Alcuni controlli sono in sospeso pulls.status_checks_success=Tutti i controlli sono stati effettuati con successo @@ -1240,13 +1591,31 @@ pulls.status_checks_failure=Alcuni controlli sono falliti pulls.status_checks_error=Alcuni controlli hanno segnalato errori pulls.status_checks_requested=Richiesto pulls.status_checks_details=Dettagli +pulls.update_branch=Aggiorna il ramo tramite merge +pulls.update_branch_rebase=Aggiorna il ramo per cambio base pulls.update_branch_success=Brench aggiornato con successo pulls.update_not_allowed=Non sei abilitato ad aggiornare il branch pulls.outdated_with_base_branch=Questo brench non è aggiornato con il branch di base +pulls.closed_at=`chiusa questa pull request %[2]s` +pulls.reopened_at=`riaperta questa pull request %[2]s` +pulls.merge_instruction_hint=`Puoi anche visualizzare le istruzioni da riga di comando.` +pulls.merge_instruction_step1_desc=Dal repository del tuo progetto, fai il check out di un nuovo branch e verifica le modifiche. +pulls.merge_instruction_step2_desc=Fai il merge delle modifiche e aggiorna su Gitea. +pulls.auto_merge_button_when_succeed=(Quando i controlli sono superati) +pulls.auto_merge_when_succeed=Unione automatica quando tutti i controlli sono superati +pulls.auto_merge_newly_scheduled=La pull request era programmata per unire quando tutti i controlli sono superati. +pulls.auto_merge_has_pending_schedule=%[1]s ha programmato questa pull request per unire automaticamente quando tutti i controlli hanno successo %[2]s. +pulls.auto_merge_cancel_schedule=Annulla fusione automatica +pulls.auto_merge_not_scheduled=Questa pull request non è programmata per la fusione automarica. +pulls.auto_merge_canceled_schedule=L'unione automatica è stata annullata per questa richiesta di pull. +pulls.auto_merge_newly_scheduled_comment=`ha programmato questa pull request per unire automaticamente quando tutti i controlli sono superati %[1]s` +pulls.auto_merge_canceled_schedule_comment=`cancella l'auto-merging di questa pull request quando tutti i testi sono superati %[1]s` +pulls.delete.title=Eliminare questa pull request? +pulls.delete.text=Vuoi davvero eliminare questo problema? (Questo rimuoverà permanentemente tutti i contenuti. Considera invece di chiuderlo, se vuoi tenerlo archiviato) milestones.new=Nuova Milestone milestones.closed=Chiuso %s @@ -1292,6 +1661,7 @@ signing.wont_sign.commitssigned=Questo merge non sarà firmato poiché i commit signing.wont_sign.approved=Il merge non sarà firmato poiché il PR non è approvato signing.wont_sign.not_signed_in=Non hai effettuato l'accesso +ext_wiki=Accesso al Wiki esterno ext_wiki.desc=Collegamento a una wiki esterna. wiki=Wiki @@ -1316,6 +1686,7 @@ wiki.page_already_exists=Esiste già una pagina Wiki con questo stesso nome. wiki.reserved_page=Il nome della pagina wiki '%s' è riservato. wiki.pages=Pagine wiki.last_updated=Ultimo aggiornamento: %s +wiki.page_name_desc=Inserisci un nome per questa pagina Wiki. Alcuni nomi speciali sono: 'Home', '_Sidebar' e '_Footer'. activity=Attività activity.period.filter_label=Periodo: @@ -1386,7 +1757,10 @@ activity.git_stats_deletion_n=%d cancellazioni search=Ricerca search.search_repo=Ricerca repository search.fuzzy=Fuzzy +search.match=Corrispondenze search.results=Risultati della ricerca per "%s" in %s +search.code_no_results=Nessun codice sorgente corrispondente al termine di ricerca trovato. +search.code_search_unavailable=Attualmente la ricerca di codice non è disponibile. Contatta l'amministratore del sito. settings=Impostazioni settings.desc=Impostazioni ti permette di gestire le impostazioni del repository @@ -1401,14 +1775,20 @@ settings.hooks=Webhooks settings.githooks=Git Hooks settings.basic_settings=Impostazioni di Base settings.mirror_settings=Impostazioni di mirror +settings.mirror_settings.docs=Configura il tuo progetto per inviare e/o ritirare automaticamente le modifiche a/da un altro repository. I rami, i tag e i commit verranno sincronizzati automaticamente. Come faccio i repository mirror? +settings.mirror_settings.mirrored_repository=Repository replicata +settings.mirror_settings.direction=Direzione +settings.mirror_settings.direction.pull=Tira +settings.mirror_settings.direction.push=Push +settings.mirror_settings.last_update=Ultimo aggiornamento +settings.mirror_settings.push_mirror.none=Nessun mirror push configurato +settings.mirror_settings.push_mirror.remote_url=Url Del Repository Remoto Git +settings.mirror_settings.push_mirror.add=Aggiungi Push Mirror settings.sync_mirror=Sincronizza ora settings.mirror_sync_in_progress=Sincronizzazione del mirror in corso. Torna tra qualche minuto. -settings.email_notifications.enable=Abilita Notifiche Email -settings.email_notifications.onmention=Solo email su Menzione -settings.email_notifications.disable=Disabilita notifiche email -settings.email_notifications.submit=Imposta Preferenze Email settings.site=Sito web settings.update_settings=Aggiorna Impostazioni +settings.branches.update_default_branch=Aggiorna Ramo Predefinito settings.advanced_settings=Opzioni avanzate settings.wiki_desc=Abilita Wiki Repository settings.use_internal_wiki=Utilizza la wiki incorporata @@ -1427,6 +1807,9 @@ settings.tracker_url_format_error=L'URL del tracker di problemi esterno non è u settings.tracker_issue_style=Formato numerico del tracciatore di issue esterno settings.tracker_issue_style.numeric=Numerico settings.tracker_issue_style.alphanumeric=Alfanumerico +settings.tracker_issue_style.regexp=Espressione Regolare +settings.tracker_issue_style.regexp_pattern=Motivo Espressione Regolare +settings.tracker_issue_style.regexp_pattern_desc=Il primo gruppo catturato verrà utilizzato al posto di {index}. settings.tracker_url_format_desc=Usa i segnaposto {user}, {repo} e {index} per il nome utente, il nome del repository e l'indice delle issue. settings.enable_timetracker=Abilita il cronografo settings.allow_only_contributors_to_track_time=Consenti soltanto ai contributori di utilizzare il cronografo @@ -1436,8 +1819,20 @@ settings.pulls.allow_merge_commits=Abilita il merging dei commit settings.pulls.allow_rebase_merge=Abilita l'unione dei commit mediante riassegnazione settings.pulls.allow_rebase_merge_commit=Abilita il rebase con commit ad unione esplicita (--no-ff) settings.pulls.allow_squash_commits=Abilita lo Squashing per unire i commits via merge +settings.pulls.allow_manual_merge=Abilita Mark PR come unito manualmente +settings.pulls.enable_autodetect_manual_merge=Abilita il rilevamento automatico della fusione manuale (Nota: in alcuni casi speciali possono verificarsi errori) +settings.pulls.allow_rebase_update=Abilita l'aggiornamento del ramo pull request per rebase +settings.pulls.default_delete_branch_after_merge=Elimina il ramo pull request dopo la fusione per impostazione predefinita +settings.packages_desc=Abilita Il Registro Dei Pacchetti Repository +settings.projects_desc=Abilita Progetti Repository settings.admin_settings=Impostazioni amministratore settings.admin_enable_health_check=Abilita verifica dell'integrità del repository (git fsck) +settings.admin_code_indexer=Indicizzatore del codice +settings.admin_stats_indexer=Indicizzatore di statistiche del codice +settings.admin_indexer_commit_sha=Hash SHA dell'ultimo commit indicizzato +settings.admin_indexer_unindexed=Non indicizzato +settings.reindex_button=Aggiungi alla coda di re-indicizzazione +settings.reindex_requested=Re-indicizzazione richiesta settings.admin_enable_close_issues_via_commit_in_any_branch=Chiudi un issue tramite un commit eseguito in un branch non predefinito settings.danger_zone=Zona Pericolosa settings.new_owner_has_same_repo=Il nuovo proprietario ha già un repository con lo stesso nome. Per favore scegli un altro nome. @@ -1452,11 +1847,20 @@ settings.convert_fork_notices_1=Questa operazione convertirà il fork in un norm settings.convert_fork_confirm=Converti Repository settings.convert_fork_succeed=Il fork è stato convertito in un repository regolare. settings.transfer=Trasferisci proprietà +settings.transfer.rejected=Il trasferimento del repository è stato rifiutato. +settings.transfer.success=Il trasferimento del repository è andato a buon fine. +settings.transfer_abort=Annulla trasferimento +settings.transfer_abort_invalid=Non è possibile annullare un trasferimento di repository non esistente. +settings.transfer_abort_success=Il trasferimento del repository a %s è stato annullato con successo. settings.transfer_desc=Trasferisci questo repository a un altro utente o a un'organizzazione nella quale hai diritti d'amministratore. settings.transfer_form_title=Inserisci il nome del repository come conferma: +settings.transfer_in_progress=Al momento c'è un trasferimento in corso. Si prega di annullarlo se si desidera trasferire questo repository a un altro utente. settings.transfer_notices_1=-Si perderà l'accesso al repository se lo si trasferisce ad un utente singolo. settings.transfer_notices_2=-Si manterrà l'accesso al repository se si trasferisce in un'organizzazione che possiedi (o condividi con qualcun'altro). +settings.transfer_notices_3=- Se il repository è privato e viene trasferito a un singolo utente, questa azione si assicura che l'utente abbia almeno i permessi di lettura (e le modifiche se necessario). settings.transfer_owner=Nuovo Proprietario +settings.transfer_perform=Esegui trasferimento +settings.transfer_started=Questo repository è stato contrassegnato per il trasferimento e attende conferma da "%s" settings.transfer_succeed=Il repository è stato trasferito. settings.signing_settings=Impostazioni Verifica Firma settings.trust_model=Modello di Fiducia per la Firma @@ -1466,6 +1870,11 @@ settings.trust_model.collaborator=Collaboratore settings.trust_model.collaborator.long=Collaboratore: Firme di fiducia da parte dei collaboratori settings.trust_model.collaborator.desc=Le firme valide da parte dei collaboratori di questo repository saranno contrassegnate con "trusted" (sia che corrispondano al committer o meno). Altrimenti, le firme valide saranno contrassegnate con "untrusted" se la firma corrisponde al committer e "unmatched" se non. settings.trust_model.committer=Committer +settings.trust_model.committer.long=Committer: firme affidabili che corrispondono ai committer (questo corrisponde a GitHub e costringerà i commit firmati di Gitea ad avere Gitea come committer) +settings.trust_model.committer.desc=Le firme valide saranno contrassegnate come "fidate" se corrispondono al committente, altrimenti saranno contrassegnate come "non corrispondono". Questo costringerà Gitea ad essere il committer dei commit firmati con l'effettivo committer contrassegnato come Co-Authored-By: e Co-Committed-By: nel commit. La chiave Gitea predefinita deve corrispondere a un utente nel database. +settings.trust_model.collaboratorcommitter=Collaboratore+Committer +settings.trust_model.collaboratorcommitter.long=Collaboratore+Committer: Firme di fiducia da parte dei collaboratori che corrispondono al committer +settings.trust_model.collaboratorcommitter.desc=Le firme valide da parte dei collaboratori di questa repository saranno contrassegnate "fidate" se corrispondono al committer. Altrimenti le firme saranno contrassegnate con "untrusted" se la firma corrisponde al committer non corrisponde. Questo costringerà Gitea a essere contrassegnato come committer su impegni firmati con l'effettivo committer contrassegnato come Co-Authored-By: e Co-Committed-By: nel commit. La chiave Gitea predefinita deve corrispondere a un utente nel database. settings.wiki_delete=Elimina dati Wiki settings.wiki_delete_desc=L'eliminazione dei dati della wiki del repository è permanente e non può essere annullata. settings.wiki_delete_notices_1=-Questa operazione eliminerà permanentemente e disabiliterà la wiki repository per %s. @@ -1496,6 +1905,8 @@ settings.add_team=Aggiungi Squadra settings.add_team_duplicate=Il team ha già il repository settings.add_team_success=Il team ha ora accesso al repository. settings.search_team=Cerca Squadra… +settings.change_team_permission_tip=Il permesso del team è impostato sulla pagina delle impostazioni del team e non può essere modificato per repository +settings.delete_team_tip=Questo team ha accesso a tutte le repository e non può essere rimosso settings.remove_team_success=L'accesso del team al repository è stato rimosso. settings.add_webhook=Aggiungi Webhook settings.add_webhook.invalid_channel_name=Il canale Webhook non può essere vuoto e contenere solo un # carattere. @@ -1510,6 +1921,9 @@ settings.webhook.response=Risposta settings.webhook.headers=Intestazioni settings.webhook.payload=Contenuto settings.webhook.body=Corpo +settings.webhook.replay.description=Riproduci questo webhook. +settings.webhook.delivery.success=Un evento è stato aggiunto alla coda di consegna. Potrebbe volerci qualche secondo prima che venga visualizzato nella cronologia delle consegne. +settings.githooks_desc=Git Hooks è alimentato da Git stesso. È possibile modificare i file hook qui sotto per impostare operazioni personalizzate. settings.githook_edit_desc=Se l'hook è inattivo, sarà presentato un contenuto esempio. Lasciando il contenuto vuoto disattiverai questo hook. settings.githook_name=Nome hook settings.githook_content=Contenuto hook @@ -1521,6 +1935,7 @@ settings.content_type=Tipo di contenuto POST settings.secret=Segreto settings.slack_username=Nome utente settings.slack_icon_url=URL icona +settings.slack_color=Colore settings.discord_username=Nome utente settings.discord_icon_url=URL icona settings.event_desc=Attivato su: @@ -1540,11 +1955,15 @@ settings.event_push=Push settings.event_push_desc=Git push in un repository. settings.event_repository=Repository settings.event_repository_desc=Repository creato o eliminato. +settings.event_header_issue=Eventi dei Problemi settings.event_issues=Issues settings.event_issues_desc=Issue aperto, chiuso, riaperto o modificato. settings.event_issue_assign=Issue Assegnato settings.event_issue_assign_desc=Issue assegnata o non assegnata. settings.event_issue_label=Issue etichettato +settings.event_issue_label_desc=Etichette dei Problemi aggiornate o cancellate. +settings.event_issue_milestone=Obiettivo Raggiunto +settings.event_issue_milestone_desc=Obiettivo raggiunto o abbandonato. settings.event_issue_comment=Commento Issue settings.event_issue_comment_desc=Commento issue creato, modificato o rimosso. settings.event_header_pull_request=Eventi di Pull Request @@ -1554,8 +1973,18 @@ settings.event_pull_request_assign=Pull Request assegnata settings.event_pull_request_assign_desc=Pull request assegnata o non assegnata. settings.event_pull_request_label=Pull Request etichettata settings.event_pull_request_label_desc=Etichette Pull request aggiornate o cancellate. +settings.event_pull_request_milestone=Pull Request raggiunta +settings.event_pull_request_milestone_desc=Pull request raggiunto o abbandonato. +settings.event_pull_request_comment=Commento su questa richiesta di pull +settings.event_pull_request_comment_desc=Commento della Pull request creato, modificato o cancellato. +settings.event_pull_request_review=Pull Request Revisionata +settings.event_pull_request_review_desc=Pull request approvata, respinta o recensione commento. +settings.event_pull_request_sync=Richiesta Pull Sincronizzata settings.event_pull_request_sync_desc=Pull request sincronizzata. +settings.event_package=Pacchetto +settings.event_package_desc=Pacchetto creato o eliminato in un repository. settings.branch_filter=Filtro branch +settings.branch_filter_desc=Whitelist dei rami per gli eventi di spinta, creazione dei rami e cancellazione dei rami, specificati come modello globo. Se vuoto o *, gli eventi per tutti i rami sono segnalati. Vedi la documentazione github.com/gobwas/glob per la sintassi. Esempi: master, {master,release*}. settings.active=Attivo settings.active_helper=Le informazioni sugli eventi innescati saranno inviate a questo URL del webhook. settings.add_hook_success=Il webhook è stato aggiunto. @@ -1567,6 +1996,23 @@ settings.hook_type=Tipo di Hook settings.slack_token=Gettone settings.slack_domain=Dominio settings.slack_channel=Canale +settings.add_web_hook_desc=Integra %s nel tuo repository. +settings.web_hook_name_gitea=Gitea +settings.web_hook_name_gogs=Gogs +settings.web_hook_name_slack=Slack +settings.web_hook_name_discord=Discord +settings.web_hook_name_dingtalk=DingTalk +settings.web_hook_name_telegram=Telegram +settings.web_hook_name_matrix=Matrix +settings.web_hook_name_msteams=Microsoft Teams +settings.web_hook_name_feishu_or_larksuite=Feishu / Lark Suite +settings.web_hook_name_feishu=Feishu +settings.web_hook_name_larksuite=Lark Suite +settings.web_hook_name_wechatwork=WeCom (Wechat Work) +settings.web_hook_name_packagist=Packagist +settings.packagist_username=Nome utente Packagist +settings.packagist_api_token=API token +settings.packagist_package_url=Url pacchetto pacchetti settings.deploy_keys=Dispiega Chiavi settings.add_deploy_key=Aggiungi Deploy Key settings.deploy_key_desc=Le deploy key possiedono l'accesso solamente alla lettura di un repository. @@ -1605,6 +2051,7 @@ settings.protect_merge_whitelist_committers_desc=Consentire soltanto agli utenti settings.protect_merge_whitelist_users=Utenti nella whitelist per il merging: settings.protect_merge_whitelist_teams=Team nella whitelist per il merging: settings.protect_check_status_contexts=Abilita Controllo Stato +settings.protect_check_status_contexts_desc=Richiedi il superamento di controlli di stato prima dell'unione di due rami. Scegliere quali controlli di stato devono passare prima che i rami possano essere uniti in un ramo che corrisponde a questa regola. Se abilitato, i commit devono prima essere inviati a un altro ramo, quindi uniti o pushati direttamente a un ramo che corrisponde a questa regola dopo aver superato i controlli di stato. Se non viene selezionato alcuna regola, l'ultimo commit avrá successo indipendentemente dal contesto. settings.protect_check_status_contexts_list=Controlli di stato trovati nell'ultima settimana per questo repository settings.protect_required_approvals=Approvazioni richieste: settings.protect_required_approvals_desc=Permetti solo di unire la richiesta pull con abbastanza recensioni positive. @@ -1615,6 +2062,11 @@ settings.protect_approvals_whitelist_teams=Team nella whitelist per le revisioni settings.dismiss_stale_approvals=Ignora impostazione vecchie settings.dismiss_stale_approvals_desc=Quando i nuovi commit che cambiano il contenuto della pull request vengono pushati nel branch, le vecchie approvazioni verranno eliminate. settings.require_signed_commits=Richiede commit firmati +settings.require_signed_commits_desc=Rifiuta i push a questo ramo se non sono firmati o verificabili. +settings.protect_protected_file_patterns=Modelli di file protetti (separati da punto e virgola '\;'): +settings.protect_protected_file_patterns_desc=File protetti che non possono essere modificati direttamente anche se l'utente ha i diritti di aggiungere, modificare o eliminare file in questo ramo. I modelli multipli possono essere separati usando il punto e virgola ('\;'). Vedi la documentazione github.com/gobwas/glob per la sintassi del modello. Esempi: .drone.yml, /docs/**/*.txt. +settings.protect_unprotected_file_patterns=Modelli di file non protetti (separati da punto e virgola '\;'): +settings.protect_unprotected_file_patterns_desc=File non protetti che possono essere modificati direttamente se l'utente ha accesso in scrittura, bypassando la restrizione push. Più modelli possono essere separati usando il punto e virgola ('\;'). Vedi la documentazione github.com/gobwas/glob per la sintassi del modello. Esempi: .drone.yml, /docs/**/*.txt. settings.add_protected_branch=Attiva protezione settings.delete_protected_branch=Disattiva protezione settings.update_protect_branch_success=La protezione branch per il branch '%s' è stata aggiornata. @@ -1623,11 +2075,26 @@ settings.protected_branch_deletion=Disattiva protezione branch settings.protected_branch_deletion_desc=Disattivare la protezione branch permette agli utenti con permesso di scrittura di pushare sul branch. Continuare? settings.block_rejected_reviews=Blocca il merge di revisioni rifiutate settings.block_rejected_reviews_desc=Il merge non sarà possibile quando sono richiesti cambiamenti da revisori, anche se ci sono sufficienti approvazioni. +settings.block_on_official_review_requests=Blocca il merge sulle richieste ufficiali di revisione +settings.block_on_official_review_requests_desc=Il merge non sarà possibile quando sono richiesti cambiamenti da revisori, anche se ci sono sufficienti approvazioni. +settings.block_outdated_branch=Blocca il merge se la pull request è obsoleta +settings.block_outdated_branch_desc=Il merging non sarà possibile quando il ramo testa è dietro il ramo base. settings.default_branch_desc=Seleziona un branch del repository predefinito per le pull request ed i commit di codice: +settings.default_merge_style_desc=Modalità di merge predefinita per le richieste di pull: settings.choose_branch=Scegli un branch… settings.no_protected_branch=Non ci sono branch protetti. settings.edit_protected_branch=Modifica settings.protected_branch_required_approvals_min=Le autorizzazioni richieste non possono essere negative. +settings.tags=Etichette +settings.tags.protection=Protezione Etichetta +settings.tags.protection.pattern=Sequenza Etichetta +settings.tags.protection.allowed=Consentito +settings.tags.protection.allowed.users=Utenti ammessi +settings.tags.protection.allowed.teams=Squadre ammesse +settings.tags.protection.allowed.noone=Nessuno +settings.tags.protection.create=Proteggi Etichetta +settings.tags.protection.none=Non ci sono etichette protette. +settings.tags.protection.pattern.description=È possibile utilizzare un singolo nome o un modello globo o un'espressione regolare per abbinare più tag. Leggi di più nella guida per i tag protetti. settings.bot_token=Token del Bot settings.chat_id=ID chat settings.matrix.homeserver_url=URL Homeserver @@ -1641,6 +2108,7 @@ settings.archive.success=Il repo è stato archiviato con successo. settings.archive.error=Si è verificato un errore durante il tentativo di archiviare il repo. Vedi il log per maggiori dettagli. settings.archive.error_ismirror=Non puoi archiviare un mirror repo. settings.archive.branchsettings_unavailable=Le impostazioni dei branch non sono disponibili se il repo è archiviato. +settings.archive.tagsettings_unavailable=Le impostazioni delle etichette non sono disponibili se il repo è archiviato. settings.unarchive.button=Non archiviare Repo settings.unarchive.header=Non archiviare questo Repo settings.unarchive.text=Dis-Archiviare la repository ripristinerà la sua capacità di ricevere commit e push, così come la creazione di nuovi problemi e richieste di pull. @@ -1672,6 +2140,12 @@ settings.lfs_pointers.inRepo=Nel repo settings.lfs_pointers.exists=Esiste nel negozio settings.lfs_pointers.accessible=Accessibile all'utente settings.lfs_pointers.associateAccessible=Associa %d OID accessibili +settings.rename_branch_failed_exist=Impossibile rinominare il ramo perché il ramo di destinazione %s esiste. +settings.rename_branch_failed_not_exist=Impossibile rinominare il ramo %s perché non esiste. +settings.rename_branch_success=Il ramo %s è stato rinominato con successo in %s. +settings.rename_branch_from=vecchio nome del ramo +settings.rename_branch_to=nuovo nome del ramo +settings.rename_branch=Rinomina ramo diff.browse_source=Sfoglia il codice sorgente diff.parent=parent @@ -1700,6 +2174,12 @@ diff.file_image_width=Larghezza diff.file_image_height=Altezza diff.file_byte_size=Dimensione diff.file_suppressed=File diff soppresso perché troppo grande +diff.file_suppressed_line_too_long=File diff soppresso perché una o più righe sono troppo lunghe +diff.too_many_files=Alcuni file non sono stati mostrati perché troppi file sono cambiati in questo diff +diff.show_more=Mostra Altro +diff.load=Carica Diff +diff.generated=generato +diff.vendored=esterno diff.comment.placeholder=Lascia un commento diff.comment.markdown_info=Lo stile con markdown è supportato. diff.comment.add_single_comment=Aggiungi un commento singolo @@ -1714,16 +2194,23 @@ diff.review.approve=Approva diff.review.reject=Richiedi cambiamenti diff.committed_by=committato da diff.protected=Protetto +diff.image.side_by_side=A fianco +diff.image.swipe=Scorri +diff.image.overlay=Sovrapposta +diff.has_escaped=Questa riga ha caratteri Unicode nascosti releases.desc=Tenere traccia di versioni e download del progetto. release.releases=Rilasci release.detail=Dettagli rilascio +release.tags=Etichette release.new_release=Nuovo Rilascio release.draft=Bozza release.prerelease=Pre-Rilascio release.stable=Stabile release.compare=Confronta release.edit=modifica +release.ahead.commits=%d commit +release.ahead.target=a %s da questa uscita release.source_code=Codice Sorgente release.new_subheader=Le release organizzano le versioni del progetto. release.edit_subheader=Le release organizzano le versioni del progetto. @@ -1739,13 +2226,20 @@ release.publish=Pubblica Rilascio release.save_draft=Salva Bozza release.edit_release=Aggiorna release release.delete_release=Elimina release +release.delete_tag=Elimina Etichetta release.deletion=Elimina release +release.deletion_desc=L'eliminazione di una release lo rimuove solo da Gitea. Il tag Git, i contenuti del repository e la cronologia rimangono invariati. Continuare? release.deletion_success=La release è stata eliminata. +release.deletion_tag_desc=Eliminerà questo tag dal repository. I contenuti del repository e la cronologia rimangono invariati. Continuare? release.deletion_tag_success=L'etichetta è stata eliminata. release.tag_name_already_exist=Una release con questo nome tag esiste già. release.tag_name_invalid=Il nome tag non è valido. +release.tag_name_protected=Il nome dell'etichetta è protetto. +release.tag_already_exist=Questo nome tag esiste già. release.downloads=Download release.download_count=Scarica: %s +release.add_tag_msg=Utilizzare il titolo e il contenuto del rilascio come messaggio di tag. +release.add_tag=Crea Solo Branch branch.name=Nome branch branch.search=Cerca branch @@ -1767,19 +2261,36 @@ branch.deleted_by=Eliminato da %s branch.restore_success=Il branch '%s' è stato ripristinato. branch.restore_failed=Impossibile ripristinare il branch '%s '. branch.protected_deletion_failed=Il branch '%s' è protetto. Non può essere eliminato. +branch.default_deletion_failed=Il branch '%s' è protetto. Non può essere eliminato. branch.restore=Ripristina Branch '%s' branch.download=Scarica Branch '%s' branch.included_desc=Questo ramo fa parte del ramo predefinito branch.included=Incluso +branch.create_new_branch=Crea un ramo dal ramo: +branch.confirm_create_branch=Crea ramo +branch.create_branch_operation=Crea ramo +branch.new_branch=Crea nuovo ramo +branch.new_branch_from=Crea un nuovo ramo da '%s' +branch.renamed=Il ramo %s è stato rinominato in %s. +tag.create_tag=Crea branch %s +tag.create_tag_operation=Crea etichetta +tag.confirm_create_tag=Crea etichetta +tag.create_tag_from=Crea un nuovo tag da '%s' +tag.create_success=Il branch '%s' è stato creato. topic.manage_topics=Gestisci argomenti topic.done=Fatto topic.count_prompt=Non puoi selezionare più di 25 argomenti topic.format_prompt=Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri. +find_file.go_to_file=Vai al file +find_file.no_matching=Nessun file corrispondente trovato +error.csv.too_large=Impossibile visualizzare questo file perché è troppo grande. +error.csv.unexpected=Impossibile visualizzare questo file perché contiene un carattere inatteso alla riga %d e alla colonna %d. +error.csv.invalid_field_count=Impossibile visualizzare questo file perché ha un numero errato di campi alla riga %d. [org] org_name_holder=Nome dell'Organizzazione @@ -1824,6 +2335,7 @@ settings.visibility.private_shortname=Privato settings.update_settings=Aggiorna Impostazioni settings.update_setting_success=Le impostazioni dell'organizzazione sono state aggiornate. settings.change_orgname_prompt=Nota: cambiare il nome dell'organizzazione cambia anche il relativo URL. +settings.change_orgname_redirect_prompt=Il vecchio nome reindirizzerà fino a quando non sarà richiesto. settings.update_avatar_success=L'avatar dell'organizzazione è stato aggiornato. settings.delete=Elimina organizzazione settings.delete_account=Elimina questa organizzazione @@ -1833,6 +2345,7 @@ settings.delete_org_title=Elimina organizzazione settings.delete_org_desc=Questa organizzazione verrà eliminata definitivamente. Continuare? settings.hooks_desc=Aggiungi i webhooks che verranno attivati per tutti i repository sotto questa organizzazione. +settings.labels_desc=Aggiungi i webhooks che verranno attivati per tutti i repository sotto questa organizzazione. members.membership_visibility=Visibilità appartenenza: members.public=Visibile @@ -1843,15 +2356,24 @@ members.member_role=Ruolo del membro: members.owner=Proprietario members.member=Membro members.remove=Rimuovi +members.remove.detail=Rimuovere %[1]s dalla %[2]s? members.leave=Abbandona +members.leave.detail=Lasciare %s? members.invite_desc=Aggiungi un nuovo membro a %s: members.invite_now=Invita ora teams.join=Iscriviti teams.leave=Abbandona +teams.leave.detail=Lasciare %s? teams.can_create_org_repo=Crea repository teams.can_create_org_repo_helper=I membri possono creare nuovi repository nell'organizzazione. Il creatore otterrà l'accesso di amministratore alla nuova repository. +teams.none_access=Nessun Accesso +teams.none_access_helper=I membri non possono visualizzare o fare altre azioni su questa unità. +teams.general_access=Accesso Generale +teams.general_access_helper=I permessi dei membri saranno decisi dalla seguente tabella dei permessi. +teams.read_access=Lettura teams.read_access_helper=I membri possono visualizzare e clonare i repository del team. +teams.write_access=Scrittura teams.write_access_helper=I membri possono leggere e pushare sui repository del team. teams.admin_access=Accesso amministratore teams.admin_access_helper=I membri possono pullare e pushare sulle repository del team e anche aggiungere collaboratori. @@ -1892,6 +2414,7 @@ dashboard=Pannello di Controllo users=Account utenti organizations=Organizzazioni repositories=Repository +hooks=Webhooks authentication=Fonti di autenticazione emails=Email Utente config=Configurazione @@ -1901,9 +2424,11 @@ first_page=Prima last_page=Ultima total=Totale: %d +dashboard.new_version_hint=Gitea %s è ora disponibile, stai eseguendo %s. Controlla il blog per maggiori dettagli. dashboard.statistic=Riepilogo dashboard.operations=Operazioni di manutenzione dashboard.system_status=Stato del sistema +dashboard.statistic_info=Il database Gitea contiene %d utenti, %d organizzazioni, %d chiavi pubbliche, %d depositi, %d orologi, %d stelle, ~%d azioni, %d accessi, %d problemi, %d commenti, %d conti sociali, %d seguono, %d specchi, %d rilasci, %d fonti di autenticazione, %d webhooks, %d pietre miliari, %d etichette, %d attività di aggancio, %d squadre, %d attività di aggiornamento, %d allegati. dashboard.operation_name=Nome Operazione dashboard.operation_switch=Cambia dashboard.operation_run=Esegui @@ -1915,24 +2440,34 @@ dashboard.task.cancelled=Compito: %[1]s annullato: %[3]s dashboard.task.error=Errore in Attività: %[1]s: %[3]s dashboard.task.finished=Compito: %[1]s iniziato da %[2]s ha finito dashboard.task.unknown=Attività sconosciuta: %[1]s +dashboard.cron.started=Cron Avviato: %[1]s dashboard.cron.process=Cron: %[1]s dashboard.cron.cancelled=Cron: %s cancellato: %[3]s dashboard.cron.error=Errore in Cron: %s: %[3]s dashboard.cron.finished=Cron: %[1]s ha finito dashboard.delete_inactive_accounts=Elimina tutti gli account non attivati dashboard.delete_inactive_accounts.started=Attività di eliminazione degli account non attivati iniziata. +dashboard.delete_repo_archives=Elimina tutti gli archivi dei repository (ZIP, TAR.GZ, etc..) dashboard.delete_repo_archives.started=Attività di eliminazione degli archivi del repository iniziata. dashboard.delete_missing_repos=Elimina tutti i repository mancanti dei loro file Git dashboard.delete_missing_repos.started=Elimina tutti i repository mancanti dei loro file Git. dashboard.delete_generated_repository_avatars=Elimina gli avatar generati nelle repository dashboard.update_mirrors=Aggiorna Mirror dashboard.repo_health_check=Controlla integrità di tutti i repository +dashboard.check_repo_stats=Controlla tutte le statistiche del repository dashboard.archive_cleanup=Elimina vecchi archivi del repository dashboard.deleted_branches_cleanup=Pulisci branch eliminati +dashboard.update_migration_poster_id=Aggiorna gli ID del poster di migrazione dashboard.git_gc_repos=Esegui la garbage collection su tutti i repository +dashboard.resync_all_sshkeys=Aggiornare il file '.ssh/authorized_keys' con le chiavi SSH Gitea. +dashboard.resync_all_sshkeys.desc=(Non necessario per il server SSH integrato.) +dashboard.resync_all_sshprincipals=Aggiornare il file '.ssh/authorized_keys' con le chiavi SSH Gitea. +dashboard.resync_all_sshprincipals.desc=(Non necessario per il server SSH integrato.) dashboard.resync_all_hooks=Sincronizza nuovamente gli hook di pre-ricezione, di aggiornamento e di post-ricezione di tutti i repository. dashboard.reinit_missing_repos=Reinizializza tutti i repository Git mancanti per i quali esistono cambiamenti registrati esistenti dashboard.sync_external_users=Sincronizza dati utente esterno +dashboard.cleanup_hook_task_table=Pulisci tabella hook_task +dashboard.cleanup_packages=Pulizia pacchetti scaduti dashboard.server_uptime=Tempo in Attività del Server dashboard.current_goroutine=Goroutine Correnti dashboard.current_memory_usage=Utilizzo di Memoria Corrente @@ -1962,6 +2497,10 @@ dashboard.total_gc_time=Pausa Totale della GC dashboard.total_gc_pause=Pausa Totale della GC dashboard.last_gc_pause=Ultima pausa della GC dashboard.gc_times=Esecuzioni GC +dashboard.delete_old_actions=Elimina tutte le vecchie azioni dal database +dashboard.delete_old_actions.started=Elimina tutte le vecchie azioni dal database iniziate. +dashboard.update_checker=Controllore dell'aggiornamento +dashboard.delete_old_system_notices=Elimina tutte le vecchie notifiche di sistema dal database users.user_manage_panel=Gestione account utente users.new_account=Crea account utente @@ -1996,9 +2535,26 @@ users.allow_import_local=Può importare repository locali users.allow_create_organization=Può creare organizzazioni users.update_profile=Aggiorna account utente users.delete_account=Elimina account utente +users.cannot_delete_self=Non puoi eliminare te stesso users.still_own_repo=Questo utente possiede ancora una o più repository. Eliminare o trasferire questi repository prima di continuare. users.still_has_org=Questo utente è membro di un'organizzazione. Rimuovi l'utente da tutte le organizzazioni prima di proseguire. +users.purge=Elimina Utente +users.purge_help=Eliminare forzatamente l'utente e tutti i depositi, le organizzazioni e i pacchetti di proprietà dell'utente. Tutti i commenti verranno eliminati troppo. +users.still_own_packages=Questo utente possiede ancora uno o più pacchetti. Elimina prima questi pacchetti. users.deletion_success=L'account utente è stato eliminato. +users.reset_2fa=Resetta 2FA +users.list_status_filter.menu_text=Filtro +users.list_status_filter.reset=Ripristina +users.list_status_filter.is_active=Attivo +users.list_status_filter.not_active=Inattivo +users.list_status_filter.is_admin=Amministratore +users.list_status_filter.not_admin=Non Amministratore +users.list_status_filter.is_restricted=Limitato +users.list_status_filter.not_restricted=Non Limitato +users.list_status_filter.is_prohibit_login=Divieto Di Login +users.list_status_filter.not_prohibit_login=Consenti Login +users.list_status_filter.is_2fa_enabled=2FA Abilitato +users.list_status_filter.not_2fa_enabled=2FA Disabilitato emails.email_manage_panel=Gestione delle Email Utente emails.primary=Primario @@ -2020,6 +2576,8 @@ orgs.members=Membri orgs.new_orga=Nuova Organizzazione repos.repo_manage_panel=Gestione Repository +repos.unadopted=Depositi Non Adottati +repos.unadopted.no_more=Nessun repository non adottato trovato repos.owner=Proprietario repos.name=Nome repos.private=Privati @@ -2029,9 +2587,24 @@ repos.forks=Fork repos.issues=Problemi repos.size=Dimensione - +packages.package_manage_panel=Gestione Pacchetti +packages.total_size=Dimensione totale: %s +packages.owner=Proprietario +packages.creator=Creatore +packages.name=Nome +packages.version=Versione +packages.type=Tipo +packages.repository=Repository +packages.size=Dimensione +packages.published=Pubblicata + +defaulthooks=Webhook predefiniti +defaulthooks.desc=I Webhooks effettuano automaticamente richieste HTTP POST ad un server quando si verificano determinati eventi Gitea. I Webhooks definiti qui sono predefiniti e verranno copiati in tutti i nuovi repository. Per saperne di più leggi la guida ai webhooks. +defaulthooks.add_webhook=Aggiungi Webhook predefinito +defaulthooks.update_webhook=Aggiorna Webhook predefinito systemhooks=Webhooks di Sistema +systemhooks.desc=I Webhooks effettuano automaticamente richieste HTTP POST ad un server quando si verificano determinati eventi Gitea. I Webhooks definiti qui agiranno su tutti i repository del sistema, quindi considera le eventuali implicazioni sulle performance che potrebbero avere. Per saperne di più leggi la guida ai webhooks. systemhooks.add_webhook=Aggiungi Webhook di Sistema systemhooks.update_webhook=Aggiorna Webhook di Sistema @@ -2058,6 +2631,7 @@ auths.attribute_name=Attributo nome auths.attribute_surname=Attributo cognome auths.attribute_mail=Attributo email auths.attribute_ssh_public_key=Attributo chiave SSH pubblica +auths.attribute_avatar=Attributo Avatar auths.attributes_in_bind=Estrai Attributi dal Contesto Bind DN auths.allow_deactivate_all=Consenti un risultato di ricerca vuoto per disattivare tutti gli utenti auths.use_paged_search=Utilizza ricerca per pagina @@ -2066,9 +2640,13 @@ auths.filter=Fitro utente auths.admin_filter=Filtro Amministratore auths.restricted_filter=Filtro riservato auths.restricted_filter_helper=Lasciare vuoto per non impostare alcun utente come limitato. Utilizzare un asterisco ('*') per impostare tutti gli utenti che non corrispondono al filtro amministratore. +auths.verify_group_membership=Verifica l'appartenenza al gruppo in LDAP (lascia vuoto il filtro per saltare) auths.group_search_base=Ricerca Gruppo Base DN auths.group_attribute_list_users=Gruppo Attributo Contenente Elenco Utenti auths.user_attribute_in_group=Attributo Utente Elencato nel Gruppo +auths.map_group_to_team=Mappa i gruppi LDAP alle squadre dell'organizzazione (lasciare vuoto il campo per saltare) +auths.map_group_to_team_removal=Rimuovi gli utenti dai team sincronizzati se l'utente non appartiene al gruppo LDAP corrispondente +auths.enable_ldap_groups=Abilita gruppi LDAP auths.ms_ad_sa=Attributi di ricerca AD MS auths.smtp_auth=Tipo di autenticazione SMTP auths.smtphost=Host SMTP @@ -2076,7 +2654,13 @@ auths.smtpport=Porta SMTP auths.allowed_domains=Domini consentiti auths.allowed_domains_helper=Lasciare vuoto per ammettere tutti i domini. Separare più domini con una virgola (','). auths.skip_tls_verify=Salta verifica TLS +auths.force_smtps=Forza SMTPS +auths.force_smtps_helper=SMTPS è sempre utilizzato sulla porta 465. Impostalo per forzare SMTPS su altre porte. (Otherwise STARTTLS sarà utilizzato su altre porte se è supportato dall'host.) +auths.helo_hostname=HELO nome dell'host +auths.helo_hostname_helper=Nome host inviato con HELO. Lasciare vuoto per inviare il nome host corrente. +auths.disable_helo=Disattiva HELO auths.pam_service_name=Nome del Servizio PAM +auths.pam_email_domain=Dominio Email PAM (opzionale) auths.oauth2_provider=OAuth2 Provider auths.oauth2_icon_url=URL icona auths.oauth2_clientID=ID Client (Chiave) @@ -2087,6 +2671,17 @@ auths.oauth2_tokenURL=URL token auths.oauth2_authURL=Autorizza URL auths.oauth2_profileURL=URL profilo auths.oauth2_emailURL=URL email +auths.skip_local_two_fa=Salta 2FA locale +auths.skip_local_two_fa_helper=Lasciare l'azzeramento significa che gli utenti locali con il set 2FA dovranno ancora passare 2FA per accedere +auths.oauth2_tenant=Comproprietà +auths.oauth2_scopes=Ambiti Aggiuntivi +auths.oauth2_required_claim_name=Nome Richiesto +auths.oauth2_required_claim_name_helper=Imposta questo nome per limitare il login da questa fonte agli utenti con un reclamo con questo nome +auths.oauth2_required_claim_value=Valore Richiesto +auths.oauth2_required_claim_value_helper=Imposta questo valore per limitare il login da questa fonte agli utenti con un reclamo con questo nome e valore +auths.oauth2_group_claim_name=Riscatta nome che fornisce nomi di gruppo per questa fonte (facoltativo) +auths.oauth2_admin_group=Valore del reclamo di gruppo per gli utenti amministratori. (Opzionale - richiede il nome della richiesta sopra) +auths.oauth2_restricted_group=Valore di reclamo di gruppo per utenti ristretti. (Facoltativo - richiede il nome di reclamo sopra) auths.enable_auto_register=Abilitare Registrazione Automatica auths.sspi_auto_create_users=Crea automaticamente gli utenti auths.sspi_auto_create_users_helper=Permetti al metodo di autenticazione SSPI di creare automaticamente nuovi account per gli utenti che accedono per la prima volta @@ -2103,6 +2698,7 @@ auths.tips.oauth2.general=Autenticazione OAuth2 auths.tips.oauth2.general.tip="Quando si registra una nuova autenticazione OAuth2, l'URL di callback/reindirizzamento deve essere:/user/oauth2//callback auths.tip.oauth2_provider=OAuth2 Provider auths.tip.bitbucket=Registra un nuovo cliente OAuth su https://bitbucket.org/account/user//oauth-consumers/new e aggiungi il permesso 'Account' - 'Read' +auths.tip.nextcloud=Registra un nuovo OAuth sulla tua istanza utilizzando il seguente menu "Impostazioni -> Sicurezza -> OAuth 2.0 client" auths.tip.dropbox=Crea una nuova applicazione su https://www.dropbox.com/developers/apps auths.tip.facebook=Registra una nuova applicazione su https://developers.facebook.com/apps e aggiungi il prodotto "Facebook Login" auths.tip.github=Registra una nuova applicazione OAuth su https://github.com/settings/applications/new @@ -2112,6 +2708,8 @@ auths.tip.openid_connect=Utilizza l'OpenID Connect Discovery URL (/.well auths.tip.twitter=Vai su https://dev.twitter.com/apps, crea una applicazione e assicurati che l'opzione "Allow this application to be used to Sign In with Twitter" sia abilitata auths.tip.discord=Registra una nuova applicazione su https://discordapp.com/developers/applications/me auths.tip.gitea=Registra una nuova applicazione OAuth2. La guida può essere trovata a https://docs.gitea.io/en-us/oauth2-provider/ +auths.tip.yandex=Crea una nuova applicazione su https://oauth.yandex.com/client/new. Seleziona i seguenti permessi da "Yandex. assport API": "Access to email address", "Access to user avatar" e "Access to username, name and surname, gender" +auths.tip.mastodon=Inserisci un URL di istanza personalizzato per l'istanza mastodon con cui vuoi autenticarti (o usa quella predefinita) auths.edit=Modifica fonte di autenticazione auths.activated=Questa fonte di autenticazione è attiva auths.new_success=L'autenticazione '%s' è stata aggiunta. @@ -2131,6 +2729,7 @@ config.app_ver=Versione Gitea config.app_url=URL di base di Gitea config.custom_conf=Percorso file di configurazione config.custom_file_root_path=Percorso Root File Personalizzato +config.domain=Dominio Server config.offline_mode=Modalità locale config.disable_router_log=Disattivare Log del Router config.run_user=Esegui come Nome utente @@ -2146,6 +2745,7 @@ config.reverse_auth_user=Autenticazione Utente Inversa config.ssh_config=Configurazione SSH config.ssh_enabled=Attivo config.ssh_start_builtin_server=Usa il server integrato +config.ssh_domain=Dominio Server Ssh config.ssh_port=Porta config.ssh_listen_port=Porta in ascolto config.ssh_root_path=Percorso Root @@ -2171,6 +2771,7 @@ config.db_path=Percorso config.service_config=Configurazione Servizio config.register_email_confirm=Richiedere la conferma Email per registrarsi config.disable_register=Disattiva Self-Registration +config.allow_only_internal_registration=Consenti la registrazione solo tramite Gitea stessa config.allow_only_external_registration=Attiva la registrazione solo tramite servizi esterni config.enable_openid_signup=Attiva OpenID Self-Registration config.enable_openid_signin=Attiva l'accesso tramite OpenID @@ -2195,15 +2796,19 @@ config.queue_length=Lunghezza della coda config.deliver_timeout=Tempo Limite di Consegna config.skip_tls_verify=Salta autenticazione TLS -config.mailer_config=Configurazione Mailer SMTP +config.mailer_config=Configurazione Mailer config.mailer_enabled=Attivo -config.mailer_disable_helo=Disattiva HELO +config.mailer_enable_helo=Abilita HELO config.mailer_name=Nome -config.mailer_host=Host +config.mailer_protocol=Protocollo +config.mailer_smtp_addr=Indirizzo SMTP +config.mailer_smtp_port=Porta SMTP config.mailer_user=Utente config.mailer_use_sendmail=Utilizza Sendmail config.mailer_sendmail_path=Percorso Sendmail config.mailer_sendmail_args=Argomenti aggiuntivi per Sendmail +config.mailer_sendmail_timeout=Timeout Sendmail +config.mailer_use_dummy=Dummy config.test_email_placeholder=Email (es. test@example.com) config.send_test_mail=Invia email di prova config.test_mail_failed=Impossibile inviare mail di prova a '%s': %v @@ -2263,12 +2868,16 @@ monitor.next=La Prossima Volta monitor.previous=La Scorsa Volta monitor.execute_times=Esecuzioni monitor.process=Processi in Esecuzione +monitor.stacktrace=Stacktraces +monitor.goroutines=%d Goroutines monitor.desc=Descrizione monitor.start=Orario Avvio monitor.execute_time=Tempo di Esecuzione +monitor.last_execution_result=Risultato monitor.process.cancel=Annulla processo monitor.process.cancel_desc=L'annullamento di un processo potrebbe causare la perdita di dati monitor.process.cancel_notices=Annulla: %s? +monitor.process.children=Figli monitor.queues=Code monitor.queue=Coda: %s monitor.queue.name=Nome @@ -2276,11 +2885,14 @@ monitor.queue.type=Tipo monitor.queue.exemplar=Tipo di esemplare monitor.queue.numberworkers=Numero di workers monitor.queue.maxnumberworkers=Massimo numero di Workers +monitor.queue.numberinqueue=Numero in coda monitor.queue.review=Rivedi configurazione monitor.queue.review_add=Rivedi/aggiungi Workers monitor.queue.configuration=Configurazione iniziale monitor.queue.nopool.title=Nessun pool di Workers monitor.queue.nopool.desc=Questa coda racchiude altre code al suo interno e non ha un proprio pool. +monitor.queue.wrapped.desc=Una coda a capo avvolge una coda iniziale lenta, le richieste in coda di buffering in un canale. Non ha un pool di lavoratori stesso. +monitor.queue.persistable-channel.desc=Un canale persistibile avvolge due code, una coda di canale che ha un proprio pool di operatori e una coda di livello per le richieste persistenti dagli arresti precedenti. Non ha un pool di operai. monitor.queue.pool.timeout=Timeout monitor.queue.pool.addworkers.title=Aggiungi Workers monitor.queue.pool.addworkers.submit=Aggiungi Workers @@ -2290,7 +2902,15 @@ monitor.queue.pool.addworkers.timeout.placeholder=Imposta 0 per non avere timeou monitor.queue.pool.addworkers.mustnumbergreaterzero=Il numero di Workers da aggiungere deve essere maggiore di zero monitor.queue.pool.addworkers.musttimeoutduration=Il timeout deve essere una durata golang, per esempio 5m o 0 monitor.queue.pool.flush.title=Pulisci Coda +monitor.queue.pool.flush.desc=Flush aggiungerà un worker che terminerà una volta che la coda sarà vuota, o il tempo sarà esaurito. monitor.queue.pool.flush.submit=Aggiungi un Flush Worker +monitor.queue.pool.flush.added=Flush Worker aggiunto per %[1]s +monitor.queue.pool.pause.title=Coda Di Pausa +monitor.queue.pool.pause.desc=La Pausa di una Coda impedirà all'elaborazione dei dati +monitor.queue.pool.pause.submit=Coda Di Pausa +monitor.queue.pool.resume.title=Riprendi Coda +monitor.queue.pool.resume.desc=Imposta questa coda per riprendere il lavoro +monitor.queue.pool.resume.submit=Riprendi Coda monitor.queue.settings.title=Impostazioni pool monitor.queue.settings.desc=I gruppi crescono dinamicamente con un boost in risposta al loro blocco delle code dei worker. Queste modifiche non influenzeranno i gruppi di worker attuali. @@ -2336,14 +2956,34 @@ notices.delete_success=Gli avvisi di sistema sono stati eliminati. [action] create_repo=ha creato il repository %s rename_repo=repository rinominato da %[1]s a [3]s +commit_repo=a inviato a %[3]s di %[4]s +create_issue=`ha aperto il problema %[3]s#%[2]s` +close_issue=`ha chiuso il problema %[3]s#%[2]s` +reopen_issue=`ha riaperto il problema %[3]s#%[2]s` +create_pull_request=`ha creato la pull request %[3]s#%[2]s` +close_pull_request=`ha chiuso la pull request %[3]s#%[2]s` +reopen_pull_request=`ha riaperto la pull request %[3]s#%[2]s` +comment_issue=`ha commentato sul problema %[3]s#%[2]s` +comment_pull=`ha commentato su pull request %[3]s#%[2]s` +merge_pull_request=`ha unito il pull request %[3]s#%[2]s` transfer_repo=repository %s trasferito in %s +push_tag=ha inviato il tag %[3]s su %[4]s delete_tag=tag eliminato %[2]s da %[3]s delete_branch=branch eliminato %[2]s da %[3]s compare_branch=Confronta compare_commits=Confronta %d commits compare_commits_general=Confronta commit +mirror_sync_push=ha sincronizzato i commit a %[3]s di %[4]s dal mirror +mirror_sync_create=ha sincronizzato un nuovo riferimento %[3]s su %[4]s dal mirror mirror_sync_delete=riferimento sincronizzato ed eliminato %[2]s a %[3]s dal mirror +approve_pull_request=`ha approvato %[3]s#%[2]s` +reject_pull_request=`ha suggerito modifiche per %[3]s#%[2]s` +publish_release=`ha rilasciato "%[4]s" su %[3]s` +review_dismissed=`respinta la recensione da %[4]s per %[3]s#%[2]s` review_dismissed_reason=Motivo: +create_branch=ha creato il ramo %[3]s in %[4]s +starred_repo=ha salvato come preferito %[2]s +watched_repo=ha iniziato a guardare %[2]s [tool] ago=%s fa @@ -2396,8 +3036,100 @@ error.probable_bad_signature=ATTENZIONE! Anche se esiste una chiave con questo I error.probable_bad_default_signature=ATTENZIONE! Anche se la chiave predefinita ha questo ID essa non verifica questo commit! Questo commit è SOSPETTO. [units] +unit=Unità error.no_unit_allowed_repo=Non possiedi il permesso di accedere ad alcuna sezione di questo repository. error.unit_not_allowed=Non possiedi il permesso di accedere a questa sezione di repository. [packages] +title=Pacchetti +desc=Gestisci pacchetti repository. +empty=Non ci sono ancora pacchetti. +empty.documentation=Per ulteriori informazioni sul registro dei pacchetti, consultare la documentazione. +empty.repo=Hai caricato un pacchetto, ma non è mostrato qui? Vai alle impostazioni del pacchetto e collegalo a questo repo. +filter.type=Tipo +filter.type.all=Tutti +filter.no_result=Il filtro non ha prodotto risultati. +filter.container.tagged=Etichettato +filter.container.untagged=Nont etichettato +published_by=Pubblicato %[1]s di %[3]s +published_by_in=Pubblicato %[1]s di %[3]s in %[5]s +installation=Installazione +about=Informazioni su questo pacchetto +requirements=Requisiti +dependencies=Dipendenze +keywords=Parole Chiave +details=Dettagli +details.author=Autore +details.project_site=Sito Del Progetto +details.license=Licenza +assets=Asset +versions=Versioni +versions.on=su +versions.view_all=Vedi tutti +dependency.id=ID +dependency.version=Versione +composer.registry=Imposta questo registro nel tuo file ~/.composer/config.json: +composer.install=Per installare il pacchetto utilizzando Composer, eseguire il seguente comando: +composer.documentation=Per ulteriori informazioni sul registro dei compositori, consultare la documentazione. +composer.dependencies=Dipendenze +composer.dependencies.development=Dipendenze Di Sviluppo +conan.details.repository=Repository +conan.registry=Configura questo registro dalla riga di comando: +conan.install=Per installare il pacchetto usando Conan, eseguire il seguente comando: +conan.documentation=Per ulteriori informazioni sul registro di Conan, consultare la documentazione. +container.details.type=Tipo Immagine +container.details.platform=Piattaforma +container.details.repository_site=Sito Repository +container.details.documentation_site=Sito Documentazione +container.pull=Tirare l'immagine dalla riga di comando: +container.documentation=Per ulteriori informazioni sul registro Container, vedere la documentazione. +container.multi_arch=OS / Arch +container.layers=Livelli Immagine +container.labels=Etichette +container.labels.key=Chiave +container.labels.value=Valore +generic.download=Scarica il pacchetto dalla riga di comando: +generic.documentation=Per ulteriori informazioni sul registro generico, consultare la documentazione. +helm.registry=Configura questo registro dalla riga di comando: +helm.install=Per installare il pacchetto, eseguire il seguente comando: +helm.documentation=Per ulteriori informazioni sul registro Helm, consultare la documentazione. +maven.registry=Configura questo registro nel file pom.xml del tuo progetto: +maven.install=Per utilizzare il pacchetto includere i seguenti nel blocco dipendenze nel file pom.xml: +maven.install2=Esegui tramite riga di comando: +maven.download=Per scaricare la dipendenza, eseguire tramite riga di comando: +maven.documentation=Per ulteriori informazioni sul registro Maven, consultare la documentazione. +nuget.registry=Configura questo registro dalla riga di comando: +nuget.install=Per installare il pacchetto utilizzando NuGet, eseguire il seguente comando: +nuget.documentation=Per ulteriori informazioni sul registro di NuGest, consultare la documentazione. +nuget.dependency.framework=Target Framework +npm.registry=Impostare questo registro nel file del progetto .npmrc: +npm.install=Per installare il pacchetto usando npm, eseguire il seguente comando: +npm.install2=o aggiungerlo al file package.json: +npm.documentation=Per ulteriori informazioni sul registro npm, vedere la documentazione. +npm.dependencies=Dipendenze +npm.dependencies.development=Dipendenze Di Sviluppo +npm.dependencies.peer=Dipendenze Peer +npm.dependencies.optional=Dipendenze Opzionali +npm.details.tag=Tag +pypi.requires=Richiede Python +pypi.install=Per installare il pacchetto usando pip, eseguire il seguente comando: +pypi.documentation=Per ulteriori informazioni sul registro PyPI, consultare la documentazione. +rubygems.install=Per installare il pacchetto usando gem, eseguire il seguente comando: +rubygems.install2=o aggiungerlo al file Gem: +rubygems.dependencies.runtime=Dipendenze Runtime +rubygems.dependencies.development=Dipendenze Di Sviluppo +rubygems.required.ruby=Richiede la versione di Ruby +rubygems.required.rubygems=Richiede la versione RubyGem +rubygems.documentation=Per ulteriori informazioni sul registro di RubyGems, vedere la documentazione. +settings.link=Collega questo pacchetto a un repository +settings.link.description=Se si collega un pacchetto a un repository, il pacchetto è elencato nell'elenco dei pacchetti del repository. +settings.link.select=Seleziona Repository +settings.link.button=Aggiorna Collegamento Repository +settings.link.success=Il link del repository è stato aggiornato correttamente. +settings.link.error=Impossibile aggiornare il link del repository. +settings.delete=Elimina pacchetto +settings.delete.description=L'eliminazione di un pacchetto è permanente e non può essere annullata. +settings.delete.notice=Stai per eliminare %s (%s). Questa operazione è irreversibile, sei sicuro? +settings.delete.success=Il pacchetto è stato eliminato. +settings.delete.error=Impossibile eliminare il pacchetto. diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini index 748715f4364ce..08edc0f034f82 100644 --- a/options/locale/locale_ja-JP.ini +++ b/options/locale/locale_ja-JP.ini @@ -179,7 +179,6 @@ log_root_path_helper=ログファイルがこのディレクトリに書き込 optional_title=オプション設定 email_title=メール設定 -smtp_host=SMTPホスト smtp_from=メール送信者 smtp_from_helper=Giteaが使用するメールアドレス。 メールアドレスのみ、または、 "名前" の形式で入力してください。 mailer_user=SMTPユーザー名 @@ -799,6 +798,7 @@ email_notifications.enable=メール通知有効 email_notifications.onmention=メンションのみメール通知 email_notifications.disable=メール通知無効 email_notifications.submit=メール設定を保存 +email_notifications.andyourown=自分に関する通知も含める visibility=ユーザーの公開範囲 visibility.public=パブリック @@ -1532,7 +1532,8 @@ pulls.remove_prefix=先頭の %s を除去 pulls.data_broken=このプルリクエストは、フォークの情報が見つからないため壊れています。 pulls.files_conflicted=このプルリクエストは、ターゲットブランチと競合する変更を含んでいます。 pulls.is_checking=マージのコンフリクトを確認中です。 少し待ってからもう一度実行してください。 -pulls.is_empty=このブランチの内容はターゲットブランチと同じです。 +pulls.is_ancestor=このブランチは既にターゲットブランチに含まれています。マージするものはありません。 +pulls.is_empty=このブランチの変更は既にターゲットブランチにあります。これは空のコミットになります。 pulls.required_status_check_failed=いくつかの必要なステータスチェックが成功していません。 pulls.required_status_check_missing=必要なステータスチェックが見つかりません。 pulls.required_status_check_administrator=管理者であるため、このプルリクエストをマージすることは可能です。 @@ -1783,10 +1784,6 @@ settings.mirror_settings.push_mirror.remote_url=リモートGitリポジトリ settings.mirror_settings.push_mirror.add=プッシュミラーを追加 settings.sync_mirror=今すぐ同期 settings.mirror_sync_in_progress=ミラー同期を実行しています。 しばらくあとでまた確認してください。 -settings.email_notifications.enable=メール通知有効 -settings.email_notifications.onmention=メンションのみメール通知 -settings.email_notifications.disable=メール通知無効 -settings.email_notifications.submit=メール設定を保存 settings.site=Webサイト settings.update_settings=設定を更新 settings.branches.update_default_branch=デフォルトブランチを更新 @@ -2539,6 +2536,8 @@ users.delete_account=ユーザーアカウントを削除 users.cannot_delete_self=自分自身を削除することはできません users.still_own_repo=このユーザーはまだ1つ以上のリポジトリを所有しています。 先にそれらのリポジトリを削除するか移転してください。 users.still_has_org=このユーザーは組織のメンバーになっています。 先に組織からこのユーザーを削除してください。 +users.purge=ユーザーを抹消 +users.purge_help=強制的にユーザーとそのユーザーが所有していたリポジトリ、組織、パッケージを削除します。コメントもすべて削除します。 users.still_own_packages=このユーザーはまだ1つ以上のパッケージを所有しています。最初にそれらのパッケージを削除してください。 users.deletion_success=ユーザーアカウントを削除しました。 users.reset_2fa=2要素認証をリセット @@ -2795,16 +2794,19 @@ config.queue_length=キューの長さ config.deliver_timeout=送信タイムアウト config.skip_tls_verify=TLS検証を省略 -config.mailer_config=SMTPメーラーの設定 +config.mailer_config=メーラー設定 config.mailer_enabled=有効 -config.mailer_disable_helo=HELOコマンド無効 +config.mailer_enable_helo=HELO有効 config.mailer_name=名称 -config.mailer_host=ホスト +config.mailer_protocol=プロトコル +config.mailer_smtp_addr=SMTPアドレス +config.mailer_smtp_port=SMTPポート config.mailer_user=ユーザー config.mailer_use_sendmail=Sendmailを使う config.mailer_sendmail_path=Sendmailのパス config.mailer_sendmail_args=Sendmailの追加引数 config.mailer_sendmail_timeout=Sendmail のタイムアウト +config.mailer_use_dummy=Dummy config.test_email_placeholder=Email (例 test@example.com) config.send_test_mail=テストメールを送信 config.test_mail_failed='%s' へのテストメール送信に失敗しました: %v @@ -3041,6 +3043,7 @@ title=パッケージ desc=リポジトリ パッケージを管理します。 empty=パッケージはまだありません。 empty.documentation=パッケージレジストリの詳細については、 ドキュメント を参照してください。 +empty.repo=パッケージはアップロードしたけども、ここに表示されない? パッケージ設定を開いて、パッケージをこのリポジトリにリンクしてください。 filter.type=タイプ filter.type.all=すべて filter.no_result=フィルタの結果、空になりました。 diff --git a/options/locale/locale_ko-KR.ini b/options/locale/locale_ko-KR.ini index 7c8754080d7b8..002007508c9bc 100644 --- a/options/locale/locale_ko-KR.ini +++ b/options/locale/locale_ko-KR.ini @@ -126,7 +126,6 @@ log_root_path_helper=로그파일은 이 디렉토리에 저장됩니다. optional_title=추가설정 email_title=이메일 설정 -smtp_host=SMTP 호스트 smtp_from=이메일 발신인 smtp_from_helper=Gitea 가 사용할 이메일 주소. 이메일 주소 또는 "이름" 형식으로 입력하세요. mailer_user=SMTP 사용자이름 @@ -807,7 +806,6 @@ issues.due_date_form_remove=삭제 issues.due_date_not_writer=이슈의 마감일을 갱신하려면 저장소 쓰기 권한이 필요합니다. issues.due_date_not_set=마감일이 설정되지 않았습니다. issues.due_date_added=마감일 %s 를 추가 %s -issues.due_date_modified=%s 마감일이 %s %s 로 변경되었습니다 issues.due_date_remove=%s %s 마감일이 삭제되었습니다. issues.due_date_overdue=기한 초과 issues.due_date_invalid=기한이 올바르지 않거나 범위를 벗어났습니다. 'yyyy-mm-dd'형식을 사용해주십시오. @@ -971,8 +969,6 @@ settings.basic_settings=기본 설정 settings.mirror_settings=미러 설정 settings.sync_mirror=지금 동기화 settings.mirror_sync_in_progress=미러 동기화 진행중입니다. 잠시 후 다시 확인해주십시오. -settings.email_notifications.enable=이메일 알림 켜기 -settings.email_notifications.disable=이메일 알림 끄기 settings.site=웹 사이트 settings.update_settings=설정 저장 settings.advanced_settings=고급 설정 @@ -1453,11 +1449,8 @@ config.queue_length=큐 길이 config.deliver_timeout=시간 제한 사용 config.skip_tls_verify=TLS 검증 건너뛰기 -config.mailer_config=SMTP 메일러 설정 config.mailer_enabled=활성화됨 -config.mailer_disable_helo=HELO 비활성화 config.mailer_name=이름 -config.mailer_host=호스트 config.mailer_user=사용자 config.mailer_use_sendmail=Sendmail 사용 config.mailer_sendmail_path=Sendmail 경로 diff --git a/options/locale/locale_lv-LV.ini b/options/locale/locale_lv-LV.ini index b87202e2b6707..ac7da8dd17600 100644 --- a/options/locale/locale_lv-LV.ini +++ b/options/locale/locale_lv-LV.ini @@ -179,7 +179,8 @@ log_root_path_helper=Žurnalizēšanas faili tiks rakstīti šajā direktorijā. optional_title=Neobligātie iestatījumi email_title=E-pastu iestatījumi -smtp_host=SMTP resursdators +smtp_addr=SMTP resursdators +smtp_port=SMTP ports smtp_from=Nosūtīt e-pastu kā smtp_from_helper=E-pasta adrese, ko Gitea izmantos. Ievadiet tika e-pasta adrese vai izmantojiet "Vārds" formātu. mailer_user=SMTP lietotāja vārds @@ -799,6 +800,7 @@ email_notifications.enable=Iespējot e-pasta paziņojumus email_notifications.onmention=Tikai, ja esmu pieminēts email_notifications.disable=Nesūtīt paziņojumus email_notifications.submit=Saglabāt sūtīšanas iestatījumus +email_notifications.andyourown=Iekļaut savus paziņojumus visibility=Lietotāja redzamība visibility.public=Publisks @@ -861,7 +863,9 @@ default_branch=Noklusējuma atzars default_branch_helper=Noklusētais atzars nosaka pamata atzaru uz kuru tiks veidoti izmaiņu pieprasījumi un koda revīziju iesūtīšana. mirror_prune=Izmest mirror_prune_desc=Izdzēst visas ārējās atsauces, kas ārējā repozitorijā vairs neeksistē +mirror_interval=Spoguļošanas intervāls (derīgas laika vienības ir 'h', 'm', 's'). Norādiet 0, lai atslēgtu periodisku spoguļošanu. (Minimālais intervāls: %s) mirror_interval_invalid=Nekorekts spoguļošanas intervāls. +mirror_sync_on_commit=Sinhronizēt, kad revīzijas tiek iesūtītas mirror_address=Spoguļa adrese mirror_address_desc=Pieslēgšanās rekvizītus norādiet autorizācijas sadaļā. mirror_address_url_invalid=Norādītais URL nav korekts. Norādiet visas URL daļas korekti. @@ -930,6 +934,7 @@ form.name_pattern_not_allowed=Repozitorija nosaukums '%s' nav atļauts. need_auth=Autorizācija migrate_options=Migrācijas opcijas migrate_service=Migrācijas serviss +migrate_options_mirror_helper=Šis repozitorijs būs spogulis migrate_options_lfs=Migrēt LFS failus migrate_options_lfs_endpoint.label=LFS galapunkts migrate_options_lfs_endpoint.description=Migrācija mēģinās izmantot attālināto URL, lai noteiktu LFS serveri. Var norādīt arī citu galapunktu, ja repozitorija LFS dati ir izvietoti citā vietā. @@ -1300,6 +1305,7 @@ issues.previous=Iepriekšējā issues.next=Nākamā issues.open_title=Atvērta issues.closed_title=Slēgta +issues.draft_title=Melnraksts issues.num_comments=%d komentāri issues.commented_at=` komentēja %s` issues.delete_comment_confirm=Vai patiešām vēlaties dzēst šo komentāru? @@ -1416,7 +1422,7 @@ issues.due_date_form_remove=Noņemt issues.due_date_not_writer=Jums ir nepieciešamas rakstīšanas tiesības uz šo repozitoriju, lai mainītu izpildes termiņu. issues.due_date_not_set=Izpildes termiņš nav uzstādīts. issues.due_date_added=pievienoja izpildes termiņu %s %s -issues.due_date_modified=mainīja izpildes termiņu uz %s no %s %s +issues.due_date_modified=mainīja termiņa datumu no %[2]s uz %[1]s %[3]s issues.due_date_remove=noņēma izpildes termiņu %s %s issues.due_date_overdue=Nokavēts issues.due_date_invalid=Datums līdz nav korekts. Izmantojiet formātu 'gggg-mm-dd'. @@ -1528,7 +1534,8 @@ pulls.remove_prefix=Noņemt %s prefiksu pulls.data_broken=Izmaiņu pieprasījums ir bojāts, jo dzēsta informācija no atdalītā repozitorija. pulls.files_conflicted=Šīs izmaiņu pieprasījuma izmaiņas konfliktē ar mērķa atzaru. pulls.is_checking=Notiek konfliktu pārbaude, mirkli uzgaidiet un atjaunojiet lapu. -pulls.is_empty=Šis atzars ir vienāds ar mērķa atzaru. +pulls.is_ancestor=Atzars jau ir pilnībā iekļauts mērķā atzarā. Nav izmaiņu, ko sapludināt. +pulls.is_empty=Mērķa atzars jau satur šī atzara izmaiņas. Šī revīzija būs tukša. pulls.required_status_check_failed=Dažas no pārbaudēm nebija veiksmīgas. pulls.required_status_check_missing=Trūkst dažu obligāto pārbaužu. pulls.required_status_check_administrator=Kā administrators Jūs varat sapludināt šo izmaiņu pieprasījumu. @@ -1607,6 +1614,8 @@ pulls.auto_merge_canceled_schedule=Automātiskā sapludināšana šim izmaiņu p pulls.auto_merge_newly_scheduled_comment=`ieplānoja automātisko sapludināšanu šim izmaiņu pieprasījumam, kad visas pārbaudes būs veiksmīgas %[1]s` pulls.auto_merge_canceled_schedule_comment=`atcēla automātisko sapludināšanu šim izmaiņu pieprasījumam %[1]s` +pulls.delete.title=Dzēst šo izmaiņu pieprasījumu? +pulls.delete.text=Vai patiešām vēlaties dzēst šo izmaiņu pieprasījumu? (Neatgriezeniski tiks izdzēsts viss saturs. Apsveriet iespēju to aizvērt, ja vēlaties informāciju saglabāt vēsturei) milestones.new=Jauns atskaites punkts milestones.closed=Aizvērts %s @@ -1777,10 +1786,6 @@ settings.mirror_settings.push_mirror.remote_url=Git attālinātā repozitorija U settings.mirror_settings.push_mirror.add=Pievienot iesūtīšanas spoguli settings.sync_mirror=Sinhronizēt tagad settings.mirror_sync_in_progress=Notiek spoguļa sinhronizācija. Atjaunojiet lapu, lai pārbaudītu atkārtoti, pēc brīža. -settings.email_notifications.enable=Iespējot e-pasta paziņojumus -settings.email_notifications.onmention=Tikai, ja esmu pieminēts -settings.email_notifications.disable=Nesūtīt paziņojumus -settings.email_notifications.submit=Saglabāt sūtīšanas iestatījumus settings.site=Mājas lapa settings.update_settings=Mainīt iestatījumus settings.branches.update_default_branch=Atjaunot noklusēto atzaru @@ -2533,6 +2538,8 @@ users.delete_account=Dzēst lietotāja kontu users.cannot_delete_self=Nevar izdzēst sevi users.still_own_repo=Lietotājam pieder repozitoriji, tos sākumā ir nepieciešams izdzēst vai mainīt to īpašnieku. users.still_has_org=Šis lietotājs ir vienas vai vairāku organizāciju biedrs, lietotāju sākumā ir nepieciešams pamest šīs organizācijas vai viņu no tām ir jāizdzēš. +users.purge=Attīrīt lietotu +users.purge_help=Piespiedu dzēst lietotāju un visus tā repozitorijus, organizācijas un pakotnes. Arī visi lietotāja komentāri tiks dzēsti. users.still_own_packages=Šim lietotājam pieder viena vai vairākas pakotnes. Tās nepieciešams izdzēst. users.deletion_success=Lietotāja konts veiksmīgi izdzēsts. users.reset_2fa=Noņemt 2FA @@ -2789,16 +2796,19 @@ config.queue_length=Rindas garums config.deliver_timeout=Piegādes noildze config.skip_tls_verify=Izlaist TLS pārbaudi -config.mailer_config=SMTP sūtītāja konfigurācija +config.mailer_config=Pasta sūtītāja konfigurācija config.mailer_enabled=Iespējota -config.mailer_disable_helo=Atspējot HELO +config.mailer_enable_helo=Iespējot HELO config.mailer_name=Nosaukums -config.mailer_host=Resursdators +config.mailer_protocol=Protokols +config.mailer_smtp_addr=SMTP adrese +config.mailer_smtp_port=SMTP ports config.mailer_user=Lietotājs config.mailer_use_sendmail=Izmantot Sendmail config.mailer_sendmail_path=Ceļš līdz sendmail programmai config.mailer_sendmail_args=Papildus Sendmail komandrindas argumenti config.mailer_sendmail_timeout=Sendmail noildze +config.mailer_use_dummy=Tukšs config.test_email_placeholder=E-pasts (piemēram, test@example.com) config.send_test_mail=Nosūtīt pārbaudes e-pastu config.test_mail_failed=Neizdevās nosūtīt pārbaudes e-pastu uz '%s': %v @@ -3035,6 +3045,7 @@ title=Pakotnes desc=Pārvaldīt repozitorija pakotnes. empty=Pašlaik šeit nav nevienas pakotnes. empty.documentation=Papildus informācija par pakotņu reģistru pieejama dokumentācijā. +empty.repo=Neparādās augšupielādēta pakotne? Apmeklējiet pakotņu iestatījumus, lai sasaistītu ar repozitoriju. filter.type=Veids filter.type.all=Visas filter.no_result=Pēc norādītajiem kritērijiem nekas netika atrasts. diff --git a/options/locale/locale_ml-IN.ini b/options/locale/locale_ml-IN.ini index 27e4f11279388..5befd50bbfdc1 100644 --- a/options/locale/locale_ml-IN.ini +++ b/options/locale/locale_ml-IN.ini @@ -112,7 +112,6 @@ log_root_path_helper=ലോഗ് ഫയലുകൾ ഈ ഡയറക്ടറ optional_title=ഐച്ഛികമായ ക്രമീകരണങ്ങൾ email_title=ഇമെയിൽ ക്രമീകരണങ്ങൾ -smtp_host=SMTP ഹോസ്റ്റ് smtp_from=ഈ വിലാസത്തില്‍ ഇമെയിൽ അയയ്‌ക്കുക smtp_from_helper=ഗിറ്റീ ഉപയോഗിയ്ക്കുന്ന ഇമെയില്‍ വിലാസം. ഒരു സാധാ ഇമെയിൽ വിലാസം നൽകുക അല്ലെങ്കിൽ "പേര്" എന്ന ഘടന ഉപയോഗിക്കുക. mailer_user=SMTP ഉപയോക്തൃനാമം diff --git a/options/locale/locale_nl-NL.ini b/options/locale/locale_nl-NL.ini index ccdf978800895..99857b96e12d8 100644 --- a/options/locale/locale_nl-NL.ini +++ b/options/locale/locale_nl-NL.ini @@ -2,6 +2,7 @@ home=Beginscherm dashboard=Overzicht explore=Verkennen help=Help +logo=Logo sign_in=Inloggen sign_in_with=Inloggen met sign_out=Uitloggen @@ -25,7 +26,7 @@ licenses=Licenties return_to_gitea=Terug naar Gitea username=Gebruikersnaam -email=E-mail adres +email=E-mailadres password=Wachtwoord access_token=Toegangstoken re_type=Typ uw wachtwoord opnieuw in @@ -34,6 +35,19 @@ twofa=Twee factor authenticatie twofa_scratch=Eenmalige twee factor authenticatie code passcode=PIN +webauthn_insert_key=Voer uw beveiligingssleutel in +webauthn_sign_in=Druk op de knop van uw beveiligingssleutel. Als uw beveiligingssleutel geen knop heeft, voeg deze dan opnieuw in. +webauthn_press_button=Druk alstublieft op de knop van uw beveiligingssleutel… +webauthn_use_twofa=Gebruik een twee-factor code van uw telefoon +webauthn_error=Kon uw beveiligingssleutel niet lezen. +webauthn_unsupported_browser=Uw browser ondersteunt momenteel geen WebAuthn. +webauthn_error_unknown=Er is een onbekende fout opgetreden. Probeer het opnieuw. +webauthn_error_insecure=WebAuthn ondersteunt alleen beveiligde verbindingen. Om te testen via HTTP, kan je de oorsprong "localhost" of "127.0.0.1" gebruiken +webauthn_error_unable_to_process=De server kon uw verzoek niet verwerken. +webauthn_error_duplicated=De beveiligingssleutel is niet toegestaan voor dit verzoek. Zorg er alstublieft voor dat de sleutel niet al geregistreerd is. +webauthn_error_empty=U moet een naam voor deze sleutel instellen. +webauthn_error_timeout=Time-out bereikt voordat uw sleutel kon worden gelezen. Laad deze pagina opnieuw en probeer het opnieuw. +webauthn_reload=Vernieuwen repository=Repository organization=Organisatie @@ -55,7 +69,7 @@ your_settings=Instellingen all=Alles sources=Bronnen -mirrors=Kopieën +mirrors=Spiegels collaborative=Samenwerkend forks=Forks @@ -74,6 +88,7 @@ remove_all=Alles verwijderen edit=Bewerk copy=Kopieer +copy_url=Kopieer URL copy_branch=Kopieer branchnaam copy_success=Gekopieerd! copy_error=Kopiëren mislukt @@ -90,9 +105,15 @@ error404=De pagina die u probeert te bereiken bestaat niet of < never=Nooit +rss_feed=RSS Feed [error] +occurred=Er is een fout opgetreden +report_message=Als je zeker weet dat dit een Gitea bug is, zoek dan naar problemen op GitHub of open een nieuw probleem indien nodig. missing_csrf=Foutief verzoek: geen CSRF-token aanwezig +invalid_csrf=Verkeerd verzoek: ongeldig CSRF-token +not_found=Het doel kon niet worden gevonden. +network_error=Netwerk fout [startpage] app_desc=Een eenvoudige, self-hosted Git service @@ -109,6 +130,7 @@ license_desc=Alles staat op documentatie voordat je een instelling aanpast. +require_db_desc=Gitea vereist MySQL, PostgreSQL, MSSQL, SQLite3 of TiDB (MySQL protocol). db_title=Database-instellingen db_type=Database-type host=Server @@ -122,10 +144,15 @@ ssl_mode=SSL charset=Karakterset path=Pad sqlite_helper=Bestandspad voor de SQLite3-database.
Vul een volledig pad in als je GItea als een service uitvoert. +reinstall_error=U probeert te installeren in een bestaande Gitea database +reinstall_confirm_message=Herinstalleren met een bestaande Gitea-database kan meerdere problemen veroorzaken. In de meeste gevallen kun je het bestaande "app.ini" gebruiken om Gitea te laten draaien. Als je weet wat je aan het doen bent, bevestig dan het volgende: +reinstall_confirm_check_1=De gegevens versleuteld door de SECRET_KEY in de app.ini kan verloren gaan: gebruikers kunnen mogelijk niet meer inloggen met 2FA/OTP & spiegels werken mogelijk niet meer. Door dit vakje aan te vinken bevestigt u dat het huidige app.ini bestand de juiste SECRET_KEY bevat. +reinstall_confirm_check_2=De repositories en instellingen moeten mogelijk opnieuw worden gesynchroniseerd. Door dit vakje aan te vinken, bevestigt u dat u de hooks voor de repositories en authorized_keys bestand handmatig zult hersynchroniseren. U bevestigt dat u ervoor zult zorgen dat de instellingen van de repository en mirror correct zijn. +reinstall_confirm_check_3=Je bevestigt dat je er absoluut zeker van bent dat deze Gitea draait met de juiste app. Geen locatie en dat je zeker weet dat je opnieuw moet installeren. Je bevestigt dat je de hierbovenstaande risico's erkent. err_empty_db_path=SQLite3 database pad mag niet leeg zijn. no_admin_and_disable_registration=U kunt zelf-registratie van de gebruiker niet uitschakelen zonder het maken van een administrator-account. err_empty_admin_password=Het administrator-wachtwoord mag niet leeg zijn. -err_empty_admin_email=De e-mail van de beheerder mag niet leeg zijn. +err_empty_admin_email=Het e-mailadres van Het beheerder mag niet leeg zijn. err_admin_name_is_reserved=Gebruikersnaam van beheerder is ongeldig, gebruikersnaam is gereserveerd err_admin_name_pattern_not_allowed=Gebruikersnaam van beheerder is ongeldig, de gebruikersnaam is gereserveerd err_admin_name_is_invalid=Gebruikersnaam van beheerder is ongeldig @@ -152,7 +179,8 @@ log_root_path_helper=Logboekbestanden worden geschreven naar deze map. optional_title=Optionele instellingen email_title=E-mail instellingen -smtp_host=SMTP host +smtp_addr=SMTP Host +smtp_port=SMTP Poort smtp_from=E-mails versturen als smtp_from_helper=E-mailadres dat Gitea gaat gebruiken. Voer een gewoon e-mailadres in of gebruik de "Naam" -indeling. mailer_user=SMTP gebruikersnaam @@ -182,13 +210,17 @@ admin_title=Instellingen beheerdersaccount admin_name=Admin gebruikersnaam admin_password=Wachtwoord confirm_password=Verifieer wachtwoord -admin_email=E-mail adres +admin_email=E-mailadres install_btn_confirm=Installeer Gitea test_git_failed=Git test niet gelukt: 'git' commando %v sqlite3_not_available=Deze Gitea-versie biedt geen ondersteuning voor SQLite3. Download de officiële build van %s (niet de versie van de 'gobuild'). invalid_db_setting=De database instelling zijn niet correct: %v +invalid_db_table=De database tabel '%s' is ongeldig: %v invalid_repo_path=Het pad van de hoofdmap van de repository is ongeldig: %v +invalid_app_data_path=Ongeldig app-gegevenspad: %v run_user_not_match=De 'uitvoeren als' gebruikersnaam is niet de huidige gebruikersnaam: %s -> %s +internal_token_failed=Interne token genereren mislukt: %v +secret_key_failed=Geheime sleutel genereren mislukt: %v save_config_failed=Kan de configuratie niet opslaan: %v invalid_admin_setting=Instelling van de administrator-account is ongeldig: %v install_success=Welkom! Bedankt dat u voor Gitea heeft gekozen. Veel plezier en succes ermee! @@ -202,6 +234,7 @@ default_enable_timetracking_popup=Tijdsregistratie voor nieuwe repositories stan no_reply_address=Verborgen e-maildomein no_reply_address_helper=Domeinnaam voor gebruikers met een verborgen e-mailadres. Bijvoorbeeld zal de gebruikersnaam 'joe' in Git worden geregistreerd als 'joe@noreply.example.org' als het verborgen email domein is ingesteld op 'noreply.example.org'. password_algorithm=Wachtwoord Hash Algoritme +password_algorithm_helper=Stel het wachtwoord hashing-algoritme in. Algoritmen hebben verschillende vereisten en sterkte. `argon2` heeft goede kenmerken, maar gebruikt veel geheugen en kan ongepast zijn voor kleinere systemen. [home] uname_holder=Gebruikersnaam of e-mailadres @@ -211,7 +244,7 @@ my_repos=Repositories show_more_repos=Toon meer repositories… collaborative_repos=Gedeelde repositories my_orgs=Mijn organisaties -my_mirrors=Mijn kopieën +my_mirrors=Mijn spiegels view_home=Bekijk %s search_repos=Zoek een repository… filter=Andere filters @@ -236,6 +269,9 @@ users=Gebruikers organizations=Organisaties search=Zoeken code=Code +search.fuzzy=Vergelijkbaar +search.match=Overeenkomst +code_search_unavailable=Er is momenteel geen code zoekfunctie beschikbaar. Neem contact op met uw sitebeheerder. repo_no_results=Er zijn geen overeenkomende repositories gevonden. user_no_results=Er zijn geen overeenkomende gebruikers gevonden. org_no_results=Er zijn geen overeenkomende organisaties gevonden. @@ -249,6 +285,8 @@ register_helper_msg=Heeft u al een account? Klik hier om in te loggen social_register_helper_msg=Heeft u al een account? Koppel deze nu! disable_register_prompt=Registratie is uitgeschakeld. Neem alstublieft contact op met de pagina beheerder. disable_register_mail=E-mailbevestiging voor registratie is uitgeschakeld. +manual_activation_only=Neem contact op met uw sitebeheerder om de activering te voltooien. +remember_me=Onthoud dit apparaat forgot_password_title=Wachtwoord vergeten forgot_password=Wachtwoord vergeten? sign_up_now=Een account nodig? Meld u nu aan. @@ -281,16 +319,22 @@ twofa_scratch_token_incorrect=Je eenmalige code is onjuist. login_userpass=Inloggen login_openid=OpenID oauth_signup_tab=Registreer nieuw account +oauth_signup_title=Voltooi nieuw account oauth_signup_submit=Account voltooien oauth_signin_tab=Bestaand account koppelen oauth_signin_title=Inloggen om het gekoppelde account te machtigen oauth_signin_submit=Account koppelen +oauth.signin.error=Er is een fout opgetreden bij het verwerken van het autorisatieverzoek. Als deze fout zich blijft voordoen, neem dan contact op met de sitebeheerder. +oauth.signin.error.access_denied=Het autorisatieverzoek is geweigerd. +oauth.signin.error.temporarily_unavailable=Autorisatie mislukt omdat de verificatieserver tijdelijk niet beschikbaar is. Probeer het later opnieuw. openid_connect_submit=Verbinden openid_connect_title=Verbind met een bestaand account openid_connect_desc=De gekozen OpenID-URI is onbekend. Koppel het aan een nieuw account hier. openid_register_title=Nieuw account aanmaken openid_register_desc=De gekozen OpenID-URI is onbekend. Koppel het aan een nieuw account hier. openid_signin_desc=Geef uw OpenID-URI. Bijvoorbeeld: https://anne.me, bob.openid.org.cn of gnusocial.net/carry. +disable_forgot_password_mail=Accountherstel is uitgeschakeld omdat er geen e-mailadres is ingesteld. Neem aub contact op met uw administrator. +disable_forgot_password_mail_admin=Accountherstel is alleen beschikbaar wanneer een e-mailadres is ingesteld. Stel e-mailadres in om accountherstel te activeren. email_domain_blacklisted=Je kan je niet registreren met dit e-mailadres. authorize_application=Autoriseer applicatie authorize_redirect_notice=U wordt doorgestuurd naar %s als u deze toepassing toestaat. @@ -304,19 +348,47 @@ password_pwned=Het gekozen wachtwoord staat op een uw wachtwoord instellen. reset_password=Account herstellen +reset_password.title=%s, u heeft verzocht om uw account te herstellen +reset_password.text=Klik op de volgende link om je account te herstellen binnen %s: register_success=Registratie succesvol - +issue_assigned.pull=@%[1]s heeft u toegewezen aan de pull request %[2]s in repository %[3]s. +issue_assigned.issue=@%[1]heeft u toegewezen aan issue %[2]s in repository %[3]s. + +issue.x_mentioned_you=@%s heeft u vermeld: +issue.action.force_push=%[1]s heeft een force-push uitgevoerd %[2]s van %[3]s naar %[4]s. +issue.action.push_1=@%[1]s heeft %[3]d commits gepusht naar %[2]s +issue.action.push_n=@%[1]s heeft %[3]d commits gepusht naar %[2]s +issue.action.close=@%[1]s sloot #%[2]d. +issue.action.reopen=@%[1]s heropend #%[2]d. +issue.action.merge=@%[1] heeft een merge uitgevoerd van #%[2]d naar %[3]s. +issue.action.approve=@%[1]s heeft deze pull request goedgekeurd. +issue.action.reject=@%[1]s vraagt om wijzigingen op deze pull request. +issue.action.review=@%[1]s heeft gereageerd op deze pull request. +issue.action.review_dismissed=@%[1]s wees de laatste review af van %[2]s voor deze pull request. +issue.action.ready_for_review=@%[1]s markeerde deze pull request klaar voor beoordeling. +issue.action.new=@%[1]s heeft #%[2]d aangemaakt. issue.in_tree_path=In %s: release.new.subject=%s in %s vrijgegeven @@ -330,8 +402,10 @@ release.download.targz=Broncode (TAR.GZ) repo.transfer.subject_to=%s zou "%s" willen overdragen aan %s repo.transfer.subject_to_you=%s wil "%s" aan jou overdragen repo.transfer.to_you=jij +repo.transfer.body=Om het te accepteren of afwijzen, bezoek %s of negeer het gewoon. repo.collaborator.added.subject=%s heeft jou toegevoegd aan %s +repo.collaborator.added.text=U bent toegevoegd als een medewerker van de repository: [modal] yes=Ja @@ -369,8 +443,10 @@ size_error=moet groter zijn dan %s min_size_error=moet minimaal %s karakters bevatten. max_size_error=mag maximaal %s karakters bevatten. email_error=is niet een valide e-mail adres. +url_error=`'%s' is niet een geldige URL.` include_error=` moet substring '%s' bevatten.` glob_pattern_error=` globpatroon is ongeldig: %s.` +regex_pattern_error=` regex patroon is ongeldig: %s.` unknown_error=Onbekende fout: captcha_incorrect=De CAPTCHA-code is onjuist. password_not_match=De wachtwoorden komen niet overeen. @@ -379,6 +455,7 @@ lang_select_error=Selecteer een taal uit de lijst. username_been_taken=Deze naam is al in gebruik. username_change_not_local_user=Niet-lokale gebruikers mogen hun gebruikersnaam niet wijzigen. repo_name_been_taken=De repository-naam wordt al gebruikt. +repository_force_private=Forceer privé is ingeschakeld: privé repositories kunnen niet openbaar worden gemaakt. repository_files_already_exist=Er bestaan al bestanden voor deze repository. Neem contact op met de systeembeheerder. repository_files_already_exist.adopt=Bestanden bestaan al voor deze repository en kunnen alleen worden geadopteerd. repository_files_already_exist.delete=Er bestaan al bestanden voor deze repository. U moet deze verwijderen. @@ -389,6 +466,7 @@ org_name_been_taken=Naam van de organisatie wordt al gebruikt. team_name_been_taken=De teamnaam is al in gebruik. team_no_units_error=Toegang verlenen tot ten minste één repository sectie. email_been_used=Het emailadres is al in gebruik. +email_invalid=Het e-mailadres is ongeldig. openid_been_used=OpenID adres '%s' reeds gebruikt. username_password_incorrect=Gebruikersnaam of wachtwoord is onjuist. password_complexity=Wachtwoord voldoet niet aan complexiteit eisen: @@ -397,6 +475,7 @@ password_uppercase_one=Minstens één hoofdletter password_digit_one=Minstens één cijfer password_special_one=Minstens één speciaal teken (interpunctie, haakjes, aanhalingstekens, etc.) enterred_invalid_repo_name=De repository-naam die u hebt ingevoerd is niet correct. +enterred_invalid_org_name=De organizatienaam die u hebt ingevoerd is niet correct. enterred_invalid_owner_name=De nieuwe eigenaarnaam is niet geldig. enterred_invalid_password=Het ingevoerde wachtwoord is onjuist. user_not_exist=De gebruiker bestaat niet. @@ -412,7 +491,9 @@ auth_failed=Verificatie mislukt: %v still_own_repo=Je account is nog eigenaar van één of meerdere repositories. Deze moeten eerst verwijderd of overgedragen worden. still_has_org=Je account is lid van één of meerdere organisaties. Verlaat deze eerst. +still_own_packages=Uw account bezit één of meer pakketten; verwijder deze eerst. org_still_own_repo=Deze organisatie bezit minstens één repositories. Verwijder deze of draag deze eerst over. +org_still_own_packages=Deze organisatie is nog eigenaar van één of meer pakketten; verwijder deze eerst. target_branch_not_exist=Doel branch bestaat niet @@ -423,6 +504,7 @@ repositories=repositories activity=Openbare activiteit followers=Volgers starred=Repositories met ster +watched=Gevolgde repositories projects=Projecten following=Volgt follow=Volg @@ -438,6 +520,7 @@ form.name_chars_not_allowed=Gebruikersnaam '%s' bevat ongeldige tekens. [settings] profile=Profiel account=Account +appearance=Vormgeving password=Wachtwoord security=Beveiliging avatar=Profielfoto @@ -451,6 +534,7 @@ twofa=Twee factor authenticatie account_link=Gekoppelde Accounts organization=Organisaties uid=uid +webauthn=Beveiligingssleutels public_profile=Openbaar profiel biography_placeholder=Vertel ons iets over jezelf @@ -461,14 +545,33 @@ website=Website location=Locatie update_theme=Thema bijwerken update_profile=Profiel bijwerken +update_language=Taal wijzigen update_language_not_found=De taal '%s' is niet beschikbaar. +update_language_success=Taal is bijgewerkt. update_profile_success=Je profiel is bijgewerkt. change_username=Je gebruikersnaam is gewijzigd. change_username_prompt=Let op: Als je je gebruikersnaam aanpast, verandert je account-URL ook. +change_username_redirect_prompt=De oude gebruikersnaam wordt doorgestuurd tot deze wordt opgeëist. continue=Doorgaan cancel=Annuleren language=Taal ui=Thema +hidden_comment_types=Verborgen commentaartypes +comment_type_group_reference=Referentie +comment_type_group_label=Label +comment_type_group_milestone=Mijlpaal +comment_type_group_assignee=Aangewezene +comment_type_group_title=Titel +comment_type_group_branch=Branch +comment_type_group_time_tracking=Tijdregistratie +comment_type_group_deadline=Deadline +comment_type_group_dependency=Afhankelijkheid +comment_type_group_lock=Vergrendel Status +comment_type_group_review_request=Review aanvragen +comment_type_group_pull_request_push=Commits toegevoegd +comment_type_group_project=Project +comment_type_group_issue_ref=Referentie issue +saved_successfully=Uw instellingen zijn succesvol opgeslagen. privacy=Privacy keep_activity_private=De activiteit van de profielpagina verbergen keep_activity_private_popup=Maakt de activiteit alleen zichtbaar voor jou en de admins @@ -482,6 +585,7 @@ delete_current_avatar=Verwijder huidige avatar uploaded_avatar_not_a_image=Het geüploade bestand is geen afbeelding. uploaded_avatar_is_too_big=Het geüploade bestand heeft de maximale grootte overschreden. update_avatar_success=Je avatar is bijgewerkt. +update_user_avatar_success=De avatar van de gebruiker is bijgewerkt. change_password=Wachtwoord bijwerken old_password=Huidige wachtwoord @@ -535,13 +639,37 @@ ssh_helper=Weet u niet hoe? Lees dan onze handleiding voor het gpg_helper=Hulp nodig? Neem een kijkje op de GitHub handleiding over GPG. add_new_key=SSH sleutel toevoegen add_new_gpg_key=GPG sleutel toevoegen +key_content_ssh_placeholder=Begint met 'ssh-ed25519', 'ssh-rsa', 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384', 'ecdsa-sha2-nistp521', 'sk-ecdsa-sha2-nistp256@openssh.com', of 'sk-ssh-ed25519@openssh.com' key_content_gpg_placeholder=Begint met '-----BEGIN PGP PUBLIC KEY BLOCK-----' add_new_principal=Verantwoordelijke toevoegen ssh_key_been_used=Deze SSH-sleutel is al toegevoegd aan de server. ssh_key_name_used=Er bestaat al een SSH sleutel met dezelfde naam in uw account. ssh_principal_been_used=Deze verantwoordelijke is al toegevoegd aan de server. gpg_key_id_used=Een publieke GPG-sleutel met dit ID bestaat al. +gpg_no_key_email_found=Deze GPG-sleutel komt met geen enkele geactiveerd e-mailadres dat aan uw account is gekoppeld overeen. Het kan nog steeds worden toegevoegd als u de opgegeven token tekent. +gpg_key_matched_identities=Overeenkomende identiteiten: +gpg_key_matched_identities_long=De ingesloten identiteiten in deze sleutel komen overeen met de geactiveerde e-mailadressen voor deze gebruiker. Commits die overeenkomen met deze e-mailadressen kunnen worden geverifieerd met deze sleutel. +gpg_key_verified=Geverifieerde sleutel +gpg_key_verified_long=Sleutel is geverifieerd met een token en kan worden gebruikt om commits te verifiëren die overeenkomen met alle geactiveerde e-mailadressen voor deze gebruiker naast de bijbehorende identiteiten voor deze sleutel. +gpg_key_verify=Verifiëren +gpg_invalid_token_signature=De opgegeven GPG-sleutel, handtekening en token komen niet overeen of de token is verouderd. +gpg_token_required=U moet een handtekening opgeven voor de onderstaande token gpg_token=Token +gpg_token_help=U kunt een handtekening genereren met: +gpg_token_code=echo "%s" | gpg -a --default-key %s --detach-sig +gpg_token_signature=Gepantserde GPG-handtekening +key_signature_gpg_placeholder=Begint met '-----BEGIN PGP SIGNATURE-----' +verify_gpg_key_success=GPG-sleutel '%s' is geverifieerd. +ssh_key_verified=Geverifieerde sleutel +ssh_key_verified_long=Sleutel is geverifieerd met een token en kan worden gebruikt om commits te verifiëren die overeenkomen met alle geactiveerde e-mailadressen voor deze gebruiker. +ssh_key_verify=Verifiëren +ssh_invalid_token_signature=De verstrekte SSH-sleutel, handtekening of token komen niet overeen of de token is verouderd. +ssh_token_required=U moet een handtekening opgeven voor het onderstaande token +ssh_token=Token +ssh_token_help=U kunt een handtekening genereren door het volgende: +ssh_token_signature=Gepantserde SSH handtekening +key_signature_ssh_placeholder=Begint met '-----BEGIN SSH SIGNATURE-----' +verify_ssh_key_success=SSH sleutel '%s' is geverifieerd. subkeys=Subkeys key_id=Key-ID key_name=Sleutel naam @@ -589,6 +717,9 @@ generate_token_success=Je nieuwe token is gegenereerd. Kopieer hem nu, want hij generate_token_name_duplicate=%s is al gebruikt als een applicatienaam. Gebruik een nieuwe. delete_token=Verwijderen access_token_deletion=Verwijder toegangstoken +access_token_deletion_cancel_action=Annuleren +access_token_deletion_confirm_action=Verwijderen +access_token_deletion_desc=Als je een token verwijdert, heeft de applicatie die het gebruikt geen toegang meer tot je account. Doorgaan? delete_token_success=De token is verwijderd. Applicaties die hem gebruiken, verliezen toegang tot je account. manage_oauth2_applications=Beheer OAuth2-applicaties @@ -639,11 +770,18 @@ or_enter_secret=Of voer deze geheime code in: %s then_enter_passcode=En vul de toegangscode, die in de applicatie weergegeven wordt, in: passcode_invalid=De code is niet correct. Probeer het nogmaals. twofa_enrolled=Tweefactorsauthenticatie is geactiveerd voor dit account. Bewaar je token (%s) op een veilige plek, omdat hij maar één keer wordt weergegeven! +twofa_failed_get_secret=Kon geheim niet ophalen. +webauthn_desc=Beveiligingssleutels zijn hardware apparaten die cryptografische sleutels bevatten. Ze kunnen worden gebruikt voor tweestapsverificatie. Beveiligingssleutels moeten de WebAuthn Authenticator standaard ondersteunen. +webauthn_register_key=Voeg beveiligingssleutel toe +webauthn_nickname=Bijnaam +webauthn_delete_key=Verwijder beveiligingssleutel +webauthn_delete_key_desc=Als u een beveiligingssleutel verwijdert, kunt u er niet meer mee inloggen. Doorgaan? manage_account_links=Gekoppelde accounts beheren manage_account_links_desc=Deze externe accounts zijn gekoppeld aan je Gitea-account. account_links_not_available=Er zijn momenteel geen externe accounts aan je Gitea-account gelinkt. +link_account=Account koppelen remove_account_link=Gekoppeld account verwijderen remove_account_link_desc=Als je een gekoppeld account verwijdert, verliest dit account toegang tot je Gitea-account. Doorgaan? remove_account_link_success=Het gekoppelde account is verwijderd. @@ -653,6 +791,7 @@ repos_none=U bezit geen repositories delete_account=Verwijder uw account delete_prompt=Als je doorgaat, wordt je gebruikersaccount permanent verwijderd. Dit KAN NIET ongedaan gemaakt worden. +delete_with_all_comments=Uw account is jonger dan %s. Om spook opmerkingen te vermijden, worden alle issue/PR reacties er samen mee verwijderd. confirm_delete_account=Bevestig verwijdering delete_account_title=Verwijder gebruikers account delete_account_desc=Weet je zeker dat je dit gebruikersaccount permanent wil verwijderen? @@ -661,12 +800,18 @@ email_notifications.enable=E-mailnotificaties inschakelen email_notifications.onmention=Alleen e-mail op vermelding email_notifications.disable=E-mailnotificaties uitschakelen email_notifications.submit=E-mailvoorkeur instellen +email_notifications.andyourown=En je eigen notificaties +visibility=Gebruiker zichtbaarheid visibility.public=Openbaar +visibility.public_tooltip=Zichtbaar voor alle gebruikers visibility.limited=Beperkt +visibility.limited_tooltip=Alleen zichtbaar voor ingelogde gebruikers visibility.private=Privé +visibility.private_tooltip=Enkel zichtbaar voor organisatieleden [repo] +new_repo_helper=Een repository bevat alle projectbestanden, inclusief de revisiegeschiedenis. Heeft u het ergens anders al? Migreer repository. owner=Eigenaar owner_helper=Sommige organisaties kunnen niet worden weergegeven in de dropdown vanwege een limiet op het maximale aantal repositories. repo_name=Naam van repository @@ -684,31 +829,55 @@ visibility_fork_helper=(Verandering van deze waarde zal van invloed zijn op alle clone_helper=Heb je hulp nodig om te clonen? Bekijk dan de handleiding. fork_repo=Repository forken fork_from=Afsplitsing van +already_forked=Je hebt %s al geforked +fork_to_different_account=Fork naar een ander account fork_visibility_helper=De zichtbaarheid van een geforkte repository kan niet worden veranderd. use_template=Gebruik dit sjabloon +clone_in_vsc=Kloon in VS Code +download_zip=ZIP downloaden +download_tar=TAR.GZ downloaden +download_bundle=BUNDLE downloaden generate_repo=Repository genereren generate_from=Genereer van repo_desc=Omschrijving repo_desc_helper=Voer korte beschrijving in (optioneel) repo_lang=Taal repo_gitignore_helper=Selecteer .gitignore templates. +repo_gitignore_helper_desc=Kies welke bestanden niet bij te houden vanuit een lijst met sjablonen voor alledaagse talen. Gebruikelijke artefacten gegenereerd door de build tools van elke taal zijn standaard inbegrepen met .gitignore. issue_labels=Issuelabels issue_labels_helper=Selecteer een issuelabelset. license=Licentie license_helper=Selecteer een licentie bestand. +license_helper_desc=Een licentie bepaalt wat anderen wel en niet met je code kunnen doen. Niet zeker welke juist is voor jouw project? Zie Kies een licentie. readme=README readme_helper=Selecteer een README-bestandssjabloon. +readme_helper_desc=Dit is de plek waar je een volledige beschrijving van je project kunt schrijven. auto_init=Initialiseer repository (voegt .gitignore, License en README toe) +trust_model_helper=Selecteer het vertrouwensmodel voor handtekeningverificatie. Mogelijke opties zijn: +trust_model_helper_collaborator=Medewerker: Vertrouw handtekeningen door medewerkers +trust_model_helper_committer=Committer: Vertrouw handtekeningen die overeenkomen met de committers +trust_model_helper_collaborator_committer=Medewerker+Committer: Vertrouw handtekeningen door medewerkers die overeenkomen met de committer +trust_model_helper_default=Standaard: Gebruik het standaard vertrouwemsmodel voor deze installatie create_repo=Nieuwe repository default_branch=Standaard branch +default_branch_helper=De standaard branch is de basis branch voor pull requests en code commits. mirror_prune=Opschonen mirror_prune_desc=Verwijder verouderde remote-tracking-referenties +mirror_interval=Spiegel Interval (geldige tijdseenheden zijn 'h', 'm', 's'). 0 om automatische synchronisatie uit te schakelen (Minimum interval: %s) mirror_interval_invalid=Kloon-interval is niet geldig. +mirror_sync_on_commit=Synchroniseer wanneer commits gepusht worden mirror_address=Klonen van URL +mirror_address_desc=Voeg alle vereiste inloggegevens toe in de autorisatie sectie. mirror_address_url_invalid=De opgegeven url is ongeldig. U dient alle componenten van de url correct te escapen. mirror_address_protocol_invalid=De opgegeven url is ongeldig. Alleen http(s):// of git:// locaties kunnen worden gemirrord. +mirror_lfs=Grote bestandsopslag (LFS) +mirror_lfs_desc=Activeer spiegelen van LFS-gegevens. +mirror_lfs_endpoint=LFS Eindpunt +mirror_lfs_endpoint_desc=Synchronisatie zal proberen de kloon-url te gebruiken om de LFS-serverte bepalen. Je kan ook een aangepast eindpunt opgeven als de LFS-gegevens ergens anders zijn opgeslagen. mirror_last_synced=Laatst gesynchroniseerd +mirror_password_placeholder=(Ongewijzigd) mirror_password_blank_placeholder=(Niet ingesteld) +mirror_password_help=Wijzig de gebruikersnaam om een opgeslagen wachtwoord te wissen. watchers=Volgers stargazers=Stargazers forks=Forks @@ -725,7 +894,14 @@ delete_preexisting_label=Verwijderen delete_preexisting=Verwijder reeds bestaande bestanden delete_preexisting_content=Verwijder bestanden in %s delete_preexisting_success=Niet-geadopteerde bestanden verwijderd in %s +blame_prior=Bekijk de schuld voorafgaand aan deze verandering +transfer.accept=Accepteer overdracht +transfer.accept_desc=Overmaken naar "%s" +transfer.reject=Overdracht afwijzen +transfer.reject_desc=Annuleer overdracht naar "%s" +transfer.no_permission_to_accept=Je hebt geen toestemming om te accepteren +transfer.no_permission_to_reject=Je hebt geen toestemming om te weigeren desc.private=Privé desc.public=Openbaar @@ -738,6 +914,7 @@ desc.archived=Gearchiveerd template.items=Sjabloon items template.git_content=Git inhoud (standaard Branch) template.git_hooks=Git Hooks +template.git_hooks_tooltip=Je bent momenteel niet in staat om Git Hooks één keer te wijzigen of te verwijderen. Selecteer deze optie alleen als je de sjabloonrepository vertrouwt. template.webhooks=Webhooks template.topics=Onderwerpen template.avatar=Profielfoto @@ -749,11 +926,20 @@ archive.title=Deze repo is gearchiveerd. U kunt bestanden bekijken en het klonen archive.issue.nocomment=Deze repo is gearchiveerd. U kunt niet reageren op problemen. archive.pull.nocomment=Deze repo is gearchiveerd. U kunt niet reageren op pull requests. +form.reach_limit_of_creation_1=U heeft al uw limiet van %d repository bereikt. +form.reach_limit_of_creation_n=U heeft al uw limiet van %d repositories bereikt. form.name_reserved=Repositorienaam '%s' is gereserveerd. form.name_pattern_not_allowed=Het patroon '%s' is niet toegestaan in de naam van een repository. +need_auth=Autorisatie migrate_options=Migratie opties migrate_service=Migratie Service +migrate_options_mirror_helper=Deze repositorie zal een spiegel zijn +migrate_options_lfs=Migreer LFS bestanden +migrate_options_lfs_endpoint.label=LFS Eindpunt +migrate_options_lfs_endpoint.description=Migratie zal proberen om je Git remote te gebruiken om de LFS-server te bepalen. Je kan ook een aangepast eindpunt opgeven als de LFS-gegevens ergens anders zijn opgeslagen. +migrate_options_lfs_endpoint.description.local=Een lokaal serverpad wordt ook ondersteund. +migrate_options_lfs_endpoint.placeholder=Laat dit leeg om af te leiden uit de kloon-url migrate_items=Migratie Items migrate_items_wiki=Wiki migrate_items_milestones=Mijlpalen @@ -765,9 +951,12 @@ migrate_items_releases=Releases migrate_repo=Migreer repository migrate.clone_address=Migreer / kloon van URL migrate.clone_address_desc=De HTTP(s)- of 'git clone'-URL van een bestaande repository +migrate.github_token_desc=Je kunt hier een of meerdere tokens met komma gescheiden plaatsen om sneller te migreren door de GitHub API limiet te beperken. WAARSCHUWING: Het misbruik van deze functie kan in strijd zijn met het beleid van de serviceprovider en leiden tot het blokkeren van rekeningen. migrate.clone_local_path=of een lokaal pad migrate.permission_denied=U bent niet gemachtigd om deze lokale repositories te importeren. +migrate.permission_denied_blocked=Je kunt niet importeren uit niet-toegestane hosts, vraag de beheerder om de instellingen ALLOWED_DOMAINS/ALLOW_LOCALNETWORKS/BLOCKED_DOMAINS te controleren. migrate.invalid_local_path=Het lokale pad is ongeldig, bestaat niet of is geen map. +migrate.invalid_lfs_endpoint=Het LFS-eindpunt is niet geldig. migrate.failed=Migratie is mislukt: %v migrate.migrate_items_options=Toegangstoken is vereist om extra items te migreren migrated_from=Gemigreerd van %[2]s @@ -776,6 +965,22 @@ migrate.migrate=Migreer van %s migrate.migrating=Migreren van %s... migrate.migrating_failed=Migreren van %s is mislukt. migrate.migrating_failed.error=Foutmelding: %s +migrate.migrating_failed_no_addr=Migratie is mislukt. +migrate.github.description=Gegevens overzetten van github.com of andere GitHub instanties. +migrate.git.description=Migreer een repositorie van elke Git service. +migrate.gitlab.description=Gegevens migreren van gitlab.com of andere GitLab-instanties. +migrate.gitea.description=Gegevens overzetten van gitea.com of andere Gitea instanties. +migrate.gogs.description=Gegevens overzetten van notabug.org of andere Gogs instanties. +migrate.onedev.description=Gegevens overzetten van code.onedev.io of andere OneDev instanties. +migrate.codebase.description=Gegevens migreren van codebasehq.com. +migrate.gitbucket.description=Gegevens migreren van GitBucket instanties. +migrate.migrating_git=Git gegevens migreren +migrate.migrating_topics=Onderwerpen migreren +migrate.migrating_milestones=Mijlpalen migreren +migrate.migrating_labels=Labels migreren +migrate.migrating_releases=Releases migreren +migrate.migrating_issues=Issues migreren +migrate.migrating_pulls=Pull-verzoeken migreren mirror_from=kopie van forked_from=geforked van @@ -797,6 +1002,7 @@ clone_this_repo=Kloon deze repository create_new_repo_command=Maak een nieuwe repository aan vanaf de console push_exist_repo=Push een bestaande repositorie vanaf de console empty_message=Deze repository bevat geen inhoud. +broken_message=De Git gegevens die ten grondslag liggen aan deze repository kunnen niet worden gelezen. Neem contact op met de beheerder van deze instantie of verwijder deze repository. code=Code code.desc=Toegang tot broncode, bestanden, commits en branches. @@ -804,11 +1010,13 @@ branch=Branch tree=Tree clear_ref=`Huidige referentie wissen` filter_branch_and_tag=Filter op branch of tag +find_tag=Label zoeken branches=Branches tags=Labels issues=Kwesties pulls=Pull-aanvragen project_board=Projecten +packages=Paketten labels=Labels org_labels_desc=Organisatielabel dat gebruikt kan worden met alle repositories onder deze organisatie org_labels_desc_manage=beheren @@ -816,23 +1024,41 @@ org_labels_desc_manage=beheren milestones=Mijlpalen commits=Commits commit=Commit +release=Release releases=Publicaties tag=Label +released_this=heeft dit gepubliceerd file.title=%s op %s file_raw=Ruw file_history=Geschiedenis +file_view_source=Bron weergeven +file_view_rendered=Weergave weergeven file_view_raw=Weergave ruw bestand file_permalink=Permalink file_too_large=Dit bestand is te groot om te tonen. - +bidi_bad_header=`Dit bestand bevat onverwachte Bidirectionele Unicode karakters!` +bidi_bad_description=`Dit bestand bevat onverwachte Bidirectionele Unicode-tekens die anders verwerkt kunnen worden dan hieronder het geval is. Als uw gebruik ervan opzettelijk en legitiem is, kunt u deze waarschuwing veilig negeren. Gebruik de Escape knop om verborgen karakters te onthullen.` +bidi_bad_description_escaped=`Dit bestand bevat onverwachte Bidirectionele Unicode-tekens. Verborgen unicode tekens worden hieronder ge-escaped. Gebruik de knop Onescape om te laten zien hoe ze renderen.` +unicode_header=`Dit bestand bevat verborgen Unicode karakters!` +unicode_description=`Dit bestand bevat verborgen Unicode-tekens die anders verwerkt kunnen worden dan hieronder het geval is. Als uw gebruik ervan opzettelijk en legitiem is, kunt u deze waarschuwing veilig negeren. Gebruik de Escape knop om verborgen karakters te onthullen.` +unicode_description_escaped=`Dit bestand bevat verborgen Unicode-tekens. Verborgen unicode tekens zijn hieronder ge-escaped. Gebruik de knop Onescape om te laten zien hoe ze renderen.` +line_unicode=`Deze regel bevat verborgen Unicode karakters` + +escape_control_characters=Escape +unescape_control_characters=Onescape +file_copy_permalink=Permalink kopiëren +view_git_blame=Bekijk Git Blame video_not_supported_in_browser=Je browser ondersteunt de HTML5 'video'-tag niet. audio_not_supported_in_browser=Je browser ondersteunt de HTML5 'audio'-tag niet. stored_lfs=Opgeslagen met Git LFS symbolic_link=Symbolic link commit_graph=Commit grafiek +commit_graph.select=Selecteer branches +commit_graph.hide_pr_refs=Verberg pull verzoeken commit_graph.monochrome=Monochroom commit_graph.color=Kleur blame=Blame +download_file=Download het bestand normal_view=Normale weergave line=regel lines=regels @@ -860,7 +1086,12 @@ editor.add_tmpl='' toevoegen editor.add='%s' toevoegen editor.update='%s' updaten editor.delete='%s' verwijderen +editor.patch=Patch toepassen +editor.patching=Patchen: +editor.fail_to_apply_patch=Kan patch '%s' niet toepassen +editor.new_patch=Nieuwe Patch editor.commit_message_desc=Voeg een optionele uitgebreide omschrijving toe… +editor.signoff_desc=Voeg een Signed-off-by toe aan het einde van het commit logbericht. editor.commit_directly_to_this_branch=Commit direct naar de branch '%s'. editor.create_new_branch=Maak een nieuwe branch voor deze commit en start van een pull-aanvraag. editor.create_new_branch_np=Maak een nieuwe branch voor deze commit. @@ -883,6 +1114,8 @@ editor.commit_empty_file_text=Het bestand dat u wilt committen is leeg. Doorgaan editor.no_changes_to_show=Er zijn geen wijzigingen om weer te geven. editor.fail_to_update_file=Bijwerken/aanmaken van bestand '%s ' mislukt. editor.fail_to_update_file_summary=Foutmelding: +editor.push_rejected_no_message=De wijziging is afgewezen door de server zonder bericht. Controleer de Git Hooks alsjeblieft. +editor.push_rejected=De wijziging is afgewezen door de server. Controleer Controleer de Git Hooks alsjeblieft. editor.push_rejected_summary=Volledig afwijzingsbericht: editor.add_subdir=Een map toevoegen… editor.unable_to_upload_files=Uploaden van bestand '%s' is mislukt: %v @@ -892,10 +1125,13 @@ editor.cannot_commit_to_protected_branch=Kan niet committen naar de beveiligde b editor.no_commit_to_branch=Kan niet rechtstreeks naar branch committen omdat: editor.user_no_push_to_branch=Gebruiker kan niet pushen naar branch editor.require_signed_commit=Branch vereist een ondertekende commit +editor.cherry_pick=Cherry-pick %s op: +editor.revert=%s ongedaan maken op: commits.desc=Bekijk de broncode-wijzigingsgeschiedenis. commits.commits=Commits commits.no_commits=Geen overeenkomstige commits. '%s' en '%s' hebben totaal verschillende histories. +commits.nothing_to_compare=Deze branches zijn gelijk. commits.search=Zoek commits… commits.search.tooltip=U kunt trefwoorden prefixen met "auteur:", "committer:", "na:" of "voor:", bv. "revert auteur:Alice voor:2019-0401". commits.find=Zoek @@ -909,11 +1145,23 @@ commits.signed_by=Getekend door commits.signed_by_untrusted_user=Ondertekend door niet-vertrouwde gebruiker commits.signed_by_untrusted_user_unmatched=Ondertekend door niet-vertrouwde gebruiker die niet overeenkomt met de committer commits.gpg_key_id=GPG sleutel-ID +commits.ssh_key_fingerprint=SSH sleutel vingerafdruk +commit.actions=Acties +commit.revert=Ongedaan maken +commit.revert-header=Maak %s ongedaan +commit.revert-content=Selecteer een branch om terug te zetten: +commit.cherry-pick=Cherry-pick +commit.cherry-pick-header=Cherry-pick: %s +commit.cherry-pick-content=Selecteer een branch om te cherry-pick op: +ext_issues=Toegang tot Externe Issues ext_issues.desc=Koppelen aan een externe kwestie-tracker. projects=Projecten +projects.desc=Beheer issues en pulls in projectborden. +projects.description=Omschrijving (optioneel) +projects.description_placeholder=Omschrijving projects.create=Project aanmaken projects.title=Titel projects.new=Nieuw project @@ -937,11 +1185,14 @@ projects.board.edit_title=Nieuwe boardnaam projects.board.new_title=Nieuwe boardnaam projects.board.new_submit=Versturen projects.board.new=Nieuw bord +projects.board.set_default=Instellen als standaard +projects.board.set_default_desc=Stel dit board in als standaard voor niet gecategoriseerde issues en pulls projects.board.delete=Verwijder bord projects.board.deletion_desc=Als een projectbord wordt verwijdert, worden alle gerelateerde kwesties naar 'Ongecategoriseerd' verplaatst. Doorgaan? projects.board.color=Kleur projects.open=Open projects.close=Sluiten +projects.board.assigned_to=Toegewezen aan issues.desc=Organiseer bugrapporten, taken en mijlpalen. issues.filter_assignees=Filter verantwoordelijke @@ -988,6 +1239,11 @@ issues.label_templates.info=Er bestaan nog geen labels. Maak een nieuw label met issues.label_templates.helper=Selecteer een labelset issues.label_templates.use=Label Set gebruiken issues.label_templates.fail_to_load_file=Kan het labelsjabloonbestand '%s' niet openen: %v +issues.add_label=voegde het %s label %s toe +issues.add_labels=voegde de %s labels %s toe +issues.remove_label=verwijderde het %s label %s +issues.remove_labels=verwijderde de %s labels %s +issues.add_remove_labels=voegde de %s toe en verwijderde de %s labels %s issues.add_milestone_at=`heeft dit %[2]s aan de mijlpaal %[1]s toegevoegd` issues.add_project_at=`heeft dit toegevoegd aan het %s project %s` issues.change_milestone_at='mijlpaal bewerkt van %s %s %s' @@ -1001,6 +1257,9 @@ issues.add_assignee_at=`was toegekend door %s %s` issues.remove_assignee_at=`is niet toegewezen door %s %s` issues.remove_self_assignment=`heeft %s zijn/haar toewijzing verwijderd` issues.change_title_at='titel aangepast van %s naar %s %s' +issues.change_ref_at=`wijzig referentie van %s naar %s %s` +issues.remove_ref_at=`heeft referentie %s verwijderd %s` +issues.add_ref_at=`heeft referentie %s toegevoegd %s` issues.delete_branch_at=`heeft %[2]s de branch %[1]s verwijderd.` issues.filter_label=Label issues.filter_label_exclude=`Gebruik alt + klik/voer in om labels uit te sluiten @@ -1014,6 +1273,7 @@ issues.filter_type.all_issues=Alle kwesties issues.filter_type.assigned_to_you=Aan jou toegewezen issues.filter_type.created_by_you=Aangemaakt door jou issues.filter_type.mentioning_you=Vermelden jou +issues.filter_type.review_requested=Review aangevraagd issues.filter_sort=Sorteer issues.filter_sort.latest=Nieuwste issues.filter_sort.oldest=Oudste @@ -1027,6 +1287,7 @@ issues.filter_sort.moststars=Meeste sterren issues.filter_sort.feweststars=Minste sterren issues.filter_sort.mostforks=Meeste forks issues.filter_sort.fewestforks=Minste forks +issues.keyword_search_unavailable=Zoeken op trefwoord is momenteel niet beschikbaar. Neem contact op met de websitebeheerder. issues.action_open=Open issues.action_close=Sluit issues.action_label=Label @@ -1039,11 +1300,13 @@ issues.previous=Vorige issues.next=Volgende issues.open_title=Open issues.closed_title=Gesloten +issues.draft_title=Concept issues.num_comments=%d opmerkingen issues.commented_at=`reageerde %s` issues.delete_comment_confirm=Weet u zeker dat u deze reactie wilt verwijderen? issues.context.copy_link=Link kopiëren issues.context.quote_reply=Citeer antwoord +issues.context.reference_issue=Verwijs in nieuw issue issues.context.edit=Bewerken issues.context.delete=Verwijder issues.no_content=Er is nog geen inhoud. @@ -1069,6 +1332,7 @@ issues.re_request_review=Opnieuw aanvragen review issues.is_stale=Er zijn wijzigingen aangebracht in deze PR sinds deze beoordeling issues.remove_request_review=Verwijder beoordelingsverzoek issues.remove_request_review_block=Kan beoordelingsverzoek niet verwijderen +issues.dismiss_review=Beoordeling afwijzen issues.sign_in_require_desc=Log in om deel te nemen aan deze discussie. issues.edit=Bewerken issues.cancel=Annuleren @@ -1112,13 +1376,21 @@ issues.lock.reason=Reden voor vergrendeling issues.lock.title=Vergrendel gesprek over dit probleem. issues.unlock.title=Ontgrendel gesprek over dit probleem. issues.comment_on_locked=Je kunt geen commentaar geven op een vergrendeld probleem. +issues.delete=Verwijderen +issues.delete.title=Deze issue verwijderen? +issues.delete.text=Wilt u deze issue echt verwijderen? (Dit is permanent en verwijdert alle inhoud. Overweeg om deze issue te sluiten, als u liever deze als archief wilt bijhouden) issues.tracker=Tijdregistratie +issues.start_tracking_short=Start timer issues.start_tracking=Start tijdregistratie issues.start_tracking_history=`%s is begonnen` issues.tracker_auto_close=Timer wordt automatisch gestopt wanneer dit probleem wordt gesloten +issues.tracking_already_started=`Je houd al tijd bij voor een ander issue!` +issues.stop_tracking=Stop timer issues.stop_tracking_history=`gestopt met werken aan %s` +issues.cancel_tracking=Weggooien issues.cancel_tracking_history=`tijd bijhouden geannuleerd: %s` issues.add_time=Tijd handmatig toevoegen +issues.del_time=Verwijder deze tijdlog issues.add_time_short=Timer toevoegen issues.add_time_cancel=Annuleren issues.add_time_history=`heeft besteedde tijd toegevoegd: %s` @@ -1141,17 +1413,20 @@ issues.due_date_form_remove=Verwijder issues.due_date_not_writer=Je hebt schrijftoegang in deze repository nodig om de deadline van een kwestie aan te passen. issues.due_date_not_set=Geen vervaldatum ingesteld. issues.due_date_added=heeft %[2]s de deadline %[1]s toegevoegd -issues.due_date_modified=heeft %[3]s de deadline aangepast van %[1]s naar %[2]s +issues.due_date_modified=de vervaldatum van %[2]s is gewijzigd naar %[1]s[3]s issues.due_date_remove=heeft %[2]s de deadline %[1]s verwijderd issues.due_date_overdue=Over tijd issues.due_date_invalid=De deadline is ongeldig of buiten bereik. Gebruik het formaat 'jjjj-mm-dd'. issues.dependency.title=Afhankelijkheden +issues.dependency.issue_no_dependencies=Geen afhankelijkheden ingesteld. +issues.dependency.pr_no_dependencies=Geen afhankelijkheden ingesteld. issues.dependency.add=Voeg afhankelijkheid toe… issues.dependency.cancel=Annuleer issues.dependency.remove=Verwijder issues.dependency.remove_info=Verwijder afhankelijkheid issues.dependency.added_dependency=`voegde een nieuwe afhankelijkheid %s toe ` issues.dependency.removed_dependency=`verwijderde een afhankelijkheid %s` +issues.dependency.issue_closing_blockedby=Het sluiten van dit issue is geblokkeerd door de volgende problemen issues.dependency.issue_close_blocks=Deze kwestie blokkeert het sluiten van de volgende kwesties issues.dependency.pr_close_blocks=Deze pull-aanvraag blokkeert het sluiten van de volgende kwesties issues.dependency.issue_close_blocked=Je moet alle kwesties die deze kwestie blokkeren sluiten voordat je deze kan sluiten. @@ -1172,6 +1447,8 @@ issues.review.self.approval=Je kan je eigen pull-aanvraag niet goedkeuren. issues.review.self.rejection=Je kan geen wijzigingen aanvragen op je eigen pull-aanvraag. issues.review.approve=heeft deze veranderingen %s goedgekeurd issues.review.comment=beoordeeld %s +issues.review.dismissed=%s's beoordeling afgewezen %s +issues.review.dismissed_label=Afgewezen issues.review.left_comment=heeft een reactie achtergelaten issues.review.content.empty=Je moet een reactie achterlaten die de gewenste verandering(en) beschrijft. issues.review.reject=aangevraagde wijzigingen %s @@ -1180,6 +1457,7 @@ issues.review.add_review_request=heeft een review aangevraagd van %s %s issues.review.remove_review_request=beoordelingsaanvraag voor %s %s verwijderd issues.review.remove_review_request_self=beoordeling geweigerd %s issues.review.pending=In behandeling +issues.review.pending.tooltip=Deze reactie is momenteel niet zichtbaar voor andere gebruikers. Selecteer '%s' -> '%s/%s/%s' ' boven aan de pagina. issues.review.review=Review issues.review.reviewers=Reviewers issues.review.outdated=Verouderd @@ -1191,21 +1469,38 @@ issues.review.resolve_conversation=Gesprek oplossen issues.review.un_resolve_conversation=Gesprek niet oplossen issues.review.resolved_by=markeerde dit gesprek als opgelost issues.assignee.error=Niet alle aangewezen personen zijn toegevoegd vanwege een onverwachte fout. +issues.reference_issue.body=Inhoud issues.content_history.deleted=verwijderd issues.content_history.edited=bewerkt +issues.content_history.created=gecreëerd +issues.content_history.delete_from_history=Uit geschiedenis verwijderen +issues.content_history.delete_from_history_confirm=Uit geschiedenis verwijderen? +issues.content_history.options=Opties +issues.reference_link=Referentie: %s compare.compare_base=basis compare.compare_head=vergelijk pulls.desc=Schakel pull-aanvragen en code-beoordelingen in. pulls.new=Nieuwe Pull aanvraag +pulls.view=Pull verzoek bekijken pulls.compare_changes=Nieuwe pull-aanvraag +pulls.allow_edits_from_maintainers=Bewerkingen toestaan van maintainers +pulls.allow_edits_from_maintainers_desc=Gebruikers met schrijftoegang tot de basis branch kunnen ook pushen naar deze branch +pulls.allow_edits_from_maintainers_err=Updaten mislukt pulls.compare_changes_desc=Selecteer de samen te voegen doel- en bron-branch. +pulls.has_viewed_file=Gezien +pulls.has_changed_since_last_review=Veranderd sinds de laatste beoordeling +pulls.viewed_files_label=%[1]d / %[2]d bestanden bekeken pulls.compare_base=samenvoegen met pulls.compare_compare=trekken van +pulls.switch_comparison_type=Wissel vergelijking type +pulls.switch_head_and_base=Verwissel hoofd en basis pulls.filter_branch=Filter branch pulls.no_results=Geen resultaten gevonden. pulls.nothing_to_compare=Deze branches zijn gelijk. Er is geen pull-aanvraag nodig. +pulls.nothing_to_compare_and_allow_empty_pr=Deze branches zijn gelijk. Deze pull verzoek zal leeg zijn. +pulls.has_pull_request=`Een pull-verzoek tussen deze branches bestaat al: %[2]s#%[3]d` pulls.create=Pull verzoek aanmaken pulls.title_desc=wil %[1]d commits van %[2]s samenvoegen met %[3]s pulls.merged_title_desc=heeft %[1]d commits samengevoegd van %[2]s naar %[3]s %[4]s @@ -1217,17 +1512,26 @@ pulls.reopen_to_merge=Heropen dit pull request aub om een een merge actie uit te pulls.cant_reopen_deleted_branch=Deze pull-aanvraag kan niet opnieuw worden geopend omdat de branch is verwijderd. pulls.merged=Samengevoegd pulls.merged_as=De pull request is samengevoegd als %[2]s. +pulls.manually_merged=Handmatig samengevoegd +pulls.manually_merged_as=Het pull-verzoek is handmatig samengevoegd als %[2]s. pulls.is_closed=Deze pull-aanvraag is gesloten. pulls.has_merged=Deze pull-aanvraag is al samengevoegd. pulls.title_wip_desc=`Start de titel met %s om te voorkomen dat deze pull-aanvraag per ongeluk wordt samengevoegd.` +pulls.cannot_merge_work_in_progress=Dit pull request is gemarkeerd als werk in uitvoering. +pulls.still_in_progress=Nog steeds bezig? +pulls.add_prefix=Voeg %s prefix toe +pulls.remove_prefix=Verwijder %s prefix pulls.data_broken=Deze pull-aanvraag is ongeldig wegens missende fork-informatie. pulls.files_conflicted=Dit pull request heeft wijzigingen die strijdig zijn met de doel branch. pulls.is_checking=Controle op samenvoegingsconflicten is nog bezig. Probeer later nog een keer. +pulls.is_ancestor=Deze branch is al opgenomen in de toegewezen branch. Er is niets om samen te voegen. +pulls.is_empty=De wijzigingen in deze branch bevinden zich al in de toegewezen branch. Dit zal een lege commit zijn. pulls.required_status_check_failed=Sommige vereiste controles waren niet succesvol. pulls.required_status_check_missing=Er ontbreken enkele vereiste controles. pulls.required_status_check_administrator=Als een beheerder kunt u deze pull-aanvraag nog samenvoegen. pulls.blocked_by_approvals=Deze pull-aanvraag heeft nog niet genoeg goedkeuringen. %d van de %d goedkeuringen zijn gegeven. pulls.blocked_by_rejection=Deze pull-aanvraag heeft wijzigingen aangevraagd door een officiële beoordelaar. +pulls.blocked_by_official_review_requests=Dit pull-verzoek heeft officiële beoordelingsverzoeken. pulls.blocked_by_outdated_branch=Deze pull-aanvraag is geblokkeerd omdat het verouderd is. pulls.blocked_by_changed_protected_files_1=Deze pull-aanvraag is geblokkeerd omdat het een beschermd bestand veranderd: pulls.blocked_by_changed_protected_files_n=Deze pull-aanvraag is geblokkeerd omdat het beschermde bestanden veranderd: @@ -1242,12 +1546,19 @@ pulls.reject_count_1=%d wijzigingsverzoek pulls.reject_count_n=%d wijzigingsverzoeken pulls.waiting_count_1=%d wachtende beoordeling pulls.waiting_count_n=%d wachtende beoordelingen +pulls.wrong_commit_id=commit id moet een commit id zijn op de doelbranch pulls.no_merge_desc=Deze pull-aanvraag kan niet worden samengevoegd, omdat alle samenvoegingsopties zijn uitgeschakeld. pulls.no_merge_helper=Schakel samenvoegingsopties in in de repositoryinstellingen of voeg de pull-aanvraag handmatig samen. pulls.no_merge_wip=Deze pull-aanvraag kan niet worden samengevoegd omdat hij als "work in progress" is gemarkeerd. pulls.no_merge_not_ready=Deze pull-aanvraag is niet klaar om samen te voegen, controleer de status en status controles. pulls.no_merge_access=Je bent niet gemachtigd om deze pull-aanvraag samen te voegen. +pulls.merge_pull_request=Maak samenvoeg-commit +pulls.rebase_merge_pull_request=Herbaseren dan snel-voorwaarts +pulls.rebase_merge_commit_pull_request=Herbaseren dan samenvoeg-commit maken +pulls.squash_merge_pull_request=Maak samenvoeg-commit +pulls.merge_manually=Handmatig samengevoegd +pulls.merge_commit_id=De merge commit ID pulls.require_signed_wont_sign=De branch heeft ondertekende commits nodig, maar deze merge zal niet worden ondertekend pulls.invalid_merge_option=Je kan de samenvoegingsoptie niet gebruiken voor deze pull-aanvraag. @@ -1258,7 +1569,10 @@ pulls.rebase_conflict_summary=Foutmelding ; %[2]s
%[3]s
pulls.unrelated_histories=Samenvoegen mislukt: de HEAD en base delen geen gemeenschappelijke geschiedenis. Tip: Probeer een andere strategie pulls.merge_out_of_date=Samenvoegen mislukt: Tijdens het samenvoegen is de basis bijgewerkt. Tip: Probeer het opnieuw. +pulls.head_out_of_date=Samenvoegen mislukt: tijdens het genereren van de samenvoeging is de kop bijgewerkt. Tip: Probeer het opnieuw. +pulls.push_rejected=Samenvoegen mislukt: De push is geweigerd. Controleer de Git Hooks voor deze repository. pulls.push_rejected_summary=Volledig afwijzingsbericht +pulls.push_rejected_no_message=Samenvoegen mislukt: De push is afgewezen, maar er was geen extern bericht.
Controleer de Git Hooks voor deze repository pulls.open_unmerged_pull_exists=`Je kan deze pull-aanvraag niet opnieuw openen omdat er een andere (#%d) met identieke eigenschappen open staat.` pulls.status_checking=Sommige controles zijn in behandeling pulls.status_checks_success=Alle checks waren succesvol @@ -1267,15 +1581,27 @@ pulls.status_checks_failure=Sommige controles zijn mislukt pulls.status_checks_error=Sommige controles hebben foutmeldingen gerapporteerd pulls.status_checks_requested=Vereist pulls.status_checks_details=Details +pulls.update_branch=Update branch via samenvoegen +pulls.update_branch_rebase=Update branch via herbaseren pulls.update_branch_success=Branch update is geslaagd pulls.update_not_allowed=Je hebt geen toestemming om branch bij te werken pulls.outdated_with_base_branch=Deze branch is verouderd met de basis branch pulls.closed_at=`heeft deze pull request gesloten %[2]s` pulls.reopened_at=`heropende deze pull request %[2]s` +pulls.merge_instruction_hint=`Je kunt ook command line instructies bekijken.` +pulls.merge_instruction_step1_desc=Vanuit het project, check een branch uit en test de veranderingen. +pulls.merge_instruction_step2_desc=Voeg de wijzigingen samen en update ze op Gitea. +pulls.auto_merge_button_when_succeed=(Bij geslaagde controles) +pulls.auto_merge_when_succeed=Automatisch samenvoegen wanneer alle controles gelukt zijn +pulls.auto_merge_newly_scheduled=De pull-verzoek was gepland om samen te voegen wanneer alle controles geslaagd zijn. +pulls.auto_merge_has_pending_schedule=%[1]s heeft deze pull-verzoek automatisch samengevoegd wanneer alle checks succesvol zijn geweest %[2]s. +pulls.auto_merge_cancel_schedule=Automatisch samenvoegen annuleren +pulls.delete.title=Deze pull-verzoek verwijderen? +pulls.delete.text=Weet je zeker dat je deze pull-verzoek wilt verwijderen? (Dit zal alle inhoud permanent verwijderen. Overweeg om het te sluiten als je het gearchiveerd wilt houden) milestones.new=Nieuwe mijlpaal milestones.closed=%s werd gesloten @@ -1321,6 +1647,7 @@ signing.wont_sign.commitssigned=De samenvoeging wordt niet ondertekend omdat all signing.wont_sign.approved=De samenvoeging wordt niet ondertekend omdat de PR niet is goedgekeurd signing.wont_sign.not_signed_in=U bent niet ingelogd +ext_wiki=Toegang tot Externe Wiki ext_wiki.desc=Koppelen aan een externe wiki. wiki=Wiki @@ -1345,6 +1672,7 @@ wiki.page_already_exists=Er bestaat al een wiki-pagina met deze naam. wiki.reserved_page=De wiki-paginanaam '%s' is gereserveerd. wiki.pages=Pagina’s wiki.last_updated=Laatst bijgewerkt: %s +wiki.page_name_desc=Voer een naam in voor deze Wiki pagina. Sommige speciale namen zijn: 'Home', '_Sidebar' en '_Footer'. activity=Activiteit activity.period.filter_label=Periode: @@ -1376,6 +1704,7 @@ activity.closed_issues_count_1=Gesloten problemen activity.closed_issues_count_n=Gesloten problemen activity.title.issues_1=%d Probleem activity.title.issues_n=%d Problemen +activity.title.issues_closed_from=%s gesloten van %s activity.title.issues_created_by=%s gemaakt door %s activity.closed_issue_label=Gesloten activity.new_issues_count_1=Nieuw probleem @@ -1413,7 +1742,11 @@ activity.git_stats_deletion_n=%d verwijderingen search=Zoek search.search_repo=Zoek repository +search.fuzzy=Vergelijkbaar +search.match=Overeenkomst search.results=Zoek resultaat voor "%s" in %s +search.code_no_results=Geen broncode gevonden die aan uw zoekterm voldoet. +search.code_search_unavailable=Er is momenteel geen code zoekfunctie beschikbaar. Neem contact op met uw sitebeheerder. settings=Instellingen settings.desc=In de instellingen kan je de instellingen van de repository aanpassen @@ -1431,14 +1764,14 @@ settings.mirror_settings=Kopie Settings settings.mirror_settings.direction=Richting settings.mirror_settings.direction.pull=Pull settings.mirror_settings.direction.push=Push +settings.mirror_settings.last_update=Laatst bijgewerkt +settings.mirror_settings.push_mirror.none=Geen spiegels geconfigureerd +settings.mirror_settings.push_mirror.add=Voeg Push Mirror toe settings.sync_mirror=Synchroniseer settings.mirror_sync_in_progress=Mirror-synchronisatie is momenteel bezig - kom later terug. -settings.email_notifications.enable=E-mailnotificaties inschakelen -settings.email_notifications.onmention=Alleen e-mail op vermelding -settings.email_notifications.disable=E-mailnotificaties uitschakelen -settings.email_notifications.submit=E-mailvoorkeur instellen settings.site=Website settings.update_settings=Instellingen bewerken +settings.branches.update_default_branch=Standaard branch bijwerken settings.advanced_settings=Geavanceerde opties settings.wiki_desc=Repository-wiki inschakelen settings.use_internal_wiki=Ingebouwde wiki gebruiken @@ -1616,6 +1949,22 @@ settings.hook_type=Type hook settings.slack_token=Slack token settings.slack_domain=Slack domein settings.slack_channel=Slack kanaal +settings.web_hook_name_gitea=Gitea +settings.web_hook_name_gogs=Gogs +settings.web_hook_name_slack=Slack +settings.web_hook_name_discord=Discord +settings.web_hook_name_dingtalk=DingTalk +settings.web_hook_name_telegram=Telegram +settings.web_hook_name_matrix=Matrix +settings.web_hook_name_msteams=Microsoft Teams +settings.web_hook_name_feishu_or_larksuite=Feishu / Lark Suite +settings.web_hook_name_feishu=Feishu +settings.web_hook_name_larksuite=Lark Suite +settings.web_hook_name_wechatwork=WeCom (Wechat Work) +settings.web_hook_name_packagist=Packagist +settings.packagist_username=Packagist gebruikersnaam +settings.packagist_api_token=API token +settings.packagist_package_url=Packagist pakket URL settings.deploy_keys=Installeer sleutels settings.add_deploy_key=Toevoegen deploy sleutel settings.deploy_key_desc=Deploy keys hebben alleen-lezen pull-toegang tot de repository. @@ -1654,6 +2003,7 @@ settings.protect_merge_whitelist_committers_desc=Sta alleen gebruikers of teams settings.protect_merge_whitelist_users=Toegestane gebruikers voor samenvoegen: settings.protect_merge_whitelist_teams=Toegestane teams voor samenvoegen: settings.protect_check_status_contexts=Status controle inschakelen +settings.protect_check_status_contexts_desc=Statuscontroles zijn vereist om te kunnen samenvoegen. Kies welke statuscontroles moeten slagen voordat branches kunnen worden samengevoegd tot een branch die aan deze regel voldoet. Wanneer ingeschakeld, moeten commits eerst naar een andere branch worden gepusht, vervolgens samengevoegd of gepusht worden naar een branch die overeenkomt met deze regel nadat de statuscontroles zijn uitgevoerd. Als er geen contexten worden geselecteerd, moet de laatste commit succesvol zijn, ongeacht de context. settings.protect_check_status_contexts_list=Status controles gevonden in de afgelopen week voor deze repository settings.protect_required_approvals=Vereiste goedkeuringen: settings.protect_required_approvals_desc=Sta alleen toe om pull request samen te voegen met voldoende positieve beoordelingen. @@ -1666,6 +2016,9 @@ settings.dismiss_stale_approvals_desc=Wanneer nieuwe commits die de inhoud van h settings.require_signed_commits=Ondertekende Commits vereisen settings.require_signed_commits_desc=Weiger pushes naar deze branch als deze niet ondertekend of niet verifieerbaar is. settings.protect_protected_file_patterns=Beschermde bestandspatronen (gescheiden door een puntkomma '\;'): +settings.protect_protected_file_patterns_desc=Beschermde bestanden die niet direct gewijzigd mogen worden, zelfs als de gebruiker het recht heeft om bestanden in deze branch toe te voegen, te bewerken of te verwijderen. Meerdere patronen kunnen worden gescheiden met een puntkomma ('\;'). Zie github.com/gobwas/glob documentatie voor patroon syntax. Voorbeelden: .drone.yml, /docs/**/*.txt. +settings.protect_unprotected_file_patterns=Onbeschermde bestandspatronen (gescheiden met een puntkomma '\;'): +settings.protect_unprotected_file_patterns_desc=Onbeschermde bestanden die direct mogen worden gewijzigd als gebruiker schrijfrechten heeft, waardoor push-beperking wordt omzeild. Meerdere patronen kunnen worden gescheiden met behulp van een puntkomma ('\;'). Zie github.com/gobwas/glob documentatie voor patroon syntax. Voorbeelden: .drone.yml, /docs/**/*.txt. settings.add_protected_branch=Bescherming aanzetten settings.delete_protected_branch=Bescherming uitzetten settings.update_protect_branch_success=Branch bescherming voor branch '%s' is bijgewerkt. @@ -1674,16 +2027,26 @@ settings.protected_branch_deletion=Branch bescherming uitschakelen settings.protected_branch_deletion_desc=Branch bescherming uitschakelen zorgt ervoor dat gebruikers met schrijfrechten naar de branch kunnen pushen. Doorgaan? settings.block_rejected_reviews=Samenvoegen van afgewezen beoordelingen blokkeren settings.block_rejected_reviews_desc=Samenvoegen zal niet mogelijk zijn wanneer er wijzigingen worden aangevraagd door officiële beoordelaars, zelfs niet als er genoeg goedkeuringen zijn. +settings.block_on_official_review_requests=Blokkeer de samenvoeging van officiële beoordelingsverzoeken +settings.block_on_official_review_requests_desc=Samenvoegen is niet mogelijk wanneer het officiële herzieningsverzoeken heeft, ook al zijn er genoeg goedkeuringen. settings.block_outdated_branch=Samenvoegen blokkeren als pull request verouderd is settings.block_outdated_branch_desc=Samenvoegen is niet mogelijk als de hoofd branch achter loop op de basis branch. settings.default_branch_desc=Selecteer een standaard repository branch voor pull requests en code commits: +settings.default_merge_style_desc=Standaard samenvoegstijl voor pull verzoeken: settings.choose_branch=Kies een branch… settings.no_protected_branch=Er zijn geen beschermde branches. settings.edit_protected_branch=Bewerken settings.protected_branch_required_approvals_min=Vereiste goedkeuringen kunnen niet negatief zijn. settings.tags=Labels +settings.tags.protection=Label Bescherming +settings.tags.protection.pattern=Label Patroon settings.tags.protection.allowed=Toegestaan +settings.tags.protection.allowed.users=Toegestane gebruikers +settings.tags.protection.allowed.teams=Toegestane teams settings.tags.protection.allowed.noone=Niemand +settings.tags.protection.create=Beveilig Label +settings.tags.protection.none=Er zijn geen beveiligde labels. +settings.tags.protection.pattern.description=U kunt een enkele naam gebruiken of een glob patroon of reguliere expressie om meerdere labels te matchen. Lees meer in de beschermde labels gids. settings.bot_token=Bot Token settings.chat_id=Chat-ID settings.matrix.homeserver_url=Homeserver URL @@ -1697,6 +2060,7 @@ settings.archive.success=De repo is succesvol gearchiveerd. settings.archive.error=Er is een fout opgetreden tijdens het archiveren van de repo. Zie het logboek voor meer informatie. settings.archive.error_ismirror=U kunt geen gespiegelde repo archiveren. settings.archive.branchsettings_unavailable=Branch instellingen zijn niet beschikbaar als de repo is gearchiveerd. +settings.archive.tagsettings_unavailable=Labelinstellingen zijn niet beschikbaar als de repo is gearchiveerd. settings.unarchive.button=Repo De-Archiveren settings.unarchive.header=Deze Repo de-archiveren settings.unarchive.text=De-Archiveren van de repo herstelt zijn vermogen om commits en pushes te ontvangen, evenals nieuwe problemen en pull-requests. @@ -1728,6 +2092,12 @@ settings.lfs_pointers.inRepo=In Repo settings.lfs_pointers.exists=Bestaat in opslag settings.lfs_pointers.accessible=Toegankelijk voor gebruiker settings.lfs_pointers.associateAccessible=Koppel toegankelijke %d OIDs +settings.rename_branch_failed_exist=Kan branch niet hernoemen omdat doel branch %s bestaat. +settings.rename_branch_failed_not_exist=Kan branch %s niet hernoemen omdat deze niet bestaat. +settings.rename_branch_success=Branch %s is succesvol hernoemd naar %s. +settings.rename_branch_from=oude branch naam +settings.rename_branch_to=nieuwe branch naam +settings.rename_branch=Hernoem branch diff.browse_source=Bladeren bron diff.parent=bovenliggende @@ -1746,7 +2116,9 @@ diff.whitespace_ignore_all_whitespace=Witruimte negeren bij het vergelijken van diff.whitespace_ignore_amount_changes=Negeer veranderingen in de hoeveelheid witruimte diff.whitespace_ignore_at_eol=Negeren van wijzigingen in witruimte op EOL diff.stats_desc=%d gewijzigde bestanden met toevoegingen van %d en %d verwijderingen +diff.stats_desc_file=%d wijzigingen: %d toevoegingen en %d verwijderingen diff.bin=BIN +diff.bin_not_shown=Binair bestand niet weergegeven. diff.view_file=Bestand weergeven diff.file_before=Voor diff.file_after=Na @@ -1754,6 +2126,12 @@ diff.file_image_width=Breedte diff.file_image_height=Hoogte diff.file_byte_size=Grootte diff.file_suppressed=Diff onderdrukt omdat het te groot bestand +diff.file_suppressed_line_too_long=Bestand-diff onderdrukt omdat een of meer regels te lang zijn +diff.too_many_files=Sommige bestanden werden niet getoond omdat er teveel bestanden zijn veranderd in deze diff +diff.show_more=Meer weergeven +diff.load=Laad Diff +diff.generated=gegenereerd +diff.vendored=vendored diff.comment.placeholder=Opmerking toevoegen diff.comment.markdown_info=Styling met markdown wordt ondersteund. diff.comment.add_single_comment=Één reactie toevoegen @@ -1768,13 +2146,20 @@ diff.review.approve=Goedkeuren diff.review.reject=Wijzigingen aanvragen diff.committed_by=gecommit door diff.protected=Beveiligd +diff.image.side_by_side=Zij aan zij +diff.image.swipe=Vegen +diff.image.overlay=Overlay +diff.has_escaped=Deze regel heeft verborgen Unicode-tekens releases.desc=Volg de projectversies en downloads. release.releases=Publicaties +release.detail=Release details +release.tags=Labels release.new_release=Nieuwe release release.draft=Concept release.prerelease=Voorlopige versie release.stable=Stabiel +release.compare=Vergelijk release.edit=bewerken release.ahead.commits=%d commits release.ahead.target=aan %s sinds deze release @@ -1955,6 +2340,7 @@ total=Totaal: %d dashboard.statistic=Overzicht dashboard.operations=Onderhoudswerkzaamheden dashboard.system_status=Systeemtatus +dashboard.statistic_info=De Gitea database heeft %d gebruikers, %d organisaties, %d openbare sleutels, %d repositories, %d volgers, %d sterren, %d acties, %d participanten, %d issues, %d reacties, %d sociale accounten, %d volgers, %d spiegels, %d publicaties, %d authenticatiebronnen, %d webhooks, %d mijlpalen, %d labels, %d hook taken, %d teams, %d bijgewerkte taken, %d bijlagen. dashboard.operation_name=Bewerking naam dashboard.operation_switch=Omschakelen dashboard.operation_run=Uitvoeren @@ -2020,6 +2406,7 @@ dashboard.total_gc_time=Totaal GC verwerkingstijd dashboard.total_gc_pause=Totaal GC verwerkingstijd dashboard.last_gc_pause=Laatste GC verwerkingstijd dashboard.gc_times=GC verwerkingen +dashboard.delete_old_system_notices=Verwijder alle oude systeemmededelingen uit de database users.user_manage_panel=Gebruikersaccount beheer users.new_account=Nieuw account aanmaken @@ -2069,7 +2456,7 @@ emails.filter_sort.email=E-mail emails.filter_sort.email_reverse=E-mail (omgekeerd) emails.filter_sort.name=Gebruikersnaam emails.filter_sort.name_reverse=Gebruikersnaam (omgekeerd) -emails.updated=E-mail bijgewerkt +emails.updated=E-mailadres bijgewerkt emails.not_updated=Bijwerken van het gevraagde e-mailadres is mislukt: %v emails.duplicate_active=Dit e-mailadres is al actief voor een andere gebruiker. emails.change_email_header=Update E-mail Eigenschappen @@ -2249,17 +2636,16 @@ config.queue_length=Lengte van wachtrij config.deliver_timeout=Bezorging verlooptijd config.skip_tls_verify=TLS-verificatie overslaan -config.mailer_config=SMTP Mailerconfiguatie config.mailer_enabled=Ingeschakeld -config.mailer_disable_helo=Schakel HELO uit config.mailer_name=Naam -config.mailer_host=Host +config.mailer_smtp_port=SMTP Poort config.mailer_user=Gebruiker config.mailer_use_sendmail=Gebruik Sendmail config.mailer_sendmail_path=Sendmail pad config.mailer_sendmail_args=Extra argumenten voor Sendmail config.mailer_sendmail_timeout=Sendmail time-out -config.test_email_placeholder=E-mail (bijv. test@example.com) +config.mailer_use_dummy=Dummy +config.test_email_placeholder=E-mailadres (bijv. test@example.com) config.send_test_mail=Test e-mail verzenden config.test_mail_failed=Verzenden van een testmail naar '%s' is mislukt: %v config.test_mail_sent=Test-email is verstuurd naar '%s'. @@ -2320,6 +2706,7 @@ monitor.process=Draaiende processen monitor.desc=Omschrijving monitor.start=Starttijd monitor.execute_time=Uitvoertijd +monitor.last_execution_result=Resultaat monitor.process.cancel=Annuleer proces monitor.process.cancel_desc=Annuleren van een proces kan gegevensverlies veroorzaken monitor.process.cancel_notices=Annuleer: %s? @@ -2448,4 +2835,8 @@ error.no_unit_allowed_repo=U heeft geen toegang tot een enkele sectie van deze r error.unit_not_allowed=U heeft geen toegang tot deze sectie van de repository. [packages] +assets=Assets +rubygems.required.ruby=Vereist Ruby versie +rubygems.required.rubygems=Vereist RubyGem versie +settings.link.button=Repository link bijwerken diff --git a/options/locale/locale_pl-PL.ini b/options/locale/locale_pl-PL.ini index 3b65957bf5a91..f4a4521fb9c23 100644 --- a/options/locale/locale_pl-PL.ini +++ b/options/locale/locale_pl-PL.ini @@ -177,7 +177,6 @@ log_root_path_helper=Pliki logów będą zapisywane w tym katalogu. optional_title=Ustawienia opcjonalne email_title=Ustawienia e-mail -smtp_host=Serwer SMTP smtp_from=Wyślij e-mail jako smtp_from_helper=Adres e-mail, z którego Gitea będzie korzystać. Wpisz prosty adres e-mail, lub użyj formatu "Nazwa" . mailer_user=Nazwa użytkownika SMTP @@ -1299,7 +1298,6 @@ issues.due_date_form_remove=Usuń issues.due_date_not_writer=Potrzebujesz uprawnień zapisu w tym repozytorium, aby zaktualizować termin realizacji zgłoszenia. issues.due_date_not_set=Brak ustawionego terminu realizacji. issues.due_date_added=dodaje termin realizacji %s %s -issues.due_date_modified=zmienia termin realizacji na %s z %s %s issues.due_date_remove=usuwa termin realizacji %s %s issues.due_date_overdue=Zaległe issues.due_date_invalid=Data realizacji jest niewłaściwa lub spoza zakresu. Użyj formatu 'yyyy-mm-dd'. @@ -1388,7 +1386,6 @@ pulls.remove_prefix=Usuń %s prefiks pulls.data_broken=Ten Pull Request jest uszkodzony ze względu na brakujące informacje o forku. pulls.files_conflicted=Ten Pull Request zawiera zmiany konfliktujące z docelową gałęzią. pulls.is_checking=Sprawdzanie konfliktów ze scalaniem w toku. Spróbuj ponownie za chwilę. -pulls.is_empty=Ten branch jest równy z docelowym branch'em. pulls.required_status_check_failed=Niektóre kontrole stanów nie były pomyślne. pulls.required_status_check_missing=Brakuje pewnych wymaganych etapów. pulls.required_status_check_administrator=Jako administrator, możesz wciąż scalić ten Pull Request. @@ -1612,10 +1609,6 @@ settings.mirror_settings.push_mirror.none=Brak skonfigurowanych kopii zapasowych settings.mirror_settings.push_mirror.remote_url=Adres URL zdalnego repozytorium Git settings.sync_mirror=Synchronizuj teraz settings.mirror_sync_in_progress=Synchronizacja kopii lustrzanych jest w toku. Sprawdź ponownie za minutę. -settings.email_notifications.enable=Włącz powiadomienia e-mail -settings.email_notifications.onmention=Wyślij wiadomość e-mail wyłącznie przy wzmiankach -settings.email_notifications.disable=Wyłącz powiadomienia e-mail -settings.email_notifications.submit=Ustaw preferencje wiadomości e-mail settings.site=Strona settings.update_settings=Aktualizuj ustawienia settings.branches.update_default_branch=Aktualizuj domyślną gałąź @@ -2500,11 +2493,8 @@ config.queue_length=Długość kolejki config.deliver_timeout=Limit czasu doręczenia config.skip_tls_verify=Pomiń weryfikację TLS -config.mailer_config=Konfiguracja dostawcy SMTP config.mailer_enabled=Włączona -config.mailer_disable_helo=Wyłącz HELO config.mailer_name=Nazwa -config.mailer_host=Serwer config.mailer_user=Użytkownik config.mailer_use_sendmail=Używaj Sendmail config.mailer_sendmail_path=Ścieżka Sendmail diff --git a/options/locale/locale_pt-BR.ini b/options/locale/locale_pt-BR.ini index 3bf98901acf47..765c69b8d7414 100644 --- a/options/locale/locale_pt-BR.ini +++ b/options/locale/locale_pt-BR.ini @@ -179,7 +179,8 @@ log_root_path_helper=Arquivos de log serão gravados neste diretório. optional_title=Configurações opcionais email_title=Configurações de e-mail -smtp_host=Host SMTP +smtp_addr=Host SMTP +smtp_port=Porta SMTP smtp_from=Enviar e-mail como smtp_from_helper=Endereço de e-mail que o Gitea irá usar. Digite um endereço de e-mail simples ou use o formato "Nome" . mailer_user=Nome de usuário do SMTP @@ -799,6 +800,7 @@ email_notifications.enable=Habilitar notificações de e-mail email_notifications.onmention=Somente e-mail com menção email_notifications.disable=Desabilitar notificações de e-mail email_notifications.submit=Atualizar preferências de e-mail +email_notifications.andyourown=E Suas Próprias Notificações visibility=Visibilidade do usuário visibility.public=Pública @@ -861,7 +863,9 @@ default_branch=Branch Padrão default_branch_helper=O branch padrão é o branch base para pull requests e commits de código. mirror_prune=Varrer mirror_prune_desc=Remover referências obsoletas de controle remoto +mirror_interval=Intervalo de espelhamento (unidades válidas são 'h', 'm', ou 's'). O desabilita a sincronização automática. (Intervalo mínimo: %s) mirror_interval_invalid=O intervalo do espelhamento não é válido. +mirror_sync_on_commit=Sincronizar quando commits forem enviados mirror_address=Clonar de URL mirror_address_desc=Coloque todas as credenciais necessárias na seção de autorização. mirror_address_url_invalid=A url fornecida é inválida. Você deve escapar todos os componentes da url corretamente. @@ -930,6 +934,7 @@ form.name_pattern_not_allowed=O padrão de '%s' não é permitido em um nome de need_auth=Autorização migrate_options=Opções de Migração migrate_service=Serviço de Migração +migrate_options_mirror_helper=Este repositório será um espelho migrate_options_lfs=Migrar arquivos LFS migrate_options_lfs_endpoint.label=Destino LFS migrate_options_lfs_endpoint.description=A migração tentará usar seu controle remoto Git para determinar o servidor LFS. Você também pode especificar um destino personalizado se os dados do repositório LFS forem armazenados em outro lugar. @@ -1300,6 +1305,7 @@ issues.previous=Anterior issues.next=Próximo issues.open_title=Aberto issues.closed_title=Fechado +issues.draft_title=Rascunho issues.num_comments=%d comentários issues.commented_at=`comentou %s` issues.delete_comment_confirm=Tem certeza que deseja excluir este comentário? @@ -1416,7 +1422,7 @@ issues.due_date_form_remove=Remover issues.due_date_not_writer=Você deve ter permissão de escrita no repositório para atualizar a data limite de uma issue. issues.due_date_not_set=Data limite não informada. issues.due_date_added=adicionou a data limite %s %s -issues.due_date_modified=modificou a data limite para %s ao invés de %s %s +issues.due_date_modified=modificou a data limite de %[2]para %[1]s %[3]s issues.due_date_remove=removeu a data limite %s %s issues.due_date_overdue=Em atraso issues.due_date_invalid=A data limite é inválida ou está fora do intervalo. Por favor, use o formato 'dd/mm/aaaa'. @@ -1490,6 +1496,7 @@ pulls.new=Novo pull request pulls.view=Ver Pull Request pulls.compare_changes=Novo pull request pulls.allow_edits_from_maintainers=Permitir edições de mantenedores +pulls.allow_edits_from_maintainers_desc=Usuários com acesso de gravação para o branch base também podem fazer push para este branch pulls.allow_edits_from_maintainers_err=Falha na atualização pulls.compare_changes_desc=Selecione o branch de destino (push) e o branch de origem (pull) para o merge. pulls.has_viewed_file=Visto @@ -1527,7 +1534,7 @@ pulls.remove_prefix=Remover o prefixo %s pulls.data_broken=Este pull request está quebrado devido a falta de informação do fork. pulls.files_conflicted=Este pull request tem alterações conflitantes com o branch de destino. pulls.is_checking=Verificação de conflitos do merge está em andamento. Tente novamente em alguns momentos. -pulls.is_empty=Este branch é igual ao branch de destino. +pulls.is_empty=As alterações neste branch já estão na branch de destino. Este será um commit vazio. pulls.required_status_check_failed=Algumas verificações necessárias não foram bem sucedidas. pulls.required_status_check_missing=Estão faltando algumas verificações necessárias. pulls.required_status_check_administrator=Como administrador, você ainda pode aplicar o merge deste pull request. @@ -1595,9 +1602,17 @@ pulls.merge_instruction_step1_desc=No repositório do seu projeto, crie um novo pulls.merge_instruction_step2_desc=Faça merge das alterações e atualize no Gitea. pulls.auto_merge_button_when_succeed=(Quando a verificação for bem-sucedida) +pulls.auto_merge_when_succeed=Mesclar automaticamente quando todas as verificações forem bem sucedidas +pulls.auto_merge_newly_scheduled=O merge do pull request foi agendado para quando todas as verificações forem bem-sucedidas. +pulls.auto_merge_cancel_schedule=Cancelar merge automático +pulls.auto_merge_not_scheduled=Este pull request não está programado para ser automaticamente mesclado. +pulls.auto_merge_canceled_schedule=O merge automático foi cancelado para este pull request. +pulls.auto_merge_canceled_schedule_comment=`cancelou o merge automático deste pull request quando todos as verificações tiverem sucesso %[1]s` +pulls.delete.title=Excluir este pull request? +pulls.delete.text=Você realmente deseja excluir este pull request? (Isto irá remover permanentemente todo o conteúdo. Considere fechá-la em vez disso, se você pretende mantê-la arquivado) milestones.new=Novo marco milestones.closed=Fechado %s @@ -1768,10 +1783,6 @@ settings.mirror_settings.push_mirror.remote_url=URL do repositório do Git remot settings.mirror_settings.push_mirror.add=Adicionar Espelho de Push settings.sync_mirror=Sincronizar agora settings.mirror_sync_in_progress=Sincronização do espelhamento está em andamento. Verifique novamente em um minuto. -settings.email_notifications.enable=Habilitar notificações de e-mail -settings.email_notifications.onmention=Somente e-mail com menção -settings.email_notifications.disable=Desabilitar notificações de e-mail -settings.email_notifications.submit=Atualizar preferências de e-mail settings.site=Site settings.update_settings=Atualizar configurações settings.branches.update_default_branch=Atualizar Branch Padrão @@ -1793,6 +1804,7 @@ settings.tracker_url_format_error=O formato da URL do issue tracker externo não settings.tracker_issue_style=Formato de número do issue tracker externo settings.tracker_issue_style.numeric=Numérico settings.tracker_issue_style.alphanumeric=Alfanumérico +settings.tracker_issue_style.regexp=Expressão Regular settings.tracker_url_format_desc=Use os espaços reservados {user}, {repo} e {index} para o nome de usuário, nome do repositório e o índice de problemas. settings.enable_timetracker=Habilitar Cronômetro settings.allow_only_contributors_to_track_time=Permitir que apenas os colaboradores acompanhem o contador de tempo @@ -2268,6 +2280,8 @@ topic.done=Feito topic.count_prompt=Você não pode selecionar mais de 25 tópicos topic.format_prompt=Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres. +find_file.go_to_file=Ir para arquivo +find_file.no_matching=Nenhum arquivo correspondente encontrado error.csv.too_large=Não é possível renderizar este arquivo porque ele é muito grande. error.csv.unexpected=Não é possível renderizar este arquivo porque ele contém um caractere inesperado na linha %d e coluna %d. @@ -2517,6 +2531,8 @@ users.delete_account=Excluir conta de usuário users.cannot_delete_self=Você não pode excluir você mesmo users.still_own_repo=Este usuário ainda possui um ou mais repositórios. Exclua ou transfira esses repositórios primeiro. users.still_has_org=Este usuário é membro de uma organização. Remova o usuário de qualquer organização primeiro. +users.purge=Eliminar usuário +users.purge_help=Exclua forçosamente o usuário e quaisquer repositórios, organizações e pacotes pertencentes ao usuário. Todos os comentários também serão excluídos. users.still_own_packages=Este usuário ainda possui um ou mais pacotes. Exclua esses pacotes primeiro. users.deletion_success=A conta de usuário foi excluída. users.reset_2fa=Reinicializar 2FA @@ -2759,11 +2775,11 @@ config.queue_length=Tamanho da fila config.deliver_timeout=Intervalo de entrega config.skip_tls_verify=Ignorar verificação de TLS -config.mailer_config=Configuração SMTP para envio de e-mail +config.mailer_config=Configuração de Envio de E-mail config.mailer_enabled=Habilitado -config.mailer_disable_helo=Desabilitar HELO config.mailer_name=Nome -config.mailer_host=Servidor +config.mailer_protocol=Protocolo +config.mailer_smtp_port=Porta SMTP config.mailer_user=Usuário config.mailer_use_sendmail=Usar o Sendmail config.mailer_sendmail_path=Caminho do Sendmail diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini index 176537129ccca..50b92a95c58b8 100644 --- a/options/locale/locale_pt-PT.ini +++ b/options/locale/locale_pt-PT.ini @@ -179,7 +179,8 @@ log_root_path_helper=Os ficheiros de registo serão escritos nesta pasta. optional_title=Configurações opcionais email_title=Configurações de email -smtp_host=Servidor SMTP +smtp_addr=Servidor SMTP +smtp_port=Porto do SMTP smtp_from=Email do remetente smtp_from_helper=Endereço de email que o Gitea vai usar. Insira um endereço de email simples ou use o formato "Nome" . mailer_user=Nome de utilizador do SMTP @@ -799,6 +800,7 @@ email_notifications.enable=Habilitar notificações por email email_notifications.onmention=Enviar email somente quando mencionado(a) email_notifications.disable=Desabilitar notificações por email email_notifications.submit=Definir preferência do email +email_notifications.andyourown=e as suas próprias notificações visibility=Visibilidade do utilizador visibility.public=Pública @@ -1532,7 +1534,8 @@ pulls.remove_prefix=Remover o prefixo %s pulls.data_broken=Este pedido de integração está danificado devido à falta de informação da derivação. pulls.files_conflicted=Este pedido de integração contém modificações que entram em conflito com o ramo de destino. pulls.is_checking=Está em andamento uma verificação de conflitos na integração. Tente novamente daqui a alguns momentos. -pulls.is_empty=Este ramo é igual ao ramo de destino. +pulls.is_ancestor=Este ramo já está incluído no ramo de destino. Não há nada a integrar. +pulls.is_empty=As modificações feitas neste ramo já existem no ramo de destino. Este cometimento ficará vazio. pulls.required_status_check_failed=Algumas das verificações obrigatórias não foram bem sucedidas. pulls.required_status_check_missing=Estão faltando algumas verificações necessárias. pulls.required_status_check_administrator=Uma vez que é administrador, ainda pode realizar a integração deste pedido. @@ -1783,10 +1786,6 @@ settings.mirror_settings.push_mirror.remote_url=URL do repositório remoto Git settings.mirror_settings.push_mirror.add=Adicionar réplica de envio settings.sync_mirror=Sincronizar agora settings.mirror_sync_in_progress=A sincronização da réplica está em andamento. Volte a verificar daqui a um minuto. -settings.email_notifications.enable=Habilitar notificações por email -settings.email_notifications.onmention=Enviar email somente quando mencionado(a) -settings.email_notifications.disable=Desabilitar notificações por email -settings.email_notifications.submit=Definir preferência do email settings.site=Sítio web settings.update_settings=Modificar configurações settings.branches.update_default_branch=Definir o ramo principal @@ -2539,6 +2538,8 @@ users.delete_account=Eliminar conta de utilizador users.cannot_delete_self=Não se pode eliminar a si próprio users.still_own_repo=Este utilizador ainda possui um ou mais repositórios. Elimine ou transfira esses repositórios primeiro. users.still_has_org=Este utilizador é membro de uma organização. Remova, primeiro, o utilizador de todas as organizações. +users.purge=Eliminar utilizador +users.purge_help=Eliminar o utilizador à força, juntamente com todos os seus repositórios, organizações e pacotes. Também serão eliminados todos os seus comentários. users.still_own_packages=Este utilizador ainda possui um ou mais pacotes. Elimine esses pacotes primeiro. users.deletion_success=A conta de utilizador foi eliminada. users.reset_2fa=Reinicializar a autenticação em dois passos @@ -2795,16 +2796,19 @@ config.queue_length=Tamanho da fila config.deliver_timeout=Prazo da entrega config.skip_tls_verify=Ignorar validação TLS -config.mailer_config=Configuração da aplicação SMTP +config.mailer_config=Configuração de envio de email config.mailer_enabled=Habilitado -config.mailer_disable_helo=Desabilitar HELO +config.mailer_enable_helo=Habilitar HELO config.mailer_name=Nome -config.mailer_host=Servidor +config.mailer_protocol=Protocolo +config.mailer_smtp_addr=Endereço SMTP +config.mailer_smtp_port=Porto do SMTP config.mailer_user=Utilizador config.mailer_use_sendmail=Usar o sendmail config.mailer_sendmail_path=Caminho do sendmail config.mailer_sendmail_args=Argumentos extras para o sendmail config.mailer_sendmail_timeout=Tempo limite do Sendmail +config.mailer_use_dummy=Fictício config.test_email_placeholder=Email (ex.: teste@exemplo.com) config.send_test_mail=Enviar email de teste config.test_mail_failed=Falhou o envio de um email de teste para '%s': %v @@ -3041,6 +3045,7 @@ title=Pacotes desc=Gerir pacotes do repositório. empty=Ainda não há pacotes. empty.documentation=Para obter mais informação sobre o registo de pacotes, veja a documentação. +empty.repo=Carregou um pacote mas este não é apresentado aqui? Vá às configurações do pacote e ligue-o a este repositório. filter.type=Tipo filter.type.all=Todos filter.no_result=O seu filtro não produziu quaisquer resultados. @@ -3113,6 +3118,8 @@ rubygems.install=Para instalar o pacote usando o gem, execute o seguinte comando rubygems.install2=ou adicione-o ao ficheiro Gemfile: rubygems.dependencies.runtime=Dependências do tempo de execução (runtime) rubygems.dependencies.development=Dependências de desenvolvimento +rubygems.required.ruby=Requer a versão do Ruby +rubygems.required.rubygems=Requer a versão do RubyGem rubygems.documentation=Para obter mais informações sobre o registo do RubyGems, consulte a documentação. settings.link=Vincular este pacote a um repositório settings.link.description=Se você vincular um pacote a um repositório, o pacote será listado na lista de pacotes do repositório. diff --git a/options/locale/locale_ru-RU.ini b/options/locale/locale_ru-RU.ini index 555959b5124c9..35fc93d441b86 100644 --- a/options/locale/locale_ru-RU.ini +++ b/options/locale/locale_ru-RU.ini @@ -2,6 +2,7 @@ home=Главная dashboard=Панель управления explore=Обзор help=Помощь +logo=Логотип sign_in=Вход sign_in_with=Войдите с помощью sign_out=Выход @@ -176,7 +177,6 @@ log_root_path_helper=Файлы журнала будут записыватьс optional_title=Расширенные настройки email_title=Настройки электронной почты -smtp_host=Узел SMTP smtp_from=Отправить эл. почту как smtp_from_helper=Адрес электронной почты, который будет использоваться Gitea. Введите обычный адрес электронной почты или используйте формат "Имя" . mailer_user=SMTP логин @@ -1260,6 +1260,7 @@ issues.previous=Предыдущая issues.next=Следующая issues.open_title=Открыто issues.closed_title=Закрыто +issues.draft_title=Черновик issues.num_comments=комментариев: %d issues.commented_at=`прокомментировал(а) %s` issues.delete_comment_confirm=Вы уверены, что хотите удалить этот комментарий? @@ -1281,7 +1282,7 @@ issues.reopened_at=`переоткрыл(а) эту проблему %[2]s` issues.ref_issue_from=`ссылка на эту проблему %[4]s %[2]s` issues.ref_pull_from=`ссылается на этот запрос на слияние %[4]s %[2]s` -issues.ref_closing_from=`ссылается на запрос на слияние %[4], который закроет эту задачу %[2]s` +issues.ref_closing_from=`ссылается на запрос на слияние %[4]s, который закроет эту задачу %[2]s` issues.ref_reopening_from=`ссылается на запрос на слияние %[4]s, который вновь откроет эту задачу %[2]s` issues.ref_closed_from=`закрыл этот запрос %[4]s %[2]s` issues.ref_reopened_from=`переоткрыл эту задачу %[4]s %[2]s` @@ -1376,7 +1377,6 @@ issues.due_date_form_remove=Удалить issues.due_date_not_writer=Для обновления срока выполнения необходим доступ на запись в репозиторий. issues.due_date_not_set=Срок выполнения не установлен. issues.due_date_added=добавлено в срок выполнения %s %s -issues.due_date_modified=срок выполнения изменён на %s с %s %s issues.due_date_remove=удалён срок выполнения %s %s issues.due_date_overdue=Просроченные issues.due_date_invalid=Срок действия недействителен или находится за пределами допустимого диапазона. Пожалуйста, используйте формат 'гггг-мм-дд'. @@ -1480,7 +1480,6 @@ pulls.remove_prefix=Удалить %s префикс pulls.data_broken=Содержимое этого запроса было нарушено вследствие удаления информации форка. pulls.files_conflicted=Этот запрос на слияние имеет изменения конфликтующие с целевой веткой. pulls.is_checking=Продолжается проверка конфликтов, пожалуйста обновите страницу несколько позже. -pulls.is_empty=Ветвь идентична с целевой. pulls.required_status_check_failed=Некоторые необходимые проверки не были пройдены. pulls.required_status_check_missing=Отсутствуют некоторые обязательные проверки. pulls.required_status_check_administrator=Как администратор, вы все равно можете принять этот запрос на слияние. @@ -1718,10 +1717,6 @@ settings.mirror_settings.push_mirror.remote_url=URL удалённого хра settings.mirror_settings.push_mirror.add=Добавить Push-зеркало settings.sync_mirror=Синхронизировать settings.mirror_sync_in_progress=Синхронизируются репозитории-зеркала. Подождите минуту и обновите страницу. -settings.email_notifications.enable=Включить почтовые уведомления -settings.email_notifications.onmention=Посылать письмо на эл. почту только при упоминании -settings.email_notifications.disable=Отключить почтовые уведомления -settings.email_notifications.submit=Установить настройки электронной почты settings.site=Сайт settings.update_settings=Обновить настройки settings.branches.update_default_branch=Обновить ветку по умолчанию @@ -2685,11 +2680,8 @@ config.queue_length=Длина очереди config.deliver_timeout=Задержка доставки config.skip_tls_verify=Пропустить проверку TLS -config.mailer_config=Настройки почты config.mailer_enabled=Почта включена -config.mailer_disable_helo=Отключить HELO config.mailer_name=Имя -config.mailer_host=Сервер config.mailer_user=Пользователь config.mailer_use_sendmail=Использовать Sendmail config.mailer_sendmail_path=Путь к Sendmail @@ -2934,6 +2926,8 @@ installation=Установка about=Об этом пакете requirements=Требования dependencies=Зависимости +composer.dependencies=Зависимости +conan.details.repository=Репозиторий container.multi_arch=ОС / архитектура container.labels.key=Ключ container.labels.value=Значение diff --git a/options/locale/locale_si-LK.ini b/options/locale/locale_si-LK.ini index be82918627dc7..17fbf544671f5 100644 --- a/options/locale/locale_si-LK.ini +++ b/options/locale/locale_si-LK.ini @@ -151,7 +151,6 @@ log_root_path_helper=ලොග් ගොනු මෙම ඩිරෙක්ට optional_title=වෛකල්පිත සැකසුම් email_title=වි-තැපෑලේ සැකසුම් -smtp_host=SMTP සත්කාරක smtp_from=ලෙස වි-තැපෑල යවන්න smtp_from_helper=විද්යුත් තැපැල් ලිපිනය Gitea භාවිතා කරනු ඇත. සරල විද්යුත් තැපැල් ලිපිනයක් ඇතුළත් කරන්න හෝ “නම” ආකෘතිය භාවිතා කරන්න. mailer_user=SMTP පරිශීලක නාමය @@ -1254,7 +1253,6 @@ issues.due_date_form_remove=ඉවත් කරන්න issues.due_date_not_writer=ඔබ නිකුත් ගේ නියමිත දිනය යාවත්කාලීන කිරීමට ගබඩාවක් ලිවීමට ප්රවේශය අවශ්ය. issues.due_date_not_set=නියමිත දිනය නියම කර නැත. issues.due_date_added=නියමිත දිනය එකතු %s %s -issues.due_date_modified=නියමිත දිනය %s සිට %s %sදක්වා වෙනස් කරන ලදි issues.due_date_remove=නියමිත දිනය ඉවත් කරන ලදි %s %s issues.due_date_overdue=කල් ඉකුත්වීම issues.due_date_invalid=නියමිත දිනය අවලංගු හෝ පරාසයෙන් බැහැර වේ. කරුණාකර 'yyyy-mm-dd' ආකෘතිය භාවිතා කරන්න. @@ -1355,7 +1353,6 @@ pulls.remove_prefix=%s උපසර්ගය ඉවත් ක pulls.data_broken=අතුරුදහන් වූ දෙබලක තොරතුරු හේතුවෙන් මෙම අදින්න ඉල්ලීම කැඩී ඇත. pulls.files_conflicted=මෙම අදින්න ඉල්ලීම ඉලක්කගත ශාඛාව සමග එකිනෙකට වෙනස් වෙනස්කම් ඇත. pulls.is_checking=ගැටුම් පරීක්ෂා කිරීම ඒකාබද්ධ කිරීම ක්රියාත්මක වෙමින් පවතී. සුළු මොහොතකින් නැවත උත්සාහ කරන්න. -pulls.is_empty=මෙම ශාඛාව ඉලක්කගත ශාඛාව සමග සමාන වේ. pulls.required_status_check_failed=සමහර අවශ්ය චෙක්පත් සාර්ථක නොවීය. pulls.required_status_check_missing=සමහර අවශ්ය චෙක්පත් අස්ථානගත වී ඇත. pulls.required_status_check_administrator=පරිපාලකයෙකු ලෙස, ඔබ තවමත් මෙම අදින්න ඉල්ලීම ඒකාබද්ධ කළ හැකිය. @@ -1587,10 +1584,6 @@ settings.mirror_settings.push_mirror.remote_url=GIT දුරස්ථ ගබඩ settings.mirror_settings.push_mirror.add=Push මිරර් එකතු කරන්න settings.sync_mirror=සමමුහූර්ත කරන්න settings.mirror_sync_in_progress=මිරර් සමමුහුර්තකරණය ක්රියාත්මක වෙමින් පවතී. විනාඩියකින් නැවත පරීක්ෂා කරන්න. -settings.email_notifications.enable=වි-තැපැල් දැනුම්දීම් සබල කරන්න -settings.email_notifications.onmention=සැඳහුම් සඳහා තැපැල් කරන්න -settings.email_notifications.disable=වි-තැපැල් දැනුම්දීම් අබල කරන්න -settings.email_notifications.submit=ඊ-තැපැල් මනාප සකසන්න settings.site=වියමන අඩවිය settings.update_settings=යාවත්කාල සැකසුම් settings.branches.update_default_branch=පෙරනිමි ශාඛාව යාවත්කාල කරන්න @@ -2514,11 +2507,8 @@ config.queue_length=පෝලිම් දිග config.deliver_timeout=කාලය ගලවාගන්න config.skip_tls_verify=TLS සත්යාපනය මඟ හරින්න -config.mailer_config=SMTP තැපැල්කරු වින්යාසය config.mailer_enabled=සබල කර ඇත -config.mailer_disable_helo=හෙලෝ අක්රීය කරන්න config.mailer_name=නම -config.mailer_host=සත්කාරක config.mailer_user=පරිශීලක config.mailer_use_sendmail=සෙන්ඩ්මේල් භාවිතා කරන්න config.mailer_sendmail_path=සෙන්ඩ්මේල් මාර්ගය diff --git a/options/locale/locale_sv-SE.ini b/options/locale/locale_sv-SE.ini index e8458136b50da..3adf6ce0ab885 100644 --- a/options/locale/locale_sv-SE.ini +++ b/options/locale/locale_sv-SE.ini @@ -138,7 +138,6 @@ log_root_path_helper=Loggfiler kommer skrivas till denna katalog. optional_title=Övriga inställningar email_title=Mejlinställningar -smtp_host=SMTP-server smtp_from=Skicka Mejl Som smtp_from_helper=Mejladress som Gitea kommer att använda. Anges i simpelt ('email@example.com') eller fullständigt ('Name ') format. mailer_user=SMTP-Användarnamn @@ -1068,7 +1067,6 @@ issues.due_date_form_remove=Ta bort issues.due_date_not_writer=Du måste ha skrivrättigheter för att ändra ett ärendes förfallodatum. issues.due_date_not_set=Inget förfallodatum satt. issues.due_date_added=lade till förfallodatumet %s %s -issues.due_date_modified=ändrade förfallodatumet från %s till %s %s issues.due_date_remove=tog bort förfallodatumet %s %s issues.due_date_overdue=Försenad issues.due_date_invalid=Förfallodatumet är ogiltigt eller utanför gränserna. Använd formatet 'åååå-mm-dd'. @@ -1300,10 +1298,6 @@ settings.basic_settings=Basinställningar settings.mirror_settings=Inställningar för spegling settings.sync_mirror=Synkronisera nu settings.mirror_sync_in_progress=Synkronisering utav speglingar pågår. Kontrollera igen om en minut. -settings.email_notifications.enable=Aktivera notiser via mejl -settings.email_notifications.onmention=Endast e-post vid omnämnande -settings.email_notifications.disable=Inaktivera notiser via mejl -settings.email_notifications.submit=Ställ in e-postinställningar settings.site=Webbplats settings.update_settings=Uppdatera inställningar settings.advanced_settings=Advancerade Inställningar @@ -1974,11 +1968,8 @@ config.queue_length=Kölängd config.deliver_timeout=Tidsfrist för leverans config.skip_tls_verify=Skippa TLS verifiering -config.mailer_config=SMTP-Mailer konfiguration config.mailer_enabled=Aktiverad -config.mailer_disable_helo=Avaktivera HELO config.mailer_name=Namn -config.mailer_host=Server config.mailer_user=Användare config.mailer_use_sendmail=Använd Sendmail config.mailer_sendmail_path=Sendmail sökväg diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini index 6d3e03c2461aa..07565395cdbd0 100644 --- a/options/locale/locale_tr-TR.ini +++ b/options/locale/locale_tr-TR.ini @@ -2,6 +2,7 @@ home=Ana Sayfa dashboard=Pano explore=Keşfet help=Yardım +logo=Logo sign_in=Giriş Yap sign_in_with=Şununla giriş yap sign_out=Çıkış Yap @@ -34,6 +35,19 @@ twofa=İki Aşamalı Doğrulama twofa_scratch=İki aşamalı kazınmış kod passcode=Şifre +webauthn_insert_key=Güvenlik anahtarınızı ekleyin +webauthn_sign_in=Güvenlik anahtarınızdaki düğmeye basın. Eğer düğme yoksa güvenlik anahtarınızı tekrar ekleyin. +webauthn_press_button=Lütfen güvenlik anahtarınızdaki düğmeye basın… +webauthn_use_twofa=Telefonunuzdan iki aşamalı doğrulama kodu kullanın +webauthn_error=Güvenlik anahtarınız okunamıyor. +webauthn_unsupported_browser=Tarayıcınız henüz WebAuthn desteklemiyor. +webauthn_error_unknown=Bilinmeyen bir hata oluştu. Lütfen tekrar deneyin. +webauthn_error_insecure=WebAuthn sadece güvenli bağlantıyı destekler. HTTP üzerinden test etmek için "localhost" veya "127.0.0.1" adreslerini kullanabilirsiniz. +webauthn_error_unable_to_process=Sunucu isteğinizi işleyemedi. +webauthn_error_duplicated=Güvenlik anahtarının bu istek için izni yok. Anahtarın halihazırda kayıtlı olmadığından emin olun. +webauthn_error_empty=Bu anahtar için bir isim belirlemelisiniz. +webauthn_error_timeout=Anahtarınız okunamadan zaman aşımı oldu. Lütfen sayfayı yenileyin ve tekrar deneyin. +webauthn_reload=Yeniden yükle repository=Depo organization=Organizasyon @@ -91,9 +105,15 @@ error404=Ulaşmaya çalıştığınız sayfa mevcut değil veya never=Asla +rss_feed=RSS Beslemesi [error] +occurred=Bir hata oluştu +report_message=Bunun bir Gitea hatası olduğundan eminseniz, lütfen GitHub sayfasında sorunu arayın veya gerekiyorsa yeni bir sorun açın. missing_csrf=Hatalı İstek: CSRF anahtarı yok +invalid_csrf=Hatalı İstek: geçersiz CSRF erişim anahtarı +not_found=Hedef bulunamadı. +network_error=Ağ hatası [startpage] app_desc=Zahmetsiz, kendi sunucunuzda barındırabileceğiniz Git servisi @@ -159,7 +179,8 @@ log_root_path_helper=Günlük dosyaları bu dizine kaydedilecektir. optional_title=İsteğe Bağlı Ayarlar email_title=E-posta Ayarları -smtp_host=SMTP Sunucusu +smtp_addr=SMTP Sunucusu +smtp_port=SMTP Portu smtp_from=E-posta Gönderen smtp_from_helper=Gitea'nın kullanacağı e-posta adresi. Yalın bir e-posta adresi girin veya "İsim" biçimini kullanın. mailer_user=SMTP Kullanıcı Adı @@ -196,7 +217,10 @@ sqlite3_not_available=Bu Gieta sürümü SQLite3 desteklemiyor. Lütfen %s adres invalid_db_setting=Veritabanı ayarları geçersiz: %v invalid_db_table='%s' veritabanı tablosu geçersiz: %v invalid_repo_path=Depo kök dizini geçersiz: %v +invalid_app_data_path=Uygulama veri yolu geçersiz: %v run_user_not_match='Birlikte çalıştır' kullanıcı adı şimdiki kullanıcı adından farklıdır: %s -> %s +internal_token_failed=Dahili belirteç oluşturulamadı: %v +secret_key_failed=Gizli anahtar oluşturulamadı: %v save_config_failed=%v Yapılandırması kaydedilirken hata oluştu invalid_admin_setting=Yönetici hesap ayarları geçersiz: %v install_success=Hoşgeldiniz! Gitea'yı seçtiğiniz için teşekkür ederiz. Eğlenin ve kendinize iyi bakın! @@ -225,6 +249,7 @@ view_home=%s Görüntüle search_repos=Depo bul… filter=Diğer Süzgeçler filter_by_team_repositories=Takım depolarına göre süz +feed_of="%s" beslemesi show_archived=Arşivlenmiş show_both_archived_unarchived=Arşivlenenler ve arşivlenmeyenlerin hepsi gösteriliyor @@ -246,6 +271,7 @@ search=Ara code=Kod search.fuzzy=Belirsiz search.match=Eşleştir +code_search_unavailable=Kod arama şu an mevcut değil. Lütfen site yöneticinizle bağlantıya geçin. repo_no_results=Eşleşen bir depo bulunamadı. user_no_results=Eşleşen kullanıcı bulunamadı. org_no_results=Eşleşen organizasyon bulunamadı. @@ -259,6 +285,7 @@ register_helper_msg=Bir hesabınız var mı? Şimdi giriş yapın! social_register_helper_msg=Hesabınız var mı? Hemen bağlayın! disable_register_prompt=Kayıt işlemi devre dışıdır. Lütfen site yöneticinizle iletişim kurun. disable_register_mail=Kayıt için e-posta doğrulama devre dışıdır. +manual_activation_only=Etkinleştirmeyi tamamlamak için site yöneticinizle bağlantıya geçin. remember_me=Bu Aygıtı hatırla forgot_password_title=Şifremi unuttum forgot_password=Şifrenizi mi unuttunuz? @@ -297,6 +324,9 @@ oauth_signup_submit=Hesabı Tamamla oauth_signin_tab=Mevcut Hesaba Bağla oauth_signin_title=Bağlantılı Hesabı Yetkilendirmek için Giriş Yapın oauth_signin_submit=Hesabı Bağla +oauth.signin.error=Yetkilendirme isteğini işlerken bir hata oluştu. Eğer hata devam ederse lütfen site yöneticisiyle bağlantıya geçin. +oauth.signin.error.access_denied=Yetkilendirme isteği reddedildi. +oauth.signin.error.temporarily_unavailable=Yetkilendirme sunucusu geçici olarak erişilemez olduğu için yetkilendirme başarısız oldu. Lütfen daha sonra tekrar deneyin. openid_connect_submit=Bağlan openid_connect_title=Mevcut olan bir hesaba bağlan openid_connect_desc=Seçilen OpenID URI'si bilinmiyor. Burada yeni bir hesapla ilişkilendir. @@ -413,6 +443,7 @@ size_error=` uzunluk en fazla %s olmalıdır.` min_size_error=` en az %s karakter içermelidir.` max_size_error=` en fazla %s karakter içermelidir.` email_error=' geçerli bir e-posta adresi değil.' +url_error=`'%s' geçerli bir bağlantı değil.` include_error=` '%s' içermelidir.` glob_pattern_error=` glob deseni geçersiz: %s.` regex_pattern_error=` regex dizisi geçersiz: %s.` @@ -424,6 +455,7 @@ lang_select_error=Listeden bir dil seçin. username_been_taken=Bu kullanıcı adı daha önce alınmış. username_change_not_local_user=Yerel olmayan kullanıcılar kendi kullanıcı adlarını değiştiremezler. repo_name_been_taken=Depo adı zaten kullanılıyor. +repository_force_private=Gizliyi Zorla devrede: gizli depolar herkese açık yapılamaz. repository_files_already_exist=Bu depo için dosyalar zaten var. Sistem yöneticisine başvurun. repository_files_already_exist.adopt=Bu depo için dosyalar zaten var ve yalnızca Kabul Edilebilir. repository_files_already_exist.delete=Bu depo için dosyalar zaten var. Onları silmelisiniz. @@ -459,7 +491,9 @@ auth_failed=Kimlik doğrulaması başarısız oldu: %v still_own_repo=Hesabınız bir veya daha fazla depoya sahip; önce onları silin veya transfer edin. still_has_org=Hesabınız bir veya daha fazla organizasyonun üyesi; öncelikle onlardan ayrılın. +still_own_packages=Hesabınız bir veya daha fazla pakete sahip; önce onları silin. org_still_own_repo=Bu organizasyon hala bir veya daha fazla depoya sahip; önce onları silin veya transfer edin. +org_still_own_packages=Bu organizasyon hala bir veya daha fazla pakete sahip; önce onları silin. target_branch_not_exist=Hedef dal mevcut değil. @@ -486,6 +520,7 @@ form.name_chars_not_allowed='%s' kullanıcı adı geçersiz karakterler içeriyo [settings] profile=Profil account=Hesap +appearance=Görünüm password=Parola security=Güvenlik avatar=Avatar @@ -499,6 +534,7 @@ twofa=İki Aşamalı Doğrulama account_link=Bağlı Hesaplar organization=Organizasyonlar uid=Tekil ID +webauthn=Güvenlik Anahtarları public_profile=Herkese Açık Profil biography_placeholder=Bize biraz kendinizden bahsedin @@ -509,7 +545,9 @@ website=Web Sitesi location=Konum update_theme=Temayı Güncelle update_profile=Profili Güncelle +update_language=Dili Güncelle update_language_not_found=‘%s‘ dili mevcut değil. +update_language_success=Dil güncellendi. update_profile_success=Profil resminiz güncellendi. change_username=Kullanıcı adınız değiştirildi. change_username_prompt=Not: Kullanıcı adı değişiklikleri hesap URL'nizi de değiştirir. @@ -518,6 +556,22 @@ continue=Devam Et cancel=İptal language=Dil ui=Tema +hidden_comment_types=Gizli yorum türleri +comment_type_group_reference=Referans +comment_type_group_label=Etiket +comment_type_group_milestone=Dönüm noktası +comment_type_group_assignee=Atanan +comment_type_group_title=Başlık +comment_type_group_branch=Dal +comment_type_group_time_tracking=Zaman İzleme +comment_type_group_deadline=Son Tarih +comment_type_group_dependency=Bağımlılık +comment_type_group_lock=Kilit Durumu +comment_type_group_review_request=İnceleme isteği +comment_type_group_pull_request_push=Eklenen işlemeler +comment_type_group_project=Proje +comment_type_group_issue_ref=Konu referansı +saved_successfully=Ayarlarınız başarılı bir şekilde kaydedildi. privacy=Gizlilik keep_activity_private=Etkinliği profil sayfasından gizle keep_activity_private_popup=Etkinliği yalnızca siz ve yöneticiler için görünür hale getirir @@ -531,6 +585,7 @@ delete_current_avatar=Güncel Avatarı Sil uploaded_avatar_not_a_image=Yüklenen dosya bir resim dosyası değil. uploaded_avatar_is_too_big=Yüklenen dosya maksimum boyutu aştı. update_avatar_success=Profil resminiz değiştirildi. +update_user_avatar_success=Kullanıcının avatarı güncellendi. change_password=Parolayı Güncelle old_password=Mevcut Parola @@ -600,7 +655,21 @@ gpg_key_verify=Doğrula gpg_invalid_token_signature=Verilen GPG anahtarı, imza ve anahtar uyuşmuyor veya anahtar çok eski. gpg_token_required=Aşağıdaki anahtar için bir imza sağlamalısınız gpg_token=Anahtar +gpg_token_help=Şunu kullanarak bir imza oluşturabilirsiniz: +gpg_token_code=echo "%s" | gpg -a --default-key %s --detach-sig +gpg_token_signature=Korumalı GPG imzası key_signature_gpg_placeholder='-----PGP İMZA BAŞLAT -----' ile başlar +verify_gpg_key_success=GPG anahtarı '%s' doğrulandı. +ssh_key_verified=Doğrulanmış Anahtar +ssh_key_verified_long=Bu anahtar bir belirteç ile doğrulandı ve bu kullanıcı için etkinleştirilmiş herhangi bir e-posta adresi ile uyuşan işlemeleri doğrulamak için kullanılabilir. +ssh_key_verify=Doğrula +ssh_invalid_token_signature=Verilen SSH anahtarı, imza veya erişim anahtarı uyuşmuyor veya erişim anahtarı çok eski. +ssh_token_required=Aşağıdaki erişim anahtarı için bir imza sağlamalısınız +ssh_token=Erişim Anahtarı +ssh_token_help=Şunu kullanarak bir imza oluşturabilirsiniz: +ssh_token_signature=Korumalı SSH imzası +key_signature_ssh_placeholder='-----BEGIN SSH SIGNATURE-----' ile başlar +verify_ssh_key_success=SSH anahtarı '%s' doğrulandı. subkeys=Alt anahtarlar key_id=Anahtar Kimliği key_name=Anahtar İsmi @@ -648,6 +717,9 @@ generate_token_success=Yeni bir jeton oluşturuldu. Tekrar gösterilmeyeceği i generate_token_name_duplicate=%s zaten bir uygulama adı olarak kullanılmış. Lütfen yeni bir tane kullanın. delete_token=Sil access_token_deletion=Erişim Jetonunu Sil +access_token_deletion_cancel_action=İptal +access_token_deletion_confirm_action=Sil +access_token_deletion_desc=Bir erişim anahtarını silmek, onu kullanan uygulamaların hesabınıza erişimini kaldırır. Bu geri alınamaz. Devam edilsin mi? delete_token_success=Jeton silindi. Onu kullanan uygulamalar artık hesabınıza erişemez. manage_oauth2_applications=OAuth2 Uygulamalarını Yönet @@ -700,10 +772,16 @@ passcode_invalid=Şifre geçersiz. Tekrar deneyin. twofa_enrolled=Hesabınız iki faktörlü kimlik doğrulamasına kaydedildi. Kazıma belirtecini (%s) yalnızca bir kez gösterdiği gibi güvenli bir yerde saklayın! twofa_failed_get_secret=Gizlilik elde edilemedi. +webauthn_desc=Güvenlik anahtarları, şifreleme anahtarlarını içeren donanım aygıtlarıdır. İki aşamalı kimlik doğrulama için kullanılabilirler. Güvenlik anahtarları WebAuthn Authenticator standardını desteklemelidir. +webauthn_register_key=Güvenlik Anahtarı Ekle +webauthn_nickname=Takma Ad +webauthn_delete_key=Güvenlik Anahtarını Kaldır +webauthn_delete_key_desc=Bir güvenlik anahtarını kaldırırsanız, onunla artık giriş yapamazsınız. Devam edilsin mi? manage_account_links=Bağlı Hesapları Yönet manage_account_links_desc=Bu harici hesaplar Gitea hesabınızla bağlantılı. account_links_not_available=Şu anda Gitea hesabınıza bağlı harici bir hesap yok. +link_account=Hesap Bağla remove_account_link=Bağlantılı Hesabı Kaldır remove_account_link_desc=Bağlantılı bir hesabı kaldırmak, onunla Gitea hesabınıza erişimi iptal edecektir. Devam edilsin mi? remove_account_link_success=Bağlantılı hesap kaldırıldı. @@ -722,6 +800,7 @@ email_notifications.enable=E-posta Bildirimlerini Etkinleştir email_notifications.onmention=Sadece Bahsedilen E-posta email_notifications.disable=E-posta Bildirimlerini Devre Dışı Bırak email_notifications.submit=E-posta Tercihlerini Ayarla +email_notifications.andyourown=Ve Sizin Bildirimleriniz visibility=Kullanıcı görünürlüğü visibility.public=Herkese Açık @@ -750,8 +829,14 @@ visibility_fork_helper=(Bunu değiştirmek tüm çatallamaları etkileyecektir.) clone_helper=Klonlama konusunda yardıma mı ihtiyacınız var? Yardım adresini ziyaret edin. fork_repo=Depoyu Çatalla fork_from=Buradan Çatalla +already_forked=%s deposunu zaten çatalladınız +fork_to_different_account=Başka bir hesaba çatalla fork_visibility_helper=Çatallanmış bir deponun görünürlüğü değiştirilemez. use_template=Bu şablonu kullan +clone_in_vsc=VS Code'ta klonla +download_zip=ZIP indir +download_tar=TAR.GZ indir +download_bundle=BUNDLE indir generate_repo=Depo Oluştur generate_from=Şuradan Oluştur repo_desc=Açıklama @@ -778,7 +863,9 @@ default_branch=Varsayılan Dal default_branch_helper=Varsayılan dal, değişiklik istekleri ve kod işlemeleri için temel daldır. mirror_prune=Buda mirror_prune_desc=Kullanılmayan uzak depoları izleyen referansları kaldır +mirror_interval=Yansı Aralığı (geçerli zaman birimleri 'h', 'm', 's'). Periyodik senkronizasyonu devre dışı bırakmak için 0 kullanın. (Asgari aralık: %s) mirror_interval_invalid=Yansı süre aralığı geçerli değil. +mirror_sync_on_commit=İşlemeler gönderildiğinde senkronize et mirror_address=URL'den Klonla mirror_address_desc=Yetkilendirme bölümüne gerekli tüm kimlik bilgilerini girin. mirror_address_url_invalid=Sağlanan Url geçersiz. Url'nin tüm bileşenlerinden doğru olarak kaçmalısınız. @@ -826,7 +913,8 @@ desc.archived=Arşivlenmiş template.items=Şablon Öğeleri template.git_content=Git İçeriği (Varsayılan Dal) -template.git_hooks=Git İstekleri +template.git_hooks=Git İstemcileri +template.git_hooks_tooltip=Eklendikten sonra Git İstemcilerini değiştirmek veya kaldırmak mümkün değildir. Bunu yalnızca şablon deposuna güveniyorsanız seçin. template.webhooks=Web İstemcileri template.topics=Konular template.avatar=Profil Resmi @@ -846,6 +934,7 @@ form.name_pattern_not_allowed='%s' deseni, depo adı için geçerli değildir. need_auth=Yetkilendirme migrate_options=Göç Seçenekleri migrate_service=Göç Hizmeti +migrate_options_mirror_helper=Bu depo bir yansı olacaktır migrate_options_lfs=LFS dosyalarını taşı migrate_options_lfs_endpoint.label=LFS Uç Noktası migrate_options_lfs_endpoint.description=Taşıma, LFS sunucusunu belirlemek için Git uzak sunucusunu kullanmaya çalışacak. Eğer LFS veri deposu başka yerdeyse özel bir uç nokta da belirtebilirsiniz. @@ -862,8 +951,10 @@ migrate_items_releases=Sürümler migrate_repo=Depoyu Göç Ettir migrate.clone_address=URL'den Taşı / Klonla migrate.clone_address_desc=Varolan bir deponun HTTP(S) veya Git 'klonlama' URL'si +migrate.github_token_desc=GitHub API hız sınırı nedeniyle göçü hızlandırmak için buraya virgülle ayrılmış bir veya daha fazla erişm anahtarı koyabilirsiniz. UYARI: Bu özelliğin kötüye kullanılması, hizmet sağlayıcının politikasını ihlal edebilir ve hesabın engellenmesine yol açabilir. migrate.clone_local_path=veya bir yerel sunucu yolu migrate.permission_denied=Yerel depoları içeri aktarma izniniz yok. +migrate.permission_denied_blocked=İzin verilmeyen sunuculardan içe aktaramazsınız, lütfen yöneticiden ALLOWED_DOMAINS/ALLOW_LOCALNETWORKS/BLOCKED_DOMAINS ayarlarını kontrol etmesini isteyin. migrate.invalid_local_path=Yerel yol geçersiz. Mevcut değil veya bir dizin değil. migrate.invalid_lfs_endpoint=LFS Uç noktası geçerli değil. migrate.failed=Göç başarısız: %v @@ -874,6 +965,15 @@ migrate.migrate=%s Konumundan Göç Et migrate.migrating=%s konumundan taşınıyor ... migrate.migrating_failed=%s konumundan taşıma başarısız oldu. migrate.migrating_failed.error=Hata: %s +migrate.migrating_failed_no_addr=Göç başarısız oldu. +migrate.github.description=Github.com veya diğer Github sunucularından veri aktar. +migrate.git.description=Herhangi bir Git hizmetinden sadece bir depoyu aktar. +migrate.gitlab.description=Gitlab.com veya diğer Gitlab sunucularından veri aktar. +migrate.gitea.description=Gitea.com veya diğer Gitea sunucularından veri aktar. +migrate.gogs.description=Notabug.org veya diğer Gogs sunucularından veri aktar. +migrate.onedev.description=Code.onedev.io ve diğer OneDev sunucularından veri aktar. +migrate.codebase.description=Codebasehq.com sitesinden veri aktar. +migrate.gitbucket.description=GitBucket sunucularından veri aktar. migrate.migrating_git=Git Verilerini Taşıma migrate.migrating_topics=Konuları Taşıma migrate.migrating_milestones=Kilometre Taşlarını Taşıma @@ -902,6 +1002,7 @@ clone_this_repo=Bu depoyu klonla create_new_repo_command=Komut satırında yeni bir depo oluşturuluyor push_exist_repo=Komut satırından mevcut bir depo itiliyor empty_message=Bu depoda herhangi bir içerik yok. +broken_message=Bu deponun altındaki Git verisi okunamıyor. Bu sunucunun yöneticisiyle bağlantıya geçin veya bu depoyu silin. code=Kod code.desc=Kaynak koda, dosyalara, işlemelere ve dallara eriş. @@ -915,6 +1016,7 @@ tags=Etiket issues=Konular pulls=Değişiklik İstekleri project_board=Projeler +packages=Paketler labels=Etiketler org_labels_desc=Bu organizasyon altında tüm depolarla kullanılabilen organizasyon düzeyinde etiketler org_labels_desc_manage=yönet @@ -926,6 +1028,7 @@ release=Sürüm releases=Sürüm tag=Etiket released_this=bu sürümü yayınladı +file.title=%s dalındaki/etiketindeki %s file_raw=Ham file_history=Geçmiş file_view_source=Kaynağı Görüntüle @@ -933,7 +1036,18 @@ file_view_rendered=Oluşturulanları Görüntüle file_view_raw=Ham Görünüm file_permalink=Kalıcı Bağlantı file_too_large=Bu dosya görüntülemek için çok büyük. - +bidi_bad_header=`Bu dosya beklenmeyen tek yönlü evrensel kodlu karakter içeriyor!` +bidi_bad_description=`Bu dosya, aşağıda görünenden farklı bir şekilde işlenebilecek beklenmeyen tek yönlü evrensel kodlu karakter içeriyor. Eğer bunu kasıtlı ve meşru olarak yaptıysanız bu uyarıyı yok sayabilirsiniz. Gizli karakterleri göstermek için Kaçış Karakterli düğmesine tıklayın.` +bidi_bad_description_escaped=`Bu dosya beklenmeyen tek yönlü evrensel kodlu karakter içeriyor. Gizlenmiş evrensel kodlu karakterler aşağıda kaçış karakteri olarak gösteriliyor. Nasıl temsil edildiklerini görüntülemek için Kaçış Karaktersiz düğmesine tıklayın.` +unicode_header=`Bu dosya gizli evrensel kodlu karakter içeriyor!` +unicode_description=`Bu dosya, aşağıda görünenden farklı bir şekilde işlenebilecek gizli evrensel kodlu karakter içeriyor. Eğer bunu kasıtlı ve meşru olarak yaptıysanız bu uyarıyı yok sayabilirsiniz. Gizli karakterleri göstermek için Kaçış Karakterli düğmesine tıklayın.` +unicode_description_escaped=`Bu dosya gizli evrensel kodlu karakter içeriyor. Gizlenmiş evrensel kodlu karakterler aşağıda kaçış karakteri olarak gösteriliyor. Nasıl temsil edildiklerini görüntülemek için Kaçış Karaktersiz düğmesine tıklayın.` +line_unicode=`Bu satırda gizli evrensel kod karakterler var` + +escape_control_characters=Kaçış Karakterli +unescape_control_characters=Kaçış Karaktersiz +file_copy_permalink=Kalıcı Bağlantıyı Kopyala +view_git_blame=Git Suç Görüntüle video_not_supported_in_browser=Tarayıcınız HTML5 'video' etiketini desteklemiyor. audio_not_supported_in_browser=Tarayıcınız HTML5 'audio' etiketini desteklemiyor. stored_lfs=Git LFS ile depolandı @@ -942,7 +1056,9 @@ commit_graph=İşleme Grafiği commit_graph.select=Dalları seç commit_graph.hide_pr_refs=Değişiklik İsteklerini Gizle commit_graph.monochrome=Siyah Beyaz +commit_graph.color=Renk blame=Suçlama +download_file=Dosya indir normal_view=Normal Görünüm line=satır lines=satır @@ -970,6 +1086,10 @@ editor.add_tmpl='' eklendi editor.add='%s' ekle editor.update='%s' güncelle editor.delete='%s' sil +editor.patch=Yama Uygula +editor.patching=Yamalanıyor: +editor.fail_to_apply_patch='%s' yaması uygulanamıyor +editor.new_patch=Yeni Yama editor.commit_message_desc=İsteğe bağlı uzun bir açıklama ekleyin… editor.signoff_desc=İşleme günlüğü mesajının sonuna işleyen tarafından imzalanan bir fragman ekleyin. editor.commit_directly_to_this_branch=Doğrudan %s bölümüne uygula. @@ -994,6 +1114,8 @@ editor.commit_empty_file_text=İşlemek üzere olduğunuz dosya boş. Devam edil editor.no_changes_to_show=Gösterilecek değişiklik yok. editor.fail_to_update_file='%s' dosyası güncellenemedi/oluşturulamadı. editor.fail_to_update_file_summary=Hata Mesajı: +editor.push_rejected_no_message=Değişiklik, bir ileti olmadan sunucu tarafından reddedildi. Git Hooks'u kontrol edin. +editor.push_rejected=Değişiklik sunucu tarafından reddedildi. Lütfen Git Hooks'u kontrol edin. editor.push_rejected_summary=Tam Red Mesajı: editor.add_subdir=Bir dizin ekle… editor.unable_to_upload_files=Şu hata ile dosyalar '%s' 'a yüklenemedi: %v @@ -1003,6 +1125,8 @@ editor.cannot_commit_to_protected_branch=Korunan '%s' dalına işleme yapılamı editor.no_commit_to_branch=Doğrudan dala işleme yapılamıyor çünkü: editor.user_no_push_to_branch=Kullanıcı dala gönderemez editor.require_signed_commit=Dal imzalı bir işleme gerektirir +editor.cherry_pick=%s şunun üzerine cımbızla: +editor.revert=%s şuna geri döndür: commits.desc=Kaynak kodu değişiklik geçmişine göz atın. commits.commits=İşleme @@ -1021,8 +1145,17 @@ commits.signed_by=İmzalayan commits.signed_by_untrusted_user=Güvenilmeyen kullanıcı tarafından imzalandı commits.signed_by_untrusted_user_unmatched=İşleyici ile eşleşmeyen güvenilmeyen kullanıcı tarafından imzalanmış commits.gpg_key_id=GPG Anahtar Kimliği +commits.ssh_key_fingerprint=SSH Anahtar Parmak İzi +commit.actions=Eylemler +commit.revert=Geri Al +commit.revert-header=Geri al: %s +commit.revert-content=Geri almak için dal seçin: +commit.cherry-pick=Cımbızla +commit.cherry-pick-header=Cımbızla: %s +commit.cherry-pick-content=Cımbızlamak için dal seçin: +ext_issues=Harici Konulara Erişim ext_issues.desc=Dışsal konu takip sistemine bağla. projects=Projeler @@ -1056,8 +1189,10 @@ projects.board.set_default=Varsayılana Ayarla projects.board.set_default_desc=Kategorize edilmemiş konular ve çekme istekleri için bu panoyu varsayılan olarak ayarlayın projects.board.delete=Panoyu Sil projects.board.deletion_desc=Bir proje panosunun silinmesi, ilgili tüm konuları 'Kategorize edilmemiş'e taşır. Devam edilsin mi? +projects.board.color=Renk projects.open=Aç projects.close=Kapat +projects.board.assigned_to=Atanan issues.desc=Hata raporlarını, görevleri ve kilometre taşlarını yönetmenizi sağlar. issues.filter_assignees=Atama Süzgeci @@ -1122,6 +1257,9 @@ issues.add_assignee_at=`%[2]s %[1]s tarafından atandı` issues.remove_assignee_at=`ataması %[2]s %[1]s tarafından kaldırıldı` issues.remove_self_assignment=`atamalarını kaldırdı %s` issues.change_title_at=`başlığı %s iken %s olarak %s değiştirdi` +issues.change_ref_at=`%s referans %s %s olarak değiştirildi` +issues.remove_ref_at=`%s referansı %s tarihinde kaldırıldı` +issues.add_ref_at=`%s referansı %s tarihinde eklendi` issues.delete_branch_at=`%s dalı silindi %s` issues.filter_label=Etiket issues.filter_label_exclude=`Etiketleri hariç tutmak için alt + tıkla/enter kullanın` @@ -1149,6 +1287,7 @@ issues.filter_sort.moststars=En çok yıldızlılar issues.filter_sort.feweststars=En az yıldızlılar issues.filter_sort.mostforks=En çok çatallananlar issues.filter_sort.fewestforks=En az çatallananlar +issues.keyword_search_unavailable=Anahtar kelime ile arama şu an mevcut değil. Lütfen site yöneticisiyle iletişime geçin. issues.action_open=Açık issues.action_close=Kapat issues.action_label=Etiket @@ -1157,11 +1296,16 @@ issues.action_milestone_no_select=Kilometre Taşı Yok issues.action_assignee=Atanan issues.action_assignee_no_select=Atanan yok issues.opened_by=%[3]s tarafından %[1]s açıldı +pulls.merged_by=%[1]s %[3]s tarafından açılan istek birleştirildi +pulls.merged_by_fake=%[2]s tarafından açılan istek %[1]s birleştirildi +issues.closed_by=%[3]s tarafından %[1]s kapatıldı issues.opened_by_fake=%[2]s tarafından %[1]s açıldı +issues.closed_by_fake=%[2]s tarafından %[1]s kapatıldı issues.previous=Önceki issues.next=Sonraki issues.open_title=Açık issues.closed_title=Kapalı +issues.draft_title=Taslak issues.num_comments=%d yorum issues.commented_at=`%s yorum yaptı` issues.delete_comment_confirm=Bu yorumu silmek istediğinizden emin misiniz? @@ -1183,7 +1327,7 @@ issues.reopened_at=`%[2]s konusunu yeniden açt issues.commit_ref_at=`%[2]s işlemesinde bu konuyu işaret etti` issues.ref_issue_from=`bu konuya referansta bulundu %[4]s %[2]s` issues.ref_pull_from=`bu değişiklik isteğine referansta bulundu %[4]s %[2]s` -issues.ref_closing_from=`bir değişiklik isteğine referansta bulundu %[4] bu konu kapatılacak %[2]s` +issues.ref_closing_from=`bir değişiklik isteğine referansta bulundu %[4]s bu konu kapatılacak %[2]s` issues.ref_reopening_from=`bir değişiklik isteğine referansta bulundu %[4]s bu konu yeniden açılacak %[2]s` issues.ref_closed_from=`bu konuyu kapat%[4]s %[2]s` issues.ref_reopened_from=`konuyu yeniden aç%[4]s %[2]s` @@ -1240,6 +1384,9 @@ issues.lock.reason=Kilitleme nedeni issues.lock.title=Konuşmayı kilitle. issues.unlock.title=Konuşmanın kilidini aç. issues.comment_on_locked=Kilitli bir konuya yorum yapamazsınız. +issues.delete=Sil +issues.delete.title=Bu konu silinsin mi? +issues.delete.text=Bu konuyu gerçekten silmek istiyor musunuz? (Bu işlem tüm içeriği kalıcı olarak silecektir. Arşivde tutma niyetiniz varsa silmek yerine kapatmayı düşünün) issues.tracker=Zaman Takibi issues.start_tracking_short=Zamanlayıcıyı Başlat issues.start_tracking=Zaman İzlemeyi Başlat @@ -1274,12 +1421,14 @@ issues.due_date_form_edit=Düzenle issues.due_date_form_remove=Kaldır issues.due_date_not_writer=Bir konunun bitiş tarihini değiştirmek için depoda yazma hakkınız olmalıdır. issues.due_date_not_set=Bitiş tarihi atanmadı. -issues.due_date_added=%[2]s %[1]s bitiş tarihini ekledi -issues.due_date_modified=%s bitiş tarihini %s iken %s olarak değiştirildi +issues.due_date_added=bitiş tarihini %s olarak %s ekledi +issues.due_date_modified=bitiş tarihini %[2]s iken %[1]s olarak %[3]s değiştirdi issues.due_date_remove=%[2]s %[1]s bitiş tarihini kaldırdı issues.due_date_overdue=Süresi Geçmiş issues.due_date_invalid=Bitiş tarihi geçersiz veya aralık dışında. Lütfen 'yyyy-aa-gg' biçimini kullanın. issues.dependency.title=Bağımlılıklar +issues.dependency.issue_no_dependencies=Bağımlılık yok. +issues.dependency.pr_no_dependencies=Bağımlılık yok. issues.dependency.add=Bağımlılık ekle… issues.dependency.cancel=İptal issues.dependency.remove=Kaldır @@ -1318,6 +1467,7 @@ issues.review.add_review_request=%s tarafından %s inceleme istedi issues.review.remove_review_request=%s %s için inceleme isteği kaldırıldı issues.review.remove_review_request_self=%s incelemeyi reddetti issues.review.pending=Beklemede +issues.review.pending.tooltip=Bu yorum başkaları tarafından görünmüyor. Bekleyen yorumlarınızı göndermek için, sayfanın üstünde '%s' -> '%s/%s/%s' seçin. issues.review.review=Gözden Geçir issues.review.reviewers=Gözden Geçirenler issues.review.outdated=Eskimiş @@ -1330,14 +1480,28 @@ issues.review.un_resolve_conversation=Konuşmayı çözme issues.review.resolved_by=bu konuşmayı çözümlenmiş olarak işaretledi issues.assignee.error=Beklenmeyen bir hata nedeniyle tüm atananlar eklenmedi. issues.reference_issue.body=Gövde +issues.content_history.deleted=silindi +issues.content_history.edited=düzenlendi +issues.content_history.created=oluşturuldu +issues.content_history.delete_from_history=Geçmişten kaldır +issues.content_history.delete_from_history_confirm=Geçmişten kaldırılsın mı? +issues.content_history.options=Seçenekler +issues.reference_link=Referans: %s compare.compare_base=temel compare.compare_head=karşılaştır pulls.desc=Değişiklik isteklerini ve kod incelemelerini etkinleştir. pulls.new=Yeni Değişiklik İsteği +pulls.view=Değişiklik İsteği Görüntüle pulls.compare_changes=Yeni Değişiklik İsteği +pulls.allow_edits_from_maintainers=Bakımcıların düzenlemelerine izin ver +pulls.allow_edits_from_maintainers_desc=Ana dala yazma hakkı olan kullanıcılar bu dala da gönderebilirler +pulls.allow_edits_from_maintainers_err=Güncelleme başarısız oldu pulls.compare_changes_desc=Birleştirmek için hedef ve kaynak dalı seçin. +pulls.has_viewed_file=Görüldü +pulls.has_changed_since_last_review=Son incelemenizden sonra değişti +pulls.viewed_files_label=%[1]d / %[2]d dosya görüldü pulls.compare_base=birleştir pulls.compare_compare=şuradan çek pulls.switch_comparison_type=Karşılaştırma türünü değiştir @@ -1346,6 +1510,7 @@ pulls.filter_branch=Dal filtrele pulls.no_results=Sonuç bulunamadı. pulls.nothing_to_compare=Bu dallar eşit. Değişiklik isteği oluşturmaya gerek yok. pulls.nothing_to_compare_and_allow_empty_pr=Bu dallar eşittir. Bu Dİ boş olacak. +pulls.has_pull_request=`Bu dallar arasında zaten bir değişiklik isteği var: %[2]s#%[3]d` pulls.create=Değişiklik İsteği Oluştur pulls.title_desc=%[2]s içindeki %[1]d işlemeyi %[3]s ile birleştirmek istiyor pulls.merged_title_desc=%[4]s %[2]s içindeki %[1]d işlemeyi %[3]s ile birleştirdi @@ -1369,7 +1534,8 @@ pulls.remove_prefix=%s ön ekini kaldır pulls.data_broken=Bu değişiklik isteği, çatallama bilgilerinin eksik olması nedeniyle bozuldu. pulls.files_conflicted=Bu değişiklik isteğinde, hedef dalla çakışan değişiklikler var. pulls.is_checking=Birleştirme çakışması denetimi devam ediyor. Birkaç dakika sonra tekrar deneyin. -pulls.is_empty=Bu dal, hedef dalla eşittir. +pulls.is_ancestor=Bu dal zaten hedef dalda mevcut. Birleştirilecek bir şey yok. +pulls.is_empty=Bu daldaki değişiklikler zaten hedef dalda mevcut. Bu boş bir işleme olacaktır. pulls.required_status_check_failed=Bazı gerekli denetimler başarılı olmadı. pulls.required_status_check_missing=Gerekli bazı kontroller eksik. pulls.required_status_check_administrator=Yönetici olarak, bu değişiklik isteğini yine de birleştirebilirsiniz. @@ -1413,7 +1579,10 @@ pulls.rebase_conflict_summary=Hata Mesajı ; %[2]s
%[3]s
pulls.unrelated_histories=Birleştirme Başarısız: Birleştirme başlığı ve tabanı ortak bir geçmişi paylaşmıyor. İpucu: Farklı bir strateji deneyin pulls.merge_out_of_date=Birleştirme Başarısız: Birleştirme oluşturulurken, taban güncellendi. İpucu: Tekrar deneyin. +pulls.head_out_of_date=Birleştirme Başarısız: Birleştirme oluşturulurken, ana güncellendi. İpucu: Tekrar deneyin. +pulls.push_rejected=Birleştirme Başarısız Oldu: Gönderme reddedildi. Bu depo için Git İstemcilerini inceleyin. pulls.push_rejected_summary=Tam Red Mesajı +pulls.push_rejected_no_message=Birleştirme başarısız oldu: Gönderme reddedildi, ancak uzak bir mesaj yoktu.
Bu depo için Git İstemcilerini inceleyin pulls.open_unmerged_pull_exists=`Aynı özelliklere sahip bekleyen bir değişiklik isteği (#%d) olduğundan yeniden açma işlemini gerçekleştiremezsiniz.` pulls.status_checking=Bazı denetlemeler beklemede pulls.status_checks_success=Tüm denetlemeler başarılı oldu @@ -1433,9 +1602,20 @@ pulls.merge_instruction_hint=`komut satırı talimat pulls.merge_instruction_step1_desc=Proje deponuzdan yeni bir dala göz atın ve değişiklikleri test edin. pulls.merge_instruction_step2_desc=Gitea'daki değişiklikleri ve güncellemeleri birleştirin. +pulls.auto_merge_button_when_succeed=(Denetlemeler başarılı olduğunda) +pulls.auto_merge_when_succeed=Tüm denetlemeler başarılı olduğundan otomatik olarak birleştir +pulls.auto_merge_newly_scheduled=Değişiklik İsteği tüm denetlemeler başarılı olduğunda birleştirilecek şekilde ayarlanmış. +pulls.auto_merge_has_pending_schedule=%[1]s, bu değişiklik isteğini tüm denetlemeler başarılı olduğunda %[2]s, otomatik olarak birleşecek şekilde ayarlamış. +pulls.auto_merge_cancel_schedule=Otomatik birleştirmeyi iptal et +pulls.auto_merge_not_scheduled=Bu değişiklik isteği için otomatik birleştirme zamanlanmamış. +pulls.auto_merge_canceled_schedule=Bu değişiklik isteği için otomatik birleştirme iptal edildi. +pulls.auto_merge_newly_scheduled_comment=`bu değişiklik isteği, tüm denetlemeler başarılı olduğunda %[1]s, otomatik olarak birleşecek şekilde ayarlandı` +pulls.auto_merge_canceled_schedule_comment=`bu değişiklik isteğinin, tüm denetlemeler başarılı olduğunda %[1]s, otomatik birleştirmesi iptal edildi` +pulls.delete.title=Bu değişiklik isteği silinsin mi? +pulls.delete.text=Bu değişiklik isteğini gerçekten silmek istiyor musunuz? (Bu işlem tüm içeriği kalıcı olarak silecektir. Arşivde tutma niyetiniz varsa silmek yerine kapatmayı düşünün) milestones.new=Yeni Kilometre Taşı milestones.closed=Kapalı %s @@ -1481,6 +1661,7 @@ signing.wont_sign.commitssigned=İlişkili tüm işlemeler imzalanmadığı içi signing.wont_sign.approved=Değişiklik İsteği onaylanmadığı için birleştirme imzalanmayacak signing.wont_sign.not_signed_in=Oturum açmadınız +ext_wiki=Harici Vikiye Erişim ext_wiki.desc=Harici bir wiki'ye bağlantı. wiki=Wiki @@ -1505,6 +1686,7 @@ wiki.page_already_exists=Aynı isimde bir Wiki sayfası zaten var. wiki.reserved_page='%s' wiki sayfa adı rezerve edilmiştir. wiki.pages=Sayfalar wiki.last_updated=Son güncelleme %s +wiki.page_name_desc=Bu Viki sayfası için bir ad girin. Bazı özel isimler 'Home', '_Sidebar' ve '_Footer' şeklindedir. activity=Aktivite activity.period.filter_label=Dönem: @@ -1577,6 +1759,8 @@ search.search_repo=Depo ara search.fuzzy=Belirsiz search.match=Eşleştir search.results="%s" için %s içinde sonuçları ara +search.code_no_results=Arama teriminizle eşleşen bir kaynak kod bulunamadı. +search.code_search_unavailable=Kod arama şu an mevcut değil. Lütfen site yöneticisiyle iletişime geçin. settings=Ayarlar settings.desc=Ayarlar, depo için ayarları yönetebileceğiniz yerdir @@ -1588,7 +1772,7 @@ settings.collaboration.read=Oku settings.collaboration.owner=Sahibi settings.collaboration.undefined=Belirsiz settings.hooks=Web İstemcileri -settings.githooks=Git İstekleri +settings.githooks=Git İstemcileri settings.basic_settings=Temel Ayarlar settings.mirror_settings=Yansıma Ayarları settings.mirror_settings.docs=Projenizi, değişiklikleri başka bir depoya/depodan otomatik olarak gönderecek ve/veya çekecek şekilde ayarlayın. Dallar, etiketler ve işlemeler otomatik olarak senkronize edilecektir. Depoları nasıl yansıtrım? @@ -1602,10 +1786,6 @@ settings.mirror_settings.push_mirror.remote_url=Git Uzak Depo URL'si settings.mirror_settings.push_mirror.add=Yansı Gönderimi Ekle settings.sync_mirror=Şimdi Eşitle settings.mirror_sync_in_progress=Yansı senkronizasyonu devam ediyor. Bir dakika sonra tekrar kontrol edin. -settings.email_notifications.enable=E-posta Bildirimlerini Etkinleştir -settings.email_notifications.onmention=Sadece Bahsedilen E-posta -settings.email_notifications.disable=E-posta Bildirimlerini Devre Dışı Bırak -settings.email_notifications.submit=E-posta Tercihlerini Ayarla settings.site=Web Sitesi settings.update_settings=Ayarları Güncelle settings.branches.update_default_branch=Varsayılan Dalı Değiştir @@ -1627,6 +1807,9 @@ settings.tracker_url_format_error=Harici konu izleyici URL biçimi geçerli bir settings.tracker_issue_style=Harici Konu İzleyici Numara Biçimi settings.tracker_issue_style.numeric=Sayısal settings.tracker_issue_style.alphanumeric=Alfanumerik +settings.tracker_issue_style.regexp=Düzenli ifade +settings.tracker_issue_style.regexp_pattern=Düzenli İfade Kalıbı +settings.tracker_issue_style.regexp_pattern_desc={index} yerine ilk eşleşen grup kullanılacaktır. settings.tracker_url_format_desc=Kullanıcı adı, depo adı ve yayın dizini için {user}, {repo} ve {index} yer tutucularını kullanın. settings.enable_timetracker=Zaman Takibini Etkinleştir settings.allow_only_contributors_to_track_time=Sadece Katkıcılar İçin Zaman Takibine İzin Ver @@ -1638,10 +1821,18 @@ settings.pulls.allow_rebase_merge_commit=Açık birleştirme işlemeleri ile Yen settings.pulls.allow_squash_commits=İşlemeleri Birleştirmek için Ezmeyi Etkinleştir settings.pulls.allow_manual_merge=Dİ'yi elle birleştirilmiş olarak işaretlemeyi etkinleştir settings.pulls.enable_autodetect_manual_merge=Kendiliğinden algılamalı elle birleştirmeyi etkinleştir (Not: Bazı özel durumlarda yanlış kararlar olabilir) +settings.pulls.allow_rebase_update=Değişiklik isteği dalının yeniden yapılandırmayla güncellenmesine izin ver settings.pulls.default_delete_branch_after_merge=Varsayılan olarak birleştirmeden sonra değişiklik isteği dalını sil +settings.packages_desc=Depo Paket Kütüğünü Etkinleştir settings.projects_desc=Depo Projelerini Etkinleştir settings.admin_settings=Yönetici Ayarları settings.admin_enable_health_check=Depo Sağlık Kontrollerini Etkinleştir (git fsck) +settings.admin_code_indexer=Kod Dizinleyici +settings.admin_stats_indexer=Kod İstatistiği Dizinleyici +settings.admin_indexer_commit_sha=Son Dizinlenen SHA +settings.admin_indexer_unindexed=Dizinlenmemiş +settings.reindex_button=Yeniden Dizinleme Kuyruğuna Ekle +settings.reindex_requested=Yeniden Dizinleme İstendi settings.admin_enable_close_issues_via_commit_in_any_branch=Varsayılan olmayan bir dalda yapılan bir işlemeyle konuyu kapat settings.danger_zone=Tehlike Alanı settings.new_owner_has_same_repo=Yeni sahibin aynı isimde başka bir deposu var. Lütfen farklı bir isim seçin. @@ -1730,6 +1921,9 @@ settings.webhook.response=Cevaplar settings.webhook.headers=Başlıklar settings.webhook.payload=İçerik settings.webhook.body=Gövde +settings.webhook.replay.description=Bu web kancasını tekrar çalıştır. +settings.webhook.delivery.success=Teslim kuyruğuna bir olay eklendi. Teslim geçmişinde görünmesi birkaç saniye alabilir. +settings.githooks_desc=Git İstemcileri Git'in kendisi tarafından desteklenmektedir. Özel işlemler ayarlamak için aşağıdaki istemci dosyalarını düzenleyebilirsiniz. settings.githook_edit_desc=İstek aktif değilse örnek içerik sunulacaktır. İçeriği boş bırakmak, isteği devre dışı bırakmayı beraberinde getirecektir. settings.githook_name=İstek İsmi settings.githook_content=İstek İçeriği @@ -1741,6 +1935,7 @@ settings.content_type=POST İçerik Türü settings.secret=Gizli settings.slack_username=Kullanıcı Adı settings.slack_icon_url=Simge Bağlantısı +settings.slack_color=Renk settings.discord_username=Kullanıcı adı settings.discord_icon_url=Simge URL'si settings.event_desc=Tetikleyici Açık: @@ -1786,6 +1981,8 @@ settings.event_pull_request_review=Değişiklik İsteği İncelendi settings.event_pull_request_review_desc=Değişiklik isteği onaylandı, reddedildi veya yorumu incelendi. settings.event_pull_request_sync=Değişiklik İsteği Senkronize Edildi settings.event_pull_request_sync_desc=Değişiklik isteği senkronize edildi. +settings.event_package=Paket +settings.event_package_desc=Bir depoda paket oluşturuldu veya silindi. settings.branch_filter=Dal filtresi settings.branch_filter_desc=Gönderme, dal oluşturma ve dal silme olayları için glob deseni olarak belirtilen dal beyaz listesi. Boşsa veya * ise, tüm dallar için olaylar raporlanır. Sözdizimi için github.com/gobwas/glob belgelerine bakın. Örnekler: master, {master,release*}. settings.active=Etkin @@ -1799,6 +1996,23 @@ settings.hook_type=İstek Türü settings.slack_token=Erişim Anahtarı settings.slack_domain=Alan Adı settings.slack_channel=Kanal +settings.add_web_hook_desc=%s web kancasını deponuza ekleyin. +settings.web_hook_name_gitea=Gitea +settings.web_hook_name_gogs=Gogs +settings.web_hook_name_slack=Slack +settings.web_hook_name_discord=Discord +settings.web_hook_name_dingtalk=DingTalk +settings.web_hook_name_telegram=Telegram +settings.web_hook_name_matrix=Matrix +settings.web_hook_name_msteams=Microsoft Teams +settings.web_hook_name_feishu_or_larksuite=Feishu / Lark Suite +settings.web_hook_name_feishu=Feishu +settings.web_hook_name_larksuite=Lark Suite +settings.web_hook_name_wechatwork=WeCom (Wechat Work) +settings.web_hook_name_packagist=Packagist +settings.packagist_username=Packagist kullanıcı adı +settings.packagist_api_token=API erişim anahtarı +settings.packagist_package_url=Packagist paket URL'si settings.deploy_keys=Dağıtım Anahtarları settings.add_deploy_key=Dağıtım Anahtarı Ekle settings.deploy_key_desc=Dağıtım anahtarları, depoyu salt okunur çekme yetkisine sahip. @@ -1926,6 +2140,12 @@ settings.lfs_pointers.inRepo=Depoda settings.lfs_pointers.exists=Mağazada var settings.lfs_pointers.accessible=Kullanıcı tarafından erişilebilir settings.lfs_pointers.associateAccessible=Erişilebilir %d OID ilişkilendirme +settings.rename_branch_failed_exist=%s dalı zaten mevcut olduğu için dalın adı değiştirilemiyor. +settings.rename_branch_failed_not_exist=%s dalının adı değiştirilemiyor, çünkü böyle bir dal yok. +settings.rename_branch_success=%s dalının adı başarılı bir şekilde %s oldu. +settings.rename_branch_from=önceki dal adı +settings.rename_branch_to=yeni dal adı +settings.rename_branch=Dalı yeniden adlandır diff.browse_source=Kaynağa Gözat diff.parent=ebeveyn @@ -1955,6 +2175,9 @@ diff.file_image_height=Yükseklik diff.file_byte_size=Boyut diff.file_suppressed=Dosya farkı çok büyük olduğundan ihmal edildi diff.file_suppressed_line_too_long=Dosya farkları bir veya daha fazla satır çok uzun olduğundan bastırıldı +diff.too_many_files=Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor +diff.show_more=Daha Fazla Göster +diff.load=Fark Yükle diff.generated=üretilen diff.vendored=sağlanmış diff.comment.placeholder=Yorum Yap @@ -1974,6 +2197,7 @@ diff.protected=Korumalı diff.image.side_by_side=Yan Yana diff.image.swipe=Kaydır diff.image.overlay=Arayüz +diff.has_escaped=Bu satırda gizli evrensel kod karakterler var releases.desc=Proje sürümlerini ve indirmeleri takip edin. release.releases=Sürümler @@ -2044,10 +2268,15 @@ branch.included_desc=Bu dal varsayılan dalın bir parçasıdır branch.included=Dahil branch.create_new_branch=Şu daldan dal oluştur: branch.confirm_create_branch=Dal oluştur +branch.create_branch_operation=Dal oluştur branch.new_branch=Yeni dal oluştur branch.new_branch_from='%s' dalından yeni dal oluştur +branch.renamed=%s dalının adı %s olarak değiştirildi. tag.create_tag=%s etiketi oluştur +tag.create_tag_operation=Etiket oluştur +tag.confirm_create_tag=Etiket oluştur +tag.create_tag_from='%s' kullanarak yeni etiket oluştur tag.create_success='%s' etiketi oluşturuldu. @@ -2056,6 +2285,8 @@ topic.done=Bitti topic.count_prompt=25'ten fazla konu seçemezsiniz topic.format_prompt=Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir. +find_file.go_to_file=Dosyaya git +find_file.no_matching=Eşleşen dosya bulunamadı error.csv.too_large=Bu dosya çok büyük olduğu için işlenemiyor. error.csv.unexpected=%d satırı ve %d sütununda beklenmeyen bir karakter içerdiğinden bu dosya işlenemiyor. @@ -2136,7 +2367,13 @@ teams.leave=Ayrıl teams.leave.detail=%s bırakılsın mı? teams.can_create_org_repo=Depoları oluştur teams.can_create_org_repo_helper=Üyeler organizasyonda yeni depolar oluşturabilirler. Oluşturan yeni depoya yönetici erişimi sağlayacak. +teams.none_access=Erişim Yok +teams.none_access_helper=Üyeler bu birimi görüntüleyemez veya üzerinde başka bir işlem yapamaz. +teams.general_access=Genel Erişim +teams.general_access_helper=Üyelerin izinleri aşağıdaki izin tablosuna göre kararlaştırılacaktır. +teams.read_access=Okuma teams.read_access_helper=Üyeler, takım depolarını görüntüleyebilir ve klonlayabilir. +teams.write_access=Yazma teams.write_access_helper=Üyeler takım depolarını okuyabilir ve itme yapabilir. teams.admin_access=Yönetici Erişimi teams.admin_access_helper=Üyeler takım depolarını çekip itebilir ve katkıcı ekleyebilir. @@ -2187,9 +2424,11 @@ first_page=İlk last_page=Son total=Toplam: %d +dashboard.new_version_hint=Gitea %s şimdi hazır, %s çalıştırıyorsunuz. Ayrıntılar için blog'a bakabilirsiniz. dashboard.statistic=Özet dashboard.operations=Bakım İşlemleri dashboard.system_status=Sistem Durumu +dashboard.statistic_info=Gitea veritabanında %d kullanıcılar, %d organizasyonlar, %d açık anahtarlar, %d depolar, %d izlemeler, %d yıldızlar, ~%d eylemler, %d erişimler, %d konular, %d yorumlar, %d sosyal hesaplar, %d takipler, %d yansılar, %d sürümler, %d kimlik doğrulama kaynakları, %d web istemcileri, %d dönüm noktaları, %d etiketler, %d istemci görevler, %d takımlar, %d güncelleme görevleri, %d ekler bulunuyor. dashboard.operation_name=İşlem Adı dashboard.operation_switch=Geç dashboard.operation_run=Çalıştır @@ -2228,6 +2467,7 @@ dashboard.resync_all_hooks=Tüm depoların alma öncesi, güncelleme ve alma son dashboard.reinit_missing_repos=Kayıtları bulunanlar için tüm eksik Git depolarını yeniden başlat dashboard.sync_external_users=Harici kullanıcı verisini senkronize et dashboard.cleanup_hook_task_table=Hook_task tablosunu temizleme +dashboard.cleanup_packages=Süresi dolmuş paketleri temizleme dashboard.server_uptime=Sunucunun Ayakta Kalma Süresi dashboard.current_goroutine=Güncel Goroutine'ler dashboard.current_memory_usage=Güncel Bellek Kullanımı @@ -2259,6 +2499,8 @@ dashboard.last_gc_pause=Son GC Durması dashboard.gc_times=GC Zamanları dashboard.delete_old_actions=Veritabanından tüm eski eylemleri sil dashboard.delete_old_actions.started=Veritabanından başlatılan tüm eski eylemleri silin. +dashboard.update_checker=Denetleyiciyi güncelle +dashboard.delete_old_system_notices=Veritabanından tüm eski sistem bildirimlerini sil users.user_manage_panel=Kullanıcı Hesap Yönetimi users.new_account=Yeni Kullanıcı Hesabı @@ -2293,10 +2535,26 @@ users.allow_import_local=Yerel Depoları Alabilir users.allow_create_organization=Organizasyon Oluşturabilir users.update_profile=Kullanıcı Hesabını Güncelle users.delete_account=Kullanıcı Hesabını Sil +users.cannot_delete_self=Kendinizi silemezsiniz users.still_own_repo=Bu kullanıcı hala bir veya daha fazla depoya sahip. Önce bu depoları silin veya transfer edin. users.still_has_org=Bu kullanıcı bir organizasyonun üyesidir. Önce kullanıcıyı tüm organizasyonlardan çıkarın. +users.purge=Kullanıcıyı Temizle +users.purge_help=Kullanıcıyı ve sahip olduğu herhangi bir depoyu, organizasyonu ve paketleri zorla sil. Tüm yorumlar da silinecektir. +users.still_own_packages=Kullanıcının bir veya daha fazla paketi var. Önce bu paketleri silin. users.deletion_success=Kullanıcı hesabı silindi. users.reset_2fa=2FD'yi sıfırla +users.list_status_filter.menu_text=Filtre +users.list_status_filter.reset=Sıfırla +users.list_status_filter.is_active=Etkin +users.list_status_filter.not_active=Etkin değil +users.list_status_filter.is_admin=Yönetici +users.list_status_filter.not_admin=Yönetici Değil +users.list_status_filter.is_restricted=Kısıtlanmış +users.list_status_filter.not_restricted=Kısıtlanmamış +users.list_status_filter.is_prohibit_login=Oturum Açmayı Önle +users.list_status_filter.not_prohibit_login=Oturum Açmaya İzin Ver +users.list_status_filter.is_2fa_enabled=2FA Etkin +users.list_status_filter.not_2fa_enabled=2FA Devre Dışı emails.email_manage_panel=Kullanıcı E-posta Yönetimi emails.primary=Birincil @@ -2329,6 +2587,16 @@ repos.forks=Çatallar repos.issues=Konular repos.size=Boyut +packages.package_manage_panel=Paket Yönetimi +packages.total_size=Toplam Boyut: %s +packages.owner=Sahibi +packages.creator=Oluşturan +packages.name=İsim +packages.version=Sürüm +packages.type=Tür +packages.repository=Depo +packages.size=Boyut +packages.published=Yayınlandı defaulthooks=Varsayılan Web İstemcileri defaulthooks.desc=Web İstemcileri, belirli Gitea olayları tetiklendiğinde otomatik olarak HTTP POST isteklerini sunucuya yapar. Burada tanımlanan Web İstemcileri varsayılandır ve tüm yeni depolara kopyalanır. web istemcileri kılavuzunda daha fazla bilgi edinin. @@ -2372,9 +2640,13 @@ auths.filter=Kullanıcı Filtresi auths.admin_filter=Yönetici Filtresi auths.restricted_filter=Kısıtlı Süzgeç auths.restricted_filter_helper=Hiçbir kullanıcıyı kısıtlı olarak ayarlamamak için boş bırakın. Yönetici Süzgeci ile eşleşmeyen tüm kullanıcıları kısıtlanmış olarak ayarlamak için yıldız işareti ('*') kullanın. +auths.verify_group_membership=LDAP'ta grup üyeliğini doğrula (atlamak için filtreyi boş bırakın) auths.group_search_base=Grup Arama Tabanı DN auths.group_attribute_list_users=Kullanıcı Listesi İçeren Grup Özelliği auths.user_attribute_in_group=Grupta Listelenen Kullanıcı Özelliği +auths.map_group_to_team=LDAP gruplarını Organizasyon takımlarına eşle (atlamak için bu alanı boş bırakın) +auths.map_group_to_team_removal=Eğer kullanıcı ilişkili LDAP grubuna ait değilse, kullanıcıları eşleşmiş takımlardan çıkarın +auths.enable_ldap_groups=LDAP gruplarını etkinleştir auths.ms_ad_sa=MS AD Arama Nitelikleri auths.smtp_auth=SMTP Yetkilendirme Türü auths.smtphost=SMTP Sunucusu @@ -2402,6 +2674,14 @@ auths.oauth2_emailURL=E-posta URL'si auths.skip_local_two_fa=Yerel 2FA'yı atla auths.skip_local_two_fa_helper=Bunu seçmediğinizde, 2FA ayarlamış olan yerel kullanıcıların, giriş yapabilmek için 2FA'yı yine de geçmeleri gerekiyor auths.oauth2_tenant=Kiracı +auths.oauth2_scopes=Ek Kapsamlar +auths.oauth2_required_claim_name=Gerekli Talep İsmi +auths.oauth2_required_claim_name_helper=Bu ismi, bu kaynağa oturum açmayı bu isimdeki talebe sahip kullanıcıların girişiyle sınırlamak için ayarlayın +auths.oauth2_required_claim_value=Gerekli Talep Değeri +auths.oauth2_required_claim_value_helper=Bu değeri, bu kaynağa oturum açmayı bu isimdeki ve değerdeki talebe sahip kullanıcıların girişiyle sınırlamak için ayarlayın +auths.oauth2_group_claim_name=Talep ismi bu kaynak için grup isimlerini sağlıyor. (İsteğe bağlı) +auths.oauth2_admin_group=Yönetici kullanıcıları için Grup Talep değeri. (İsteğe bağlı, yukarıda talep ismine gerek duyar) +auths.oauth2_restricted_group=Kısıtlı kullanıcılar için Grup Talep değeri. (İsteğe bağlı, yukarıda talep ismine gerek duyar) auths.enable_auto_register=Otomatik Kaydolmayı Etkinleştir auths.sspi_auto_create_users=Kullanıcıları otomatik olarak oluştur auths.sspi_auto_create_users_helper=SSPI kimlik doğrulama yönteminin ilk kez oturum açan kullanıcılar için otomatik olarak yeni hesaplar oluşturmasına izin ver @@ -2449,6 +2729,7 @@ config.app_ver=Gitea Sürümü config.app_url=Gitea Taban URL'si config.custom_conf=Yapılandırma Dosyası Yolu config.custom_file_root_path=Özel Dosya Kök Yolu +config.domain=Sunucu Alan Adı config.offline_mode=Yerel Kip config.disable_router_log=Yönlendirici Log'larını Devre Dışı Bırak config.run_user=Şu Kullanıcı Olarak Çalıştır @@ -2464,6 +2745,7 @@ config.reverse_auth_user=Tersine Yetkilendirme Kullanıcısı config.ssh_config=SSH Yapılandırması config.ssh_enabled=Aktif config.ssh_start_builtin_server=Yerleşik Sunucuyu Kullan +config.ssh_domain=SSH Sunucusu Alan Adı config.ssh_port=Bağlantı Noktası config.ssh_listen_port=Port'u Dinle config.ssh_root_path=Kök Yol @@ -2514,16 +2796,19 @@ config.queue_length=Kuyruk Uzunluğu config.deliver_timeout=Dağıtım Zaman Aşımı config.skip_tls_verify=TLS Doğrulamasını Geç -config.mailer_config=SMTP Mailer Yapılandırması +config.mailer_config=Mailer Yapılandırması config.mailer_enabled=Aktif -config.mailer_disable_helo=HELO'yu Devre Dışı Bırak +config.mailer_enable_helo=HELO'yu etkinleştir config.mailer_name=İsim -config.mailer_host=Sunucu +config.mailer_protocol=Protokol +config.mailer_smtp_addr=SMTP Adresi +config.mailer_smtp_port=SMTP Portu config.mailer_user=Kullanıcı config.mailer_use_sendmail=Sendmail Kullan config.mailer_sendmail_path=Sendmail Yolu config.mailer_sendmail_args=Sendmail İçin İlave Değişkenler config.mailer_sendmail_timeout=Sendmail Zaman Aşımı +config.mailer_use_dummy=Sahte config.test_email_placeholder=E-posta (ör. test@example.com) config.send_test_mail=Test E-postası Gönder config.test_mail_failed='%s' adresine test e-postası gönderilemedi: %v @@ -2583,12 +2868,16 @@ monitor.next=Sonraki Zaman monitor.previous=Önceki Zaman monitor.execute_times=Çalıştırma monitor.process=Çalışan Süreçler +monitor.stacktrace=Yığın izleme +monitor.goroutines=%d Gorutinleri monitor.desc=Açıklama monitor.start=Başlangıç Zamanı monitor.execute_time=Çalıştırma Zamanı +monitor.last_execution_result=Sonuç monitor.process.cancel=İşlemi iptal et monitor.process.cancel_desc=Bir işlemi iptal etmek veri kaybına neden olabilir monitor.process.cancel_notices=İptal et: %s? +monitor.process.children=Çocuklar monitor.queues=Kuyruklar monitor.queue=Kuyruk: %s monitor.queue.name=İsim @@ -2596,6 +2885,7 @@ monitor.queue.type=Tür monitor.queue.exemplar=Örnek Türü monitor.queue.numberworkers=Çalışan Sayısı monitor.queue.maxnumberworkers=En Fazla Çalışan Sayısı +monitor.queue.numberinqueue=Kuyruktaki Sayı monitor.queue.review=Yapılandırmayı İncele monitor.queue.review_add=Çalışanları İncele/Ekle monitor.queue.configuration=Başlangıç Yapılandırması @@ -2615,6 +2905,12 @@ monitor.queue.pool.flush.title=Kuyruk Temizleme monitor.queue.pool.flush.desc=Temizleme, kuyruk boş olduğunda veya zaman aşımına uğradığında sona erecek bir işçi ekler. monitor.queue.pool.flush.submit=Temizleme İşçisi Ekle monitor.queue.pool.flush.added=%[1]s için Temizleme İşçisi eklendi +monitor.queue.pool.pause.title=Kuyruğu Duraklat +monitor.queue.pool.pause.desc=Kuyruğun duraklatılması veriyi işlemesini önleyecektir +monitor.queue.pool.pause.submit=Kuyruğu Duraklat +monitor.queue.pool.resume.title=Kuyruğu Sürdür +monitor.queue.pool.resume.desc=Bu kuyruğun çalışmasını sürdür +monitor.queue.pool.resume.submit=Kuyruğu Sürdür monitor.queue.settings.title=Havuz Ayarları monitor.queue.settings.desc=Havuzlar, çalışan kuyruğunun engellenmesine yanıt olarak dinamik bir şekilde büyür. Bu değişiklikler mevcut çalışan gruplarını etkilemeyecektir. @@ -2660,14 +2956,34 @@ notices.delete_success=Sistem bildirimleri silindi. [action] create_repo=depo %s oluşturuldu rename_repo=%[1]s olan depo adını %[3]s buna çevirdi +commit_repo=%[4]s deposuna %[3]s dalını gönderdi +create_issue=`%[3]s#%[2]s konusunu açtı` +close_issue=`%[3]s#%[2]s konusunu kapattı` +reopen_issue=`%[3]s#%[2]s konusunu tekrar açtı` +create_pull_request=`%[3]s#%[2]s değişiklik isteğini oluşturdu` +close_pull_request=`%[3]s#%[2]s değişiklik isteğini kapattı` +reopen_pull_request=`%[3]s#%[2]s değişiklik isteğini yeniden açtı` +comment_issue=`%[3]s#%[2]s konusuna yorum yaptı` +comment_pull=`%[3]s#%[2]s değişiklik isteğine yorum yaptı` +merge_pull_request=`%[3]s#%[2]s değişiklik isteğini birleştirdi` transfer_repo=depo %s %s'a aktarıldı +push_tag=%[3]s etiketini %[4]s dalına gönderdi delete_tag=%[2]s etiketi %[3]s deposundan silindi delete_branch=%[3]s deposundan %[2]s dalı silindi compare_branch=Karşılaştır compare_commits=%d işlemeyi karşılaştır compare_commits_general=İşlemeleri karşılaştır +mirror_sync_push=yansıdan %[4]s deposundaki %[3]s dalına işlemeleri eşitledi +mirror_sync_create=%[3]s yeni referansını, %[4]s olarak yansıdan eşledi mirror_sync_delete=%[3]s adresindeki %[2]s referansını eşitledi ve sildi +approve_pull_request=`%[3]s#%[2]s değişiklik isteğini onayladı` +reject_pull_request=`%[3]s#%[2]s için değişiklikler önerdi` +publish_release=`%[3]s deposu için "%[4]s" sürümü yayınlandı` +review_dismissed=`%[3]s#%[2]s için %[4]s yorumunu reddetti` review_dismissed_reason=Sebep: +create_branch=%[4]s deposunda %[3]s dalını oluşturdu +starred_repo=%[2]s deposuna yıldız bıraktı +watched_repo=%[2]s deposunu izlemeye başladı [tool] ago=%s önce @@ -2720,8 +3036,100 @@ error.probable_bad_signature=UYARI! Veritabanında bu kimliğe sahip bir anahtar error.probable_bad_default_signature=UYARI! Varsayılan anahtarın bu kimliği olmasına rağmen, bu işlemeyi doğrulamaz! Bu işleme ŞÜPHELİDİR. [units] +unit=Birim error.no_unit_allowed_repo=Bu deponun hiçbir bölümüne erişme izniniz yok. error.unit_not_allowed=Bu depo bölümüne erişme izniniz yok. [packages] +title=Paketler +desc=Depo paketlerini yönet. +empty=Henüz hiçbir paket yok. +empty.documentation=Paket kütüğü hakkında daha fazla bilgi için, belgeye bakabilirsiniz. +empty.repo=Bir paket yüklediniz ama burada gösterilmiyor mu? Paket ayarlarına gidin ve bu depoya bağlantı verin. +filter.type=Tür +filter.type.all=Tümü +filter.no_result=Filtreniz herhangi bir sonuç döndürmedi. +filter.container.tagged=Etiketlenmiş +filter.container.untagged=Etiketlenmemiş +published_by=%[1]s, %[3]s tarafından yayınlandı +published_by_in=%[1]s, %[3]s tarafından %[5]s içerisinde yayınlanmış +installation=Kurulum +about=Bu paket hakkında +requirements=Gereksinimler +dependencies=Bağımlılıklar +keywords=Anahtar Kelimeler +details=Ayrıntılar +details.author=Yazar +details.project_site=Proje Web Sitesi +details.license=Lisans +assets=Varlıklar +versions=Sürümler +versions.on=açık +versions.view_all=Tümünü görüntüle +dependency.id=Kimlik +dependency.version=Sürüm +composer.registry=Bu kütüğü ~/.composer/config.json dosyasında ayarlayın: +composer.install=Paketi Composer ile kurmak için, şu komutu çalıştırın: +composer.documentation=Composer kütüğü hakkında daha fazla bilgi için, belgeye bakabilirsiniz. +composer.dependencies=Bağımlılıklar +composer.dependencies.development=Geliştirme Bağımlılıkları +conan.details.repository=Depo +conan.registry=Bu kütüğü komut satırını kullanarak kurun: +conan.install=Conan ile paket kurmak için aşağıdaki komutu çalıştırın: +conan.documentation=Conan kütüğü hakkında daha fazla bilgi için, belgeye bakabilirsiniz. +container.details.type=Görüntü Türü +container.details.platform=Platform +container.details.repository_site=Depo Sitesi +container.details.documentation_site=Belge Sitesi +container.pull=Görüntüyü komut satırını kullanarak çekin: +container.documentation=Taşıyıcı kütüğü hakkında daha fazla bilgi için, belgeye bakabilirsiniz. +container.multi_arch=İşletim Sistemi / Mimari +container.layers=Görüntü Katmanları +container.labels=Etiketler +container.labels.key=Anahtar +container.labels.value=Değer +generic.download=Paketi komut satırında indirin: +generic.documentation=Genel kütük hakkında daha fazla bilgi için, belgeye bakabilirsiniz. +helm.registry=Bu kütüğü komut satırını kullanarak kurun: +helm.install=Paketi kurmak için, aşağıdaki komutu çalıştırın: +helm.documentation=Helm kütüğü hakkında daha fazla bilgi için, belgeye bakabilirsiniz. +maven.registry=Bu kütüğü projenizdeki pom.xml dosyasında ayarlayın: +maven.install=Paketi kullanmak için aşağıdaki dependencies parçasını pom.xml dosyasınıza ekleyin: +maven.install2=Komut satırında çalıştırın: +maven.download=Bağımlılığı indirmek için, komut satırında çalıştırın: +maven.documentation=Maven kütüğü hakkında daha fazla bilgi için, belgeye bakabilirsiniz. +nuget.registry=Bu kütüğü komut satırını kullanarak kurun: +nuget.install=Paketi NuGet ile kurmak için, şu komutu çalıştırın: +nuget.documentation=NuGet kütüğü hakkında daha fazla bilgi için, belgeye bakabilirsiniz. +nuget.dependency.framework=Hedef Çerçeve +npm.registry=Bu kütüğü projenizdeki .npmrc dosyasında ayarlayın: +npm.install=Paketi npm ile kurmak için, şu komutu çalıştırın: +npm.install2=veya paketi package.json dosyasına ekleyin: +npm.documentation=Npm kütüğü hakkında daha fazla bilgi için, belgeye bakabilirsiniz. +npm.dependencies=Bağımlılıklar +npm.dependencies.development=Geliştirme Bağımlılıkları +npm.dependencies.peer=Eş Bağımlılıkları +npm.dependencies.optional=İsteğe Bağlı Bağımlılıklar +npm.details.tag=Etiket +pypi.requires=Gereken Python +pypi.install=Paketi pip ile kurmak için, şu komutu çalıştırın: +pypi.documentation=PyPI kütüğü hakkında daha fazla bilgi için, belgeye bakabilirsiniz. +rubygems.install=Paketi gem ile kurmak için, şu komutu çalıştırın: +rubygems.install2=veya paketi Gemfile dosyasına ekleyin: +rubygems.dependencies.runtime=Çalışma Zamanı Bağımlılıkları +rubygems.dependencies.development=Geliştirme Bağımlılıkları +rubygems.required.ruby=Gereken Ruby sürümü +rubygems.required.rubygems=Gereken RubyGem sürümü +rubygems.documentation=RubyGems kütüğü hakkında daha fazla bilgi için, belgeye bakabilirsiniz. +settings.link=Bu paketi bir depoya bağlayın +settings.link.description=Eğer bir paketi bir depoya bağlarsanız, paket deponun paket listesinde listelenecektir. +settings.link.select=Depo Seç +settings.link.button=Depo Bağlantısını Güncelle +settings.link.success=Depo bağlantısı başarıyla güncellendi. +settings.link.error=Depo bağlantısı güncellenemedi. +settings.delete=Paket Sil +settings.delete.description=Bir paketi silmek kalıcıdır ve geri alınamaz. +settings.delete.notice=%s (%s) paketini silmek üzeresiniz. Bu işlem geri alınamaz, emin misiniz? +settings.delete.success=Paket silindi. +settings.delete.error=Paket silinemedi. diff --git a/options/locale/locale_uk-UA.ini b/options/locale/locale_uk-UA.ini index 460ab2192cc24..a5f26fd2202c6 100644 --- a/options/locale/locale_uk-UA.ini +++ b/options/locale/locale_uk-UA.ini @@ -161,7 +161,6 @@ log_root_path_helper=Файли журналу будуть записані в optional_title=Додаткові налаштування email_title=Налаштування Email -smtp_host=SMTP хост smtp_from=Відправляти Email від імені smtp_from_helper=Електронна пошта для використання в Gіtea. Введіть звичайну електронну адресу або використовуйте формат: "Ім'я" . mailer_user=SMTP Ім'я кристувача @@ -1317,7 +1316,6 @@ issues.due_date_form_remove=Видалити issues.due_date_not_writer=Вам потрібен доступ до запису в репозиторії, щоб оновити дату завершення задач. issues.due_date_not_set=Термін виконання не встановлений. issues.due_date_added=додав(ла) дату завершення %s %s -issues.due_date_modified=термін змінено з %s %s на %s issues.due_date_remove=видалив(ла) дату завершення %s %s issues.due_date_overdue=Прострочено issues.due_date_invalid=Термін дії не дійсний або знаходиться за межами допустимого діапазону. Будь ласка використовуйте формат 'yyyy-mm-dd'. @@ -1418,7 +1416,6 @@ pulls.remove_prefix=Видалити префікс %s pulls.data_broken=Зміст цього запиту було порушено внаслідок видалення інформації Форком. Цей запит тягнеться через відсутність інформації про вилучення. pulls.files_conflicted=Цей запит має зміни, що конфліктують з цільовою гілкою. pulls.is_checking=Триває перевірка конфліктів, будь ласка обновіть сторінку дещо пізніше. -pulls.is_empty=Ця гілка ідентична з цільовою гілкою. pulls.required_status_check_failed=Деякі необхідні перевірки виконані з помилками. pulls.required_status_check_missing=Декілька з необхідних перевірок відсутні. pulls.required_status_check_administrator=Як адміністратор ви все одно можете об'єднати цей запит на злиття. @@ -1652,10 +1649,6 @@ settings.mirror_settings.push_mirror.remote_url=URL віддаленого ре settings.mirror_settings.push_mirror.add=Додати Push дзеркало settings.sync_mirror=Синхронізувати зараз settings.mirror_sync_in_progress=Синхронізуються репозиторії-дзеркала. Зачекайте хвилину і обновіть сторінку. -settings.email_notifications.enable=Увімкнути сповіщення email -settings.email_notifications.onmention=Повідомнення email тільки при згадуванні -settings.email_notifications.disable=Вимкнути email сповіщення -settings.email_notifications.submit=Налаштувати параметри email settings.site=Веб-сайт settings.update_settings=Оновити налаштування settings.branches.update_default_branch=Оновити гілку за замовчуванням @@ -2588,11 +2581,8 @@ config.queue_length=Довжина черги config.deliver_timeout=Затримка доставки config.skip_tls_verify=Пропустити перевірку TLS -config.mailer_config=Конфігурація SMTP-сервера config.mailer_enabled=Увімкнено -config.mailer_disable_helo=Вимкнути HELO config.mailer_name=Ім'я -config.mailer_host=Хост config.mailer_user=Користувач config.mailer_use_sendmail=Використовувати Sendmail config.mailer_sendmail_path=Шлях до Sendmail diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index eec7c0ba596ee..ef239d0e3fbf9 100644 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -179,7 +179,6 @@ log_root_path_helper=日志文件将写入此目录。 optional_title=可选设置 email_title=电子邮箱设置 -smtp_host=SMTP 主机 smtp_from=电子邮件发件人 smtp_from_helper=电子邮件地址 Gitea 将使用。输入一个普通的电子邮件地址或使用 "名称" 格式。 mailer_user=SMTP 用户名 @@ -1419,7 +1418,6 @@ issues.due_date_form_remove=删除 issues.due_date_not_writer=你需要仓库写入权限来修改工单到期时间。 issues.due_date_not_set=未设置到期时间。 issues.due_date_added=于 %[2]s 设置到期时间为 %[1]s -issues.due_date_modified=于 %[3]s 将到期时间从 %[2]s 修改为 %[1]s issues.due_date_remove=于 %[2]s 删除了到期时间 %[1]s issues.due_date_overdue=过期 issues.due_date_invalid=到期日期无效或超出范围。请使用 'yyyy-mm-dd' 格式。 @@ -1531,7 +1529,6 @@ pulls.remove_prefix=删除 %s 前缀 pulls.data_broken=此合并请求因为派生仓库信息缺失而中断。 pulls.files_conflicted=此合并请求有变更与目标分支冲突。 pulls.is_checking=正在进行合并冲突检测,请稍后再试。 -pulls.is_empty=此分支与目标分支相同。 pulls.required_status_check_failed=一些必要的检查没有成功 pulls.required_status_check_missing=缺少一些必要的检查。 pulls.required_status_check_administrator=作为管理员,您仍可合并此合并请求 @@ -1682,7 +1679,7 @@ 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=输入此 Wiki 页面的名称。特殊名称有:'Home', '_Sidebar' 和 '_Footer'。 activity=动态 activity.period.filter_label=周期: @@ -1782,10 +1779,6 @@ settings.mirror_settings.push_mirror.remote_url=Git 远程仓库链接 settings.mirror_settings.push_mirror.add=添加推送镜像 settings.sync_mirror=同步 settings.mirror_sync_in_progress=镜像同步正在进行中,请稍后再试。 -settings.email_notifications.enable=启用邮件通知 -settings.email_notifications.onmention=只在被提到时邮件通知 -settings.email_notifications.disable=停用邮件通知 -settings.email_notifications.submit=邮件通知设置 settings.site=网站 settings.update_settings=更新仓库设置 settings.branches.update_default_branch=更新默认分支 @@ -2794,11 +2787,8 @@ config.queue_length=队列长度 config.deliver_timeout=推送超时 config.skip_tls_verify=跳过 TLS 验证 -config.mailer_config=邮件配置 config.mailer_enabled=启用服务 -config.mailer_disable_helo=禁用 HELO 操作 config.mailer_name=任务名称 -config.mailer_host=邮件主机地址 config.mailer_user=发送者帐号 config.mailer_use_sendmail=使用 Sendmail config.mailer_sendmail_path=Sendmail 路径 diff --git a/options/locale/locale_zh-HK.ini b/options/locale/locale_zh-HK.ini index c6ea7ce673515..587ee5bb23094 100644 --- a/options/locale/locale_zh-HK.ini +++ b/options/locale/locale_zh-HK.ini @@ -64,7 +64,6 @@ repo_path=儲存庫的根目錄 log_root_path=日誌路徑 optional_title=可選設定 -smtp_host=SMTP 主機 federated_avatar_lookup_popup=開啟聯合頭像查詢並使用基於開放源碼的 libravatar 服務 enable_captcha_popup=要求在用戶註冊時輸入驗證碼 admin_password=管理員密碼 @@ -760,9 +759,7 @@ config.deliver_timeout=推送超時 config.skip_tls_verify=略過 TLS 驗證 config.mailer_enabled=啟用服務 -config.mailer_disable_helo=禁用 HELO 操作 config.mailer_name=發送者名稱 -config.mailer_host=郵件主機地址 config.mailer_user=發送者帳號 config.oauth_config=社交帳號設定 diff --git a/options/locale/locale_zh-TW.ini b/options/locale/locale_zh-TW.ini index 3dcd5ecd04012..0e0dc6d59fed5 100644 --- a/options/locale/locale_zh-TW.ini +++ b/options/locale/locale_zh-TW.ini @@ -179,7 +179,6 @@ log_root_path_helper=日誌檔將寫入此目錄。 optional_title=可選設定 email_title=電子郵件設定 -smtp_host=SMTP 主機 smtp_from=電子郵件寄件者 smtp_from_helper=Gitea 將會使用的電子信箱,直接輸入電子信箱或使用「"名稱" 」的格式。 mailer_user=SMTP 帳號 @@ -758,7 +757,7 @@ twofa_is_enrolled=您的帳戶已經啟用兩步驟驗證。 twofa_not_enrolled=您的帳戶目前尚未啟用兩步驟驗證。 twofa_disable=停用兩步驟驗證 twofa_scratch_token_regenerate=重新產生備用驗證碼 -twofa_scratch_token_regenerated=您的備用驗證碼是 %s。請將它保存到一個安全的地方。 +twofa_scratch_token_regenerated=您的備用驗證碼是 %s。請將它保存到安全的地方。 twofa_enroll=啟用兩步驟驗證 twofa_disable_note=如有需要,您可以停用兩步驟驗證。 twofa_disable_desc=關閉兩步驟驗證會使您的帳戶安全性降低,是否繼續? @@ -768,7 +767,7 @@ scan_this_image=使用您的授權應用程式來掃瞄圖片: or_enter_secret=或者輸入密碼: %s then_enter_passcode=然後輸入應用程式中顯示的驗證碼: passcode_invalid=無效的驗證碼,請重試。 -twofa_enrolled=您的帳戶已經啟用了兩步驟驗證。請將備用驗證碼 (%s) 保存到一個安全的地方,它只會顯示這麼一次! +twofa_enrolled=您的帳戶已經啟用了兩步驟驗證。請將備用驗證碼 (%s) 保存到安全的地方,它只會顯示這麼一次! twofa_failed_get_secret=取得密鑰 (Secret) 失敗。 webauthn_desc=安全金鑰是包含加密密鑰的硬體設備,它們可以用於兩步驟驗證。安全金鑰必須支援 WebAuthn Authenticator 標準。 @@ -843,7 +842,7 @@ repo_lang=儲存庫語言 repo_gitignore_helper=選擇 .gitignore 範本 repo_gitignore_helper_desc=從常見語言範本清單中挑選忽略追蹤的檔案。預設情況下各種語言建置工具產生的特殊檔案都包含在 .gitignore 中。 issue_labels=問題標籤 -issue_labels_helper=選擇一個問題標籤集 +issue_labels_helper=選擇問題標籤集 license=授權條款 license_helper=請選擇授權條款檔案 license_helper_desc=授權條款定義了他人使用您原始碼的允許和禁止事項。不確定哪個適用於您的專案?查看選擇授權條款。 @@ -861,7 +860,9 @@ default_branch=預設分支 default_branch_helper=預設分支是合併請求和提交程式碼的基礎分支。 mirror_prune=裁減 mirror_prune_desc=刪除過時的遠端追蹤參考 +mirror_interval=鏡像間隔 (有效時間單位為 'h'、'm'、's'),設為 0 以停用定期同步。(最小間隔: %s) mirror_interval_invalid=鏡像週期無效 +mirror_sync_on_commit=推送提交後進行同步 mirror_address=從 URL Clone mirror_address_desc=在授權資訊中填入必要的資料。 mirror_address_url_invalid=提供的網址無效。請檢查您輸入的網址是否正確。 @@ -1089,7 +1090,7 @@ editor.commit_message_desc=(選用) 加入詳細說明... editor.signoff_desc=在提交訊息底部加入提交者的「Signed-off-by」資訊。 editor.commit_directly_to_this_branch=直接提交到 %s 分支。 editor.create_new_branch=為此提交建立新分支並提出合併請求。 -editor.create_new_branch_np=為本次提交建立一個 新分支。 +editor.create_new_branch_np=為本次提交建立新分支。 editor.propose_file_change=提出檔案變更 editor.new_branch_name_desc=新的分支名稱... editor.cancel=取消 @@ -1173,7 +1174,7 @@ projects.type.none=無 projects.type.basic_kanban=基本看板 projects.type.bug_triage=Bug 檢傷分類 projects.template.desc=專案範本 -projects.template.desc_helper=選擇一個專案範本以開始 +projects.template.desc_helper=選擇專案範本以開始 projects.type.uncategorized=未分類 projects.board.edit=編輯看板 projects.board.edit_title=新看板名稱 @@ -1300,6 +1301,7 @@ issues.previous=上一頁 issues.next=下一頁 issues.open_title=開放中 issues.closed_title=已關閉 +issues.draft_title=草稿 issues.num_comments=%d 則留言 issues.commented_at=`已留言 %s` issues.delete_comment_confirm=您確定要刪除這則留言嗎? @@ -1416,7 +1418,6 @@ issues.due_date_form_remove=移除 issues.due_date_not_writer=您需要儲存庫寫入權限來更改問題的截止日。 issues.due_date_not_set=未設定截止日期。 issues.due_date_added=新增了截止日期 %s %s -issues.due_date_modified=將截止日期修改為 %s ,原截止日期: %s %s issues.due_date_remove=移除了截止日期 %s %s issues.due_date_overdue=逾期 issues.due_date_invalid=截止日期無效或超出範圍,請使用「yyyy-mm-dd」的格式。 @@ -1528,7 +1529,6 @@ pulls.remove_prefix=移除 %s 前綴 pulls.data_broken=此合併請求已損毀,因為遺失 Fork 資訊。 pulls.files_conflicted=此合併請求有變更和目標分支衝突。 pulls.is_checking=正在進行合併衝突檢查,請稍後再試。 -pulls.is_empty=此分支與目標分支相同。 pulls.required_status_check_failed=未通過某些必要的檢查。 pulls.required_status_check_missing=遺失某些必要的檢查。 pulls.required_status_check_administrator=身為系統管理員,您依然可以進行合併。 @@ -1779,10 +1779,6 @@ settings.mirror_settings.push_mirror.remote_url=Git 遠端儲存庫 URL settings.mirror_settings.push_mirror.add=新增推送鏡像 settings.sync_mirror=立即同步 settings.mirror_sync_in_progress=鏡像同步正在進行中。 請稍後再回來看看。 -settings.email_notifications.enable=啟用郵件通知 -settings.email_notifications.onmention=只在被提到時傳送郵件通知 -settings.email_notifications.disable=關閉郵件通知 -settings.email_notifications.submit=套用郵件偏好設定 settings.site=網站 settings.update_settings=更新設定 settings.branches.update_default_branch=更新預設分支 @@ -2213,7 +2209,7 @@ release.new_subheader=發布、整理專案的版本。 release.edit_subheader=發布、整理專案的版本。 release.tag_name=標籤名稱 release.target=目標分支 -release.tag_helper=新增或選擇一個既有的標籤。 +release.tag_helper=新增或選擇既有的標籤。 release.title=標題 release.content=內容 release.prerelease_desc=標記為 Pre-Release @@ -2694,8 +2690,8 @@ auths.tips.oauth2.general.tip=註冊新的 OAuth2 認證時,callback/redirect auths.tip.oauth2_provider=OAuth2 提供者 auths.tip.bitbucket=註冊新的 OAuth 客戶端並加入權限「Account - Read」。網址:https://bitbucket.org/account/user//oauth-consumers/new auths.tip.nextcloud=在您的執行個體中,於選單「設定 -> 安全性 -> OAuth 2.0 客戶端」註冊新的 OAuth 客戶端 -auths.tip.dropbox=建立一個新的 App。網址:https://www.dropbox.com/developers/apps -auths.tip.facebook=註冊一個新的應用程式並新增產品「Facebook 登入」。網址:https://developers.facebook.com/apps +auths.tip.dropbox=建立新的 App。網址:https://www.dropbox.com/developers/apps +auths.tip.facebook=註冊新的應用程式並新增產品「Facebook 登入」。網址:https://developers.facebook.com/apps auths.tip.github=註冊新的 OAuth 應用程式。網址:https://github.com/settings/applications/new auths.tip.gitlab=註冊新的應用程式。網址:https://gitlab.com/profile/applications auths.tip.google_plus=從 Google API 控制台取得 OAuth2 用戶端憑證。網址:https://console.developers.google.com/ @@ -2791,11 +2787,8 @@ config.queue_length=佇列長度 config.deliver_timeout=傳送逾時 config.skip_tls_verify=略過 TLS 驗證 -config.mailer_config=SMTP 組態 config.mailer_enabled=啟用服務 -config.mailer_disable_helo=停用 HELO 操作 config.mailer_name=發送者名稱 -config.mailer_host=郵件主機地址 config.mailer_user=發送者帳號 config.mailer_use_sendmail=使用 Sendmail config.mailer_sendmail_path=Sendmail 路徑 diff --git a/package-lock.json b/package-lock.json index 411a22037d12e..945193538591e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,7 @@ "license": "MIT", "dependencies": { "@claviska/jquery-minicolors": "2.3.6", - "@primer/octicons": "17.2.0", + "@primer/octicons": "17.4.0", "add-asset-webpack-plugin": "2.0.1", "css-loader": "6.7.1", "dropzone": "6.0.0-beta.2", @@ -19,16 +19,17 @@ "font-awesome": "4.7.0", "jquery": "3.6.0", "jquery.are-you-sure": "1.9.0", - "less": "4.1.2", + "less": "4.1.3", "less-loader": "11.0.0", "license-checker-webpack-plugin": "0.2.1", - "mermaid": "9.1.2", - "mini-css-extract-plugin": "2.6.0", + "mermaid": "9.1.3", + "mini-css-extract-plugin": "2.6.1", "monaco-editor": "0.33.0", "monaco-editor-webpack-plugin": "7.0.1", - "pretty-ms": "7.0.1", + "pretty-ms": "8.0.0", "sortablejs": "1.15.0", - "swagger-ui-dist": "4.11.1", + "swagger-ui-dist": "4.13.2", + "tippy.js": "6.3.7", "tributejs": "5.1.3", "uint8-to-base64": "0.2.0", "vue": "2.6.14", @@ -36,32 +37,33 @@ "vue-calendar-heatmap": "0.8.4", "vue-loader": "15.9.8", "vue-template-compiler": "2.6.14", - "webpack": "5.72.1", - "webpack-cli": "4.9.2", - "workbox-routing": "6.5.3", - "workbox-strategies": "6.5.3", + "webpack": "5.74.0", + "webpack-cli": "4.10.0", + "workbox-routing": "6.5.4", + "workbox-strategies": "6.5.4", "worker-loader": "3.0.8", "wrap-ansi": "8.0.1" }, "devDependencies": { - "@happy-dom/jest-environment": "4.0.1", - "@stoplight/spectral-cli": "6.4.1", - "eslint": "8.15.0", - "eslint-plugin-html": "6.2.0", + "@happy-dom/jest-environment": "6.0.4", + "@stoplight/spectral-cli": "6.5.0", + "eslint": "8.21.0", "eslint-plugin-import": "2.26.0", "eslint-plugin-jquery": "1.5.1", - "eslint-plugin-unicorn": "42.0.0", - "eslint-plugin-vue": "9.0.1", - "jest": "28.1.0", - "jest-extended": "2.0.0", + "eslint-plugin-sonarjs": "0.14.0", + "eslint-plugin-unicorn": "43.0.2", + "eslint-plugin-vue": "9.3.0", + "jest": "28.1.3", + "jest-extended": "3.0.1", + "markdownlint-cli": "0.32.1", "postcss-less": "6.0.0", - "stylelint": "14.8.2", - "stylelint-config-standard": "25.0.0", + "stylelint": "14.9.1", + "stylelint-config-standard": "26.0.0", "svgo": "2.8.0", - "updates": "13.0.5" + "updates": "13.1.4" }, "engines": { - "node": ">= 14" + "node": ">= 14.0.0" } }, "node_modules/@ampproject/remapping": { @@ -84,42 +86,42 @@ "dev": true }, "node_modules/@babel/code-frame": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", - "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", "dev": true, "dependencies": { - "@babel/highlight": "^7.16.7" + "@babel/highlight": "^7.18.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.17.10", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.10.tgz", - "integrity": "sha512-GZt/TCsG70Ms19gfZO1tM4CVnXsPgEPBCpJu+Qz3L0LUDsY5nZqFZglIoPC1kIYOtNBZlrnFT+klg12vFGZXrw==", + "version": "7.18.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.18.8.tgz", + "integrity": "sha512-HSmX4WZPPK3FUxYp7g2T6EyO8j96HlZJlxmKPSh6KAcqwyDrfx7hKjXpAW/0FhFfTJsR0Yt4lAjLI2coMptIHQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.0.tgz", - "integrity": "sha512-Xyw74OlJwDijToNi0+6BBI5mLLR5+5R3bcSH80LXzjzEGEUlvNzujEE71BaD/ApEZHAvFI/Mlmp4M5lIkdeeWw==", + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.10.tgz", + "integrity": "sha512-JQM6k6ENcBFKVtWvLavlvi/mPcpYZ3+R+2EySDEMSMbp7Mn4FexlbbJVrx2R7Ijhr01T8gyqrOaABWIOgxeUyw==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.18.0", - "@babel/helper-compilation-targets": "^7.17.10", - "@babel/helper-module-transforms": "^7.18.0", - "@babel/helpers": "^7.18.0", - "@babel/parser": "^7.18.0", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.18.0", - "@babel/types": "^7.18.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.18.10", + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-module-transforms": "^7.18.9", + "@babel/helpers": "^7.18.9", + "@babel/parser": "^7.18.10", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.18.10", + "@babel/types": "^7.18.10", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -144,13 +146,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.0.tgz", - "integrity": "sha512-81YO9gGx6voPXlvYdZBliFXAZU8vZ9AZ6z+CjlmcnaeOcYSFbMTpdeDUO9xD9dh/68Vq03I8ZspfUTPfitcDHg==", + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.10.tgz", + "integrity": "sha512-0+sW7e3HjQbiHbj1NeU/vN8ornohYlacAfZIaXhdoGweQqgcNy69COVciYYqEXJ/v+9OBA7Frxm4CVAuNqKeNA==", "dev": true, "dependencies": { - "@babel/types": "^7.18.0", - "@jridgewell/gen-mapping": "^0.3.0", + "@babel/types": "^7.18.10", + "@jridgewell/gen-mapping": "^0.3.2", "jsesc": "^2.5.1" }, "engines": { @@ -158,12 +160,12 @@ } }, "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.1.tgz", - "integrity": "sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", "dev": true, "dependencies": { - "@jridgewell/set-array": "^1.0.0", + "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.9" }, @@ -172,13 +174,13 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.17.10", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.10.tgz", - "integrity": "sha512-gh3RxjWbauw/dFiU/7whjd0qN9K6nPJMqe6+Er7rOavFh0CQUSwhAE3IcTho2rywPJFxej6TUUHDkWcYI6gGqQ==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.9.tgz", + "integrity": "sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.17.10", - "@babel/helper-validator-option": "^7.16.7", + "@babel/compat-data": "^7.18.8", + "@babel/helper-validator-option": "^7.18.6", "browserslist": "^4.20.2", "semver": "^6.3.0" }, @@ -199,145 +201,151 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", - "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", "dev": true, - "dependencies": { - "@babel/types": "^7.16.7" - }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.17.9", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz", - "integrity": "sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz", + "integrity": "sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A==", "dev": true, "dependencies": { - "@babel/template": "^7.16.7", - "@babel/types": "^7.17.0" + "@babel/template": "^7.18.6", + "@babel/types": "^7.18.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", - "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", "dev": true, "dependencies": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.18.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", - "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", "dev": true, "dependencies": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.18.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.18.0.tgz", - "integrity": "sha512-kclUYSUBIjlvnzN2++K9f2qzYKFgjmnmjwL4zlmU5f8ZtzgWe8s0rUPSTGy2HmK4P8T52MQsS+HTQAgZd3dMEA==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.18.9.tgz", + "integrity": "sha512-KYNqY0ICwfv19b31XzvmI/mfcylOzbLtowkw+mfvGPAQ3kfCnMLYbED3YecL5tPd8nAYFQFAd6JHp2LxZk/J1g==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-simple-access": "^7.17.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/helper-validator-identifier": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.18.0", - "@babel/types": "^7.18.0" + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.18.6", + "@babel/template": "^7.18.6", + "@babel/traverse": "^7.18.9", + "@babel/types": "^7.18.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.17.12", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.17.12.tgz", - "integrity": "sha512-JDkf04mqtN3y4iAbO1hv9U2ARpPyPL1zqyWs/2WG1pgSq9llHFjStX5jdxb84himgJm+8Ng+x0oiWF/nw/XQKA==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.18.9.tgz", + "integrity": "sha512-aBXPT3bmtLryXaoJLyYPXPlSD4p1ld9aYeR+sJNOZjJJGiOpb+fKfh3NkcCu7J54nUJwCERPBExCCpyCOHnu/w==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz", - "integrity": "sha512-txyMCGroZ96i+Pxr3Je3lzEJjqwaRC9buMUgtomcrLe5Nd0+fk1h0LLA+ixUF5OW7AhHuQ7Es1WcQJZmZsz2XA==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz", + "integrity": "sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==", "dev": true, "dependencies": { - "@babel/types": "^7.17.0" + "@babel/types": "^7.18.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", - "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", "dev": true, "dependencies": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.18.6" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/helper-string-parser": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz", + "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", + "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", - "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.18.0.tgz", - "integrity": "sha512-AE+HMYhmlMIbho9nbvicHyxFwhrO+xhKB6AhRxzl8w46Yj0VXTZjEsAoBVC7rB2I0jzX+yWyVybnO08qkfx6kg==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.18.9.tgz", + "integrity": "sha512-Jf5a+rbrLoR4eNdUmnFu8cN5eNJT6qdTdOg5IHIzq87WwyRw9PwguLFOWYgktN/60IP4fgDUawJvs7PjQIzELQ==", "dev": true, "dependencies": { - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.18.0", - "@babel/types": "^7.18.0" + "@babel/template": "^7.18.6", + "@babel/traverse": "^7.18.9", + "@babel/types": "^7.18.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.17.12", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.17.12.tgz", - "integrity": "sha512-7yykMVF3hfZY2jsHZEEgLc+3x4o1O+fYyULu11GynEUQNwB6lua+IIQn1FiJxNucd5UlyJryrwsOh8PL9Sn8Qg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.16.7", + "@babel/helper-validator-identifier": "^7.18.6", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -383,13 +391,13 @@ "node_modules/@babel/highlight/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, "node_modules/@babel/highlight/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, "engines": { "node": ">=0.8.0" @@ -398,7 +406,7 @@ "node_modules/@babel/highlight/node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, "engines": { "node": ">=4" @@ -417,9 +425,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.0.tgz", - "integrity": "sha512-AqDccGC+m5O/iUStSJy3DGRIUFu7WbY/CppZYwrEUB4N0tZlnI8CSTsgL7v5fHVFmUbRv2sd+yy27o8Ydt4MGg==", + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.10.tgz", + "integrity": "sha512-TYk3OA0HKL6qNryUayb5UUEhM/rkOQozIBEA5ITXh5DWrSp0TlUQXMyZmnWxG/DizSWBeeQ0Zbc5z8UGaaqoeg==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -576,12 +584,12 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.17.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.17.12.tgz", - "integrity": "sha512-TYY0SXFiO31YXtNg3HtFwNJHjLsAyIIhAhNWkQ5whPPS7HWUFlg9z0Ta4qAQNjQbP1wsSt/oKkmZ/4/WWdMUpw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz", + "integrity": "sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.17.12" + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -591,9 +599,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.0.tgz", - "integrity": "sha512-YMQvx/6nKEaucl0MY56mwIG483xk8SDNdlUwb2Ts6FUpr7fm85DxEmsY18LXBNhcTz6tO6JwZV8w1W06v8UKeg==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.9.tgz", + "integrity": "sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==", "dependencies": { "regenerator-runtime": "^0.13.4" }, @@ -602,33 +610,33 @@ } }, "node_modules/@babel/template": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", - "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.16.7", - "@babel/parser": "^7.16.7", - "@babel/types": "^7.16.7" + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.0.tgz", - "integrity": "sha512-oNOO4vaoIQoGjDQ84LgtF/IAlxlyqL4TUuoQ7xLkQETFaHkY1F7yazhB4Kt3VcZGL0ZF/jhrEpnXqUb0M7V3sw==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.18.0", - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.17.9", - "@babel/helper-hoist-variables": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.18.0", - "@babel/types": "^7.18.0", + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.10.tgz", + "integrity": "sha512-J7ycxg0/K9XCtLyHf0cz2DqDihonJeIo+z+HEdRe9YuT8TY4A66i+Ab2/xZCEW7Ro60bPCBBfqqboHSamoV3+g==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.18.10", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -646,12 +654,13 @@ } }, "node_modules/@babel/types": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.0.tgz", - "integrity": "sha512-vhAmLPAiC8j9K2GnsnLPCIH5wCrPpYIVBCWRBFDCB7Y/BXLqi/O+1RSTTM2bsmg6U/551+FCf9PNPxjABmxHTw==", + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.10.tgz", + "integrity": "sha512-MJvnbEiiNkpjo+LknnmRrqbY1GPUUggjv+wQVjetM/AONoupqRALB7I6jGqNUAZsKcRIEu2J6FRFvsczljjsaQ==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.16.7", + "@babel/helper-string-parser": "^7.18.10", + "@babel/helper-validator-identifier": "^7.18.6", "to-fast-properties": "^2.0.0" }, "engines": { @@ -677,6 +686,23 @@ "jquery": ">= 1.7.x" } }, + "node_modules/@csstools/selector-specificity": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz", + "integrity": "sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==", + "dev": true, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2", + "postcss-selector-parser": "^6.0.10" + } + }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", @@ -685,16 +711,31 @@ "node": ">=10.0.0" } }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.14.53.tgz", + "integrity": "sha512-W2dAL6Bnyn4xa/QRSU3ilIK4EzD5wgYXKXJiS1HDF5vU3675qc2bvFyLwbUcdmssDveyndy7FbitrCoiV/eMLg==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@eslint/eslintrc": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.3.tgz", - "integrity": "sha512-uGo44hIwoLGNyduRpjdEpovcbMdd+Nv7amtmJxnKmI8xj6yd5LncmSwDa5NgX/41lIFJtkjD6YdVfgEzPfJ5UA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", + "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^9.3.2", - "globals": "^13.9.0", + "globals": "^13.15.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -705,24 +746,46 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "node_modules/@happy-dom/jest-environment": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@happy-dom/jest-environment/-/jest-environment-4.0.1.tgz", - "integrity": "sha512-G6hwPF+JlTr4vcJ7xrJYKYrpXPv3ceoGfVX2ZKX9AH7GRQz6Zeq1OWRpEsSezxnwd/bbzsNP6wLakVzWy6jCTQ==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@happy-dom/jest-environment/-/jest-environment-6.0.4.tgz", + "integrity": "sha512-3FEWODVN4H7Hnkbm7IEtRE8lU7uitxSsnVagkQbfjjwKSUfF6BT9MJ95VF7nLimdc5ctOIa7ZbDietRRIpgSHw==", "dev": true, "dependencies": { "@jest/environment": "^27.5.1", "@jest/fake-timers": "^27.5.1", "@jest/types": "^27.5.1", - "happy-dom": "^4.0.1", + "happy-dom": "^6.0.4", "jest-mock": "^27.5.1", "jest-util": "^27.5.1" } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", - "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz", + "integrity": "sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", @@ -733,6 +796,16 @@ "node": ">=10.10.0" } }, + "node_modules/@humanwhocodes/gitignore-to-minimatch": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", + "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", @@ -829,24 +902,6 @@ "node": ">=8" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", @@ -866,16 +921,16 @@ } }, "node_modules/@jest/console": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.0.tgz", - "integrity": "sha512-tscn3dlJFGay47kb4qVruQg/XWlmvU0xp3EJOjzzY+sBaI+YgwKcvAmTcyYU7xEiLLIY5HCdWRooAL8dqkFlDA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.3.tgz", + "integrity": "sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==", "dev": true, "dependencies": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^28.1.0", - "jest-util": "^28.1.0", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", "slash": "^3.0.0" }, "engines": { @@ -883,12 +938,12 @@ } }, "node_modules/@jest/console/node_modules/@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "dependencies": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -909,18 +964,18 @@ } }, "node_modules/@jest/console/node_modules/jest-message-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.0.tgz", - "integrity": "sha512-RpA8mpaJ/B2HphDMiDlrAZdDytkmwFqgjDZovM21F35lHGeUeCvYmm6W+sbQ0ydaLpg5bFAUuWG1cjqOl8vqrw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^28.1.0", + "pretty-format": "^28.1.3", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -929,12 +984,12 @@ } }, "node_modules/@jest/console/node_modules/jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "dependencies": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -946,37 +1001,37 @@ } }, "node_modules/@jest/core": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-28.1.0.tgz", - "integrity": "sha512-/2PTt0ywhjZ4NwNO4bUqD9IVJfmFVhVKGlhvSpmEfUCuxYf/3NHcKmRFI+I71lYzbTT3wMuYpETDCTHo81gC/g==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-28.1.3.tgz", + "integrity": "sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA==", "dev": true, "dependencies": { - "@jest/console": "^28.1.0", - "@jest/reporters": "^28.1.0", - "@jest/test-result": "^28.1.0", - "@jest/transform": "^28.1.0", - "@jest/types": "^28.1.0", + "@jest/console": "^28.1.3", + "@jest/reporters": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "ci-info": "^3.2.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", - "jest-changed-files": "^28.0.2", - "jest-config": "^28.1.0", - "jest-haste-map": "^28.1.0", - "jest-message-util": "^28.1.0", + "jest-changed-files": "^28.1.3", + "jest-config": "^28.1.3", + "jest-haste-map": "^28.1.3", + "jest-message-util": "^28.1.3", "jest-regex-util": "^28.0.2", - "jest-resolve": "^28.1.0", - "jest-resolve-dependencies": "^28.1.0", - "jest-runner": "^28.1.0", - "jest-runtime": "^28.1.0", - "jest-snapshot": "^28.1.0", - "jest-util": "^28.1.0", - "jest-validate": "^28.1.0", - "jest-watcher": "^28.1.0", + "jest-resolve": "^28.1.3", + "jest-resolve-dependencies": "^28.1.3", + "jest-runner": "^28.1.3", + "jest-runtime": "^28.1.3", + "jest-snapshot": "^28.1.3", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", + "jest-watcher": "^28.1.3", "micromatch": "^4.0.4", - "pretty-format": "^28.1.0", + "pretty-format": "^28.1.3", "rimraf": "^3.0.0", "slash": "^3.0.0", "strip-ansi": "^6.0.0" @@ -994,12 +1049,12 @@ } }, "node_modules/@jest/core/node_modules/@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "dependencies": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -1020,18 +1075,18 @@ } }, "node_modules/@jest/core/node_modules/jest-message-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.0.tgz", - "integrity": "sha512-RpA8mpaJ/B2HphDMiDlrAZdDytkmwFqgjDZovM21F35lHGeUeCvYmm6W+sbQ0ydaLpg5bFAUuWG1cjqOl8vqrw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^28.1.0", + "pretty-format": "^28.1.3", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -1040,12 +1095,12 @@ } }, "node_modules/@jest/core/node_modules/jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "dependencies": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -1072,22 +1127,22 @@ } }, "node_modules/@jest/expect": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-28.1.0.tgz", - "integrity": "sha512-be9ETznPLaHOmeJqzYNIXv1ADEzENuQonIoobzThOYPuK/6GhrWNIJDVTgBLCrz3Am73PyEU2urQClZp0hLTtA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-28.1.3.tgz", + "integrity": "sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw==", "dev": true, "dependencies": { - "expect": "^28.1.0", - "jest-snapshot": "^28.1.0" + "expect": "^28.1.3", + "jest-snapshot": "^28.1.3" }, "engines": { "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/@jest/expect-utils": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-28.1.0.tgz", - "integrity": "sha512-5BrG48dpC0sB80wpeIX5FU6kolDJI4K0n5BM9a5V38MGx0pyRvUBSS0u2aNTdDzmOrCjhOg8pGs6a20ivYkdmw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-28.1.3.tgz", + "integrity": "sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==", "dev": true, "dependencies": { "jest-get-type": "^28.0.2" @@ -1114,58 +1169,58 @@ } }, "node_modules/@jest/globals": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-28.1.0.tgz", - "integrity": "sha512-3m7sTg52OTQR6dPhsEQSxAvU+LOBbMivZBwOvKEZ+Rb+GyxVnXi9HKgOTYkx/S99T8yvh17U4tNNJPIEQmtwYw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-28.1.3.tgz", + "integrity": "sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA==", "dev": true, "dependencies": { - "@jest/environment": "^28.1.0", - "@jest/expect": "^28.1.0", - "@jest/types": "^28.1.0" + "@jest/environment": "^28.1.3", + "@jest/expect": "^28.1.3", + "@jest/types": "^28.1.3" }, "engines": { "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/@jest/globals/node_modules/@jest/environment": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.0.tgz", - "integrity": "sha512-S44WGSxkRngzHslhV6RoAExekfF7Qhwa6R5+IYFa81mpcj0YgdBnRSmvHe3SNwOt64yXaE5GG8Y2xM28ii5ssA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", + "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", "dev": true, "dependencies": { - "@jest/fake-timers": "^28.1.0", - "@jest/types": "^28.1.0", + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", - "jest-mock": "^28.1.0" + "jest-mock": "^28.1.3" }, "engines": { "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/@jest/globals/node_modules/@jest/fake-timers": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.0.tgz", - "integrity": "sha512-Xqsf/6VLeAAq78+GNPzI7FZQRf5cCHj1qgQxCjws9n8rKw8r1UYoeaALwBvyuzOkpU3c1I6emeMySPa96rxtIg==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", + "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", "dev": true, "dependencies": { - "@jest/types": "^28.1.0", - "@sinonjs/fake-timers": "^9.1.1", + "@jest/types": "^28.1.3", + "@sinonjs/fake-timers": "^9.1.2", "@types/node": "*", - "jest-message-util": "^28.1.0", - "jest-mock": "^28.1.0", - "jest-util": "^28.1.0" + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" }, "engines": { "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/@jest/globals/node_modules/@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "dependencies": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -1195,18 +1250,18 @@ } }, "node_modules/@jest/globals/node_modules/jest-message-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.0.tgz", - "integrity": "sha512-RpA8mpaJ/B2HphDMiDlrAZdDytkmwFqgjDZovM21F35lHGeUeCvYmm6W+sbQ0ydaLpg5bFAUuWG1cjqOl8vqrw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^28.1.0", + "pretty-format": "^28.1.3", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -1215,12 +1270,12 @@ } }, "node_modules/@jest/globals/node_modules/jest-mock": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.0.tgz", - "integrity": "sha512-H7BrhggNn77WhdL7O1apG0Q/iwl0Bdd5E1ydhCJzL3oBLh/UYxAwR3EJLsBZ9XA3ZU4PA3UNw4tQjduBTCTmLw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", + "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", "dev": true, "dependencies": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*" }, "engines": { @@ -1228,12 +1283,12 @@ } }, "node_modules/@jest/globals/node_modules/jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "dependencies": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -1245,17 +1300,17 @@ } }, "node_modules/@jest/reporters": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-28.1.0.tgz", - "integrity": "sha512-qxbFfqap/5QlSpIizH9c/bFCDKsQlM4uAKSOvZrP+nIdrjqre3FmKzpTtYyhsaVcOSNK7TTt2kjm+4BJIjysFA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-28.1.3.tgz", + "integrity": "sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg==", "dev": true, "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^28.1.0", - "@jest/test-result": "^28.1.0", - "@jest/transform": "^28.1.0", - "@jest/types": "^28.1.0", - "@jridgewell/trace-mapping": "^0.3.7", + "@jest/console": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", + "@jridgewell/trace-mapping": "^0.3.13", "@types/node": "*", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", @@ -1267,13 +1322,14 @@ "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.1.3", - "jest-util": "^28.1.0", - "jest-worker": "^28.1.0", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", + "jest-worker": "^28.1.3", "slash": "^3.0.0", "string-length": "^4.0.1", "strip-ansi": "^6.0.0", "terminal-link": "^2.0.0", - "v8-to-istanbul": "^9.0.0" + "v8-to-istanbul": "^9.0.1" }, "engines": { "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" @@ -1288,12 +1344,12 @@ } }, "node_modules/@jest/reporters/node_modules/@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "dependencies": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -1313,13 +1369,33 @@ "@types/yargs-parser": "*" } }, + "node_modules/@jest/reporters/node_modules/jest-message-util": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^28.1.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^28.1.3", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, "node_modules/@jest/reporters/node_modules/jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "dependencies": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -1331,24 +1407,24 @@ } }, "node_modules/@jest/schemas": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.0.2.tgz", - "integrity": "sha512-YVDJZjd4izeTDkij00vHHAymNXQ6WWsdChFRK86qck6Jpr3DCL5W3Is3vslviRlP+bLuMYRLbdp98amMvqudhA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz", + "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==", "dev": true, "dependencies": { - "@sinclair/typebox": "^0.23.3" + "@sinclair/typebox": "^0.24.1" }, "engines": { "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/@jest/source-map": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-28.0.2.tgz", - "integrity": "sha512-Y9dxC8ZpN3kImkk0LkK5XCEneYMAXlZ8m5bflmSL5vrwyeUpJfentacCUg6fOb8NOpOO7hz2+l37MV77T6BFPw==", + "version": "28.1.2", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-28.1.2.tgz", + "integrity": "sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww==", "dev": true, "dependencies": { - "@jridgewell/trace-mapping": "^0.3.7", + "@jridgewell/trace-mapping": "^0.3.13", "callsites": "^3.0.0", "graceful-fs": "^4.2.9" }, @@ -1357,13 +1433,13 @@ } }, "node_modules/@jest/test-result": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.0.tgz", - "integrity": "sha512-sBBFIyoPzrZho3N+80P35A5oAkSKlGfsEFfXFWuPGBsW40UAjCkGakZhn4UQK4iQlW2vgCDMRDOob9FGKV8YoQ==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.3.tgz", + "integrity": "sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==", "dev": true, "dependencies": { - "@jest/console": "^28.1.0", - "@jest/types": "^28.1.0", + "@jest/console": "^28.1.3", + "@jest/types": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -1372,12 +1448,12 @@ } }, "node_modules/@jest/test-result/node_modules/@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "dependencies": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -1398,14 +1474,14 @@ } }, "node_modules/@jest/test-sequencer": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-28.1.0.tgz", - "integrity": "sha512-tZCEiVWlWNTs/2iK9yi6o3AlMfbbYgV4uuZInSVdzZ7ftpHZhCMuhvk2HLYhCZzLgPFQ9MnM1YaxMnh3TILFiQ==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-28.1.3.tgz", + "integrity": "sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw==", "dev": true, "dependencies": { - "@jest/test-result": "^28.1.0", + "@jest/test-result": "^28.1.3", "graceful-fs": "^4.2.9", - "jest-haste-map": "^28.1.0", + "jest-haste-map": "^28.1.3", "slash": "^3.0.0" }, "engines": { @@ -1413,22 +1489,22 @@ } }, "node_modules/@jest/transform": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-28.1.0.tgz", - "integrity": "sha512-omy2xe5WxlAfqmsTjTPxw+iXRTRnf+NtX0ToG+4S0tABeb4KsKmPUHq5UBuwunHg3tJRwgEQhEp0M/8oiatLEA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-28.1.3.tgz", + "integrity": "sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", - "@jest/types": "^28.1.0", - "@jridgewell/trace-mapping": "^0.3.7", + "@jest/types": "^28.1.3", + "@jridgewell/trace-mapping": "^0.3.13", "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^28.1.0", + "jest-haste-map": "^28.1.3", "jest-regex-util": "^28.0.2", - "jest-util": "^28.1.0", + "jest-util": "^28.1.3", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", @@ -1439,12 +1515,12 @@ } }, "node_modules/@jest/transform/node_modules/@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "dependencies": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -1465,12 +1541,12 @@ } }, "node_modules/@jest/transform/node_modules/jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "dependencies": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -1511,34 +1587,52 @@ } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz", - "integrity": "sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA==", - "dev": true, + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/set-array": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.1.tgz", - "integrity": "sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==", - "dev": true, + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", + "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.13", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz", - "integrity": "sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==", - "dev": true + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz", - "integrity": "sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w==", - "dev": true, + "version": "0.3.14", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz", + "integrity": "sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ==", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -1600,10 +1694,19 @@ "node": ">= 8" } }, + "node_modules/@popperjs/core": { + "version": "2.11.5", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.5.tgz", + "integrity": "sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, "node_modules/@primer/octicons": { - "version": "17.2.0", - "resolved": "https://registry.npmjs.org/@primer/octicons/-/octicons-17.2.0.tgz", - "integrity": "sha512-A3YetVbJX5J4JGa2AfVrEl1lE3FtT+7HdSzphFRs1QF5OgsUpkNbyjvVxeCxVZaG6zXYbbbPWsPF06PtsIyUWQ==", + "version": "17.4.0", + "resolved": "https://registry.npmjs.org/@primer/octicons/-/octicons-17.4.0.tgz", + "integrity": "sha512-fRD9A/JszKOe5mDIU+g1b8jvcPj/qzusxdxnrIrg8Db0mLHsbGc4xNMUtHbRmgFOKaF6/QBR+WnWGQxv4yTcBg==", "dependencies": { "object-assign": "^4.1.1" } @@ -1646,12 +1749,6 @@ "rollup": "^1.20.0||^2.0.0" } }, - "node_modules/@rollup/pluginutils/node_modules/@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", - "dev": true - }, "node_modules/@rollup/pluginutils/node_modules/estree-walker": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", @@ -1659,9 +1756,9 @@ "dev": true }, "node_modules/@sinclair/typebox": { - "version": "0.23.5", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.23.5.tgz", - "integrity": "sha512-AFBVi/iT4g20DHoujvMH1aEDn8fGJh4xsRGCP6d8RpLPMqsNPvW01Jcn0QysXTsg++/xj25NmJsGyH9xug/wKg==", + "version": "0.24.26", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.26.tgz", + "integrity": "sha512-1ZVIyyS1NXDRVT8GjWD5jULjhDyM3IsIHef2VGUMdnWOlX2tkPjyEX/7K0TGSH2S8EaPhp1ylFdjSjUGQ+gecg==", "dev": true }, "node_modules/@sinonjs/commons": { @@ -1682,6 +1779,22 @@ "@sinonjs/commons": "^1.7.0" } }, + "node_modules/@stoplight/better-ajv-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stoplight/better-ajv-errors/-/better-ajv-errors-1.0.1.tgz", + "integrity": "sha512-rgxT+ZMeZbYRiOLNk6Oy6e/Ig1iQKo0IL8v/Y9E/0FewzgtkGs/p5dMeUpIFZXWj3RZaEPmfL9yh0oUEmNXZjg==", + "dev": true, + "dependencies": { + "jsonpointer": "^5.0.0", + "leven": "^3.1.0" + }, + "engines": { + "node": "^12.20 || >= 14.13" + }, + "peerDependencies": { + "ajv": ">=8" + } + }, "node_modules/@stoplight/json": { "version": "3.17.0", "resolved": "https://registry.npmjs.org/@stoplight/json/-/json-3.17.0.tgz", @@ -1770,9 +1883,9 @@ } }, "node_modules/@stoplight/spectral-cli": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-cli/-/spectral-cli-6.4.1.tgz", - "integrity": "sha512-l5nWXy/6YEyk51VVrOurhupVScIqfK0ra8yIRSli+gnW5Kf5Nfw5PLci5GceQGaM5WE+wmqZ/iY95yOVFwHc+A==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-cli/-/spectral-cli-6.5.0.tgz", + "integrity": "sha512-BmTnQkkhG6E301ADUX7dhQtIIUT/WVRszRHy+90M5Bxk+4kod/6Gi8w7sWuQ5myDls3mLEMjYWUOKaUALuPvug==", "dev": true, "dependencies": { "@rollup/plugin-commonjs": "^20.0.0", @@ -1834,37 +1947,10 @@ "node": ">= 6" } }, - "node_modules/@stoplight/spectral-cli/node_modules/yargs": { - "version": "17.3.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.3.1.tgz", - "integrity": "sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA==", - "dev": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@stoplight/spectral-cli/node_modules/yargs-parser": { - "version": "21.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", - "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", - "dev": true, - "engines": { - "node": ">=12" - } - }, "node_modules/@stoplight/spectral-core": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-core/-/spectral-core-1.12.3.tgz", - "integrity": "sha512-+PhVzTD8q6kUZw4BcbM+ibVaH5/ELryKt5tlLitA8SJIaJ+5/9ZKaGN0AV3ExZQZGYvXwucPOQuJKYZYKA6mWg==", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-core/-/spectral-core-1.13.0.tgz", + "integrity": "sha512-h++UIhdYK6bCZYHCK8byeyOq2tgAUbXdwdR3+Wy1O3PrJERdA9fyL0I3KQ595HylZRo7z1PUoSeyY6FMypWTBQ==", "dev": true, "dependencies": { "@stoplight/better-ajv-errors": "1.0.1", @@ -1875,11 +1961,13 @@ "@stoplight/spectral-ref-resolver": "^1.0.0", "@stoplight/spectral-runtime": "^1.0.0", "@stoplight/types": "~13.2.0", + "@types/es-aggregate-error": "^1.0.2", "@types/json-schema": "^7.0.11", "ajv": "^8.6.0", "ajv-errors": "~3.0.0", "ajv-formats": "~2.1.0", "blueimp-md5": "2.18.0", + "es-aggregate-error": "^1.0.7", "jsonpath-plus": "6.0.1", "lodash": "~4.17.21", "lodash.topath": "^4.5.2", @@ -1893,22 +1981,6 @@ "node": "^12.20 || >= 14.13" } }, - "node_modules/@stoplight/spectral-core/node_modules/@stoplight/better-ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@stoplight/better-ajv-errors/-/better-ajv-errors-1.0.1.tgz", - "integrity": "sha512-rgxT+ZMeZbYRiOLNk6Oy6e/Ig1iQKo0IL8v/Y9E/0FewzgtkGs/p5dMeUpIFZXWj3RZaEPmfL9yh0oUEmNXZjg==", - "dev": true, - "dependencies": { - "jsonpointer": "^5.0.0", - "leven": "^3.1.0" - }, - "engines": { - "node": "^12.20 || >= 14.13" - }, - "peerDependencies": { - "ajv": ">=8" - } - }, "node_modules/@stoplight/spectral-core/node_modules/@stoplight/json": { "version": "3.18.1", "resolved": "https://registry.npmjs.org/@stoplight/json/-/json-3.18.1.tgz", @@ -1938,37 +2010,6 @@ "node": "^12.20 || >=14.13" } }, - "node_modules/@stoplight/spectral-core/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@stoplight/spectral-core/node_modules/ajv-errors": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-3.0.0.tgz", - "integrity": "sha512-V3wD15YHfHz6y0KdhYFjyy9vWtEVALT9UrxfN3zqlI6dMioHnJrqOYfyPKol3oqrnCM9uwkcdCwkJ0WUcbLMTQ==", - "dev": true, - "peerDependencies": { - "ajv": "^8.0.1" - } - }, - "node_modules/@stoplight/spectral-core/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, "node_modules/@stoplight/spectral-formats": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@stoplight/spectral-formats/-/spectral-formats-1.2.0.tgz", @@ -1985,9 +2026,9 @@ } }, "node_modules/@stoplight/spectral-functions": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-functions/-/spectral-functions-1.6.1.tgz", - "integrity": "sha512-f4cFtbI35bQtY0t4fYhKtS+/nMU3UsAeFlqm4tARGGG5WjOv4ieCFNFbgodKNiO3F4O+syMEjVQuXlBNPuY7jw==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-functions/-/spectral-functions-1.7.0.tgz", + "integrity": "sha512-ya3ovvH17QqHeL1o41rEXISJIUegb763Y8yWI01VaLj4zehKOjLzVNKIp1PsUNkG88M5fwB8Lrvjzcd3M8O3iw==", "dev": true, "dependencies": { "@stoplight/better-ajv-errors": "1.0.1", @@ -2007,22 +2048,6 @@ "node": ">=12" } }, - "node_modules/@stoplight/spectral-functions/node_modules/@stoplight/better-ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@stoplight/better-ajv-errors/-/better-ajv-errors-1.0.1.tgz", - "integrity": "sha512-rgxT+ZMeZbYRiOLNk6Oy6e/Ig1iQKo0IL8v/Y9E/0FewzgtkGs/p5dMeUpIFZXWj3RZaEPmfL9yh0oUEmNXZjg==", - "dev": true, - "dependencies": { - "jsonpointer": "^5.0.0", - "leven": "^3.1.0" - }, - "engines": { - "node": "^12.20 || >= 14.13" - }, - "peerDependencies": { - "ajv": ">=8" - } - }, "node_modules/@stoplight/spectral-functions/node_modules/@stoplight/json": { "version": "3.17.2", "resolved": "https://registry.npmjs.org/@stoplight/json/-/json-3.17.2.tgz", @@ -2039,70 +2064,25 @@ "node": ">=8.3.0" } }, - "node_modules/@stoplight/spectral-functions/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "node_modules/@stoplight/spectral-parsers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-parsers/-/spectral-parsers-1.0.1.tgz", + "integrity": "sha512-JGKlrTxhjUzIGo2FOCf8Qp0WKTWXedoRNPovqYPE8pAp08epqU8DzHwl/i46BGH5yfTmouKMZgBN/PV2+Cr5jw==", "dev": true, "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "@stoplight/json": "3.17.0", + "@stoplight/types": "12.3.0", + "@stoplight/yaml": "4.2.2", + "tslib": "^2.3.1" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "engines": { + "node": ">=12" } }, - "node_modules/@stoplight/spectral-functions/node_modules/ajv-draft-04": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", - "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", - "dev": true, - "peerDependencies": { - "ajv": "^8.5.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/@stoplight/spectral-functions/node_modules/ajv-errors": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-3.0.0.tgz", - "integrity": "sha512-V3wD15YHfHz6y0KdhYFjyy9vWtEVALT9UrxfN3zqlI6dMioHnJrqOYfyPKol3oqrnCM9uwkcdCwkJ0WUcbLMTQ==", - "dev": true, - "peerDependencies": { - "ajv": "^8.0.1" - } - }, - "node_modules/@stoplight/spectral-functions/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/@stoplight/spectral-parsers": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-parsers/-/spectral-parsers-1.0.1.tgz", - "integrity": "sha512-JGKlrTxhjUzIGo2FOCf8Qp0WKTWXedoRNPovqYPE8pAp08epqU8DzHwl/i46BGH5yfTmouKMZgBN/PV2+Cr5jw==", - "dev": true, - "dependencies": { - "@stoplight/json": "3.17.0", - "@stoplight/types": "12.3.0", - "@stoplight/yaml": "4.2.2", - "tslib": "^2.3.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@stoplight/spectral-ref-resolver": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-ref-resolver/-/spectral-ref-resolver-1.0.1.tgz", - "integrity": "sha512-0tY7nTOccvTsa3c4QbSWfJ8wGfPO1RXvmKnmBjuyLfoTMNuhkHPII9gKhCjygsshzsBLxs2IyRHZYhWYVnEbCA==", + "node_modules/@stoplight/spectral-ref-resolver": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-ref-resolver/-/spectral-ref-resolver-1.0.1.tgz", + "integrity": "sha512-0tY7nTOccvTsa3c4QbSWfJ8wGfPO1RXvmKnmBjuyLfoTMNuhkHPII9gKhCjygsshzsBLxs2IyRHZYhWYVnEbCA==", "dev": true, "dependencies": { "@stoplight/json-ref-readers": "1.2.2", @@ -2116,12 +2096,12 @@ } }, "node_modules/@stoplight/spectral-ruleset-bundler": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-ruleset-bundler/-/spectral-ruleset-bundler-1.3.0.tgz", - "integrity": "sha512-6Tif7GQL18F0LN1+FhEmhFWgE/TiWudb/pFl4DC7oS1QRoutB7QJPqIfVFSmteToPidxlrIbC6VAXSyEhlpDVQ==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-ruleset-bundler/-/spectral-ruleset-bundler-1.3.1.tgz", + "integrity": "sha512-TWjLFYBor1s/0v3xXwdVzzyUVu7ez2vYVNN4RMbJG7HIZgYW8MMVx4AVg5Eo1ZgLTkj/aeaoAOjIP7t+u6IBUg==", "dev": true, "dependencies": { - "@rollup/plugin-commonjs": "^21.0.1", + "@rollup/plugin-commonjs": "~22.0.0", "@stoplight/path": "1.3.2", "@stoplight/spectral-core": ">=1", "@stoplight/spectral-formats": ">=1", @@ -2134,7 +2114,7 @@ "@stoplight/types": "^12.3.0", "@types/node": "*", "pony-cause": "1.1.1", - "rollup": "~2.67.0", + "rollup": "~2.75.5", "tslib": "^2.3.1", "validate-npm-package-name": "3.0.0" }, @@ -2143,9 +2123,9 @@ } }, "node_modules/@stoplight/spectral-ruleset-bundler/node_modules/@rollup/plugin-commonjs": { - "version": "21.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-21.1.0.tgz", - "integrity": "sha512-6ZtHx3VHIp2ReNNDxHjuUml6ur+WcQ28N1yHgCQwsbNkQg2suhxGMDQGJOn/KuDxKtd1xuZP5xSTwBA4GQ8hbA==", + "version": "22.0.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-22.0.1.tgz", + "integrity": "sha512-dGfEZvdjDHObBiP5IvwTKMVeq/tBZGMBHZFMdIV1ClMM/YoWS34xrHFGfag9SN2ZtMgNZRFruqvxZQEa70O6nQ==", "dev": true, "dependencies": { "@rollup/pluginutils": "^3.1.0", @@ -2157,16 +2137,16 @@ "resolve": "^1.17.0" }, "engines": { - "node": ">= 8.0.0" + "node": ">= 12.0.0" }, "peerDependencies": { - "rollup": "^2.38.3" + "rollup": "^2.68.0" } }, "node_modules/@stoplight/spectral-ruleset-bundler/node_modules/rollup": { - "version": "2.67.3", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.67.3.tgz", - "integrity": "sha512-G/x1vUwbGtP6O5ZM8/sWr8+p7YfZhI18pPqMRtMYMWSbHjKZ/ajHGiM+GWNTlWyOR0EHIdT8LHU+Z4ciIZ1oBw==", + "version": "2.75.7", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.75.7.tgz", + "integrity": "sha512-VSE1iy0eaAYNCxEXaleThdFXqZJ42qDBatAwrfnPlENEZ8erQ+0LYX4JXOLPceWfZpV1VtZwZ3dFCuOZiSyFtQ==", "dev": true, "bin": { "rollup": "dist/bin/rollup" @@ -2212,32 +2192,10 @@ "node": ">=8" } }, - "node_modules/@stoplight/spectral-ruleset-migrator/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@stoplight/spectral-ruleset-migrator/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, "node_modules/@stoplight/spectral-rulesets": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-rulesets/-/spectral-rulesets-1.11.0.tgz", - "integrity": "sha512-0zFbxIuoWmGrkl2txOuaEDF8o6aoKDpMAYOG2oDfmmX9FhXX3c3ivIy80hyb2tMKkIYuqqx/zwIiOuww5S8iUA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-rulesets/-/spectral-rulesets-1.11.1.tgz", + "integrity": "sha512-0MDr5MW000FIZ3C47YY2Cg4NzU6wJFvvpSl1QRijRzdAVqQ1DgD3FgRDKHTA6OO7BmgWdCQYKSI8KwOH1Ju3kw==", "dev": true, "dependencies": { "@asyncapi/specs": "^2.14.0", @@ -2259,22 +2217,6 @@ "node": ">=12" } }, - "node_modules/@stoplight/spectral-rulesets/node_modules/@stoplight/better-ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@stoplight/better-ajv-errors/-/better-ajv-errors-1.0.1.tgz", - "integrity": "sha512-rgxT+ZMeZbYRiOLNk6Oy6e/Ig1iQKo0IL8v/Y9E/0FewzgtkGs/p5dMeUpIFZXWj3RZaEPmfL9yh0oUEmNXZjg==", - "dev": true, - "dependencies": { - "jsonpointer": "^5.0.0", - "leven": "^3.1.0" - }, - "engines": { - "node": "^12.20 || >= 14.13" - }, - "peerDependencies": { - "ajv": ">=8" - } - }, "node_modules/@stoplight/spectral-rulesets/node_modules/@stoplight/types": { "version": "12.5.0", "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-12.5.0.tgz", @@ -2288,28 +2230,6 @@ "node": ">=8" } }, - "node_modules/@stoplight/spectral-rulesets/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@stoplight/spectral-rulesets/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, "node_modules/@stoplight/spectral-runtime": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@stoplight/spectral-runtime/-/spectral-runtime-1.1.2.tgz", @@ -2443,28 +2363,37 @@ "@types/node": "*" } }, + "node_modules/@types/es-aggregate-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/es-aggregate-error/-/es-aggregate-error-1.0.2.tgz", + "integrity": "sha512-erqUpFXksaeR2kejKnhnjZjbFxUpGZx4Z7ydNL9ie8tEhXPiZTsLeUDJ6aR1F8j5wWUAtOAQWUqkc7givBJbBA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/eslint": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.2.tgz", - "integrity": "sha512-Z1nseZON+GEnFjJc04sv4NSALGjhFwy6K0HXt7qsn5ArfAKtb63dXNJHf+1YW6IpOIYRBGUbu3GwJdj8DGnCjA==", + "version": "8.4.5", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.5.tgz", + "integrity": "sha512-dhsC09y1gpJWnK+Ff4SGvCuSnk9DaU0BJZSzOwa6GVSg65XtTugLBITDAAzRU5duGBoXBHpdR/9jHGxJjNflJQ==", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" } }, "node_modules/@types/eslint-scope": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.3.tgz", - "integrity": "sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g==", + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", + "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", "dependencies": { "@types/eslint": "*", "@types/estree": "*" } }, "node_modules/@types/estree": { - "version": "0.0.51", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", - "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==" + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" }, "node_modules/@types/form-data": { "version": "0.0.33", @@ -2531,9 +2460,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "17.0.35", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.35.tgz", - "integrity": "sha512-vu1SrqBjbbZ3J6vwY17jBs8Sr/BKA+/a/WtjRG+whKg1iuLFOosq872EXS0eXWILdO36DHQQeku/ZcL6hz2fpg==" + "version": "18.6.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.6.3.tgz", + "integrity": "sha512-6qKpDtoaYLM+5+AFChLhHermMQxc3TOEFIDzrZLPRGHPrLEwqFkkT5Kx3ju05g6X7uDPazz3jHbKPX0KzCjntg==" }, "node_modules/@types/normalize-package-data": { "version": "2.4.1", @@ -2548,9 +2477,9 @@ "dev": true }, "node_modules/@types/prettier": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.1.tgz", - "integrity": "sha512-XFjFHmaLVifrAKaZ+EKghFHtHSUonyw8P2Qmy2/+osBnrKbH9UYtlK10zg8/kCt47MFilll/DEDKy3DHfJ0URw==", + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.4.tgz", + "integrity": "sha512-fOwvpvQYStpb/zHMx0Cauwywu9yLDmzWiiQBC7gJyq5tYLUXFZvDG7VK1B7WBxxjBJNKFOZ0zLoOQn8vmATbhw==", "dev": true }, "node_modules/@types/qs": { @@ -2645,7 +2574,7 @@ "node_modules/@vue/component-compiler-utils/node_modules/yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" }, "node_modules/@webassemblyjs/ast": { "version": "1.11.1", @@ -2779,18 +2708,18 @@ } }, "node_modules/@webpack-cli/configtest": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.1.1.tgz", - "integrity": "sha512-1FBc1f9G4P/AxMqIgfZgeOTuRnwZMten8E7zap5zgpPInnCrP8D4Q81+4CWIch8i/Nf7nXjP0v6CjjbHOrXhKg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz", + "integrity": "sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==", "peerDependencies": { "webpack": "4.x.x || 5.x.x", "webpack-cli": "4.x.x" } }, "node_modules/@webpack-cli/info": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.4.1.tgz", - "integrity": "sha512-PKVGmazEq3oAo46Q63tpMr4HipI3OPfP7LiNOEJg963RMgT0rqheag28NCML0o3GIzA3DmxP1ZIAv9oTX1CUIA==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.5.0.tgz", + "integrity": "sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==", "dependencies": { "envinfo": "^7.7.3" }, @@ -2799,9 +2728,9 @@ } }, "node_modules/@webpack-cli/serve": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.6.1.tgz", - "integrity": "sha512-gNGTiTrjEVQ0OcVnzsRSqTxaBSr+dmTfm+qJsCDluky8uhdLWep7Gcr62QsAKHTMxjCS/8nEITsmFAhfIx+QSw==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz", + "integrity": "sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==", "peerDependencies": { "webpack-cli": "4.x.x" }, @@ -2834,9 +2763,9 @@ } }, "node_modules/acorn": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", "bin": { "acorn": "bin/acorn" }, @@ -2897,13 +2826,13 @@ } }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", "dependencies": { "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", "uri-js": "^4.2.2" }, "funding": { @@ -2911,6 +2840,29 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ajv-draft-04": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", + "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", + "dev": true, + "peerDependencies": { + "ajv": "^8.5.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-errors": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-3.0.0.tgz", + "integrity": "sha512-V3wD15YHfHz6y0KdhYFjyy9vWtEVALT9UrxfN3zqlI6dMioHnJrqOYfyPKol3oqrnCM9uwkcdCwkJ0WUcbLMTQ==", + "dev": true, + "peerDependencies": { + "ajv": "^8.0.1" + } + }, "node_modules/ajv-formats": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", @@ -2927,32 +2879,15 @@ } } }, - "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "fast-deep-equal": "^3.1.3" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "peerDependencies": { - "ajv": "^6.9.1" + "ajv": "^8.8.2" } }, "node_modules/ansi-escapes": { @@ -3138,15 +3073,15 @@ "dev": true }, "node_modules/babel-jest": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.0.tgz", - "integrity": "sha512-zNKk0yhDZ6QUwfxh9k07GII6siNGMJWVUU49gmFj5gfdqDKLqa2RArXOF2CODp4Dr7dLxN2cvAV+667dGJ4b4w==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.3.tgz", + "integrity": "sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q==", "dev": true, "dependencies": { - "@jest/transform": "^28.1.0", + "@jest/transform": "^28.1.3", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^28.0.2", + "babel-preset-jest": "^28.1.3", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "slash": "^3.0.0" @@ -3175,9 +3110,9 @@ } }, "node_modules/babel-plugin-jest-hoist": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.0.2.tgz", - "integrity": "sha512-Kizhn/ZL+68ZQHxSnHyuvJv8IchXD62KQxV77TBDV/xoBFBOfgRAk97GNs6hXdTTCiVES9nB2I6+7MXXrk5llQ==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz", + "integrity": "sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q==", "dev": true, "dependencies": { "@babel/template": "^7.3.3", @@ -3213,12 +3148,12 @@ } }, "node_modules/babel-preset-jest": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-28.0.2.tgz", - "integrity": "sha512-sYzXIdgIXXroJTFeB3S6sNDWtlJ2dllCdTEsnZ65ACrMojj3hVNFRmnJ1HZtomGi+Be7aqpY/HJ92fr8OhKVkQ==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz", + "integrity": "sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A==", "dev": true, "dependencies": { - "babel-plugin-jest-hoist": "^28.0.2", + "babel-plugin-jest-hoist": "^28.1.3", "babel-preset-current-node-syntax": "^1.0.0" }, "engines": { @@ -3279,9 +3214,9 @@ } }, "node_modules/browserslist": { - "version": "4.20.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.3.tgz", - "integrity": "sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz", + "integrity": "sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==", "funding": [ { "type": "opencollective", @@ -3293,11 +3228,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001332", - "electron-to-chromium": "^1.4.118", - "escalade": "^3.1.1", - "node-releases": "^2.0.3", - "picocolors": "^1.0.0" + "caniuse-lite": "^1.0.30001370", + "electron-to-chromium": "^1.4.202", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.5" }, "bin": { "browserslist": "cli.js" @@ -3396,9 +3330,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001341", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001341.tgz", - "integrity": "sha512-2SodVrFFtvGENGCv0ChVJIDQ0KPaS1cg7/qtfMaICgeMolDdo/Z2OD32F0Aq9yl6F4YFwGPBS5AaPqNYiW4PoA==", + "version": "1.0.30001373", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001373.tgz", + "integrity": "sha512-pJYArGHrPp3TUqQzFYRmP/lwJlj8RCbVe3Gd3eJQkAV8SAC6b19XS9BjMvRdvaS8RMkaTN8ZhoHP6S1y8zzwEQ==", "funding": [ { "type": "opencollective", @@ -3450,9 +3384,9 @@ } }, "node_modules/ci-info": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.1.tgz", - "integrity": "sha512-SXgeMX9VwDe7iFFaEWkA5AstuER9YKqy4EhHqr4DVqkwmD9rpVimkMKWHdjn30Ja45txyjhSn63lVX69eVCckg==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.2.tgz", + "integrity": "sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg==", "dev": true }, "node_modules/cjs-module-lexer": { @@ -3476,7 +3410,7 @@ "node_modules/clean-regexp/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, "engines": { "node": ">=0.8.0" @@ -3549,7 +3483,7 @@ "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "dev": true, "engines": { "iojs": ">= 1.0.0", @@ -3557,14 +3491,14 @@ } }, "node_modules/codemirror": { - "version": "5.65.4", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.4.tgz", - "integrity": "sha512-tytrSm5Rh52b6j36cbDXN+FHwHCl9aroY4BrDZB2NFFL3Wjfq9nuYVLFFhaOYOczKAg3JXTr8BuT8LcE5QY4Iw==" + "version": "5.65.7", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.7.tgz", + "integrity": "sha512-zb67cXzgugIQmb6tfD4G11ILjYoMfTjwcjn+cWsa4GewlI2adhR/h3kolkoCQTm1msD/1BuqVTKuO09ELsS++A==" }, "node_modules/codemirror-spell-checker": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/codemirror-spell-checker/-/codemirror-spell-checker-1.1.2.tgz", - "integrity": "sha1-HGYPkIlIPMtRE7m6nKGcP0mTNx4=", + "integrity": "sha512-2Tl6n0v+GJRsC9K3MLCdLaMOmvWL0uukajNJseorZJsslaxZyZMgENocPU8R0DyoTAiKsyqiemSOZo7kjGV0LQ==", "dependencies": { "typo-js": "*" } @@ -3598,9 +3532,9 @@ "dev": true }, "node_modules/colorette": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", - "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==" + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==" }, "node_modules/combined-stream": { "version": "1.0.8", @@ -3615,11 +3549,12 @@ } }, "node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.0.tgz", + "integrity": "sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw==", + "dev": true, "engines": { - "node": ">= 10" + "node": "^12.20.0 || >=14" } }, "node_modules/commondir": { @@ -3631,7 +3566,7 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "node_modules/concat-stream": { "version": "1.6.2", @@ -3648,6 +3583,36 @@ "typedarray": "^0.0.6" } }, + "node_modules/concat-stream/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/concat-stream/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/concat-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/consolidate": { "version": "0.15.1", "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.15.1.tgz", @@ -3715,9 +3680,9 @@ } }, "node_modules/css-functions-list": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.0.1.tgz", - "integrity": "sha512-PriDuifDt4u4rkDgnqRCLnjfMatufLmWNfQnGCq34xZwpY3oabwhB9SqRBmuvWUgndbemCFlKqg+nO7C2q0SBw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.1.0.tgz", + "integrity": "sha512-/9lCvYZaUbBGvYUgYGFJ4dcYiyqdhSjG7IPVluoV8A1ILjkF7ilmhp1OGUz8n+nmBcu0RNrQAzgD8B6FJbrt2w==", "dev": true, "engines": { "node": ">=12.22" @@ -3792,7 +3757,7 @@ "node_modules/css.escape": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", - "integrity": "sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s=", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", "dev": true }, "node_modules/cssesc": { @@ -3819,16 +3784,16 @@ } }, "node_modules/d3": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/d3/-/d3-7.4.4.tgz", - "integrity": "sha512-97FE+MYdAlV3R9P74+R3Uar7wUKkIFu89UWMjEaDhiJ9VxKvqaMxauImy8PC2DdBkdM2BxJOIoLxPrcZUyrKoQ==", + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/d3/-/d3-7.6.1.tgz", + "integrity": "sha512-txMTdIHFbcpLx+8a0IFhZsbp+PfBBPt8yfbmukZTQFroKuFqIwqswF0qE5JXWefylaAVpSXFoKm3yP+jpNLFLw==", "dependencies": { "d3-array": "3", "d3-axis": "3", "d3-brush": "3", "d3-chord": "3", "d3-color": "3", - "d3-contour": "3", + "d3-contour": "4", "d3-delaunay": "6", "d3-dispatch": "3", "d3-drag": "3", @@ -3859,9 +3824,9 @@ } }, "node_modules/d3-array": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.1.6.tgz", - "integrity": "sha512-DCbBBNuKOeiR9h04ySRBMW52TFVc91O9wJziuyXw6Ztmy8D3oZbmCkOO3UHKC7ceNJsN2Mavo9+vwV8EAEUXzA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.0.tgz", + "integrity": "sha512-3yXFQo0oG3QCxbF06rMPFyGRMGJNS7NvsV1+2joOjbBE+9xvWQ8+GcMJAjRCzw06zQ3/arXeJgbPYcjUCuC+3g==", "dependencies": { "internmap": "1 - 2" }, @@ -3917,11 +3882,11 @@ } }, "node_modules/d3-contour": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-3.0.1.tgz", - "integrity": "sha512-0Oc4D0KyhwhM7ZL0RMnfGycLN7hxHB8CMmwZ3+H26PWAG0ozNuYG5hXSDNgmP1SgJkQMrlG6cP20HoaSbvcJTQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.0.tgz", + "integrity": "sha512-7aQo0QHUTu/Ko3cP9YK9yUTxtoDEiDGwnBHyLxG5M4vqlBkO/uixMRele3nfsfj6UXOcuReVpVXzAboGraYIJw==", "dependencies": { - "d3-array": "2 - 3" + "d3-array": "^3.2.0" }, "engines": { "node": ">=12" @@ -3982,6 +3947,14 @@ "node": ">=12" } }, + "node_modules/d3-dsv/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "engines": { + "node": ">= 10" + } + }, "node_modules/d3-ease": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", @@ -4511,7 +4484,7 @@ "node_modules/de-indent": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", - "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=" + "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==" }, "node_modules/debug": { "version": "4.3.4", @@ -4533,7 +4506,7 @@ "node_modules/decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "dev": true, "engines": { "node": ">=0.10.0" @@ -4542,7 +4515,7 @@ "node_modules/decamelize-keys": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", - "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "integrity": "sha512-ocLWuYzRPoS9bfiSdDd3cxvrzovVMZnRDVEzAs+hWIVXGDbHxWMECij2OBuyB/An0FFW/nLuq6Kv1i/YC5Qfzg==", "dev": true, "dependencies": { "decamelize": "^1.1.0", @@ -4555,7 +4528,7 @@ "node_modules/decamelize-keys/node_modules/map-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", "dev": true, "engines": { "node": ">=0.10.0" @@ -4564,9 +4537,18 @@ "node_modules/dedent": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", "dev": true }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -4636,7 +4618,7 @@ "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true, "engines": { "node": ">=0.4.0" @@ -4670,12 +4652,12 @@ } }, "node_modules/diff-sequences": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", - "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", + "version": "28.1.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.1.1.tgz", + "integrity": "sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==", "dev": true, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/dir-glob": { @@ -4798,9 +4780,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.137", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.137.tgz", - "integrity": "sha512-0Rcpald12O11BUogJagX3HsCN3FE83DSqWjgXoHo5a72KUKMSfI39XBgJpgNNxS9fuGzytaFjE06kZkiVFy2qA==" + "version": "1.4.210", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.210.tgz", + "integrity": "sha512-kSiX4tuyZijV7Cz0MWVmGT8K2siqaOA4Z66K5dCttPPRh0HicOcOAEj1KlC8O8J1aOS/1M8rGofOzksLKaHWcQ==" }, "node_modules/emittery": { "version": "0.10.2", @@ -4828,9 +4810,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.9.3.tgz", - "integrity": "sha512-Bq9VSor+kjvW3f9/MiiR4eE3XYgOl7/rS8lnSxbRbF3kS0B2r+Y9w5krBWxZgDxASVZbdYrn5wT4j/Wb0J9qow==", + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", + "integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==", "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -4926,6 +4908,27 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es-aggregate-error": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/es-aggregate-error/-/es-aggregate-error-1.0.8.tgz", + "integrity": "sha512-AKUb5MKLWMozPlFRHOKqWD7yta5uaEhH21qwtnf6FlKjNjTJOoqFi0/G14+FfSkIQhhu6X68Af4xgRC6y8qG4A==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5", + "function-bind": "^1.1.1", + "functions-have-names": "^1.2.3", + "get-intrinsic": "^1.1.1", + "globalthis": "^1.0.2", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/es-module-lexer": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", @@ -4958,9 +4961,9 @@ } }, "node_modules/esbuild": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.39.tgz", - "integrity": "sha512-2kKujuzvRWYtwvNjYDY444LQIA3TyJhJIX3Yo4+qkFlDDtGlSicWgeHVJqMUP/2sSfH10PGwfsj+O2ro1m10xQ==", + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.53.tgz", + "integrity": "sha512-ohO33pUBQ64q6mmheX1mZ8mIXj8ivQY/L4oVuAshr+aJI+zLl+amrp3EodrUNDNYVrKJXGPfIHFGhO8slGRjuw==", "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" @@ -4969,47 +4972,243 @@ "node": ">=12" }, "optionalDependencies": { - "esbuild-android-64": "0.14.39", - "esbuild-android-arm64": "0.14.39", - "esbuild-darwin-64": "0.14.39", - "esbuild-darwin-arm64": "0.14.39", - "esbuild-freebsd-64": "0.14.39", - "esbuild-freebsd-arm64": "0.14.39", - "esbuild-linux-32": "0.14.39", - "esbuild-linux-64": "0.14.39", - "esbuild-linux-arm": "0.14.39", - "esbuild-linux-arm64": "0.14.39", - "esbuild-linux-mips64le": "0.14.39", - "esbuild-linux-ppc64le": "0.14.39", - "esbuild-linux-riscv64": "0.14.39", - "esbuild-linux-s390x": "0.14.39", - "esbuild-netbsd-64": "0.14.39", - "esbuild-openbsd-64": "0.14.39", - "esbuild-sunos-64": "0.14.39", - "esbuild-windows-32": "0.14.39", - "esbuild-windows-64": "0.14.39", - "esbuild-windows-arm64": "0.14.39" + "@esbuild/linux-loong64": "0.14.53", + "esbuild-android-64": "0.14.53", + "esbuild-android-arm64": "0.14.53", + "esbuild-darwin-64": "0.14.53", + "esbuild-darwin-arm64": "0.14.53", + "esbuild-freebsd-64": "0.14.53", + "esbuild-freebsd-arm64": "0.14.53", + "esbuild-linux-32": "0.14.53", + "esbuild-linux-64": "0.14.53", + "esbuild-linux-arm": "0.14.53", + "esbuild-linux-arm64": "0.14.53", + "esbuild-linux-mips64le": "0.14.53", + "esbuild-linux-ppc64le": "0.14.53", + "esbuild-linux-riscv64": "0.14.53", + "esbuild-linux-s390x": "0.14.53", + "esbuild-netbsd-64": "0.14.53", + "esbuild-openbsd-64": "0.14.53", + "esbuild-sunos-64": "0.14.53", + "esbuild-windows-32": "0.14.53", + "esbuild-windows-64": "0.14.53", + "esbuild-windows-arm64": "0.14.53" + } + }, + "node_modules/esbuild-android-64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.53.tgz", + "integrity": "sha512-fIL93sOTnEU+NrTAVMIKiAw0YH22HWCAgg4N4Z6zov2t0kY9RAJ50zY9ZMCQ+RT6bnOfDt8gCTnt/RaSNA2yRA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" } }, - "node_modules/esbuild-darwin-64": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.39.tgz", - "integrity": "sha512-ImT6eUw3kcGcHoUxEcdBpi6LfTRWaV6+qf32iYYAfwOeV+XaQ/Xp5XQIBiijLeo+LpGci9M0FVec09nUw41a5g==", + "node_modules/esbuild-android-arm64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.53.tgz", + "integrity": "sha512-PC7KaF1v0h/nWpvlU1UMN7dzB54cBH8qSsm7S9mkwFA1BXpaEOufCg8hdoEI1jep0KeO/rjZVWrsH8+q28T77A==", "cpu": [ - "x64" + "arm64" ], "optional": true, "os": [ - "darwin" + "android" ], "engines": { "node": ">=12" } }, - "node_modules/esbuild-loader": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-2.19.0.tgz", - "integrity": "sha512-urGNVE6Tl2rqx92ElKi/LiExXjGvcH6HfDBFzJ9Ppwqh4n6Jmx8x7RKAyMzSM78b6CAaJLhDncG5sPrL0ROh5Q==", + "node_modules/esbuild-darwin-64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.53.tgz", + "integrity": "sha512-gE7P5wlnkX4d4PKvLBUgmhZXvL7lzGRLri17/+CmmCzfncIgq8lOBvxGMiQ4xazplhxq+72TEohyFMZLFxuWvg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-arm64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.53.tgz", + "integrity": "sha512-otJwDU3hnI15Q98PX4MJbknSZ/WSR1I45il7gcxcECXzfN4Mrpft5hBDHXNRnCh+5858uPXBXA1Vaz2jVWLaIA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.53.tgz", + "integrity": "sha512-WkdJa8iyrGHyKiPF4lk0MiOF87Q2SkE+i+8D4Cazq3/iqmGPJ6u49je300MFi5I2eUsQCkaOWhpCVQMTKGww2w==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-arm64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.53.tgz", + "integrity": "sha512-9T7WwCuV30NAx0SyQpw8edbKvbKELnnm1FHg7gbSYaatH+c8WJW10g/OdM7JYnv7qkimw2ZTtSA+NokOLd2ydQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-32": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.53.tgz", + "integrity": "sha512-VGanLBg5en2LfGDgLEUxQko2lqsOS7MTEWUi8x91YmsHNyzJVT/WApbFFx3MQGhkf+XdimVhpyo5/G0PBY91zg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.53.tgz", + "integrity": "sha512-pP/FA55j/fzAV7N9DF31meAyjOH6Bjuo3aSKPh26+RW85ZEtbJv9nhoxmGTd9FOqjx59Tc1ZbrJabuiXlMwuZQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.53.tgz", + "integrity": "sha512-/u81NGAVZMopbmzd21Nu/wvnKQK3pT4CrvQ8BTje1STXcQAGnfyKgQlj3m0j2BzYbvQxSy+TMck4TNV2onvoPA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.53.tgz", + "integrity": "sha512-GDmWITT+PMsjCA6/lByYk7NyFssW4Q6in32iPkpjZ/ytSyH+xeEx8q7HG3AhWH6heemEYEWpTll/eui3jwlSnw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-mips64le": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.53.tgz", + "integrity": "sha512-d6/XHIQW714gSSp6tOOX2UscedVobELvQlPMkInhx1NPz4ThZI9uNLQ4qQJHGBGKGfu+rtJsxM4NVHLhnNRdWQ==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-ppc64le": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.53.tgz", + "integrity": "sha512-ndnJmniKPCB52m+r6BtHHLAOXw+xBCWIxNnedbIpuREOcbSU/AlyM/2dA3BmUQhsHdb4w3amD5U2s91TJ3MzzA==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-riscv64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.53.tgz", + "integrity": "sha512-yG2sVH+QSix6ct4lIzJj329iJF3MhloLE6/vKMQAAd26UVPVkhMFqFopY+9kCgYsdeWvXdPgmyOuKa48Y7+/EQ==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-s390x": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.53.tgz", + "integrity": "sha512-OCJlgdkB+XPYndHmw6uZT7jcYgzmx9K+28PVdOa/eLjdoYkeAFvH5hTwX4AXGLZLH09tpl4bVsEtvuyUldaNCg==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-loader": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-2.19.0.tgz", + "integrity": "sha512-urGNVE6Tl2rqx92ElKi/LiExXjGvcH6HfDBFzJ9Ppwqh4n6Jmx8x7RKAyMzSM78b6CAaJLhDncG5sPrL0ROh5Q==", "dependencies": { "esbuild": "^0.14.39", "joycon": "^3.0.1", @@ -5025,6 +5224,96 @@ "webpack": "^4.40.0 || ^5.0.0" } }, + "node_modules/esbuild-netbsd-64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.53.tgz", + "integrity": "sha512-gp2SB+Efc7MhMdWV2+pmIs/Ja/Mi5rjw+wlDmmbIn68VGXBleNgiEZG+eV2SRS0kJEUyHNedDtwRIMzaohWedQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-openbsd-64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.53.tgz", + "integrity": "sha512-eKQ30ZWe+WTZmteDYg8S+YjHV5s4iTxeSGhJKJajFfQx9TLZJvsJX0/paqwP51GicOUruFpSUAs2NCc0a4ivQQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-sunos-64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.53.tgz", + "integrity": "sha512-OWLpS7a2FrIRukQqcgQqR1XKn0jSJoOdT+RlhAxUoEQM/IpytS3FXzCJM6xjUYtpO5GMY0EdZJp+ur2pYdm39g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-32": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.53.tgz", + "integrity": "sha512-m14XyWQP5rwGW0tbEfp95U6A0wY0DYPInWBB7D69FAXUpBpBObRoGTKRv36lf2RWOdE4YO3TNvj37zhXjVL5xg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.53.tgz", + "integrity": "sha512-s9skQFF0I7zqnQ2K8S1xdLSfZFsPLuOGmSx57h2btSEswv0N0YodYvqLcJMrNMXh6EynOmWD7rz+0rWWbFpIHQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-arm64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.53.tgz", + "integrity": "sha512-E+5Gvb+ZWts+00T9II6wp2L3KG2r3iGxByqd/a1RmLmYWVsSVUjkvIxZuJ3hYTIbhLkH5PRwpldGTKYqVz0nzQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -5139,13 +5428,14 @@ } }, "node_modules/eslint": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.15.0.tgz", - "integrity": "sha512-GG5USZ1jhCu8HJkzGgeK8/+RGnHaNYZGrGDzUtigK3BsGESW/rs2az23XqE0WVwDxy1VRvvjSSGu5nB0Bu+6SA==", + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.21.0.tgz", + "integrity": "sha512-/XJ1+Qurf1T9G2M5IHrsjp+xrGT73RZf23xA1z5wB1ZzzEAWSZKvRwhWxTFp1rvkvCfwcvAUNAP31bhKTTGfDA==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.2.3", - "@humanwhocodes/config-array": "^0.9.2", + "@eslint/eslintrc": "^1.3.0", + "@humanwhocodes/config-array": "^0.10.4", + "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -5155,14 +5445,17 @@ "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.2", + "espree": "^9.3.3", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", "functional-red-black-tree": "^1.0.1", "glob-parent": "^6.0.1", - "globals": "^13.6.0", + "globals": "^13.15.0", + "globby": "^11.1.0", + "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", @@ -5231,13 +5524,71 @@ "ms": "^2.1.1" } }, - "node_modules/eslint-plugin-html": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-6.2.0.tgz", - "integrity": "sha512-vi3NW0E8AJombTvt8beMwkL1R/fdRWl4QSNRNMhVQKWm36/X0KF0unGNAY4mqUF06mnwVWZcIcerrCnfn9025g==", + "node_modules/eslint-module-utils/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", "dev": true, "dependencies": { - "htmlparser2": "^7.1.2" + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "engines": { + "node": ">=4" } }, "node_modules/eslint-plugin-import": { @@ -5291,7 +5642,7 @@ "node_modules/eslint-plugin-import/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, "node_modules/eslint-plugin-jquery": { @@ -5303,14 +5654,26 @@ "eslint": ">=5.4.0" } }, + "node_modules/eslint-plugin-sonarjs": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.14.0.tgz", + "integrity": "sha512-0X0q3fB8ghppms19cR2oIK2ajoFp7DEy3AVGDqO7WX02r1aWOzkrHa+veatGZw+R7amgBvfcF0qHCG66p9Zoag==", + "dev": true, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, "node_modules/eslint-plugin-unicorn": { - "version": "42.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-42.0.0.tgz", - "integrity": "sha512-ixBsbhgWuxVaNlPTT8AyfJMlhyC5flCJFjyK3oKE8TRrwBnaHvUbuIkCM1lqg8ryYrFStL/T557zfKzX4GKSlg==", + "version": "43.0.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-43.0.2.tgz", + "integrity": "sha512-DtqZ5mf/GMlfWoz1abIjq5jZfaFuHzGBZYIeuJfEoKKGWRHr2JiJR+ea+BF7Wx2N1PPRoT/2fwgiK1NnmNE3Hg==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.15.7", - "ci-info": "^3.3.0", + "@babel/helper-validator-identifier": "^7.18.6", + "ci-info": "^3.3.2", "clean-regexp": "^1.0.0", "eslint-utils": "^3.0.0", "esquery": "^1.4.0", @@ -5321,23 +5684,23 @@ "read-pkg-up": "^7.0.1", "regexp-tree": "^0.1.24", "safe-regex": "^2.1.1", - "semver": "^7.3.5", + "semver": "^7.3.7", "strip-indent": "^3.0.0" }, "engines": { - "node": ">=12" + "node": ">=14.18" }, "funding": { "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" }, "peerDependencies": { - "eslint": ">=8.8.0" + "eslint": ">=8.18.0" } }, "node_modules/eslint-plugin-vue": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.0.1.tgz", - "integrity": "sha512-/w/9/vzz+4bSYtp5UqXgJ0CfycXTMtpp6lkz7/fMp0CcJxPWyRP6Pr88ihhrsNEcVt2ZweMupWRNYa+5Md41LQ==", + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.3.0.tgz", + "integrity": "sha512-iscKKkBZgm6fGZwFt6poRoWC0Wy2dQOlwUPW++CiPoQiw1enctV2Hj5DBzzjJZfyqs+FAXhgzL4q0Ww03AgSmQ==", "dev": true, "dependencies": { "eslint-utils": "^3.0.0", @@ -5404,18 +5767,43 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "node_modules/espree": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", - "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", + "version": "9.3.3", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.3.tgz", + "integrity": "sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng==", "dev": true, "dependencies": { - "acorn": "^8.7.1", + "acorn": "^8.8.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.3.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/esprima": { @@ -5498,6 +5886,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", @@ -5531,35 +5920,35 @@ "node_modules/exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", "dev": true, "engines": { "node": ">= 0.8.0" } }, "node_modules/expect": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-28.1.0.tgz", - "integrity": "sha512-qFXKl8Pmxk8TBGfaFKRtcQjfXEnKAs+dmlxdwvukJZorwrAabT7M3h8oLOG01I2utEhkmUTi17CHaPBovZsKdw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/expect/-/expect-28.1.3.tgz", + "integrity": "sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g==", "dev": true, "dependencies": { - "@jest/expect-utils": "^28.1.0", + "@jest/expect-utils": "^28.1.3", "jest-get-type": "^28.0.2", - "jest-matcher-utils": "^28.1.0", - "jest-message-util": "^28.1.0", - "jest-util": "^28.1.0" + "jest-matcher-utils": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3" }, "engines": { "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/expect/node_modules/@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "dependencies": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -5580,18 +5969,18 @@ } }, "node_modules/expect/node_modules/jest-message-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.0.tgz", - "integrity": "sha512-RpA8mpaJ/B2HphDMiDlrAZdDytkmwFqgjDZovM21F35lHGeUeCvYmm6W+sbQ0ydaLpg5bFAUuWG1cjqOl8vqrw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^28.1.0", + "pretty-format": "^28.1.3", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -5600,12 +5989,12 @@ } }, "node_modules/expect/node_modules/jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "dependencies": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -5655,7 +6044,7 @@ "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, "node_modules/fast-memoize": { @@ -5665,9 +6054,12 @@ "dev": true }, "node_modules/fastest-levenshtein": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", - "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==" + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "engines": { + "node": ">= 4.9.1" + } }, "node_modules/fastq": { "version": "1.13.0", @@ -5719,15 +6111,19 @@ } }, "node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "dependencies": { - "locate-path": "^2.0.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/flat-cache": { @@ -5744,15 +6140,15 @@ } }, "node_modules/flatted": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", - "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.6.tgz", + "integrity": "sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==", "dev": true }, "node_modules/font-awesome": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz", - "integrity": "sha1-j6jPBBGhoxr9B7BtKQK7n8gVoTM=", + "integrity": "sha512-U6kGnykA/6bFmg1M/oT9EkFeIYv7JlX3bozwQJWiiLz6L0w3F5vBVPxHlwyX/vtNq1ckcpRKOB9f2Qal/VtFpg==", "engines": { "node": ">=0.10.3" } @@ -5788,7 +6184,7 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "node_modules/fsevents": { "version": "2.3.2", @@ -5817,30 +6213,6 @@ "node": ">=0.8.0" } }, - "node_modules/ftp/node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "dev": true - }, - "node_modules/ftp/node_modules/readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/ftp/node_modules/string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", - "dev": true - }, "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -5867,7 +6239,7 @@ "node_modules/functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", "dev": true }, "node_modules/functions-have-names": { @@ -5898,14 +6270,14 @@ } }, "node_modules/get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", + "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", "dev": true, "dependencies": { "function-bind": "^1.1.1", "has": "^1.0.3", - "has-symbols": "^1.0.1" + "has-symbols": "^1.0.3" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5923,7 +6295,7 @@ "node_modules/get-port": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", - "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=", + "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==", "dev": true, "engines": { "node": ">=4" @@ -5946,12 +6318,12 @@ "dev": true }, "node_modules/get-stdin": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", - "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz", + "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==", "dev": true, "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -5961,6 +6333,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, "engines": { "node": ">=10" }, @@ -6063,6 +6436,12 @@ "node": ">=6" } }, + "node_modules/global-prefix/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, "node_modules/global-prefix/node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -6076,9 +6455,9 @@ } }, "node_modules/globals": { - "version": "13.15.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", - "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -6090,6 +6469,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/globby": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", @@ -6113,7 +6507,7 @@ "node_modules/globjoin": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", - "integrity": "sha1-L0SUrIkZ43Z8XLtpHp9GMyQoXUM=", + "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", "dev": true }, "node_modules/graceful-fs": { @@ -6121,6 +6515,12 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, "node_modules/graphlib": { "version": "2.1.8", "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz", @@ -6135,9 +6535,9 @@ "integrity": "sha512-6QatdkKxXCMfvCW4rM++0RqyLQAzFX5nwl3yHS0XPgkZBkiSEY3VZVbMltrdtsbER/xZonLtyHt684wRp4erlQ==" }, "node_modules/happy-dom": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-4.0.1.tgz", - "integrity": "sha512-GUj2ayfbWYHPeQfcK0N+lygRE/DsrjQbALJq0zrxHLc9KYzhFSCmaCOISuNgHV/21EEeVIX55KoPTqMcX362+g==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-6.0.4.tgz", + "integrity": "sha512-b+ID23Ms0BY08UNLymsOMG7EI2jSlwEt4cbJs938GZfeNAg+fqgkSO3TokQMgSOFoHznpjWmpVjBUL5boJ9PWw==", "dev": true, "dependencies": { "css.escape": "^1.5.1", @@ -6228,7 +6628,7 @@ "node_modules/hash-sum": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", - "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=" + "integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==" }, "node_modules/he": { "version": "1.2.0", @@ -6262,25 +6662,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/htmlparser2": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz", - "integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==", - "dev": true, - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.2", - "domutils": "^2.8.0", - "entities": "^3.0.1" - } - }, "node_modules/http-basic": { "version": "8.1.3", "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", @@ -6358,6 +6739,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, "engines": { "node": ">=10.17.0" } @@ -6396,7 +6778,7 @@ "node_modules/image-size": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", - "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=", + "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==", "optional": true, "bin": { "image-size": "bin/image-size.js" @@ -6461,7 +6843,7 @@ "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, "engines": { "node": ">=0.8.19" @@ -6479,7 +6861,7 @@ "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -6491,10 +6873,13 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-3.0.0.tgz", + "integrity": "sha512-TxYQaeNW/N8ymDvwAxPyRbhMBtnEwuvaTYpOQkFx1nSeusgezHniEc/l35Vo4iCq/mMiTJbpD7oYxN98hFlfmw==", + "dev": true, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } }, "node_modules/internal-slot": { "version": "1.0.3", @@ -6535,7 +6920,7 @@ "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, "node_modules/is-bigint": { @@ -6567,15 +6952,18 @@ } }, "node_modules/is-builtin-module": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.1.0.tgz", - "integrity": "sha512-OV7JjAgOTfAFJmHZLvpSTb4qi0nIILDV1gWPYDnDJUTNFM5aGlRAhk4QcT8i7TuAleeEV5Fdkqn3t4mS+Q11fg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.0.tgz", + "integrity": "sha512-phDA4oSGt7vl1n5tJvTWooWWAsXLY+2xCnxNqvKhGEzujg+A43wPlPOyDg3C8XQHN+6k/JTQWJ/j0dQh/qr+Hw==", "dev": true, "dependencies": { - "builtin-modules": "^3.0.0" + "builtin-modules": "^3.3.0" }, "engines": { "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-callable": { @@ -6619,7 +7007,7 @@ "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "engines": { "node": ">=0.10.0" } @@ -6690,7 +7078,7 @@ "node_modules/is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", "dev": true, "engines": { "node": ">=0.10.0" @@ -6755,6 +7143,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, "engines": { "node": ">=8" }, @@ -6810,20 +7199,20 @@ "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==" }, "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", "dev": true }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "engines": { "node": ">=0.10.0" } @@ -6891,9 +7280,9 @@ } }, "node_modules/istanbul-reports": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.4.tgz", - "integrity": "sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", "dev": true, "dependencies": { "html-escaper": "^2.0.0", @@ -6904,14 +7293,15 @@ } }, "node_modules/jest": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-28.1.0.tgz", - "integrity": "sha512-TZR+tHxopPhzw3c3560IJXZWLNHgpcz1Zh0w5A65vynLGNcg/5pZ+VildAd7+XGOu6jd58XMY/HNn0IkZIXVXg==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest/-/jest-28.1.3.tgz", + "integrity": "sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA==", "dev": true, "dependencies": { - "@jest/core": "^28.1.0", + "@jest/core": "^28.1.3", + "@jest/types": "^28.1.3", "import-local": "^3.0.2", - "jest-cli": "^28.1.0" + "jest-cli": "^28.1.3" }, "bin": { "jest": "bin/jest.js" @@ -6929,87 +7319,87 @@ } }, "node_modules/jest-changed-files": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-28.0.2.tgz", - "integrity": "sha512-QX9u+5I2s54ZnGoMEjiM2WeBvJR2J7w/8ZUmH2um/WLAuGAYFQcsVXY9+1YL6k0H/AGUdH8pXUAv6erDqEsvIA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-28.1.3.tgz", + "integrity": "sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA==", "dev": true, "dependencies": { "execa": "^5.0.0", - "throat": "^6.0.1" + "p-limit": "^3.1.0" }, "engines": { "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/jest-circus": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-28.1.0.tgz", - "integrity": "sha512-rNYfqfLC0L0zQKRKsg4n4J+W1A2fbyGH7Ss/kDIocp9KXD9iaL111glsLu7+Z7FHuZxwzInMDXq+N1ZIBkI/TQ==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-28.1.3.tgz", + "integrity": "sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow==", "dev": true, "dependencies": { - "@jest/environment": "^28.1.0", - "@jest/expect": "^28.1.0", - "@jest/test-result": "^28.1.0", - "@jest/types": "^28.1.0", + "@jest/environment": "^28.1.3", + "@jest/expect": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^0.7.0", "is-generator-fn": "^2.0.0", - "jest-each": "^28.1.0", - "jest-matcher-utils": "^28.1.0", - "jest-message-util": "^28.1.0", - "jest-runtime": "^28.1.0", - "jest-snapshot": "^28.1.0", - "jest-util": "^28.1.0", - "pretty-format": "^28.1.0", + "jest-each": "^28.1.3", + "jest-matcher-utils": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-runtime": "^28.1.3", + "jest-snapshot": "^28.1.3", + "jest-util": "^28.1.3", + "p-limit": "^3.1.0", + "pretty-format": "^28.1.3", "slash": "^3.0.0", - "stack-utils": "^2.0.3", - "throat": "^6.0.1" + "stack-utils": "^2.0.3" }, "engines": { "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/jest-circus/node_modules/@jest/environment": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.0.tgz", - "integrity": "sha512-S44WGSxkRngzHslhV6RoAExekfF7Qhwa6R5+IYFa81mpcj0YgdBnRSmvHe3SNwOt64yXaE5GG8Y2xM28ii5ssA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", + "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", "dev": true, "dependencies": { - "@jest/fake-timers": "^28.1.0", - "@jest/types": "^28.1.0", + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", - "jest-mock": "^28.1.0" + "jest-mock": "^28.1.3" }, "engines": { "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/jest-circus/node_modules/@jest/fake-timers": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.0.tgz", - "integrity": "sha512-Xqsf/6VLeAAq78+GNPzI7FZQRf5cCHj1qgQxCjws9n8rKw8r1UYoeaALwBvyuzOkpU3c1I6emeMySPa96rxtIg==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", + "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", "dev": true, "dependencies": { - "@jest/types": "^28.1.0", - "@sinonjs/fake-timers": "^9.1.1", + "@jest/types": "^28.1.3", + "@sinonjs/fake-timers": "^9.1.2", "@types/node": "*", - "jest-message-util": "^28.1.0", - "jest-mock": "^28.1.0", - "jest-util": "^28.1.0" + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" }, "engines": { "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/jest-circus/node_modules/@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "dependencies": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -7039,18 +7429,18 @@ } }, "node_modules/jest-circus/node_modules/jest-message-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.0.tgz", - "integrity": "sha512-RpA8mpaJ/B2HphDMiDlrAZdDytkmwFqgjDZovM21F35lHGeUeCvYmm6W+sbQ0ydaLpg5bFAUuWG1cjqOl8vqrw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^28.1.0", + "pretty-format": "^28.1.3", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -7059,12 +7449,12 @@ } }, "node_modules/jest-circus/node_modules/jest-mock": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.0.tgz", - "integrity": "sha512-H7BrhggNn77WhdL7O1apG0Q/iwl0Bdd5E1ydhCJzL3oBLh/UYxAwR3EJLsBZ9XA3ZU4PA3UNw4tQjduBTCTmLw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", + "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", "dev": true, "dependencies": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*" }, "engines": { @@ -7072,12 +7462,12 @@ } }, "node_modules/jest-circus/node_modules/jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "dependencies": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -7089,21 +7479,21 @@ } }, "node_modules/jest-cli": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-28.1.0.tgz", - "integrity": "sha512-fDJRt6WPRriHrBsvvgb93OxgajHHsJbk4jZxiPqmZbMDRcHskfJBBfTyjFko0jjfprP544hOktdSi9HVgl4VUQ==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-28.1.3.tgz", + "integrity": "sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ==", "dev": true, "dependencies": { - "@jest/core": "^28.1.0", - "@jest/test-result": "^28.1.0", - "@jest/types": "^28.1.0", + "@jest/core": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", "import-local": "^3.0.2", - "jest-config": "^28.1.0", - "jest-util": "^28.1.0", - "jest-validate": "^28.1.0", + "jest-config": "^28.1.3", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", "prompts": "^2.0.1", "yargs": "^17.3.1" }, @@ -7123,12 +7513,12 @@ } }, "node_modules/jest-cli/node_modules/@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "dependencies": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -7149,12 +7539,12 @@ } }, "node_modules/jest-cli/node_modules/jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "dependencies": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -7166,31 +7556,31 @@ } }, "node_modules/jest-config": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-28.1.0.tgz", - "integrity": "sha512-aOV80E9LeWrmflp7hfZNn/zGA4QKv/xsn2w8QCBP0t0+YqObuCWTSgNbHJ0j9YsTuCO08ZR/wsvlxqqHX20iUA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-28.1.3.tgz", + "integrity": "sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^28.1.0", - "@jest/types": "^28.1.0", - "babel-jest": "^28.1.0", + "@jest/test-sequencer": "^28.1.3", + "@jest/types": "^28.1.3", + "babel-jest": "^28.1.3", "chalk": "^4.0.0", "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-circus": "^28.1.0", - "jest-environment-node": "^28.1.0", + "jest-circus": "^28.1.3", + "jest-environment-node": "^28.1.3", "jest-get-type": "^28.0.2", "jest-regex-util": "^28.0.2", - "jest-resolve": "^28.1.0", - "jest-runner": "^28.1.0", - "jest-util": "^28.1.0", - "jest-validate": "^28.1.0", + "jest-resolve": "^28.1.3", + "jest-runner": "^28.1.3", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", "micromatch": "^4.0.4", "parse-json": "^5.2.0", - "pretty-format": "^28.1.0", + "pretty-format": "^28.1.3", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" }, @@ -7211,12 +7601,12 @@ } }, "node_modules/jest-config/node_modules/@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "dependencies": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -7237,12 +7627,12 @@ } }, "node_modules/jest-config/node_modules/jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "dependencies": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -7254,65 +7644,24 @@ } }, "node_modules/jest-diff": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", - "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz", + "integrity": "sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-diff/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-diff/node_modules/jest-get-type": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", - "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", - "dev": true, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-diff/node_modules/pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" + "diff-sequences": "^28.1.1", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/jest-diff/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, "node_modules/jest-docblock": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-28.0.2.tgz", - "integrity": "sha512-FH10WWw5NxLoeSdQlJwu+MTiv60aXV/t8KEwIRGEv74WARE1cXIqh1vGdy2CraHuWOOrnzTWj/azQKqW4fO7xg==", + "version": "28.1.1", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-28.1.1.tgz", + "integrity": "sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA==", "dev": true, "dependencies": { "detect-newline": "^3.0.0" @@ -7322,28 +7671,28 @@ } }, "node_modules/jest-each": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-28.1.0.tgz", - "integrity": "sha512-a/XX02xF5NTspceMpHujmOexvJ4GftpYXqr6HhhmKmExtMXsyIN/fvanQlt/BcgFoRKN4OCXxLQKth9/n6OPFg==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-28.1.3.tgz", + "integrity": "sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g==", "dev": true, "dependencies": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "chalk": "^4.0.0", "jest-get-type": "^28.0.2", - "jest-util": "^28.1.0", - "pretty-format": "^28.1.0" + "jest-util": "^28.1.3", + "pretty-format": "^28.1.3" }, "engines": { "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/jest-each/node_modules/@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "dependencies": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -7364,12 +7713,12 @@ } }, "node_modules/jest-each/node_modules/jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "dependencies": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -7381,61 +7730,61 @@ } }, "node_modules/jest-environment-node": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-28.1.0.tgz", - "integrity": "sha512-gBLZNiyrPw9CSMlTXF1yJhaBgWDPVvH0Pq6bOEwGMXaYNzhzhw2kA/OijNF8egbCgDS0/veRv97249x2CX+udQ==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-28.1.3.tgz", + "integrity": "sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A==", "dev": true, "dependencies": { - "@jest/environment": "^28.1.0", - "@jest/fake-timers": "^28.1.0", - "@jest/types": "^28.1.0", + "@jest/environment": "^28.1.3", + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", - "jest-mock": "^28.1.0", - "jest-util": "^28.1.0" + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" }, "engines": { "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/jest-environment-node/node_modules/@jest/environment": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.0.tgz", - "integrity": "sha512-S44WGSxkRngzHslhV6RoAExekfF7Qhwa6R5+IYFa81mpcj0YgdBnRSmvHe3SNwOt64yXaE5GG8Y2xM28ii5ssA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", + "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", "dev": true, "dependencies": { - "@jest/fake-timers": "^28.1.0", - "@jest/types": "^28.1.0", + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", - "jest-mock": "^28.1.0" + "jest-mock": "^28.1.3" }, "engines": { "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/jest-environment-node/node_modules/@jest/fake-timers": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.0.tgz", - "integrity": "sha512-Xqsf/6VLeAAq78+GNPzI7FZQRf5cCHj1qgQxCjws9n8rKw8r1UYoeaALwBvyuzOkpU3c1I6emeMySPa96rxtIg==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", + "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", "dev": true, "dependencies": { - "@jest/types": "^28.1.0", - "@sinonjs/fake-timers": "^9.1.1", + "@jest/types": "^28.1.3", + "@sinonjs/fake-timers": "^9.1.2", "@types/node": "*", - "jest-message-util": "^28.1.0", - "jest-mock": "^28.1.0", - "jest-util": "^28.1.0" + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" }, "engines": { "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/jest-environment-node/node_modules/@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "dependencies": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -7465,18 +7814,18 @@ } }, "node_modules/jest-environment-node/node_modules/jest-message-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.0.tgz", - "integrity": "sha512-RpA8mpaJ/B2HphDMiDlrAZdDytkmwFqgjDZovM21F35lHGeUeCvYmm6W+sbQ0ydaLpg5bFAUuWG1cjqOl8vqrw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^28.1.0", + "pretty-format": "^28.1.3", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -7485,12 +7834,12 @@ } }, "node_modules/jest-environment-node/node_modules/jest-mock": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.0.tgz", - "integrity": "sha512-H7BrhggNn77WhdL7O1apG0Q/iwl0Bdd5E1ydhCJzL3oBLh/UYxAwR3EJLsBZ9XA3ZU4PA3UNw4tQjduBTCTmLw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", + "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", "dev": true, "dependencies": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*" }, "engines": { @@ -7498,12 +7847,12 @@ } }, "node_modules/jest-environment-node/node_modules/jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "dependencies": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -7515,30 +7864,21 @@ } }, "node_modules/jest-extended": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jest-extended/-/jest-extended-2.0.0.tgz", - "integrity": "sha512-6AgjJQVaBEKGSK3FH90kOiRUWJsbzn9NWtW0pjGkAFIdH0oPilfkV/gHPJdVvJeBiqT3jMHw8TUg9pUGC1azDg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/jest-extended/-/jest-extended-3.0.1.tgz", + "integrity": "sha512-OSGbKUhbjy7QikfQyK3ishFrAqLeRodBzeJk7SuuWGACAT7HHcGuJ4aUQ3ueLANx4KSv1Pa7r1LJWGtJ3eI0xA==", "dev": true, "dependencies": { - "jest-diff": "^27.2.5", - "jest-get-type": "^27.0.6" + "jest-diff": "^28.0.0", + "jest-get-type": "^28.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^14.15.0 || ^16.13.0 || >=18.0.0" }, "peerDependencies": { "jest": ">=27.2.5" } }, - "node_modules/jest-extended/node_modules/jest-get-type": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", - "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", - "dev": true, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, "node_modules/jest-get-type": { "version": "28.0.2", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", @@ -7549,22 +7889,22 @@ } }, "node_modules/jest-haste-map": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-28.1.0.tgz", - "integrity": "sha512-xyZ9sXV8PtKi6NCrJlmq53PyNVHzxmcfXNVvIRHpHmh1j/HChC4pwKgyjj7Z9us19JMw8PpQTJsFWOsIfT93Dw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-28.1.3.tgz", + "integrity": "sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA==", "dev": true, "dependencies": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "graceful-fs": "^4.2.9", "jest-regex-util": "^28.0.2", - "jest-util": "^28.1.0", - "jest-worker": "^28.1.0", + "jest-util": "^28.1.3", + "jest-worker": "^28.1.3", "micromatch": "^4.0.4", - "walker": "^1.0.7" + "walker": "^1.0.8" }, "engines": { "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" @@ -7574,12 +7914,12 @@ } }, "node_modules/jest-haste-map/node_modules/@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "dependencies": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -7600,12 +7940,12 @@ } }, "node_modules/jest-haste-map/node_modules/jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "dependencies": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -7617,52 +7957,28 @@ } }, "node_modules/jest-leak-detector": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-28.1.0.tgz", - "integrity": "sha512-uIJDQbxwEL2AMMs2xjhZl2hw8s77c3wrPaQ9v6tXJLGaaQ+4QrNJH5vuw7hA7w/uGT/iJ42a83opAqxGHeyRIA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-28.1.3.tgz", + "integrity": "sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA==", "dev": true, "dependencies": { "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.0" + "pretty-format": "^28.1.3" }, "engines": { "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/jest-matcher-utils": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.0.tgz", - "integrity": "sha512-onnax0n2uTLRQFKAjC7TuaxibrPSvZgKTcSCnNUz/tOjJ9UhxNm7ZmPpoQavmTDUjXvUQ8KesWk2/VdrxIFzTQ==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^28.1.0", - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-matcher-utils/node_modules/diff-sequences": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.0.2.tgz", - "integrity": "sha512-YtEoNynLDFCRznv/XDalsKGSZDoj0U5kLnXvY0JSq3nBboRrZXjD81+eSiwi+nzcZDwedMmcowcxNwwgFW23mQ==", - "dev": true, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-matcher-utils/node_modules/jest-diff": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.0.tgz", - "integrity": "sha512-8eFd3U3OkIKRtlasXfiAQfbovgFgRDb0Ngcs2E+FMeBZ4rUezqIaGjuyggJBp+llosQXNEWofk/Sz4Hr5gMUhA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz", + "integrity": "sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^28.0.2", + "jest-diff": "^28.1.3", "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.0" + "pretty-format": "^28.1.3" }, "engines": { "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" @@ -7760,17 +8076,17 @@ } }, "node_modules/jest-resolve": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-28.1.0.tgz", - "integrity": "sha512-vvfN7+tPNnnhDvISuzD1P+CRVP8cK0FHXRwPAcdDaQv4zgvwvag2n55/h5VjYcM5UJG7L4TwE5tZlzcI0X2Lhw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-28.1.3.tgz", + "integrity": "sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ==", "dev": true, "dependencies": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^28.1.0", + "jest-haste-map": "^28.1.3", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^28.1.0", - "jest-validate": "^28.1.0", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", "resolve": "^1.20.0", "resolve.exports": "^1.1.0", "slash": "^3.0.0" @@ -7780,25 +8096,25 @@ } }, "node_modules/jest-resolve-dependencies": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.0.tgz", - "integrity": "sha512-Ue1VYoSZquPwEvng7Uefw8RmZR+me/1kr30H2jMINjGeHgeO/JgrR6wxj2ofkJ7KSAA11W3cOrhNCbj5Dqqd9g==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.3.tgz", + "integrity": "sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA==", "dev": true, "dependencies": { "jest-regex-util": "^28.0.2", - "jest-snapshot": "^28.1.0" + "jest-snapshot": "^28.1.3" }, "engines": { "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/jest-resolve/node_modules/@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "dependencies": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -7819,12 +8135,12 @@ } }, "node_modules/jest-resolve/node_modules/jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "dependencies": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -7836,76 +8152,76 @@ } }, "node_modules/jest-runner": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-28.1.0.tgz", - "integrity": "sha512-FBpmuh1HB2dsLklAlRdOxNTTHKFR6G1Qmd80pVDvwbZXTriqjWqjei5DKFC1UlM732KjYcE6yuCdiF0WUCOS2w==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-28.1.3.tgz", + "integrity": "sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA==", "dev": true, "dependencies": { - "@jest/console": "^28.1.0", - "@jest/environment": "^28.1.0", - "@jest/test-result": "^28.1.0", - "@jest/transform": "^28.1.0", - "@jest/types": "^28.1.0", + "@jest/console": "^28.1.3", + "@jest/environment": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "emittery": "^0.10.2", "graceful-fs": "^4.2.9", - "jest-docblock": "^28.0.2", - "jest-environment-node": "^28.1.0", - "jest-haste-map": "^28.1.0", - "jest-leak-detector": "^28.1.0", - "jest-message-util": "^28.1.0", - "jest-resolve": "^28.1.0", - "jest-runtime": "^28.1.0", - "jest-util": "^28.1.0", - "jest-watcher": "^28.1.0", - "jest-worker": "^28.1.0", - "source-map-support": "0.5.13", - "throat": "^6.0.1" + "jest-docblock": "^28.1.1", + "jest-environment-node": "^28.1.3", + "jest-haste-map": "^28.1.3", + "jest-leak-detector": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-resolve": "^28.1.3", + "jest-runtime": "^28.1.3", + "jest-util": "^28.1.3", + "jest-watcher": "^28.1.3", + "jest-worker": "^28.1.3", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" }, "engines": { "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/jest-runner/node_modules/@jest/environment": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.0.tgz", - "integrity": "sha512-S44WGSxkRngzHslhV6RoAExekfF7Qhwa6R5+IYFa81mpcj0YgdBnRSmvHe3SNwOt64yXaE5GG8Y2xM28ii5ssA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", + "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", "dev": true, "dependencies": { - "@jest/fake-timers": "^28.1.0", - "@jest/types": "^28.1.0", + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", - "jest-mock": "^28.1.0" + "jest-mock": "^28.1.3" }, "engines": { "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/jest-runner/node_modules/@jest/fake-timers": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.0.tgz", - "integrity": "sha512-Xqsf/6VLeAAq78+GNPzI7FZQRf5cCHj1qgQxCjws9n8rKw8r1UYoeaALwBvyuzOkpU3c1I6emeMySPa96rxtIg==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", + "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", "dev": true, "dependencies": { - "@jest/types": "^28.1.0", - "@sinonjs/fake-timers": "^9.1.1", + "@jest/types": "^28.1.3", + "@sinonjs/fake-timers": "^9.1.2", "@types/node": "*", - "jest-message-util": "^28.1.0", - "jest-mock": "^28.1.0", - "jest-util": "^28.1.0" + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" }, "engines": { "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/jest-runner/node_modules/@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "dependencies": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -7935,18 +8251,18 @@ } }, "node_modules/jest-runner/node_modules/jest-message-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.0.tgz", - "integrity": "sha512-RpA8mpaJ/B2HphDMiDlrAZdDytkmwFqgjDZovM21F35lHGeUeCvYmm6W+sbQ0ydaLpg5bFAUuWG1cjqOl8vqrw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^28.1.0", + "pretty-format": "^28.1.3", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -7955,12 +8271,12 @@ } }, "node_modules/jest-runner/node_modules/jest-mock": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.0.tgz", - "integrity": "sha512-H7BrhggNn77WhdL7O1apG0Q/iwl0Bdd5E1ydhCJzL3oBLh/UYxAwR3EJLsBZ9XA3ZU4PA3UNw4tQjduBTCTmLw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", + "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", "dev": true, "dependencies": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*" }, "engines": { @@ -7968,12 +8284,12 @@ } }, "node_modules/jest-runner/node_modules/jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "dependencies": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -7985,31 +8301,31 @@ } }, "node_modules/jest-runtime": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-28.1.0.tgz", - "integrity": "sha512-wNYDiwhdH/TV3agaIyVF0lsJ33MhyujOe+lNTUiolqKt8pchy1Hq4+tDMGbtD5P/oNLA3zYrpx73T9dMTOCAcg==", - "dev": true, - "dependencies": { - "@jest/environment": "^28.1.0", - "@jest/fake-timers": "^28.1.0", - "@jest/globals": "^28.1.0", - "@jest/source-map": "^28.0.2", - "@jest/test-result": "^28.1.0", - "@jest/transform": "^28.1.0", - "@jest/types": "^28.1.0", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-28.1.3.tgz", + "integrity": "sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw==", + "dev": true, + "dependencies": { + "@jest/environment": "^28.1.3", + "@jest/fake-timers": "^28.1.3", + "@jest/globals": "^28.1.3", + "@jest/source-map": "^28.1.2", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", "execa": "^5.0.0", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-haste-map": "^28.1.0", - "jest-message-util": "^28.1.0", - "jest-mock": "^28.1.0", + "jest-haste-map": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", "jest-regex-util": "^28.0.2", - "jest-resolve": "^28.1.0", - "jest-snapshot": "^28.1.0", - "jest-util": "^28.1.0", + "jest-resolve": "^28.1.3", + "jest-snapshot": "^28.1.3", + "jest-util": "^28.1.3", "slash": "^3.0.0", "strip-bom": "^4.0.0" }, @@ -8018,44 +8334,44 @@ } }, "node_modules/jest-runtime/node_modules/@jest/environment": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.0.tgz", - "integrity": "sha512-S44WGSxkRngzHslhV6RoAExekfF7Qhwa6R5+IYFa81mpcj0YgdBnRSmvHe3SNwOt64yXaE5GG8Y2xM28ii5ssA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", + "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", "dev": true, "dependencies": { - "@jest/fake-timers": "^28.1.0", - "@jest/types": "^28.1.0", + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", - "jest-mock": "^28.1.0" + "jest-mock": "^28.1.3" }, "engines": { "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/jest-runtime/node_modules/@jest/fake-timers": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.0.tgz", - "integrity": "sha512-Xqsf/6VLeAAq78+GNPzI7FZQRf5cCHj1qgQxCjws9n8rKw8r1UYoeaALwBvyuzOkpU3c1I6emeMySPa96rxtIg==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", + "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", "dev": true, "dependencies": { - "@jest/types": "^28.1.0", - "@sinonjs/fake-timers": "^9.1.1", + "@jest/types": "^28.1.3", + "@sinonjs/fake-timers": "^9.1.2", "@types/node": "*", - "jest-message-util": "^28.1.0", - "jest-mock": "^28.1.0", - "jest-util": "^28.1.0" + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" }, "engines": { "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/jest-runtime/node_modules/@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "dependencies": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -8085,18 +8401,18 @@ } }, "node_modules/jest-runtime/node_modules/jest-message-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.0.tgz", - "integrity": "sha512-RpA8mpaJ/B2HphDMiDlrAZdDytkmwFqgjDZovM21F35lHGeUeCvYmm6W+sbQ0ydaLpg5bFAUuWG1cjqOl8vqrw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^28.1.0", + "pretty-format": "^28.1.3", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -8105,12 +8421,12 @@ } }, "node_modules/jest-runtime/node_modules/jest-mock": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.0.tgz", - "integrity": "sha512-H7BrhggNn77WhdL7O1apG0Q/iwl0Bdd5E1ydhCJzL3oBLh/UYxAwR3EJLsBZ9XA3ZU4PA3UNw4tQjduBTCTmLw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", + "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", "dev": true, "dependencies": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*" }, "engines": { @@ -8118,12 +8434,12 @@ } }, "node_modules/jest-runtime/node_modules/jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "dependencies": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -8135,9 +8451,9 @@ } }, "node_modules/jest-snapshot": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-28.1.0.tgz", - "integrity": "sha512-ex49M2ZrZsUyQLpLGxQtDbahvgBjlLPgklkqGM0hq/F7W/f8DyqZxVHjdy19QKBm4O93eDp+H5S23EiTbbUmHw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-28.1.3.tgz", + "integrity": "sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", @@ -8145,23 +8461,23 @@ "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.3.3", - "@jest/expect-utils": "^28.1.0", - "@jest/transform": "^28.1.0", - "@jest/types": "^28.1.0", + "@jest/expect-utils": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", "@types/babel__traverse": "^7.0.6", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^28.1.0", + "expect": "^28.1.3", "graceful-fs": "^4.2.9", - "jest-diff": "^28.1.0", + "jest-diff": "^28.1.3", "jest-get-type": "^28.0.2", - "jest-haste-map": "^28.1.0", - "jest-matcher-utils": "^28.1.0", - "jest-message-util": "^28.1.0", - "jest-util": "^28.1.0", + "jest-haste-map": "^28.1.3", + "jest-matcher-utils": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", "natural-compare": "^1.4.0", - "pretty-format": "^28.1.0", + "pretty-format": "^28.1.3", "semver": "^7.3.5" }, "engines": { @@ -8169,12 +8485,12 @@ } }, "node_modules/jest-snapshot/node_modules/@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "dependencies": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -8194,43 +8510,19 @@ "@types/yargs-parser": "*" } }, - "node_modules/jest-snapshot/node_modules/diff-sequences": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.0.2.tgz", - "integrity": "sha512-YtEoNynLDFCRznv/XDalsKGSZDoj0U5kLnXvY0JSq3nBboRrZXjD81+eSiwi+nzcZDwedMmcowcxNwwgFW23mQ==", - "dev": true, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-snapshot/node_modules/jest-diff": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.0.tgz", - "integrity": "sha512-8eFd3U3OkIKRtlasXfiAQfbovgFgRDb0Ngcs2E+FMeBZ4rUezqIaGjuyggJBp+llosQXNEWofk/Sz4Hr5gMUhA==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^28.0.2", - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, "node_modules/jest-snapshot/node_modules/jest-message-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.0.tgz", - "integrity": "sha512-RpA8mpaJ/B2HphDMiDlrAZdDytkmwFqgjDZovM21F35lHGeUeCvYmm6W+sbQ0ydaLpg5bFAUuWG1cjqOl8vqrw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^28.1.0", + "pretty-format": "^28.1.3", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -8239,12 +8531,12 @@ } }, "node_modules/jest-snapshot/node_modules/jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "dependencies": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -8273,29 +8565,29 @@ } }, "node_modules/jest-validate": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-28.1.0.tgz", - "integrity": "sha512-Lly7CJYih3vQBfjLeANGgBSBJ7pEa18cxpQfQEq2go2xyEzehnHfQTjoUia8xUv4x4J80XKFIDwJJThXtRFQXQ==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-28.1.3.tgz", + "integrity": "sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA==", "dev": true, "dependencies": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "camelcase": "^6.2.0", "chalk": "^4.0.0", "jest-get-type": "^28.0.2", "leven": "^3.1.0", - "pretty-format": "^28.1.0" + "pretty-format": "^28.1.3" }, "engines": { "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/jest-validate/node_modules/@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "dependencies": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -8328,18 +8620,18 @@ } }, "node_modules/jest-watcher": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.0.tgz", - "integrity": "sha512-tNHMtfLE8Njcr2IRS+5rXYA4BhU90gAOwI9frTGOqd+jX0P/Au/JfRSNqsf5nUTcWdbVYuLxS1KjnzILSoR5hA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.3.tgz", + "integrity": "sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==", "dev": true, "dependencies": { - "@jest/test-result": "^28.1.0", - "@jest/types": "^28.1.0", + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "emittery": "^0.10.2", - "jest-util": "^28.1.0", + "jest-util": "^28.1.3", "string-length": "^4.0.1" }, "engines": { @@ -8347,12 +8639,12 @@ } }, "node_modules/jest-watcher/node_modules/@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "dependencies": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -8373,12 +8665,12 @@ } }, "node_modules/jest-watcher/node_modules/jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "dependencies": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -8390,9 +8682,9 @@ } }, "node_modules/jest-worker": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.0.tgz", - "integrity": "sha512-ZHwM6mNwaWBR52Snff8ZvsCTqQsvhCxP/bT1I6T6DAnb6ygkshsyLQIMxFwHpYxht0HOoqt23JlC01viI7T03A==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", + "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==", "dev": true, "dependencies": { "@types/node": "*", @@ -8418,6 +8710,32 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/jest/node_modules/@jest/types": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^28.1.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest/node_modules/@types/yargs": { + "version": "17.0.10", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", + "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, "node_modules/joycon": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", @@ -8487,14 +8805,14 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, "node_modules/json5": { @@ -8533,9 +8851,9 @@ } }, "node_modules/jsonpointer": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.0.tgz", - "integrity": "sha512-PNYZIdMjVIvVgDSYKTT63Y+KZ6IZvGRNNWcxwD+GNnUz1MKPfv30J8ueCjdwcN0nDx2SlshgyB7Oy0epAzVRRg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", "dev": true, "engines": { "node": ">=0.10.0" @@ -8583,9 +8901,9 @@ "dev": true }, "node_modules/less": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/less/-/less-4.1.2.tgz", - "integrity": "sha512-EoQp/Et7OSOVu0aJknJOtlXZsnr8XE8KwuzTHOLeVSEx8pVWUICc8Q0VYRHgzyjX78nMEyC/oztWFbgyhtNfDA==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/less/-/less-4.1.3.tgz", + "integrity": "sha512-w16Xk/Ta9Hhyei0Gpz9m7VS8F28nieJaL/VyShID7cYvP6IL5oHeL6p4TXSDJqZE/lNv0oJ2pGVjJsRkfwm5FA==", "dependencies": { "copy-anything": "^2.0.1", "parse-node-version": "^1.0.1", @@ -8603,7 +8921,7 @@ "image-size": "~0.5.0", "make-dir": "^2.1.0", "mime": "^1.4.1", - "needle": "^2.5.2", + "needle": "^3.1.0", "source-map": "~0.6.0" } }, @@ -8725,6 +9043,15 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, + "node_modules/linkify-it": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", + "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", + "dev": true, + "dependencies": { + "uc.micro": "^1.0.1" + } + }, "node_modules/loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", @@ -8747,16 +9074,18 @@ } }, "node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "p-locate": "^5.0.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/lodash": { @@ -8767,7 +9096,7 @@ "node_modules/lodash._reinterpolate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" + "integrity": "sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==" }, "node_modules/lodash.get": { "version": "4.4.2", @@ -8787,11 +9116,6 @@ "integrity": "sha512-4hNPN5jlm/N/HLMCO43v8BXKq9Z7QdAGc/VGrRD61w8gN9g/6jF9A4L1pbUgBLCffi0w9VsXfTOij5x8iTyFvg==", "dev": true }, - "node_modules/lodash.sortby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" - }, "node_modules/lodash.template": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", @@ -8818,18 +9142,16 @@ "node_modules/lodash.truncate": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", "dev": true }, "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" + "yallist": "^3.0.2" } }, "node_modules/magic-string": { @@ -8886,10 +9208,117 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/markdown-it": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz", + "integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1", + "entities": "~3.0.1", + "linkify-it": "^4.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/markdownlint": { + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.26.1.tgz", + "integrity": "sha512-8sLz1ktz5s4E0IDum2H9aiWLQU7RA5Eket9HUW5IRwfFnW2RD2ZyqYePW+z71tMc7lrFZc1+yPmlN9lirbJnlg==", + "dev": true, + "dependencies": { + "markdown-it": "13.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/markdownlint-cli": { + "version": "0.32.1", + "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.32.1.tgz", + "integrity": "sha512-hVLQ+72b5esQd7I+IqzBEB4x/4C+wJaxS2M6nqaGoDwrtNY6gydGf5CIUJtQcXtqsM615++a8TZPsvEtH6H4gw==", + "dev": true, + "dependencies": { + "commander": "~9.4.0", + "get-stdin": "~9.0.0", + "glob": "~8.0.3", + "ignore": "~5.2.0", + "js-yaml": "^4.1.0", + "jsonc-parser": "~3.1.0", + "markdownlint": "~0.26.1", + "markdownlint-rule-helpers": "~0.17.1", + "minimatch": "~5.1.0", + "run-con": "~1.2.11" + }, + "bin": { + "markdownlint": "markdownlint.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/markdownlint-cli/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==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/markdownlint-cli/node_modules/glob": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", + "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/markdownlint-cli/node_modules/jsonc-parser": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.1.0.tgz", + "integrity": "sha512-DRf0QjnNeCUds3xTjKlQQ3DpJD51GvDjJfnxUVWg6PZTo2otSm+slzNAxU/35hF8/oJIKoG9slq30JYOsF2azg==", + "dev": true + }, + "node_modules/markdownlint-cli/node_modules/minimatch": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", + "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/markdownlint-rule-helpers": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.17.1.tgz", + "integrity": "sha512-Djc5IjJt7VA5sZRisISsJC/rQXR7hr8JS9u6Q9/ce3mjPZdzw535cFGG0U6Mag+ldRTRmRwCcTfivOh57KUP4w==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/marked": { - "version": "4.0.16", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.16.tgz", - "integrity": "sha512-wahonIQ5Jnyatt2fn8KqF/nIqZM8mh3oRu2+l5EANGMhu6RFjiSG52QNE2eWzFMI94HqYSgN184NurgNG6CztA==", + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.18.tgz", + "integrity": "sha512-wbLDJ7Zh0sqA0Vdg6aqlbT+yPxqLblpAZh1mK2+AO2twQkPywvvqQNfEPVwSSRjZ7dZcdeVBIAgiO7MMp3Dszw==", "bin": { "marked": "bin/marked.js" }, @@ -8913,6 +9342,12 @@ "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", "dev": true }, + "node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", + "dev": true + }, "node_modules/meow": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", @@ -8951,6 +9386,18 @@ "node": ">=10" } }, + "node_modules/meow/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/meow/node_modules/normalize-package-data": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", @@ -8978,6 +9425,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/meow/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/merge-source-map": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", @@ -9000,9 +9453,9 @@ } }, "node_modules/mermaid": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-9.1.2.tgz", - "integrity": "sha512-RVf3hBKqiMfyORHboCaEjOAK1TomLO50hYRPvlTrZCXlCniM5pRpe8UlkHBjjpaLtioZnbdYv/vEVj7iKnwkJQ==", + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-9.1.3.tgz", + "integrity": "sha512-jTIYiqKwsUXVCoxHUVkK8t0QN3zSKIdJlb9thT0J5jCnzXyc+gqTbZE2QmjRfavFTPPn5eRy5zaFp7V+6RhxYg==", "dependencies": { "@braintree/sanitize-url": "^6.0.0", "d3": "^7.0.0", @@ -9062,6 +9515,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, "engines": { "node": ">=6" } @@ -9076,9 +9530,9 @@ } }, "node_modules/mini-css-extract-plugin": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.0.tgz", - "integrity": "sha512-ndG8nxCEnAemsg4FSgS+yNyHKgkTB4nPKqCOgh65j3/30qqC5RaSQQXMm++Y6sb6E1zRSxPkztj9fqxhS1Eo6w==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.1.tgz", + "integrity": "sha512-wd+SD57/K6DiV7jIR34P+s3uckTRuQvx0tKPcvjFlrEylk6P4mQ2KSWk1hblj1Kxaqok7LogKOieygXqBczNlg==", "dependencies": { "schema-utils": "^4.0.0" }, @@ -9165,17 +9619,17 @@ "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, "node_modules/needle": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/needle/-/needle-2.9.1.tgz", - "integrity": "sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-3.1.0.tgz", + "integrity": "sha512-gCE9weDhjVGCRqS8dwDR/D3GTAeyXLXuqp7I8EzH6DllZGXSUyxuqqLh+YX9rMAWaaTFyVAg6rHGL25dqvczKw==", "optional": true, "dependencies": { "debug": "^3.2.6", - "iconv-lite": "^0.4.4", + "iconv-lite": "^0.6.3", "sax": "^1.2.4" }, "bin": { @@ -9194,18 +9648,6 @@ "ms": "^2.1.1" } }, - "node_modules/needle/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "optional": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", @@ -9262,13 +9704,13 @@ "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", "dev": true }, "node_modules/node-releases": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.4.tgz", - "integrity": "sha512-gbMzqQtTtDz/00jQzZ21PQzdI9PyLYqUSvD0p3naOhX4odFji0ZxYdnVwPTxmSwkmxhcFImpozceidSG+AgoPQ==" + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", + "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==" }, "node_modules/normalize-package-data": { "version": "2.5.0", @@ -9300,16 +9742,11 @@ "node": ">=0.10.0" } }, - "node_modules/normalize-selector": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/normalize-selector/-/normalize-selector-0.2.0.tgz", - "integrity": "sha1-0LFF62kRicY6eNIB3E/bEpPvDAM=", - "dev": true - }, "node_modules/npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, "dependencies": { "path-key": "^3.0.0" }, @@ -9318,9 +9755,9 @@ } }, "node_modules/nth-check": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz", - "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", "dev": true, "dependencies": { "boolbase": "^1.0.0" @@ -9332,15 +9769,15 @@ "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "engines": { "node": ">=0.10.0" } }, "node_modules/object-inspect": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", - "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -9393,7 +9830,7 @@ "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dependencies": { "wrappy": "1" } @@ -9402,6 +9839,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, "dependencies": { "mimic-fn": "^2.1.0" }, @@ -9430,36 +9868,41 @@ } }, "node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "dependencies": { - "p-try": "^1.0.0" + "yocto-queue": "^0.1.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "dependencies": { - "p-limit": "^1.1.0" + "p-limit": "^3.0.2" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true, + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/pac-proxy-agent": { @@ -9511,7 +9954,7 @@ "node_modules/parse-cache-control": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", - "integrity": "sha1-juqz5U+laSD+Fro493+iGqzC104=", + "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==", "dev": true }, "node_modules/parse-json": { @@ -9533,11 +9976,14 @@ } }, "node_modules/parse-ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", - "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-3.0.0.tgz", + "integrity": "sha512-Tpb8Z7r7XbbtBTrM9UhpkzzaMrqA2VXMT3YChzYltwV3P3pM6t8wl7TvpMnSTosz1aQAdVib7kdoys7vYOPerw==", "engines": { - "node": ">=6" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/parse-node-version": { @@ -9549,18 +9995,17 @@ } }, "node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true, + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "engines": { "node": ">=0.10.0" } @@ -9680,22 +10125,6 @@ "node": ">=8" } }, - "node_modules/pkg-dir/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-dir/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "engines": { - "node": ">=8" - } - }, "node_modules/pluralize": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", @@ -9762,7 +10191,7 @@ "node_modules/postcss-media-query-parser": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", - "integrity": "sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ=", + "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", "dev": true }, "node_modules/postcss-modules-extract-imports": { @@ -9823,7 +10252,7 @@ "node_modules/postcss-resolve-nested-selector": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", - "integrity": "sha1-Kcy8fDfe36wwTp//C/FZaz9qDk4=", + "integrity": "sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==", "dev": true }, "node_modules/postcss-safe-parser": { @@ -9869,9 +10298,9 @@ } }, "node_modules/prettier": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz", - "integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", "optional": true, "bin": { "prettier": "bin-prettier.js" @@ -9884,12 +10313,12 @@ } }, "node_modules/pretty-format": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.0.tgz", - "integrity": "sha512-79Z4wWOYCdvQkEoEuSlBhHJqWeZ8D8YRPiPctJFCtvuaClGpiwiQYSCUOE6IEKUbbFukKOTFIUAXE8N4EQTo1Q==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", "dev": true, "dependencies": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" @@ -9911,14 +10340,14 @@ } }, "node_modules/pretty-ms": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz", - "integrity": "sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-8.0.0.tgz", + "integrity": "sha512-ASJqOugUF1bbzI35STMBUpZqdfYKlJugy6JBziGi2EE+AL5JPJGSzvpeVXojxrr0ViUYoToUjb5kjSEGf7Y83Q==", "dependencies": { - "parse-ms": "^2.1.0" + "parse-ms": "^3.0.0" }, "engines": { - "node": ">=10" + "node": ">=14.16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -9977,21 +10406,6 @@ "node": ">= 8" } }, - "node_modules/proxy-agent/node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/proxy-agent/node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -10001,13 +10415,13 @@ "node_modules/prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", "optional": true }, "node_modules/pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" }, "node_modules/punycode": { "version": "2.1.1", @@ -10018,9 +10432,9 @@ } }, "node_modules/qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "dev": true, "dependencies": { "side-channel": "^1.0.4" @@ -10096,9 +10510,9 @@ } }, "node_modules/react-is": { - "version": "18.1.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.1.0.tgz", - "integrity": "sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==", + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, "node_modules/read-pkg": { @@ -10185,24 +10599,6 @@ "node": ">=8" } }, - "node_modules/read-pkg-up/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/read-pkg-up/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/read-pkg-up/node_modules/type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", @@ -10222,18 +10618,15 @@ } }, "node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", "dev": true, "dependencies": { "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" } }, "node_modules/rechoir": { @@ -10306,7 +10699,7 @@ "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, "engines": { "node": ">=0.10.0" @@ -10330,11 +10723,11 @@ } }, "node_modules/resolve": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", - "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", "dependencies": { - "is-core-module": "^2.8.1", + "is-core-module": "^2.9.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -10412,9 +10805,9 @@ "integrity": "sha512-ndEIpszUHiG4HtDsQLeIuMvRsDnn8c8rYStabochtUeCvfuvNptb5TUbVD68LRAILPX7p9nqQGh4xJgn3EHS/g==" }, "node_modules/rollup": { - "version": "2.76.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.76.0.tgz", - "integrity": "sha512-9jwRIEY1jOzKLj3nsY/yot41r19ITdQrhs+q3ggNWhr9TQgduHqANvPpS32RNpzGklJu3G1AJfvlZLi/6wFgWA==", + "version": "2.77.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.77.2.tgz", + "integrity": "sha512-m/4YzYgLcpMQbxX3NmAqDvwLATZzxt8bIegO78FZLl+lAgKJBd1DRAOeEiZcKOIOPjxE6ewHWHNgGEalFXuz1g==", "dev": true, "peer": true, "bin": { @@ -10427,6 +10820,21 @@ "fsevents": "~2.3.2" } }, + "node_modules/run-con": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/run-con/-/run-con-1.2.11.tgz", + "integrity": "sha512-NEMGsUT+cglWkzEr4IFK21P4Jca45HqiAbIIZIBdX5+UZTB24Mb/21iNGgz9xZa8tL6vbW7CXmq7MFN42+VjNQ==", + "dev": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~3.0.0", + "minimist": "^1.2.6", + "strip-json-comments": "~3.1.1" + }, + "bin": { + "run-con": "cli.js" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -10452,7 +10860,7 @@ "node_modules/rw": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", - "integrity": "sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q=" + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" }, "node_modules/safe-buffer": { "version": "5.1.2", @@ -10503,37 +10911,6 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/schema-utils/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/schema-utils/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/schema-utils/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, "node_modules/semver": { "version": "7.3.7", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", @@ -10548,6 +10925,22 @@ "node": ">=10" } }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, "node_modules/serialize-javascript": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", @@ -10609,7 +11002,8 @@ "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true }, "node_modules/simple-eval": { "version": "1.0.0", @@ -10666,12 +11060,12 @@ } }, "node_modules/socks": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz", - "integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.0.tgz", + "integrity": "sha512-scnOe9y4VuiNUULJN72GrM26BNOjVsfPXI+j+98PkyEfsIXroa5ofyjT+FzGvn/xHs73U2JtoBYAVx9Hl4quSA==", "dev": true, "dependencies": { - "ip": "^1.1.5", + "ip": "^2.0.0", "smart-buffer": "^4.2.0" }, "engines": { @@ -10693,6 +11087,12 @@ "node": ">= 6" } }, + "node_modules/socks/node_modules/ip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", + "dev": true + }, "node_modules/sortablejs": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.15.0.tgz", @@ -10797,25 +11197,17 @@ "spdx-ranges": "^2.0.0" } }, - "node_modules/specificity": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/specificity/-/specificity-0.4.1.tgz", - "integrity": "sha512-1klA3Gi5PD1Wv9Q0wUoOQN1IWAuPu0D1U03ThXTr0cJ20+/iq2tHSDnK7Kk/0LXJ1ztUB2/1Os0wKmfyNgUQfg==", - "dev": true, - "bin": { - "specificity": "bin/specificity" - } - }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, "node_modules/stable": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility", "dev": true }, "node_modules/stack-utils": { @@ -10859,13 +11251,10 @@ } }, "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "dev": true }, "node_modules/string-length": { "version": "4.0.2", @@ -10945,6 +11334,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, "engines": { "node": ">=6" } @@ -10976,19 +11366,20 @@ "node_modules/style-search": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", - "integrity": "sha1-eVjHk+R+MuB9K1yv5cC/jhLneQI=", + "integrity": "sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==", "dev": true }, "node_modules/stylelint": { - "version": "14.8.2", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.8.2.tgz", - "integrity": "sha512-tjDfexCYfoPdl/xcDJ9Fv+Ko9cvzbDnmdiaqEn3ovXHXasi/hbkt5tSjsiReQ+ENqnz0eltaX/AOO+AlzVdcNA==", + "version": "14.9.1", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.9.1.tgz", + "integrity": "sha512-RdAkJdPiLqHawCSnu21nE27MjNXaVd4WcOHA4vK5GtIGjScfhNnaOuWR2wWdfKFAvcWQPOYe311iveiVKSmwsA==", "dev": true, "dependencies": { + "@csstools/selector-specificity": "^2.0.1", "balanced-match": "^2.0.0", "colord": "^2.9.2", "cosmiconfig": "^7.0.1", - "css-functions-list": "^3.0.1", + "css-functions-list": "^3.1.0", "debug": "^4.3.4", "execall": "^2.0.0", "fast-glob": "^3.2.11", @@ -11008,16 +11399,14 @@ "meow": "^9.0.0", "micromatch": "^4.0.5", "normalize-path": "^3.0.0", - "normalize-selector": "^0.2.0", "picocolors": "^1.0.0", - "postcss": "^8.4.13", + "postcss": "^8.4.14", "postcss-media-query-parser": "^0.2.3", "postcss-resolve-nested-selector": "^0.1.1", "postcss-safe-parser": "^6.0.0", "postcss-selector-parser": "^6.0.10", "postcss-value-parser": "^4.2.0", "resolve-from": "^5.0.0", - "specificity": "^0.4.1", "string-width": "^4.2.3", "strip-ansi": "^6.0.1", "style-search": "^0.1.0", @@ -11039,24 +11428,24 @@ } }, "node_modules/stylelint-config-recommended": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-7.0.0.tgz", - "integrity": "sha512-yGn84Bf/q41J4luis1AZ95gj0EQwRX8lWmGmBwkwBNSkpGSpl66XcPTulxGa/Z91aPoNGuIGBmFkcM1MejMo9Q==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-8.0.0.tgz", + "integrity": "sha512-IK6dWvE000+xBv9jbnHOnBq01gt6HGVB2ZTsot+QsMpe82doDQ9hvplxfv4YnpEuUwVGGd9y6nbaAnhrjcxhZQ==", "dev": true, "peerDependencies": { - "stylelint": "^14.4.0" + "stylelint": "^14.8.0" } }, "node_modules/stylelint-config-standard": { - "version": "25.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-25.0.0.tgz", - "integrity": "sha512-21HnP3VSpaT1wFjFvv9VjvOGDtAviv47uTp3uFmzcN+3Lt+RYRv6oAplLaV51Kf792JSxJ6svCJh/G18E9VnCA==", + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-26.0.0.tgz", + "integrity": "sha512-hUuB7LaaqM8abvkOO84wh5oYSkpXgTzHu2Zza6e7mY+aOmpNTjoFBRxSLlzY0uAOMWEFx0OMKzr+reG1BUtcqQ==", "dev": true, "dependencies": { - "stylelint-config-recommended": "^7.0.0" + "stylelint-config-recommended": "^8.0.0" }, "peerDependencies": { - "stylelint": "^14.4.0" + "stylelint": "^14.9.0" } }, "node_modules/stylelint/node_modules/balanced-match": { @@ -11065,6 +11454,18 @@ "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", "dev": true }, + "node_modules/stylelint/node_modules/get-stdin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/stylelint/node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", @@ -11123,7 +11524,7 @@ "node_modules/svg-tags": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", - "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=", + "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", "dev": true }, "node_modules/svgo": { @@ -11147,10 +11548,19 @@ "node": ">=10.13.0" } }, + "node_modules/svgo/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, "node_modules/swagger-ui-dist": { - "version": "4.11.1", - "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-4.11.1.tgz", - "integrity": "sha512-pf3kfSTYdF9mYFY2VnfJ51wnXlSVhEGdtymhpHzfbFw2jTbiEWgBoVz5EB9aW2EaJvUGTM1YHAXYZX7Jk4RdAQ==" + "version": "4.13.2", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-4.13.2.tgz", + "integrity": "sha512-jHL6UyIYpvEI7NsuWd0R3hJaPQTg6Oo4qSBo+oVfOEkv6rrQm/475RGSMmZgV6ajp+Sgrp9CqrDjQYAgQqiv1A==" }, "node_modules/sync-request": { "version": "6.1.0", @@ -11191,28 +11601,6 @@ "node": ">=10.0.0" } }, - "node_modules/table/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/table/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -11238,13 +11626,13 @@ } }, "node_modules/terser": { - "version": "5.13.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.13.1.tgz", - "integrity": "sha512-hn4WKOfwnwbYfe48NgrQjqNOH9jzLqRcIfbYytOXCOv46LBfWr9bDS17MQqOi+BWGD0sJK3Sj5NC/gJjiojaoA==", + "version": "5.14.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.14.2.tgz", + "integrity": "sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==", "dependencies": { + "@jridgewell/source-map": "^0.3.2", "acorn": "^8.5.0", "commander": "^2.20.0", - "source-map": "~0.8.0-beta.0", "source-map-support": "~0.5.20" }, "bin": { @@ -11255,14 +11643,14 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.1.tgz", - "integrity": "sha512-GvlZdT6wPQKbDNW/GDQzZFg/j4vKU96yl2q6mcUkzKOgW4gwf1Z8cZToUCrz31XHlPWH8MVb1r2tFtdDtTGJ7g==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.3.tgz", + "integrity": "sha512-Fx60G5HNYknNTNQnzQ1VePRuu89ZVYWfjRAeT5rITuCY/1b08s49e5kSQwHDirKZWuoKOBRFS98EUUoZ9kLEwQ==", "dependencies": { + "@jridgewell/trace-mapping": "^0.3.7", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1", "terser": "^5.7.2" }, "engines": { @@ -11287,6 +11675,29 @@ } } }, + "node_modules/terser-webpack-plugin/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, "node_modules/terser-webpack-plugin/node_modules/jest-worker": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", @@ -11300,6 +11711,11 @@ "node": ">= 10.13.0" } }, + "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, "node_modules/terser-webpack-plugin/node_modules/schema-utils": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", @@ -11336,17 +11752,6 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, - "node_modules/terser/node_modules/source-map": { - "version": "0.8.0-beta.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", - "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", - "dependencies": { - "whatwg-url": "^7.0.0" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/terser/node_modules/source-map-support": { "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", @@ -11356,37 +11761,6 @@ "source-map": "^0.6.0" } }, - "node_modules/terser/node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/terser/node_modules/tr46": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", - "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/terser/node_modules/webidl-conversions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" - }, - "node_modules/terser/node_modules/whatwg-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", - "dependencies": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" - } - }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -11404,7 +11778,7 @@ "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, "node_modules/then-request": { @@ -11435,11 +11809,13 @@ "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", "dev": true }, - "node_modules/throat": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", - "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", - "dev": true + "node_modules/tippy.js": { + "version": "6.3.7", + "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz", + "integrity": "sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==", + "dependencies": { + "@popperjs/core": "^2.9.0" + } }, "node_modules/tmpl": { "version": "1.0.5", @@ -11450,7 +11826,7 @@ "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true, "engines": { "node": ">=4" @@ -11479,7 +11855,7 @@ "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "dev": true }, "node_modules/tributejs": { @@ -11523,7 +11899,7 @@ "node_modules/tsconfig-paths/node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true, "engines": { "node": ">=4" @@ -11570,13 +11946,19 @@ "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", "dev": true }, "node_modules/typo-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/typo-js/-/typo-js-1.2.1.tgz", - "integrity": "sha512-bTGLjbD3WqZDR3CgEFkyi9Q/SS2oM29ipXrWfDb4M74ea69QwKAECVceYpaBu0GfdnASMg9Qfl67ttB23nePHg==" + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/typo-js/-/typo-js-1.2.2.tgz", + "integrity": "sha512-C7pYBQK17EjSg8tVNY91KHdUt5Nf6FMJ+c3js076quPmBML57PmNMzAcIq/2kf/hSYtFABNDIYNYlJRl5BJhGw==" + }, + "node_modules/uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true }, "node_modules/uint8-to-base64": { "version": "0.2.0", @@ -11616,10 +11998,35 @@ "node": ">= 0.8" } }, + "node_modules/update-browserslist-db": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz", + "integrity": "sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist-lint": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, "node_modules/updates": { - "version": "13.0.5", - "resolved": "https://registry.npmjs.org/updates/-/updates-13.0.5.tgz", - "integrity": "sha512-ut7RIiH5Qys7jan4cS9i1Lqk6AAKGmVy1q0udDNJ4YXhvVoUdwQTAk5I9/wkSH6nHQtqhaqytCcZvS6hEJs8xg==", + "version": "13.1.4", + "resolved": "https://registry.npmjs.org/updates/-/updates-13.1.4.tgz", + "integrity": "sha512-s8FKpHpREDoIbd1JDcEvsdf+wenhcQjrZK8v7OTIW69kozPttm6rW84Mm/LFouiDVYgaubY3us7sZlRUiGVx4Q==", "dev": true, "bin": { "updates": "bin/updates.js" @@ -11645,7 +12052,7 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/utility-types": { "version": "3.10.0", @@ -11674,12 +12081,12 @@ "dev": true }, "node_modules/v8-to-istanbul": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.0.tgz", - "integrity": "sha512-HcvgY/xaRm7isYmyx+lFKA4uQmfUbN0J4M0nNItvzTvH/iQ9kW5j/t4YSR+Ge323/lrgDAWJoF46tzGQHwBHFw==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", + "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==", "dev": true, "dependencies": { - "@jridgewell/trace-mapping": "^0.3.7", + "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", "convert-source-map": "^1.6.0" }, @@ -11745,9 +12152,9 @@ } }, "node_modules/vue-eslint-parser": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.0.2.tgz", - "integrity": "sha512-uCPQwTGjOtAYrwnU+76pYxalhjsh7iFBsHwBqDHiOPTxtICDaraO4Szw54WFTNZTAEsgHHzqFOu1mmnBOBRzDA==", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.0.3.tgz", + "integrity": "sha512-yL+ZDb+9T0ELG4VIFo/2anAOz8SvBdlqEnQnvJ3M7Scq56DvtjY0VY88bByRZB0D4J0u8olBcfrXTVONXsh4og==", "dev": true, "dependencies": { "debug": "^4.3.4", @@ -11889,9 +12296,9 @@ } }, "node_modules/watchpack": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz", - "integrity": "sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", + "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -11910,20 +12317,20 @@ } }, "node_modules/webpack": { - "version": "5.72.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.72.1.tgz", - "integrity": "sha512-dXG5zXCLspQR4krZVR6QgajnZOjW2K/djHvdcRaDQvsjV9z9vaW6+ja5dZOYbqBBjF6kGXka/2ZyxNdc+8Jung==", + "version": "5.74.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.74.0.tgz", + "integrity": "sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==", "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^0.0.51", "@webassemblyjs/ast": "1.11.1", "@webassemblyjs/wasm-edit": "1.11.1", "@webassemblyjs/wasm-parser": "1.11.1", - "acorn": "^8.4.1", + "acorn": "^8.7.1", "acorn-import-assertions": "^1.7.6", "browserslist": "^4.14.5", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.9.3", + "enhanced-resolve": "^5.10.0", "es-module-lexer": "^0.9.0", "eslint-scope": "5.1.1", "events": "^3.2.0", @@ -11936,7 +12343,7 @@ "schema-utils": "^3.1.0", "tapable": "^2.1.1", "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.3.1", + "watchpack": "^2.4.0", "webpack-sources": "^3.2.3" }, "bin": { @@ -11956,17 +12363,17 @@ } }, "node_modules/webpack-cli": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.9.2.tgz", - "integrity": "sha512-m3/AACnBBzK/kMTcxWHcZFPrw/eQuY4Df1TxvIWfWM2x7mRqBQCqKEd96oCUa9jkapLBaFfRce33eGDb4Pr7YQ==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.10.0.tgz", + "integrity": "sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==", "dependencies": { "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.1.1", - "@webpack-cli/info": "^1.4.1", - "@webpack-cli/serve": "^1.6.1", + "@webpack-cli/configtest": "^1.2.0", + "@webpack-cli/info": "^1.5.0", + "@webpack-cli/serve": "^1.7.0", "colorette": "^2.0.14", "commander": "^7.0.0", - "execa": "^5.0.0", + "cross-spawn": "^7.0.3", "fastest-levenshtein": "^1.0.12", "import-local": "^3.0.2", "interpret": "^2.2.0", @@ -11979,6 +12386,10 @@ "engines": { "node": ">=10.13.0" }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, "peerDependencies": { "webpack": "4.x.x || 5.x.x" }, @@ -11997,6 +12408,14 @@ } } }, + "node_modules/webpack-cli/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "engines": { + "node": ">= 10" + } + }, "node_modules/webpack-merge": { "version": "5.8.0", "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", @@ -12021,6 +12440,34 @@ "node": ">=10.13.0" } }, + "node_modules/webpack/node_modules/@types/estree": { + "version": "0.0.51", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", + "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==" + }, + "node_modules/webpack/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, "node_modules/webpack/node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -12041,6 +12488,11 @@ "node": ">=4.0" } }, + "node_modules/webpack/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, "node_modules/webpack/node_modules/schema-utils": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", @@ -12090,7 +12542,7 @@ "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "dev": true, "dependencies": { "tr46": "~0.0.3", @@ -12100,7 +12552,7 @@ "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": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", "dev": true }, "node_modules/which": { @@ -12154,24 +12606,24 @@ } }, "node_modules/workbox-core": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.5.3.tgz", - "integrity": "sha512-Bb9ey5n/M9x+l3fBTlLpHt9ASTzgSGj6vxni7pY72ilB/Pb3XtN+cZ9yueboVhD5+9cNQrC9n/E1fSrqWsUz7Q==" + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.5.4.tgz", + "integrity": "sha512-OXYb+m9wZm8GrORlV2vBbE5EC1FKu71GGp0H4rjmxmF4/HLbMCoTFws87M3dFwgpmg0v00K++PImpNQ6J5NQ6Q==" }, "node_modules/workbox-routing": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.5.3.tgz", - "integrity": "sha512-DFjxcuRAJjjt4T34RbMm3MCn+xnd36UT/2RfPRfa8VWJGItGJIn7tG+GwVTdHmvE54i/QmVTJepyAGWtoLPTmg==", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.5.4.tgz", + "integrity": "sha512-apQswLsbrrOsBUWtr9Lf80F+P1sHnQdYodRo32SjiByYi36IDyL2r7BH1lJtFX8fwNHDa1QOVY74WKLLS6o5Pg==", "dependencies": { - "workbox-core": "6.5.3" + "workbox-core": "6.5.4" } }, "node_modules/workbox-strategies": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.5.3.tgz", - "integrity": "sha512-MgmGRrDVXs7rtSCcetZgkSZyMpRGw8HqL2aguszOc3nUmzGZsT238z/NN9ZouCxSzDu3PQ3ZSKmovAacaIhu1w==", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.5.4.tgz", + "integrity": "sha512-DEtsxhx0LIYWkJBTQolRxG4EI0setTJkqR4m7r4YpBdxtWJH1Mbg01Cj8ZjNOO8etqfA3IZaOPHUxCs8cBsKLw==", "dependencies": { - "workbox-core": "6.5.3" + "workbox-core": "6.5.4" } }, "node_modules/worker-loader": { @@ -12193,6 +12645,34 @@ "webpack": "^4.0.0 || ^5.0.0" } }, + "node_modules/worker-loader/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/worker-loader/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/worker-loader/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, "node_modules/worker-loader/node_modules/schema-utils": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", @@ -12286,7 +12766,7 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/write-file-atomic": { "version": "4.0.1", @@ -12329,9 +12809,10 @@ } }, "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true }, "node_modules/yaml": { "version": "1.10.2", @@ -12343,9 +12824,9 @@ } }, "node_modules/yargs": { - "version": "17.5.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz", - "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.3.1.tgz", + "integrity": "sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA==", "dev": true, "dependencies": { "cliui": "^7.0.2", @@ -12377,6 +12858,18 @@ "engines": { "node": ">=12" } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } }, "dependencies": { @@ -12397,36 +12890,36 @@ "dev": true }, "@babel/code-frame": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", - "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", "dev": true, "requires": { - "@babel/highlight": "^7.16.7" + "@babel/highlight": "^7.18.6" } }, "@babel/compat-data": { - "version": "7.17.10", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.10.tgz", - "integrity": "sha512-GZt/TCsG70Ms19gfZO1tM4CVnXsPgEPBCpJu+Qz3L0LUDsY5nZqFZglIoPC1kIYOtNBZlrnFT+klg12vFGZXrw==", + "version": "7.18.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.18.8.tgz", + "integrity": "sha512-HSmX4WZPPK3FUxYp7g2T6EyO8j96HlZJlxmKPSh6KAcqwyDrfx7hKjXpAW/0FhFfTJsR0Yt4lAjLI2coMptIHQ==", "dev": true }, "@babel/core": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.0.tgz", - "integrity": "sha512-Xyw74OlJwDijToNi0+6BBI5mLLR5+5R3bcSH80LXzjzEGEUlvNzujEE71BaD/ApEZHAvFI/Mlmp4M5lIkdeeWw==", + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.10.tgz", + "integrity": "sha512-JQM6k6ENcBFKVtWvLavlvi/mPcpYZ3+R+2EySDEMSMbp7Mn4FexlbbJVrx2R7Ijhr01T8gyqrOaABWIOgxeUyw==", "dev": true, "requires": { "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.18.0", - "@babel/helper-compilation-targets": "^7.17.10", - "@babel/helper-module-transforms": "^7.18.0", - "@babel/helpers": "^7.18.0", - "@babel/parser": "^7.18.0", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.18.0", - "@babel/types": "^7.18.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.18.10", + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-module-transforms": "^7.18.9", + "@babel/helpers": "^7.18.9", + "@babel/parser": "^7.18.10", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.18.10", + "@babel/types": "^7.18.10", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -12443,23 +12936,23 @@ } }, "@babel/generator": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.0.tgz", - "integrity": "sha512-81YO9gGx6voPXlvYdZBliFXAZU8vZ9AZ6z+CjlmcnaeOcYSFbMTpdeDUO9xD9dh/68Vq03I8ZspfUTPfitcDHg==", + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.10.tgz", + "integrity": "sha512-0+sW7e3HjQbiHbj1NeU/vN8ornohYlacAfZIaXhdoGweQqgcNy69COVciYYqEXJ/v+9OBA7Frxm4CVAuNqKeNA==", "dev": true, "requires": { - "@babel/types": "^7.18.0", - "@jridgewell/gen-mapping": "^0.3.0", + "@babel/types": "^7.18.10", + "@jridgewell/gen-mapping": "^0.3.2", "jsesc": "^2.5.1" }, "dependencies": { "@jridgewell/gen-mapping": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.1.tgz", - "integrity": "sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", "dev": true, "requires": { - "@jridgewell/set-array": "^1.0.0", + "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.9" } @@ -12467,13 +12960,13 @@ } }, "@babel/helper-compilation-targets": { - "version": "7.17.10", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.10.tgz", - "integrity": "sha512-gh3RxjWbauw/dFiU/7whjd0qN9K6nPJMqe6+Er7rOavFh0CQUSwhAE3IcTho2rywPJFxej6TUUHDkWcYI6gGqQ==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.9.tgz", + "integrity": "sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg==", "dev": true, "requires": { - "@babel/compat-data": "^7.17.10", - "@babel/helper-validator-option": "^7.16.7", + "@babel/compat-data": "^7.18.8", + "@babel/helper-validator-option": "^7.18.6", "browserslist": "^4.20.2", "semver": "^6.3.0" }, @@ -12487,112 +12980,115 @@ } }, "@babel/helper-environment-visitor": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", - "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" - } + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "dev": true }, "@babel/helper-function-name": { - "version": "7.17.9", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz", - "integrity": "sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz", + "integrity": "sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A==", "dev": true, "requires": { - "@babel/template": "^7.16.7", - "@babel/types": "^7.17.0" + "@babel/template": "^7.18.6", + "@babel/types": "^7.18.9" } }, "@babel/helper-hoist-variables": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", - "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", "dev": true, "requires": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.18.6" } }, "@babel/helper-module-imports": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", - "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", "dev": true, "requires": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.18.6" } }, "@babel/helper-module-transforms": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.18.0.tgz", - "integrity": "sha512-kclUYSUBIjlvnzN2++K9f2qzYKFgjmnmjwL4zlmU5f8ZtzgWe8s0rUPSTGy2HmK4P8T52MQsS+HTQAgZd3dMEA==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.18.9.tgz", + "integrity": "sha512-KYNqY0ICwfv19b31XzvmI/mfcylOzbLtowkw+mfvGPAQ3kfCnMLYbED3YecL5tPd8nAYFQFAd6JHp2LxZk/J1g==", "dev": true, "requires": { - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-simple-access": "^7.17.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/helper-validator-identifier": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.18.0", - "@babel/types": "^7.18.0" + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.18.6", + "@babel/template": "^7.18.6", + "@babel/traverse": "^7.18.9", + "@babel/types": "^7.18.9" } }, "@babel/helper-plugin-utils": { - "version": "7.17.12", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.17.12.tgz", - "integrity": "sha512-JDkf04mqtN3y4iAbO1hv9U2ARpPyPL1zqyWs/2WG1pgSq9llHFjStX5jdxb84himgJm+8Ng+x0oiWF/nw/XQKA==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.18.9.tgz", + "integrity": "sha512-aBXPT3bmtLryXaoJLyYPXPlSD4p1ld9aYeR+sJNOZjJJGiOpb+fKfh3NkcCu7J54nUJwCERPBExCCpyCOHnu/w==", "dev": true }, "@babel/helper-simple-access": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz", - "integrity": "sha512-txyMCGroZ96i+Pxr3Je3lzEJjqwaRC9buMUgtomcrLe5Nd0+fk1h0LLA+ixUF5OW7AhHuQ7Es1WcQJZmZsz2XA==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz", + "integrity": "sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==", "dev": true, "requires": { - "@babel/types": "^7.17.0" + "@babel/types": "^7.18.6" } }, "@babel/helper-split-export-declaration": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", - "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", "dev": true, "requires": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.18.6" } }, + "@babel/helper-string-parser": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz", + "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==", + "dev": true + }, "@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", + "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==", "dev": true }, "@babel/helper-validator-option": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", - "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", "dev": true }, "@babel/helpers": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.18.0.tgz", - "integrity": "sha512-AE+HMYhmlMIbho9nbvicHyxFwhrO+xhKB6AhRxzl8w46Yj0VXTZjEsAoBVC7rB2I0jzX+yWyVybnO08qkfx6kg==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.18.9.tgz", + "integrity": "sha512-Jf5a+rbrLoR4eNdUmnFu8cN5eNJT6qdTdOg5IHIzq87WwyRw9PwguLFOWYgktN/60IP4fgDUawJvs7PjQIzELQ==", "dev": true, "requires": { - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.18.0", - "@babel/types": "^7.18.0" + "@babel/template": "^7.18.6", + "@babel/traverse": "^7.18.9", + "@babel/types": "^7.18.9" } }, "@babel/highlight": { - "version": "7.17.12", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.17.12.tgz", - "integrity": "sha512-7yykMVF3hfZY2jsHZEEgLc+3x4o1O+fYyULu11GynEUQNwB6lua+IIQn1FiJxNucd5UlyJryrwsOh8PL9Sn8Qg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.16.7", + "@babel/helper-validator-identifier": "^7.18.6", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -12629,19 +13125,19 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true }, "supports-color": { @@ -12656,9 +13152,9 @@ } }, "@babel/parser": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.0.tgz", - "integrity": "sha512-AqDccGC+m5O/iUStSJy3DGRIUFu7WbY/CppZYwrEUB4N0tZlnI8CSTsgL7v5fHVFmUbRv2sd+yy27o8Ydt4MGg==", + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.10.tgz", + "integrity": "sha512-TYk3OA0HKL6qNryUayb5UUEhM/rkOQozIBEA5ITXh5DWrSp0TlUQXMyZmnWxG/DizSWBeeQ0Zbc5z8UGaaqoeg==", "dev": true }, "@babel/plugin-syntax-async-generators": { @@ -12770,47 +13266,47 @@ } }, "@babel/plugin-syntax-typescript": { - "version": "7.17.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.17.12.tgz", - "integrity": "sha512-TYY0SXFiO31YXtNg3HtFwNJHjLsAyIIhAhNWkQ5whPPS7HWUFlg9z0Ta4qAQNjQbP1wsSt/oKkmZ/4/WWdMUpw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz", + "integrity": "sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.17.12" + "@babel/helper-plugin-utils": "^7.18.6" } }, "@babel/runtime": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.0.tgz", - "integrity": "sha512-YMQvx/6nKEaucl0MY56mwIG483xk8SDNdlUwb2Ts6FUpr7fm85DxEmsY18LXBNhcTz6tO6JwZV8w1W06v8UKeg==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.9.tgz", + "integrity": "sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==", "requires": { "regenerator-runtime": "^0.13.4" } }, "@babel/template": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", - "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", "dev": true, "requires": { - "@babel/code-frame": "^7.16.7", - "@babel/parser": "^7.16.7", - "@babel/types": "^7.16.7" + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" } }, "@babel/traverse": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.0.tgz", - "integrity": "sha512-oNOO4vaoIQoGjDQ84LgtF/IAlxlyqL4TUuoQ7xLkQETFaHkY1F7yazhB4Kt3VcZGL0ZF/jhrEpnXqUb0M7V3sw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.18.0", - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.17.9", - "@babel/helper-hoist-variables": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.18.0", - "@babel/types": "^7.18.0", + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.10.tgz", + "integrity": "sha512-J7ycxg0/K9XCtLyHf0cz2DqDihonJeIo+z+HEdRe9YuT8TY4A66i+Ab2/xZCEW7Ro60bPCBBfqqboHSamoV3+g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.18.10", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -12824,12 +13320,13 @@ } }, "@babel/types": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.0.tgz", - "integrity": "sha512-vhAmLPAiC8j9K2GnsnLPCIH5wCrPpYIVBCWRBFDCB7Y/BXLqi/O+1RSTTM2bsmg6U/551+FCf9PNPxjABmxHTw==", + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.10.tgz", + "integrity": "sha512-MJvnbEiiNkpjo+LknnmRrqbY1GPUUggjv+wQVjetM/AONoupqRALB7I6jGqNUAZsKcRIEu2J6FRFvsczljjsaQ==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.16.7", + "@babel/helper-string-parser": "^7.18.10", + "@babel/helper-validator-identifier": "^7.18.6", "to-fast-properties": "^2.0.0" } }, @@ -12850,46 +13347,79 @@ "integrity": "sha512-8Ro6D4GCrmOl41+6w4NFhEOpx8vjxwVRI69bulXsFDt49uVRKhLU5TnzEV7AmOJrylkVq+ugnYNMiGHBieeKUQ==", "requires": {} }, + "@csstools/selector-specificity": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz", + "integrity": "sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==", + "dev": true, + "requires": {} + }, "@discoveryjs/json-ext": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==" }, + "@esbuild/linux-loong64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.14.53.tgz", + "integrity": "sha512-W2dAL6Bnyn4xa/QRSU3ilIK4EzD5wgYXKXJiS1HDF5vU3675qc2bvFyLwbUcdmssDveyndy7FbitrCoiV/eMLg==", + "optional": true + }, "@eslint/eslintrc": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.3.tgz", - "integrity": "sha512-uGo44hIwoLGNyduRpjdEpovcbMdd+Nv7amtmJxnKmI8xj6yd5LncmSwDa5NgX/41lIFJtkjD6YdVfgEzPfJ5UA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", + "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^9.3.2", - "globals": "^13.9.0", + "globals": "^13.15.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + } } }, "@happy-dom/jest-environment": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@happy-dom/jest-environment/-/jest-environment-4.0.1.tgz", - "integrity": "sha512-G6hwPF+JlTr4vcJ7xrJYKYrpXPv3ceoGfVX2ZKX9AH7GRQz6Zeq1OWRpEsSezxnwd/bbzsNP6wLakVzWy6jCTQ==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@happy-dom/jest-environment/-/jest-environment-6.0.4.tgz", + "integrity": "sha512-3FEWODVN4H7Hnkbm7IEtRE8lU7uitxSsnVagkQbfjjwKSUfF6BT9MJ95VF7nLimdc5ctOIa7ZbDietRRIpgSHw==", "dev": true, "requires": { "@jest/environment": "^27.5.1", "@jest/fake-timers": "^27.5.1", "@jest/types": "^27.5.1", - "happy-dom": "^4.0.1", + "happy-dom": "^6.0.4", "jest-mock": "^27.5.1", "jest-util": "^27.5.1" } }, "@humanwhocodes/config-array": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", - "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz", + "integrity": "sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==", "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.1", @@ -12897,6 +13427,12 @@ "minimatch": "^3.0.4" } }, + "@humanwhocodes/gitignore-to-minimatch": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", + "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", + "dev": true + }, "@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", @@ -12972,18 +13508,6 @@ "p-limit": "^2.2.0" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, "resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", @@ -12999,26 +13523,26 @@ "dev": true }, "@jest/console": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.0.tgz", - "integrity": "sha512-tscn3dlJFGay47kb4qVruQg/XWlmvU0xp3EJOjzzY+sBaI+YgwKcvAmTcyYU7xEiLLIY5HCdWRooAL8dqkFlDA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.3.tgz", + "integrity": "sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==", "dev": true, "requires": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^28.1.0", - "jest-util": "^28.1.0", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", "slash": "^3.0.0" }, "dependencies": { "@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "requires": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -13036,29 +13560,29 @@ } }, "jest-message-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.0.tgz", - "integrity": "sha512-RpA8mpaJ/B2HphDMiDlrAZdDytkmwFqgjDZovM21F35lHGeUeCvYmm6W+sbQ0ydaLpg5bFAUuWG1cjqOl8vqrw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^28.1.0", + "pretty-format": "^28.1.3", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "requires": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -13069,49 +13593,49 @@ } }, "@jest/core": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-28.1.0.tgz", - "integrity": "sha512-/2PTt0ywhjZ4NwNO4bUqD9IVJfmFVhVKGlhvSpmEfUCuxYf/3NHcKmRFI+I71lYzbTT3wMuYpETDCTHo81gC/g==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-28.1.3.tgz", + "integrity": "sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA==", "dev": true, "requires": { - "@jest/console": "^28.1.0", - "@jest/reporters": "^28.1.0", - "@jest/test-result": "^28.1.0", - "@jest/transform": "^28.1.0", - "@jest/types": "^28.1.0", + "@jest/console": "^28.1.3", + "@jest/reporters": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "ci-info": "^3.2.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", - "jest-changed-files": "^28.0.2", - "jest-config": "^28.1.0", - "jest-haste-map": "^28.1.0", - "jest-message-util": "^28.1.0", + "jest-changed-files": "^28.1.3", + "jest-config": "^28.1.3", + "jest-haste-map": "^28.1.3", + "jest-message-util": "^28.1.3", "jest-regex-util": "^28.0.2", - "jest-resolve": "^28.1.0", - "jest-resolve-dependencies": "^28.1.0", - "jest-runner": "^28.1.0", - "jest-runtime": "^28.1.0", - "jest-snapshot": "^28.1.0", - "jest-util": "^28.1.0", - "jest-validate": "^28.1.0", - "jest-watcher": "^28.1.0", + "jest-resolve": "^28.1.3", + "jest-resolve-dependencies": "^28.1.3", + "jest-runner": "^28.1.3", + "jest-runtime": "^28.1.3", + "jest-snapshot": "^28.1.3", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", + "jest-watcher": "^28.1.3", "micromatch": "^4.0.4", - "pretty-format": "^28.1.0", + "pretty-format": "^28.1.3", "rimraf": "^3.0.0", "slash": "^3.0.0", "strip-ansi": "^6.0.0" }, "dependencies": { "@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "requires": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -13129,29 +13653,29 @@ } }, "jest-message-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.0.tgz", - "integrity": "sha512-RpA8mpaJ/B2HphDMiDlrAZdDytkmwFqgjDZovM21F35lHGeUeCvYmm6W+sbQ0ydaLpg5bFAUuWG1cjqOl8vqrw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^28.1.0", + "pretty-format": "^28.1.3", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "requires": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -13174,19 +13698,19 @@ } }, "@jest/expect": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-28.1.0.tgz", - "integrity": "sha512-be9ETznPLaHOmeJqzYNIXv1ADEzENuQonIoobzThOYPuK/6GhrWNIJDVTgBLCrz3Am73PyEU2urQClZp0hLTtA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-28.1.3.tgz", + "integrity": "sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw==", "dev": true, "requires": { - "expect": "^28.1.0", - "jest-snapshot": "^28.1.0" + "expect": "^28.1.3", + "jest-snapshot": "^28.1.3" } }, "@jest/expect-utils": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-28.1.0.tgz", - "integrity": "sha512-5BrG48dpC0sB80wpeIX5FU6kolDJI4K0n5BM9a5V38MGx0pyRvUBSS0u2aNTdDzmOrCjhOg8pGs6a20ivYkdmw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-28.1.3.tgz", + "integrity": "sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==", "dev": true, "requires": { "jest-get-type": "^28.0.2" @@ -13207,49 +13731,49 @@ } }, "@jest/globals": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-28.1.0.tgz", - "integrity": "sha512-3m7sTg52OTQR6dPhsEQSxAvU+LOBbMivZBwOvKEZ+Rb+GyxVnXi9HKgOTYkx/S99T8yvh17U4tNNJPIEQmtwYw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-28.1.3.tgz", + "integrity": "sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA==", "dev": true, "requires": { - "@jest/environment": "^28.1.0", - "@jest/expect": "^28.1.0", - "@jest/types": "^28.1.0" + "@jest/environment": "^28.1.3", + "@jest/expect": "^28.1.3", + "@jest/types": "^28.1.3" }, "dependencies": { "@jest/environment": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.0.tgz", - "integrity": "sha512-S44WGSxkRngzHslhV6RoAExekfF7Qhwa6R5+IYFa81mpcj0YgdBnRSmvHe3SNwOt64yXaE5GG8Y2xM28ii5ssA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", + "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", "dev": true, "requires": { - "@jest/fake-timers": "^28.1.0", - "@jest/types": "^28.1.0", + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", - "jest-mock": "^28.1.0" + "jest-mock": "^28.1.3" } }, "@jest/fake-timers": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.0.tgz", - "integrity": "sha512-Xqsf/6VLeAAq78+GNPzI7FZQRf5cCHj1qgQxCjws9n8rKw8r1UYoeaALwBvyuzOkpU3c1I6emeMySPa96rxtIg==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", + "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", "dev": true, "requires": { - "@jest/types": "^28.1.0", - "@sinonjs/fake-timers": "^9.1.1", + "@jest/types": "^28.1.3", + "@sinonjs/fake-timers": "^9.1.2", "@types/node": "*", - "jest-message-util": "^28.1.0", - "jest-mock": "^28.1.0", - "jest-util": "^28.1.0" + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" } }, "@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "requires": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -13276,39 +13800,39 @@ } }, "jest-message-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.0.tgz", - "integrity": "sha512-RpA8mpaJ/B2HphDMiDlrAZdDytkmwFqgjDZovM21F35lHGeUeCvYmm6W+sbQ0ydaLpg5bFAUuWG1cjqOl8vqrw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^28.1.0", + "pretty-format": "^28.1.3", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "jest-mock": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.0.tgz", - "integrity": "sha512-H7BrhggNn77WhdL7O1apG0Q/iwl0Bdd5E1ydhCJzL3oBLh/UYxAwR3EJLsBZ9XA3ZU4PA3UNw4tQjduBTCTmLw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", + "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", "dev": true, "requires": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*" } }, "jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "requires": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -13319,17 +13843,17 @@ } }, "@jest/reporters": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-28.1.0.tgz", - "integrity": "sha512-qxbFfqap/5QlSpIizH9c/bFCDKsQlM4uAKSOvZrP+nIdrjqre3FmKzpTtYyhsaVcOSNK7TTt2kjm+4BJIjysFA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-28.1.3.tgz", + "integrity": "sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg==", "dev": true, "requires": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^28.1.0", - "@jest/test-result": "^28.1.0", - "@jest/transform": "^28.1.0", - "@jest/types": "^28.1.0", - "@jridgewell/trace-mapping": "^0.3.7", + "@jest/console": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", + "@jridgewell/trace-mapping": "^0.3.13", "@types/node": "*", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", @@ -13341,22 +13865,23 @@ "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.1.3", - "jest-util": "^28.1.0", - "jest-worker": "^28.1.0", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", + "jest-worker": "^28.1.3", "slash": "^3.0.0", "string-length": "^4.0.1", "strip-ansi": "^6.0.0", "terminal-link": "^2.0.0", - "v8-to-istanbul": "^9.0.0" + "v8-to-istanbul": "^9.0.1" }, "dependencies": { "@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "requires": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -13373,13 +13898,30 @@ "@types/yargs-parser": "*" } }, + "jest-message-util": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^28.1.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^28.1.3", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + } + }, "jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "requires": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -13390,44 +13932,44 @@ } }, "@jest/schemas": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.0.2.tgz", - "integrity": "sha512-YVDJZjd4izeTDkij00vHHAymNXQ6WWsdChFRK86qck6Jpr3DCL5W3Is3vslviRlP+bLuMYRLbdp98amMvqudhA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz", + "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==", "dev": true, "requires": { - "@sinclair/typebox": "^0.23.3" + "@sinclair/typebox": "^0.24.1" } }, "@jest/source-map": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-28.0.2.tgz", - "integrity": "sha512-Y9dxC8ZpN3kImkk0LkK5XCEneYMAXlZ8m5bflmSL5vrwyeUpJfentacCUg6fOb8NOpOO7hz2+l37MV77T6BFPw==", + "version": "28.1.2", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-28.1.2.tgz", + "integrity": "sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww==", "dev": true, "requires": { - "@jridgewell/trace-mapping": "^0.3.7", + "@jridgewell/trace-mapping": "^0.3.13", "callsites": "^3.0.0", "graceful-fs": "^4.2.9" } }, "@jest/test-result": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.0.tgz", - "integrity": "sha512-sBBFIyoPzrZho3N+80P35A5oAkSKlGfsEFfXFWuPGBsW40UAjCkGakZhn4UQK4iQlW2vgCDMRDOob9FGKV8YoQ==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.3.tgz", + "integrity": "sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==", "dev": true, "requires": { - "@jest/console": "^28.1.0", - "@jest/types": "^28.1.0", + "@jest/console": "^28.1.3", + "@jest/types": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, "dependencies": { "@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "requires": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -13447,34 +13989,34 @@ } }, "@jest/test-sequencer": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-28.1.0.tgz", - "integrity": "sha512-tZCEiVWlWNTs/2iK9yi6o3AlMfbbYgV4uuZInSVdzZ7ftpHZhCMuhvk2HLYhCZzLgPFQ9MnM1YaxMnh3TILFiQ==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-28.1.3.tgz", + "integrity": "sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw==", "dev": true, "requires": { - "@jest/test-result": "^28.1.0", + "@jest/test-result": "^28.1.3", "graceful-fs": "^4.2.9", - "jest-haste-map": "^28.1.0", + "jest-haste-map": "^28.1.3", "slash": "^3.0.0" } }, "@jest/transform": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-28.1.0.tgz", - "integrity": "sha512-omy2xe5WxlAfqmsTjTPxw+iXRTRnf+NtX0ToG+4S0tABeb4KsKmPUHq5UBuwunHg3tJRwgEQhEp0M/8oiatLEA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-28.1.3.tgz", + "integrity": "sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA==", "dev": true, "requires": { "@babel/core": "^7.11.6", - "@jest/types": "^28.1.0", - "@jridgewell/trace-mapping": "^0.3.7", + "@jest/types": "^28.1.3", + "@jridgewell/trace-mapping": "^0.3.13", "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^28.1.0", + "jest-haste-map": "^28.1.3", "jest-regex-util": "^28.0.2", - "jest-util": "^28.1.0", + "jest-util": "^28.1.3", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", @@ -13482,12 +14024,12 @@ }, "dependencies": { "@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "requires": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -13505,12 +14047,12 @@ } }, "jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "requires": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -13544,28 +14086,45 @@ } }, "@jridgewell/resolve-uri": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz", - "integrity": "sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA==", - "dev": true + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" }, "@jridgewell/set-array": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.1.tgz", - "integrity": "sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==", - "dev": true + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==" + }, + "@jridgewell/source-map": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", + "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "dependencies": { + "@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + } + } }, "@jridgewell/sourcemap-codec": { - "version": "1.4.13", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz", - "integrity": "sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==", - "dev": true + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" }, "@jridgewell/trace-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz", - "integrity": "sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w==", - "dev": true, + "version": "0.3.14", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz", + "integrity": "sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ==", "requires": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -13608,10 +14167,15 @@ "fastq": "^1.6.0" } }, + "@popperjs/core": { + "version": "2.11.5", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.5.tgz", + "integrity": "sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw==" + }, "@primer/octicons": { - "version": "17.2.0", - "resolved": "https://registry.npmjs.org/@primer/octicons/-/octicons-17.2.0.tgz", - "integrity": "sha512-A3YetVbJX5J4JGa2AfVrEl1lE3FtT+7HdSzphFRs1QF5OgsUpkNbyjvVxeCxVZaG6zXYbbbPWsPF06PtsIyUWQ==", + "version": "17.4.0", + "resolved": "https://registry.npmjs.org/@primer/octicons/-/octicons-17.4.0.tgz", + "integrity": "sha512-fRD9A/JszKOe5mDIU+g1b8jvcPj/qzusxdxnrIrg8Db0mLHsbGc4xNMUtHbRmgFOKaF6/QBR+WnWGQxv4yTcBg==", "requires": { "object-assign": "^4.1.1" } @@ -13642,12 +14206,6 @@ "picomatch": "^2.2.2" }, "dependencies": { - "@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", - "dev": true - }, "estree-walker": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", @@ -13657,9 +14215,9 @@ } }, "@sinclair/typebox": { - "version": "0.23.5", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.23.5.tgz", - "integrity": "sha512-AFBVi/iT4g20DHoujvMH1aEDn8fGJh4xsRGCP6d8RpLPMqsNPvW01Jcn0QysXTsg++/xj25NmJsGyH9xug/wKg==", + "version": "0.24.26", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.26.tgz", + "integrity": "sha512-1ZVIyyS1NXDRVT8GjWD5jULjhDyM3IsIHef2VGUMdnWOlX2tkPjyEX/7K0TGSH2S8EaPhp1ylFdjSjUGQ+gecg==", "dev": true }, "@sinonjs/commons": { @@ -13680,6 +14238,16 @@ "@sinonjs/commons": "^1.7.0" } }, + "@stoplight/better-ajv-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stoplight/better-ajv-errors/-/better-ajv-errors-1.0.1.tgz", + "integrity": "sha512-rgxT+ZMeZbYRiOLNk6Oy6e/Ig1iQKo0IL8v/Y9E/0FewzgtkGs/p5dMeUpIFZXWj3RZaEPmfL9yh0oUEmNXZjg==", + "dev": true, + "requires": { + "jsonpointer": "^5.0.0", + "leven": "^3.1.0" + } + }, "@stoplight/json": { "version": "3.17.0", "resolved": "https://registry.npmjs.org/@stoplight/json/-/json-3.17.0.tgz", @@ -13752,9 +14320,9 @@ "dev": true }, "@stoplight/spectral-cli": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-cli/-/spectral-cli-6.4.1.tgz", - "integrity": "sha512-l5nWXy/6YEyk51VVrOurhupVScIqfK0ra8yIRSli+gnW5Kf5Nfw5PLci5GceQGaM5WE+wmqZ/iY95yOVFwHc+A==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-cli/-/spectral-cli-6.5.0.tgz", + "integrity": "sha512-BmTnQkkhG6E301ADUX7dhQtIIUT/WVRszRHy+90M5Bxk+4kod/6Gi8w7sWuQ5myDls3mLEMjYWUOKaUALuPvug==", "dev": true, "requires": { "@rollup/plugin-commonjs": "^20.0.0", @@ -13803,34 +14371,13 @@ "requires": { "is-glob": "^4.0.1" } - }, - "yargs": { - "version": "17.3.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.3.1.tgz", - "integrity": "sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.0.0" - } - }, - "yargs-parser": { - "version": "21.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", - "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", - "dev": true } } }, "@stoplight/spectral-core": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-core/-/spectral-core-1.12.3.tgz", - "integrity": "sha512-+PhVzTD8q6kUZw4BcbM+ibVaH5/ELryKt5tlLitA8SJIaJ+5/9ZKaGN0AV3ExZQZGYvXwucPOQuJKYZYKA6mWg==", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-core/-/spectral-core-1.13.0.tgz", + "integrity": "sha512-h++UIhdYK6bCZYHCK8byeyOq2tgAUbXdwdR3+Wy1O3PrJERdA9fyL0I3KQ595HylZRo7z1PUoSeyY6FMypWTBQ==", "dev": true, "requires": { "@stoplight/better-ajv-errors": "1.0.1", @@ -13841,11 +14388,13 @@ "@stoplight/spectral-ref-resolver": "^1.0.0", "@stoplight/spectral-runtime": "^1.0.0", "@stoplight/types": "~13.2.0", + "@types/es-aggregate-error": "^1.0.2", "@types/json-schema": "^7.0.11", "ajv": "^8.6.0", "ajv-errors": "~3.0.0", "ajv-formats": "~2.1.0", "blueimp-md5": "2.18.0", + "es-aggregate-error": "^1.0.7", "jsonpath-plus": "6.0.1", "lodash": "~4.17.21", "lodash.topath": "^4.5.2", @@ -13856,16 +14405,6 @@ "tslib": "^2.3.0" }, "dependencies": { - "@stoplight/better-ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@stoplight/better-ajv-errors/-/better-ajv-errors-1.0.1.tgz", - "integrity": "sha512-rgxT+ZMeZbYRiOLNk6Oy6e/Ig1iQKo0IL8v/Y9E/0FewzgtkGs/p5dMeUpIFZXWj3RZaEPmfL9yh0oUEmNXZjg==", - "dev": true, - "requires": { - "jsonpointer": "^5.0.0", - "leven": "^3.1.0" - } - }, "@stoplight/json": { "version": "3.18.1", "resolved": "https://registry.npmjs.org/@stoplight/json/-/json-3.18.1.tgz", @@ -13888,31 +14427,6 @@ "@types/json-schema": "^7.0.4", "utility-types": "^3.10.0" } - }, - "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "ajv-errors": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-3.0.0.tgz", - "integrity": "sha512-V3wD15YHfHz6y0KdhYFjyy9vWtEVALT9UrxfN3zqlI6dMioHnJrqOYfyPKol3oqrnCM9uwkcdCwkJ0WUcbLMTQ==", - "dev": true, - "requires": {} - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true } } }, @@ -13929,9 +14443,9 @@ } }, "@stoplight/spectral-functions": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-functions/-/spectral-functions-1.6.1.tgz", - "integrity": "sha512-f4cFtbI35bQtY0t4fYhKtS+/nMU3UsAeFlqm4tARGGG5WjOv4ieCFNFbgodKNiO3F4O+syMEjVQuXlBNPuY7jw==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-functions/-/spectral-functions-1.7.0.tgz", + "integrity": "sha512-ya3ovvH17QqHeL1o41rEXISJIUegb763Y8yWI01VaLj4zehKOjLzVNKIp1PsUNkG88M5fwB8Lrvjzcd3M8O3iw==", "dev": true, "requires": { "@stoplight/better-ajv-errors": "1.0.1", @@ -13948,16 +14462,6 @@ "tslib": "^2.3.0" }, "dependencies": { - "@stoplight/better-ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@stoplight/better-ajv-errors/-/better-ajv-errors-1.0.1.tgz", - "integrity": "sha512-rgxT+ZMeZbYRiOLNk6Oy6e/Ig1iQKo0IL8v/Y9E/0FewzgtkGs/p5dMeUpIFZXWj3RZaEPmfL9yh0oUEmNXZjg==", - "dev": true, - "requires": { - "jsonpointer": "^5.0.0", - "leven": "^3.1.0" - } - }, "@stoplight/json": { "version": "3.17.2", "resolved": "https://registry.npmjs.org/@stoplight/json/-/json-3.17.2.tgz", @@ -13970,38 +14474,6 @@ "lodash": "^4.17.21", "safe-stable-stringify": "^1.1" } - }, - "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "ajv-draft-04": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", - "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", - "dev": true, - "requires": {} - }, - "ajv-errors": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-3.0.0.tgz", - "integrity": "sha512-V3wD15YHfHz6y0KdhYFjyy9vWtEVALT9UrxfN3zqlI6dMioHnJrqOYfyPKol3oqrnCM9uwkcdCwkJ0WUcbLMTQ==", - "dev": true, - "requires": {} - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true } } }, @@ -14031,12 +14503,12 @@ } }, "@stoplight/spectral-ruleset-bundler": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-ruleset-bundler/-/spectral-ruleset-bundler-1.3.0.tgz", - "integrity": "sha512-6Tif7GQL18F0LN1+FhEmhFWgE/TiWudb/pFl4DC7oS1QRoutB7QJPqIfVFSmteToPidxlrIbC6VAXSyEhlpDVQ==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-ruleset-bundler/-/spectral-ruleset-bundler-1.3.1.tgz", + "integrity": "sha512-TWjLFYBor1s/0v3xXwdVzzyUVu7ez2vYVNN4RMbJG7HIZgYW8MMVx4AVg5Eo1ZgLTkj/aeaoAOjIP7t+u6IBUg==", "dev": true, "requires": { - "@rollup/plugin-commonjs": "^21.0.1", + "@rollup/plugin-commonjs": "~22.0.0", "@stoplight/path": "1.3.2", "@stoplight/spectral-core": ">=1", "@stoplight/spectral-formats": ">=1", @@ -14049,15 +14521,15 @@ "@stoplight/types": "^12.3.0", "@types/node": "*", "pony-cause": "1.1.1", - "rollup": "~2.67.0", + "rollup": "~2.75.5", "tslib": "^2.3.1", "validate-npm-package-name": "3.0.0" }, "dependencies": { "@rollup/plugin-commonjs": { - "version": "21.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-21.1.0.tgz", - "integrity": "sha512-6ZtHx3VHIp2ReNNDxHjuUml6ur+WcQ28N1yHgCQwsbNkQg2suhxGMDQGJOn/KuDxKtd1xuZP5xSTwBA4GQ8hbA==", + "version": "22.0.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-22.0.1.tgz", + "integrity": "sha512-dGfEZvdjDHObBiP5IvwTKMVeq/tBZGMBHZFMdIV1ClMM/YoWS34xrHFGfag9SN2ZtMgNZRFruqvxZQEa70O6nQ==", "dev": true, "requires": { "@rollup/pluginutils": "^3.1.0", @@ -14070,9 +14542,9 @@ } }, "rollup": { - "version": "2.67.3", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.67.3.tgz", - "integrity": "sha512-G/x1vUwbGtP6O5ZM8/sWr8+p7YfZhI18pPqMRtMYMWSbHjKZ/ajHGiM+GWNTlWyOR0EHIdT8LHU+Z4ciIZ1oBw==", + "version": "2.75.7", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.75.7.tgz", + "integrity": "sha512-VSE1iy0eaAYNCxEXaleThdFXqZJ42qDBatAwrfnPlENEZ8erQ+0LYX4JXOLPceWfZpV1VtZwZ3dFCuOZiSyFtQ==", "dev": true, "requires": { "fsevents": "~2.3.2" @@ -14107,31 +14579,13 @@ "resolved": "https://registry.npmjs.org/@stoplight/ordered-object-literal/-/ordered-object-literal-1.0.2.tgz", "integrity": "sha512-0ZMS/9sNU3kVo/6RF3eAv7MK9DY8WLjiVJB/tVyfF2lhr2R4kqh534jZ0PlrFB9CRXrdndzn1DbX6ihKZXft2w==", "dev": true - }, - "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true } } }, "@stoplight/spectral-rulesets": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-rulesets/-/spectral-rulesets-1.11.0.tgz", - "integrity": "sha512-0zFbxIuoWmGrkl2txOuaEDF8o6aoKDpMAYOG2oDfmmX9FhXX3c3ivIy80hyb2tMKkIYuqqx/zwIiOuww5S8iUA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-rulesets/-/spectral-rulesets-1.11.1.tgz", + "integrity": "sha512-0MDr5MW000FIZ3C47YY2Cg4NzU6wJFvvpSl1QRijRzdAVqQ1DgD3FgRDKHTA6OO7BmgWdCQYKSI8KwOH1Ju3kw==", "dev": true, "requires": { "@asyncapi/specs": "^2.14.0", @@ -14150,16 +14604,6 @@ "tslib": "^2.3.0" }, "dependencies": { - "@stoplight/better-ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@stoplight/better-ajv-errors/-/better-ajv-errors-1.0.1.tgz", - "integrity": "sha512-rgxT+ZMeZbYRiOLNk6Oy6e/Ig1iQKo0IL8v/Y9E/0FewzgtkGs/p5dMeUpIFZXWj3RZaEPmfL9yh0oUEmNXZjg==", - "dev": true, - "requires": { - "jsonpointer": "^5.0.0", - "leven": "^3.1.0" - } - }, "@stoplight/types": { "version": "12.5.0", "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-12.5.0.tgz", @@ -14169,24 +14613,6 @@ "@types/json-schema": "^7.0.4", "utility-types": "^3.10.0" } - }, - "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true } } }, @@ -14308,28 +14734,37 @@ "@types/node": "*" } }, + "@types/es-aggregate-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/es-aggregate-error/-/es-aggregate-error-1.0.2.tgz", + "integrity": "sha512-erqUpFXksaeR2kejKnhnjZjbFxUpGZx4Z7ydNL9ie8tEhXPiZTsLeUDJ6aR1F8j5wWUAtOAQWUqkc7givBJbBA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/eslint": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.2.tgz", - "integrity": "sha512-Z1nseZON+GEnFjJc04sv4NSALGjhFwy6K0HXt7qsn5ArfAKtb63dXNJHf+1YW6IpOIYRBGUbu3GwJdj8DGnCjA==", + "version": "8.4.5", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.5.tgz", + "integrity": "sha512-dhsC09y1gpJWnK+Ff4SGvCuSnk9DaU0BJZSzOwa6GVSg65XtTugLBITDAAzRU5duGBoXBHpdR/9jHGxJjNflJQ==", "requires": { "@types/estree": "*", "@types/json-schema": "*" } }, "@types/eslint-scope": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.3.tgz", - "integrity": "sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g==", + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", + "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", "requires": { "@types/eslint": "*", "@types/estree": "*" } }, "@types/estree": { - "version": "0.0.51", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", - "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==" + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" }, "@types/form-data": { "version": "0.0.33", @@ -14396,9 +14831,9 @@ "dev": true }, "@types/node": { - "version": "17.0.35", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.35.tgz", - "integrity": "sha512-vu1SrqBjbbZ3J6vwY17jBs8Sr/BKA+/a/WtjRG+whKg1iuLFOosq872EXS0eXWILdO36DHQQeku/ZcL6hz2fpg==" + "version": "18.6.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.6.3.tgz", + "integrity": "sha512-6qKpDtoaYLM+5+AFChLhHermMQxc3TOEFIDzrZLPRGHPrLEwqFkkT5Kx3ju05g6X7uDPazz3jHbKPX0KzCjntg==" }, "@types/normalize-package-data": { "version": "2.4.1", @@ -14413,9 +14848,9 @@ "dev": true }, "@types/prettier": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.1.tgz", - "integrity": "sha512-XFjFHmaLVifrAKaZ+EKghFHtHSUonyw8P2Qmy2/+osBnrKbH9UYtlK10zg8/kCt47MFilll/DEDKy3DHfJ0URw==", + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.4.tgz", + "integrity": "sha512-fOwvpvQYStpb/zHMx0Cauwywu9yLDmzWiiQBC7gJyq5tYLUXFZvDG7VK1B7WBxxjBJNKFOZ0zLoOQn8vmATbhw==", "dev": true }, "@types/qs": { @@ -14501,7 +14936,7 @@ "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" } } }, @@ -14637,23 +15072,23 @@ } }, "@webpack-cli/configtest": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.1.1.tgz", - "integrity": "sha512-1FBc1f9G4P/AxMqIgfZgeOTuRnwZMten8E7zap5zgpPInnCrP8D4Q81+4CWIch8i/Nf7nXjP0v6CjjbHOrXhKg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz", + "integrity": "sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==", "requires": {} }, "@webpack-cli/info": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.4.1.tgz", - "integrity": "sha512-PKVGmazEq3oAo46Q63tpMr4HipI3OPfP7LiNOEJg963RMgT0rqheag28NCML0o3GIzA3DmxP1ZIAv9oTX1CUIA==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.5.0.tgz", + "integrity": "sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==", "requires": { "envinfo": "^7.7.3" } }, "@webpack-cli/serve": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.6.1.tgz", - "integrity": "sha512-gNGTiTrjEVQ0OcVnzsRSqTxaBSr+dmTfm+qJsCDluky8uhdLWep7Gcr62QsAKHTMxjCS/8nEITsmFAhfIx+QSw==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz", + "integrity": "sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==", "requires": {} }, "@xtuc/ieee754": { @@ -14676,9 +15111,9 @@ } }, "acorn": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==" + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==" }, "acorn-import-assertions": { "version": "1.8.0", @@ -14715,47 +15150,45 @@ } }, "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", "requires": { "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", "uri-js": "^4.2.2" } }, + "ajv-draft-04": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", + "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", + "dev": true, + "requires": {} + }, + "ajv-errors": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-3.0.0.tgz", + "integrity": "sha512-V3wD15YHfHz6y0KdhYFjyy9vWtEVALT9UrxfN3zqlI6dMioHnJrqOYfyPKol3oqrnCM9uwkcdCwkJ0WUcbLMTQ==", + "dev": true, + "requires": {} + }, "ajv-formats": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", "requires": { "ajv": "^8.0.0" - }, - "dependencies": { - "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - } } }, "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "requires": {} + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "requires": { + "fast-deep-equal": "^3.1.3" + } }, "ansi-escapes": { "version": "4.3.2", @@ -14888,15 +15321,15 @@ "dev": true }, "babel-jest": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.0.tgz", - "integrity": "sha512-zNKk0yhDZ6QUwfxh9k07GII6siNGMJWVUU49gmFj5gfdqDKLqa2RArXOF2CODp4Dr7dLxN2cvAV+667dGJ4b4w==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.3.tgz", + "integrity": "sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q==", "dev": true, "requires": { - "@jest/transform": "^28.1.0", + "@jest/transform": "^28.1.3", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^28.0.2", + "babel-preset-jest": "^28.1.3", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "slash": "^3.0.0" @@ -14916,9 +15349,9 @@ } }, "babel-plugin-jest-hoist": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.0.2.tgz", - "integrity": "sha512-Kizhn/ZL+68ZQHxSnHyuvJv8IchXD62KQxV77TBDV/xoBFBOfgRAk97GNs6hXdTTCiVES9nB2I6+7MXXrk5llQ==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz", + "integrity": "sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q==", "dev": true, "requires": { "@babel/template": "^7.3.3", @@ -14948,12 +15381,12 @@ } }, "babel-preset-jest": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-28.0.2.tgz", - "integrity": "sha512-sYzXIdgIXXroJTFeB3S6sNDWtlJ2dllCdTEsnZ65ACrMojj3hVNFRmnJ1HZtomGi+Be7aqpY/HJ92fr8OhKVkQ==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz", + "integrity": "sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A==", "dev": true, "requires": { - "babel-plugin-jest-hoist": "^28.0.2", + "babel-plugin-jest-hoist": "^28.1.3", "babel-preset-current-node-syntax": "^1.0.0" } }, @@ -15002,15 +15435,14 @@ } }, "browserslist": { - "version": "4.20.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.3.tgz", - "integrity": "sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz", + "integrity": "sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==", "requires": { - "caniuse-lite": "^1.0.30001332", - "electron-to-chromium": "^1.4.118", - "escalade": "^3.1.1", - "node-releases": "^2.0.3", - "picocolors": "^1.0.0" + "caniuse-lite": "^1.0.30001370", + "electron-to-chromium": "^1.4.202", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.5" } }, "bser": { @@ -15079,9 +15511,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001341", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001341.tgz", - "integrity": "sha512-2SodVrFFtvGENGCv0ChVJIDQ0KPaS1cg7/qtfMaICgeMolDdo/Z2OD32F0Aq9yl6F4YFwGPBS5AaPqNYiW4PoA==" + "version": "1.0.30001373", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001373.tgz", + "integrity": "sha512-pJYArGHrPp3TUqQzFYRmP/lwJlj8RCbVe3Gd3eJQkAV8SAC6b19XS9BjMvRdvaS8RMkaTN8ZhoHP6S1y8zzwEQ==" }, "caseless": { "version": "0.12.0", @@ -15111,9 +15543,9 @@ "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==" }, "ci-info": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.1.tgz", - "integrity": "sha512-SXgeMX9VwDe7iFFaEWkA5AstuER9YKqy4EhHqr4DVqkwmD9rpVimkMKWHdjn30Ja45txyjhSn63lVX69eVCckg==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.2.tgz", + "integrity": "sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg==", "dev": true }, "cjs-module-lexer": { @@ -15134,7 +15566,7 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true } } @@ -15195,18 +15627,18 @@ "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "dev": true }, "codemirror": { - "version": "5.65.4", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.4.tgz", - "integrity": "sha512-tytrSm5Rh52b6j36cbDXN+FHwHCl9aroY4BrDZB2NFFL3Wjfq9nuYVLFFhaOYOczKAg3JXTr8BuT8LcE5QY4Iw==" + "version": "5.65.7", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.7.tgz", + "integrity": "sha512-zb67cXzgugIQmb6tfD4G11ILjYoMfTjwcjn+cWsa4GewlI2adhR/h3kolkoCQTm1msD/1BuqVTKuO09ELsS++A==" }, "codemirror-spell-checker": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/codemirror-spell-checker/-/codemirror-spell-checker-1.1.2.tgz", - "integrity": "sha1-HGYPkIlIPMtRE7m6nKGcP0mTNx4=", + "integrity": "sha512-2Tl6n0v+GJRsC9K3MLCdLaMOmvWL0uukajNJseorZJsslaxZyZMgENocPU8R0DyoTAiKsyqiemSOZo7kjGV0LQ==", "requires": { "typo-js": "*" } @@ -15237,9 +15669,9 @@ "dev": true }, "colorette": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", - "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==" + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==" }, "combined-stream": { "version": "1.0.8", @@ -15251,9 +15683,10 @@ } }, "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.0.tgz", + "integrity": "sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw==", + "dev": true }, "commondir": { "version": "1.0.1", @@ -15264,7 +15697,7 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "concat-stream": { "version": "1.6.2", @@ -15276,6 +15709,38 @@ "inherits": "^2.0.3", "readable-stream": "^2.2.2", "typedarray": "^0.0.6" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } } }, "consolidate": { @@ -15333,9 +15798,9 @@ } }, "css-functions-list": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.0.1.tgz", - "integrity": "sha512-PriDuifDt4u4rkDgnqRCLnjfMatufLmWNfQnGCq34xZwpY3oabwhB9SqRBmuvWUgndbemCFlKqg+nO7C2q0SBw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.1.0.tgz", + "integrity": "sha512-/9lCvYZaUbBGvYUgYGFJ4dcYiyqdhSjG7IPVluoV8A1ILjkF7ilmhp1OGUz8n+nmBcu0RNrQAzgD8B6FJbrt2w==", "dev": true }, "css-loader": { @@ -15385,7 +15850,7 @@ "css.escape": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", - "integrity": "sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s=", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", "dev": true }, "cssesc": { @@ -15403,16 +15868,16 @@ } }, "d3": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/d3/-/d3-7.4.4.tgz", - "integrity": "sha512-97FE+MYdAlV3R9P74+R3Uar7wUKkIFu89UWMjEaDhiJ9VxKvqaMxauImy8PC2DdBkdM2BxJOIoLxPrcZUyrKoQ==", + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/d3/-/d3-7.6.1.tgz", + "integrity": "sha512-txMTdIHFbcpLx+8a0IFhZsbp+PfBBPt8yfbmukZTQFroKuFqIwqswF0qE5JXWefylaAVpSXFoKm3yP+jpNLFLw==", "requires": { "d3-array": "3", "d3-axis": "3", "d3-brush": "3", "d3-chord": "3", "d3-color": "3", - "d3-contour": "3", + "d3-contour": "4", "d3-delaunay": "6", "d3-dispatch": "3", "d3-drag": "3", @@ -15440,9 +15905,9 @@ } }, "d3-array": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.1.6.tgz", - "integrity": "sha512-DCbBBNuKOeiR9h04ySRBMW52TFVc91O9wJziuyXw6Ztmy8D3oZbmCkOO3UHKC7ceNJsN2Mavo9+vwV8EAEUXzA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.0.tgz", + "integrity": "sha512-3yXFQo0oG3QCxbF06rMPFyGRMGJNS7NvsV1+2joOjbBE+9xvWQ8+GcMJAjRCzw06zQ3/arXeJgbPYcjUCuC+3g==", "requires": { "internmap": "1 - 2" } @@ -15483,11 +15948,11 @@ "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==" }, "d3-contour": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-3.0.1.tgz", - "integrity": "sha512-0Oc4D0KyhwhM7ZL0RMnfGycLN7hxHB8CMmwZ3+H26PWAG0ozNuYG5hXSDNgmP1SgJkQMrlG6cP20HoaSbvcJTQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.0.tgz", + "integrity": "sha512-7aQo0QHUTu/Ko3cP9YK9yUTxtoDEiDGwnBHyLxG5M4vqlBkO/uixMRele3nfsfj6UXOcuReVpVXzAboGraYIJw==", "requires": { - "d3-array": "2 - 3" + "d3-array": "^3.2.0" } }, "d3-delaunay": { @@ -15520,6 +15985,13 @@ "commander": "7", "iconv-lite": "0.6", "rw": "1" + }, + "dependencies": { + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" + } } }, "d3-ease": { @@ -15973,7 +16445,7 @@ "de-indent": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", - "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=" + "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==" }, "debug": { "version": "4.3.4", @@ -15987,13 +16459,13 @@ "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "dev": true }, "decamelize-keys": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", - "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "integrity": "sha512-ocLWuYzRPoS9bfiSdDd3cxvrzovVMZnRDVEzAs+hWIVXGDbHxWMECij2OBuyB/An0FFW/nLuq6Kv1i/YC5Qfzg==", "dev": true, "requires": { "decamelize": "^1.1.0", @@ -16003,7 +16475,7 @@ "map-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", "dev": true } } @@ -16011,7 +16483,13 @@ "dedent": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", + "dev": true + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "dev": true }, "deep-is": { @@ -16070,7 +16548,7 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true }, "depd": { @@ -16092,9 +16570,9 @@ "dev": true }, "diff-sequences": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", - "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", + "version": "28.1.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.1.1.tgz", + "integrity": "sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==", "dev": true }, "dir-glob": { @@ -16192,9 +16670,9 @@ } }, "electron-to-chromium": { - "version": "1.4.137", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.137.tgz", - "integrity": "sha512-0Rcpald12O11BUogJagX3HsCN3FE83DSqWjgXoHo5a72KUKMSfI39XBgJpgNNxS9fuGzytaFjE06kZkiVFy2qA==" + "version": "1.4.210", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.210.tgz", + "integrity": "sha512-kSiX4tuyZijV7Cz0MWVmGT8K2siqaOA4Z66K5dCttPPRh0HicOcOAEj1KlC8O8J1aOS/1M8rGofOzksLKaHWcQ==" }, "emittery": { "version": "0.10.2", @@ -16213,9 +16691,9 @@ "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" }, "enhanced-resolve": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.9.3.tgz", - "integrity": "sha512-Bq9VSor+kjvW3f9/MiiR4eE3XYgOl7/rS8lnSxbRbF3kS0B2r+Y9w5krBWxZgDxASVZbdYrn5wT4j/Wb0J9qow==", + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", + "integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==", "requires": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -16287,6 +16765,21 @@ "unbox-primitive": "^1.0.2" } }, + "es-aggregate-error": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/es-aggregate-error/-/es-aggregate-error-1.0.8.tgz", + "integrity": "sha512-AKUb5MKLWMozPlFRHOKqWD7yta5uaEhH21qwtnf6FlKjNjTJOoqFi0/G14+FfSkIQhhu6X68Af4xgRC6y8qG4A==", + "dev": true, + "requires": { + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5", + "function-bind": "^1.1.1", + "functions-have-names": "^1.2.3", + "get-intrinsic": "^1.1.1", + "globalthis": "^1.0.2", + "has-property-descriptors": "^1.0.0" + } + }, "es-module-lexer": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", @@ -16313,36 +16806,115 @@ } }, "esbuild": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.39.tgz", - "integrity": "sha512-2kKujuzvRWYtwvNjYDY444LQIA3TyJhJIX3Yo4+qkFlDDtGlSicWgeHVJqMUP/2sSfH10PGwfsj+O2ro1m10xQ==", - "requires": { - "esbuild-android-64": "0.14.39", - "esbuild-android-arm64": "0.14.39", - "esbuild-darwin-64": "0.14.39", - "esbuild-darwin-arm64": "0.14.39", - "esbuild-freebsd-64": "0.14.39", - "esbuild-freebsd-arm64": "0.14.39", - "esbuild-linux-32": "0.14.39", - "esbuild-linux-64": "0.14.39", - "esbuild-linux-arm": "0.14.39", - "esbuild-linux-arm64": "0.14.39", - "esbuild-linux-mips64le": "0.14.39", - "esbuild-linux-ppc64le": "0.14.39", - "esbuild-linux-riscv64": "0.14.39", - "esbuild-linux-s390x": "0.14.39", - "esbuild-netbsd-64": "0.14.39", - "esbuild-openbsd-64": "0.14.39", - "esbuild-sunos-64": "0.14.39", - "esbuild-windows-32": "0.14.39", - "esbuild-windows-64": "0.14.39", - "esbuild-windows-arm64": "0.14.39" - } + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.53.tgz", + "integrity": "sha512-ohO33pUBQ64q6mmheX1mZ8mIXj8ivQY/L4oVuAshr+aJI+zLl+amrp3EodrUNDNYVrKJXGPfIHFGhO8slGRjuw==", + "requires": { + "@esbuild/linux-loong64": "0.14.53", + "esbuild-android-64": "0.14.53", + "esbuild-android-arm64": "0.14.53", + "esbuild-darwin-64": "0.14.53", + "esbuild-darwin-arm64": "0.14.53", + "esbuild-freebsd-64": "0.14.53", + "esbuild-freebsd-arm64": "0.14.53", + "esbuild-linux-32": "0.14.53", + "esbuild-linux-64": "0.14.53", + "esbuild-linux-arm": "0.14.53", + "esbuild-linux-arm64": "0.14.53", + "esbuild-linux-mips64le": "0.14.53", + "esbuild-linux-ppc64le": "0.14.53", + "esbuild-linux-riscv64": "0.14.53", + "esbuild-linux-s390x": "0.14.53", + "esbuild-netbsd-64": "0.14.53", + "esbuild-openbsd-64": "0.14.53", + "esbuild-sunos-64": "0.14.53", + "esbuild-windows-32": "0.14.53", + "esbuild-windows-64": "0.14.53", + "esbuild-windows-arm64": "0.14.53" + } + }, + "esbuild-android-64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.53.tgz", + "integrity": "sha512-fIL93sOTnEU+NrTAVMIKiAw0YH22HWCAgg4N4Z6zov2t0kY9RAJ50zY9ZMCQ+RT6bnOfDt8gCTnt/RaSNA2yRA==", + "optional": true + }, + "esbuild-android-arm64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.53.tgz", + "integrity": "sha512-PC7KaF1v0h/nWpvlU1UMN7dzB54cBH8qSsm7S9mkwFA1BXpaEOufCg8hdoEI1jep0KeO/rjZVWrsH8+q28T77A==", + "optional": true }, "esbuild-darwin-64": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.39.tgz", - "integrity": "sha512-ImT6eUw3kcGcHoUxEcdBpi6LfTRWaV6+qf32iYYAfwOeV+XaQ/Xp5XQIBiijLeo+LpGci9M0FVec09nUw41a5g==", + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.53.tgz", + "integrity": "sha512-gE7P5wlnkX4d4PKvLBUgmhZXvL7lzGRLri17/+CmmCzfncIgq8lOBvxGMiQ4xazplhxq+72TEohyFMZLFxuWvg==", + "optional": true + }, + "esbuild-darwin-arm64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.53.tgz", + "integrity": "sha512-otJwDU3hnI15Q98PX4MJbknSZ/WSR1I45il7gcxcECXzfN4Mrpft5hBDHXNRnCh+5858uPXBXA1Vaz2jVWLaIA==", + "optional": true + }, + "esbuild-freebsd-64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.53.tgz", + "integrity": "sha512-WkdJa8iyrGHyKiPF4lk0MiOF87Q2SkE+i+8D4Cazq3/iqmGPJ6u49je300MFi5I2eUsQCkaOWhpCVQMTKGww2w==", + "optional": true + }, + "esbuild-freebsd-arm64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.53.tgz", + "integrity": "sha512-9T7WwCuV30NAx0SyQpw8edbKvbKELnnm1FHg7gbSYaatH+c8WJW10g/OdM7JYnv7qkimw2ZTtSA+NokOLd2ydQ==", + "optional": true + }, + "esbuild-linux-32": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.53.tgz", + "integrity": "sha512-VGanLBg5en2LfGDgLEUxQko2lqsOS7MTEWUi8x91YmsHNyzJVT/WApbFFx3MQGhkf+XdimVhpyo5/G0PBY91zg==", + "optional": true + }, + "esbuild-linux-64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.53.tgz", + "integrity": "sha512-pP/FA55j/fzAV7N9DF31meAyjOH6Bjuo3aSKPh26+RW85ZEtbJv9nhoxmGTd9FOqjx59Tc1ZbrJabuiXlMwuZQ==", + "optional": true + }, + "esbuild-linux-arm": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.53.tgz", + "integrity": "sha512-/u81NGAVZMopbmzd21Nu/wvnKQK3pT4CrvQ8BTje1STXcQAGnfyKgQlj3m0j2BzYbvQxSy+TMck4TNV2onvoPA==", + "optional": true + }, + "esbuild-linux-arm64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.53.tgz", + "integrity": "sha512-GDmWITT+PMsjCA6/lByYk7NyFssW4Q6in32iPkpjZ/ytSyH+xeEx8q7HG3AhWH6heemEYEWpTll/eui3jwlSnw==", + "optional": true + }, + "esbuild-linux-mips64le": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.53.tgz", + "integrity": "sha512-d6/XHIQW714gSSp6tOOX2UscedVobELvQlPMkInhx1NPz4ThZI9uNLQ4qQJHGBGKGfu+rtJsxM4NVHLhnNRdWQ==", + "optional": true + }, + "esbuild-linux-ppc64le": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.53.tgz", + "integrity": "sha512-ndnJmniKPCB52m+r6BtHHLAOXw+xBCWIxNnedbIpuREOcbSU/AlyM/2dA3BmUQhsHdb4w3amD5U2s91TJ3MzzA==", + "optional": true + }, + "esbuild-linux-riscv64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.53.tgz", + "integrity": "sha512-yG2sVH+QSix6ct4lIzJj329iJF3MhloLE6/vKMQAAd26UVPVkhMFqFopY+9kCgYsdeWvXdPgmyOuKa48Y7+/EQ==", + "optional": true + }, + "esbuild-linux-s390x": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.53.tgz", + "integrity": "sha512-OCJlgdkB+XPYndHmw6uZT7jcYgzmx9K+28PVdOa/eLjdoYkeAFvH5hTwX4AXGLZLH09tpl4bVsEtvuyUldaNCg==", "optional": true }, "esbuild-loader": { @@ -16358,6 +16930,42 @@ "webpack-sources": "^2.2.0" } }, + "esbuild-netbsd-64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.53.tgz", + "integrity": "sha512-gp2SB+Efc7MhMdWV2+pmIs/Ja/Mi5rjw+wlDmmbIn68VGXBleNgiEZG+eV2SRS0kJEUyHNedDtwRIMzaohWedQ==", + "optional": true + }, + "esbuild-openbsd-64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.53.tgz", + "integrity": "sha512-eKQ30ZWe+WTZmteDYg8S+YjHV5s4iTxeSGhJKJajFfQx9TLZJvsJX0/paqwP51GicOUruFpSUAs2NCc0a4ivQQ==", + "optional": true + }, + "esbuild-sunos-64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.53.tgz", + "integrity": "sha512-OWLpS7a2FrIRukQqcgQqR1XKn0jSJoOdT+RlhAxUoEQM/IpytS3FXzCJM6xjUYtpO5GMY0EdZJp+ur2pYdm39g==", + "optional": true + }, + "esbuild-windows-32": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.53.tgz", + "integrity": "sha512-m14XyWQP5rwGW0tbEfp95U6A0wY0DYPInWBB7D69FAXUpBpBObRoGTKRv36lf2RWOdE4YO3TNvj37zhXjVL5xg==", + "optional": true + }, + "esbuild-windows-64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.53.tgz", + "integrity": "sha512-s9skQFF0I7zqnQ2K8S1xdLSfZFsPLuOGmSx57h2btSEswv0N0YodYvqLcJMrNMXh6EynOmWD7rz+0rWWbFpIHQ==", + "optional": true + }, + "esbuild-windows-arm64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.53.tgz", + "integrity": "sha512-E+5Gvb+ZWts+00T9II6wp2L3KG2r3iGxByqd/a1RmLmYWVsSVUjkvIxZuJ3hYTIbhLkH5PRwpldGTKYqVz0nzQ==", + "optional": true + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -16435,13 +17043,14 @@ } }, "eslint": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.15.0.tgz", - "integrity": "sha512-GG5USZ1jhCu8HJkzGgeK8/+RGnHaNYZGrGDzUtigK3BsGESW/rs2az23XqE0WVwDxy1VRvvjSSGu5nB0Bu+6SA==", + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.21.0.tgz", + "integrity": "sha512-/XJ1+Qurf1T9G2M5IHrsjp+xrGT73RZf23xA1z5wB1ZzzEAWSZKvRwhWxTFp1rvkvCfwcvAUNAP31bhKTTGfDA==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.2.3", - "@humanwhocodes/config-array": "^0.9.2", + "@eslint/eslintrc": "^1.3.0", + "@humanwhocodes/config-array": "^0.10.4", + "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -16451,14 +17060,17 @@ "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.2", + "espree": "^9.3.3", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", "functional-red-black-tree": "^1.0.1", "glob-parent": "^6.0.1", - "globals": "^13.6.0", + "globals": "^13.15.0", + "globby": "^11.1.0", + "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", @@ -16475,6 +17087,26 @@ "strip-json-comments": "^3.1.0", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + } } }, "eslint-import-resolver-node": { @@ -16516,18 +17148,58 @@ "requires": { "ms": "^2.1.1" } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true } } }, - "eslint-plugin-html": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-6.2.0.tgz", - "integrity": "sha512-vi3NW0E8AJombTvt8beMwkL1R/fdRWl4QSNRNMhVQKWm36/X0KF0unGNAY4mqUF06mnwVWZcIcerrCnfn9025g==", - "dev": true, - "requires": { - "htmlparser2": "^7.1.2" - } - }, "eslint-plugin-import": { "version": "2.26.0", "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", @@ -16570,7 +17242,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true } } @@ -16582,14 +17254,21 @@ "dev": true, "requires": {} }, + "eslint-plugin-sonarjs": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.14.0.tgz", + "integrity": "sha512-0X0q3fB8ghppms19cR2oIK2ajoFp7DEy3AVGDqO7WX02r1aWOzkrHa+veatGZw+R7amgBvfcF0qHCG66p9Zoag==", + "dev": true, + "requires": {} + }, "eslint-plugin-unicorn": { - "version": "42.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-42.0.0.tgz", - "integrity": "sha512-ixBsbhgWuxVaNlPTT8AyfJMlhyC5flCJFjyK3oKE8TRrwBnaHvUbuIkCM1lqg8ryYrFStL/T557zfKzX4GKSlg==", + "version": "43.0.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-43.0.2.tgz", + "integrity": "sha512-DtqZ5mf/GMlfWoz1abIjq5jZfaFuHzGBZYIeuJfEoKKGWRHr2JiJR+ea+BF7Wx2N1PPRoT/2fwgiK1NnmNE3Hg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.15.7", - "ci-info": "^3.3.0", + "@babel/helper-validator-identifier": "^7.18.6", + "ci-info": "^3.3.2", "clean-regexp": "^1.0.0", "eslint-utils": "^3.0.0", "esquery": "^1.4.0", @@ -16600,14 +17279,14 @@ "read-pkg-up": "^7.0.1", "regexp-tree": "^0.1.24", "safe-regex": "^2.1.1", - "semver": "^7.3.5", + "semver": "^7.3.7", "strip-indent": "^3.0.0" } }, "eslint-plugin-vue": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.0.1.tgz", - "integrity": "sha512-/w/9/vzz+4bSYtp5UqXgJ0CfycXTMtpp6lkz7/fMp0CcJxPWyRP6Pr88ihhrsNEcVt2ZweMupWRNYa+5Md41LQ==", + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.3.0.tgz", + "integrity": "sha512-iscKKkBZgm6fGZwFt6poRoWC0Wy2dQOlwUPW++CiPoQiw1enctV2Hj5DBzzjJZfyqs+FAXhgzL4q0Ww03AgSmQ==", "dev": true, "requires": { "eslint-utils": "^3.0.0", @@ -16653,12 +17332,12 @@ "dev": true }, "espree": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", - "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", + "version": "9.3.3", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.3.tgz", + "integrity": "sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng==", "dev": true, "requires": { - "acorn": "^8.7.1", + "acorn": "^8.8.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.3.0" } @@ -16718,6 +17397,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, "requires": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", @@ -16742,29 +17422,29 @@ "exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", "dev": true }, "expect": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-28.1.0.tgz", - "integrity": "sha512-qFXKl8Pmxk8TBGfaFKRtcQjfXEnKAs+dmlxdwvukJZorwrAabT7M3h8oLOG01I2utEhkmUTi17CHaPBovZsKdw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/expect/-/expect-28.1.3.tgz", + "integrity": "sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g==", "dev": true, "requires": { - "@jest/expect-utils": "^28.1.0", + "@jest/expect-utils": "^28.1.3", "jest-get-type": "^28.0.2", - "jest-matcher-utils": "^28.1.0", - "jest-message-util": "^28.1.0", - "jest-util": "^28.1.0" + "jest-matcher-utils": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3" }, "dependencies": { "@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "requires": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -16782,29 +17462,29 @@ } }, "jest-message-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.0.tgz", - "integrity": "sha512-RpA8mpaJ/B2HphDMiDlrAZdDytkmwFqgjDZovM21F35lHGeUeCvYmm6W+sbQ0ydaLpg5bFAUuWG1cjqOl8vqrw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^28.1.0", + "pretty-format": "^28.1.3", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "requires": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -16849,7 +17529,7 @@ "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, "fast-memoize": { @@ -16859,9 +17539,9 @@ "dev": true }, "fastest-levenshtein": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", - "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==" + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==" }, "fastq": { "version": "1.13.0", @@ -16904,12 +17584,13 @@ } }, "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "requires": { - "locate-path": "^2.0.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" } }, "flat-cache": { @@ -16923,15 +17604,15 @@ } }, "flatted": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", - "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.6.tgz", + "integrity": "sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==", "dev": true }, "font-awesome": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz", - "integrity": "sha1-j6jPBBGhoxr9B7BtKQK7n8gVoTM=" + "integrity": "sha512-U6kGnykA/6bFmg1M/oT9EkFeIYv7JlX3bozwQJWiiLz6L0w3F5vBVPxHlwyX/vtNq1ckcpRKOB9f2Qal/VtFpg==" }, "form-data": { "version": "2.5.1", @@ -16958,7 +17639,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "fsevents": { "version": "2.3.2", @@ -16975,32 +17656,6 @@ "requires": { "readable-stream": "1.1.x", "xregexp": "2.0.0" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "dev": true - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", - "dev": true - } } }, "function-bind": { @@ -17023,7 +17678,7 @@ "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", "dev": true }, "functions-have-names": { @@ -17045,14 +17700,14 @@ "dev": true }, "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", + "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", "dev": true, "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", - "has-symbols": "^1.0.1" + "has-symbols": "^1.0.3" } }, "get-package-type": { @@ -17064,7 +17719,7 @@ "get-port": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", - "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=", + "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==", "dev": true }, "get-source": { @@ -17086,15 +17741,16 @@ } }, "get-stdin": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", - "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz", + "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==", "dev": true }, "get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==" + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true }, "get-symbol-description": { "version": "1.0.0", @@ -17167,6 +17823,12 @@ "which": "^1.3.1" }, "dependencies": { + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -17179,14 +17841,23 @@ } }, "globals": { - "version": "13.15.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", - "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", "dev": true, "requires": { "type-fest": "^0.20.2" } }, + "globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3" + } + }, "globby": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", @@ -17204,7 +17875,7 @@ "globjoin": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", - "integrity": "sha1-L0SUrIkZ43Z8XLtpHp9GMyQoXUM=", + "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", "dev": true }, "graceful-fs": { @@ -17212,6 +17883,12 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, "graphlib": { "version": "2.1.8", "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz", @@ -17226,9 +17903,9 @@ "integrity": "sha512-6QatdkKxXCMfvCW4rM++0RqyLQAzFX5nwl3yHS0XPgkZBkiSEY3VZVbMltrdtsbER/xZonLtyHt684wRp4erlQ==" }, "happy-dom": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-4.0.1.tgz", - "integrity": "sha512-GUj2ayfbWYHPeQfcK0N+lygRE/DsrjQbALJq0zrxHLc9KYzhFSCmaCOISuNgHV/21EEeVIX55KoPTqMcX362+g==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-6.0.4.tgz", + "integrity": "sha512-b+ID23Ms0BY08UNLymsOMG7EI2jSlwEt4cbJs938GZfeNAg+fqgkSO3TokQMgSOFoHznpjWmpVjBUL5boJ9PWw==", "dev": true, "requires": { "css.escape": "^1.5.1", @@ -17292,7 +17969,7 @@ "hash-sum": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", - "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=" + "integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==" }, "he": { "version": "1.2.0", @@ -17317,18 +17994,6 @@ "integrity": "sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==", "dev": true }, - "htmlparser2": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz", - "integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==", - "dev": true, - "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.2", - "domutils": "^2.8.0", - "entities": "^3.0.1" - } - }, "http-basic": { "version": "8.1.3", "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", @@ -17395,7 +18060,8 @@ "human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==" + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true }, "iconv-lite": { "version": "0.6.3", @@ -17420,7 +18086,7 @@ "image-size": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", - "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=", + "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==", "optional": true }, "immer": { @@ -17457,7 +18123,7 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true }, "indent-string": { @@ -17469,7 +18135,7 @@ "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "requires": { "once": "^1.3.0", "wrappy": "1" @@ -17481,9 +18147,9 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-3.0.0.tgz", + "integrity": "sha512-TxYQaeNW/N8ymDvwAxPyRbhMBtnEwuvaTYpOQkFx1nSeusgezHniEc/l35Vo4iCq/mMiTJbpD7oYxN98hFlfmw==", "dev": true }, "internal-slot": { @@ -17516,7 +18182,7 @@ "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, "is-bigint": { @@ -17539,12 +18205,12 @@ } }, "is-builtin-module": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.1.0.tgz", - "integrity": "sha512-OV7JjAgOTfAFJmHZLvpSTb4qi0nIILDV1gWPYDnDJUTNFM5aGlRAhk4QcT8i7TuAleeEV5Fdkqn3t4mS+Q11fg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.0.tgz", + "integrity": "sha512-phDA4oSGt7vl1n5tJvTWooWWAsXLY+2xCnxNqvKhGEzujg+A43wPlPOyDg3C8XQHN+6k/JTQWJ/j0dQh/qr+Hw==", "dev": true, "requires": { - "builtin-modules": "^3.0.0" + "builtin-modules": "^3.3.0" } }, "is-callable": { @@ -17573,7 +18239,7 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" }, "is-fullwidth-code-point": { "version": "3.0.0", @@ -17617,7 +18283,7 @@ "is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", "dev": true }, "is-plain-object": { @@ -17663,7 +18329,8 @@ "is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true }, "is-string": { "version": "1.0.7", @@ -17698,20 +18365,20 @@ "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==" }, "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", "dev": true }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==" }, "istanbul-lib-coverage": { "version": "3.2.0", @@ -17763,9 +18430,9 @@ } }, "istanbul-reports": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.4.tgz", - "integrity": "sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", "dev": true, "requires": { "html-escaper": "^2.0.0", @@ -17773,86 +18440,112 @@ } }, "jest": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-28.1.0.tgz", - "integrity": "sha512-TZR+tHxopPhzw3c3560IJXZWLNHgpcz1Zh0w5A65vynLGNcg/5pZ+VildAd7+XGOu6jd58XMY/HNn0IkZIXVXg==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest/-/jest-28.1.3.tgz", + "integrity": "sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA==", "dev": true, "requires": { - "@jest/core": "^28.1.0", + "@jest/core": "^28.1.3", + "@jest/types": "^28.1.3", "import-local": "^3.0.2", - "jest-cli": "^28.1.0" + "jest-cli": "^28.1.3" + }, + "dependencies": { + "@jest/types": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", + "dev": true, + "requires": { + "@jest/schemas": "^28.1.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "17.0.10", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", + "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + } } }, "jest-changed-files": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-28.0.2.tgz", - "integrity": "sha512-QX9u+5I2s54ZnGoMEjiM2WeBvJR2J7w/8ZUmH2um/WLAuGAYFQcsVXY9+1YL6k0H/AGUdH8pXUAv6erDqEsvIA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-28.1.3.tgz", + "integrity": "sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA==", "dev": true, "requires": { "execa": "^5.0.0", - "throat": "^6.0.1" + "p-limit": "^3.1.0" } }, "jest-circus": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-28.1.0.tgz", - "integrity": "sha512-rNYfqfLC0L0zQKRKsg4n4J+W1A2fbyGH7Ss/kDIocp9KXD9iaL111glsLu7+Z7FHuZxwzInMDXq+N1ZIBkI/TQ==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-28.1.3.tgz", + "integrity": "sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow==", "dev": true, "requires": { - "@jest/environment": "^28.1.0", - "@jest/expect": "^28.1.0", - "@jest/test-result": "^28.1.0", - "@jest/types": "^28.1.0", + "@jest/environment": "^28.1.3", + "@jest/expect": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^0.7.0", "is-generator-fn": "^2.0.0", - "jest-each": "^28.1.0", - "jest-matcher-utils": "^28.1.0", - "jest-message-util": "^28.1.0", - "jest-runtime": "^28.1.0", - "jest-snapshot": "^28.1.0", - "jest-util": "^28.1.0", - "pretty-format": "^28.1.0", + "jest-each": "^28.1.3", + "jest-matcher-utils": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-runtime": "^28.1.3", + "jest-snapshot": "^28.1.3", + "jest-util": "^28.1.3", + "p-limit": "^3.1.0", + "pretty-format": "^28.1.3", "slash": "^3.0.0", - "stack-utils": "^2.0.3", - "throat": "^6.0.1" + "stack-utils": "^2.0.3" }, "dependencies": { "@jest/environment": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.0.tgz", - "integrity": "sha512-S44WGSxkRngzHslhV6RoAExekfF7Qhwa6R5+IYFa81mpcj0YgdBnRSmvHe3SNwOt64yXaE5GG8Y2xM28ii5ssA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", + "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", "dev": true, "requires": { - "@jest/fake-timers": "^28.1.0", - "@jest/types": "^28.1.0", + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", - "jest-mock": "^28.1.0" + "jest-mock": "^28.1.3" } }, "@jest/fake-timers": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.0.tgz", - "integrity": "sha512-Xqsf/6VLeAAq78+GNPzI7FZQRf5cCHj1qgQxCjws9n8rKw8r1UYoeaALwBvyuzOkpU3c1I6emeMySPa96rxtIg==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", + "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", "dev": true, "requires": { - "@jest/types": "^28.1.0", - "@sinonjs/fake-timers": "^9.1.1", + "@jest/types": "^28.1.3", + "@sinonjs/fake-timers": "^9.1.2", "@types/node": "*", - "jest-message-util": "^28.1.0", - "jest-mock": "^28.1.0", - "jest-util": "^28.1.0" + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" } }, "@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "requires": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -17879,39 +18572,39 @@ } }, "jest-message-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.0.tgz", - "integrity": "sha512-RpA8mpaJ/B2HphDMiDlrAZdDytkmwFqgjDZovM21F35lHGeUeCvYmm6W+sbQ0ydaLpg5bFAUuWG1cjqOl8vqrw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^28.1.0", + "pretty-format": "^28.1.3", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "jest-mock": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.0.tgz", - "integrity": "sha512-H7BrhggNn77WhdL7O1apG0Q/iwl0Bdd5E1ydhCJzL3oBLh/UYxAwR3EJLsBZ9XA3ZU4PA3UNw4tQjduBTCTmLw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", + "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", "dev": true, "requires": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*" } }, "jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "requires": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -17922,32 +18615,32 @@ } }, "jest-cli": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-28.1.0.tgz", - "integrity": "sha512-fDJRt6WPRriHrBsvvgb93OxgajHHsJbk4jZxiPqmZbMDRcHskfJBBfTyjFko0jjfprP544hOktdSi9HVgl4VUQ==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-28.1.3.tgz", + "integrity": "sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ==", "dev": true, "requires": { - "@jest/core": "^28.1.0", - "@jest/test-result": "^28.1.0", - "@jest/types": "^28.1.0", + "@jest/core": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", "import-local": "^3.0.2", - "jest-config": "^28.1.0", - "jest-util": "^28.1.0", - "jest-validate": "^28.1.0", + "jest-config": "^28.1.3", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", "prompts": "^2.0.1", "yargs": "^17.3.1" }, "dependencies": { "@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "requires": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -17965,12 +18658,12 @@ } }, "jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "requires": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -17981,42 +18674,42 @@ } }, "jest-config": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-28.1.0.tgz", - "integrity": "sha512-aOV80E9LeWrmflp7hfZNn/zGA4QKv/xsn2w8QCBP0t0+YqObuCWTSgNbHJ0j9YsTuCO08ZR/wsvlxqqHX20iUA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-28.1.3.tgz", + "integrity": "sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ==", "dev": true, "requires": { "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^28.1.0", - "@jest/types": "^28.1.0", - "babel-jest": "^28.1.0", + "@jest/test-sequencer": "^28.1.3", + "@jest/types": "^28.1.3", + "babel-jest": "^28.1.3", "chalk": "^4.0.0", "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-circus": "^28.1.0", - "jest-environment-node": "^28.1.0", + "jest-circus": "^28.1.3", + "jest-environment-node": "^28.1.3", "jest-get-type": "^28.0.2", "jest-regex-util": "^28.0.2", - "jest-resolve": "^28.1.0", - "jest-runner": "^28.1.0", - "jest-util": "^28.1.0", - "jest-validate": "^28.1.0", + "jest-resolve": "^28.1.3", + "jest-runner": "^28.1.3", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", "micromatch": "^4.0.4", "parse-json": "^5.2.0", - "pretty-format": "^28.1.0", + "pretty-format": "^28.1.3", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" }, "dependencies": { "@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "requires": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -18034,12 +18727,12 @@ } }, "jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "requires": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -18050,77 +18743,46 @@ } }, "jest-diff": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", - "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz", + "integrity": "sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, - "jest-get-type": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", - "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", - "dev": true - }, - "pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - } - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - } + "diff-sequences": "^28.1.1", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" } }, "jest-docblock": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-28.0.2.tgz", - "integrity": "sha512-FH10WWw5NxLoeSdQlJwu+MTiv60aXV/t8KEwIRGEv74WARE1cXIqh1vGdy2CraHuWOOrnzTWj/azQKqW4fO7xg==", + "version": "28.1.1", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-28.1.1.tgz", + "integrity": "sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA==", "dev": true, "requires": { "detect-newline": "^3.0.0" } }, "jest-each": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-28.1.0.tgz", - "integrity": "sha512-a/XX02xF5NTspceMpHujmOexvJ4GftpYXqr6HhhmKmExtMXsyIN/fvanQlt/BcgFoRKN4OCXxLQKth9/n6OPFg==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-28.1.3.tgz", + "integrity": "sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g==", "dev": true, "requires": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "chalk": "^4.0.0", "jest-get-type": "^28.0.2", - "jest-util": "^28.1.0", - "pretty-format": "^28.1.0" + "jest-util": "^28.1.3", + "pretty-format": "^28.1.3" }, "dependencies": { "@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "requires": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -18138,12 +18800,12 @@ } }, "jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "requires": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -18154,52 +18816,52 @@ } }, "jest-environment-node": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-28.1.0.tgz", - "integrity": "sha512-gBLZNiyrPw9CSMlTXF1yJhaBgWDPVvH0Pq6bOEwGMXaYNzhzhw2kA/OijNF8egbCgDS0/veRv97249x2CX+udQ==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-28.1.3.tgz", + "integrity": "sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A==", "dev": true, "requires": { - "@jest/environment": "^28.1.0", - "@jest/fake-timers": "^28.1.0", - "@jest/types": "^28.1.0", + "@jest/environment": "^28.1.3", + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", - "jest-mock": "^28.1.0", - "jest-util": "^28.1.0" + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" }, "dependencies": { "@jest/environment": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.0.tgz", - "integrity": "sha512-S44WGSxkRngzHslhV6RoAExekfF7Qhwa6R5+IYFa81mpcj0YgdBnRSmvHe3SNwOt64yXaE5GG8Y2xM28ii5ssA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", + "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", "dev": true, "requires": { - "@jest/fake-timers": "^28.1.0", - "@jest/types": "^28.1.0", + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", - "jest-mock": "^28.1.0" + "jest-mock": "^28.1.3" } }, "@jest/fake-timers": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.0.tgz", - "integrity": "sha512-Xqsf/6VLeAAq78+GNPzI7FZQRf5cCHj1qgQxCjws9n8rKw8r1UYoeaALwBvyuzOkpU3c1I6emeMySPa96rxtIg==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", + "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", "dev": true, "requires": { - "@jest/types": "^28.1.0", - "@sinonjs/fake-timers": "^9.1.1", + "@jest/types": "^28.1.3", + "@sinonjs/fake-timers": "^9.1.2", "@types/node": "*", - "jest-message-util": "^28.1.0", - "jest-mock": "^28.1.0", - "jest-util": "^28.1.0" + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" } }, "@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "requires": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -18226,39 +18888,39 @@ } }, "jest-message-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.0.tgz", - "integrity": "sha512-RpA8mpaJ/B2HphDMiDlrAZdDytkmwFqgjDZovM21F35lHGeUeCvYmm6W+sbQ0ydaLpg5bFAUuWG1cjqOl8vqrw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^28.1.0", + "pretty-format": "^28.1.3", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "jest-mock": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.0.tgz", - "integrity": "sha512-H7BrhggNn77WhdL7O1apG0Q/iwl0Bdd5E1ydhCJzL3oBLh/UYxAwR3EJLsBZ9XA3ZU4PA3UNw4tQjduBTCTmLw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", + "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", "dev": true, "requires": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*" } }, "jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "requires": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -18269,21 +18931,13 @@ } }, "jest-extended": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jest-extended/-/jest-extended-2.0.0.tgz", - "integrity": "sha512-6AgjJQVaBEKGSK3FH90kOiRUWJsbzn9NWtW0pjGkAFIdH0oPilfkV/gHPJdVvJeBiqT3jMHw8TUg9pUGC1azDg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/jest-extended/-/jest-extended-3.0.1.tgz", + "integrity": "sha512-OSGbKUhbjy7QikfQyK3ishFrAqLeRodBzeJk7SuuWGACAT7HHcGuJ4aUQ3ueLANx4KSv1Pa7r1LJWGtJ3eI0xA==", "dev": true, "requires": { - "jest-diff": "^27.2.5", - "jest-get-type": "^27.0.6" - }, - "dependencies": { - "jest-get-type": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", - "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", - "dev": true - } + "jest-diff": "^28.0.0", + "jest-get-type": "^28.0.0" } }, "jest-get-type": { @@ -18293,12 +18947,12 @@ "dev": true }, "jest-haste-map": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-28.1.0.tgz", - "integrity": "sha512-xyZ9sXV8PtKi6NCrJlmq53PyNVHzxmcfXNVvIRHpHmh1j/HChC4pwKgyjj7Z9us19JMw8PpQTJsFWOsIfT93Dw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-28.1.3.tgz", + "integrity": "sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA==", "dev": true, "requires": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", @@ -18306,19 +18960,19 @@ "fsevents": "^2.3.2", "graceful-fs": "^4.2.9", "jest-regex-util": "^28.0.2", - "jest-util": "^28.1.0", - "jest-worker": "^28.1.0", + "jest-util": "^28.1.3", + "jest-worker": "^28.1.3", "micromatch": "^4.0.4", - "walker": "^1.0.7" + "walker": "^1.0.8" }, "dependencies": { "@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "requires": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -18336,12 +18990,12 @@ } }, "jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "requires": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -18352,45 +19006,25 @@ } }, "jest-leak-detector": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-28.1.0.tgz", - "integrity": "sha512-uIJDQbxwEL2AMMs2xjhZl2hw8s77c3wrPaQ9v6tXJLGaaQ+4QrNJH5vuw7hA7w/uGT/iJ42a83opAqxGHeyRIA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-28.1.3.tgz", + "integrity": "sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA==", "dev": true, "requires": { "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.0" + "pretty-format": "^28.1.3" } }, "jest-matcher-utils": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.0.tgz", - "integrity": "sha512-onnax0n2uTLRQFKAjC7TuaxibrPSvZgKTcSCnNUz/tOjJ9UhxNm7ZmPpoQavmTDUjXvUQ8KesWk2/VdrxIFzTQ==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz", + "integrity": "sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^28.1.0", + "jest-diff": "^28.1.3", "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.0" - }, - "dependencies": { - "diff-sequences": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.0.2.tgz", - "integrity": "sha512-YtEoNynLDFCRznv/XDalsKGSZDoj0U5kLnXvY0JSq3nBboRrZXjD81+eSiwi+nzcZDwedMmcowcxNwwgFW23mQ==", - "dev": true - }, - "jest-diff": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.0.tgz", - "integrity": "sha512-8eFd3U3OkIKRtlasXfiAQfbovgFgRDb0Ngcs2E+FMeBZ4rUezqIaGjuyggJBp+llosQXNEWofk/Sz4Hr5gMUhA==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^28.0.2", - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.0" - } - } + "pretty-format": "^28.1.3" } }, "jest-message-util": { @@ -18459,29 +19093,29 @@ "dev": true }, "jest-resolve": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-28.1.0.tgz", - "integrity": "sha512-vvfN7+tPNnnhDvISuzD1P+CRVP8cK0FHXRwPAcdDaQv4zgvwvag2n55/h5VjYcM5UJG7L4TwE5tZlzcI0X2Lhw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-28.1.3.tgz", + "integrity": "sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ==", "dev": true, "requires": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^28.1.0", + "jest-haste-map": "^28.1.3", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^28.1.0", - "jest-validate": "^28.1.0", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", "resolve": "^1.20.0", "resolve.exports": "^1.1.0", "slash": "^3.0.0" }, "dependencies": { "@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "requires": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -18499,12 +19133,12 @@ } }, "jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "requires": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -18515,77 +19149,77 @@ } }, "jest-resolve-dependencies": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.0.tgz", - "integrity": "sha512-Ue1VYoSZquPwEvng7Uefw8RmZR+me/1kr30H2jMINjGeHgeO/JgrR6wxj2ofkJ7KSAA11W3cOrhNCbj5Dqqd9g==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.3.tgz", + "integrity": "sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA==", "dev": true, "requires": { "jest-regex-util": "^28.0.2", - "jest-snapshot": "^28.1.0" + "jest-snapshot": "^28.1.3" } }, "jest-runner": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-28.1.0.tgz", - "integrity": "sha512-FBpmuh1HB2dsLklAlRdOxNTTHKFR6G1Qmd80pVDvwbZXTriqjWqjei5DKFC1UlM732KjYcE6yuCdiF0WUCOS2w==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-28.1.3.tgz", + "integrity": "sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA==", "dev": true, "requires": { - "@jest/console": "^28.1.0", - "@jest/environment": "^28.1.0", - "@jest/test-result": "^28.1.0", - "@jest/transform": "^28.1.0", - "@jest/types": "^28.1.0", + "@jest/console": "^28.1.3", + "@jest/environment": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "emittery": "^0.10.2", "graceful-fs": "^4.2.9", - "jest-docblock": "^28.0.2", - "jest-environment-node": "^28.1.0", - "jest-haste-map": "^28.1.0", - "jest-leak-detector": "^28.1.0", - "jest-message-util": "^28.1.0", - "jest-resolve": "^28.1.0", - "jest-runtime": "^28.1.0", - "jest-util": "^28.1.0", - "jest-watcher": "^28.1.0", - "jest-worker": "^28.1.0", - "source-map-support": "0.5.13", - "throat": "^6.0.1" + "jest-docblock": "^28.1.1", + "jest-environment-node": "^28.1.3", + "jest-haste-map": "^28.1.3", + "jest-leak-detector": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-resolve": "^28.1.3", + "jest-runtime": "^28.1.3", + "jest-util": "^28.1.3", + "jest-watcher": "^28.1.3", + "jest-worker": "^28.1.3", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" }, "dependencies": { "@jest/environment": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.0.tgz", - "integrity": "sha512-S44WGSxkRngzHslhV6RoAExekfF7Qhwa6R5+IYFa81mpcj0YgdBnRSmvHe3SNwOt64yXaE5GG8Y2xM28ii5ssA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", + "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", "dev": true, "requires": { - "@jest/fake-timers": "^28.1.0", - "@jest/types": "^28.1.0", + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", - "jest-mock": "^28.1.0" + "jest-mock": "^28.1.3" } }, "@jest/fake-timers": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.0.tgz", - "integrity": "sha512-Xqsf/6VLeAAq78+GNPzI7FZQRf5cCHj1qgQxCjws9n8rKw8r1UYoeaALwBvyuzOkpU3c1I6emeMySPa96rxtIg==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", + "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", "dev": true, "requires": { - "@jest/types": "^28.1.0", - "@sinonjs/fake-timers": "^9.1.1", + "@jest/types": "^28.1.3", + "@sinonjs/fake-timers": "^9.1.2", "@types/node": "*", - "jest-message-util": "^28.1.0", - "jest-mock": "^28.1.0", - "jest-util": "^28.1.0" + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" } }, "@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "requires": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -18612,39 +19246,39 @@ } }, "jest-message-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.0.tgz", - "integrity": "sha512-RpA8mpaJ/B2HphDMiDlrAZdDytkmwFqgjDZovM21F35lHGeUeCvYmm6W+sbQ0ydaLpg5bFAUuWG1cjqOl8vqrw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^28.1.0", + "pretty-format": "^28.1.3", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "jest-mock": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.0.tgz", - "integrity": "sha512-H7BrhggNn77WhdL7O1apG0Q/iwl0Bdd5E1ydhCJzL3oBLh/UYxAwR3EJLsBZ9XA3ZU4PA3UNw4tQjduBTCTmLw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", + "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", "dev": true, "requires": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*" } }, "jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "requires": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -18655,68 +19289,68 @@ } }, "jest-runtime": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-28.1.0.tgz", - "integrity": "sha512-wNYDiwhdH/TV3agaIyVF0lsJ33MhyujOe+lNTUiolqKt8pchy1Hq4+tDMGbtD5P/oNLA3zYrpx73T9dMTOCAcg==", - "dev": true, - "requires": { - "@jest/environment": "^28.1.0", - "@jest/fake-timers": "^28.1.0", - "@jest/globals": "^28.1.0", - "@jest/source-map": "^28.0.2", - "@jest/test-result": "^28.1.0", - "@jest/transform": "^28.1.0", - "@jest/types": "^28.1.0", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-28.1.3.tgz", + "integrity": "sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw==", + "dev": true, + "requires": { + "@jest/environment": "^28.1.3", + "@jest/fake-timers": "^28.1.3", + "@jest/globals": "^28.1.3", + "@jest/source-map": "^28.1.2", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", "execa": "^5.0.0", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-haste-map": "^28.1.0", - "jest-message-util": "^28.1.0", - "jest-mock": "^28.1.0", + "jest-haste-map": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", "jest-regex-util": "^28.0.2", - "jest-resolve": "^28.1.0", - "jest-snapshot": "^28.1.0", - "jest-util": "^28.1.0", + "jest-resolve": "^28.1.3", + "jest-snapshot": "^28.1.3", + "jest-util": "^28.1.3", "slash": "^3.0.0", "strip-bom": "^4.0.0" }, "dependencies": { "@jest/environment": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.0.tgz", - "integrity": "sha512-S44WGSxkRngzHslhV6RoAExekfF7Qhwa6R5+IYFa81mpcj0YgdBnRSmvHe3SNwOt64yXaE5GG8Y2xM28ii5ssA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", + "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", "dev": true, "requires": { - "@jest/fake-timers": "^28.1.0", - "@jest/types": "^28.1.0", + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", - "jest-mock": "^28.1.0" + "jest-mock": "^28.1.3" } }, "@jest/fake-timers": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.0.tgz", - "integrity": "sha512-Xqsf/6VLeAAq78+GNPzI7FZQRf5cCHj1qgQxCjws9n8rKw8r1UYoeaALwBvyuzOkpU3c1I6emeMySPa96rxtIg==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", + "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", "dev": true, "requires": { - "@jest/types": "^28.1.0", - "@sinonjs/fake-timers": "^9.1.1", + "@jest/types": "^28.1.3", + "@sinonjs/fake-timers": "^9.1.2", "@types/node": "*", - "jest-message-util": "^28.1.0", - "jest-mock": "^28.1.0", - "jest-util": "^28.1.0" + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" } }, "@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "requires": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -18743,39 +19377,39 @@ } }, "jest-message-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.0.tgz", - "integrity": "sha512-RpA8mpaJ/B2HphDMiDlrAZdDytkmwFqgjDZovM21F35lHGeUeCvYmm6W+sbQ0ydaLpg5bFAUuWG1cjqOl8vqrw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^28.1.0", + "pretty-format": "^28.1.3", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "jest-mock": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.0.tgz", - "integrity": "sha512-H7BrhggNn77WhdL7O1apG0Q/iwl0Bdd5E1ydhCJzL3oBLh/UYxAwR3EJLsBZ9XA3ZU4PA3UNw4tQjduBTCTmLw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", + "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", "dev": true, "requires": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*" } }, "jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "requires": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -18786,9 +19420,9 @@ } }, "jest-snapshot": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-28.1.0.tgz", - "integrity": "sha512-ex49M2ZrZsUyQLpLGxQtDbahvgBjlLPgklkqGM0hq/F7W/f8DyqZxVHjdy19QKBm4O93eDp+H5S23EiTbbUmHw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-28.1.3.tgz", + "integrity": "sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg==", "dev": true, "requires": { "@babel/core": "^7.11.6", @@ -18796,33 +19430,33 @@ "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.3.3", - "@jest/expect-utils": "^28.1.0", - "@jest/transform": "^28.1.0", - "@jest/types": "^28.1.0", + "@jest/expect-utils": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", "@types/babel__traverse": "^7.0.6", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^28.1.0", + "expect": "^28.1.3", "graceful-fs": "^4.2.9", - "jest-diff": "^28.1.0", + "jest-diff": "^28.1.3", "jest-get-type": "^28.0.2", - "jest-haste-map": "^28.1.0", - "jest-matcher-utils": "^28.1.0", - "jest-message-util": "^28.1.0", - "jest-util": "^28.1.0", + "jest-haste-map": "^28.1.3", + "jest-matcher-utils": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", "natural-compare": "^1.4.0", - "pretty-format": "^28.1.0", + "pretty-format": "^28.1.3", "semver": "^7.3.5" }, "dependencies": { "@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "requires": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -18839,48 +19473,30 @@ "@types/yargs-parser": "*" } }, - "diff-sequences": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.0.2.tgz", - "integrity": "sha512-YtEoNynLDFCRznv/XDalsKGSZDoj0U5kLnXvY0JSq3nBboRrZXjD81+eSiwi+nzcZDwedMmcowcxNwwgFW23mQ==", - "dev": true - }, - "jest-diff": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.0.tgz", - "integrity": "sha512-8eFd3U3OkIKRtlasXfiAQfbovgFgRDb0Ngcs2E+FMeBZ4rUezqIaGjuyggJBp+llosQXNEWofk/Sz4Hr5gMUhA==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^28.0.2", - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.0" - } - }, "jest-message-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.0.tgz", - "integrity": "sha512-RpA8mpaJ/B2HphDMiDlrAZdDytkmwFqgjDZovM21F35lHGeUeCvYmm6W+sbQ0ydaLpg5bFAUuWG1cjqOl8vqrw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^28.1.0", + "pretty-format": "^28.1.3", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "requires": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -18905,26 +19521,26 @@ } }, "jest-validate": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-28.1.0.tgz", - "integrity": "sha512-Lly7CJYih3vQBfjLeANGgBSBJ7pEa18cxpQfQEq2go2xyEzehnHfQTjoUia8xUv4x4J80XKFIDwJJThXtRFQXQ==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-28.1.3.tgz", + "integrity": "sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA==", "dev": true, "requires": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "camelcase": "^6.2.0", "chalk": "^4.0.0", "jest-get-type": "^28.0.2", "leven": "^3.1.0", - "pretty-format": "^28.1.0" + "pretty-format": "^28.1.3" }, "dependencies": { "@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "requires": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -18950,28 +19566,28 @@ } }, "jest-watcher": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.0.tgz", - "integrity": "sha512-tNHMtfLE8Njcr2IRS+5rXYA4BhU90gAOwI9frTGOqd+jX0P/Au/JfRSNqsf5nUTcWdbVYuLxS1KjnzILSoR5hA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.3.tgz", + "integrity": "sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==", "dev": true, "requires": { - "@jest/test-result": "^28.1.0", - "@jest/types": "^28.1.0", + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "emittery": "^0.10.2", - "jest-util": "^28.1.0", + "jest-util": "^28.1.3", "string-length": "^4.0.1" }, "dependencies": { "@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "requires": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -18989,12 +19605,12 @@ } }, "jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "requires": { - "@jest/types": "^28.1.0", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -19005,9 +19621,9 @@ } }, "jest-worker": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.0.tgz", - "integrity": "sha512-ZHwM6mNwaWBR52Snff8ZvsCTqQsvhCxP/bT1I6T6DAnb6ygkshsyLQIMxFwHpYxht0HOoqt23JlC01viI7T03A==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", + "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==", "dev": true, "requires": { "@types/node": "*", @@ -19077,14 +19693,14 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, "json5": { @@ -19114,9 +19730,9 @@ "dev": true }, "jsonpointer": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.0.tgz", - "integrity": "sha512-PNYZIdMjVIvVgDSYKTT63Y+KZ6IZvGRNNWcxwD+GNnUz1MKPfv30J8ueCjdwcN0nDx2SlshgyB7Oy0epAzVRRg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", "dev": true }, "just-extend": { @@ -19152,9 +19768,9 @@ "dev": true }, "less": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/less/-/less-4.1.2.tgz", - "integrity": "sha512-EoQp/Et7OSOVu0aJknJOtlXZsnr8XE8KwuzTHOLeVSEx8pVWUICc8Q0VYRHgzyjX78nMEyC/oztWFbgyhtNfDA==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/less/-/less-4.1.3.tgz", + "integrity": "sha512-w16Xk/Ta9Hhyei0Gpz9m7VS8F28nieJaL/VyShID7cYvP6IL5oHeL6p4TXSDJqZE/lNv0oJ2pGVjJsRkfwm5FA==", "requires": { "copy-anything": "^2.0.1", "errno": "^0.1.1", @@ -19162,7 +19778,7 @@ "image-size": "~0.5.0", "make-dir": "^2.1.0", "mime": "^1.4.1", - "needle": "^2.5.2", + "needle": "^3.1.0", "parse-node-version": "^1.0.1", "source-map": "~0.6.0", "tslib": "^2.3.0" @@ -19258,6 +19874,15 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, + "linkify-it": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", + "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", + "dev": true, + "requires": { + "uc.micro": "^1.0.1" + } + }, "loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", @@ -19274,13 +19899,12 @@ } }, "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "p-locate": "^5.0.0" } }, "lodash": { @@ -19291,7 +19915,7 @@ "lodash._reinterpolate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" + "integrity": "sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==" }, "lodash.get": { "version": "4.4.2", @@ -19311,11 +19935,6 @@ "integrity": "sha512-4hNPN5jlm/N/HLMCO43v8BXKq9Z7QdAGc/VGrRD61w8gN9g/6jF9A4L1pbUgBLCffi0w9VsXfTOij5x8iTyFvg==", "dev": true }, - "lodash.sortby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" - }, "lodash.template": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", @@ -19342,15 +19961,16 @@ "lodash.truncate": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", "dev": true }, "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, "requires": { - "yallist": "^4.0.0" + "yallist": "^3.0.2" } }, "magic-string": { @@ -19394,10 +20014,95 @@ "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", "dev": true }, + "markdown-it": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz", + "integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==", + "dev": true, + "requires": { + "argparse": "^2.0.1", + "entities": "~3.0.1", + "linkify-it": "^4.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + } + }, + "markdownlint": { + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.26.1.tgz", + "integrity": "sha512-8sLz1ktz5s4E0IDum2H9aiWLQU7RA5Eket9HUW5IRwfFnW2RD2ZyqYePW+z71tMc7lrFZc1+yPmlN9lirbJnlg==", + "dev": true, + "requires": { + "markdown-it": "13.0.1" + } + }, + "markdownlint-cli": { + "version": "0.32.1", + "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.32.1.tgz", + "integrity": "sha512-hVLQ+72b5esQd7I+IqzBEB4x/4C+wJaxS2M6nqaGoDwrtNY6gydGf5CIUJtQcXtqsM615++a8TZPsvEtH6H4gw==", + "dev": true, + "requires": { + "commander": "~9.4.0", + "get-stdin": "~9.0.0", + "glob": "~8.0.3", + "ignore": "~5.2.0", + "js-yaml": "^4.1.0", + "jsonc-parser": "~3.1.0", + "markdownlint": "~0.26.1", + "markdownlint-rule-helpers": "~0.17.1", + "minimatch": "~5.1.0", + "run-con": "~1.2.11" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "glob": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", + "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + } + }, + "jsonc-parser": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.1.0.tgz", + "integrity": "sha512-DRf0QjnNeCUds3xTjKlQQ3DpJD51GvDjJfnxUVWg6PZTo2otSm+slzNAxU/35hF8/oJIKoG9slq30JYOsF2azg==", + "dev": true + }, + "minimatch": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", + "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, + "markdownlint-rule-helpers": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.17.1.tgz", + "integrity": "sha512-Djc5IjJt7VA5sZRisISsJC/rQXR7hr8JS9u6Q9/ce3mjPZdzw535cFGG0U6Mag+ldRTRmRwCcTfivOh57KUP4w==", + "dev": true + }, "marked": { - "version": "4.0.16", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.16.tgz", - "integrity": "sha512-wahonIQ5Jnyatt2fn8KqF/nIqZM8mh3oRu2+l5EANGMhu6RFjiSG52QNE2eWzFMI94HqYSgN184NurgNG6CztA==" + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.18.tgz", + "integrity": "sha512-wbLDJ7Zh0sqA0Vdg6aqlbT+yPxqLblpAZh1mK2+AO2twQkPywvvqQNfEPVwSSRjZ7dZcdeVBIAgiO7MMp3Dszw==" }, "mathml-tag-names": { "version": "2.1.3", @@ -19411,6 +20116,12 @@ "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", "dev": true }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", + "dev": true + }, "meow": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", @@ -19440,6 +20151,15 @@ "lru-cache": "^6.0.0" } }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, "normalize-package-data": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", @@ -19457,6 +20177,12 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } }, @@ -19479,9 +20205,9 @@ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" }, "mermaid": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-9.1.2.tgz", - "integrity": "sha512-RVf3hBKqiMfyORHboCaEjOAK1TomLO50hYRPvlTrZCXlCniM5pRpe8UlkHBjjpaLtioZnbdYv/vEVj7iKnwkJQ==", + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-9.1.3.tgz", + "integrity": "sha512-jTIYiqKwsUXVCoxHUVkK8t0QN3zSKIdJlb9thT0J5jCnzXyc+gqTbZE2QmjRfavFTPPn5eRy5zaFp7V+6RhxYg==", "requires": { "@braintree/sanitize-url": "^6.0.0", "d3": "^7.0.0", @@ -19525,7 +20251,8 @@ "mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true }, "min-indent": { "version": "1.0.1", @@ -19534,9 +20261,9 @@ "dev": true }, "mini-css-extract-plugin": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.0.tgz", - "integrity": "sha512-ndG8nxCEnAemsg4FSgS+yNyHKgkTB4nPKqCOgh65j3/30qqC5RaSQQXMm++Y6sb6E1zRSxPkztj9fqxhS1Eo6w==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.1.tgz", + "integrity": "sha512-wd+SD57/K6DiV7jIR34P+s3uckTRuQvx0tKPcvjFlrEylk6P4mQ2KSWk1hblj1Kxaqok7LogKOieygXqBczNlg==", "requires": { "schema-utils": "^4.0.0" } @@ -19597,17 +20324,17 @@ "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, "needle": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/needle/-/needle-2.9.1.tgz", - "integrity": "sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-3.1.0.tgz", + "integrity": "sha512-gCE9weDhjVGCRqS8dwDR/D3GTAeyXLXuqp7I8EzH6DllZGXSUyxuqqLh+YX9rMAWaaTFyVAg6rHGL25dqvczKw==", "optional": true, "requires": { "debug": "^3.2.6", - "iconv-lite": "^0.4.4", + "iconv-lite": "^0.6.3", "sax": "^1.2.4" }, "dependencies": { @@ -19619,15 +20346,6 @@ "requires": { "ms": "^2.1.1" } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } } } }, @@ -19668,13 +20386,13 @@ "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", "dev": true }, "node-releases": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.4.tgz", - "integrity": "sha512-gbMzqQtTtDz/00jQzZ21PQzdI9PyLYqUSvD0p3naOhX4odFji0ZxYdnVwPTxmSwkmxhcFImpozceidSG+AgoPQ==" + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", + "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==" }, "normalize-package-data": { "version": "2.5.0", @@ -19702,24 +20420,19 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, - "normalize-selector": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/normalize-selector/-/normalize-selector-0.2.0.tgz", - "integrity": "sha1-0LFF62kRicY6eNIB3E/bEpPvDAM=", - "dev": true - }, "npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, "requires": { "path-key": "^3.0.0" } }, "nth-check": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz", - "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", "dev": true, "requires": { "boolbase": "^1.0.0" @@ -19728,12 +20441,12 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" }, "object-inspect": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", - "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", "dev": true }, "object-keys": { @@ -19768,7 +20481,7 @@ "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "requires": { "wrappy": "1" } @@ -19777,6 +20490,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, "requires": { "mimic-fn": "^2.1.0" } @@ -19796,28 +20510,27 @@ } }, "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "requires": { - "p-try": "^1.0.0" + "yocto-queue": "^0.1.0" } }, "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "requires": { - "p-limit": "^1.1.0" + "p-limit": "^3.0.2" } }, "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, "pac-proxy-agent": { "version": "5.0.0", @@ -19859,7 +20572,7 @@ "parse-cache-control": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", - "integrity": "sha1-juqz5U+laSD+Fro493+iGqzC104=", + "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==", "dev": true }, "parse-json": { @@ -19875,9 +20588,9 @@ } }, "parse-ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", - "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-3.0.0.tgz", + "integrity": "sha512-Tpb8Z7r7XbbtBTrM9UhpkzzaMrqA2VXMT3YChzYltwV3P3pM6t8wl7TvpMnSTosz1aQAdVib7kdoys7vYOPerw==" }, "parse-node-version": { "version": "1.0.1", @@ -19885,15 +20598,14 @@ "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==" }, "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" }, "path-key": { "version": "3.1.1", @@ -19973,16 +20685,6 @@ "requires": { "p-limit": "^2.2.0" } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" } } }, @@ -20023,7 +20725,7 @@ "postcss-media-query-parser": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", - "integrity": "sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ=", + "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", "dev": true }, "postcss-modules-extract-imports": { @@ -20061,7 +20763,7 @@ "postcss-resolve-nested-selector": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", - "integrity": "sha1-Kcy8fDfe36wwTp//C/FZaz9qDk4=", + "integrity": "sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==", "dev": true }, "postcss-safe-parser": { @@ -20092,18 +20794,18 @@ "dev": true }, "prettier": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz", - "integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", "optional": true }, "pretty-format": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.0.tgz", - "integrity": "sha512-79Z4wWOYCdvQkEoEuSlBhHJqWeZ8D8YRPiPctJFCtvuaClGpiwiQYSCUOE6IEKUbbFukKOTFIUAXE8N4EQTo1Q==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", "dev": true, "requires": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" @@ -20118,11 +20820,11 @@ } }, "pretty-ms": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz", - "integrity": "sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-8.0.0.tgz", + "integrity": "sha512-ASJqOugUF1bbzI35STMBUpZqdfYKlJugy6JBziGi2EE+AL5JPJGSzvpeVXojxrr0ViUYoToUjb5kjSEGf7Y83Q==", "requires": { - "parse-ms": "^2.1.0" + "parse-ms": "^3.0.0" } }, "printable-characters": { @@ -20170,23 +20872,6 @@ "pac-proxy-agent": "^5.0.0", "proxy-from-env": "^1.0.0", "socks-proxy-agent": "^5.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - } } }, "proxy-from-env": { @@ -20198,13 +20883,13 @@ "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", "optional": true }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" }, "punycode": { "version": "2.1.1", @@ -20212,9 +20897,9 @@ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, "qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "dev": true, "requires": { "side-channel": "^1.0.4" @@ -20263,9 +20948,9 @@ } }, "react-is": { - "version": "18.1.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.1.0.tgz", - "integrity": "sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==", + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, "read-pkg": { @@ -20336,18 +21021,6 @@ "p-limit": "^2.2.0" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, "type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", @@ -20357,18 +21030,15 @@ } }, "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", "dev": true, "requires": { "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" } }, "rechoir": { @@ -20420,7 +21090,7 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true }, "require-from-string": { @@ -20435,11 +21105,11 @@ "dev": true }, "resolve": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", - "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", "requires": { - "is-core-module": "^2.8.1", + "is-core-module": "^2.9.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" } @@ -20491,15 +21161,27 @@ "integrity": "sha512-ndEIpszUHiG4HtDsQLeIuMvRsDnn8c8rYStabochtUeCvfuvNptb5TUbVD68LRAILPX7p9nqQGh4xJgn3EHS/g==" }, "rollup": { - "version": "2.76.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.76.0.tgz", - "integrity": "sha512-9jwRIEY1jOzKLj3nsY/yot41r19ITdQrhs+q3ggNWhr9TQgduHqANvPpS32RNpzGklJu3G1AJfvlZLi/6wFgWA==", + "version": "2.77.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.77.2.tgz", + "integrity": "sha512-m/4YzYgLcpMQbxX3NmAqDvwLATZzxt8bIegO78FZLl+lAgKJBd1DRAOeEiZcKOIOPjxE6ewHWHNgGEalFXuz1g==", "dev": true, "peer": true, "requires": { "fsevents": "~2.3.2" } }, + "run-con": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/run-con/-/run-con-1.2.11.tgz", + "integrity": "sha512-NEMGsUT+cglWkzEr4IFK21P4Jca45HqiAbIIZIBdX5+UZTB24Mb/21iNGgz9xZa8tL6vbW7CXmq7MFN42+VjNQ==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~3.0.0", + "minimist": "^1.2.6", + "strip-json-comments": "~3.1.1" + } + }, "run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -20511,7 +21193,7 @@ "rw": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", - "integrity": "sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q=" + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" }, "safe-buffer": { "version": "5.1.2", @@ -20553,32 +21235,6 @@ "ajv": "^8.8.0", "ajv-formats": "^2.1.1", "ajv-keywords": "^5.0.0" - }, - "dependencies": { - "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "requires": { - "fast-deep-equal": "^3.1.3" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - } } }, "semver": { @@ -20587,6 +21243,21 @@ "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", "requires": { "lru-cache": "^6.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } } }, "serialize-javascript": { @@ -20638,7 +21309,8 @@ "signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true }, "simple-eval": { "version": "1.0.0", @@ -20679,13 +21351,21 @@ "dev": true }, "socks": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz", - "integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.0.tgz", + "integrity": "sha512-scnOe9y4VuiNUULJN72GrM26BNOjVsfPXI+j+98PkyEfsIXroa5ofyjT+FzGvn/xHs73U2JtoBYAVx9Hl4quSA==", "dev": true, "requires": { - "ip": "^1.1.5", + "ip": "^2.0.0", "smart-buffer": "^4.2.0" + }, + "dependencies": { + "ip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", + "dev": true + } } }, "socks-proxy-agent": { @@ -20797,16 +21477,10 @@ "spdx-ranges": "^2.0.0" } }, - "specificity": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/specificity/-/specificity-0.4.1.tgz", - "integrity": "sha512-1klA3Gi5PD1Wv9Q0wUoOQN1IWAuPu0D1U03ThXTr0cJ20+/iq2tHSDnK7Kk/0LXJ1ztUB2/1Os0wKmfyNgUQfg==", - "dev": true - }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, "stable": { @@ -20849,13 +21523,10 @@ "dev": true }, "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "dev": true }, "string-length": { "version": "4.0.2", @@ -20916,7 +21587,8 @@ "strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true }, "strip-indent": { "version": "3.0.0", @@ -20936,19 +21608,20 @@ "style-search": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", - "integrity": "sha1-eVjHk+R+MuB9K1yv5cC/jhLneQI=", + "integrity": "sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==", "dev": true }, "stylelint": { - "version": "14.8.2", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.8.2.tgz", - "integrity": "sha512-tjDfexCYfoPdl/xcDJ9Fv+Ko9cvzbDnmdiaqEn3ovXHXasi/hbkt5tSjsiReQ+ENqnz0eltaX/AOO+AlzVdcNA==", + "version": "14.9.1", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.9.1.tgz", + "integrity": "sha512-RdAkJdPiLqHawCSnu21nE27MjNXaVd4WcOHA4vK5GtIGjScfhNnaOuWR2wWdfKFAvcWQPOYe311iveiVKSmwsA==", "dev": true, "requires": { + "@csstools/selector-specificity": "^2.0.1", "balanced-match": "^2.0.0", "colord": "^2.9.2", "cosmiconfig": "^7.0.1", - "css-functions-list": "^3.0.1", + "css-functions-list": "^3.1.0", "debug": "^4.3.4", "execall": "^2.0.0", "fast-glob": "^3.2.11", @@ -20968,16 +21641,14 @@ "meow": "^9.0.0", "micromatch": "^4.0.5", "normalize-path": "^3.0.0", - "normalize-selector": "^0.2.0", "picocolors": "^1.0.0", - "postcss": "^8.4.13", + "postcss": "^8.4.14", "postcss-media-query-parser": "^0.2.3", "postcss-resolve-nested-selector": "^0.1.1", "postcss-safe-parser": "^6.0.0", "postcss-selector-parser": "^6.0.10", "postcss-value-parser": "^4.2.0", "resolve-from": "^5.0.0", - "specificity": "^0.4.1", "string-width": "^4.2.3", "strip-ansi": "^6.0.1", "style-search": "^0.1.0", @@ -20994,6 +21665,12 @@ "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", "dev": true }, + "get-stdin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "dev": true + }, "resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", @@ -21003,19 +21680,19 @@ } }, "stylelint-config-recommended": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-7.0.0.tgz", - "integrity": "sha512-yGn84Bf/q41J4luis1AZ95gj0EQwRX8lWmGmBwkwBNSkpGSpl66XcPTulxGa/Z91aPoNGuIGBmFkcM1MejMo9Q==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-8.0.0.tgz", + "integrity": "sha512-IK6dWvE000+xBv9jbnHOnBq01gt6HGVB2ZTsot+QsMpe82doDQ9hvplxfv4YnpEuUwVGGd9y6nbaAnhrjcxhZQ==", "dev": true, "requires": {} }, "stylelint-config-standard": { - "version": "25.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-25.0.0.tgz", - "integrity": "sha512-21HnP3VSpaT1wFjFvv9VjvOGDtAviv47uTp3uFmzcN+3Lt+RYRv6oAplLaV51Kf792JSxJ6svCJh/G18E9VnCA==", + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-26.0.0.tgz", + "integrity": "sha512-hUuB7LaaqM8abvkOO84wh5oYSkpXgTzHu2Zza6e7mY+aOmpNTjoFBRxSLlzY0uAOMWEFx0OMKzr+reG1BUtcqQ==", "dev": true, "requires": { - "stylelint-config-recommended": "^7.0.0" + "stylelint-config-recommended": "^8.0.0" } }, "stylis": { @@ -21055,7 +21732,7 @@ "svg-tags": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", - "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=", + "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", "dev": true }, "svgo": { @@ -21071,12 +21748,20 @@ "csso": "^4.2.0", "picocolors": "^1.0.0", "stable": "^0.1.8" + }, + "dependencies": { + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true + } } }, "swagger-ui-dist": { - "version": "4.11.1", - "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-4.11.1.tgz", - "integrity": "sha512-pf3kfSTYdF9mYFY2VnfJ51wnXlSVhEGdtymhpHzfbFw2jTbiEWgBoVz5EB9aW2EaJvUGTM1YHAXYZX7Jk4RdAQ==" + "version": "4.13.2", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-4.13.2.tgz", + "integrity": "sha512-jHL6UyIYpvEI7NsuWd0R3hJaPQTg6Oo4qSBo+oVfOEkv6rrQm/475RGSMmZgV6ajp+Sgrp9CqrDjQYAgQqiv1A==" }, "sync-request": { "version": "6.1.0", @@ -21109,26 +21794,6 @@ "slice-ansi": "^4.0.0", "string-width": "^4.2.3", "strip-ansi": "^6.0.1" - }, - "dependencies": { - "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - } } }, "tapable": { @@ -21147,13 +21812,13 @@ } }, "terser": { - "version": "5.13.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.13.1.tgz", - "integrity": "sha512-hn4WKOfwnwbYfe48NgrQjqNOH9jzLqRcIfbYytOXCOv46LBfWr9bDS17MQqOi+BWGD0sJK3Sj5NC/gJjiojaoA==", + "version": "5.14.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.14.2.tgz", + "integrity": "sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==", "requires": { + "@jridgewell/source-map": "^0.3.2", "acorn": "^8.5.0", "commander": "^2.20.0", - "source-map": "~0.8.0-beta.0", "source-map-support": "~0.5.20" }, "dependencies": { @@ -21162,14 +21827,6 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, - "source-map": { - "version": "0.8.0-beta.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", - "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", - "requires": { - "whatwg-url": "^7.0.0" - } - }, "source-map-support": { "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", @@ -21177,52 +21834,39 @@ "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "tr46": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", - "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", - "requires": { - "punycode": "^2.1.0" - } - }, - "webidl-conversions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" - }, - "whatwg-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", - "requires": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" } } } }, "terser-webpack-plugin": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.1.tgz", - "integrity": "sha512-GvlZdT6wPQKbDNW/GDQzZFg/j4vKU96yl2q6mcUkzKOgW4gwf1Z8cZToUCrz31XHlPWH8MVb1r2tFtdDtTGJ7g==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.3.tgz", + "integrity": "sha512-Fx60G5HNYknNTNQnzQ1VePRuu89ZVYWfjRAeT5rITuCY/1b08s49e5kSQwHDirKZWuoKOBRFS98EUUoZ9kLEwQ==", "requires": { + "@jridgewell/trace-mapping": "^0.3.7", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1", "terser": "^5.7.2" }, "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "requires": {} + }, "jest-worker": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", @@ -21233,6 +21877,11 @@ "supports-color": "^8.0.0" } }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, "schema-utils": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", @@ -21267,7 +21916,7 @@ "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, "then-request": { @@ -21297,11 +21946,13 @@ } } }, - "throat": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", - "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", - "dev": true + "tippy.js": { + "version": "6.3.7", + "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz", + "integrity": "sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==", + "requires": { + "@popperjs/core": "^2.9.0" + } }, "tmpl": { "version": "1.0.5", @@ -21312,7 +21963,7 @@ "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true }, "to-regex-range": { @@ -21332,7 +21983,7 @@ "tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "dev": true }, "tributejs": { @@ -21370,7 +22021,7 @@ "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true } } @@ -21404,13 +22055,19 @@ "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", "dev": true }, "typo-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/typo-js/-/typo-js-1.2.1.tgz", - "integrity": "sha512-bTGLjbD3WqZDR3CgEFkyi9Q/SS2oM29ipXrWfDb4M74ea69QwKAECVceYpaBu0GfdnASMg9Qfl67ttB23nePHg==" + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/typo-js/-/typo-js-1.2.2.tgz", + "integrity": "sha512-C7pYBQK17EjSg8tVNY91KHdUt5Nf6FMJ+c3js076quPmBML57PmNMzAcIq/2kf/hSYtFABNDIYNYlJRl5BJhGw==" + }, + "uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true }, "uint8-to-base64": { "version": "0.2.0", @@ -21441,10 +22098,19 @@ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true }, + "update-browserslist-db": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz", + "integrity": "sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q==", + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } + }, "updates": { - "version": "13.0.5", - "resolved": "https://registry.npmjs.org/updates/-/updates-13.0.5.tgz", - "integrity": "sha512-ut7RIiH5Qys7jan4cS9i1Lqk6AAKGmVy1q0udDNJ4YXhvVoUdwQTAk5I9/wkSH6nHQtqhaqytCcZvS6hEJs8xg==", + "version": "13.1.4", + "resolved": "https://registry.npmjs.org/updates/-/updates-13.1.4.tgz", + "integrity": "sha512-s8FKpHpREDoIbd1JDcEvsdf+wenhcQjrZK8v7OTIW69kozPttm6rW84Mm/LFouiDVYgaubY3us7sZlRUiGVx4Q==", "dev": true }, "uri-js": { @@ -21464,7 +22130,7 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "utility-types": { "version": "3.10.0", @@ -21490,12 +22156,12 @@ "dev": true }, "v8-to-istanbul": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.0.tgz", - "integrity": "sha512-HcvgY/xaRm7isYmyx+lFKA4uQmfUbN0J4M0nNItvzTvH/iQ9kW5j/t4YSR+Ge323/lrgDAWJoF46tzGQHwBHFw==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", + "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==", "dev": true, "requires": { - "@jridgewell/trace-mapping": "^0.3.7", + "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", "convert-source-map": "^1.6.0" } @@ -21552,9 +22218,9 @@ } }, "vue-eslint-parser": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.0.2.tgz", - "integrity": "sha512-uCPQwTGjOtAYrwnU+76pYxalhjsh7iFBsHwBqDHiOPTxtICDaraO4Szw54WFTNZTAEsgHHzqFOu1mmnBOBRzDA==", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.0.3.tgz", + "integrity": "sha512-yL+ZDb+9T0ELG4VIFo/2anAOz8SvBdlqEnQnvJ3M7Scq56DvtjY0VY88bByRZB0D4J0u8olBcfrXTVONXsh4og==", "dev": true, "requires": { "debug": "^4.3.4", @@ -21664,9 +22330,9 @@ } }, "watchpack": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz", - "integrity": "sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", + "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", "requires": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -21679,20 +22345,20 @@ "dev": true }, "webpack": { - "version": "5.72.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.72.1.tgz", - "integrity": "sha512-dXG5zXCLspQR4krZVR6QgajnZOjW2K/djHvdcRaDQvsjV9z9vaW6+ja5dZOYbqBBjF6kGXka/2ZyxNdc+8Jung==", + "version": "5.74.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.74.0.tgz", + "integrity": "sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==", "requires": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^0.0.51", "@webassemblyjs/ast": "1.11.1", "@webassemblyjs/wasm-edit": "1.11.1", "@webassemblyjs/wasm-parser": "1.11.1", - "acorn": "^8.4.1", + "acorn": "^8.7.1", "acorn-import-assertions": "^1.7.6", "browserslist": "^4.14.5", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.9.3", + "enhanced-resolve": "^5.10.0", "es-module-lexer": "^0.9.0", "eslint-scope": "5.1.1", "events": "^3.2.0", @@ -21705,10 +22371,32 @@ "schema-utils": "^3.1.0", "tapable": "^2.1.1", "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.3.1", + "watchpack": "^2.4.0", "webpack-sources": "^3.2.3" }, "dependencies": { + "@types/estree": { + "version": "0.0.51", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", + "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==" + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "requires": {} + }, "eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -21723,6 +22411,11 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, "schema-utils": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", @@ -21741,22 +22434,29 @@ } }, "webpack-cli": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.9.2.tgz", - "integrity": "sha512-m3/AACnBBzK/kMTcxWHcZFPrw/eQuY4Df1TxvIWfWM2x7mRqBQCqKEd96oCUa9jkapLBaFfRce33eGDb4Pr7YQ==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.10.0.tgz", + "integrity": "sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==", "requires": { "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.1.1", - "@webpack-cli/info": "^1.4.1", - "@webpack-cli/serve": "^1.6.1", + "@webpack-cli/configtest": "^1.2.0", + "@webpack-cli/info": "^1.5.0", + "@webpack-cli/serve": "^1.7.0", "colorette": "^2.0.14", "commander": "^7.0.0", - "execa": "^5.0.0", + "cross-spawn": "^7.0.3", "fastest-levenshtein": "^1.0.12", "import-local": "^3.0.2", "interpret": "^2.2.0", "rechoir": "^0.7.0", "webpack-merge": "^5.7.3" + }, + "dependencies": { + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" + } } }, "webpack-merge": { @@ -21795,7 +22495,7 @@ "whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "dev": true, "requires": { "tr46": "~0.0.3", @@ -21805,7 +22505,7 @@ "webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", "dev": true } } @@ -21849,24 +22549,24 @@ "dev": true }, "workbox-core": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.5.3.tgz", - "integrity": "sha512-Bb9ey5n/M9x+l3fBTlLpHt9ASTzgSGj6vxni7pY72ilB/Pb3XtN+cZ9yueboVhD5+9cNQrC9n/E1fSrqWsUz7Q==" + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.5.4.tgz", + "integrity": "sha512-OXYb+m9wZm8GrORlV2vBbE5EC1FKu71GGp0H4rjmxmF4/HLbMCoTFws87M3dFwgpmg0v00K++PImpNQ6J5NQ6Q==" }, "workbox-routing": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.5.3.tgz", - "integrity": "sha512-DFjxcuRAJjjt4T34RbMm3MCn+xnd36UT/2RfPRfa8VWJGItGJIn7tG+GwVTdHmvE54i/QmVTJepyAGWtoLPTmg==", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.5.4.tgz", + "integrity": "sha512-apQswLsbrrOsBUWtr9Lf80F+P1sHnQdYodRo32SjiByYi36IDyL2r7BH1lJtFX8fwNHDa1QOVY74WKLLS6o5Pg==", "requires": { - "workbox-core": "6.5.3" + "workbox-core": "6.5.4" } }, "workbox-strategies": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.5.3.tgz", - "integrity": "sha512-MgmGRrDVXs7rtSCcetZgkSZyMpRGw8HqL2aguszOc3nUmzGZsT238z/NN9ZouCxSzDu3PQ3ZSKmovAacaIhu1w==", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.5.4.tgz", + "integrity": "sha512-DEtsxhx0LIYWkJBTQolRxG4EI0setTJkqR4m7r4YpBdxtWJH1Mbg01Cj8ZjNOO8etqfA3IZaOPHUxCs8cBsKLw==", "requires": { - "workbox-core": "6.5.3" + "workbox-core": "6.5.4" } }, "worker-loader": { @@ -21878,6 +22578,28 @@ "schema-utils": "^3.0.0" }, "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "requires": {} + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, "schema-utils": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", @@ -21938,7 +22660,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "write-file-atomic": { "version": "4.0.1", @@ -21969,9 +22691,10 @@ "dev": true }, "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true }, "yaml": { "version": "1.10.2", @@ -21980,9 +22703,9 @@ "dev": true }, "yargs": { - "version": "17.5.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz", - "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.3.1.tgz", + "integrity": "sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA==", "dev": true, "requires": { "cliui": "^7.0.2", @@ -22007,6 +22730,12 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true } } } diff --git a/package.json b/package.json index 1ec816fc569d6..a3e13eb609bb1 100644 --- a/package.json +++ b/package.json @@ -4,11 +4,11 @@ "private": true, "type": "module", "engines": { - "node": ">= 14" + "node": ">= 14.0.0" }, "dependencies": { "@claviska/jquery-minicolors": "2.3.6", - "@primer/octicons": "17.2.0", + "@primer/octicons": "17.4.0", "add-asset-webpack-plugin": "2.0.1", "css-loader": "6.7.1", "dropzone": "6.0.0-beta.2", @@ -19,16 +19,17 @@ "font-awesome": "4.7.0", "jquery": "3.6.0", "jquery.are-you-sure": "1.9.0", - "less": "4.1.2", + "less": "4.1.3", "less-loader": "11.0.0", "license-checker-webpack-plugin": "0.2.1", - "mermaid": "9.1.2", - "mini-css-extract-plugin": "2.6.0", + "mermaid": "9.1.3", + "mini-css-extract-plugin": "2.6.1", "monaco-editor": "0.33.0", "monaco-editor-webpack-plugin": "7.0.1", - "pretty-ms": "7.0.1", + "pretty-ms": "8.0.0", "sortablejs": "1.15.0", - "swagger-ui-dist": "4.11.1", + "swagger-ui-dist": "4.13.2", + "tippy.js": "6.3.7", "tributejs": "5.1.3", "uint8-to-base64": "0.2.0", "vue": "2.6.14", @@ -36,29 +37,30 @@ "vue-calendar-heatmap": "0.8.4", "vue-loader": "15.9.8", "vue-template-compiler": "2.6.14", - "webpack": "5.72.1", - "webpack-cli": "4.9.2", - "workbox-routing": "6.5.3", - "workbox-strategies": "6.5.3", + "webpack": "5.74.0", + "webpack-cli": "4.10.0", + "workbox-routing": "6.5.4", + "workbox-strategies": "6.5.4", "worker-loader": "3.0.8", "wrap-ansi": "8.0.1" }, "devDependencies": { - "@happy-dom/jest-environment": "4.0.1", - "@stoplight/spectral-cli": "6.4.1", - "eslint": "8.15.0", - "eslint-plugin-html": "6.2.0", + "@happy-dom/jest-environment": "6.0.4", + "@stoplight/spectral-cli": "6.5.0", + "eslint": "8.21.0", "eslint-plugin-import": "2.26.0", "eslint-plugin-jquery": "1.5.1", - "eslint-plugin-unicorn": "42.0.0", - "eslint-plugin-vue": "9.0.1", - "jest": "28.1.0", - "jest-extended": "2.0.0", + "eslint-plugin-sonarjs": "0.14.0", + "eslint-plugin-unicorn": "43.0.2", + "eslint-plugin-vue": "9.3.0", + "jest": "28.1.3", + "jest-extended": "3.0.1", + "markdownlint-cli": "0.32.1", "postcss-less": "6.0.0", - "stylelint": "14.8.2", - "stylelint-config-standard": "25.0.0", + "stylelint": "14.9.1", + "stylelint-config-standard": "26.0.0", "svgo": "2.8.0", - "updates": "13.0.5" + "updates": "13.1.4" }, "browserslist": [ "defaults", diff --git a/public/img/svg/gitea-pub.svg b/public/img/svg/gitea-pub.svg new file mode 100644 index 0000000000000..4a750c7082edb --- /dev/null +++ b/public/img/svg/gitea-pub.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/svg/octicon-cache.svg b/public/img/svg/octicon-cache.svg new file mode 100644 index 0000000000000..20b14138d910d --- /dev/null +++ b/public/img/svg/octicon-cache.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/svg/octicon-checkbox.svg b/public/img/svg/octicon-checkbox.svg new file mode 100644 index 0000000000000..f0313bc747fc9 --- /dev/null +++ b/public/img/svg/octicon-checkbox.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/svg/octicon-command-palette.svg b/public/img/svg/octicon-command-palette.svg new file mode 100644 index 0000000000000..92fcd63149510 --- /dev/null +++ b/public/img/svg/octicon-command-palette.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/svg/octicon-copilot-error.svg b/public/img/svg/octicon-copilot-error.svg new file mode 100644 index 0000000000000..97c88a12bf1a9 --- /dev/null +++ b/public/img/svg/octicon-copilot-error.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/svg/octicon-copilot-warning.svg b/public/img/svg/octicon-copilot-warning.svg new file mode 100644 index 0000000000000..32bd7361aeddf --- /dev/null +++ b/public/img/svg/octicon-copilot-warning.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/svg/octicon-copilot.svg b/public/img/svg/octicon-copilot.svg new file mode 100644 index 0000000000000..1a99f1f5f988f --- /dev/null +++ b/public/img/svg/octicon-copilot.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/svg/octicon-git-merge-queue.svg b/public/img/svg/octicon-git-merge-queue.svg new file mode 100644 index 0000000000000..17d7767b058cf --- /dev/null +++ b/public/img/svg/octicon-git-merge-queue.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/svg/octicon-paperclip.svg b/public/img/svg/octicon-paperclip.svg new file mode 100644 index 0000000000000..ddae143818ffe --- /dev/null +++ b/public/img/svg/octicon-paperclip.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/svg/octicon-table.svg b/public/img/svg/octicon-table.svg index 905b2bb9b4c26..5b80f78357b65 100644 --- a/public/img/svg/octicon-table.svg +++ b/public/img/svg/octicon-table.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/public/img/svg/octicon-tasklist.svg b/public/img/svg/octicon-tasklist.svg index 81e41a87ced59..41b7c90f6de43 100644 --- a/public/img/svg/octicon-tasklist.svg +++ b/public/img/svg/octicon-tasklist.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/routers/api/packages/api.go b/routers/api/packages/api.go index b5fdc739d7c10..4b274860dcdff 100644 --- a/routers/api/packages/api.go +++ b/routers/api/packages/api.go @@ -21,6 +21,7 @@ import ( "code.gitea.io/gitea/routers/api/packages/maven" "code.gitea.io/gitea/routers/api/packages/npm" "code.gitea.io/gitea/routers/api/packages/nuget" + "code.gitea.io/gitea/routers/api/packages/pub" "code.gitea.io/gitea/routers/api/packages/pypi" "code.gitea.io/gitea/routers/api/packages/rubygems" "code.gitea.io/gitea/services/auth" @@ -216,6 +217,20 @@ func Routes() *web.Route { }, reqPackageAccess(perm.AccessModeWrite)) }) }) + r.Group("/pub", func() { + r.Group("/api/packages", func() { + r.Group("/versions/new", func() { + r.Get("", pub.RequestUpload) + r.Post("/upload", pub.UploadPackageFile) + r.Get("/finalize/{id}/{version}", pub.FinalizePackage) + }, reqPackageAccess(perm.AccessModeWrite)) + r.Group("/{id}", func() { + r.Get("", pub.EnumeratePackageVersions) + r.Get("/files/{version}", pub.DownloadPackageFile) + r.Get("/{version}", pub.PackageVersionMetadata) + }) + }) + }) r.Group("/pypi", func() { r.Post("/", reqPackageAccess(perm.AccessModeWrite), pypi.UploadPackageFile) r.Get("/files/{id}/{version}/{filename}", pypi.DownloadPackageFile) @@ -257,6 +272,7 @@ func ContainerRoutes() *web.Route { r.Get("", container.ReqContainerAccess, container.DetermineSupport) r.Get("/token", container.Authenticate) + r.Get("/_catalog", container.ReqContainerAccess, container.GetRepositoryList) r.Group("/{username}", func() { r.Group("/{image}", func() { r.Group("/blobs/uploads", func() { diff --git a/routers/api/packages/composer/api.go b/routers/api/packages/composer/api.go index 5e1cc293da0f8..45bb7eae1c197 100644 --- a/routers/api/packages/composer/api.go +++ b/routers/api/packages/composer/api.go @@ -88,7 +88,7 @@ func createPackageMetadataResponse(registryURL string, pds []*packages_model.Pac for _, pd := range pds { packageType := "" - for _, pvp := range pd.Properties { + for _, pvp := range pd.VersionProperties { if pvp.Name == composer_module.TypeProperty { packageType = pvp.Value break diff --git a/routers/api/packages/composer/composer.go b/routers/api/packages/composer/composer.go index 23de28c7f9ed2..81cef39f1c496 100644 --- a/routers/api/packages/composer/composer.go +++ b/routers/api/packages/composer/composer.go @@ -19,6 +19,7 @@ import ( packages_module "code.gitea.io/gitea/modules/packages" composer_module "code.gitea.io/gitea/modules/packages/composer" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/packages/helper" packages_service "code.gitea.io/gitea/services/packages" @@ -62,10 +63,11 @@ func SearchPackages(ctx *context.Context) { } opts := &packages_model.PackageSearchOptions{ - OwnerID: ctx.Package.Owner.ID, - Type: packages_model.TypeComposer, - Name: packages_model.SearchValue{Value: ctx.FormTrim("q")}, - Paginator: &paginator, + OwnerID: ctx.Package.Owner.ID, + Type: packages_model.TypeComposer, + Name: packages_model.SearchValue{Value: ctx.FormTrim("q")}, + IsInternal: util.OptionalBoolFalse, + Paginator: &paginator, } if ctx.FormTrim("type") != "" { opts.Properties = map[string]string{ @@ -225,7 +227,7 @@ func UploadPackage(ctx *context.Context) { SemverCompatible: true, Creator: ctx.Doer, Metadata: cp.Metadata, - Properties: map[string]string{ + VersionProperties: map[string]string{ composer_module.TypeProperty: cp.Type, }, }, diff --git a/routers/api/packages/container/blob.go b/routers/api/packages/container/blob.go index 8f6254f583213..8a9cbd4a15fbf 100644 --- a/routers/api/packages/container/blob.go +++ b/routers/api/packages/container/blob.go @@ -29,6 +29,7 @@ func saveAsPackageBlob(hsr packages_module.HashedSizeReader, pi *packages_servic contentStore := packages_module.NewContentStore() err := db.WithTx(func(ctx context.Context) error { + created := true p := &packages_model.Package{ OwnerID: pi.Owner.ID, Type: packages_model.TypeContainer, @@ -37,12 +38,21 @@ func saveAsPackageBlob(hsr packages_module.HashedSizeReader, pi *packages_servic } var err error if p, err = packages_model.TryInsertPackage(ctx, p); err != nil { - if err != packages_model.ErrDuplicatePackage { + if err == packages_model.ErrDuplicatePackage { + created = false + } else { log.Error("Error inserting package: %v", err) return err } } + if created { + if _, err := packages_model.InsertProperty(ctx, packages_model.PropertyTypePackage, p.ID, container_module.PropertyRepository, strings.ToLower(pi.Owner.LowerName+"/"+pi.Name)); err != nil { + log.Error("Error setting package property: %v", err) + return err + } + } + pv := &packages_model.PackageVersion{ PackageID: p.ID, CreatorID: pi.Owner.ID, diff --git a/routers/api/packages/container/container.go b/routers/api/packages/container/container.go index 2a564b3446a16..b961cd4afb393 100644 --- a/routers/api/packages/container/container.go +++ b/routers/api/packages/container/container.go @@ -112,7 +112,7 @@ func apiErrorDefined(ctx *context.Context, err *namedError) { // ReqContainerAccess is a middleware which checks the current user valid (real user or ghost for anonymous access) func ReqContainerAccess(ctx *context.Context) { if ctx.Doer == nil { - ctx.Resp.Header().Add("WWW-Authenticate", `Bearer realm="`+setting.AppURL+`v2/token"`) + ctx.Resp.Header().Add("WWW-Authenticate", `Bearer realm="`+setting.AppURL+`v2/token",service="container_registry",scope="*"`) apiErrorDefined(ctx, errUnauthorized) } } @@ -151,6 +151,39 @@ func Authenticate(ctx *context.Context) { }) } +// https://docs.docker.com/registry/spec/api/#listing-repositories +func GetRepositoryList(ctx *context.Context) { + n := ctx.FormInt("n") + if n <= 0 || n > 100 { + n = 100 + } + last := ctx.FormTrim("last") + + repositories, err := container_model.GetRepositories(ctx, ctx.Doer, n, last) + if err != nil { + apiError(ctx, http.StatusInternalServerError, err) + return + } + + type RepositoryList struct { + Repositories []string `json:"repositories"` + } + + if len(repositories) == n { + v := url.Values{} + if n > 0 { + v.Add("n", strconv.Itoa(n)) + } + v.Add("last", repositories[len(repositories)-1]) + + ctx.Resp.Header().Set("Link", fmt.Sprintf(`; rel="next"`, v.Encode())) + } + + jsonResponse(ctx, http.StatusOK, RepositoryList{ + Repositories: repositories, + }) +} + // https://github.com/opencontainers/distribution-spec/blob/main/spec.md#mounting-a-blob-from-another-repository // https://github.com/opencontainers/distribution-spec/blob/main/spec.md#single-post // https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pushing-a-blob-in-chunks diff --git a/routers/api/packages/container/manifest.go b/routers/api/packages/container/manifest.go index d899ac8ee2f6a..319c9bcabc11c 100644 --- a/routers/api/packages/container/manifest.go +++ b/routers/api/packages/container/manifest.go @@ -267,6 +267,7 @@ func processImageManifestIndex(mci *manifestCreationInfo, buf *packages_module.H } func createPackageAndVersion(ctx context.Context, mci *manifestCreationInfo, metadata *container_module.Metadata) (*packages_model.PackageVersion, error) { + created := true p := &packages_model.Package{ OwnerID: mci.Owner.ID, Type: packages_model.TypeContainer, @@ -275,12 +276,21 @@ func createPackageAndVersion(ctx context.Context, mci *manifestCreationInfo, met } var err error if p, err = packages_model.TryInsertPackage(ctx, p); err != nil { - if err != packages_model.ErrDuplicatePackage { + if err == packages_model.ErrDuplicatePackage { + created = false + } else { log.Error("Error inserting package: %v", err) return nil, err } } + if created { + if _, err := packages_model.InsertProperty(ctx, packages_model.PropertyTypePackage, p.ID, container_module.PropertyRepository, strings.ToLower(mci.Owner.LowerName+"/"+mci.Image)); err != nil { + log.Error("Error setting package property: %v", err) + return nil, err + } + } + metadata.IsTagged = mci.IsTagged metadataJSON, err := json.Marshal(metadata) diff --git a/routers/api/packages/generic/generic.go b/routers/api/packages/generic/generic.go index d862f77259ace..9a3a185d9da50 100644 --- a/routers/api/packages/generic/generic.go +++ b/routers/api/packages/generic/generic.go @@ -8,6 +8,7 @@ import ( "errors" "net/http" "regexp" + "strings" packages_model "code.gitea.io/gitea/models/packages" "code.gitea.io/gitea/modules/context" @@ -15,8 +16,6 @@ import ( packages_module "code.gitea.io/gitea/modules/packages" "code.gitea.io/gitea/routers/api/packages/helper" packages_service "code.gitea.io/gitea/services/packages" - - "github.com/hashicorp/go-version" ) var ( @@ -97,8 +96,7 @@ func UploadPackage(ctx *context.Context) { Name: packageName, Version: packageVersion, }, - SemverCompatible: true, - Creator: ctx.Doer, + Creator: ctx.Doer, }, &packages_service.PackageFileCreationInfo{ PackageFileInfo: packages_service.PackageFileInfo{ @@ -157,10 +155,10 @@ func sanitizeParameters(ctx *context.Context) (string, string, string, error) { return "", "", "", errors.New("Invalid package name or filename") } - v, err := version.NewSemver(ctx.Params("packageversion")) - if err != nil { - return "", "", "", err + packageVersion := strings.TrimSpace(ctx.Params("packageversion")) + if packageVersion == "" { + return "", "", "", errors.New("Invalid package version") } - return packageName, v.String(), filename, nil + return packageName, packageVersion, filename, nil } diff --git a/routers/api/packages/helm/helm.go b/routers/api/packages/helm/helm.go index ae0643a35a90f..f59cfc7c7b38f 100644 --- a/routers/api/packages/helm/helm.go +++ b/routers/api/packages/helm/helm.go @@ -19,6 +19,7 @@ import ( packages_module "code.gitea.io/gitea/modules/packages" helm_module "code.gitea.io/gitea/modules/packages/helm" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/packages/helper" packages_service "code.gitea.io/gitea/services/packages" @@ -39,8 +40,9 @@ func apiError(ctx *context.Context, status int, obj interface{}) { // Index generates the Helm charts index func Index(ctx *context.Context) { pvs, _, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{ - OwnerID: ctx.Package.Owner.ID, - Type: packages_model.TypeHelm, + OwnerID: ctx.Package.Owner.ID, + Type: packages_model.TypeHelm, + IsInternal: util.OptionalBoolFalse, }) if err != nil { apiError(ctx, http.StatusInternalServerError, err) @@ -108,6 +110,7 @@ func DownloadPackageFile(ctx *context.Context) { Value: ctx.Params("package"), }, HasFileWithName: filename, + IsInternal: util.OptionalBoolFalse, }) if err != nil { apiError(ctx, http.StatusInternalServerError, err) diff --git a/routers/api/packages/maven/maven.go b/routers/api/packages/maven/maven.go index bba4babf04f6f..072a15f95c41d 100644 --- a/routers/api/packages/maven/maven.go +++ b/routers/api/packages/maven/maven.go @@ -266,8 +266,9 @@ func UploadPackageFile(ctx *context.Context) { PackageFileInfo: packages_service.PackageFileInfo{ Filename: params.Filename, }, - Data: buf, - IsLead: false, + Data: buf, + IsLead: false, + OverwriteExisting: params.IsMeta, } // If it's the package pom file extract the metadata diff --git a/routers/api/packages/npm/api.go b/routers/api/packages/npm/api.go index 56c897704398d..4b6b803971b7a 100644 --- a/routers/api/packages/npm/api.go +++ b/routers/api/packages/npm/api.go @@ -25,7 +25,7 @@ func createPackageMetadataResponse(registryURL string, pds []*packages_model.Pac for _, pd := range pds { versions[pd.SemVer.String()] = createPackageMetadataVersion(registryURL, pd) - for _, pvp := range pd.Properties { + for _, pvp := range pd.VersionProperties { if pvp.Name == npm_module.TagProperty { distTags[pvp.Value] = pd.Version.Version } diff --git a/routers/api/packages/npm/npm.go b/routers/api/packages/npm/npm.go index d127134d44558..152edc681a048 100644 --- a/routers/api/packages/npm/npm.go +++ b/routers/api/packages/npm/npm.go @@ -18,6 +18,7 @@ import ( packages_module "code.gitea.io/gitea/modules/packages" npm_module "code.gitea.io/gitea/modules/packages/npm" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/packages/helper" packages_service "code.gitea.io/gitea/services/packages" @@ -261,6 +262,7 @@ func setPackageTag(tag string, pv *packages_model.PackageVersion, deleteOnly boo Properties: map[string]string{ npm_module.TagProperty: tag, }, + IsInternal: util.OptionalBoolFalse, }) if err != nil { return err diff --git a/routers/api/packages/nuget/nuget.go b/routers/api/packages/nuget/nuget.go index 013c0c1e33543..81ea28bcad498 100644 --- a/routers/api/packages/nuget/nuget.go +++ b/routers/api/packages/nuget/nuget.go @@ -17,6 +17,7 @@ import ( packages_module "code.gitea.io/gitea/modules/packages" nuget_module "code.gitea.io/gitea/modules/packages/nuget" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/packages/helper" packages_service "code.gitea.io/gitea/services/packages" ) @@ -39,9 +40,10 @@ func ServiceIndex(ctx *context.Context) { // SearchService https://docs.microsoft.com/en-us/nuget/api/search-query-service-resource#search-for-packages func SearchService(ctx *context.Context) { pvs, count, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{ - OwnerID: ctx.Package.Owner.ID, - Type: packages_model.TypeNuGet, - Name: packages_model.SearchValue{Value: ctx.FormTrim("q")}, + OwnerID: ctx.Package.Owner.ID, + Type: packages_model.TypeNuGet, + Name: packages_model.SearchValue{Value: ctx.FormTrim("q")}, + IsInternal: util.OptionalBoolFalse, Paginator: db.NewAbsoluteListOptions( ctx.FormInt("skip"), ctx.FormInt("take"), @@ -100,7 +102,7 @@ func RegistrationLeaf(ctx *context.Context) { packageName := ctx.Params("id") packageVersion := strings.TrimSuffix(ctx.Params("version"), ".json") - pv, err := packages_model.GetVersionByNameAndVersion(db.DefaultContext, ctx.Package.Owner.ID, packages_model.TypeNuGet, packageName, packageVersion) + pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeNuGet, packageName, packageVersion) if err != nil { if err == packages_model.ErrPackageNotExist { apiError(ctx, http.StatusNotFound, err) @@ -215,7 +217,7 @@ func UploadPackage(ctx *context.Context) { ) if err != nil { if err == packages_model.ErrDuplicatePackageVersion { - apiError(ctx, http.StatusBadRequest, err) + apiError(ctx, http.StatusConflict, err) return } apiError(ctx, http.StatusInternalServerError, err) @@ -272,7 +274,7 @@ func UploadSymbolPackage(ctx *context.Context) { case packages_model.ErrPackageNotExist: apiError(ctx, http.StatusNotFound, err) case packages_model.ErrDuplicatePackageFile: - apiError(ctx, http.StatusBadRequest, err) + apiError(ctx, http.StatusConflict, err) default: apiError(ctx, http.StatusInternalServerError, err) } @@ -297,7 +299,7 @@ func UploadSymbolPackage(ctx *context.Context) { if err != nil { switch err { case packages_model.ErrDuplicatePackageFile: - apiError(ctx, http.StatusBadRequest, err) + apiError(ctx, http.StatusConflict, err) default: apiError(ctx, http.StatusInternalServerError, err) } @@ -412,4 +414,6 @@ func DeletePackage(ctx *context.Context) { } apiError(ctx, http.StatusInternalServerError, err) } + + ctx.Status(http.StatusNoContent) } diff --git a/routers/api/packages/pub/pub.go b/routers/api/packages/pub/pub.go new file mode 100644 index 0000000000000..470f4462388ae --- /dev/null +++ b/routers/api/packages/pub/pub.go @@ -0,0 +1,275 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package pub + +import ( + "fmt" + "io" + "net/http" + "net/url" + "sort" + "strings" + "time" + + packages_model "code.gitea.io/gitea/models/packages" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/json" + "code.gitea.io/gitea/modules/log" + packages_module "code.gitea.io/gitea/modules/packages" + pub_module "code.gitea.io/gitea/modules/packages/pub" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/routers/api/packages/helper" + packages_service "code.gitea.io/gitea/services/packages" +) + +func jsonResponse(ctx *context.Context, status int, obj interface{}) { + resp := ctx.Resp + resp.Header().Set("Content-Type", "application/vnd.pub.v2+json") + resp.WriteHeader(status) + if err := json.NewEncoder(resp).Encode(obj); err != nil { + log.Error("JSON encode: %v", err) + } +} + +func apiError(ctx *context.Context, status int, obj interface{}) { + type Error struct { + Code string `json:"code"` + Message string `json:"message"` + } + type ErrorWrapper struct { + Error Error `json:"error"` + } + + helper.LogAndProcessError(ctx, status, obj, func(message string) { + jsonResponse(ctx, status, ErrorWrapper{ + Error: Error{ + Code: http.StatusText(status), + Message: message, + }, + }) + }) +} + +type packageVersions struct { + Name string `json:"name"` + Latest *versionMetadata `json:"latest"` + Versions []*versionMetadata `json:"versions"` +} + +type versionMetadata struct { + Version string `json:"version"` + ArchiveURL string `json:"archive_url"` + Published time.Time `json:"published"` + Pubspec interface{} `json:"pubspec,omitempty"` +} + +func packageDescriptorToMetadata(baseURL string, pd *packages_model.PackageDescriptor) *versionMetadata { + return &versionMetadata{ + Version: pd.Version.Version, + ArchiveURL: fmt.Sprintf("%s/files/%s.tar.gz", baseURL, url.PathEscape(pd.Version.Version)), + Published: time.Unix(int64(pd.Version.CreatedUnix), 0), + Pubspec: pd.Metadata.(*pub_module.Metadata).Pubspec, + } +} + +func baseURL(ctx *context.Context) string { + return setting.AppURL + "api/packages/" + ctx.Package.Owner.Name + "/pub/api/packages" +} + +// https://github.com/dart-lang/pub/blob/master/doc/repository-spec-v2.md#list-all-versions-of-a-package +func EnumeratePackageVersions(ctx *context.Context) { + packageName := ctx.Params("id") + + pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypePub, packageName) + if err != nil { + apiError(ctx, http.StatusInternalServerError, err) + return + } + if len(pvs) == 0 { + apiError(ctx, http.StatusNotFound, err) + return + } + + pds, err := packages_model.GetPackageDescriptors(ctx, pvs) + if err != nil { + apiError(ctx, http.StatusInternalServerError, err) + return + } + + sort.Slice(pds, func(i, j int) bool { + return pds[i].SemVer.LessThan(pds[j].SemVer) + }) + + baseURL := fmt.Sprintf("%s/%s", baseURL(ctx), url.PathEscape(pds[0].Package.Name)) + + versions := make([]*versionMetadata, 0, len(pds)) + for _, pd := range pds { + versions = append(versions, packageDescriptorToMetadata(baseURL, pd)) + } + + jsonResponse(ctx, http.StatusOK, &packageVersions{ + Name: pds[0].Package.Name, + Latest: packageDescriptorToMetadata(baseURL, pds[0]), + Versions: versions, + }) +} + +// https://github.com/dart-lang/pub/blob/master/doc/repository-spec-v2.md#deprecated-inspect-a-specific-version-of-a-package +func PackageVersionMetadata(ctx *context.Context) { + packageName := ctx.Params("id") + packageVersion := ctx.Params("version") + + pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypePub, packageName, packageVersion) + if err != nil { + if err == packages_model.ErrPackageNotExist { + apiError(ctx, http.StatusNotFound, err) + return + } + apiError(ctx, http.StatusInternalServerError, err) + return + } + + pd, err := packages_model.GetPackageDescriptor(ctx, pv) + if err != nil { + apiError(ctx, http.StatusInternalServerError, err) + return + } + + jsonResponse(ctx, http.StatusOK, packageDescriptorToMetadata( + fmt.Sprintf("%s/%s", baseURL(ctx), url.PathEscape(pd.Package.Name)), + pd, + )) +} + +// https://github.com/dart-lang/pub/blob/master/doc/repository-spec-v2.md#publishing-packages +func RequestUpload(ctx *context.Context) { + type UploadRequest struct { + URL string `json:"url"` + Fields map[string]string `json:"fields"` + } + + jsonResponse(ctx, http.StatusOK, UploadRequest{ + URL: baseURL(ctx) + "/versions/new/upload", + Fields: make(map[string]string), + }) +} + +// https://github.com/dart-lang/pub/blob/master/doc/repository-spec-v2.md#publishing-packages +func UploadPackageFile(ctx *context.Context) { + file, _, err := ctx.Req.FormFile("file") + if err != nil { + apiError(ctx, http.StatusBadRequest, err) + return + } + defer file.Close() + + buf, err := packages_module.CreateHashedBufferFromReader(file, 32*1024*1024) + if err != nil { + apiError(ctx, http.StatusInternalServerError, err) + return + } + defer buf.Close() + + pck, err := pub_module.ParsePackage(buf) + if err != nil { + apiError(ctx, http.StatusInternalServerError, err) + return + } + + if _, err := buf.Seek(0, io.SeekStart); err != nil { + apiError(ctx, http.StatusInternalServerError, err) + return + } + + _, _, err = packages_service.CreatePackageAndAddFile( + &packages_service.PackageCreationInfo{ + PackageInfo: packages_service.PackageInfo{ + Owner: ctx.Package.Owner, + PackageType: packages_model.TypePub, + Name: pck.Name, + Version: pck.Version, + }, + SemverCompatible: true, + Creator: ctx.Doer, + Metadata: pck.Metadata, + }, + &packages_service.PackageFileCreationInfo{ + PackageFileInfo: packages_service.PackageFileInfo{ + Filename: strings.ToLower(pck.Version + ".tar.gz"), + }, + Data: buf, + IsLead: true, + }, + ) + if err != nil { + if err == packages_model.ErrDuplicatePackageVersion { + apiError(ctx, http.StatusBadRequest, err) + return + } + apiError(ctx, http.StatusInternalServerError, err) + return + } + + ctx.Resp.Header().Set("Location", fmt.Sprintf("%s/versions/new/finalize/%s/%s", baseURL(ctx), url.PathEscape(pck.Name), url.PathEscape(pck.Version))) + ctx.Status(http.StatusNoContent) +} + +// https://github.com/dart-lang/pub/blob/master/doc/repository-spec-v2.md#publishing-packages +func FinalizePackage(ctx *context.Context) { + packageName := ctx.Params("id") + packageVersion := ctx.Params("version") + + _, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypePub, packageName, packageVersion) + if err != nil { + if err == packages_model.ErrPackageNotExist { + apiError(ctx, http.StatusNotFound, err) + return + } + apiError(ctx, http.StatusInternalServerError, err) + return + } + + type Success struct { + Message string `json:"message"` + } + type SuccessWrapper struct { + Success Success `json:"success"` + } + + jsonResponse(ctx, http.StatusOK, SuccessWrapper{Success{}}) +} + +// https://github.com/dart-lang/pub/blob/master/doc/repository-spec-v2.md#deprecated-download-a-specific-version-of-a-package +func DownloadPackageFile(ctx *context.Context) { + packageName := ctx.Params("id") + packageVersion := strings.TrimSuffix(ctx.Params("version"), ".tar.gz") + + pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypePub, packageName, packageVersion) + if err != nil { + if err == packages_model.ErrPackageNotExist { + apiError(ctx, http.StatusNotFound, err) + return + } + apiError(ctx, http.StatusInternalServerError, err) + return + } + + pd, err := packages_model.GetPackageDescriptor(ctx, pv) + if err != nil { + apiError(ctx, http.StatusInternalServerError, err) + return + } + + pf := pd.Files[0].File + + s, _, err := packages_service.GetPackageFileStream(ctx, pf) + if err != nil { + apiError(ctx, http.StatusInternalServerError, err) + return + } + defer s.Close() + + ctx.ServeStream(s, pf.Name) +} diff --git a/routers/api/packages/rubygems/rubygems.go b/routers/api/packages/rubygems/rubygems.go index b3815a914ea7e..4f066a83033e2 100644 --- a/routers/api/packages/rubygems/rubygems.go +++ b/routers/api/packages/rubygems/rubygems.go @@ -16,6 +16,7 @@ import ( "code.gitea.io/gitea/modules/context" packages_module "code.gitea.io/gitea/modules/packages" rubygems_module "code.gitea.io/gitea/modules/packages/rubygems" + "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/packages/helper" packages_service "code.gitea.io/gitea/services/packages" ) @@ -40,8 +41,9 @@ func EnumeratePackages(ctx *context.Context) { // EnumeratePackagesLatest serves the list of the latest version of every package func EnumeratePackagesLatest(ctx *context.Context) { pvs, _, err := packages_model.SearchLatestVersions(ctx, &packages_model.PackageSearchOptions{ - OwnerID: ctx.Package.Owner.ID, - Type: packages_model.TypeRubyGems, + OwnerID: ctx.Package.Owner.ID, + Type: packages_model.TypeRubyGems, + IsInternal: util.OptionalBoolFalse, }) if err != nil { apiError(ctx, http.StatusInternalServerError, err) @@ -289,6 +291,7 @@ func getVersionsByFilename(ctx *context.Context, filename string) ([]*packages_m OwnerID: ctx.Package.Owner.ID, Type: packages_model.TypeRubyGems, HasFileWithName: filename, + IsInternal: util.OptionalBoolFalse, }) return pvs, err } diff --git a/routers/api/v1/admin/user.go b/routers/api/v1/admin/user.go index 71932136b1f98..1a4b02001133d 100644 --- a/routers/api/v1/admin/user.go +++ b/routers/api/v1/admin/user.go @@ -316,7 +316,7 @@ func DeleteUser(ctx *context.APIContext) { return } - if err := user_service.DeleteUser(ctx.ContextUser); err != nil { + if err := user_service.DeleteUser(ctx, ctx.ContextUser, ctx.FormBool("purge")); err != nil { if models.IsErrUserOwnRepos(err) || models.IsErrUserHasOrgs(err) || models.IsErrUserOwnPackages(err) { diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 44e0c290a0881..e1478fa2aa99a 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -982,6 +982,15 @@ func Routes() *web.Route { }) }, reqRepoReader(unit.TypeReleases)) m.Post("/mirror-sync", reqToken(), reqRepoWriter(unit.TypeCode), repo.MirrorSync) + m.Post("/push_mirrors-sync", reqAdmin(), repo.PushMirrorSync) + m.Group("/push_mirrors", func() { + m.Combo("").Get(repo.ListPushMirrors). + Post(bind(api.CreatePushMirrorOption{}), repo.AddPushMirror) + m.Combo("/{name}"). + Delete(repo.DeletePushMirrorByRemoteName). + Get(repo.GetPushMirrorByName) + }, reqAdmin()) + m.Get("/editorconfig/{filename}", context.ReferencesGitRepo(), context.RepoRefForAPI, reqRepoReader(unit.TypeCode), repo.GetEditorconfig) m.Group("/pulls", func() { m.Combo("").Get(repo.ListPullRequests). diff --git a/routers/api/v1/packages/package.go b/routers/api/v1/packages/package.go index 038924737ac7c..2c023891022aa 100644 --- a/routers/api/v1/packages/package.go +++ b/routers/api/v1/packages/package.go @@ -11,6 +11,7 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/v1/utils" packages_service "code.gitea.io/gitea/services/packages" ) @@ -40,7 +41,7 @@ func ListPackages(ctx *context.APIContext) { // in: query // description: package type filter // type: string - // enum: [composer, conan, container, generic, helm, maven, npm, nuget, pypi, rubygems] + // enum: [composer, conan, container, generic, helm, maven, npm, nuget, pub, pypi, rubygems] // - name: q // in: query // description: name filter @@ -55,10 +56,11 @@ func ListPackages(ctx *context.APIContext) { query := ctx.FormTrim("q") pvs, count, err := packages.SearchVersions(ctx, &packages.PackageSearchOptions{ - OwnerID: ctx.Package.Owner.ID, - Type: packages.Type(packageType), - Name: packages.SearchValue{Value: query}, - Paginator: &listOptions, + OwnerID: ctx.Package.Owner.ID, + Type: packages.Type(packageType), + Name: packages.SearchValue{Value: query}, + IsInternal: util.OptionalBoolFalse, + Paginator: &listOptions, }) if err != nil { ctx.Error(http.StatusInternalServerError, "SearchVersions", err) diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go index 1ac1088839231..8353a4e501cd7 100644 --- a/routers/api/v1/repo/file.go +++ b/routers/api/v1/repo/file.go @@ -18,7 +18,6 @@ import ( git_model "code.gitea.io/gitea/models/git" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" - "code.gitea.io/gitea/modules/cache" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/httpcache" @@ -33,6 +32,8 @@ import ( files_service "code.gitea.io/gitea/services/repository/files" ) +const giteaObjectTypeHeader = "X-Gitea-Object-Type" + // GetRawFile get a file by path on a repository func GetRawFile(ctx *context.APIContext) { // swagger:operation GET /repos/{owner}/{repo}/raw/{filepath} repository repoGetRawFile @@ -72,11 +73,13 @@ func GetRawFile(ctx *context.APIContext) { return } - blob, lastModified := getBlobForEntry(ctx) + blob, entry, lastModified := getBlobForEntry(ctx) if ctx.Written() { return } + ctx.RespHeader().Set(giteaObjectTypeHeader, string(files_service.GetObjectTypeFromTreeEntry(entry))) + if err := common.ServeBlob(ctx.Context, blob, lastModified); err != nil { ctx.Error(http.StatusInternalServerError, "ServeBlob", err) } @@ -119,11 +122,13 @@ func GetRawFileOrLFS(ctx *context.APIContext) { return } - blob, lastModified := getBlobForEntry(ctx) + blob, entry, lastModified := getBlobForEntry(ctx) if ctx.Written() { return } + ctx.RespHeader().Set(giteaObjectTypeHeader, string(files_service.GetObjectTypeFromTreeEntry(entry))) + // LFS Pointer files are at most 1024 bytes - so any blob greater than 1024 bytes cannot be an LFS file if blob.Size() > 1024 { // First handle caching for the blob @@ -218,7 +223,7 @@ func GetRawFileOrLFS(ctx *context.APIContext) { } } -func getBlobForEntry(ctx *context.APIContext) (blob *git.Blob, lastModified time.Time) { +func getBlobForEntry(ctx *context.APIContext) (blob *git.Blob, entry *git.TreeEntry, lastModified time.Time) { entry, err := ctx.Repo.Commit.GetTreeEntryByPath(ctx.Repo.TreePath) if err != nil { if git.IsErrNotExist(err) { @@ -234,12 +239,7 @@ func getBlobForEntry(ctx *context.APIContext) (blob *git.Blob, lastModified time return } - var c *git.LastCommitCache - if setting.CacheService.LastCommit.Enabled && ctx.Repo.CommitsCount >= setting.CacheService.LastCommit.CommitsCount { - c = git.NewLastCommitCache(ctx.Repo.Repository.FullName(), ctx.Repo.GitRepo, setting.LastCommitCacheTTLSeconds, cache.GetCache()) - } - - info, _, err := git.Entries([]*git.TreeEntry{entry}).GetCommitsInfo(ctx, ctx.Repo.Commit, path.Dir("/" + ctx.Repo.TreePath)[1:], c) + info, _, err := git.Entries([]*git.TreeEntry{entry}).GetCommitsInfo(ctx, ctx.Repo.Commit, path.Dir("/" + ctx.Repo.TreePath)[1:]) if err != nil { ctx.Error(http.StatusInternalServerError, "GetCommitsInfo", err) return @@ -251,7 +251,7 @@ func getBlobForEntry(ctx *context.APIContext) (blob *git.Blob, lastModified time } blob = entry.Blob() - return blob, lastModified + return blob, entry, lastModified } // GetArchive get archive of a repository diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index ddad18ef62caf..08e3e037417c0 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -282,7 +282,7 @@ func SearchIssues(ctx *context.APIContext) { } } - ctx.SetLinkHeader(int(filteredCount), setting.UI.IssuePagingNum) + ctx.SetLinkHeader(int(filteredCount), limit) ctx.SetTotalCountHeader(filteredCount) ctx.JSON(http.StatusOK, convert.ToAPIIssueList(issues)) } diff --git a/routers/api/v1/repo/mirror.go b/routers/api/v1/repo/mirror.go index 3d29383550c32..91e5e0c031617 100644 --- a/routers/api/v1/repo/mirror.go +++ b/routers/api/v1/repo/mirror.go @@ -6,13 +6,25 @@ package repo import ( "errors" + "fmt" "net/http" + "time" + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/convert" mirror_module "code.gitea.io/gitea/modules/mirror" "code.gitea.io/gitea/modules/setting" + api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/forms" + "code.gitea.io/gitea/services/migrations" + mirror_service "code.gitea.io/gitea/services/mirror" ) // MirrorSync adds a mirrored repository to the sync queue @@ -63,3 +75,317 @@ func MirrorSync(ctx *context.APIContext) { ctx.Status(http.StatusOK) } + +// PushMirrorSync adds all push mirrored repositories to the sync queue +func PushMirrorSync(ctx *context.APIContext) { + // swagger:operation POST /repos/{owner}/{repo}/push_mirrors-sync repository repoPushMirrorSync + // --- + // summary: Sync all push mirrored repository + // produces: + // - application/json + // parameters: + // - name: owner + // in: path + // description: owner of the repo to sync + // type: string + // required: true + // - name: repo + // in: path + // description: name of the repo to sync + // type: string + // required: true + // responses: + // "200": + // "$ref": "#/responses/empty" + // "400": + // "$ref": "#/responses/error" + // "403": + // "$ref": "#/responses/forbidden" + + if !setting.Mirror.Enabled { + ctx.Error(http.StatusBadRequest, "PushMirrorSync", "Mirror feature is disabled") + return + } + // Get All push mirrors of a specific repo + pushMirrors, _, err := repo_model.GetPushMirrorsByRepoID(ctx, ctx.Repo.Repository.ID, db.ListOptions{}) + if err != nil { + ctx.Error(http.StatusNotFound, "PushMirrorSync", err) + return + } + for _, mirror := range pushMirrors { + ok := mirror_service.SyncPushMirror(ctx, mirror.ID) + if !ok { + ctx.Error(http.StatusInternalServerError, "PushMirrorSync", "error occurred when syncing push mirror "+mirror.RemoteName) + return + } + } + + ctx.Status(http.StatusOK) +} + +// ListPushMirrors get list of push mirrors of a repository +func ListPushMirrors(ctx *context.APIContext) { + // swagger:operation GET /repos/{owner}/{repo}/push_mirrors repository repoListPushMirrors + // --- + // summary: Get all push mirrors of the repository + // produces: + // - application/json + // parameters: + // - name: owner + // in: path + // description: owner of the repo + // type: string + // required: true + // - name: repo + // in: path + // description: name of the repo + // type: string + // required: true + // - name: page + // in: query + // description: page number of results to return (1-based) + // type: integer + // - name: limit + // in: query + // description: page size of results + // type: integer + // responses: + // "200": + // "$ref": "#/responses/PushMirrorList" + // "400": + // "$ref": "#/responses/error" + // "403": + // "$ref": "#/responses/forbidden" + + if !setting.Mirror.Enabled { + ctx.Error(http.StatusBadRequest, "GetPushMirrorsByRepoID", "Mirror feature is disabled") + return + } + + repo := ctx.Repo.Repository + // Get all push mirrors for the specified repository. + pushMirrors, count, err := repo_model.GetPushMirrorsByRepoID(ctx, repo.ID, utils.GetListOptions(ctx)) + if err != nil { + ctx.Error(http.StatusNotFound, "GetPushMirrorsByRepoID", err) + return + } + + responsePushMirrors := make([]*api.PushMirror, 0, len(pushMirrors)) + for _, mirror := range pushMirrors { + m, err := convert.ToPushMirror(mirror) + if err == nil { + responsePushMirrors = append(responsePushMirrors, m) + } + + } + ctx.SetLinkHeader(len(responsePushMirrors), utils.GetListOptions(ctx).PageSize) + ctx.SetTotalCountHeader(count) + ctx.JSON(http.StatusOK, responsePushMirrors) +} + +// GetPushMirrorByName get push mirror of a repository by name +func GetPushMirrorByName(ctx *context.APIContext) { + // swagger:operation GET /repos/{owner}/{repo}/push_mirrors/{name} repository repoGetPushMirrorByRemoteName + // --- + // summary: Get push mirror of the repository by remoteName + // produces: + // - application/json + // parameters: + // - name: owner + // in: path + // description: owner of the repo + // type: string + // required: true + // - name: repo + // in: path + // description: name of the repo + // type: string + // required: true + // - name: name + // in: path + // description: remote name of push mirror + // type: string + // required: true + // responses: + // "200": + // "$ref": "#/responses/PushMirror" + // "400": + // "$ref": "#/responses/error" + // "403": + // "$ref": "#/responses/forbidden" + + if !setting.Mirror.Enabled { + ctx.Error(http.StatusBadRequest, "GetPushMirrorByRemoteName", "Mirror feature is disabled") + return + } + + mirrorName := ctx.Params(":name") + // Get push mirror of a specific repo by remoteName + pushMirror, err := repo_model.GetPushMirror(ctx, repo_model.PushMirrorOptions{RepoID: ctx.Repo.Repository.ID, RemoteName: mirrorName}) + if err != nil { + ctx.Error(http.StatusNotFound, "GetPushMirrors", err) + return + } + m, err := convert.ToPushMirror(pushMirror) + if err != nil { + ctx.ServerError("GetPushMirrorByRemoteName", err) + return + } + ctx.JSON(http.StatusOK, m) +} + +// AddPushMirror adds a push mirror to a repository +func AddPushMirror(ctx *context.APIContext) { + // swagger:operation POST /repos/{owner}/{repo}/push_mirrors repository repoAddPushMirror + // --- + // summary: add a push mirror to the repository + // consumes: + // - application/json + // produces: + // - application/json + // parameters: + // - name: owner + // in: path + // description: owner of the repo + // type: string + // required: true + // - name: repo + // in: path + // description: name of the repo + // type: string + // required: true + // - name: body + // in: body + // schema: + // "$ref": "#/definitions/CreatePushMirrorOption" + // responses: + // "201": + // "$ref": "#/responses/PushMirror" + // "403": + // "$ref": "#/responses/forbidden" + // "400": + // "$ref": "#/responses/error" + + if !setting.Mirror.Enabled { + ctx.Error(http.StatusBadRequest, "AddPushMirror", "Mirror feature is disabled") + return + } + + pushMirror := web.GetForm(ctx).(*api.CreatePushMirrorOption) + CreatePushMirror(ctx, pushMirror) +} + +// DeletePushMirrorByRemoteName deletes a push mirror from a repository by remoteName +func DeletePushMirrorByRemoteName(ctx *context.APIContext) { + // swagger:operation DELETE /repos/{owner}/{repo}/push_mirrors/{name} repository repoDeletePushMirror + // --- + // summary: deletes a push mirror from a repository by remoteName + // produces: + // - application/json + // parameters: + // - name: owner + // in: path + // description: owner of the repo + // type: string + // required: true + // - name: repo + // in: path + // description: name of the repo + // type: string + // required: true + // - name: name + // in: path + // description: remote name of the pushMirror + // type: string + // required: true + // responses: + // "204": + // "$ref": "#/responses/empty" + // "404": + // "$ref": "#/responses/notFound" + // "400": + // "$ref": "#/responses/error" + + if !setting.Mirror.Enabled { + ctx.Error(http.StatusBadRequest, "DeletePushMirrorByName", "Mirror feature is disabled") + return + } + + remoteName := ctx.Params(":name") + // Delete push mirror on repo by name. + err := repo_model.DeletePushMirrors(ctx, repo_model.PushMirrorOptions{RepoID: ctx.Repo.Repository.ID, RemoteName: remoteName}) + if err != nil { + ctx.Error(http.StatusNotFound, "DeletePushMirrors", err) + return + } + ctx.Status(http.StatusNoContent) +} + +func CreatePushMirror(ctx *context.APIContext, mirrorOption *api.CreatePushMirrorOption) { + repo := ctx.Repo.Repository + + interval, err := time.ParseDuration(mirrorOption.Interval) + if err != nil || (interval != 0 && interval < setting.Mirror.MinInterval) { + ctx.Error(http.StatusBadRequest, "CreatePushMirror", err) + return + } + + address, err := forms.ParseRemoteAddr(mirrorOption.RemoteAddress, mirrorOption.RemoteUsername, mirrorOption.RemotePassword) + if err == nil { + err = migrations.IsMigrateURLAllowed(address, ctx.ContextUser) + } + if err != nil { + HandleRemoteAddressError(ctx, err) + return + } + + remoteSuffix, err := util.CryptoRandomString(10) + if err != nil { + ctx.ServerError("CryptoRandomString", err) + return + } + + pushMirror := &repo_model.PushMirror{ + RepoID: repo.ID, + Repo: repo, + RemoteName: fmt.Sprintf("remote_mirror_%s", remoteSuffix), + Interval: interval, + } + + if err = repo_model.InsertPushMirror(ctx, pushMirror); err != nil { + ctx.ServerError("InsertPushMirror", err) + return + } + + // if the registration of the push mirrorOption fails remove it from the database + if err = mirror_service.AddPushMirrorRemote(ctx, pushMirror, address); err != nil { + if err := repo_model.DeletePushMirrors(ctx, repo_model.PushMirrorOptions{ID: pushMirror.ID, RepoID: pushMirror.RepoID}); err != nil { + ctx.ServerError("DeletePushMirrors", err) + } + ctx.ServerError("AddPushMirrorRemote", err) + return + } + m, err := convert.ToPushMirror(pushMirror) + if err != nil { + ctx.ServerError("ToPushMirror", err) + return + } + ctx.JSON(http.StatusOK, m) +} + +func HandleRemoteAddressError(ctx *context.APIContext, err error) { + if models.IsErrInvalidCloneAddr(err) { + addrErr := err.(*models.ErrInvalidCloneAddr) + switch { + case addrErr.IsProtocolInvalid: + ctx.Error(http.StatusBadRequest, "CreatePushMirror", "Invalid mirror protocol") + case addrErr.IsURLError: + ctx.Error(http.StatusBadRequest, "CreatePushMirror", "Invalid Url ") + case addrErr.IsPermissionDenied: + ctx.Error(http.StatusUnauthorized, "CreatePushMirror", "Permission denied") + default: + ctx.Error(http.StatusBadRequest, "CreatePushMirror", "Unknown error") + } + return + } +} diff --git a/routers/api/v1/repo/pull_review.go b/routers/api/v1/repo/pull_review.go index 1b61a40222d69..f36d0586ab6b9 100644 --- a/routers/api/v1/repo/pull_review.go +++ b/routers/api/v1/repo/pull_review.go @@ -823,7 +823,7 @@ func DismissPullReview(ctx *context.APIContext) { // "422": // "$ref": "#/responses/validationError" opts := web.GetForm(ctx).(*api.DismissPullReviewOptions) - dismissReview(ctx, opts.Message, true) + dismissReview(ctx, opts.Message, true, opts.Priors) } // UnDismissPullReview cancel to dismiss a review for a pull request @@ -863,10 +863,10 @@ func UnDismissPullReview(ctx *context.APIContext) { // "$ref": "#/responses/forbidden" // "422": // "$ref": "#/responses/validationError" - dismissReview(ctx, "", false) + dismissReview(ctx, "", false, false) } -func dismissReview(ctx *context.APIContext, msg string, isDismiss bool) { +func dismissReview(ctx *context.APIContext, msg string, isDismiss, dismissPriors bool) { if !ctx.Repo.IsAdmin() { ctx.Error(http.StatusForbidden, "", "Must be repo admin") return @@ -886,7 +886,7 @@ func dismissReview(ctx *context.APIContext, msg string, isDismiss bool) { return } - _, err := pull_service.DismissReview(ctx, review.ID, ctx.Repo.Repository.ID, msg, ctx.Doer, isDismiss) + _, err := pull_service.DismissReview(ctx, review.ID, ctx.Repo.Repository.ID, msg, ctx.Doer, isDismiss, dismissPriors) if err != nil { ctx.Error(http.StatusInternalServerError, "pull_service.DismissReview", err) return diff --git a/routers/api/v1/repo/release.go b/routers/api/v1/repo/release.go index 8dfe7e06d26f8..80009f78e99c0 100644 --- a/routers/api/v1/repo/release.go +++ b/routers/api/v1/repo/release.go @@ -224,6 +224,7 @@ func CreateRelease(ctx *context.APIContext) { rel.IsTag = false rel.Repo = ctx.Repo.Repository rel.Publisher = ctx.Doer + rel.Target = form.Target if err = release_service.UpdateRelease(ctx.Doer, ctx.Repo.GitRepo, rel, nil, nil, nil); err != nil { ctx.Error(http.StatusInternalServerError, "UpdateRelease", err) diff --git a/routers/api/v1/swagger/options.go b/routers/api/v1/swagger/options.go index df3d011246973..e8cfc0706f5ca 100644 --- a/routers/api/v1/swagger/options.go +++ b/routers/api/v1/swagger/options.go @@ -169,4 +169,7 @@ type swaggerParameterBodies struct { // in:body CreateWikiPageOptions api.CreateWikiPageOptions + + // in:body + CreatePushMirrorOption api.CreatePushMirrorOption } diff --git a/routers/api/v1/swagger/repo.go b/routers/api/v1/swagger/repo.go index ab802db7812fe..3522e242764ee 100644 --- a/routers/api/v1/swagger/repo.go +++ b/routers/api/v1/swagger/repo.go @@ -345,6 +345,20 @@ type swaggerWikiCommitList struct { Body api.WikiCommitList `json:"body"` } +// PushMirror +// swagger:response PushMirror +type swaggerPushMirror struct { + // in:body + Body api.PushMirror `json:"body"` +} + +// PushMirrorList +// swagger:response PushMirrorList +type swaggerPushMirrorList struct { + // in:body + Body []api.PushMirror `json:"body"` +} + // RepoCollaboratorPermission // swagger:response RepoCollaboratorPermission type swaggerRepoCollaboratorPermission struct { diff --git a/routers/api/v1/utils/git.go b/routers/api/v1/utils/git.go index ac64d5b87bfed..816f8b3595f7e 100644 --- a/routers/api/v1/utils/git.go +++ b/routers/api/v1/utils/git.go @@ -10,6 +10,7 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/log" ) // ResolveRefOrSha resolve ref to sha if exist @@ -19,6 +20,7 @@ func ResolveRefOrSha(ctx *context.APIContext, ref string) string { return "" } + sha := ref // Search branches and tags for _, refType := range []string{"heads", "tags"} { refSHA, lastMethodName, err := searchRefCommitByType(ctx, refType, ref) @@ -27,10 +29,19 @@ func ResolveRefOrSha(ctx *context.APIContext, ref string) string { return "" } if refSHA != "" { - return refSHA + sha = refSHA + break } } - return ref + + if ctx.Repo.GitRepo != nil { + err := ctx.Repo.GitRepo.AddLastCommitCache(ctx.Repo.Repository.GetCommitsCountCacheKey(ref, ref != sha), ctx.Repo.Repository.FullName(), sha) + if err != nil { + log.Error("Unable to get commits count for %s in %s. Error: %v", sha, ctx.Repo.Repository.FullName(), err) + } + } + + return sha } // GetGitRefs return git references based on filter diff --git a/routers/common/repo.go b/routers/common/repo.go index b3cd749115fb1..a9e80fad48c8d 100644 --- a/routers/common/repo.go +++ b/routers/common/repo.go @@ -7,12 +7,13 @@ package common import ( "fmt" "io" + "net/url" "path" "path/filepath" "strings" "time" - "code.gitea.io/gitea/modules/charset" + charsetModule "code.gitea.io/gitea/modules/charset" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/httpcache" @@ -42,7 +43,7 @@ func ServeBlob(ctx *context.Context, blob *git.Blob, lastModified time.Time) err } // ServeData download file from io.Reader -func ServeData(ctx *context.Context, name string, size int64, reader io.Reader) error { +func ServeData(ctx *context.Context, filePath string, size int64, reader io.Reader) error { buf := make([]byte, 1024) n, err := util.ReadAtMost(reader, buf) if err != nil { @@ -52,56 +53,73 @@ func ServeData(ctx *context.Context, name string, size int64, reader io.Reader) buf = buf[:n] } - ctx.Resp.Header().Set("Cache-Control", "public,max-age=86400") + httpcache.AddCacheControlToHeader(ctx.Resp.Header(), 5*time.Minute) if size >= 0 { ctx.Resp.Header().Set("Content-Length", fmt.Sprintf("%d", size)) } else { - log.Error("ServeData called to serve data: %s with size < 0: %d", name, size) + log.Error("ServeData called to serve data: %s with size < 0: %d", filePath, size) } - name = path.Base(name) - // Google Chrome dislike commas in filenames, so let's change it to a space - name = strings.ReplaceAll(name, ",", " ") + fileName := path.Base(filePath) + sniffedType := typesniffer.DetectContentType(buf) + isPlain := sniffedType.IsText() || ctx.FormBool("render") + mimeType := "" + charset := "" - st := typesniffer.DetectContentType(buf) - - mappedMimeType := "" if setting.MimeTypeMap.Enabled { - fileExtension := strings.ToLower(filepath.Ext(name)) - mappedMimeType = setting.MimeTypeMap.Map[fileExtension] + fileExtension := strings.ToLower(filepath.Ext(fileName)) + mimeType = setting.MimeTypeMap.Map[fileExtension] } - if st.IsText() || ctx.FormBool("render") { - cs, err := charset.DetectEncoding(buf) - if err != nil { - log.Error("Detect raw file %s charset failed: %v, using by default utf-8", name, err) - cs = "utf-8" + + if mimeType == "" { + if sniffedType.IsBrowsableBinaryType() { + mimeType = sniffedType.GetMimeType() + } else if isPlain { + mimeType = "text/plain" + } else { + mimeType = typesniffer.ApplicationOctetStream } - if mappedMimeType == "" { - mappedMimeType = "text/plain" + } + + if isPlain { + charset, err = charsetModule.DetectEncoding(buf) + if err != nil { + log.Error("Detect raw file %s charset failed: %v, using by default utf-8", filePath, err) + charset = "utf-8" } - ctx.Resp.Header().Set("Content-Type", mappedMimeType+"; charset="+strings.ToLower(cs)) + } + + if charset != "" { + ctx.Resp.Header().Set("Content-Type", mimeType+"; charset="+strings.ToLower(charset)) } else { - ctx.Resp.Header().Set("Access-Control-Expose-Headers", "Content-Disposition") - if mappedMimeType != "" { - ctx.Resp.Header().Set("Content-Type", mappedMimeType) - } - if (st.IsImage() || st.IsPDF()) && (setting.UI.SVG.Enabled || !st.IsSvgImage()) { - ctx.Resp.Header().Set("Content-Disposition", fmt.Sprintf(`inline; filename="%s"`, name)) - if st.IsSvgImage() || st.IsPDF() { - ctx.Resp.Header().Set("Content-Security-Policy", "default-src 'none'; style-src 'unsafe-inline'; sandbox") - ctx.Resp.Header().Set("X-Content-Type-Options", "nosniff") - if st.IsSvgImage() { - ctx.Resp.Header().Set("Content-Type", typesniffer.SvgMimeType) - } else { - ctx.Resp.Header().Set("Content-Type", typesniffer.ApplicationOctetStream) - } - } - } else { - ctx.Resp.Header().Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, name)) - } + ctx.Resp.Header().Set("Content-Type", mimeType) + } + ctx.Resp.Header().Set("X-Content-Type-Options", "nosniff") + + isSVG := sniffedType.IsSvgImage() + + // serve types that can present a security risk with CSP + if isSVG { + ctx.Resp.Header().Set("Content-Security-Policy", "default-src 'none'; style-src 'unsafe-inline'; sandbox") + } else if sniffedType.IsPDF() { + // no sandbox attribute for pdf as it breaks rendering in at least safari. this + // should generally be safe as scripts inside PDF can not escape the PDF document + // see https://bugs.chromium.org/p/chromium/issues/detail?id=413851 for more discussion + ctx.Resp.Header().Set("Content-Security-Policy", "default-src 'none'; style-src 'unsafe-inline'") } + disposition := "inline" + if isSVG && !setting.UI.SVG.Enabled { + disposition = "attachment" + } + + // encode filename per https://datatracker.ietf.org/doc/html/rfc5987 + encodedFileName := `filename*=UTF-8''` + url.PathEscape(fileName) + + ctx.Resp.Header().Set("Content-Disposition", disposition+"; "+encodedFileName) + ctx.Resp.Header().Set("Access-Control-Expose-Headers", "Content-Disposition") + _, err = ctx.Resp.Write(buf) if err != nil { return err diff --git a/routers/init.go b/routers/init.go index 72ccf3526c1fb..e640ca48453bc 100644 --- a/routers/init.go +++ b/routers/init.go @@ -141,7 +141,6 @@ func GlobalInitInstalled(ctx context.Context) { mustInit(repo_service.Init) // Booting long running goroutines. - cron.NewContext(ctx) issue_indexer.InitIssueIndexer(false) code_indexer.Init() mustInit(stats_indexer.Init) @@ -160,6 +159,9 @@ func GlobalInitInstalled(ctx context.Context) { auth.Init() svg.Init() + + // Finally start up the cron + cron.NewContext(ctx) } // NormalRoutes represents non install routes diff --git a/routers/install/install.go b/routers/install/install.go index 27c3509fdec51..8060414a1115a 100644 --- a/routers/install/install.go +++ b/routers/install/install.go @@ -133,7 +133,8 @@ func Install(ctx *context.Context) { // E-mail service settings if setting.MailService != nil { - form.SMTPHost = setting.MailService.Host + form.SMTPAddr = setting.MailService.SMTPAddr + form.SMTPPort = setting.MailService.SMTPPort form.SMTPFrom = setting.MailService.From form.SMTPUser = setting.MailService.User form.SMTPPasswd = setting.MailService.Passwd @@ -421,9 +422,10 @@ func SubmitInstall(ctx *context.Context) { cfg.Section("server").Key("LFS_START_SERVER").SetValue("false") } - if len(strings.TrimSpace(form.SMTPHost)) > 0 { + if len(strings.TrimSpace(form.SMTPAddr)) > 0 { cfg.Section("mailer").Key("ENABLED").SetValue("true") - cfg.Section("mailer").Key("HOST").SetValue(form.SMTPHost) + cfg.Section("mailer").Key("SMTP_ADDR").SetValue(form.SMTPAddr) + cfg.Section("mailer").Key("SMTP_PORT").SetValue(form.SMTPPort) cfg.Section("mailer").Key("FROM").SetValue(form.SMTPFrom) cfg.Section("mailer").Key("USER").SetValue(form.SMTPUser) cfg.Section("mailer").Key("PASSWD").SetValue(form.SMTPPasswd) diff --git a/routers/install/routes.go b/routers/install/routes.go index 32829ede9e26f..fdabcb9dc22c1 100644 --- a/routers/install/routes.go +++ b/routers/install/routes.go @@ -9,6 +9,7 @@ import ( "net/http" "path" + "code.gitea.io/gitea/modules/httpcache" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/public" "code.gitea.io/gitea/modules/setting" @@ -62,6 +63,7 @@ func installRecovery() func(next http.Handler) http.Handler { "SignedUserName": "", } + httpcache.AddCacheControlToHeader(w.Header(), 0, "no-transform") w.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions) if !setting.IsProd { diff --git a/routers/web/admin/auths.go b/routers/web/admin/auths.go index 7ea8a52809e60..b79b317555966 100644 --- a/routers/web/admin/auths.go +++ b/routers/web/admin/auths.go @@ -159,7 +159,7 @@ func parseLDAPConfig(form forms.AuthenticationForm) *ldap.Source { func parseSMTPConfig(form forms.AuthenticationForm) *smtp.Source { return &smtp.Source{ Auth: form.SMTPAuth, - Host: form.SMTPHost, + Addr: form.SMTPAddr, Port: form.SMTPPort, AllowedDomains: form.AllowedDomains, ForceSMTPS: form.ForceSMTPS, diff --git a/routers/web/admin/packages.go b/routers/web/admin/packages.go index 79bf025dd28c3..5de8922e6f34f 100644 --- a/routers/web/admin/packages.go +++ b/routers/web/admin/packages.go @@ -13,6 +13,7 @@ import ( "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/util" packages_service "code.gitea.io/gitea/services/packages" ) @@ -31,9 +32,10 @@ func Packages(ctx *context.Context) { sort := ctx.FormTrim("sort") pvs, total, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{ - Type: packages_model.Type(packageType), - Name: packages_model.SearchValue{Value: query}, - Sort: sort, + Type: packages_model.Type(packageType), + Name: packages_model.SearchValue{Value: query}, + Sort: sort, + IsInternal: util.OptionalBoolFalse, Paginator: &db.ListOptions{ PageSize: setting.UI.PackagesPagingNum, Page: page, diff --git a/routers/web/admin/users.go b/routers/web/admin/users.go index c37ecfd71ea90..aab633ec84b24 100644 --- a/routers/web/admin/users.go +++ b/routers/web/admin/users.go @@ -419,29 +419,21 @@ func DeleteUser(ctx *context.Context) { // admin should not delete themself if u.ID == ctx.Doer.ID { ctx.Flash.Error(ctx.Tr("admin.users.cannot_delete_self")) - ctx.JSON(http.StatusOK, map[string]interface{}{ - "redirect": setting.AppSubURL + "/admin/users/" + url.PathEscape(ctx.Params(":userid")), - }) + ctx.Redirect(setting.AppSubURL + "/admin/users/" + url.PathEscape(ctx.Params(":userid"))) return } - if err = user_service.DeleteUser(u); err != nil { + if err = user_service.DeleteUser(ctx, u, ctx.FormBool("purge")); err != nil { switch { case models.IsErrUserOwnRepos(err): ctx.Flash.Error(ctx.Tr("admin.users.still_own_repo")) - ctx.JSON(http.StatusOK, map[string]interface{}{ - "redirect": setting.AppSubURL + "/admin/users/" + url.PathEscape(ctx.Params(":userid")), - }) + ctx.Redirect(setting.AppSubURL + "/admin/users/" + url.PathEscape(ctx.Params(":userid"))) case models.IsErrUserHasOrgs(err): ctx.Flash.Error(ctx.Tr("admin.users.still_has_org")) - ctx.JSON(http.StatusOK, map[string]interface{}{ - "redirect": setting.AppSubURL + "/admin/users/" + url.PathEscape(ctx.Params(":userid")), - }) + ctx.Redirect(setting.AppSubURL + "/admin/users/" + url.PathEscape(ctx.Params(":userid"))) case models.IsErrUserOwnPackages(err): ctx.Flash.Error(ctx.Tr("admin.users.still_own_packages")) - ctx.JSON(http.StatusOK, map[string]interface{}{ - "redirect": setting.AppSubURL + "/admin/users/" + ctx.Params(":userid"), - }) + ctx.Redirect(setting.AppSubURL + "/admin/users/" + ctx.Params(":userid")) default: ctx.ServerError("DeleteUser", err) } @@ -450,9 +442,7 @@ func DeleteUser(ctx *context.Context) { log.Trace("Account deleted by admin (%s): %s", ctx.Doer.Name, u.Name) ctx.Flash.Success(ctx.Tr("admin.users.deletion_success")) - ctx.JSON(http.StatusOK, map[string]interface{}{ - "redirect": setting.AppSubURL + "/admin/users", - }) + ctx.Redirect(setting.AppSubURL + "/admin/users") } // AvatarPost response for change user's avatar request diff --git a/routers/web/auth/webauthn.go b/routers/web/auth/webauthn.go index 4778c9a9a3690..917cbdd57bf67 100644 --- a/routers/web/auth/webauthn.go +++ b/routers/web/auth/webauthn.go @@ -5,7 +5,6 @@ package auth import ( - "encoding/base32" "errors" "net/http" @@ -129,7 +128,7 @@ func WebAuthnLoginAssertionPost(ctx *context.Context) { } // Success! Get the credential and update the sign count with the new value we received. - dbCred, err := auth.GetWebAuthnCredentialByCredID(user.ID, base32.HexEncoding.EncodeToString(cred.ID)) + dbCred, err := auth.GetWebAuthnCredentialByCredID(user.ID, cred.ID) if err != nil { ctx.ServerError("GetWebAuthnCredentialByCredID", err) return diff --git a/routers/web/base.go b/routers/web/base.go index c7ade55a61f6f..30a24a1275432 100644 --- a/routers/web/base.go +++ b/routers/web/base.go @@ -158,6 +158,7 @@ func Recovery() func(next http.Handler) http.Handler { store["SignedUserName"] = "" } + httpcache.AddCacheControlToHeader(w.Header(), 0, "no-transform") w.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions) if !setting.IsProd { diff --git a/routers/web/org/home.go b/routers/web/org/home.go index d565a0c242404..63243a391f0e6 100644 --- a/routers/web/org/home.go +++ b/routers/web/org/home.go @@ -39,11 +39,6 @@ func Home(ctx *context.Context) { org := ctx.Org.Organization - if !organization.HasOrgOrUserVisible(ctx, org.AsUser(), ctx.Doer) { - ctx.NotFound("HasOrgOrUserVisible", nil) - return - } - ctx.Data["PageIsUserProfile"] = true ctx.Data["Title"] = org.DisplayName() if len(org.Description) != 0 { diff --git a/routers/web/org/members.go b/routers/web/org/members.go index 374c893575230..ec5a98fc6a240 100644 --- a/routers/web/org/members.go +++ b/routers/web/org/members.go @@ -45,6 +45,7 @@ func Members(ctx *context.Context) { } opts.PublicOnly = !isMember && !ctx.Doer.IsAdmin } + ctx.Data["PublicOnly"] = opts.PublicOnly total, err := organization.CountOrgMembers(opts) if err != nil { diff --git a/routers/web/org/setting.go b/routers/web/org/setting.go index c22a124e7421a..3f7bc59856f36 100644 --- a/routers/web/org/setting.go +++ b/routers/web/org/setting.go @@ -24,6 +24,7 @@ import ( user_setting "code.gitea.io/gitea/routers/web/user/setting" "code.gitea.io/gitea/services/forms" "code.gitea.io/gitea/services/org" + container_service "code.gitea.io/gitea/services/packages/container" repo_service "code.gitea.io/gitea/services/repository" user_service "code.gitea.io/gitea/services/user" ) @@ -88,6 +89,12 @@ func SettingsPost(ctx *context.Context) { } return } + + if err := container_service.UpdateRepositoryNames(ctx, org.AsUser(), form.Name); err != nil { + ctx.ServerError("UpdateRepositoryNames", err) + return + } + // reset ctx.org.OrgLink with new name ctx.Org.OrgLink = setting.AppSubURL + "/org/" + url.PathEscape(form.Name) log.Trace("Organization name changed: %s -> %s", org.Name, form.Name) diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go index 5c46882f3d264..8ed794b45c7dc 100644 --- a/routers/web/repo/compare.go +++ b/routers/web/repo/compare.go @@ -786,6 +786,19 @@ func CompareDiff(ctx *context.Context) { ctx.Data["IsDiffCompare"] = true ctx.Data["RequireTribute"] = true setTemplateIfExists(ctx, pullRequestTemplateKey, nil, pullRequestTemplateCandidates) + + // If a template content is set, prepend the "content". In this case that's only + // applicable if you have one commit to compare and that commit has a message. + // In that case the commit message will be prepend to the template body. + if templateContent, ok := ctx.Data[pullRequestTemplateKey].(string); ok && templateContent != "" { + if content, ok := ctx.Data["content"].(string); ok && content != "" { + // Re-use the same key as that's priortized over the "content" key. + // Add two new lines between the content to ensure there's always at least + // one empty line between them. + ctx.Data[pullRequestTemplateKey] = content + "\n\n" + templateContent + } + } + ctx.Data["IsAttachmentEnabled"] = setting.Attachment.Enabled upload.AddUploadContext(ctx, "comment") diff --git a/routers/web/repo/download.go b/routers/web/repo/download.go index 6755cda874869..cd2d305de6607 100644 --- a/routers/web/repo/download.go +++ b/routers/web/repo/download.go @@ -10,7 +10,6 @@ import ( "time" git_model "code.gitea.io/gitea/models/git" - "code.gitea.io/gitea/modules/cache" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/httpcache" @@ -99,12 +98,7 @@ func getBlobForEntry(ctx *context.Context) (blob *git.Blob, lastModified time.Ti return } - var c *git.LastCommitCache - if setting.CacheService.LastCommit.Enabled && ctx.Repo.CommitsCount >= setting.CacheService.LastCommit.CommitsCount { - c = git.NewLastCommitCache(ctx.Repo.Repository.FullName(), ctx.Repo.GitRepo, setting.LastCommitCacheTTLSeconds, cache.GetCache()) - } - - info, _, err := git.Entries([]*git.TreeEntry{entry}).GetCommitsInfo(ctx, ctx.Repo.Commit, path.Dir("/" + ctx.Repo.TreePath)[1:], c) + info, _, err := git.Entries([]*git.TreeEntry{entry}).GetCommitsInfo(ctx, ctx.Repo.Commit, path.Dir("/" + ctx.Repo.TreePath)[1:]) if err != nil { ctx.ServerError("GetCommitsInfo", err) return diff --git a/routers/web/repo/http.go b/routers/web/repo/http.go index 6a85bca16b2f5..5aa2bcd13471b 100644 --- a/routers/web/repo/http.go +++ b/routers/web/repo/http.go @@ -474,11 +474,12 @@ func serviceRPC(ctx gocontext.Context, h serviceHandler, service string) { cmd := git.NewCommand(h.r.Context(), service, "--stateless-rpc", h.dir) cmd.SetDescription(fmt.Sprintf("%s %s %s [repo_path: %s]", git.GitExecutable, service, "--stateless-rpc", h.dir)) if err := cmd.Run(&git.RunOpts{ - Dir: h.dir, - Env: append(os.Environ(), h.environ...), - Stdout: h.w, - Stdin: reqBody, - Stderr: &stderr, + Dir: h.dir, + Env: append(os.Environ(), h.environ...), + Stdout: h.w, + Stdin: reqBody, + Stderr: &stderr, + UseContextTimeout: true, }); err != nil { if err.Error() != "signal: killed" { log.Error("Fail to serve RPC(%s) in %s: %v - %s", service, h.dir, err, stderr.String()) diff --git a/routers/web/repo/packages.go b/routers/web/repo/packages.go index 03ea4fc5f4f46..57db19aa3257f 100644 --- a/routers/web/repo/packages.go +++ b/routers/web/repo/packages.go @@ -9,9 +9,11 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/packages" + "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/util" ) const ( @@ -32,10 +34,11 @@ func Packages(ctx *context.Context) { PageSize: setting.UI.PackagesPagingNum, Page: page, }, - OwnerID: ctx.ContextUser.ID, - RepoID: ctx.Repo.Repository.ID, - Type: packages.Type(packageType), - Name: packages.SearchValue{Value: query}, + OwnerID: ctx.ContextUser.ID, + RepoID: ctx.Repo.Repository.ID, + Type: packages.Type(packageType), + Name: packages.SearchValue{Value: query}, + IsInternal: util.OptionalBoolFalse, }) if err != nil { ctx.ServerError("SearchLatestVersions", err) @@ -60,6 +63,9 @@ func Packages(ctx *context.Context) { ctx.Data["Query"] = query ctx.Data["PackageType"] = packageType ctx.Data["HasPackages"] = hasPackages + if ctx.Repo != nil { + ctx.Data["CanWritePackages"] = ctx.IsUserRepoWriter([]unit.Type{unit.TypePackages}) || ctx.IsUserSiteAdmin() + } ctx.Data["PackageDescriptors"] = pds ctx.Data["Total"] = total ctx.Data["RepositoryAccessMap"] = map[int64]bool{ctx.Repo.Repository.ID: true} // There is only the current repository diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index 2a961c3cbc554..7c140a4e5991e 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -510,6 +510,8 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C return nil } ctx.Data["GetCommitMessages"] = pull_service.GetSquashMergeCommitMessages(ctx, pull) + } else { + ctx.Data["GetCommitMessages"] = "" } sha, err := baseGitRepo.GetRefCommitID(pull.GetGitRefName()) diff --git a/routers/web/repo/pull_review.go b/routers/web/repo/pull_review.go index 5a9f7a8138909..bc64f35472ea4 100644 --- a/routers/web/repo/pull_review.go +++ b/routers/web/repo/pull_review.go @@ -242,7 +242,7 @@ func SubmitReview(ctx *context.Context) { // DismissReview dismissing stale review by repo admin func DismissReview(ctx *context.Context) { form := web.GetForm(ctx).(*forms.DismissReviewForm) - comm, err := pull_service.DismissReview(ctx, form.ReviewID, ctx.Repo.Repository.ID, form.Message, ctx.Doer, true) + comm, err := pull_service.DismissReview(ctx, form.ReviewID, ctx.Repo.Repository.ID, form.Message, ctx.Doer, true, true) if err != nil { ctx.ServerError("pull_service.DismissReview", err) return diff --git a/routers/web/repo/setting.go b/routers/web/repo/setting.go index 5ded0561c65b5..a59824cecdb42 100644 --- a/routers/web/repo/setting.go +++ b/routers/web/repo/setting.go @@ -90,7 +90,7 @@ func SettingsCtxData(ctx *context.Context) { } ctx.Data["StatsIndexerStatus"] = status } - pushMirrors, err := repo_model.GetPushMirrorsByRepoID(ctx.Repo.Repository.ID) + pushMirrors, _, err := repo_model.GetPushMirrorsByRepoID(ctx, ctx.Repo.Repository.ID, db.ListOptions{}) if err != nil { ctx.ServerError("GetPushMirrorsByRepoID", err) return @@ -284,7 +284,7 @@ func SettingsPost(ctx *context.Context) { return } - m, err := selectPushMirrorByForm(form, repo) + m, err := selectPushMirrorByForm(ctx, form, repo) if err != nil { ctx.NotFound("", nil) return @@ -305,7 +305,7 @@ func SettingsPost(ctx *context.Context) { // as an error on the UI for this action ctx.Data["Err_RepoName"] = nil - m, err := selectPushMirrorByForm(form, repo) + m, err := selectPushMirrorByForm(ctx, form, repo) if err != nil { ctx.NotFound("", nil) return @@ -316,7 +316,7 @@ func SettingsPost(ctx *context.Context) { return } - if err = repo_model.DeletePushMirrorByID(m.ID); err != nil { + if err = repo_model.DeletePushMirrors(ctx, repo_model.PushMirrorOptions{ID: m.ID, RepoID: m.RepoID}); err != nil { ctx.ServerError("DeletePushMirrorByID", err) return } @@ -364,14 +364,14 @@ func SettingsPost(ctx *context.Context) { SyncOnCommit: form.PushMirrorSyncOnCommit, Interval: interval, } - if err := repo_model.InsertPushMirror(m); err != nil { + if err := repo_model.InsertPushMirror(ctx, m); err != nil { ctx.ServerError("InsertPushMirror", err) return } if err := mirror_service.AddPushMirrorRemote(ctx, m, address); err != nil { - if err := repo_model.DeletePushMirrorByID(m.ID); err != nil { - log.Error("DeletePushMirrorByID %v", err) + if err := repo_model.DeletePushMirrors(ctx, repo_model.PushMirrorOptions{ID: m.ID, RepoID: m.RepoID}); err != nil { + log.Error("DeletePushMirrors %v", err) } ctx.ServerError("AddPushMirrorRemote", err) return @@ -476,7 +476,7 @@ func SettingsPost(ctx *context.Context) { deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeProjects) } - if form.EnablePackages && !unit_model.TypeProjects.UnitGlobalDisabled() { + if form.EnablePackages && !unit_model.TypePackages.UnitGlobalDisabled() { units = append(units, repo_model.RepoUnit{ RepoID: repo.ID, Type: unit_model.TypePackages, @@ -1222,13 +1222,13 @@ func SettingsDeleteAvatar(ctx *context.Context) { ctx.Redirect(ctx.Repo.RepoLink + "/settings") } -func selectPushMirrorByForm(form *forms.RepoSettingForm, repo *repo_model.Repository) (*repo_model.PushMirror, error) { +func selectPushMirrorByForm(ctx *context.Context, form *forms.RepoSettingForm, repo *repo_model.Repository) (*repo_model.PushMirror, error) { id, err := strconv.ParseInt(form.PushMirrorID, 10, 64) if err != nil { return nil, err } - pushMirrors, err := repo_model.GetPushMirrorsByRepoID(repo.ID) + pushMirrors, _, err := repo_model.GetPushMirrorsByRepoID(ctx, repo.ID, db.ListOptions{}) if err != nil { return nil, err } diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go index 17169699dfbe1..6a9c6b9bbacea 100644 --- a/routers/web/repo/view.go +++ b/routers/web/repo/view.go @@ -15,7 +15,6 @@ import ( "net/http" "net/url" "path" - "strconv" "strings" "time" @@ -27,7 +26,6 @@ import ( unit_model "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/cache" "code.gitea.io/gitea/modules/charset" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" @@ -58,17 +56,8 @@ type namedBlob struct { blob *git.Blob } -func linesBytesCount(s []byte) int { - nl := []byte{'\n'} - n := bytes.Count(s, nl) - if len(s) > 0 && !bytes.HasSuffix(s, nl) { - n++ - } - return n -} - // FIXME: There has to be a more efficient way of doing this -func getReadmeFileFromPath(commit *git.Commit, treePath string) (*namedBlob, error) { +func getReadmeFileFromPath(ctx *context.Context, commit *git.Commit, treePath string) (*namedBlob, error) { tree, err := commit.SubTree(treePath) if err != nil { return nil, err @@ -79,50 +68,33 @@ func getReadmeFileFromPath(commit *git.Commit, treePath string) (*namedBlob, err return nil, err } - var readmeFiles [4]*namedBlob - exts := []string{".md", ".txt", ""} // sorted by priority + // Create a list of extensions in priority order + // 1. Markdown files - with and without localisation - e.g. README.en-us.md or README.md + // 2. Txt files - e.g. README.txt + // 3. No extension - e.g. README + exts := append(localizedExtensions(".md", ctx.Language()), ".txt", "") // sorted by priority + extCount := len(exts) + readmeFiles := make([]*namedBlob, extCount+1) for _, entry := range entries { if entry.IsDir() { continue } - for i, ext := range exts { - if markup.IsReadmeFile(entry.Name(), ext) { - if readmeFiles[i] == nil || base.NaturalSortLess(readmeFiles[i].name, entry.Blob().Name()) { - name := entry.Name() - isSymlink := entry.IsLink() - target := entry - if isSymlink { - target, err = entry.FollowLinks() - if err != nil && !git.IsErrBadLink(err) { - return nil, err - } - } - if target != nil && (target.IsExecutable() || target.IsRegular()) { - readmeFiles[i] = &namedBlob{ - name, - isSymlink, - target.Blob(), - } - } - } - } - } - - if markup.IsReadmeFile(entry.Name()) { - if readmeFiles[3] == nil || base.NaturalSortLess(readmeFiles[3].name, entry.Blob().Name()) { + if i, ok := markup.IsReadmeFileExtension(entry.Name(), exts...); ok { + if readmeFiles[i] == nil || base.NaturalSortLess(readmeFiles[i].name, entry.Blob().Name()) { name := entry.Name() isSymlink := entry.IsLink() + target := entry if isSymlink { - entry, err = entry.FollowLinks() + target, err = entry.FollowLinks() if err != nil && !git.IsErrBadLink(err) { return nil, err } } - if entry != nil && (entry.IsExecutable() || entry.IsRegular()) { - readmeFiles[3] = &namedBlob{ + if target != nil && (target.IsExecutable() || target.IsRegular()) { + readmeFiles[i] = &namedBlob{ name, isSymlink, - entry.Blob(), + target.Blob(), } } } @@ -162,13 +134,38 @@ func renderDirectory(ctx *context.Context, treeLink string) { renderReadmeFile(ctx, readmeFile, readmeTreelink) } +// localizedExtensions prepends the provided language code with and without a +// regional identifier to the provided extenstion. +// Note: the language code will always be lower-cased, if a region is present it must be separated with a `-` +// Note: ext should be prefixed with a `.` +func localizedExtensions(ext, languageCode string) (localizedExts []string) { + if len(languageCode) < 1 { + return []string{ext} + } + + lowerLangCode := "." + strings.ToLower(languageCode) + + if strings.Contains(lowerLangCode, "-") { + underscoreLangCode := strings.ReplaceAll(lowerLangCode, "-", "_") + indexOfDash := strings.Index(lowerLangCode, "-") + // e.g. [.zh-cn.md, .zh_cn.md, .zh.md, .md] + return []string{lowerLangCode + ext, underscoreLangCode + ext, lowerLangCode[:indexOfDash] + ext, ext} + } + + // e.g. [.en.md, .md] + return []string{lowerLangCode + ext, ext} +} + func findReadmeFile(ctx *context.Context, entries git.Entries, treeLink string) (*namedBlob, string) { - // 3 for the extensions in exts[] in order - // the last one is for a readme that doesn't - // strictly match an extension - var readmeFiles [4]*namedBlob - var docsEntries [3]*git.TreeEntry - exts := []string{".md", ".txt", ""} // sorted by priority + // Create a list of extensions in priority order + // 1. Markdown files - with and without localisation - e.g. README.en-us.md or README.md + // 2. Txt files - e.g. README.txt + // 3. No extension - e.g. README + exts := append(localizedExtensions(".md", ctx.Language()), ".txt", "") // sorted by priority + extCount := len(exts) + readmeFiles := make([]*namedBlob, extCount+1) + + docsEntries := make([]*git.TreeEntry, 3) // (one of docs/, .gitea/ or .github/) for _, entry := range entries { if entry.IsDir() { lowerName := strings.ToLower(entry.Name()) @@ -189,47 +186,24 @@ func findReadmeFile(ctx *context.Context, entries git.Entries, treeLink string) continue } - for i, ext := range exts { - if markup.IsReadmeFile(entry.Name(), ext) { - log.Debug("%s", entry.Name()) - name := entry.Name() - isSymlink := entry.IsLink() - target := entry - if isSymlink { - var err error - target, err = entry.FollowLinks() - if err != nil && !git.IsErrBadLink(err) { - ctx.ServerError("FollowLinks", err) - return nil, "" - } - } - log.Debug("%t", target == nil) - if target != nil && (target.IsExecutable() || target.IsRegular()) { - readmeFiles[i] = &namedBlob{ - name, - isSymlink, - target.Blob(), - } - } - } - } - - if markup.IsReadmeFile(entry.Name()) { + if i, ok := markup.IsReadmeFileExtension(entry.Name(), exts...); ok { + log.Debug("Potential readme file: %s", entry.Name()) name := entry.Name() isSymlink := entry.IsLink() + target := entry if isSymlink { var err error - entry, err = entry.FollowLinks() + target, err = entry.FollowLinks() if err != nil && !git.IsErrBadLink(err) { ctx.ServerError("FollowLinks", err) return nil, "" } } - if entry != nil && (entry.IsExecutable() || entry.IsRegular()) { - readmeFiles[3] = &namedBlob{ + if target != nil && (target.IsExecutable() || target.IsRegular()) { + readmeFiles[i] = &namedBlob{ name, isSymlink, - entry.Blob(), + target.Blob(), } } } @@ -250,7 +224,7 @@ func findReadmeFile(ctx *context.Context, entries git.Entries, treeLink string) continue } var err error - readmeFile, err = getReadmeFileFromPath(ctx.Repo.Commit, entry.GetSubJumpablePathName()) + readmeFile, err = getReadmeFileFromPath(ctx, ctx.Repo.Commit, entry.GetSubJumpablePathName()) if err != nil { ctx.ServerError("getReadmeFileFromPath", err) return nil, "" @@ -556,8 +530,14 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st ) } else { buf, _ := io.ReadAll(rd) - lineNums := linesBytesCount(buf) - ctx.Data["NumLines"] = strconv.Itoa(lineNums) + + // empty: 0 lines; "a": one line; "a\n": two lines; "a\nb": two lines; + // the NumLines is only used for the display on the UI: "xxx lines" + if len(buf) == 0 { + ctx.Data["NumLines"] = 0 + } else { + ctx.Data["NumLines"] = bytes.Count(buf, []byte{'\n'}) + 1 + } ctx.Data["NumLinesSet"] = true language := "" @@ -585,7 +565,11 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st language = "" } } - fileContent := highlight.File(lineNums, blob.Name(), language, buf) + fileContent, err := highlight.File(blob.Name(), language, buf) + if err != nil { + log.Error("highlight.File failed, fallback to plain text: %v", err) + fileContent = highlight.PlainText(buf) + } status, _ := charset.EscapeControlReader(bytes.NewReader(buf), io.Discard) ctx.Data["EscapeStatus"] = status statuses := make([]charset.EscapeStatus, len(fileContent)) @@ -812,11 +796,6 @@ func renderDirectoryFiles(ctx *context.Context, timeout time.Duration) git.Entri defer cancel() } - var c *git.LastCommitCache - if setting.CacheService.LastCommit.Enabled && ctx.Repo.CommitsCount >= setting.CacheService.LastCommit.CommitsCount { - c = git.NewLastCommitCache(ctx.Repo.Repository.FullName(), ctx.Repo.GitRepo, setting.LastCommitCacheTTLSeconds, cache.GetCache()) - } - selected := map[string]bool{} for _, pth := range ctx.FormStrings("f[]") { selected[pth] = true @@ -833,7 +812,7 @@ func renderDirectoryFiles(ctx *context.Context, timeout time.Duration) git.Entri } var latestCommit *git.Commit - ctx.Data["Files"], latestCommit, err = entries.GetCommitsInfo(commitInfoCtx, ctx.Repo.Commit, ctx.Repo.TreePath, c) + ctx.Data["Files"], latestCommit, err = entries.GetCommitsInfo(commitInfoCtx, ctx.Repo.Commit, ctx.Repo.TreePath) if err != nil { ctx.ServerError("GetCommitsInfo", err) return nil @@ -854,15 +833,15 @@ func renderDirectoryFiles(ctx *context.Context, timeout time.Duration) git.Entri } ctx.Data["LatestCommitVerification"] = verification ctx.Data["LatestCommitUser"] = user_model.ValidateCommitWithEmail(latestCommit) - } - statuses, _, err := git_model.GetLatestCommitStatus(ctx, ctx.Repo.Repository.ID, ctx.Repo.Commit.ID.String(), db.ListOptions{}) - if err != nil { - log.Error("GetLatestCommitStatus: %v", err) - } + statuses, _, err := git_model.GetLatestCommitStatus(ctx, ctx.Repo.Repository.ID, latestCommit.ID.String(), db.ListOptions{}) + if err != nil { + log.Error("GetLatestCommitStatus: %v", err) + } - ctx.Data["LatestCommitStatus"] = git_model.CalcCommitStatus(statuses) - ctx.Data["LatestCommitStatuses"] = statuses + ctx.Data["LatestCommitStatus"] = git_model.CalcCommitStatus(statuses) + ctx.Data["LatestCommitStatuses"] = statuses + } branchLink := ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL() treeLink := branchLink @@ -902,10 +881,14 @@ func renderCode(ctx *context.Context) { ctx.Data["PageIsViewCode"] = true if ctx.Repo.Repository.IsEmpty { - reallyEmpty, err := ctx.Repo.GitRepo.IsEmpty() - if err != nil { - ctx.ServerError("GitRepo.IsEmpty", err) - return + reallyEmpty := true + var err error + if ctx.Repo.GitRepo != nil { + reallyEmpty, err = ctx.Repo.GitRepo.IsEmpty() + if err != nil { + ctx.ServerError("GitRepo.IsEmpty", err) + return + } } if reallyEmpty { ctx.HTML(http.StatusOK, tplRepoEMPTY) diff --git a/routers/web/repo/view_test.go b/routers/web/repo/view_test.go new file mode 100644 index 0000000000000..9d5a88fca412b --- /dev/null +++ b/routers/web/repo/view_test.go @@ -0,0 +1,63 @@ +// Copyright 2017 The Gitea Authors. All rights reserved. +// Copyright 2014 The Gogs Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package repo + +import ( + "reflect" + "testing" +) + +func Test_localizedExtensions(t *testing.T) { + tests := []struct { + name string + ext string + languageCode string + wantLocalizedExts []string + }{ + { + name: "empty language", + ext: ".md", + wantLocalizedExts: []string{".md"}, + }, + { + name: "No region - lowercase", + languageCode: "en", + ext: ".csv", + wantLocalizedExts: []string{".en.csv", ".csv"}, + }, + { + name: "No region - uppercase", + languageCode: "FR", + ext: ".txt", + wantLocalizedExts: []string{".fr.txt", ".txt"}, + }, + { + name: "With region - lowercase", + languageCode: "en-us", + ext: ".md", + wantLocalizedExts: []string{".en-us.md", ".en_us.md", ".en.md", ".md"}, + }, + { + name: "With region - uppercase", + languageCode: "en-CA", + ext: ".MD", + wantLocalizedExts: []string{".en-ca.MD", ".en_ca.MD", ".en.MD", ".MD"}, + }, + { + name: "With region - all uppercase", + languageCode: "ZH-TW", + ext: ".md", + wantLocalizedExts: []string{".zh-tw.md", ".zh_tw.md", ".zh.md", ".md"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if gotLocalizedExts := localizedExtensions(tt.ext, tt.languageCode); !reflect.DeepEqual(gotLocalizedExts, tt.wantLocalizedExts) { + t.Errorf("localizedExtensions() = %v, want %v", gotLocalizedExts, tt.wantLocalizedExts) + } + }) + } +} diff --git a/routers/web/user/home.go b/routers/web/user/home.go index 698117e9571fb..648269980472e 100644 --- a/routers/web/user/home.go +++ b/routers/web/user/home.go @@ -591,6 +591,7 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { LabelIDs: opts.LabelIDs, Org: org, Team: team, + RepoCond: opts.RepoCond, } issueStats, err = issues_model.GetUserIssueStats(statsOpts) diff --git a/routers/web/user/package.go b/routers/web/user/package.go index b2b550cb73b4d..59aaf07ff2a81 100644 --- a/routers/web/user/package.go +++ b/routers/web/user/package.go @@ -8,6 +8,7 @@ import ( "net/http" "code.gitea.io/gitea/models/db" + org_model "code.gitea.io/gitea/models/organization" packages_model "code.gitea.io/gitea/models/packages" container_model "code.gitea.io/gitea/models/packages/container" "code.gitea.io/gitea/models/perm" @@ -17,6 +18,7 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/services/forms" packages_service "code.gitea.io/gitea/services/packages" @@ -43,9 +45,10 @@ func ListPackages(ctx *context.Context) { PageSize: setting.UI.PackagesPagingNum, Page: page, }, - OwnerID: ctx.ContextUser.ID, - Type: packages_model.Type(packageType), - Name: packages_model.SearchValue{Value: query}, + OwnerID: ctx.ContextUser.ID, + Type: packages_model.Type(packageType), + Name: packages_model.SearchValue{Value: query}, + IsInternal: util.OptionalBoolFalse, }) if err != nil { ctx.ServerError("SearchLatestVersions", err) @@ -91,6 +94,21 @@ func ListPackages(ctx *context.Context) { ctx.Data["Total"] = total ctx.Data["RepositoryAccessMap"] = repositoryAccessMap + // TODO: context/org -> HandleOrgAssignment() can not be used + if ctx.ContextUser.IsOrganization() { + org := org_model.OrgFromUser(ctx.ContextUser) + ctx.Data["Org"] = org + ctx.Data["OrgLink"] = ctx.ContextUser.OrganisationLink() + + if ctx.Doer != nil { + ctx.Data["IsOrganizationMember"], _ = org_model.IsOrganizationMember(ctx, org.ID, ctx.Doer.ID) + ctx.Data["IsOrganizationOwner"], _ = org_model.IsOrganizationOwner(ctx, org.ID, ctx.Doer.ID) + } else { + ctx.Data["IsOrganizationMember"] = false + ctx.Data["IsOrganizationOwner"] = false + } + } + pager := context.NewPagination(int(total), setting.UI.PackagesPagingNum, page, 5) pager.AddParam(ctx, "q", "Query") pager.AddParam(ctx, "type", "PackageType") @@ -112,7 +130,8 @@ func RedirectToLastVersion(ctx *context.Context) { } pvs, _, err := packages_model.SearchLatestVersions(ctx, &packages_model.PackageSearchOptions{ - PackageID: p.ID, + PackageID: p.ID, + IsInternal: util.OptionalBoolFalse, }) if err != nil { ctx.ServerError("GetPackageByName", err) @@ -157,8 +176,9 @@ func ViewPackageVersion(ctx *context.Context) { }) default: pvs, total, err = packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{ - Paginator: db.NewAbsoluteListOptions(0, 5), - PackageID: pd.Package.ID, + Paginator: db.NewAbsoluteListOptions(0, 5), + PackageID: pd.Package.ID, + IsInternal: util.OptionalBoolFalse, }) if err != nil { ctx.ServerError("SearchVersions", err) @@ -254,6 +274,7 @@ func ListPackageVersions(ctx *context.Context) { ExactMatch: false, Value: query, }, + IsInternal: util.OptionalBoolFalse, }) if err != nil { ctx.ServerError("SearchVersions", err) diff --git a/routers/web/user/setting/account.go b/routers/web/user/setting/account.go index dfade13a1ce48..8b95caf2fcb0e 100644 --- a/routers/web/user/setting/account.go +++ b/routers/web/user/setting/account.go @@ -156,7 +156,8 @@ func EmailPost(ctx *context.Context) { preference := ctx.FormString("preference") if !(preference == user_model.EmailNotificationsEnabled || preference == user_model.EmailNotificationsOnMention || - preference == user_model.EmailNotificationsDisabled) { + preference == user_model.EmailNotificationsDisabled || + preference == user_model.EmailNotificationsAndYourOwn) { log.Error("Email notifications preference change returned unrecognized option %s: %s", preference, ctx.Doer.Name) ctx.ServerError("SetEmailPreference", errors.New("option unrecognized")) return @@ -248,7 +249,7 @@ func DeleteAccount(ctx *context.Context) { return } - if err := user.DeleteUser(ctx.Doer); err != nil { + if err := user.DeleteUser(ctx, ctx.Doer, false); err != nil { switch { case models.IsErrUserOwnRepos(err): ctx.Flash.Error(ctx.Tr("form.still_own_repo")) diff --git a/routers/web/user/setting/profile.go b/routers/web/user/setting/profile.go index b07813e7250e6..c9a7afe982f78 100644 --- a/routers/web/user/setting/profile.go +++ b/routers/web/user/setting/profile.go @@ -30,6 +30,7 @@ import ( "code.gitea.io/gitea/modules/web/middleware" "code.gitea.io/gitea/services/agit" "code.gitea.io/gitea/services/forms" + container_service "code.gitea.io/gitea/services/packages/container" user_service "code.gitea.io/gitea/services/user" ) @@ -90,6 +91,11 @@ func HandleUsernameChange(ctx *context.Context, user *user_model.User, newName s return err } + if err := container_service.UpdateRepositoryNames(ctx, user, newName); err != nil { + ctx.ServerError("UpdateRepositoryNames", err) + return err + } + log.Trace("User name changed: %s -> %s", user.Name, newName) return nil } diff --git a/routers/web/web.go b/routers/web/web.go index ae273d99e4ffd..a9f43fb2c4feb 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -12,6 +12,7 @@ import ( "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/unit" + "code.gitea.io/gitea/modules/cache" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/httpcache" @@ -289,6 +290,13 @@ func RegisterRoutes(m *web.Route) { } } + dlSourceEnabled := func(ctx *context.Context) { + if setting.Repository.DisableDownloadSourceArchives { + ctx.Error(http.StatusNotFound) + return + } + } + // FIXME: not all routes need go through same middleware. // Especially some AJAX requests, we can reduce middleware number to improve performance. // Routers. @@ -610,6 +618,12 @@ func RegisterRoutes(m *web.Route) { } // ***** START: Organization ***** + m.Group("/org", func() { + m.Group("/{org}", func() { + m.Get("/members", org.Members) + }, context.OrgAssignment()) + }, ignSignIn) + m.Group("/org", func() { m.Group("", func() { m.Get("/create", org.Create) @@ -625,7 +639,6 @@ func RegisterRoutes(m *web.Route) { m.Get("/pulls/{team}", user.Pulls) m.Get("/milestones", reqMilestonesDashboardPageEnabled, user.Milestones) m.Get("/milestones/{team}", reqMilestonesDashboardPageEnabled, user.Milestones) - m.Get("/members", org.Members) m.Post("/members/action/{action}", org.MembersAction) m.Get("/teams", org.Teams) }, context.OrgAssignment(true, false, true)) @@ -1006,6 +1019,7 @@ func RegisterRoutes(m *web.Route) { return } ctx.Data["CommitsCount"] = ctx.Repo.CommitsCount + ctx.Repo.GitRepo.LastCommitCache = git.NewLastCommitCache(ctx.Repo.CommitsCount, ctx.Repo.Repository.FullName(), ctx.Repo.GitRepo, cache.GetCache()) }) }, ignSignIn, context.RepoAssignment, context.UnitTypes(), reqRepoReleaseReader) @@ -1099,7 +1113,7 @@ func RegisterRoutes(m *web.Route) { m.Group("/archive", func() { m.Get("/*", repo.Download) m.Post("/*", repo.InitiateDownload) - }, repo.MustBeNotEmpty, reqRepoCodeReader) + }, repo.MustBeNotEmpty, dlSourceEnabled, reqRepoCodeReader) m.Group("/branches", func() { m.Get("", repo.Branches) diff --git a/services/auth/source/smtp/auth.go b/services/auth/source/smtp/auth.go index 8d0cbb11cdc9a..a9e4b0e5f4454 100644 --- a/services/auth/source/smtp/auth.go +++ b/services/auth/source/smtp/auth.go @@ -58,10 +58,10 @@ var ErrUnsupportedLoginType = errors.New("Login source is unknown") func Authenticate(a smtp.Auth, source *Source) error { tlsConfig := &tls.Config{ InsecureSkipVerify: source.SkipVerify, - ServerName: source.Host, + ServerName: source.Addr, } - conn, err := net.Dial("tcp", net.JoinHostPort(source.Host, strconv.Itoa(source.Port))) + conn, err := net.Dial("tcp", net.JoinHostPort(source.Addr, strconv.Itoa(source.Port))) if err != nil { return err } @@ -71,7 +71,7 @@ func Authenticate(a smtp.Auth, source *Source) error { conn = tls.Client(conn, tlsConfig) } - client, err := smtp.NewClient(conn, source.Host) + client, err := smtp.NewClient(conn, source.Addr) if err != nil { return fmt.Errorf("failed to create NewClient: %w", err) } diff --git a/services/auth/source/smtp/source.go b/services/auth/source/smtp/source.go index 5e69f912da35b..b2286d42a0ff7 100644 --- a/services/auth/source/smtp/source.go +++ b/services/auth/source/smtp/source.go @@ -19,7 +19,7 @@ import ( // Source holds configuration for the SMTP login source. type Source struct { Auth string - Host string + Addr string Port int AllowedDomains string `xorm:"TEXT"` ForceSMTPS bool diff --git a/services/auth/source/smtp/source_authenticate.go b/services/auth/source/smtp/source_authenticate.go index dff24d494ee0f..63fd3e55110b7 100644 --- a/services/auth/source/smtp/source_authenticate.go +++ b/services/auth/source/smtp/source_authenticate.go @@ -32,7 +32,7 @@ func (source *Source) Authenticate(user *user_model.User, userName, password str var auth smtp.Auth switch source.Auth { case PlainAuthentication: - auth = smtp.PlainAuth("", userName, password, source.Host) + auth = smtp.PlainAuth("", userName, password, source.Addr) case LoginAuthentication: auth = &loginAuthenticator{userName, password} case CRAMMD5Authentication: diff --git a/services/forms/auth_form.go b/services/forms/auth_form.go index 7e7c75675299b..9064be2cca38e 100644 --- a/services/forms/auth_form.go +++ b/services/forms/auth_form.go @@ -45,7 +45,7 @@ type AuthenticationForm struct { IsActive bool IsSyncEnabled bool SMTPAuth string - SMTPHost string + SMTPAddr string SMTPPort int AllowedDomains string SecurityProtocol int `binding:"Range(0,2)"` diff --git a/services/forms/user_form.go b/services/forms/user_form.go index 405b4a9a490f2..c8f2b02d8c809 100644 --- a/services/forms/user_form.go +++ b/services/forms/user_form.go @@ -40,7 +40,8 @@ type InstallForm struct { AppURL string `binding:"Required"` LogRootPath string `binding:"Required"` - SMTPHost string + SMTPAddr string + SMTPPort string SMTPFrom string SMTPUser string `binding:"OmitEmpty;MaxSize(254)" locale:"install.mailer_user"` SMTPPasswd string diff --git a/services/gitdiff/gitdiff.go b/services/gitdiff/gitdiff.go index 6e8c149dabd94..6dd237bbc8d47 100644 --- a/services/gitdiff/gitdiff.go +++ b/services/gitdiff/gitdiff.go @@ -15,7 +15,6 @@ import ( "io" "net/url" "os" - "regexp" "sort" "strings" "time" @@ -40,7 +39,7 @@ import ( "golang.org/x/text/transform" ) -// DiffLineType represents the type of a DiffLine. +// DiffLineType represents the type of DiffLine. type DiffLineType uint8 // DiffLineType possible values. @@ -51,7 +50,7 @@ const ( DiffLineSection ) -// DiffFileType represents the type of a DiffFile. +// DiffFileType represents the type of DiffFile. type DiffFileType uint8 // DiffFileType possible values. @@ -100,12 +99,12 @@ type DiffLineSectionInfo struct { // BlobExcerptChunkSize represent max lines of excerpt const BlobExcerptChunkSize = 20 -// GetType returns the type of a DiffLine. +// GetType returns the type of DiffLine. func (d *DiffLine) GetType() int { return int(d.Type) } -// CanComment returns whether or not a line can get commented +// CanComment returns whether a line can get commented func (d *DiffLine) CanComment() bool { return len(d.Comments) == 0 && d.Type != DiffLineSection } @@ -191,287 +190,13 @@ var ( codeTagSuffix = []byte(`
`) ) -var ( - unfinishedtagRegex = regexp.MustCompile(`<[^>]*$`) - trailingSpanRegex = regexp.MustCompile(`]?$`) - entityRegex = regexp.MustCompile(`&[#]*?[0-9[:alpha:]]*$`) -) - -// shouldWriteInline represents combinations where we manually write inline changes -func shouldWriteInline(diff diffmatchpatch.Diff, lineType DiffLineType) bool { - if true && - diff.Type == diffmatchpatch.DiffEqual || - diff.Type == diffmatchpatch.DiffInsert && lineType == DiffLineAdd || - diff.Type == diffmatchpatch.DiffDelete && lineType == DiffLineDel { - return true - } - return false -} - -func fixupBrokenSpans(diffs []diffmatchpatch.Diff) []diffmatchpatch.Diff { - // Create a new array to store our fixed up blocks - fixedup := make([]diffmatchpatch.Diff, 0, len(diffs)) - - // semantically label some numbers - const insert, delete, equal = 0, 1, 2 - - // record the positions of the last type of each block in the fixedup blocks - last := []int{-1, -1, -1} - operation := []diffmatchpatch.Operation{diffmatchpatch.DiffInsert, diffmatchpatch.DiffDelete, diffmatchpatch.DiffEqual} - - // create a writer for insert and deletes - toWrite := []strings.Builder{ - {}, - {}, - } - - // make some flags for insert and delete - unfinishedTag := []bool{false, false} - unfinishedEnt := []bool{false, false} - - // store stores the provided text in the writer for the typ - store := func(text string, typ int) { - (&(toWrite[typ])).WriteString(text) - } - - // hasStored returns true if there is stored content - hasStored := func(typ int) bool { - return (&toWrite[typ]).Len() > 0 - } - - // stored will return that content - stored := func(typ int) string { - return (&toWrite[typ]).String() - } - - // empty will empty the stored content - empty := func(typ int) { - (&toWrite[typ]).Reset() - } - - // pop will remove the stored content appending to a diff block for that typ - pop := func(typ int, fixedup []diffmatchpatch.Diff) []diffmatchpatch.Diff { - if hasStored(typ) { - if last[typ] > last[equal] { - fixedup[last[typ]].Text += stored(typ) - } else { - fixedup = append(fixedup, diffmatchpatch.Diff{ - Type: operation[typ], - Text: stored(typ), - }) - } - empty(typ) - } - return fixedup - } - - // Now we walk the provided diffs and check the type of each block in turn - for _, diff := range diffs { - - typ := delete // flag for handling insert or delete typs - switch diff.Type { - case diffmatchpatch.DiffEqual: - // First check if there is anything stored - if hasStored(insert) || hasStored(delete) { - // There are two reasons for storing content: - // 1. Unfinished Entity <- Could be more efficient here by not doing this if we're looking for a tag - if unfinishedEnt[insert] || unfinishedEnt[delete] { - // we look for a ';' to finish an entity - idx := strings.IndexRune(diff.Text, ';') - if idx >= 0 { - // if we find a ';' store the preceding content to both insert and delete - store(diff.Text[:idx+1], insert) - store(diff.Text[:idx+1], delete) - - // and remove it from this block - diff.Text = diff.Text[idx+1:] - - // reset the ent flags - unfinishedEnt[insert] = false - unfinishedEnt[delete] = false - } else { - // otherwise store it all on insert and delete - store(diff.Text, insert) - store(diff.Text, delete) - // and empty this block - diff.Text = "" - } - } - // 2. Unfinished Tag - if unfinishedTag[insert] || unfinishedTag[delete] { - // we look for a '>' to finish a tag - idx := strings.IndexRune(diff.Text, '>') - if idx >= 0 { - store(diff.Text[:idx+1], insert) - store(diff.Text[:idx+1], delete) - diff.Text = diff.Text[idx+1:] - unfinishedTag[insert] = false - unfinishedTag[delete] = false - } else { - store(diff.Text, insert) - store(diff.Text, delete) - diff.Text = "" - } - } - - // If we've completed the required tag/entities - if !(unfinishedTag[insert] || unfinishedTag[delete] || unfinishedEnt[insert] || unfinishedEnt[delete]) { - // pop off the stack - fixedup = pop(insert, fixedup) - fixedup = pop(delete, fixedup) - } - - // If that has left this diff block empty then shortcut - if len(diff.Text) == 0 { - continue - } - } - - // check if this block ends in an unfinished tag? - idx := unfinishedtagRegex.FindStringIndex(diff.Text) - if idx != nil { - unfinishedTag[insert] = true - unfinishedTag[delete] = true - } else { - // otherwise does it end in an unfinished entity? - idx = entityRegex.FindStringIndex(diff.Text) - if idx != nil { - unfinishedEnt[insert] = true - unfinishedEnt[delete] = true - } - } - - // If there is an unfinished component - if idx != nil { - // Store the fragment - store(diff.Text[idx[0]:], insert) - store(diff.Text[idx[0]:], delete) - // and remove it from this block - diff.Text = diff.Text[:idx[0]] - } - - // If that hasn't left the block empty - if len(diff.Text) > 0 { - // store the position of the last equal block and store it in our diffs - last[equal] = len(fixedup) - fixedup = append(fixedup, diff) - } - continue - case diffmatchpatch.DiffInsert: - typ = insert - fallthrough - case diffmatchpatch.DiffDelete: - // First check if there is anything stored for this type - if hasStored(typ) { - // if there is prepend it to this block, empty the storage and reset our flags - diff.Text = stored(typ) + diff.Text - empty(typ) - unfinishedEnt[typ] = false - unfinishedTag[typ] = false - } - - // check if this block ends in an unfinished tag - idx := unfinishedtagRegex.FindStringIndex(diff.Text) - if idx != nil { - unfinishedTag[typ] = true - } else { - // otherwise does it end in an unfinished entity - idx = entityRegex.FindStringIndex(diff.Text) - if idx != nil { - unfinishedEnt[typ] = true - } - } - - // If there is an unfinished component - if idx != nil { - // Store the fragment - store(diff.Text[idx[0]:], typ) - // and remove it from this block - diff.Text = diff.Text[:idx[0]] - } - - // If that hasn't left the block empty - if len(diff.Text) > 0 { - // if the last block of this type was after the last equal block - if last[typ] > last[equal] { - // store this blocks content on that block - fixedup[last[typ]].Text += diff.Text - } else { - // otherwise store the position of the last block of this type and store the block - last[typ] = len(fixedup) - fixedup = append(fixedup, diff) - } - } - continue - } - } - - // pop off any remaining stored content - fixedup = pop(insert, fixedup) - fixedup = pop(delete, fixedup) - - return fixedup -} - -func diffToHTML(fileName string, diffs []diffmatchpatch.Diff, lineType DiffLineType) DiffInline { +func diffToHTML(lineWrapperTags []string, diffs []diffmatchpatch.Diff, lineType DiffLineType) string { buf := bytes.NewBuffer(nil) - match := "" - - diffs = fixupBrokenSpans(diffs) - + // restore the line wrapper tags and , if necessary + for _, tag := range lineWrapperTags { + buf.WriteString(tag) + } for _, diff := range diffs { - if shouldWriteInline(diff, lineType) { - if len(match) > 0 { - diff.Text = match + diff.Text - match = "" - } - // Chroma HTML syntax highlighting is done before diffing individual lines in order to maintain consistency. - // Since inline changes might split in the middle of a chroma span tag or HTML entity, make we manually put it back together - // before writing so we don't try insert added/removed code spans in the middle of one of those - // and create broken HTML. This is done by moving incomplete HTML forward until it no longer matches our pattern of - // a line ending with an incomplete HTML entity or partial/opening . - - // EX: - // diffs[{Type: dmp.DiffDelete, Text: "language}] - - // After first iteration - // diffs[{Type: dmp.DiffDelete, Text: "language"}, //write out - // {Type: dmp.DiffEqual, Text: ",}] - - // After second iteration - // {Type: dmp.DiffEqual, Text: ""}, // write out - // {Type: dmp.DiffDelete, Text: ",}] - - // Final - // {Type: dmp.DiffDelete, Text: ",}] - // end up writing , - // Instead of lass="p", - - m := trailingSpanRegex.FindStringSubmatchIndex(diff.Text) - if m != nil { - match = diff.Text[m[0]:m[1]] - diff.Text = strings.TrimSuffix(diff.Text, match) - } - m = entityRegex.FindStringSubmatchIndex(diff.Text) - if m != nil { - match = diff.Text[m[0]:m[1]] - diff.Text = strings.TrimSuffix(diff.Text, match) - } - // Print an existing closing span first before opening added/remove-code span so it doesn't unintentionally close it - if strings.HasPrefix(diff.Text, "") { - buf.WriteString("
") - diff.Text = strings.TrimPrefix(diff.Text, "") - } - // If we weren't able to fix it then this should avoid broken HTML by not inserting more spans below - // The previous/next diff section will contain the rest of the tag that is missing here - if strings.Count(diff.Text, "<") != strings.Count(diff.Text, ">") { - buf.WriteString(diff.Text) - continue - } - } switch { case diff.Type == diffmatchpatch.DiffEqual: buf.WriteString(diff.Text) @@ -485,7 +210,10 @@ func diffToHTML(fileName string, diffs []diffmatchpatch.Diff, lineType DiffLineT buf.Write(codeTagSuffix) } } - return DiffInlineWithUnicodeEscape(template.HTML(buf.String())) + for range lineWrapperTags { + buf.WriteString("") + } + return buf.String() } // GetLine gets a specific line by type (add or del) and file line number @@ -597,10 +325,12 @@ func (diffSection *DiffSection) GetComputedInlineDiffFor(diffLine *DiffLine) Dif return DiffInlineWithHighlightCode(diffSection.FileName, language, diffLine.Content) } - diffRecord := diffMatchPatch.DiffMain(highlight.Code(diffSection.FileName, language, diff1[1:]), highlight.Code(diffSection.FileName, language, diff2[1:]), true) - diffRecord = diffMatchPatch.DiffCleanupEfficiency(diffRecord) - - return diffToHTML(diffSection.FileName, diffRecord, diffLine.Type) + hcd := newHighlightCodeDiff() + diffRecord := hcd.diffWithHighlight(diffSection.FileName, language, diff1[1:], diff2[1:]) + // it seems that Gitea doesn't need the line wrapper of Chroma, so do not add them back + // if the line wrappers are still needed in the future, it can be added back by "diffToHTML(hcd.lineWrapperTags. ...)" + diffHTML := diffToHTML(nil, diffRecord, diffLine.Type) + return DiffInlineWithUnicodeEscape(template.HTML(diffHTML)) } // DiffFile represents a file diff. @@ -1289,7 +1019,7 @@ func readFileName(rd *strings.Reader) (string, bool) { if char == '"' { fmt.Fscanf(rd, "%q ", &name) if len(name) == 0 { - log.Error("Reader has no file name: %v", rd) + log.Error("Reader has no file name: reader=%+v", rd) return "", true } @@ -1311,7 +1041,7 @@ func readFileName(rd *strings.Reader) (string, bool) { } } if len(name) < 2 { - log.Error("Unable to determine name from reader: %v", rd) + log.Error("Unable to determine name from reader: reader=%+v", rd) return "", true } return name[2:], ambiguity diff --git a/services/gitdiff/gitdiff_test.go b/services/gitdiff/gitdiff_test.go index caca0e91d8f13..e88d831759b7b 100644 --- a/services/gitdiff/gitdiff_test.go +++ b/services/gitdiff/gitdiff_test.go @@ -7,7 +7,6 @@ package gitdiff import ( "fmt" - "html/template" "strconv" "strings" "testing" @@ -17,93 +16,27 @@ import ( "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" - "code.gitea.io/gitea/modules/highlight" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/setting" dmp "github.com/sergi/go-diff/diffmatchpatch" "github.com/stretchr/testify/assert" - "gopkg.in/ini.v1" ) -func assertEqual(t *testing.T, s1 string, s2 template.HTML) { - if s1 != string(s2) { - t.Errorf("Did not receive expected results:\nExpected: %s\nActual: %s", s1, s2) - } -} - func TestDiffToHTML(t *testing.T) { - setting.Cfg = ini.Empty() - assertEqual(t, "foo bar biz", diffToHTML("", []dmp.Diff{ + assert.Equal(t, "foo bar biz", diffToHTML(nil, []dmp.Diff{ {Type: dmp.DiffEqual, Text: "foo "}, {Type: dmp.DiffInsert, Text: "bar"}, {Type: dmp.DiffDelete, Text: " baz"}, {Type: dmp.DiffEqual, Text: " biz"}, - }, DiffLineAdd).Content) + }, DiffLineAdd)) - assertEqual(t, "foo bar biz", diffToHTML("", []dmp.Diff{ + assert.Equal(t, "foo bar biz", diffToHTML(nil, []dmp.Diff{ {Type: dmp.DiffEqual, Text: "foo "}, {Type: dmp.DiffDelete, Text: "bar"}, {Type: dmp.DiffInsert, Text: " baz"}, {Type: dmp.DiffEqual, Text: " biz"}, - }, DiffLineDel).Content) - - assertEqual(t, "if !nohl && (lexer != nil || r.GuessLanguage) {", diffToHTML("", []dmp.Diff{ - {Type: dmp.DiffEqual, Text: "if !nohl && (lexer != nil"}, - {Type: dmp.DiffInsert, Text: " || r.GuessLanguage)"}, - {Type: dmp.DiffEqual, Text: " {"}, - }, DiffLineAdd).Content) - - assertEqual(t, "tagURL := fmt.Sprintf("## [%s](%s/%s/%s/%s?q=&type=all&state=closed&milestone=%d) - %s", ge.Milestone\", ge.BaseURL, ge.Owner, ge.Repo, from, milestoneID, time.Now().Format("2006-01-02"))", diffToHTML("", []dmp.Diff{ - {Type: dmp.DiffEqual, Text: "tagURL := fmt.Sprintf("## [%s](%s/%s/%s/%s?q=&type=all&state=closed&milestone=%d) - %s", ge.Milestone\""}, - {Type: dmp.DiffInsert, Text: "f\">getGiteaTagURL(client"}, - {Type: dmp.DiffEqual, Text: ", ge.BaseURL, ge.Owner, ge.Repo, "}, - {Type: dmp.DiffDelete, Text: "from, milestoneID, time.Now().Format("2006-01-02")"}, - {Type: dmp.DiffInsert, Text: "ge.Milestone, from, milestoneID"}, - {Type: dmp.DiffEqual, Text: ")"}, - }, DiffLineDel).Content) - - assertEqual(t, "r.WrapperRenderer(w, language, true, attrs, false)", diffToHTML("", []dmp.Diff{ - {Type: dmp.DiffEqual, Text: "r.WrapperRenderer(w, "}, - {Type: dmp.DiffDelete, Text: "language, true, attrs"}, - {Type: dmp.DiffEqual, Text: ", false)"}, - }, DiffLineDel).Content) - - assertEqual(t, "language, true, attrs, false)", diffToHTML("", []dmp.Diff{ - {Type: dmp.DiffInsert, Text: "language, true, attrs"}, - {Type: dmp.DiffEqual, Text: ", false)"}, - }, DiffLineAdd).Content) - - assertEqual(t, "print("// ", sys.argv)", diffToHTML("", []dmp.Diff{ - {Type: dmp.DiffEqual, Text: "print"}, - {Type: dmp.DiffInsert, Text: "("}, - {Type: dmp.DiffEqual, Text: ""// ", sys.argv"}, - {Type: dmp.DiffInsert, Text: ")"}, - }, DiffLineAdd).Content) - - assertEqual(t, "sh 'useradd -u $(stat -c "%u" .gitignore) jenkins'", diffToHTML("", []dmp.Diff{ - {Type: dmp.DiffEqual, Text: "sh "}, - {Type: dmp.DiffDelete, Text: "4;useradd -u 111 jenkins""}, - {Type: dmp.DiffInsert, Text: "9;useradd -u $(stat -c "%u" .gitignore) jenkins'"}, - {Type: dmp.DiffEqual, Text: ";"}, - }, DiffLineAdd).Content) - - assertEqual(t, " <h4 class="release-list-title df ac">", diffToHTML("", []dmp.Diff{ - {Type: dmp.DiffEqual, Text: " <h"}, - {Type: dmp.DiffInsert, Text: "4 class=&#"}, - {Type: dmp.DiffEqual, Text: "3"}, - {Type: dmp.DiffInsert, Text: "4;release-list-title df ac""}, - {Type: dmp.DiffEqual, Text: ">"}, - }, DiffLineAdd).Content) + }, DiffLineDel)) } func TestParsePatch_skipTo(t *testing.T) { @@ -592,7 +525,6 @@ index 0000000..6bb8f39 if err != nil { t.Errorf("ParsePatch failed: %s", err) } - println(result) diff2 := `diff --git "a/A \\ B" "b/A \\ B" --- "a/A \\ B" @@ -712,18 +644,6 @@ func TestGetDiffRangeWithWhitespaceBehavior(t *testing.T) { } } -func TestDiffToHTML_14231(t *testing.T) { - setting.Cfg = ini.Empty() - diffRecord := diffMatchPatch.DiffMain(highlight.Code("main.v", "", " run()\n"), highlight.Code("main.v", "", " run(db)\n"), true) - diffRecord = diffMatchPatch.DiffCleanupEfficiency(diffRecord) - - expected := ` run(db) -` - output := diffToHTML("main.v", diffRecord, DiffLineAdd) - - assertEqual(t, expected, output.Content) -} - func TestNoCrashes(t *testing.T) { type testcase struct { gitdiff string diff --git a/services/gitdiff/highlightdiff.go b/services/gitdiff/highlightdiff.go new file mode 100644 index 0000000000000..4ceada4d7ec95 --- /dev/null +++ b/services/gitdiff/highlightdiff.go @@ -0,0 +1,223 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package gitdiff + +import ( + "strings" + + "code.gitea.io/gitea/modules/highlight" + + "github.com/sergi/go-diff/diffmatchpatch" +) + +// token is a html tag or entity, eg: "", "", "<" +func extractHTMLToken(s string) (before, token, after string, valid bool) { + for pos1 := 0; pos1 < len(s); pos1++ { + if s[pos1] == '<' { + pos2 := strings.IndexByte(s[pos1:], '>') + if pos2 == -1 { + return "", "", s, false + } + return s[:pos1], s[pos1 : pos1+pos2+1], s[pos1+pos2+1:], true + } else if s[pos1] == '&' { + pos2 := strings.IndexByte(s[pos1:], ';') + if pos2 == -1 { + return "", "", s, false + } + return s[:pos1], s[pos1 : pos1+pos2+1], s[pos1+pos2+1:], true + } + } + return "", "", s, true +} + +// highlightCodeDiff is used to do diff with highlighted HTML code. +// It totally depends on Chroma's valid HTML output and its structure, do not use these functions for other purposes. +// The HTML tags and entities will be replaced by Unicode placeholders: "{TEXT}" => "\uE000{TEXT}\uE001" +// These Unicode placeholders are friendly to the diff. +// Then after diff, the placeholders in diff result will be recovered to the HTML tags and entities. +// It's guaranteed that the tags in final diff result are paired correctly. +type highlightCodeDiff struct { + placeholderBegin rune + placeholderMaxCount int + placeholderIndex int + placeholderTokenMap map[rune]string + tokenPlaceholderMap map[string]rune + + placeholderOverflowCount int + + lineWrapperTags []string +} + +func newHighlightCodeDiff() *highlightCodeDiff { + return &highlightCodeDiff{ + placeholderBegin: rune(0x100000), // Plane 16: Supplementary Private Use Area B (U+100000..U+10FFFD) + placeholderMaxCount: 64000, + placeholderTokenMap: map[rune]string{}, + tokenPlaceholderMap: map[string]rune{}, + } +} + +// nextPlaceholder returns 0 if no more placeholder can be used +// the diff is done line by line, usually there are only a few (no more than 10) placeholders in one line +// so the placeholderMaxCount is impossible to be exhausted in real cases. +func (hcd *highlightCodeDiff) nextPlaceholder() rune { + for hcd.placeholderIndex < hcd.placeholderMaxCount { + r := hcd.placeholderBegin + rune(hcd.placeholderIndex) + hcd.placeholderIndex++ + // only use non-existing (not used by code) rune as placeholders + if _, ok := hcd.placeholderTokenMap[r]; !ok { + return r + } + } + return 0 // no more available placeholder +} + +func (hcd *highlightCodeDiff) isInPlaceholderRange(r rune) bool { + return hcd.placeholderBegin <= r && r < hcd.placeholderBegin+rune(hcd.placeholderMaxCount) +} + +func (hcd *highlightCodeDiff) collectUsedRunes(code string) { + for _, r := range code { + if hcd.isInPlaceholderRange(r) { + // put the existing rune (used by code) in map, then this rune won't be used a placeholder anymore. + hcd.placeholderTokenMap[r] = "" + } + } +} + +func (hcd *highlightCodeDiff) diffWithHighlight(filename, language, codeA, codeB string) []diffmatchpatch.Diff { + hcd.collectUsedRunes(codeA) + hcd.collectUsedRunes(codeB) + + highlightCodeA := highlight.Code(filename, language, codeA) + highlightCodeB := highlight.Code(filename, language, codeB) + + highlightCodeA = hcd.convertToPlaceholders(highlightCodeA) + highlightCodeB = hcd.convertToPlaceholders(highlightCodeB) + + diffs := diffMatchPatch.DiffMain(highlightCodeA, highlightCodeB, true) + diffs = diffMatchPatch.DiffCleanupEfficiency(diffs) + + for i := range diffs { + hcd.recoverOneDiff(&diffs[i]) + } + return diffs +} + +// convertToPlaceholders totally depends on Chroma's valid HTML output and its structure, do not use these functions for other purposes. +func (hcd *highlightCodeDiff) convertToPlaceholders(htmlCode string) string { + var tagStack []string + res := strings.Builder{} + + firstRunForLineTags := hcd.lineWrapperTags == nil + + var beforeToken, token string + var valid bool + + // the standard chroma highlight HTML is " ... " + for { + beforeToken, token, htmlCode, valid = extractHTMLToken(htmlCode) + if !valid || token == "" { + break + } + // write the content before the token into result string, and consume the token in the string + res.WriteString(beforeToken) + + // the line wrapper tags should be removed before diff + if strings.HasPrefix(token, `") + continue + } + + var tokenInMap string + if strings.HasSuffix(token, "" for "" + tokenInMap = token + "" + tagStack = tagStack[:len(tagStack)-1] + } else if token[0] == '<' { // for opening tag + tokenInMap = token + tagStack = append(tagStack, token) + } else if token[0] == '&' { // for html entity + tokenInMap = token + } // else: impossible + + // remember the placeholder and token in the map + placeholder, ok := hcd.tokenPlaceholderMap[tokenInMap] + if !ok { + placeholder = hcd.nextPlaceholder() + if placeholder != 0 { + hcd.tokenPlaceholderMap[tokenInMap] = placeholder + hcd.placeholderTokenMap[placeholder] = tokenInMap + } + } + + if placeholder != 0 { + res.WriteRune(placeholder) // use the placeholder to replace the token + } else { + // unfortunately, all private use runes has been exhausted, no more placeholder could be used, no more converting + // usually, the exhausting won't occur in real cases, the magnitude of used placeholders is not larger than that of the CSS classes outputted by chroma. + hcd.placeholderOverflowCount++ + if strings.HasPrefix(token, "&") { + // when the token is a html entity, something must be outputted even if there is no placeholder. + res.WriteRune(0xFFFD) // replacement character TODO: how to handle this case more gracefully? + res.WriteString(token[1:]) // still output the entity code part, otherwise there will be no diff result. + } + } + } + + // write the remaining string + res.WriteString(htmlCode) + return res.String() +} + +func (hcd *highlightCodeDiff) recoverOneDiff(diff *diffmatchpatch.Diff) { + sb := strings.Builder{} + var tagStack []string + + for _, r := range diff.Text { + token, ok := hcd.placeholderTokenMap[r] + if !ok || token == "" { + sb.WriteRune(r) // if the rune is not a placeholder, write it as it is + continue + } + var tokenToRecover string + if strings.HasPrefix(token, "')+1] + if len(tagStack) == 0 { + continue // if no opening tag in stack yet, skip the closing tag + } + tagStack = tagStack[:len(tagStack)-1] + } else if token[0] == '<' { // for opening tag + tokenToRecover = token + tagStack = append(tagStack, token) + } else if token[0] == '&' { // for html entity + tokenToRecover = token + } // else: impossible + sb.WriteString(tokenToRecover) + } + + if len(tagStack) > 0 { + // close all opening tags + for i := len(tagStack) - 1; i >= 0; i-- { + tagToClose := tagStack[i] + // get the closing tag "" from "" or "" + pos := strings.IndexAny(tagToClose, " >") + if pos != -1 { + sb.WriteString("") + } // else: impossible. every tag was pushed into the stack by the code above and is valid HTML opening tag + } + } + + diff.Text = sb.String() +} diff --git a/services/gitdiff/highlightdiff_test.go b/services/gitdiff/highlightdiff_test.go new file mode 100644 index 0000000000000..1cd78bc94272d --- /dev/null +++ b/services/gitdiff/highlightdiff_test.go @@ -0,0 +1,126 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package gitdiff + +import ( + "fmt" + "strings" + "testing" + + "github.com/sergi/go-diff/diffmatchpatch" + "github.com/stretchr/testify/assert" +) + +func TestDiffWithHighlight(t *testing.T) { + hcd := newHighlightCodeDiff() + diffs := hcd.diffWithHighlight( + "main.v", "", + " run('<>')\n", + " run(db)\n", + ) + + expected := ` run('<>')` + "\n" + output := diffToHTML(nil, diffs, DiffLineDel) + assert.Equal(t, expected, output) + + expected = ` run(db)` + "\n" + output = diffToHTML(nil, diffs, DiffLineAdd) + assert.Equal(t, expected, output) + + hcd = newHighlightCodeDiff() + hcd.placeholderTokenMap['O'] = "" + hcd.placeholderTokenMap['C'] = "" + diff := diffmatchpatch.Diff{} + + diff.Text = "OC" + hcd.recoverOneDiff(&diff) + assert.Equal(t, "", diff.Text) + + diff.Text = "O" + hcd.recoverOneDiff(&diff) + assert.Equal(t, "", diff.Text) + + diff.Text = "C" + hcd.recoverOneDiff(&diff) + assert.Equal(t, "", diff.Text) +} + +func TestDiffWithHighlightPlaceholder(t *testing.T) { + hcd := newHighlightCodeDiff() + diffs := hcd.diffWithHighlight( + "main.js", "", + "a='\U00100000'", + "a='\U0010FFFD''", + ) + assert.Equal(t, "", hcd.placeholderTokenMap[0x00100000]) + assert.Equal(t, "", hcd.placeholderTokenMap[0x0010FFFD]) + + expected := fmt.Sprintf(`a='%s'`, "\U00100000") + output := diffToHTML(hcd.lineWrapperTags, diffs, DiffLineDel) + assert.Equal(t, expected, output) + + hcd = newHighlightCodeDiff() + diffs = hcd.diffWithHighlight( + "main.js", "", + "a='\U00100000'", + "a='\U0010FFFD'", + ) + expected = fmt.Sprintf(`a='%s'`, "\U0010FFFD") + output = diffToHTML(nil, diffs, DiffLineAdd) + assert.Equal(t, expected, output) +} + +func TestDiffWithHighlightPlaceholderExhausted(t *testing.T) { + hcd := newHighlightCodeDiff() + hcd.placeholderMaxCount = 0 + diffs := hcd.diffWithHighlight( + "main.js", "", + "'", + ``, + ) + output := diffToHTML(nil, diffs, DiffLineDel) + expected := fmt.Sprintf(`%s#39;`, "\uFFFD") + assert.Equal(t, expected, output) + + hcd = newHighlightCodeDiff() + hcd.placeholderMaxCount = 0 + diffs = hcd.diffWithHighlight( + "main.js", "", + "a < b", + "a > b", + ) + output = diffToHTML(nil, diffs, DiffLineDel) + expected = fmt.Sprintf(`a %slt; b`, "\uFFFD") + assert.Equal(t, expected, output) + + output = diffToHTML(nil, diffs, DiffLineAdd) + expected = fmt.Sprintf(`a %sgt; b`, "\uFFFD") + assert.Equal(t, expected, output) +} + +func TestDiffWithHighlightTagMatch(t *testing.T) { + totalOverflow := 0 + for i := 0; i < 100; i++ { + hcd := newHighlightCodeDiff() + hcd.placeholderMaxCount = i + diffs := hcd.diffWithHighlight( + "main.js", "", + "a='1'", + "b='2'", + ) + totalOverflow += hcd.placeholderOverflowCount + + output := diffToHTML(nil, diffs, DiffLineDel) + c1 := strings.Count(output, " 0 { + if len(opts.User) > 0 { + if !canAuth { + return fmt.Errorf("SMTP server does not support AUTH, but credentials provided") + } + var auth smtp.Auth if strings.Contains(options, "CRAM-MD5") { @@ -219,34 +236,34 @@ func (s *smtpSender) Send(from string, to []string, msg io.WriterTo) error { if auth != nil { if err = client.Auth(auth); err != nil { - return fmt.Errorf("Auth: %v", err) + return fmt.Errorf("failed to authenticate SMTP: %v", err) } } } if opts.OverrideEnvelopeFrom { if err = client.Mail(opts.EnvelopeFrom); err != nil { - return fmt.Errorf("Mail: %v", err) + return fmt.Errorf("failed to issue MAIL command: %v", err) } } else { if err = client.Mail(from); err != nil { - return fmt.Errorf("Mail: %v", err) + return fmt.Errorf("failed to issue MAIL command: %v", err) } } for _, rec := range to { if err = client.Rcpt(rec); err != nil { - return fmt.Errorf("Rcpt: %v", err) + return fmt.Errorf("failed to issue RCPT command: %v", err) } } w, err := client.Data() if err != nil { - return fmt.Errorf("Data: %v", err) + return fmt.Errorf("failed to issue DATA command: %v", err) } else if _, err = msg.WriteTo(w); err != nil { - return fmt.Errorf("WriteTo: %v", err) + return fmt.Errorf("SMTP write failed: %v", err) } else if err = w.Close(); err != nil { - return fmt.Errorf("Close: %v", err) + return fmt.Errorf("SMTP close failed: %v", err) } return client.Quit() @@ -338,13 +355,13 @@ func NewContext() { return } - switch setting.MailService.MailerType { - case "smtp": - Sender = &smtpSender{} + switch setting.MailService.Protocol { case "sendmail": Sender = &sendmailSender{} case "dummy": Sender = &dummySender{} + default: + Sender = &smtpSender{} } mailQueue = queue.CreateQueue("mail", func(data ...queue.Data) []queue.Data { diff --git a/services/mirror/mirror.go b/services/mirror/mirror.go index 8321829ad26ba..3b4a8e5f8a6d7 100644 --- a/services/mirror/mirror.go +++ b/services/mirror/mirror.go @@ -106,7 +106,7 @@ func Update(ctx context.Context, pullLimit, pushLimit int) error { pushMirrorsRequested := 0 if pushLimit != 0 { - if err := repo_model.PushMirrorsIterate(pushLimit, func(idx int, bean interface{}) error { + if err := repo_model.PushMirrorsIterate(ctx, pushLimit, func(idx int, bean interface{}) error { if err := handler(idx, bean); err != nil { return err } diff --git a/services/mirror/mirror_push.go b/services/mirror/mirror_push.go index 2927bed72b279..0c8960d78bf20 100644 --- a/services/mirror/mirror_push.go +++ b/services/mirror/mirror_push.go @@ -94,7 +94,7 @@ func SyncPushMirror(ctx context.Context, mirrorID int64) bool { log.Error("PANIC whilst syncPushMirror[%d] Panic: %v\nStacktrace: %s", mirrorID, err, log.Stack(2)) }() - m, err := repo_model.GetPushMirrorByID(mirrorID) + m, err := repo_model.GetPushMirror(ctx, repo_model.PushMirrorOptions{ID: mirrorID}) if err != nil { log.Error("GetPushMirrorByID [%d]: %v", mirrorID, err) return false @@ -116,7 +116,7 @@ func SyncPushMirror(ctx context.Context, mirrorID int64) bool { m.LastUpdateUnix = timeutil.TimeStampNow() - if err := repo_model.UpdatePushMirror(m); err != nil { + if err := repo_model.UpdatePushMirror(ctx, m); err != nil { log.Error("UpdatePushMirror [%d]: %v", m.ID, err) return false diff --git a/services/packages/container/cleanup.go b/services/packages/container/cleanup.go index 390a0b7b052d5..d23a481f279e4 100644 --- a/services/packages/container/cleanup.go +++ b/services/packages/container/cleanup.go @@ -6,10 +6,13 @@ package container import ( "context" + "strings" "time" packages_model "code.gitea.io/gitea/models/packages" container_model "code.gitea.io/gitea/models/packages/container" + user_model "code.gitea.io/gitea/models/user" + container_module "code.gitea.io/gitea/modules/packages/container" "code.gitea.io/gitea/modules/util" ) @@ -59,7 +62,7 @@ func cleanupExpiredUploadedBlobs(ctx context.Context, olderThan time.Duration) e ExactMatch: true, Value: container_model.UploadVersion, }, - IsInternal: true, + IsInternal: util.OptionalBoolTrue, HasFiles: util.OptionalBoolFalse, }) if err != nil { @@ -78,3 +81,25 @@ func cleanupExpiredUploadedBlobs(ctx context.Context, olderThan time.Duration) e return nil } + +// UpdateRepositoryNames updates the repository name property for all packages of the specific owner +func UpdateRepositoryNames(ctx context.Context, owner *user_model.User, newOwnerName string) error { + ps, err := packages_model.GetPackagesByType(ctx, owner.ID, packages_model.TypeContainer) + if err != nil { + return err + } + + newOwnerName = strings.ToLower(newOwnerName) + + for _, p := range ps { + if err := packages_model.DeletePropertyByName(ctx, packages_model.PropertyTypePackage, p.ID, container_module.PropertyRepository); err != nil { + return err + } + + if _, err := packages_model.InsertProperty(ctx, packages_model.PropertyTypePackage, p.ID, container_module.PropertyRepository, newOwnerName+"/"+p.LowerName); err != nil { + return err + } + } + + return nil +} diff --git a/services/packages/packages.go b/services/packages/packages.go index 7f25fce5b85cc..4bc31a34e8051 100644 --- a/services/packages/packages.go +++ b/services/packages/packages.go @@ -13,11 +13,13 @@ import ( "code.gitea.io/gitea/models/db" packages_model "code.gitea.io/gitea/models/packages" + repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/notification" packages_module "code.gitea.io/gitea/modules/packages" + "code.gitea.io/gitea/modules/util" container_service "code.gitea.io/gitea/services/packages/container" ) @@ -32,10 +34,11 @@ type PackageInfo struct { // PackageCreationInfo describes a package to create type PackageCreationInfo struct { PackageInfo - SemverCompatible bool - Creator *user_model.User - Metadata interface{} - Properties map[string]string + SemverCompatible bool + Creator *user_model.User + Metadata interface{} + PackageProperties map[string]string + VersionProperties map[string]string } // PackageFileInfo describes a package file @@ -108,8 +111,9 @@ func createPackageAndAddFile(pvci *PackageCreationInfo, pfci *PackageFileCreatio } func createPackageAndVersion(ctx context.Context, pvci *PackageCreationInfo, allowDuplicate bool) (*packages_model.PackageVersion, bool, error) { - log.Trace("Creating package: %v, %v, %v, %s, %s, %+v, %v", pvci.Creator.ID, pvci.Owner.ID, pvci.PackageType, pvci.Name, pvci.Version, pvci.Properties, allowDuplicate) + log.Trace("Creating package: %v, %v, %v, %s, %s, %+v, %+v, %v", pvci.Creator.ID, pvci.Owner.ID, pvci.PackageType, pvci.Name, pvci.Version, pvci.PackageProperties, pvci.VersionProperties, allowDuplicate) + packageCreated := true p := &packages_model.Package{ OwnerID: pvci.Owner.ID, Type: pvci.PackageType, @@ -119,18 +123,29 @@ func createPackageAndVersion(ctx context.Context, pvci *PackageCreationInfo, all } var err error if p, err = packages_model.TryInsertPackage(ctx, p); err != nil { - if err != packages_model.ErrDuplicatePackage { + if err == packages_model.ErrDuplicatePackage { + packageCreated = false + } else { log.Error("Error inserting package: %v", err) return nil, false, err } } + if packageCreated { + for name, value := range pvci.PackageProperties { + if _, err := packages_model.InsertProperty(ctx, packages_model.PropertyTypePackage, p.ID, name, value); err != nil { + log.Error("Error setting package property: %v", err) + return nil, false, err + } + } + } + metadataJSON, err := json.Marshal(pvci.Metadata) if err != nil { return nil, false, err } - created := true + versionCreated := true pv := &packages_model.PackageVersion{ PackageID: p.ID, CreatorID: pvci.Creator.ID, @@ -140,7 +155,7 @@ func createPackageAndVersion(ctx context.Context, pvci *PackageCreationInfo, all } if pv, err = packages_model.GetOrInsertVersion(ctx, pv); err != nil { if err == packages_model.ErrDuplicatePackageVersion { - created = false + versionCreated = false } if err != packages_model.ErrDuplicatePackageVersion || !allowDuplicate { log.Error("Error inserting package: %v", err) @@ -148,8 +163,8 @@ func createPackageAndVersion(ctx context.Context, pvci *PackageCreationInfo, all } } - if created { - for name, value := range pvci.Properties { + if versionCreated { + for name, value := range pvci.VersionProperties { if _, err := packages_model.InsertProperty(ctx, packages_model.PropertyTypeVersion, pv.ID, name, value); err != nil { log.Error("Error setting package version property: %v", err) return nil, false, err @@ -157,7 +172,7 @@ func createPackageAndVersion(ctx context.Context, pvci *PackageCreationInfo, all } } - return pv, created, nil + return pv, versionCreated, nil } // AddFileToExistingPackage adds a file to an existing package. If the package does not exist, ErrPackageNotExist is returned @@ -348,9 +363,18 @@ func Cleanup(unused context.Context, olderThan time.Duration) error { return err } - if err := packages_model.DeletePackagesIfUnreferenced(ctx); err != nil { + ps, err := packages_model.FindUnreferencedPackages(ctx) + if err != nil { return err } + for _, p := range ps { + if err := packages_model.DeleteAllProperties(ctx, packages_model.PropertyTypePackage, p.ID); err != nil { + return err + } + if err := packages_model.DeletePackageByID(ctx, p.ID); err != nil { + return err + } + } pbs, err := packages_model.FindExpiredUnreferencedBlobs(ctx, olderThan) if err != nil { @@ -426,7 +450,7 @@ func GetFileStreamByPackageVersionAndFileID(ctx context.Context, owner *user_mod // GetFileStreamByPackageVersion returns the content of the specific package file func GetFileStreamByPackageVersion(ctx context.Context, pv *packages_model.PackageVersion, pfi *PackageFileInfo) (io.ReadCloser, *packages_model.PackageFile, error) { - pf, err := packages_model.GetFileForVersionByName(db.DefaultContext, pv.ID, pfi.Filename, pfi.CompositeKey) + pf, err := packages_model.GetFileForVersionByName(ctx, pv.ID, pfi.Filename, pfi.CompositeKey) if err != nil { return nil, nil, err } @@ -451,3 +475,31 @@ func GetPackageFileStream(ctx context.Context, pf *packages_model.PackageFile) ( } return s, pf, err } + +// RemoveAllPackages for User +func RemoveAllPackages(ctx context.Context, userID int64) (int, error) { + count := 0 + for { + pkgVersions, _, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{ + Paginator: &db.ListOptions{ + PageSize: repo_model.RepositoryListDefaultPageSize, + Page: 1, + }, + OwnerID: userID, + IsInternal: util.OptionalBoolNone, + }) + if err != nil { + return count, fmt.Errorf("GetOwnedPackages[%d]: %w", userID, err) + } + if len(pkgVersions) == 0 { + break + } + for _, pv := range pkgVersions { + if err := DeletePackageVersionAndReferences(ctx, pv); err != nil { + return count, fmt.Errorf("unable to delete package %d:%s[%d]. Error: %w", pv.PackageID, pv.Version, pv.ID, err) + } + count++ + } + } + return count, nil +} diff --git a/services/pull/patch.go b/services/pull/patch.go index bb09acc89f63a..32895b2e784fc 100644 --- a/services/pull/patch.go +++ b/services/pull/patch.go @@ -124,6 +124,7 @@ func (e *errMergeConflict) Error() string { } func attemptMerge(ctx context.Context, file *unmergedFile, tmpBasePath string, gitRepo *git.Repository) error { + log.Trace("Attempt to merge:\n%v", file) switch { case file.stage1 != nil && (file.stage2 == nil || file.stage3 == nil): // 1. Deleted in one or both: @@ -295,7 +296,8 @@ func checkConflicts(ctx context.Context, pr *issues_model.PullRequest, gitRepo * var treeHash string treeHash, _, err = git.NewCommand(ctx, "write-tree").RunStdString(&git.RunOpts{Dir: tmpBasePath}) if err != nil { - return false, err + lsfiles, _, _ := git.NewCommand(ctx, "ls-files", "-u").RunStdString(&git.RunOpts{Dir: tmpBasePath}) + return false, fmt.Errorf("unable to write unconflicted tree: %w\n`git ls-files -u`:\n%s", err, lsfiles) } treeHash = strings.TrimSpace(treeHash) baseTree, err := gitRepo.GetTree("base") diff --git a/services/pull/patch_unmerged.go b/services/pull/patch_unmerged.go index 38394191429cd..465465d0daed9 100644 --- a/services/pull/patch_unmerged.go +++ b/services/pull/patch_unmerged.go @@ -42,6 +42,17 @@ func (line *lsFileLine) SameAs(other *lsFileLine) bool { line.path == other.path } +// String provides a string representation for logging +func (line *lsFileLine) String() string { + if line == nil { + return "" + } + if line.err != nil { + return fmt.Sprintf("%d %s %s %s %v", line.stage, line.mode, line.path, line.sha, line.err) + } + return fmt.Sprintf("%d %s %s %s", line.stage, line.mode, line.path, line.sha) +} + // readUnmergedLsFileLines calls git ls-files -u -z and parses the lines into mode-sha-stage-path quadruplets // it will push these to the provided channel closing it at the end func readUnmergedLsFileLines(ctx context.Context, tmpBasePath string, outputChan chan *lsFileLine) { @@ -118,6 +129,17 @@ type unmergedFile struct { err error } +// String provides a string representation of the an unmerged file for logging +func (u *unmergedFile) String() string { + if u == nil { + return "" + } + if u.err != nil { + return fmt.Sprintf("error: %v\n%v\n%v\n%v", u.err, u.stage1, u.stage2, u.stage3) + } + return fmt.Sprintf("%v\n%v\n%v", u.stage1, u.stage2, u.stage3) +} + // unmergedFiles will collate the output from readUnstagedLsFileLines in to file triplets and send them // to the provided channel, closing at the end. func unmergedFiles(ctx context.Context, tmpBasePath string, unmerged chan *unmergedFile) { @@ -138,6 +160,7 @@ func unmergedFiles(ctx context.Context, tmpBasePath string, unmerged chan *unmer next := &unmergedFile{} for line := range lsFileLineChan { + log.Trace("Got line: %v Current State:\n%v", line, next) if line.err != nil { log.Error("Unable to run ls-files -u -z! Error: %v", line.err) unmerged <- &unmergedFile{err: fmt.Errorf("unable to run ls-files -u -z! Error: %v", line.err)} @@ -149,7 +172,7 @@ func unmergedFiles(ctx context.Context, tmpBasePath string, unmerged chan *unmer case 0: // Should not happen as this represents successfully merged file - we will tolerate and ignore though case 1: - if next.stage1 != nil { + if next.stage1 != nil || next.stage2 != nil || next.stage3 != nil { // We need to handle the unstaged file stage1,stage2,stage3 unmerged <- next } diff --git a/services/pull/review.go b/services/pull/review.go index 22e0ae9853955..8d8903c6a9521 100644 --- a/services/pull/review.go +++ b/services/pull/review.go @@ -20,6 +20,7 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/notification" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/util" ) // CreateCodeComment creates a comment on the code line @@ -271,7 +272,7 @@ func SubmitReview(ctx context.Context, doer *user_model.User, gitRepo *git.Repos } // DismissReview dismissing stale review by repo admin -func DismissReview(ctx context.Context, reviewID, repoID int64, message string, doer *user_model.User, isDismiss bool) (comment *issues_model.Comment, err error) { +func DismissReview(ctx context.Context, reviewID, repoID int64, message string, doer *user_model.User, isDismiss, dismissPriors bool) (comment *issues_model.Comment, err error) { review, err := issues_model.GetReviewByID(ctx, reviewID) if err != nil { return @@ -295,6 +296,22 @@ func DismissReview(ctx context.Context, reviewID, repoID int64, message string, return } + if dismissPriors { + reviews, err := issues_model.GetReviews(ctx, &issues_model.GetReviewOptions{ + IssueID: review.IssueID, + ReviewerID: review.ReviewerID, + Dismissed: util.OptionalBoolFalse, + }) + if err != nil { + return nil, err + } + for _, oldReview := range reviews { + if err = issues_model.DismissReview(oldReview, true); err != nil { + return nil, err + } + } + } + if !isDismiss { return nil, nil } diff --git a/services/repository/adopt.go b/services/repository/adopt.go index 48f049cd28117..6d6611c705f89 100644 --- a/services/repository/adopt.go +++ b/services/repository/adopt.go @@ -143,8 +143,6 @@ func adoptRepository(ctx context.Context, repoPath string, u *user_model.User, r return fmt.Errorf("setDefaultBranch: %v", err) } } - - repo.DefaultBranch = strings.TrimPrefix(repo.DefaultBranch, git.BranchPrefix) } branches, _, _ := gitRepo.GetBranchNames(0, 0) found := false diff --git a/services/repository/cache.go b/services/repository/cache.go index 5b0c929be1a48..855fe7f4a042e 100644 --- a/services/repository/cache.go +++ b/services/repository/cache.go @@ -34,15 +34,13 @@ func CacheRef(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Rep return err } - commitsCount, err := cache.GetInt64(repo.GetCommitsCountCacheKey(getRefName(fullRefName), true), commit.CommitsCount) - if err != nil { - return err + if gitRepo.LastCommitCache == nil { + commitsCount, err := cache.GetInt64(repo.GetCommitsCountCacheKey(getRefName(fullRefName), true), commit.CommitsCount) + if err != nil { + return err + } + gitRepo.LastCommitCache = git.NewLastCommitCache(commitsCount, repo.FullName(), gitRepo, cache.GetCache()) } - if commitsCount < setting.CacheService.LastCommit.CommitsCount { - return nil - } - - commitCache := git.NewLastCommitCache(repo.FullName(), gitRepo, setting.LastCommitCacheTTLSeconds, cache.GetCache()) - return commitCache.CacheCommit(ctx, commit) + return commit.CacheCommit(ctx) } diff --git a/services/repository/files/content.go b/services/repository/files/content.go index 2237671a60cbb..34c8aeec25e43 100644 --- a/services/repository/files/content.go +++ b/services/repository/files/content.go @@ -101,6 +101,22 @@ func GetContentsOrList(ctx context.Context, repo *repo_model.Repository, treePat return fileList, nil } +// GetObjectTypeFromTreeEntry check what content is behind it +func GetObjectTypeFromTreeEntry(entry *git.TreeEntry) ContentType { + switch { + case entry.IsDir(): + return ContentTypeDir + case entry.IsSubModule(): + return ContentTypeSubmodule + case entry.IsExecutable(), entry.IsRegular(): + return ContentTypeRegular + case entry.IsLink(): + return ContentTypeLink + default: + return "" + } +} + // GetContents gets the meta data on a file's contents. Ref can be a branch, commit or tag func GetContents(ctx context.Context, repo *repo_model.Repository, treePath, ref string, forList bool) (*api.ContentsResponse, error) { if ref == "" { @@ -149,13 +165,24 @@ func GetContents(ctx context.Context, repo *repo_model.Repository, treePath, ref } selfURLString := selfURL.String() + err = gitRepo.AddLastCommitCache(repo.GetCommitsCountCacheKey(ref, refType != git.ObjectCommit), repo.FullName(), commitID) + if err != nil { + return nil, err + } + + lastCommit, err := commit.GetCommitByPath(treePath) + if err != nil { + return nil, err + } + // All content types have these fields in populated contentsResponse := &api.ContentsResponse{ - Name: entry.Name(), - Path: treePath, - SHA: entry.ID.String(), - Size: entry.Size(), - URL: &selfURLString, + Name: entry.Name(), + Path: treePath, + SHA: entry.ID.String(), + LastCommitSHA: lastCommit.ID.String(), + Size: entry.Size(), + URL: &selfURLString, Links: &api.FileLinksResponse{ Self: &selfURLString, }, diff --git a/services/repository/files/content_test.go b/services/repository/files/content_test.go index 342ebae329168..24fcd6c4c5d5e 100644 --- a/services/repository/files/content_test.go +++ b/services/repository/files/content_test.go @@ -33,17 +33,18 @@ func getExpectedReadmeContentsResponse() *api.ContentsResponse { gitURL := "https://try.gitea.io/api/v1/repos/user2/repo1/git/blobs/" + sha downloadURL := "https://try.gitea.io/user2/repo1/raw/branch/master/" + treePath return &api.ContentsResponse{ - Name: treePath, - Path: treePath, - SHA: "4b4851ad51df6a7d9f25c979345979eaeb5b349f", - Type: "file", - Size: 30, - Encoding: &encoding, - Content: &content, - URL: &selfURL, - HTMLURL: &htmlURL, - GitURL: &gitURL, - DownloadURL: &downloadURL, + Name: treePath, + Path: treePath, + SHA: "4b4851ad51df6a7d9f25c979345979eaeb5b349f", + LastCommitSHA: "65f1bf27bc3bf70f64657658635e66094edbcb4d", + Type: "file", + Size: 30, + Encoding: &encoding, + Content: &content, + URL: &selfURL, + HTMLURL: &htmlURL, + GitURL: &gitURL, + DownloadURL: &downloadURL, Links: &api.FileLinksResponse{ Self: &selfURL, GitURL: &gitURL, diff --git a/services/repository/files/file_test.go b/services/repository/files/file_test.go index ee0582dfc2170..e158c63de24a7 100644 --- a/services/repository/files/file_test.go +++ b/services/repository/files/file_test.go @@ -43,17 +43,18 @@ func getExpectedFileResponse() *api.FileResponse { downloadURL := setting.AppURL + "user2/repo1/raw/branch/master/" + treePath return &api.FileResponse{ Content: &api.ContentsResponse{ - Name: treePath, - Path: treePath, - SHA: sha, - Type: "file", - Size: 30, - Encoding: &encoding, - Content: &content, - URL: &selfURL, - HTMLURL: &htmlURL, - GitURL: &gitURL, - DownloadURL: &downloadURL, + Name: treePath, + Path: treePath, + SHA: sha, + LastCommitSHA: "65f1bf27bc3bf70f64657658635e66094edbcb4d", + Type: "file", + Size: 30, + Encoding: &encoding, + Content: &content, + URL: &selfURL, + HTMLURL: &htmlURL, + GitURL: &gitURL, + DownloadURL: &downloadURL, Links: &api.FileLinksResponse{ Self: &selfURL, GitURL: &gitURL, diff --git a/services/repository/template.go b/services/repository/template.go index d7e8145811feb..3f2291ad63781 100644 --- a/services/repository/template.go +++ b/services/repository/template.go @@ -23,6 +23,11 @@ func GenerateIssueLabels(ctx context.Context, templateRepo, generateRepo *repo_m if err != nil { return err } + // Prevent insert being called with an empty slice which would result in + // err "no element on slice when insert". + if len(templateLabels) == 0 { + return nil + } newLabels := make([]*issues_model.Label, 0, len(templateLabels)) for _, templateLabel := range templateLabels { diff --git a/services/user/user.go b/services/user/user.go index 4db4d7ca17f12..1edd9294cbfbd 100644 --- a/services/user/user.go +++ b/services/user/user.go @@ -21,19 +21,117 @@ import ( repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/avatar" + "code.gitea.io/gitea/modules/eventsource" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/storage" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/services/packages" ) // DeleteUser completely and permanently deletes everything of a user, // but issues/comments/pulls will be kept and shown as someone has been deleted, // unless the user is younger than USER_DELETE_WITH_COMMENTS_MAX_DAYS. -func DeleteUser(u *user_model.User) error { +func DeleteUser(ctx context.Context, u *user_model.User, purge bool) error { if u.IsOrganization() { return fmt.Errorf("%s is an organization not a user", u.Name) } + if purge { + // Disable the user first + // NOTE: This is deliberately not within a transaction as it must disable the user immediately to prevent any further action by the user to be purged. + if err := user_model.UpdateUserCols(ctx, &user_model.User{ + ID: u.ID, + IsActive: false, + IsRestricted: true, + IsAdmin: false, + ProhibitLogin: true, + Passwd: "", + Salt: "", + PasswdHashAlgo: "", + MaxRepoCreation: 0, + }, "is_active", "is_restricted", "is_admin", "prohibit_login", "max_repo_creation", "passwd", "salt", "passwd_hash_algo"); err != nil { + return fmt.Errorf("unable to disable user: %s[%d] prior to purge. UpdateUserCols: %w", u.Name, u.ID, err) + } + + // Force any logged in sessions to log out + // FIXME: We also need to tell the session manager to log them out too. + eventsource.GetManager().SendMessage(u.ID, &eventsource.Event{ + Name: "logout", + }) + + // Delete all repos belonging to this user + // Now this is not within a transaction because there are internal transactions within the DeleteRepository + // BUT: the db will still be consistent even if a number of repos have already been deleted. + // And in fact we want to capture any repositories that are being created in other transactions in the meantime + // + // An alternative option here would be write a DeleteAllRepositoriesForUserID function which would delete all of the repos + // but such a function would likely get out of date + for { + repos, _, err := repo_model.GetUserRepositories(&repo_model.SearchRepoOptions{ + ListOptions: db.ListOptions{ + PageSize: repo_model.RepositoryListDefaultPageSize, + Page: 1, + }, + Private: true, + OwnerID: u.ID, + Actor: u, + }) + if err != nil { + return fmt.Errorf("SearchRepositoryByName: %v", err) + } + if len(repos) == 0 { + break + } + for _, repo := range repos { + if err := models.DeleteRepository(u, u.ID, repo.ID); err != nil { + return fmt.Errorf("unable to delete repository %s for %s[%d]. Error: %v", repo.Name, u.Name, u.ID, err) + } + } + } + + // Remove from Organizations and delete last owner organizations + // Now this is not within a transaction because there are internal transactions within the DeleteOrganization + // BUT: the db will still be consistent even if a number of organizations memberships and organizations have already been deleted + // And in fact we want to capture any organization additions that are being created in other transactions in the meantime + // + // An alternative option here would be write a function which would delete all organizations but it seems + // but such a function would likely get out of date + for { + orgs, err := organization.FindOrgs(organization.FindOrgOptions{ + ListOptions: db.ListOptions{ + PageSize: repo_model.RepositoryListDefaultPageSize, + Page: 1, + }, + UserID: u.ID, + IncludePrivate: true, + }) + if err != nil { + return fmt.Errorf("unable to find org list for %s[%d]. Error: %v", u.Name, u.ID, err) + } + if len(orgs) == 0 { + break + } + for _, org := range orgs { + if err := models.RemoveOrgUser(org.ID, u.ID); err != nil { + if organization.IsErrLastOrgOwner(err) { + err = organization.DeleteOrganization(ctx, org) + } + if err != nil { + return fmt.Errorf("unable to remove user %s[%d] from org %s[%d]. Error: %v", u.Name, u.ID, org.Name, org.ID, err) + } + } + } + } + + // Delete Packages + if setting.Packages.Enabled { + if _, err := packages.RemoveAllPackages(ctx, u.ID); err != nil { + return err + } + } + } + ctx, committer, err := db.TxContext() if err != nil { return err @@ -41,7 +139,8 @@ func DeleteUser(u *user_model.User) error { defer committer.Close() // Note: A user owns any repository or belongs to any organization - // cannot perform delete operation. + // cannot perform delete operation. This causes a race with the purge above + // however consistency requires that we ensure that this is the case // Check ownership of repository. count, err := repo_model.CountRepositories(ctx, repo_model.CountRepositoryOptions{OwnerID: u.ID}) @@ -66,7 +165,7 @@ func DeleteUser(u *user_model.User) error { return models.ErrUserOwnPackages{UID: u.ID} } - if err := models.DeleteUser(ctx, u); err != nil { + if err := models.DeleteUser(ctx, u, purge); err != nil { return fmt.Errorf("DeleteUser: %v", err) } @@ -117,7 +216,7 @@ func DeleteInactiveUsers(ctx context.Context, olderThan time.Duration) error { return db.ErrCancelledf("Before delete inactive user %s", u.Name) default: } - if err := DeleteUser(u); err != nil { + if err := DeleteUser(ctx, u, false); err != nil { // Ignore users that were set inactive by admin. if models.IsErrUserOwnRepos(err) || models.IsErrUserHasOrgs(err) || models.IsErrUserOwnPackages(err) { continue diff --git a/services/user/user_test.go b/services/user/user_test.go index cfa02b0033116..d8673593df22c 100644 --- a/services/user/user_test.go +++ b/services/user/user_test.go @@ -33,7 +33,7 @@ func TestDeleteUser(t *testing.T) { ownedRepos := make([]*repo_model.Repository, 0, 10) assert.NoError(t, db.GetEngine(db.DefaultContext).Find(&ownedRepos, &repo_model.Repository{OwnerID: userID})) if len(ownedRepos) > 0 { - err := DeleteUser(user) + err := DeleteUser(db.DefaultContext, user, false) assert.Error(t, err) assert.True(t, models.IsErrUserOwnRepos(err)) return @@ -47,7 +47,7 @@ func TestDeleteUser(t *testing.T) { return } } - assert.NoError(t, DeleteUser(user)) + assert.NoError(t, DeleteUser(db.DefaultContext, user, false)) unittest.AssertNotExistsBean(t, &user_model.User{ID: userID}) unittest.CheckConsistencyFor(t, &user_model.User{}, &repo_model.Repository{}) } @@ -57,7 +57,27 @@ func TestDeleteUser(t *testing.T) { test(11) org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) - assert.Error(t, DeleteUser(org)) + assert.Error(t, DeleteUser(db.DefaultContext, org, false)) +} + +func TestPurgeUser(t *testing.T) { + test := func(userID int64) { + assert.NoError(t, unittest.PrepareTestDatabase()) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userID}).(*user_model.User) + + err := DeleteUser(db.DefaultContext, user, true) + assert.NoError(t, err) + + unittest.AssertNotExistsBean(t, &user_model.User{ID: userID}) + unittest.CheckConsistencyFor(t, &user_model.User{}, &repo_model.Repository{}) + } + test(2) + test(4) + test(8) + test(11) + + org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) + assert.Error(t, DeleteUser(db.DefaultContext, org, false)) } func TestCreateUser(t *testing.T) { @@ -72,7 +92,7 @@ func TestCreateUser(t *testing.T) { assert.NoError(t, user_model.CreateUser(user)) - assert.NoError(t, DeleteUser(user)) + assert.NoError(t, DeleteUser(db.DefaultContext, user, false)) } func TestCreateUser_Issue5882(t *testing.T) { @@ -101,6 +121,6 @@ func TestCreateUser_Issue5882(t *testing.T) { assert.Equal(t, !u.AllowCreateOrganization, v.disableOrgCreation) - assert.NoError(t, DeleteUser(v.user)) + assert.NoError(t, DeleteUser(db.DefaultContext, v.user, false)) } } diff --git a/templates/admin/config.tmpl b/templates/admin/config.tmpl index a55a797262a01..ccd1029cd80c1 100644 --- a/templates/admin/config.tmpl +++ b/templates/admin/config.tmpl @@ -218,12 +218,7 @@ {{if .MailerEnabled}}
{{.locale.Tr "admin.config.mailer_name"}}
{{.Mailer.Name}}
- {{if eq .Mailer.MailerType "smtp"}} -
{{.locale.Tr "admin.config.mailer_disable_helo"}}
-
{{if .DisableHelo}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}
-
{{.locale.Tr "admin.config.mailer_host"}}
-
{{.Mailer.Host}}
- {{else if eq .Mailer.MailerType "sendmail"}} + {{if eq .Mailer.Protocol "sendmail"}}
{{.locale.Tr "admin.config.mailer_use_sendmail"}}
{{svg "octicon-check"}}
{{.locale.Tr "admin.config.mailer_sendmail_path"}}
@@ -232,6 +227,18 @@
{{.Mailer.SendmailArgs}}
{{.locale.Tr "admin.config.mailer_sendmail_timeout"}}
{{.Mailer.SendmailTimeout}} {{.locale.Tr "tool.raw_seconds"}}
+ {{else if eq .Mailer.Protocol "dummy"}} +
{{.locale.Tr "admin.config.mailer_use_dummy"}}
+
{{svg "octicon-check"}}
+ {{else}}{{/* SMTP family */}} +
{{.locale.Tr "admin.config.mailer_protocol"}}
+
{{.Mailer.Protocol}}
+
{{.locale.Tr "admin.config.mailer_enable_helo"}}
+
{{if .Mailer.EnableHelo}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}
+
{{.locale.Tr "admin.config.mailer_smtp_addr"}}
+
{{.Mailer.SMTPAddr}}
+
{{.locale.Tr "admin.config.mailer_smtp_port"}}
+
{{.Mailer.SMTPPort}}
{{end}}
{{.locale.Tr "admin.config.mailer_user"}}
{{if .Mailer.User}}{{.Mailer.User}}{{else}}(empty){{end}}

diff --git a/templates/admin/packages/list.tmpl b/templates/admin/packages/list.tmpl index 18e8c5fed8da6..61721532a441b 100644 --- a/templates/admin/packages/list.tmpl +++ b/templates/admin/packages/list.tmpl @@ -21,6 +21,7 @@ + diff --git a/templates/admin/user/edit.tmpl b/templates/admin/user/edit.tmpl index 29dcaa127af28..17cbef9f108a7 100644 --- a/templates/admin/user/edit.tmpl +++ b/templates/admin/user/edit.tmpl @@ -151,7 +151,7 @@
-
{{.locale.Tr "admin.users.delete_account"}}
+
{{.locale.Tr "admin.users.delete_account"}}
@@ -196,7 +196,7 @@
- - + {{svg "octicon-bell"}} diff --git a/templates/base/head_script.tmpl b/templates/base/head_script.tmpl index 2f74b959e2a1a..48a3df693a39b 100644 --- a/templates/base/head_script.tmpl +++ b/templates/base/head_script.tmpl @@ -4,7 +4,6 @@ If you are customizing Gitea, please do not change this file. If you introduce mistakes in it, Gitea JavaScript code wouldn't run correctly. */}} - diff --git a/templates/repo/clone_script.tmpl b/templates/repo/clone_script.tmpl new file mode 100644 index 0000000000000..48b7ad3299ca2 --- /dev/null +++ b/templates/repo/clone_script.tmpl @@ -0,0 +1,23 @@ + diff --git a/templates/repo/commits.tmpl b/templates/repo/commits.tmpl index 7e068a370c9fa..9282e1d387ef2 100644 --- a/templates/repo/commits.tmpl +++ b/templates/repo/commits.tmpl @@ -3,9 +3,9 @@ {{template "repo/header" .}}
{{template "repo/sub_menu" .}} -