Compare commits
87 Commits
0xsysr3ll/
...
renovate/t
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
51f4ce1358 | ||
|
|
4939f13dbe | ||
|
|
5e57fdcf66 | ||
|
|
cf4883a55e | ||
|
|
5e64d49c32 | ||
|
|
c6bcfe0ae4 | ||
|
|
6076878f76 | ||
|
|
8f0c904928 | ||
|
|
04b9d87174 | ||
|
|
b499976902 | ||
|
|
87fb0dfd6c | ||
|
|
b6a913211a | ||
|
|
39ae32f509 | ||
|
|
c2977f6430 | ||
|
|
92504b7864 | ||
|
|
018e04a657 | ||
|
|
e503de323a | ||
|
|
bcd8002887 | ||
|
|
33a5d9a9ac | ||
|
|
15be3d7475 | ||
|
|
55c2d541e6 | ||
|
|
1ed86c14c0 | ||
|
|
91261f6a61 | ||
|
|
3dea58eead | ||
|
|
3eea8ee98e | ||
|
|
7cd3521cfd | ||
|
|
e53c2a34dc | ||
|
|
095784bf62 | ||
|
|
4f7819f028 | ||
|
|
028c7c2434 | ||
|
|
e3dc1c302d | ||
|
|
a44a3b1e14 | ||
|
|
186998b888 | ||
|
|
df54fb9451 | ||
|
|
673f3f2939 | ||
|
|
3cd66589ca | ||
|
|
dbee2fdf9f | ||
|
|
0ffe3e8067 | ||
|
|
2dac679f1b | ||
|
|
faa2c0a005 | ||
|
|
a0a784b976 | ||
|
|
0d270ac871 | ||
|
|
8fc68c3888 | ||
|
|
8b41685b31 | ||
|
|
5bd31040c0 | ||
|
|
127a91ca9c | ||
|
|
7d2e24a528 | ||
|
|
ddf347994a | ||
|
|
0f7d29624b | ||
|
|
f627a8e9db | ||
|
|
6031fab3b4 | ||
|
|
e1d3f29383 | ||
|
|
f8f90cb903 | ||
|
|
65844a2f23 | ||
|
|
62755692e9 | ||
|
|
beba2ea099 | ||
|
|
88b2e7843f | ||
|
|
dbd5935ade | ||
|
|
bb2120c14d | ||
|
|
c9037f77e6 | ||
|
|
48631db989 | ||
|
|
ac7c2983d3 | ||
|
|
767dc529e8 | ||
|
|
448a25e2a4 | ||
|
|
3f35b8c886 | ||
|
|
d0f029b46e | ||
|
|
e0a81038cd | ||
|
|
4ab919360a | ||
|
|
adbcf80333 | ||
|
|
f91a26befe | ||
|
|
0c95b5ec91 | ||
|
|
193d4dc668 | ||
|
|
d0c9afc16e | ||
|
|
57d583e1bd | ||
|
|
8bbe7864af | ||
|
|
66b4e2c871 | ||
|
|
3ee69663dc | ||
|
|
539d49879d | ||
|
|
15356dfe49 | ||
|
|
1f04eeb040 | ||
|
|
e3028c21f2 | ||
|
|
9d8b343790 | ||
|
|
f4fe16608a | ||
|
|
d660a540da | ||
|
|
48ef2984e5 | ||
|
|
c5fc31c352 | ||
|
|
c3b9ea6ce4 |
@@ -16,6 +16,7 @@ module.exports = {
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
'@typescript-eslint/no-explicit-any': 'warn', // disable the rule for now to replicate previous behavior
|
||||
'@typescript-eslint/camelcase': 0,
|
||||
'@typescript-eslint/no-use-before-define': 0,
|
||||
'jsx-a11y/no-noninteractive-tabindex': 0,
|
||||
|
||||
11
.github/ISSUE_TEMPLATE/bug.yml
vendored
@@ -1,6 +1,7 @@
|
||||
name: 🐛 Bug Report
|
||||
description: Report a problem
|
||||
labels: ['bug', 'awaiting triage']
|
||||
labels: ['awaiting triage']
|
||||
type: bug
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
@@ -91,6 +92,14 @@ body:
|
||||
attributes:
|
||||
label: Additional Context
|
||||
description: Please provide any additional information that may be relevant or helpful.
|
||||
- type: checkboxes
|
||||
id: search-existing
|
||||
attributes:
|
||||
label: Search Existing Issues
|
||||
description: Have you searched existing issues to see if this bug has already been reported?
|
||||
options:
|
||||
- label: Yes, I have searched existing issues.
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: terms
|
||||
attributes:
|
||||
|
||||
63
.github/ISSUE_TEMPLATE/documentation.yml
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
name: 📚 Documentation
|
||||
description: Report a docs problem or suggest a docs improvement
|
||||
title: "[Docs]: "
|
||||
labels: ["documentation", "awaiting triage"]
|
||||
type: task
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for helping improve the docs!
|
||||
|
||||
Use this template for documentation issues (typos, unclear steps, missing info, outdated screenshots).
|
||||
For app bugs or feature ideas, please use the other templates.
|
||||
- type: input
|
||||
id: doc-location
|
||||
attributes:
|
||||
label: Page / Location
|
||||
description: Link to the docs page or the file/path (e.g. https://docs.seerr.dev/... or README.md)
|
||||
placeholder: "https://docs.seerr.dev/..."
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: doc-area
|
||||
attributes:
|
||||
label: Docs Area
|
||||
options:
|
||||
- docs site
|
||||
- migration guide
|
||||
- README / repo docs
|
||||
- API / integrations
|
||||
- other
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: problem
|
||||
attributes:
|
||||
label: What’s wrong / missing?
|
||||
description: Describe the issue in the docs.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: suggested-fix
|
||||
attributes:
|
||||
label: Suggested change
|
||||
description: If you know what should be changed, describe it (or paste proposed wording).
|
||||
validations:
|
||||
required: false
|
||||
- type: checkboxes
|
||||
id: search-existing
|
||||
attributes:
|
||||
label: Search Existing Issues
|
||||
description: Have you searched existing issues to see if this has already been reported?
|
||||
options:
|
||||
- label: Yes, I have searched existing issues.
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: terms
|
||||
attributes:
|
||||
label: Code of Conduct
|
||||
description: By submitting this issue, you agree to follow our Code of Conduct.
|
||||
options:
|
||||
- label: I agree to follow Seerr's [Code of Conduct](https://github.com/seerr-team/seerr/blob/develop/CODE_OF_CONDUCT.md).
|
||||
required: true
|
||||
11
.github/ISSUE_TEMPLATE/enhancement.yml
vendored
@@ -1,6 +1,7 @@
|
||||
name: ✨ Feature Request
|
||||
description: Suggest an idea
|
||||
labels: ['enhancement', 'awaiting triage']
|
||||
labels: ['awaiting triage']
|
||||
type: feature
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
@@ -27,6 +28,14 @@ body:
|
||||
attributes:
|
||||
label: Additional Context
|
||||
description: Provide any additional information or screenshots that may be relevant or helpful.
|
||||
- type: checkboxes
|
||||
id: search-existing
|
||||
attributes:
|
||||
label: Search Existing Issues
|
||||
description: Have you searched existing issues to see if this feature has already been requested?
|
||||
options:
|
||||
- label: Yes, I have searched existing issues.
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: terms
|
||||
attributes:
|
||||
|
||||
65
.github/ISSUE_TEMPLATE/maintenance.yml
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
name: 🧰 Maintenance / Chore
|
||||
description: CI, GitHub Actions, build, dependencies, refactors (non-feature work)
|
||||
title: "[Chore]: "
|
||||
labels: ["maintenance", "awaiting triage"]
|
||||
type: task
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Maintainers / contributors: use this for internal tasks (CI, workflows, tooling, refactors).
|
||||
If you're reporting a user-facing bug or requesting a feature, use the other templates.
|
||||
- type: dropdown
|
||||
id: area
|
||||
attributes:
|
||||
label: Area
|
||||
options:
|
||||
- CI / GitHub Actions
|
||||
- build / packaging
|
||||
- dependencies
|
||||
- release process
|
||||
- refactor / tech debt
|
||||
- tooling / scripts
|
||||
- other
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: summary
|
||||
attributes:
|
||||
label: Summary
|
||||
description: What needs doing and why?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: acceptance
|
||||
attributes:
|
||||
label: Acceptance criteria
|
||||
description: What does "done" look like?
|
||||
placeholder: |
|
||||
- [ ] ...
|
||||
- [ ] ...
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: related
|
||||
attributes:
|
||||
label: Related links
|
||||
description: PRs, failing workflow runs, logs, or relevant issues.
|
||||
validations:
|
||||
required: false
|
||||
- type: checkboxes
|
||||
id: search-existing
|
||||
attributes:
|
||||
label: Search Existing Issues
|
||||
description: Have you searched existing issues to see if this has already been reported?
|
||||
options:
|
||||
- label: Yes, I have searched existing issues.
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: terms
|
||||
attributes:
|
||||
label: Code of Conduct
|
||||
description: By submitting this issue, you agree to follow our Code of Conduct.
|
||||
options:
|
||||
- label: I agree to follow Seerr's [Code of Conduct](https://github.com/seerr-team/seerr/blob/develop/CODE_OF_CONDUCT.md).
|
||||
required: true
|
||||
33
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,14 +1,33 @@
|
||||
#### Description
|
||||
<!--
|
||||
Please read contributing guide before submitting
|
||||
your pull request. Please fill in each section below to help us better prioritize your pull request. Thanks!
|
||||
-->
|
||||
|
||||
#### Screenshot (if UI-related)
|
||||
## Description
|
||||
|
||||
#### To-Dos
|
||||
<!--- Describe your changes in detail -->
|
||||
<!--- Why is this change required? What problem does it solve? -->
|
||||
<!--- If it fixes an open issue, please link to the issue here. -->
|
||||
|
||||
- Fixes #XXXX
|
||||
|
||||
## How Has This Been Tested?
|
||||
|
||||
<!--- Please describe in detail how you tested your changes. -->
|
||||
<!--- Include details of your testing environment, and the tests you ran to -->
|
||||
<!--- see how your change affects other areas of the code, etc. -->
|
||||
|
||||
## Screenshots / Logs (if applicable)
|
||||
|
||||
## Checklist:
|
||||
|
||||
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
|
||||
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
|
||||
|
||||
- [ ] I have read and followed the contribution [guidelines](https://github.com/seerr-team/seerr/blob/develop/CONTRIBUTING.md).
|
||||
- [ ] Disclosed any use of AI (see our [policy](https://github.com/seerr-team/seerr/blob/develop/CONTRIBUTING.md#ai-assistance-notice))
|
||||
- [ ] I have updated the documentation accordingly.
|
||||
- [ ] All new and existing tests passed.
|
||||
- [ ] Successful build `pnpm build`
|
||||
- [ ] Translation keys `pnpm i18n:extract`
|
||||
- [ ] Database migration (if required)
|
||||
|
||||
#### Issues Fixed or Closed
|
||||
|
||||
- Fixes #XXXX
|
||||
|
||||
4
.github/cliff.toml
vendored
@@ -33,9 +33,9 @@ body = """
|
||||
{{ self::print_commit(commit=commit) }}
|
||||
{%- endfor %}
|
||||
{%- for commit in commits %}
|
||||
{%- if not commit.scope -%}
|
||||
{%- if not commit.scope %}
|
||||
{{ self::print_commit(commit=commit) }}
|
||||
{%- endif -%}
|
||||
{%- endif %}
|
||||
{%- endfor -%}
|
||||
{%- endfor -%}
|
||||
|
||||
|
||||
2
.github/renovate/helm.json5
vendored
@@ -16,7 +16,7 @@
|
||||
description: 'Update appVersion in Chart.yaml to match Docker image',
|
||||
fileMatch: ['(^|/)Chart\\.yaml$'],
|
||||
matchStrings: [
|
||||
'#\\s+renovate:\\s+image=(?<depName>\\S*)\nappVersion:\\s+"(?<currentValue>\\S*)"',
|
||||
"#\\s+renovate:\\s+image=(?<depName>\\S*)\nappVersion:\\s+'(?<currentValue>\\S*)'",
|
||||
],
|
||||
datasourceTemplate: 'docker',
|
||||
},
|
||||
|
||||
80
.github/workflows/ci.yml
vendored
@@ -18,18 +18,82 @@ env:
|
||||
DOCKER_HUB: seerr/seerr
|
||||
|
||||
concurrency:
|
||||
group: ci-${{ github.ref }}
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
i18n:
|
||||
name: i18n Check
|
||||
if: github.event_name == 'pull_request'
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GH_REPO: ${{ github.repository }}
|
||||
NUMBER: ${{ github.event.pull_request.number }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Pnpm Setup
|
||||
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
with:
|
||||
node-version-file: 'package.json'
|
||||
|
||||
- name: Get pnpm store directory
|
||||
shell: bash
|
||||
run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
|
||||
|
||||
- name: Setup pnpm cache
|
||||
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
||||
with:
|
||||
path: ${{ env.STORE_PATH }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
|
||||
- name: Install dependencies
|
||||
env:
|
||||
CI: true
|
||||
run: pnpm install
|
||||
|
||||
- name: i18n Check
|
||||
shell: bash
|
||||
env:
|
||||
I18N_LABEL: i18n-out-of-sync
|
||||
BODY: |
|
||||
The i18n check failed because translation messages are out of sync.
|
||||
|
||||
This usually happens when you've added or modified translation strings in your code but haven't updated the translation file.
|
||||
|
||||
Please run `pnpm i18n:extract` and commit the changes.
|
||||
run: |
|
||||
retry() { n=0; until "$@"; do n=$((n+1)); [ $n -ge 3 ] && break; echo "retry $n: $*" >&2; sleep 2; done; }
|
||||
check_failed=0; node bin/check-i18n.js || check_failed=$?
|
||||
pr_labels=$(gh pr view "$NUMBER" -R "$GH_REPO" --json labels -q '.labels[].name' 2>/dev/null) || true
|
||||
has_label=0
|
||||
while IFS= read -r name; do [ -n "$name" ] && [ "$name" = "$I18N_LABEL" ] && has_label=1 && break; done <<< "$pr_labels"
|
||||
if [ "$check_failed" -eq 1 ]; then
|
||||
[ "$has_label" -eq 0 ] && { retry gh pr edit "$NUMBER" -R "$GH_REPO" --add-label "$I18N_LABEL" || true; retry gh pr comment "$NUMBER" -R "$GH_REPO" -b "$BODY" || true; }
|
||||
else
|
||||
[ "$has_label" -eq 1 ] && retry gh pr edit "$NUMBER" -R "$GH_REPO" --remove-label "$I18N_LABEL" || true
|
||||
fi
|
||||
exit $check_failed
|
||||
test:
|
||||
name: Lint & Test Build
|
||||
if: github.event_name == 'pull_request'
|
||||
runs-on: ubuntu-24.04
|
||||
container: node:22.20.0-alpine3.22@sha256:dbcedd8aeab47fbc0f4dd4bffa55b7c3c729a707875968d467aaaea42d6225af
|
||||
container: node:22.22.0-alpine3.22@sha256:0c49915657c1c77c64c8af4d91d2f13fe96853bbd957993ed00dd592cbecc284
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -78,7 +142,7 @@ jobs:
|
||||
runs-on: ${{ matrix.runner }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -87,7 +151,7 @@ jobs:
|
||||
run: echo "TIMESTAMP=$(git log -1 --pretty=%ct)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
|
||||
|
||||
- name: Warm cache (no push) — ${{ matrix.platform }}
|
||||
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
|
||||
@@ -114,7 +178,7 @@ jobs:
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -123,7 +187,7 @@ jobs:
|
||||
run: echo "TIMESTAMP=$(git log -1 --pretty=%ct)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
|
||||
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
@@ -140,7 +204,7 @@ jobs:
|
||||
|
||||
- name: Extract metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
|
||||
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0
|
||||
with:
|
||||
images: |
|
||||
${{ env.DOCKER_HUB }}
|
||||
|
||||
10
.github/workflows/codeql.yml
vendored
@@ -20,7 +20,7 @@ permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: codeql-${{ github.ref }}
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
@@ -37,20 +37,20 @@ jobs:
|
||||
language: [actions, javascript]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@e296a935590eb16afc0c0108289f68c87e2a89a5 # v4.30.7
|
||||
uses: github/codeql-action/init@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
queries: +security-and-quality
|
||||
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@e296a935590eb16afc0c0108289f68c87e2a89a5 # v4.30.7
|
||||
uses: github/codeql-action/autobuild@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@e296a935590eb16afc0c0108289f68c87e2a89a5 # v4.30.7
|
||||
uses: github/codeql-action/analyze@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10
|
||||
with:
|
||||
category: '/language:${{ matrix.language }}'
|
||||
|
||||
2
.github/workflows/conflict_labeler.yml
vendored
@@ -14,7 +14,7 @@ permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: merge-conflict-${{ github.ref }}
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
|
||||
6
.github/workflows/cypress.yml
vendored
@@ -28,7 +28,7 @@ permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: cypress-${{ github.ref }}
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
@@ -37,7 +37,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -67,7 +67,7 @@ jobs:
|
||||
run: pnpm exec cypress install
|
||||
|
||||
- name: Cypress run
|
||||
uses: cypress-io/github-action@b8ba51a856ba5f4c15cf39007636d4ab04f23e3c # v6.10.2
|
||||
uses: cypress-io/github-action@f790eee7a50d9505912f50c2095510be7de06aa7 # v6.10.9
|
||||
with:
|
||||
install: false
|
||||
build: pnpm cypress:build
|
||||
|
||||
83
.github/workflows/detect-duplicate.yml
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
|
||||
name: Duplicate Issue Detector
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
|
||||
permissions: {}
|
||||
|
||||
env:
|
||||
EMBEDDING_MODEL: ${{ vars.EMBEDDING_MODEL }}
|
||||
GROQ_MODEL: ${{ vars.GROQ_MODEL }}
|
||||
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
|
||||
|
||||
jobs:
|
||||
detect-duplicate:
|
||||
runs-on: ubuntu-24.04
|
||||
if: ${{ !github.event.issue.pull_request }}
|
||||
permissions:
|
||||
issues: write
|
||||
actions: read
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
|
||||
- name: Pnpm Setup
|
||||
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
with:
|
||||
node-version-file: 'package.json'
|
||||
|
||||
- name: Get pnpm store directory
|
||||
shell: bash
|
||||
run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
|
||||
|
||||
- name: Setup pnpm cache
|
||||
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
||||
with:
|
||||
path: ${{ env.STORE_PATH }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
|
||||
- name: Install dependencies
|
||||
working-directory: bin/duplicate-detector
|
||||
env:
|
||||
CI: true
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Download issue index
|
||||
uses: dawidd6/action-download-artifact@5c98f0b039f36ef966fdb7dfa9779262785ecb05 # v14
|
||||
with:
|
||||
name: issue-index
|
||||
workflow: rebuild-issue-index.yml
|
||||
path: bin/duplicate-detector
|
||||
search_artifacts: true
|
||||
if_no_artifact_found: warn
|
||||
|
||||
- name: Build index if missing
|
||||
working-directory: bin/duplicate-detector
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITHUB_REPOSITORY: ${{ github.repository }}
|
||||
INDEX_PATH: issue_index.json
|
||||
run: |
|
||||
if [ ! -f issue_index.json ]; then
|
||||
echo "No index found — building from scratch..."
|
||||
node build-index.mjs
|
||||
fi
|
||||
|
||||
- name: Detect duplicates
|
||||
working-directory: bin/duplicate-detector
|
||||
continue-on-error: true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITHUB_REPOSITORY: ${{ github.repository }}
|
||||
ISSUE_NUMBER: ${{ github.event.issue.number }}
|
||||
INDEX_PATH: issue_index.json
|
||||
run: node detect.mjs
|
||||
6
.github/workflows/docs-deploy.yml
vendored
@@ -6,7 +6,7 @@ on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- legacy-jellyseerr
|
||||
- develop
|
||||
paths:
|
||||
- 'docs/**'
|
||||
- 'gen-docs/**'
|
||||
@@ -15,7 +15,7 @@ permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: pages
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
@@ -23,7 +23,7 @@ jobs:
|
||||
name: Build Docusaurus
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
6
.github/workflows/docs-link-check.yml
vendored
@@ -25,7 +25,7 @@ permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: docs-link-check-${{ github.ref }}
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
@@ -36,13 +36,13 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Run Lychee link checker
|
||||
uses: lycheeverse/lychee-action@885c65f3dc543b57c898c8099f4e08c8afd178a2 # v2.6.1
|
||||
uses: lycheeverse/lychee-action@a8c4c7cb88f0c7386610c35eb25108e448569cb0 # v2.7.0
|
||||
with:
|
||||
fail: false
|
||||
args: >-
|
||||
|
||||
8
.github/workflows/helm.yml
vendored
@@ -14,7 +14,7 @@ permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: helm-charts
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
has_artifacts: ${{ steps.check-artifacts.outputs.has_artifacts }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
@@ -93,7 +93,7 @@ jobs:
|
||||
if: needs.package-helm-chart.outputs.has_artifacts == 'true'
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
@@ -151,7 +151,7 @@ jobs:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
6
.github/workflows/lint-helm-charts.yml
vendored
@@ -18,7 +18,7 @@ permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: charts-lint-${{ github.ref }}
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
@@ -37,7 +37,7 @@ jobs:
|
||||
uses: azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4 # v4.3.1
|
||||
|
||||
- name: Set up chart-testing
|
||||
uses: helm/chart-testing-action@0d28d3144d3a25ea2cc349d6e59901c4ff469b3b # v2.7.0
|
||||
uses: helm/chart-testing-action@6ec842c01de15ebb84c8627d2744a0c2f2755c9f # v2.8.0
|
||||
|
||||
- name: Ensure documentation is updated
|
||||
uses: docker://jnorwood/helm-docs:v1.14.2@sha256:7e562b49ab6b1dbc50c3da8f2dd6ffa8a5c6bba327b1c6335cc15ce29267979c
|
||||
|
||||
12
.github/workflows/preview.yml
vendored
@@ -15,7 +15,7 @@ env:
|
||||
DOCKER_HUB: seerr/seerr
|
||||
|
||||
concurrency:
|
||||
group: preview-${{ github.ref }}
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
@@ -33,7 +33,7 @@ jobs:
|
||||
runs-on: ${{ matrix.runner }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -42,7 +42,7 @@ jobs:
|
||||
run: echo "TIMESTAMP=$(git log -1 --pretty=%ct)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
|
||||
|
||||
- name: Derive preview version from tag
|
||||
id: ver
|
||||
@@ -79,7 +79,7 @@ jobs:
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -88,7 +88,7 @@ jobs:
|
||||
run: echo "TIMESTAMP=$(git log -1 --pretty=%ct)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
|
||||
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
@@ -115,7 +115,7 @@ jobs:
|
||||
|
||||
- name: Extract metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
|
||||
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0
|
||||
with:
|
||||
images: |
|
||||
${{ env.DOCKER_HUB }}
|
||||
|
||||
65
.github/workflows/rebuild-issue-index.yml
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
|
||||
name: Rebuild Issue Index
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 3 * * *"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions: {}
|
||||
|
||||
env:
|
||||
EMBEDDING_MODEL: ${{ vars.EMBEDDING_MODEL }}
|
||||
|
||||
jobs:
|
||||
build-index:
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
issues: read
|
||||
actions: write
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
|
||||
- name: Pnpm Setup
|
||||
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
with:
|
||||
node-version-file: 'package.json'
|
||||
|
||||
- name: Get pnpm store directory
|
||||
shell: bash
|
||||
run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
|
||||
|
||||
- name: Setup pnpm cache
|
||||
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
||||
with:
|
||||
path: ${{ env.STORE_PATH }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
|
||||
- name: Install dependencies
|
||||
working-directory: bin/duplicate-detector
|
||||
env:
|
||||
CI: true
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build issue index
|
||||
working-directory: bin/duplicate-detector
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITHUB_REPOSITORY: ${{ github.repository }}
|
||||
INDEX_PATH: issue_index.json
|
||||
run: node build-index.mjs
|
||||
|
||||
- name: Upload index artifact
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
with:
|
||||
name: issue-index
|
||||
path: bin/duplicate-detector/issue_index.json
|
||||
retention-days: 7
|
||||
42
.github/workflows/release.yml
vendored
@@ -11,7 +11,7 @@ permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: release-${{ github.ref }}
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
@@ -27,14 +27,14 @@ jobs:
|
||||
release_body: ${{ steps.git-cliff.outputs.content }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Generate changelog
|
||||
id: git-cliff
|
||||
uses: orhun/git-cliff-action@d77b37db2e3f7398432d34b72a12aa3e2ba87e51 # v4.6.0
|
||||
uses: orhun/git-cliff-action@e16f179f0be49ecdfe63753837f20b9531642772 # v4.7.0
|
||||
with:
|
||||
config: .github/cliff.toml
|
||||
args: -vv --current
|
||||
@@ -50,7 +50,7 @@ jobs:
|
||||
needs: changelog
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -76,7 +76,7 @@ jobs:
|
||||
VERSION: ${{ github.ref_name }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -85,7 +85,7 @@ jobs:
|
||||
run: echo "TIMESTAMP=$(git log -1 --pretty=%ct)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
|
||||
|
||||
- name: Warm cache [${{ matrix.platform }}]
|
||||
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
|
||||
@@ -115,7 +115,7 @@ jobs:
|
||||
VERSION: ${{ github.ref_name }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -124,7 +124,7 @@ jobs:
|
||||
run: echo "TIMESTAMP=$(git log -1 --pretty=%ct)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
|
||||
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
@@ -141,7 +141,7 @@ jobs:
|
||||
|
||||
- name: Extract metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
|
||||
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0
|
||||
with:
|
||||
images: |
|
||||
${{ env.DOCKER_HUB }}
|
||||
@@ -201,7 +201,7 @@ jobs:
|
||||
COSIGN_YES: 'true'
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -209,7 +209,7 @@ jobs:
|
||||
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
|
||||
|
||||
- name: Install Trivy
|
||||
uses: aquasecurity/setup-trivy@e6c2c5e321ed9123bda567646e2f96565e34abe1 # v0.2.4
|
||||
uses: aquasecurity/setup-trivy@3fb12ec12f41e471780db15c232d5dd185dcb514 # v0.2.5
|
||||
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
@@ -279,17 +279,17 @@ jobs:
|
||||
--certificate-identity "https://github.com/${{ github.workflow_ref }}" \
|
||||
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
|
||||
|
||||
- name: Verify attestations
|
||||
run: |
|
||||
cosign verify-attestation "ghcr.io/${{ github.repository }}@${{ needs.publish.outputs.image_digest }}" \
|
||||
--type cyclonedx \
|
||||
--certificate-identity "https://github.com/${{ github.workflow_ref }}" \
|
||||
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" > /dev/null
|
||||
# - name: Verify attestations
|
||||
# run: |
|
||||
# cosign verify-attestation "ghcr.io/${{ github.repository }}@${{ needs.publish.outputs.image_digest }}" \
|
||||
# --type cyclonedx \
|
||||
# --certificate-identity "https://github.com/${{ github.workflow_ref }}" \
|
||||
# --certificate-oidc-issuer "https://token.actions.githubusercontent.com" > /dev/null
|
||||
|
||||
cosign verify-attestation "${{ env.DOCKER_HUB }}@${{ needs.publish.outputs.image_digest }}" \
|
||||
--type cyclonedx \
|
||||
--certificate-identity "https://github.com/${{ github.workflow_ref }}" \
|
||||
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" > /dev/null
|
||||
# cosign verify-attestation "${{ env.DOCKER_HUB }}@${{ needs.publish.outputs.image_digest }}" \
|
||||
# --type cyclonedx \
|
||||
# --certificate-identity "https://github.com/${{ github.workflow_ref }}" \
|
||||
# --certificate-oidc-issuer "https://token.actions.githubusercontent.com" > /dev/null
|
||||
|
||||
publish-release:
|
||||
name: Publish release
|
||||
|
||||
@@ -12,7 +12,7 @@ on:
|
||||
permissions: {}
|
||||
|
||||
concurrency:
|
||||
group: renovate-helm-hooks-${{ github.ref }}
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
@@ -25,19 +25,19 @@ jobs:
|
||||
if: github.actor == 'renovate[bot]'
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4
|
||||
- uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
|
||||
id: app-token
|
||||
with:
|
||||
app-id: 2138788
|
||||
private-key: ${{ secrets.APP_SEERR_HELM_PRIVATE_KEY }}
|
||||
|
||||
- name: Set up chart-testing
|
||||
uses: helm/chart-testing-action@0d28d3144d3a25ea2cc349d6e59901c4ff469b3b # v2.7.0
|
||||
uses: helm/chart-testing-action@6ec842c01de15ebb84c8627d2744a0c2f2755c9f # v2.8.0
|
||||
|
||||
- name: Run chart-testing (list-changed)
|
||||
id: list-changed
|
||||
|
||||
28
.github/workflows/semantic-pr.yml
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
name: "Semantic PR"
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- opened
|
||||
- reopened
|
||||
- edited
|
||||
- synchronize
|
||||
|
||||
permissions: {}
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
main:
|
||||
name: Validate PR Title
|
||||
runs-on: ubuntu-slim
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
checks: write
|
||||
steps:
|
||||
- uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 # v6.1.1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
4
.github/workflows/stale.yml
vendored
@@ -9,7 +9,7 @@ on:
|
||||
permissions: {}
|
||||
|
||||
concurrency:
|
||||
group: close-stale-${{ github.ref }}
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/stale@5f858e3efba33a5ca4407a664cc011ad407f2008 # v10.1.0
|
||||
- uses: actions/stale@997185467fa4f803885201cee163a9f38240193d # v10.1.1
|
||||
with:
|
||||
any-of-labels: "pending author's response"
|
||||
exempt-issue-labels: 'confirmed'
|
||||
|
||||
4
.github/workflows/test-docs-deploy.yml
vendored
@@ -14,7 +14,7 @@ permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: docs-pr-${{ github.ref }}
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
6
.github/workflows/trivy-scan.yml
vendored
@@ -16,7 +16,7 @@ permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: trivy-scan-${{ github.ref }}
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
@@ -34,7 +34,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
@@ -56,6 +56,6 @@ jobs:
|
||||
ignore-unfixed: true
|
||||
|
||||
- name: Upload SARIF to code scanning
|
||||
uses: github/codeql-action/upload-sarif@e296a935590eb16afc0c0108289f68c87e2a89a5 # v4.30.7
|
||||
uses: github/codeql-action/upload-sarif@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10
|
||||
with:
|
||||
sarif_file: trivy.sarif
|
||||
|
||||
@@ -4,15 +4,17 @@ dist/
|
||||
config/
|
||||
pnpm-lock.yaml
|
||||
cypress/config/settings.cypress.json
|
||||
.github
|
||||
.vscode
|
||||
|
||||
# assets
|
||||
src/assets/
|
||||
public/
|
||||
!public/sw.js
|
||||
docs/
|
||||
!/public/
|
||||
/public/*
|
||||
!/public/sw.js
|
||||
public/*
|
||||
!public/sw.js
|
||||
|
||||
# helm charts
|
||||
**/charts
|
||||
|
||||
# Prettier breaks GitHub alert syntax in markdown
|
||||
*.md
|
||||
@@ -1,5 +1,5 @@
|
||||
module.exports = {
|
||||
plugins: [require('./merged-prettier-plugin.js')],
|
||||
plugins: ['prettier-plugin-organize-imports', 'prettier-plugin-tailwindcss'],
|
||||
singleQuote: true,
|
||||
trailingComma: 'es5',
|
||||
overrides: [
|
||||
@@ -27,5 +27,11 @@ module.exports = {
|
||||
rangeEnd: 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
files: 'public/offline.html',
|
||||
options: {
|
||||
rangeEnd: 0,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -122,7 +122,7 @@ Steps:
|
||||
|
||||
- If you are taking on an existing bug or feature ticket, please comment on the [issue](/../../issues) to avoid multiple people working on the same thing.
|
||||
- All commits **must** follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)
|
||||
- Pull requests with commits not following this standard will **not** be merged.
|
||||
- Pull requests with titles or commits not following this standard will **not** be merged. PR titles are automatically checked for compliance.
|
||||
- Please make meaningful commits, or squash them prior to opening a pull request.
|
||||
- Do not squash commits once people have begun reviewing your changes.
|
||||
- Always rebase your commit to the latest `develop` branch. Do **not** merge `develop` into your branch.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:22.20.0-alpine3.22@sha256:cb3143549582cc5f74f26f0992cdef4a422b22128cb517f94173a5f910fa4ee7 AS base
|
||||
FROM node:22.22.0-alpine3.22@sha256:0c49915657c1c77c64c8af4d91d2f13fe96853bbd957993ed00dd592cbecc284 AS base
|
||||
ARG SOURCE_DATE_EPOCH
|
||||
ARG TARGETPLATFORM
|
||||
ENV TARGETPLATFORM=${TARGETPLATFORM:-linux/amd64}
|
||||
@@ -33,7 +33,7 @@ RUN pnpm build
|
||||
|
||||
RUN rm -rf .next/cache
|
||||
|
||||
FROM node:22.20.0-alpine3.22@sha256:cb3143549582cc5f74f26f0992cdef4a422b22128cb517f94173a5f910fa4ee7
|
||||
FROM node:22.22.0-alpine3.22@sha256:0c49915657c1c77c64c8af4d91d2f13fe96853bbd957993ed00dd592cbecc284
|
||||
ARG SOURCE_DATE_EPOCH
|
||||
ARG COMMIT_TAG
|
||||
ENV NODE_ENV=production
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:22.20.0-alpine3.22@sha256:cb3143549582cc5f74f26f0992cdef4a422b22128cb517f94173a5f910fa4ee7
|
||||
FROM node:22.22.0-alpine3.22@sha256:0c49915657c1c77c64c8af4d91d2f13fe96853bbd957993ed00dd592cbecc284
|
||||
|
||||
ENV PNPM_HOME="/pnpm"
|
||||
ENV PATH="$PNPM_HOME:$PATH"
|
||||
|
||||
18
README.md
@@ -1,6 +1,6 @@
|
||||
<div align="center">⚠️ <strong>NOTE:</strong> We are currently in the process of merging Overseerr and Jellyseerr into this unified repository.</div>
|
||||
|
||||
<h1 align="center" style="font-size: 4em;">🚧 Seerr</h1>
|
||||
<p align="center">
|
||||
<img src="./public/logo_full.svg" alt="Seerr" style="margin: 20px 0;">
|
||||
</p>
|
||||
<p align="center">
|
||||
<img src="https://github.com/seerr-team/seerr/actions/workflows/release.yml/badge.svg" alt="Seerr Release" />
|
||||
<img src="https://github.com/seerr-team/seerr/actions/workflows/ci.yml/badge.svg" alt="Seerr CI">
|
||||
@@ -8,7 +8,7 @@
|
||||
<p align="center">
|
||||
<a href="https://discord.gg/seerr"><img src="https://img.shields.io/discord/783137440809746482" alt="Discord"></a>
|
||||
<a href="https://hub.docker.com/r/seerr/seerr"><img src="https://img.shields.io/docker/pulls/seerr/seerr" alt="Docker pulls"></a>
|
||||
<a href="https://translate.seerr.dev/engage/seerr/"><img src="https://translate.seerr.dev/widget/seerr/seerr-frontend/svg-badge.svg" alt="Translation status" /></a>
|
||||
<a href="https://translate.seerr.dev/engage/seerr/"><img src="https://translate.seerr.dev/widget/seerr/svg-badge.svg" alt="Translation status" /></a>
|
||||
<a href="https://github.com/seerr-team/seerr/blob/develop/LICENSE"><img alt="GitHub" src="https://img.shields.io/github/license/seerr-team/seerr"></a>
|
||||
|
||||
**Seerr** is a free and open source software application for managing requests for your media library. It integrates with the media server of your choice: [Jellyfin](https://jellyfin.org), [Plex](https://plex.tv), and [Emby](https://emby.media/). In addition, it integrates with your existing services, such as **[Sonarr](https://sonarr.tv/)**, **[Radarr](https://radarr.video/)**.
|
||||
@@ -26,7 +26,7 @@
|
||||
- Granular permission system.
|
||||
- Support for various notification agents.
|
||||
- Mobile-friendly design, for when you need to approve requests on the go!
|
||||
- Support for watchlisting & blacklisting media.
|
||||
- Support for watchlisting & blocklisting media.
|
||||
|
||||
With more features on the way! Check out our [issue tracker](/../../issues) to see the features which have already been requested.
|
||||
|
||||
@@ -38,7 +38,13 @@ https://docs.seerr.dev/getting-started/
|
||||
|
||||
## Preview
|
||||
|
||||
<img src="./public/preview.jpg">
|
||||
<img src="./public/preview.jpg" alt="Seerr application preview" />
|
||||
|
||||
## Migrating from Overseerr/Jellyseerr to Seerr
|
||||
|
||||
Read our [release announcement](https://docs.seerr.dev/blog/seerr-release) to learn what Seerr means for Jellyseerr and Overseerr users.
|
||||
|
||||
Please follow our [migration guide](https://docs.seerr.dev/migration-guide) for detailed instructions on migrating from Overseerr or Jellyseerr.
|
||||
|
||||
## Support
|
||||
|
||||
|
||||
39
bin/check-i18n.js
Normal file
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Check that i18n locale files are in sync with extracted messages.
|
||||
* Runs `pnpm i18n:extract` and compares en.json; exits 1 if they differ.
|
||||
*/
|
||||
const { execSync } = require('child_process');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const localePath = path.join(
|
||||
__dirname,
|
||||
'..',
|
||||
'src',
|
||||
'i18n',
|
||||
'locale',
|
||||
'en.json'
|
||||
);
|
||||
const backupPath = `${localePath}.bak`;
|
||||
|
||||
try {
|
||||
fs.copyFileSync(localePath, backupPath);
|
||||
execSync('pnpm i18n:extract', { stdio: 'inherit' });
|
||||
const original = fs.readFileSync(backupPath, 'utf8');
|
||||
const extracted = fs.readFileSync(localePath, 'utf8');
|
||||
fs.unlinkSync(backupPath);
|
||||
|
||||
if (original !== extracted) {
|
||||
console.error(
|
||||
"i18n messages are out of sync. Please run 'pnpm i18n:extract' and commit the changes."
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
} catch (err) {
|
||||
if (fs.existsSync(backupPath)) {
|
||||
fs.unlinkSync(backupPath);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
1
bin/duplicate-detector/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
node_modules/
|
||||
120
bin/duplicate-detector/build-index.mjs
Normal file
@@ -0,0 +1,120 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Build Issue Embedding Index
|
||||
*
|
||||
* Fetches all open issues and recently closed ones,
|
||||
* generates embeddings using a local ONNX transformer model,
|
||||
* and saves them as a JSON artifact for the duplicate detector.
|
||||
*/
|
||||
|
||||
import { pipeline } from '@huggingface/transformers';
|
||||
import { mkdirSync, writeFileSync } from 'node:fs';
|
||||
import { dirname } from 'node:path';
|
||||
import { fetchIssues, issueText } from './utils.mjs';
|
||||
|
||||
const MODEL_NAME = process.env.EMBEDDING_MODEL || 'Xenova/all-MiniLM-L6-v2';
|
||||
const OUTPUT_PATH = 'issue_index.json';
|
||||
const INCLUDE_CLOSED_DAYS = 90;
|
||||
const MAX_ISSUES = 5000;
|
||||
const BATCH_SIZE = 64;
|
||||
|
||||
async function main() {
|
||||
console.log('Fetching open issues...');
|
||||
const openIssues = await fetchIssues({
|
||||
state: 'open',
|
||||
maxIssues: MAX_ISSUES,
|
||||
});
|
||||
console.log(`Fetched ${openIssues.length} open issues`);
|
||||
|
||||
const since = new Date(
|
||||
Date.now() - INCLUDE_CLOSED_DAYS * 24 * 60 * 60 * 1000
|
||||
).toISOString();
|
||||
console.log(
|
||||
`Fetching closed issues from last ${INCLUDE_CLOSED_DAYS} days...`
|
||||
);
|
||||
|
||||
const closedIssues = await fetchIssues({
|
||||
state: 'closed',
|
||||
since,
|
||||
maxIssues: MAX_ISSUES,
|
||||
});
|
||||
console.log(`Fetched ${closedIssues.length} closed issues`);
|
||||
let allIssues = [...openIssues, ...closedIssues];
|
||||
|
||||
const seen = new Set();
|
||||
allIssues = allIssues.filter((issue) => {
|
||||
if (seen.has(issue.number)) return false;
|
||||
seen.add(issue.number);
|
||||
return true;
|
||||
});
|
||||
|
||||
console.log(`Total unique issues to index: ${allIssues.length}`);
|
||||
|
||||
if (allIssues.length === 0) {
|
||||
console.warn('No issues found - writing empty index');
|
||||
writeFileSync(OUTPUT_PATH, JSON.stringify({ issues: [], embeddings: [] }));
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`Loading model: ${MODEL_NAME}`);
|
||||
const extractor = await pipeline('feature-extraction', MODEL_NAME, {
|
||||
dtype: 'fp32',
|
||||
});
|
||||
|
||||
const texts = allIssues.map((issue) => issueText(issue.title, issue.body));
|
||||
const allEmbeddings = [];
|
||||
|
||||
console.log(`Generating embeddings for ${texts.length} issues...`);
|
||||
for (let i = 0; i < texts.length; i += BATCH_SIZE) {
|
||||
const batch = texts.slice(i, i + BATCH_SIZE);
|
||||
const output = await extractor(batch, {
|
||||
pooling: 'mean',
|
||||
normalize: true,
|
||||
});
|
||||
|
||||
const vectors = output.tolist();
|
||||
allEmbeddings.push(...vectors);
|
||||
|
||||
const progress = Math.min(i + BATCH_SIZE, texts.length);
|
||||
console.log(` ${progress}/${texts.length}`);
|
||||
}
|
||||
|
||||
const issueMetadata = allIssues.map((issue) => {
|
||||
const body = (issue.body || '').trim();
|
||||
return {
|
||||
number: issue.number,
|
||||
title: issue.title,
|
||||
state: issue.state,
|
||||
url: issue.html_url,
|
||||
body_preview: body.slice(0, 500) || '',
|
||||
labels: (issue.labels || []).map((l) => l.name),
|
||||
created_at: issue.created_at,
|
||||
updated_at: issue.updated_at,
|
||||
};
|
||||
});
|
||||
|
||||
const indexData = {
|
||||
issues: issueMetadata,
|
||||
embeddings: allEmbeddings,
|
||||
model: MODEL_NAME,
|
||||
issue_count: issueMetadata.length,
|
||||
built_at: new Date().toISOString(),
|
||||
};
|
||||
|
||||
const dir = dirname(OUTPUT_PATH);
|
||||
if (dir && dir !== '.') mkdirSync(dir, { recursive: true });
|
||||
writeFileSync(OUTPUT_PATH, JSON.stringify(indexData));
|
||||
|
||||
const sizeMb = (
|
||||
Buffer.byteLength(JSON.stringify(indexData)) /
|
||||
(1024 * 1024)
|
||||
).toFixed(1);
|
||||
console.log(
|
||||
`Index saved to ${OUTPUT_PATH} (${sizeMb} MB, ${issueMetadata.length} issues)`
|
||||
);
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
274
bin/duplicate-detector/detect.mjs
Normal file
@@ -0,0 +1,274 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Duplicate Issue Detector
|
||||
*
|
||||
* Triggered on new issue creation. Compares the new issue against an
|
||||
* existing embedding index, then uses an LLM to
|
||||
* confirm duplicates before posting a comment for maintainer review.
|
||||
*/
|
||||
|
||||
import { pipeline } from '@huggingface/transformers';
|
||||
import { existsSync, readFileSync } from 'node:fs';
|
||||
import {
|
||||
addLabel,
|
||||
dotProduct,
|
||||
fetchIssues,
|
||||
getIssue,
|
||||
issueText,
|
||||
postComment,
|
||||
} from './utils.mjs';
|
||||
|
||||
const SIMILARITY_THRESHOLD = 0.55;
|
||||
const TOP_K = 5;
|
||||
const MAX_COMMENT_CANDIDATES = 3;
|
||||
const MODEL_NAME = process.env.EMBEDDING_MODEL || 'Xenova/all-MiniLM-L6-v2';
|
||||
const GROQ_MODEL = process.env.GROQ_MODEL || 'llama-3.3-70b-versatile';
|
||||
const INDEX_PATH = 'issue_index.json';
|
||||
const LABEL_NAME = 'possible-duplicate';
|
||||
|
||||
const GROQ_API_KEY = process.env.GROQ_API_KEY || '';
|
||||
const ISSUE_NUMBER = parseInt(process.env.ISSUE_NUMBER, 10);
|
||||
|
||||
function loadIndex(path) {
|
||||
if (!existsSync(path)) {
|
||||
console.error(
|
||||
`Index file not found at ${path}. Run build-index.mjs first.`
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const data = JSON.parse(readFileSync(path, 'utf-8'));
|
||||
console.log(`Loaded index with ${data.issues.length} issues`);
|
||||
return data;
|
||||
}
|
||||
|
||||
function findSimilar(
|
||||
queryEmbedding,
|
||||
index,
|
||||
{ topK = TOP_K, threshold = SIMILARITY_THRESHOLD, excludeNumber } = {}
|
||||
) {
|
||||
const { issues, embeddings } = index;
|
||||
if (!issues.length) return [];
|
||||
|
||||
const scored = issues.map((issue, i) => ({
|
||||
...issue,
|
||||
score: dotProduct(queryEmbedding, embeddings[i]),
|
||||
}));
|
||||
|
||||
return scored
|
||||
.sort((a, b) => b.score - a.score)
|
||||
.filter(
|
||||
(c) =>
|
||||
c.score >= threshold && (!excludeNumber || c.number !== excludeNumber)
|
||||
)
|
||||
.slice(0, topK);
|
||||
}
|
||||
|
||||
const CONFIRM_SYSTEM_PROMPT = `You are a GitHub issue triage assistant. You will be given a NEW issue and one \
|
||||
or more CANDIDATE issues that may be duplicates.
|
||||
|
||||
For each candidate, determine if the new issue is truly a duplicate (same root \
|
||||
problem/request) or merely related (similar area but different issue).
|
||||
|
||||
Respond ONLY with a JSON array of objects, each with:
|
||||
- "number": the candidate issue number
|
||||
- "duplicate": true or false
|
||||
- "reason": one-sentence explanation
|
||||
|
||||
Example:
|
||||
[{"number": 123, "duplicate": true, "reason": "Both report the same crash when ..."}]`;
|
||||
|
||||
async function confirmWithLlm(newIssue, candidates) {
|
||||
if (!GROQ_API_KEY) {
|
||||
console.warn('GROQ_API_KEY not set — skipping LLM confirmation');
|
||||
return candidates;
|
||||
}
|
||||
|
||||
const candidateText = candidates
|
||||
.map(
|
||||
(c) =>
|
||||
`### Candidate #${c.number} (similarity: ${c.score.toFixed(2)})\n` +
|
||||
`**Title:** ${c.title}\n` +
|
||||
`**State:** ${c.state}\n` +
|
||||
`**Body preview:** ${(c.body_preview || 'N/A').slice(0, 500)}`
|
||||
)
|
||||
.join('\n\n');
|
||||
|
||||
const userPrompt =
|
||||
`## NEW ISSUE #${newIssue.number}\n` +
|
||||
`**Title:** ${newIssue.title}\n` +
|
||||
`**Body:**\n${(newIssue.body || 'No body').slice(0, 1500)}\n\n` +
|
||||
`---\n\n` +
|
||||
`## CANDIDATES\n${candidateText}`;
|
||||
|
||||
try {
|
||||
const resp = await fetch(
|
||||
'https://api.groq.com/openai/v1/chat/completions',
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: `Bearer ${GROQ_API_KEY}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: GROQ_MODEL,
|
||||
messages: [
|
||||
{ role: 'system', content: CONFIRM_SYSTEM_PROMPT },
|
||||
{ role: 'user', content: userPrompt },
|
||||
],
|
||||
temperature: 0.1,
|
||||
max_tokens: 1024,
|
||||
}),
|
||||
signal: AbortSignal.timeout(30_000),
|
||||
}
|
||||
);
|
||||
|
||||
if (!resp.ok) {
|
||||
const text = await resp.text();
|
||||
throw new Error(`Groq API error ${resp.status}: ${text}`);
|
||||
}
|
||||
|
||||
let content = (await resp.json()).choices[0].message.content.trim();
|
||||
|
||||
if (content.startsWith('```')) {
|
||||
content = content
|
||||
.split('\n')
|
||||
.slice(1)
|
||||
.join('\n')
|
||||
.replace(/```\s*$/, '')
|
||||
.trim();
|
||||
}
|
||||
|
||||
const verdicts = JSON.parse(content);
|
||||
if (!Array.isArray(verdicts)) {
|
||||
throw new Error('Invalid LLM response format - expected array');
|
||||
}
|
||||
|
||||
const verdictMap = new Map(verdicts.map((v) => [v.number, v]));
|
||||
|
||||
const confirmed = [];
|
||||
for (const c of candidates) {
|
||||
const verdict = verdictMap.get(c.number);
|
||||
if (verdict?.duplicate) {
|
||||
c.llm_reason = verdict.reason || '';
|
||||
confirmed.push(c);
|
||||
} else {
|
||||
const reason = verdict?.reason || 'not evaluated';
|
||||
console.log(` #${c.number} ruled out by LLM: ${reason}`);
|
||||
}
|
||||
}
|
||||
|
||||
return confirmed;
|
||||
} catch (err) {
|
||||
console.warn(
|
||||
`LLM confirmation failed: ${err.message} - falling back to all candidates`
|
||||
);
|
||||
return candidates;
|
||||
}
|
||||
}
|
||||
|
||||
function formatComment(candidates) {
|
||||
const lines = [
|
||||
'**Possible duplicate detected**',
|
||||
'',
|
||||
'This issue may be a duplicate of the following (detected via semantic similarity + LLM review):',
|
||||
'',
|
||||
];
|
||||
|
||||
for (const c of candidates.slice(0, MAX_COMMENT_CANDIDATES)) {
|
||||
const confidence = `${(c.score * 100).toFixed(0)}%`;
|
||||
let line = `- #${c.number} (${confidence} match) — ${c.title}`;
|
||||
if (c.llm_reason) {
|
||||
line += `\n > *${c.llm_reason}*`;
|
||||
}
|
||||
lines.push(line);
|
||||
}
|
||||
|
||||
lines.push(
|
||||
'',
|
||||
'A maintainer will review this. If this is **not** a duplicate, no action is needed.',
|
||||
'',
|
||||
`<!-- duplicate-bot: candidates=${candidates.map((c) => c.number).join(',')} -->`
|
||||
);
|
||||
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
async function main() {
|
||||
if (!ISSUE_NUMBER) {
|
||||
console.error('ISSUE_NUMBER not set');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log(`Processing issue #${ISSUE_NUMBER}`);
|
||||
const issue = await getIssue(ISSUE_NUMBER);
|
||||
|
||||
const oneHourAgo = new Date(Date.now() - 60 * 60 * 1000).toISOString();
|
||||
const recentIssues = await fetchIssues({
|
||||
creator: issue.user.login,
|
||||
since: oneHourAgo,
|
||||
state: 'all',
|
||||
});
|
||||
|
||||
if (recentIssues.length > 10) {
|
||||
console.log(
|
||||
`User ${issue.user.login} created ${recentIssues.length} issues in the last hour - skipping to prevent spam`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (issue.pull_request) {
|
||||
console.log('Skipping - this is a pull request');
|
||||
return;
|
||||
}
|
||||
|
||||
if (issue.user.type === 'Bot') {
|
||||
console.log('Skipping - issue created by bot');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`Loading model: ${MODEL_NAME}`);
|
||||
const extractor = await pipeline('feature-extraction', MODEL_NAME, {
|
||||
dtype: 'fp32',
|
||||
});
|
||||
const index = loadIndex(INDEX_PATH);
|
||||
|
||||
const text = issueText(issue.title, issue.body);
|
||||
const output = await extractor(text, { pooling: 'mean', normalize: true });
|
||||
const queryEmbedding = output.tolist()[0];
|
||||
|
||||
let candidates = findSimilar(queryEmbedding, index, {
|
||||
topK: TOP_K,
|
||||
threshold: SIMILARITY_THRESHOLD,
|
||||
excludeNumber: issue.number,
|
||||
});
|
||||
|
||||
if (!candidates.length) {
|
||||
console.log('No similar issues found above threshold - done');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`Found ${candidates.length} candidates above threshold:`);
|
||||
for (const c of candidates) {
|
||||
console.log(` #${c.number} (${c.score.toFixed(3)}) - ${c.title}`);
|
||||
}
|
||||
|
||||
console.log('Running LLM confirmation via Groq...');
|
||||
candidates = await confirmWithLlm(issue, candidates);
|
||||
|
||||
if (!candidates.length) {
|
||||
console.log('LLM ruled out all candidates - done');
|
||||
return;
|
||||
}
|
||||
|
||||
const comment = formatComment(candidates);
|
||||
await postComment(ISSUE_NUMBER, comment);
|
||||
await addLabel(ISSUE_NUMBER, LABEL_NAME);
|
||||
|
||||
console.log('Done!');
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
17
bin/duplicate-detector/package.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "duplicate-detector",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"packageManager": "pnpm@10.17.1",
|
||||
"scripts": {
|
||||
"build-index": "node build-index.mjs",
|
||||
"detect": "node detect.mjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@huggingface/transformers": "^3.8.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=22.0"
|
||||
}
|
||||
}
|
||||
655
bin/duplicate-detector/pnpm-lock.yaml
generated
Normal file
@@ -0,0 +1,655 @@
|
||||
lockfileVersion: '9.0'
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
importers:
|
||||
|
||||
.:
|
||||
dependencies:
|
||||
'@huggingface/transformers':
|
||||
specifier: ^3.8.1
|
||||
version: 3.8.1
|
||||
|
||||
packages:
|
||||
|
||||
'@emnapi/runtime@1.8.1':
|
||||
resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==}
|
||||
|
||||
'@huggingface/jinja@0.5.5':
|
||||
resolution: {integrity: sha512-xRlzazC+QZwr6z4ixEqYHo9fgwhTZ3xNSdljlKfUFGZSdlvt166DljRELFUfFytlYOYvo3vTisA/AFOuOAzFQQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@huggingface/transformers@3.8.1':
|
||||
resolution: {integrity: sha512-tsTk4zVjImqdqjS8/AOZg2yNLd1z9S5v+7oUPpXaasDRwEDhB+xnglK1k5cad26lL5/ZIaeREgWWy0bs9y9pPA==}
|
||||
|
||||
'@img/colour@1.0.0':
|
||||
resolution: {integrity: sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@img/sharp-darwin-arm64@0.34.5':
|
||||
resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@img/sharp-darwin-x64@0.34.5':
|
||||
resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@img/sharp-libvips-darwin-arm64@1.2.4':
|
||||
resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@img/sharp-libvips-darwin-x64@1.2.4':
|
||||
resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@img/sharp-libvips-linux-arm64@1.2.4':
|
||||
resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-libvips-linux-arm@1.2.4':
|
||||
resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-libvips-linux-ppc64@1.2.4':
|
||||
resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-libvips-linux-riscv64@1.2.4':
|
||||
resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-libvips-linux-s390x@1.2.4':
|
||||
resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-libvips-linux-x64@1.2.4':
|
||||
resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-arm64@1.2.4':
|
||||
resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-x64@1.2.4':
|
||||
resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linux-arm64@0.34.5':
|
||||
resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linux-arm@0.34.5':
|
||||
resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linux-ppc64@0.34.5':
|
||||
resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linux-riscv64@0.34.5':
|
||||
resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linux-s390x@0.34.5':
|
||||
resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linux-x64@0.34.5':
|
||||
resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linuxmusl-arm64@0.34.5':
|
||||
resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linuxmusl-x64@0.34.5':
|
||||
resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-wasm32@0.34.5':
|
||||
resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [wasm32]
|
||||
|
||||
'@img/sharp-win32-arm64@0.34.5':
|
||||
resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@img/sharp-win32-ia32@0.34.5':
|
||||
resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
'@img/sharp-win32-x64@0.34.5':
|
||||
resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@isaacs/fs-minipass@4.0.1':
|
||||
resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
|
||||
'@protobufjs/aspromise@1.1.2':
|
||||
resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==}
|
||||
|
||||
'@protobufjs/base64@1.1.2':
|
||||
resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==}
|
||||
|
||||
'@protobufjs/codegen@2.0.4':
|
||||
resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==}
|
||||
|
||||
'@protobufjs/eventemitter@1.1.0':
|
||||
resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==}
|
||||
|
||||
'@protobufjs/fetch@1.1.0':
|
||||
resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==}
|
||||
|
||||
'@protobufjs/float@1.0.2':
|
||||
resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==}
|
||||
|
||||
'@protobufjs/inquire@1.1.0':
|
||||
resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==}
|
||||
|
||||
'@protobufjs/path@1.1.2':
|
||||
resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==}
|
||||
|
||||
'@protobufjs/pool@1.1.0':
|
||||
resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==}
|
||||
|
||||
'@protobufjs/utf8@1.1.0':
|
||||
resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==}
|
||||
|
||||
'@types/node@25.2.2':
|
||||
resolution: {integrity: sha512-BkmoP5/FhRYek5izySdkOneRyXYN35I860MFAGupTdebyE66uZaR+bXLHq8k4DirE5DwQi3NuhvRU1jqTVwUrQ==}
|
||||
|
||||
boolean@3.2.0:
|
||||
resolution: {integrity: sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==}
|
||||
deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
|
||||
|
||||
chownr@3.0.0:
|
||||
resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
define-data-property@1.1.4:
|
||||
resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
define-properties@1.2.1:
|
||||
resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
detect-libc@2.1.2:
|
||||
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
detect-node@2.1.0:
|
||||
resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==}
|
||||
|
||||
es-define-property@1.0.1:
|
||||
resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
es-errors@1.3.0:
|
||||
resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
es6-error@4.1.1:
|
||||
resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==}
|
||||
|
||||
escape-string-regexp@4.0.0:
|
||||
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
flatbuffers@25.9.23:
|
||||
resolution: {integrity: sha512-MI1qs7Lo4Syw0EOzUl0xjs2lsoeqFku44KpngfIduHBYvzm8h2+7K8YMQh1JtVVVrUvhLpNwqVi4DERegUJhPQ==}
|
||||
|
||||
global-agent@3.0.0:
|
||||
resolution: {integrity: sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==}
|
||||
engines: {node: '>=10.0'}
|
||||
|
||||
globalthis@1.0.4:
|
||||
resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
gopd@1.2.0:
|
||||
resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
guid-typescript@1.0.9:
|
||||
resolution: {integrity: sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ==}
|
||||
|
||||
has-property-descriptors@1.0.2:
|
||||
resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==}
|
||||
|
||||
json-stringify-safe@5.0.1:
|
||||
resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==}
|
||||
|
||||
long@5.3.2:
|
||||
resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==}
|
||||
|
||||
matcher@3.0.0:
|
||||
resolution: {integrity: sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
minipass@7.1.2:
|
||||
resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
|
||||
minizlib@3.1.0:
|
||||
resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==}
|
||||
engines: {node: '>= 18'}
|
||||
|
||||
object-keys@1.1.1:
|
||||
resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
onnxruntime-common@1.21.0:
|
||||
resolution: {integrity: sha512-Q632iLLrtCAVOTO65dh2+mNbQir/QNTVBG3h/QdZBpns7mZ0RYbLRBgGABPbpU9351AgYy7SJf1WaeVwMrBFPQ==}
|
||||
|
||||
onnxruntime-common@1.22.0-dev.20250409-89f8206ba4:
|
||||
resolution: {integrity: sha512-vDJMkfCfb0b1A836rgHj+ORuZf4B4+cc2bASQtpeoJLueuFc5DuYwjIZUBrSvx/fO5IrLjLz+oTrB3pcGlhovQ==}
|
||||
|
||||
onnxruntime-node@1.21.0:
|
||||
resolution: {integrity: sha512-NeaCX6WW2L8cRCSqy3bInlo5ojjQqu2fD3D+9W5qb5irwxhEyWKXeH2vZ8W9r6VxaMPUan+4/7NDwZMtouZxEw==}
|
||||
os: [win32, darwin, linux]
|
||||
|
||||
onnxruntime-web@1.22.0-dev.20250409-89f8206ba4:
|
||||
resolution: {integrity: sha512-0uS76OPgH0hWCPrFKlL8kYVV7ckM7t/36HfbgoFw6Nd0CZVVbQC4PkrR8mBX8LtNUFZO25IQBqV2Hx2ho3FlbQ==}
|
||||
|
||||
platform@1.3.6:
|
||||
resolution: {integrity: sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==}
|
||||
|
||||
protobufjs@7.5.4:
|
||||
resolution: {integrity: sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
|
||||
roarr@2.15.4:
|
||||
resolution: {integrity: sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==}
|
||||
engines: {node: '>=8.0'}
|
||||
|
||||
semver-compare@1.0.0:
|
||||
resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==}
|
||||
|
||||
semver@7.7.4:
|
||||
resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==}
|
||||
engines: {node: '>=10'}
|
||||
hasBin: true
|
||||
|
||||
serialize-error@7.0.1:
|
||||
resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
sharp@0.34.5:
|
||||
resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
|
||||
sprintf-js@1.1.3:
|
||||
resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==}
|
||||
|
||||
tar@7.5.7:
|
||||
resolution: {integrity: sha512-fov56fJiRuThVFXD6o6/Q354S7pnWMJIVlDBYijsTNx6jKSE4pvrDTs6lUnmGvNyfJwFQQwWy3owKz1ucIhveQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
tslib@2.8.1:
|
||||
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
|
||||
|
||||
type-fest@0.13.1:
|
||||
resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
undici-types@7.16.0:
|
||||
resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
|
||||
|
||||
yallist@5.0.0:
|
||||
resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
snapshots:
|
||||
|
||||
'@emnapi/runtime@1.8.1':
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
optional: true
|
||||
|
||||
'@huggingface/jinja@0.5.5': {}
|
||||
|
||||
'@huggingface/transformers@3.8.1':
|
||||
dependencies:
|
||||
'@huggingface/jinja': 0.5.5
|
||||
onnxruntime-node: 1.21.0
|
||||
onnxruntime-web: 1.22.0-dev.20250409-89f8206ba4
|
||||
sharp: 0.34.5
|
||||
|
||||
'@img/colour@1.0.0': {}
|
||||
|
||||
'@img/sharp-darwin-arm64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-darwin-arm64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-darwin-x64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-darwin-x64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-darwin-arm64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-darwin-x64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-arm64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-arm@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-ppc64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-riscv64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-s390x@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-x64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-arm64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-x64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-arm64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-arm64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-arm@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-arm': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-ppc64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-ppc64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-riscv64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-riscv64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-s390x@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-s390x': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-x64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-x64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linuxmusl-arm64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linuxmusl-arm64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linuxmusl-x64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linuxmusl-x64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-wasm32@0.34.5':
|
||||
dependencies:
|
||||
'@emnapi/runtime': 1.8.1
|
||||
optional: true
|
||||
|
||||
'@img/sharp-win32-arm64@0.34.5':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-win32-ia32@0.34.5':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-win32-x64@0.34.5':
|
||||
optional: true
|
||||
|
||||
'@isaacs/fs-minipass@4.0.1':
|
||||
dependencies:
|
||||
minipass: 7.1.2
|
||||
|
||||
'@protobufjs/aspromise@1.1.2': {}
|
||||
|
||||
'@protobufjs/base64@1.1.2': {}
|
||||
|
||||
'@protobufjs/codegen@2.0.4': {}
|
||||
|
||||
'@protobufjs/eventemitter@1.1.0': {}
|
||||
|
||||
'@protobufjs/fetch@1.1.0':
|
||||
dependencies:
|
||||
'@protobufjs/aspromise': 1.1.2
|
||||
'@protobufjs/inquire': 1.1.0
|
||||
|
||||
'@protobufjs/float@1.0.2': {}
|
||||
|
||||
'@protobufjs/inquire@1.1.0': {}
|
||||
|
||||
'@protobufjs/path@1.1.2': {}
|
||||
|
||||
'@protobufjs/pool@1.1.0': {}
|
||||
|
||||
'@protobufjs/utf8@1.1.0': {}
|
||||
|
||||
'@types/node@25.2.2':
|
||||
dependencies:
|
||||
undici-types: 7.16.0
|
||||
|
||||
boolean@3.2.0: {}
|
||||
|
||||
chownr@3.0.0: {}
|
||||
|
||||
define-data-property@1.1.4:
|
||||
dependencies:
|
||||
es-define-property: 1.0.1
|
||||
es-errors: 1.3.0
|
||||
gopd: 1.2.0
|
||||
|
||||
define-properties@1.2.1:
|
||||
dependencies:
|
||||
define-data-property: 1.1.4
|
||||
has-property-descriptors: 1.0.2
|
||||
object-keys: 1.1.1
|
||||
|
||||
detect-libc@2.1.2: {}
|
||||
|
||||
detect-node@2.1.0: {}
|
||||
|
||||
es-define-property@1.0.1: {}
|
||||
|
||||
es-errors@1.3.0: {}
|
||||
|
||||
es6-error@4.1.1: {}
|
||||
|
||||
escape-string-regexp@4.0.0: {}
|
||||
|
||||
flatbuffers@25.9.23: {}
|
||||
|
||||
global-agent@3.0.0:
|
||||
dependencies:
|
||||
boolean: 3.2.0
|
||||
es6-error: 4.1.1
|
||||
matcher: 3.0.0
|
||||
roarr: 2.15.4
|
||||
semver: 7.7.4
|
||||
serialize-error: 7.0.1
|
||||
|
||||
globalthis@1.0.4:
|
||||
dependencies:
|
||||
define-properties: 1.2.1
|
||||
gopd: 1.2.0
|
||||
|
||||
gopd@1.2.0: {}
|
||||
|
||||
guid-typescript@1.0.9: {}
|
||||
|
||||
has-property-descriptors@1.0.2:
|
||||
dependencies:
|
||||
es-define-property: 1.0.1
|
||||
|
||||
json-stringify-safe@5.0.1: {}
|
||||
|
||||
long@5.3.2: {}
|
||||
|
||||
matcher@3.0.0:
|
||||
dependencies:
|
||||
escape-string-regexp: 4.0.0
|
||||
|
||||
minipass@7.1.2: {}
|
||||
|
||||
minizlib@3.1.0:
|
||||
dependencies:
|
||||
minipass: 7.1.2
|
||||
|
||||
object-keys@1.1.1: {}
|
||||
|
||||
onnxruntime-common@1.21.0: {}
|
||||
|
||||
onnxruntime-common@1.22.0-dev.20250409-89f8206ba4: {}
|
||||
|
||||
onnxruntime-node@1.21.0:
|
||||
dependencies:
|
||||
global-agent: 3.0.0
|
||||
onnxruntime-common: 1.21.0
|
||||
tar: 7.5.7
|
||||
|
||||
onnxruntime-web@1.22.0-dev.20250409-89f8206ba4:
|
||||
dependencies:
|
||||
flatbuffers: 25.9.23
|
||||
guid-typescript: 1.0.9
|
||||
long: 5.3.2
|
||||
onnxruntime-common: 1.22.0-dev.20250409-89f8206ba4
|
||||
platform: 1.3.6
|
||||
protobufjs: 7.5.4
|
||||
|
||||
platform@1.3.6: {}
|
||||
|
||||
protobufjs@7.5.4:
|
||||
dependencies:
|
||||
'@protobufjs/aspromise': 1.1.2
|
||||
'@protobufjs/base64': 1.1.2
|
||||
'@protobufjs/codegen': 2.0.4
|
||||
'@protobufjs/eventemitter': 1.1.0
|
||||
'@protobufjs/fetch': 1.1.0
|
||||
'@protobufjs/float': 1.0.2
|
||||
'@protobufjs/inquire': 1.1.0
|
||||
'@protobufjs/path': 1.1.2
|
||||
'@protobufjs/pool': 1.1.0
|
||||
'@protobufjs/utf8': 1.1.0
|
||||
'@types/node': 25.2.2
|
||||
long: 5.3.2
|
||||
|
||||
roarr@2.15.4:
|
||||
dependencies:
|
||||
boolean: 3.2.0
|
||||
detect-node: 2.1.0
|
||||
globalthis: 1.0.4
|
||||
json-stringify-safe: 5.0.1
|
||||
semver-compare: 1.0.0
|
||||
sprintf-js: 1.1.3
|
||||
|
||||
semver-compare@1.0.0: {}
|
||||
|
||||
semver@7.7.4: {}
|
||||
|
||||
serialize-error@7.0.1:
|
||||
dependencies:
|
||||
type-fest: 0.13.1
|
||||
|
||||
sharp@0.34.5:
|
||||
dependencies:
|
||||
'@img/colour': 1.0.0
|
||||
detect-libc: 2.1.2
|
||||
semver: 7.7.4
|
||||
optionalDependencies:
|
||||
'@img/sharp-darwin-arm64': 0.34.5
|
||||
'@img/sharp-darwin-x64': 0.34.5
|
||||
'@img/sharp-libvips-darwin-arm64': 1.2.4
|
||||
'@img/sharp-libvips-darwin-x64': 1.2.4
|
||||
'@img/sharp-libvips-linux-arm': 1.2.4
|
||||
'@img/sharp-libvips-linux-arm64': 1.2.4
|
||||
'@img/sharp-libvips-linux-ppc64': 1.2.4
|
||||
'@img/sharp-libvips-linux-riscv64': 1.2.4
|
||||
'@img/sharp-libvips-linux-s390x': 1.2.4
|
||||
'@img/sharp-libvips-linux-x64': 1.2.4
|
||||
'@img/sharp-libvips-linuxmusl-arm64': 1.2.4
|
||||
'@img/sharp-libvips-linuxmusl-x64': 1.2.4
|
||||
'@img/sharp-linux-arm': 0.34.5
|
||||
'@img/sharp-linux-arm64': 0.34.5
|
||||
'@img/sharp-linux-ppc64': 0.34.5
|
||||
'@img/sharp-linux-riscv64': 0.34.5
|
||||
'@img/sharp-linux-s390x': 0.34.5
|
||||
'@img/sharp-linux-x64': 0.34.5
|
||||
'@img/sharp-linuxmusl-arm64': 0.34.5
|
||||
'@img/sharp-linuxmusl-x64': 0.34.5
|
||||
'@img/sharp-wasm32': 0.34.5
|
||||
'@img/sharp-win32-arm64': 0.34.5
|
||||
'@img/sharp-win32-ia32': 0.34.5
|
||||
'@img/sharp-win32-x64': 0.34.5
|
||||
|
||||
sprintf-js@1.1.3: {}
|
||||
|
||||
tar@7.5.7:
|
||||
dependencies:
|
||||
'@isaacs/fs-minipass': 4.0.1
|
||||
chownr: 3.0.0
|
||||
minipass: 7.1.2
|
||||
minizlib: 3.1.0
|
||||
yallist: 5.0.0
|
||||
|
||||
tslib@2.8.1:
|
||||
optional: true
|
||||
|
||||
type-fest@0.13.1: {}
|
||||
|
||||
undici-types@7.16.0: {}
|
||||
|
||||
yallist@5.0.0: {}
|
||||
116
bin/duplicate-detector/utils.mjs
Normal file
@@ -0,0 +1,116 @@
|
||||
const GITHUB_API = 'https://api.github.com';
|
||||
const GITHUB_TOKEN = process.env.GITHUB_TOKEN;
|
||||
const GITHUB_REPOSITORY = process.env.GITHUB_REPOSITORY;
|
||||
|
||||
function ghHeaders() {
|
||||
return {
|
||||
Authorization: `token ${GITHUB_TOKEN}`,
|
||||
Accept: 'application/vnd.github+json',
|
||||
};
|
||||
}
|
||||
|
||||
export async function fetchIssues({
|
||||
state = 'open',
|
||||
since,
|
||||
maxIssues = 5000,
|
||||
} = {}) {
|
||||
const issues = [];
|
||||
let page = 1;
|
||||
const perPage = 100;
|
||||
|
||||
while (issues.length < maxIssues) {
|
||||
const params = new URLSearchParams({
|
||||
state,
|
||||
per_page: String(perPage),
|
||||
page: String(page),
|
||||
sort: 'updated',
|
||||
direction: 'desc',
|
||||
});
|
||||
if (since) params.set('since', since);
|
||||
|
||||
const url = `${GITHUB_API}/repos/${GITHUB_REPOSITORY}/issues?${params}`;
|
||||
const resp = await fetch(url, { headers: ghHeaders() });
|
||||
|
||||
if (!resp.ok) {
|
||||
throw new Error(`GitHub API error: ${resp.status} ${resp.statusText}`);
|
||||
}
|
||||
|
||||
const batch = await resp.json();
|
||||
if (!batch.length) break;
|
||||
|
||||
for (const item of batch) {
|
||||
if (!item.pull_request) {
|
||||
issues.push(item);
|
||||
}
|
||||
}
|
||||
|
||||
page++;
|
||||
if (batch.length < perPage) break;
|
||||
}
|
||||
|
||||
return issues.slice(0, maxIssues);
|
||||
}
|
||||
|
||||
export async function getIssue(issueNumber) {
|
||||
const url = `${GITHUB_API}/repos/${GITHUB_REPOSITORY}/issues/${issueNumber}`;
|
||||
const resp = await fetch(url, { headers: ghHeaders() });
|
||||
|
||||
if (!resp.ok) {
|
||||
throw new Error(`GitHub API error: ${resp.status} ${resp.statusText}`);
|
||||
}
|
||||
|
||||
return resp.json();
|
||||
}
|
||||
|
||||
export async function postComment(issueNumber, body) {
|
||||
const url = `${GITHUB_API}/repos/${GITHUB_REPOSITORY}/issues/${issueNumber}/comments`;
|
||||
const resp = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers: { ...ghHeaders(), 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ body }),
|
||||
});
|
||||
|
||||
if (!resp.ok) {
|
||||
throw new Error(
|
||||
`Failed to post comment: ${resp.status} ${resp.statusText}`
|
||||
);
|
||||
}
|
||||
|
||||
console.log(`Posted comment on #${issueNumber}`);
|
||||
}
|
||||
|
||||
export async function addLabel(issueNumber, label) {
|
||||
const url = `${GITHUB_API}/repos/${GITHUB_REPOSITORY}/issues/${issueNumber}/labels`;
|
||||
const resp = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers: { ...ghHeaders(), 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ labels: [label] }),
|
||||
});
|
||||
|
||||
if (resp.status === 404) {
|
||||
console.warn(
|
||||
`Label '${label}' does not exist - skipping. Create it manually.`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!resp.ok) {
|
||||
throw new Error(`Failed to add label: ${resp.status} ${resp.statusText}`);
|
||||
}
|
||||
|
||||
console.log(`Added label '${label}' to #${issueNumber}`);
|
||||
}
|
||||
|
||||
export function issueText(title, body) {
|
||||
body = (body || '').trim();
|
||||
if (body.length > 2000) body = body.slice(0, 2000) + '...';
|
||||
return body ? `${title}\n\n${body}` : title;
|
||||
}
|
||||
|
||||
export function dotProduct(a, b) {
|
||||
let sum = 0;
|
||||
for (let i = 0; i < a.length; i++) {
|
||||
sum += a[i] * b[i];
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
@@ -3,9 +3,9 @@ kubeVersion: '>=1.23.0-0'
|
||||
name: seerr-chart
|
||||
description: Seerr helm chart for Kubernetes
|
||||
type: application
|
||||
version: 3.0.0
|
||||
version: 3.1.0
|
||||
# renovate: image=ghcr.io/seerr-team/seerr
|
||||
appVersion: '2.7.3'
|
||||
appVersion: 'v3.0.1'
|
||||
maintainers:
|
||||
- name: Seerr Team
|
||||
url: https://github.com/orgs/seerr-team/people
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# seerr-chart
|
||||
|
||||
  
|
||||
  
|
||||
|
||||
Seerr helm chart for Kubernetes
|
||||
|
||||
@@ -22,7 +22,7 @@ Kubernetes: `>=1.23.0-0`
|
||||
|
||||
## Installation
|
||||
|
||||
Refer to [https://docs.seerr.dev/getting-started/kubernetes](Seerr kubernetes documentation)
|
||||
Refer to [Seerr kubernetes documentation](https://docs.seerr.dev/getting-started/kubernetes)
|
||||
|
||||
## Update Notes
|
||||
|
||||
@@ -44,9 +44,10 @@ If `replicaCount` value was used - remove it. Helm update should work fine after
|
||||
| Key | Type | Default | Description |
|
||||
|-----|------|---------|-------------|
|
||||
| affinity | object | `{}` | |
|
||||
| config | object | `{"persistence":{"accessModes":["ReadWriteOnce"],"annotations":{},"name":"","size":"5Gi","volumeName":""}}` | Creating PVC to store configuration |
|
||||
| config | object | `{"persistence":{"accessModes":["ReadWriteOnce"],"annotations":{},"existingClaim":"","name":"","size":"5Gi","volumeName":""}}` | Creating PVC to store configuration |
|
||||
| config.persistence.accessModes | list | `["ReadWriteOnce"]` | Access modes of persistent disk |
|
||||
| config.persistence.annotations | object | `{}` | Annotations for PVCs |
|
||||
| config.persistence.existingClaim | string | `""` | Specify an existing `PersistentVolumeClaim` to use. If this value is provided, the default PVC will not be created |
|
||||
| config.persistence.name | string | `""` | Config name |
|
||||
| config.persistence.size | string | `"5Gi"` | Size of persistent disk |
|
||||
| config.persistence.volumeName | string | `""` | Name of the permanent volume to reference in the claim. Can be used to bind to existing volumes. |
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
## Installation
|
||||
|
||||
Refer to [https://docs.seerr.dev/getting-started/kubernetes](Seerr kubernetes documentation)
|
||||
Refer to [Seerr kubernetes documentation](https://docs.seerr.dev/getting-started/kubernetes)
|
||||
|
||||
## Update Notes
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
{{- if not .Values.config.persistence.existingClaim -}}
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
@@ -22,3 +23,4 @@ spec:
|
||||
resources:
|
||||
requests:
|
||||
storage: "{{ .Values.config.persistence.size }}"
|
||||
{{- end -}}
|
||||
@@ -103,7 +103,7 @@ spec:
|
||||
volumes:
|
||||
- name: config
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ include "seerr.configPersistenceName" . }}
|
||||
claimName: {{ if .Values.config.persistence.existingClaim }}{{ .Values.config.persistence.existingClaim }}{{- else }}{{ include "seerr.configPersistenceName" . }}{{- end }}
|
||||
{{- with .Values.volumes }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
|
||||
@@ -86,6 +86,8 @@ config:
|
||||
# -- Name of the permanent volume to reference in the claim.
|
||||
# Can be used to bind to existing volumes.
|
||||
volumeName: ''
|
||||
# -- Specify an existing `PersistentVolumeClaim` to use. If this value is provided, the default PVC will not be created
|
||||
existingClaim: ''
|
||||
|
||||
ingress:
|
||||
enabled: false
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
"discoverRegion": "",
|
||||
"streamingRegion": "",
|
||||
"originalLanguage": "",
|
||||
"blacklistedTags": "",
|
||||
"blacklistedTagsLimit": 50,
|
||||
"blocklistedTags": "",
|
||||
"blocklistedTagsLimit": 50,
|
||||
"trustProxy": false,
|
||||
"mediaServerType": 1,
|
||||
"partialRequestsEnabled": true,
|
||||
|
||||
@@ -23,7 +23,7 @@ Welcome to the Seerr Documentation.
|
||||
- Localization into other languages.
|
||||
- Support for **PostgreSQL** and **SQLite** databases.
|
||||
- Support for various notification agents.
|
||||
- Easily **Watchlist** or **Blacklist** media.
|
||||
- Easily **Watchlist** or **Blocklist** media.
|
||||
- More features to come!
|
||||
|
||||
## We need your help!
|
||||
|
||||
@@ -26,8 +26,7 @@ sudo mkdir -p /opt/seerr && cd /opt/seerr
|
||||
```
|
||||
2. Clone the Seerr repository and checkout the main branch:
|
||||
```bash
|
||||
git clone https://github.com/seerr-team/seerr.git
|
||||
cd seerr
|
||||
git clone https://github.com/seerr-team/seerr.git .
|
||||
git checkout main
|
||||
```
|
||||
3. Install the dependencies:
|
||||
|
||||
@@ -13,6 +13,12 @@ Refer to [Configuring Databases](/extending-seerr/database-config#postgresql-opt
|
||||
|
||||
:::info
|
||||
An alternative Docker image is available on Docker Hub for this project. You can find it at [Docker Hub Repository Link](https://hub.docker.com/r/seerr/seerr)
|
||||
|
||||
Our Docker images are available with the following tags:
|
||||
|
||||
- `latest`: Always points to the most recent stable release.
|
||||
- Version tags (e.g., `v3.0.0`): For specific stable versions.
|
||||
- `develop`: Rolling release/nightly builds for using the latest changes (use with caution).
|
||||
:::
|
||||
|
||||
:::info
|
||||
@@ -38,6 +44,13 @@ For details on the Docker CLI, please [review the official `docker run` document
|
||||
|
||||
#### Installation:
|
||||
|
||||
```bash
|
||||
# Create the appdata folder
|
||||
mkdir /path/to/appdata/config
|
||||
# Chown the folder as the container runs as the `node` user (UID 1000).
|
||||
chown -R 1000:1000 /path/to/appdata/config
|
||||
```
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--name seerr \
|
||||
@@ -48,20 +61,16 @@ docker run -d \
|
||||
-p 5055:5055 \
|
||||
-v /path/to/appdata/config:/app/config \
|
||||
--restart unless-stopped \
|
||||
ghcr.io/seerr-team/seerr:latest
|
||||
```
|
||||
|
||||
The argument `-e PORT=5055` is optional.
|
||||
|
||||
If you want to add a healthcheck to the above command, you can add the following flags :
|
||||
```
|
||||
--health-cmd "wget --no-verbose --tries=1 --spider http://localhost:5055/api/v1/status || exit 1" \
|
||||
--health-start-period 20s \
|
||||
--health-timeout 3s \
|
||||
--health-interval 15s \
|
||||
--health-retries 3 \
|
||||
ghcr.io/seerr-team/seerr:latest
|
||||
```
|
||||
|
||||
The argument `-e PORT=5055` is optional.
|
||||
|
||||
To run the container as a specific user/group, you may optionally add `--user=[ user | user:group | uid | uid:gid | user:gid | uid:group ]` to the above command.
|
||||
|
||||
#### Updating:
|
||||
@@ -115,6 +124,13 @@ services:
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
```bash
|
||||
# Create the appdata folder
|
||||
mkdir /path/to/appdata/config
|
||||
# Chown the folder as the container runs as the `node` user (UID 1000).
|
||||
chown -R 1000:1000 /path/to/appdata/config
|
||||
```
|
||||
|
||||
Then, start all services defined in the Compose file:
|
||||
```bash
|
||||
docker compose up -d
|
||||
@@ -129,9 +145,6 @@ Then, restart all services defined in the Compose file:
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
:::tip
|
||||
You may alternatively use a third-party mechanism like [dockge](https://github.com/louislam/dockge) to manage your docker compose files.
|
||||
:::
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
@@ -166,20 +179,16 @@ docker run -d \
|
||||
-p 5055:5055 \
|
||||
-v seerr-data:/app/config \
|
||||
--restart unless-stopped \
|
||||
ghcr.io/seerr-team/seerr:latest
|
||||
```
|
||||
|
||||
The argument `-e PORT=5055` is optional.
|
||||
|
||||
If you want to add a healthcheck to the above command, you can add the following flags :
|
||||
```
|
||||
--health-cmd "wget --no-verbose --tries=1 --spider http://localhost:5055/api/v1/status || exit 1" \
|
||||
--health-start-period 20s \
|
||||
--health-timeout 3s \
|
||||
--health-interval 15s \
|
||||
--health-retries 3 \
|
||||
ghcr.io/seerr-team/seerr:latest
|
||||
```
|
||||
|
||||
The argument `-e PORT=5055` is optional.
|
||||
|
||||
#### Updating:
|
||||
Pull the latest image:
|
||||
```bash
|
||||
|
||||
@@ -7,5 +7,9 @@ import DocCardList from '@theme/DocCardList';
|
||||
Third-party installation methods are maintained by the community. The Seerr team is not responsible for these packages.
|
||||
:::
|
||||
|
||||
:::info
|
||||
Want to add a third-party installation method? Contributions are welcome! Feel free to open a pull request.
|
||||
:::
|
||||
|
||||
|
||||
<DocCardList />
|
||||
|
||||
@@ -10,8 +10,21 @@ import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Nix Package Manager
|
||||
:::danger
|
||||
This method has not yet been updated for Seerr and is currently a work in progress.
|
||||
You can follow the ongoing work on these pull requests:
|
||||
- https://github.com/NixOS/nixpkgs/pull/450096
|
||||
- https://github.com/NixOS/nixpkgs/pull/450093
|
||||
:::
|
||||
|
||||
<!--
|
||||
:::warning
|
||||
Third-party installation methods are maintained by the community. The Seerr team is not responsible for these packages.
|
||||
:::
|
||||
|
||||
:::warning
|
||||
This method is not recommended for most users. It is intended for advanced users who are using NixOS distribution.
|
||||
:::
|
||||
|
||||
Refer to [NixOS documentation](https://search.nixos.org/options?channel=25.05&query=seerr)
|
||||
-->
|
||||
|
||||
20
docs/getting-started/third-parties/truenas.mdx
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
title: TrueNAS (Advanced)
|
||||
description: Install Seerr using TrueNAS
|
||||
sidebar_position: 4
|
||||
---
|
||||
# TrueNAS
|
||||
:::danger
|
||||
This method has not yet been updated for Seerr and is currently a work in progress.
|
||||
You can follow the ongoing work on this issue https://github.com/truenas/apps/issues/3374.
|
||||
:::
|
||||
|
||||
<!--
|
||||
:::warning
|
||||
Third-party installation methods are maintained by the community. The Seerr team is not responsible for these packages.
|
||||
:::
|
||||
|
||||
:::warning
|
||||
This method is not recommended for most users. It is intended for advanced users who are using TrueNAS distribution.
|
||||
:::
|
||||
-->
|
||||
@@ -5,6 +5,7 @@ sidebar_position: 3
|
||||
---
|
||||
|
||||
# Unraid
|
||||
|
||||
:::warning
|
||||
Third-party installation methods are maintained by the community. The Seerr team is not responsible for these packages.
|
||||
:::
|
||||
@@ -13,8 +14,76 @@ Third-party installation methods are maintained by the community. The Seerr team
|
||||
This method is not recommended for most users. It is intended for advanced users who are using Unraid.
|
||||
:::
|
||||
|
||||
1. Ensure you have the **Community Applications** plugin installed.
|
||||
2. Inside the **Community Applications** app store, search for **Seerr**.
|
||||
3. Click the **Install Button**.
|
||||
4. On the following **Add Container** screen, make changes to the **Host Port** and **Host Path 1** \(Appdata\) as needed.
|
||||
5. Click apply and access "Seerr" at your `<ServerIP:HostPort>` in a web browser.
|
||||
|
||||
If an official Unraid Community Applications template for Seerr isn't available in your catalog, you can install Seerr manually using Unraid's Docker UI.
|
||||
|
||||
## Fresh Installation
|
||||
|
||||
### 1. Create the config directory
|
||||
|
||||
:::note
|
||||
Seerr is now rootless. Unraid typically runs Docker containers as `nobody:users` (UID 99, GID 100), but Seerr now runs internally as UID 1000, GID 1000. This creates a permission mismatch.
|
||||
:::
|
||||
|
||||
:::info
|
||||
**If migrating**: Copy your existing Jellyseerr/Overseerr config files (e.g., from `/mnt/user/appdata/overseerr/` or `/mnt/user/appdata/jellyseerr`) to `/mnt/user/appdata/seerr`, then apply the permissions below
|
||||
:::
|
||||
|
||||
Open the Unraid terminal and run:
|
||||
|
||||
```bash
|
||||
mkdir -p /mnt/user/appdata/seerr
|
||||
chown -R 1000:1000 /mnt/user/appdata/seerr
|
||||
```
|
||||
|
||||
### 2. Add the Docker container
|
||||
|
||||
Navigate to the **Docker** tab in Unraid and click **Add Container**. Fill in the following:
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| **Name** | `seerr` |
|
||||
| **Repository** | `ghcr.io/seerr-team/seerr:latest` |
|
||||
| **Registry URL** (optional) | `https://ghcr.io` |
|
||||
| **Icon URL** | `https://raw.githubusercontent.com/seerr-team/seerr/develop/public/android-chrome-512x512.png` |
|
||||
| **WebUI** | `http://[IP]:[PORT:5055]` |
|
||||
| **Extra Parameters** | `--init` |
|
||||
| **Network Type** | `bridge` |
|
||||
| **Privileged** | `Off` |
|
||||
|
||||
Then click **Add another Path, Port, Variable** to add:
|
||||
|
||||
**Port:**
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Container Port | `5055` |
|
||||
| Host Port | `5055` |
|
||||
| Connection Type | `TCP` |
|
||||
|
||||
**Path:**
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Container Path | `/app/config` |
|
||||
| Host Path | `/mnt/user/appdata/seerr` |
|
||||
|
||||
**Variable:**
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Key | `TZ` |
|
||||
| Value | Your [TZ database name](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) (e.g., `America/New_York`) |
|
||||
|
||||
**Variable (optional):**
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Key | `LOG_LEVEL` |
|
||||
| Value | `info` |
|
||||
|
||||
Click **Apply** to create and start the container.
|
||||
|
||||
### 3. Access Seerr
|
||||
|
||||
Open the WebUI at `http://<your-unraid-ip>:5055` and follow the setup wizard.
|
||||
|
||||
:::info
|
||||
The `--init` flag in **Extra Parameters** is required. Seerr does not include its own init process, so `--init` ensures proper signal handling and clean container shutdowns.
|
||||
:::
|
||||
|
||||
@@ -5,30 +5,56 @@ title: Migration guide
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
:::important
|
||||
Read our [release announcement](/blog/seerr-release) to learn what Seerr means for Jellyseerr and Overseerr users.
|
||||
:::
|
||||
|
||||
Whether you come from Overseerr or Jellyseerr, you don't need to perform any manual migration steps, your instance will automatically be migrated to Seerr.
|
||||
This migration will run automatically the first time you start your instance using the Seerr codebase (Docker image or source build or Kubernetes, etc.).
|
||||
An additional migration will happen for Overseerr users, to migrate their configuration to the new codebase.
|
||||
|
||||
:::warning
|
||||
:::danger
|
||||
Before doing anything you should backup your existing instance so that you can rollback in case something goes wrong.
|
||||
See [Backups](/using-seerr/backups) for details on how to properly backup your instance.
|
||||
:::
|
||||
|
||||
:::warning
|
||||
Installation methods are now divided into two categories: official and third-party methods.
|
||||
The Seerr team is only responsible for official installation methods, while third-party methods are maintained by the community.
|
||||
Some methods are currently not maintained, but this does not mean they are permanently discontinued. The community may restore and support them if they choose to do so.
|
||||
|
||||
- **Snap package:** Not maintained
|
||||
:::
|
||||
|
||||
## Docker
|
||||
Refer to [Seerr Docker Documentation](/getting-started/docker), all of our examples have been updated to reflect the below change.
|
||||
|
||||
:::info
|
||||
Seerr provides a secure, fully featured image with everything you need included.
|
||||
We sincerely appreciate the past contributions from third-party maintainers, which helped enhance this image and its capabilities.
|
||||
To maintain consistency and security, we encourage everyone to use the features available in the official Seerr image.
|
||||
If you feel something is missing, please submit a feature request—your feedback is always welcome!
|
||||
|
||||
Our Docker images are available with the following tags:
|
||||
|
||||
- `latest`: Always points to the most recent stable release.
|
||||
- Version tags (e.g., `v3.0.0`): For specific stable versions.
|
||||
- `develop`: Rolling release/nightly builds for using the latest changes (use with caution).
|
||||
:::
|
||||
|
||||
Changes :
|
||||
- Renamed all references from `overseerr` or `jellyseerr` to `seerr`.
|
||||
- The container image reference has been updated.
|
||||
- The container can now be run as a non-root user (`node` user); remove the `user` directive if you have configured it.
|
||||
- The container no longer provides an init process, so you must configure it by adding `init: true` for Docker Compose or `--init` for the Docker CLI.
|
||||
|
||||
#### Config folder permissions
|
||||
:::info
|
||||
**Config folder permissions**: Since the container now runs as the `node` user (UID 1000), you must ensure your config folder has the correct permissions. The `node` user must have read and write access to the `/app/config` directory.
|
||||
Since the container now runs as the `node` user (UID 1000), you must ensure your config folder has the correct permissions. The `node` user must have read and write access to the `/app/config` directory.
|
||||
|
||||
If you're migrating from a previous installation, you may need to update the ownership of your config folder:
|
||||
```bash
|
||||
sudo chown -R 1000:1000 /path/to/appdata/config
|
||||
docker run --rm -v /path/to/appdata/config:/data alpine chown -R 1000:1000 /data
|
||||
```
|
||||
|
||||
This ensures the `node` user (UID 1000) owns the config directory and can read and write to it.
|
||||
@@ -126,6 +152,12 @@ Summary of changes :
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
|
||||
## Build From Source
|
||||
Refer to [Seerr Build From Source Documentation](/getting-started/buildfromsource), all of our examples have been updated to reflect the below change.
|
||||
|
||||
Install from scratch by following the documentation, restore your data as described in [Backups](/using-seerr/backups), and then start Seerr. No additional steps are required.
|
||||
|
||||
## Kubernetes
|
||||
Refer to [Seerr Kubernetes Documentation](/getting-started/kubernetes), all of our examples have been updated to reflect the below change.
|
||||
|
||||
@@ -166,3 +198,83 @@ Summary of changes :
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Third-party installation methods
|
||||
### Nix
|
||||
|
||||
Waiting for https://github.com/NixOS/nixpkgs/pull/450096 and https://github.com/NixOS/nixpkgs/pull/450093
|
||||
|
||||
### AUR
|
||||
|
||||
See https://aur.archlinux.org/packages/seerr
|
||||
|
||||
### TrueNAS
|
||||
|
||||
Waiting for https://github.com/truenas/apps/issues/3374
|
||||
|
||||
### Unraid
|
||||
|
||||
Refer to [Seerr Unraid Documentation](/getting-started/third-parties/unraid), all of our examples have been updated to reflect the below change.
|
||||
|
||||
Seerr will automatically migrate your existing Overseerr or Jellyseerr data on first startup. No manual database migration is needed.
|
||||
|
||||
1. Stop and remove the old Overseerr (or Jellyseerr) container from the Unraid **Docker** tab. Click the container icon, then **Stop**, then **Remove**. **⚠️ Do not delete the appdata folder ⚠️**
|
||||
|
||||
2. Back up your existing appdata folder:
|
||||
```bash
|
||||
cp -a /mnt/user/appdata/overseerr /mnt/user/appdata/overseerr-backup
|
||||
```
|
||||
|
||||
3. Fix config folder permissions — Seerr runs as the `node` user (UID 1000) instead of root:
|
||||
```bash
|
||||
chown -R 1000:1000 /mnt/user/appdata/overseerr
|
||||
```
|
||||
For Jellyseerr users, replace `overseerr` with `jellyseerr` in the path above.
|
||||
|
||||
4. Add a new container in the Unraid **Docker** tab. Click **Add Container** and fill in the following:
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| **Name** | `seerr` |
|
||||
| **Repository** | `ghcr.io/seerr-team/seerr:latest` |
|
||||
| **Registry URL** (optional) | `https://ghcr.io` |
|
||||
| **Icon URL** | `https://raw.githubusercontent.com/seerr-team/seerr/develop/public/android-chrome-512x512.png` |
|
||||
| **WebUI** | `http://[IP]:[PORT:5055]` |
|
||||
| **Extra Parameters** | `--init` |
|
||||
| **Network Type** | `bridge` |
|
||||
| **Privileged** | `Off` |
|
||||
|
||||
Then click **Add another Path, Port, Variable** to add:
|
||||
|
||||
**Port:**
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Container Port | `5055` |
|
||||
| Host Port | `5055` |
|
||||
| Connection Type | `TCP` |
|
||||
|
||||
**Path** — point this to your existing config folder:
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Container Path | `/app/config` |
|
||||
| Host Path | `/mnt/user/appdata/overseerr` |
|
||||
|
||||
For Jellyseerr users, use `/mnt/user/appdata/jellyseerr`.
|
||||
|
||||
**Variable:**
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Key | `TZ` |
|
||||
| Value | Your [TZ database name](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) (e.g., `America/New_York`) |
|
||||
|
||||
**Variable (optional):**
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Key | `LOG_LEVEL` |
|
||||
| Value | `info` |
|
||||
|
||||
5. Click **Apply** to start the container. Check the container logs to confirm the automatic migration completed successfully.
|
||||
|
||||
:::tip
|
||||
If you are using a reverse proxy (such as SWAG or Nginx Proxy Manager), update your proxy configuration to point to the new container name `seerr`. The default port remains `5055`.
|
||||
:::
|
||||
@@ -174,4 +174,36 @@ This can happen if you have a new installation of Jellyfin/Emby or if you have c
|
||||
|
||||
This process should restore your admin privileges while preserving your settings.
|
||||
|
||||
## Failed to enable web push notifications
|
||||
|
||||
### Option 1: You are using Pi-hole
|
||||
|
||||
When using Pi-hole, you need to whitelist the proper domains in order for the queries to not be intercepted and blocked by Pi-hole.
|
||||
If you are using a chromium based browser (eg: Chrome, Brave, Edge...), the domain you need to whitelist is `fcm.googleapis.com`
|
||||
If you are using Firefox, the domain you need to whitelist is `push.services.mozilla.com`
|
||||
|
||||
1. Log into your Pi-hole through the admin interface, then click on Domains situated under GROUP MANAGEMENT.
|
||||
2. Add the domain corresponding to your browser in the `Domain to be added` field and then click on Add to allowed domains.
|
||||
3. Now in order for those changes to be used you need to flush your current dns cache.
|
||||
4. You can do so by using this command line in your Pi-hole terminal:
|
||||
```bash
|
||||
pihole restartdns
|
||||
```
|
||||
If this command fails (which is unlikely), use this equivalent:
|
||||
```bash
|
||||
pihole -f && pihole restartdns
|
||||
```
|
||||
5. Then restart your Seerr instance and try to enable the web push notifications again.
|
||||
|
||||
|
||||
### Option 2: You are using Brave browser
|
||||
|
||||
Brave is a "De-Googled" browser. So by default or if you refused a prompt in the past, it cuts the access to the FCM (Firebase Cloud Messaging) service, which is mandatory for the web push notifications on Chromium based browsers.
|
||||
|
||||
1. Open Brave and paste this address in the url bar: `brave://settings/privacy`
|
||||
2. Look for the option: "Use Google services for push messaging"
|
||||
3. Activate this option
|
||||
4. Relaunch Brave completely
|
||||
5. You should now see the notifications prompt appearing instead of an error message.
|
||||
|
||||
If you still encounter issues, please reach out on our support channels.
|
||||
|
||||
@@ -13,7 +13,7 @@ These settings are stored in the `settings.json` file located in the Seerr data
|
||||
|
||||
## User Data
|
||||
|
||||
Apart from the settings, all other data—including user accounts, media requests, blacklist etc. are stored in the database (either SQLite or PostgreSQL).
|
||||
Apart from the settings, all other data—including user accounts, media requests, blocklist etc. are stored in the database (either SQLite or PostgreSQL).
|
||||
|
||||
# Backup
|
||||
|
||||
|
||||
@@ -6,18 +6,22 @@ sidebar_position: 2
|
||||
|
||||
# Web Push
|
||||
|
||||
The web push notification agent enables you and your users to receive Seerr notifications in a supported browser.
|
||||
|
||||
This notification agent does not require any configuration, but is not enabled in Seerr
|
||||
|
||||
:::warning
|
||||
Web push notifications require a secure connection to your Seerr instance. Refer to the [Reverse Proxy](/extending-seerr/reverse-proxy) documentation for more information.
|
||||
:::
|
||||
|
||||
To set up web push notifications, simply enable the agent in **Settings → Notifications → Web Push**. You and your users will then be prompted to allow notifications in your web browser.
|
||||
The web push notification agent enables you and your users to receive Seerr notifications in a supported browser. This offers a native notification experience without the need to install an app.
|
||||
|
||||
Users can opt out of these notifications, or customize the notification types they would like to subscribe to, in their user settings.
|
||||
This notification agent does not require any configuration, but is not enabled by default in Seerr.
|
||||
|
||||
:::info
|
||||
Web push notifications offer a native notification experience without the need to install an app.
|
||||
To set up web push notifications, simply enable the agent in **Settings → Notifications → Web Push**.
|
||||
|
||||
You and your users have the option to enable web push notifications by going to your **User Profile → Edit Settings → Notifications → Web Push → Enable web push**. Here you can also customize the notifications you'd like to receive.
|
||||
|
||||
:::info[Mobile Users]
|
||||
For Web Push notifications to work on mobile you need to add Seerr to your home screen as progressive web app (PWA).
|
||||
:::
|
||||
|
||||
:::info[iOS Users]
|
||||
On iOS you may need to enable the Safari notifications feature flag by going to **Settings → Safari → Advanced → Feature Flags** and enabling "Notifications".
|
||||
:::
|
||||
|
||||
@@ -62,13 +62,13 @@ Set the default display language for Seerr. Users can override this setting in t
|
||||
|
||||
These settings filter content shown on the "Discover" home page based on regional availability and original language, respectively. The Streaming Region filters the available streaming providers on the media page. Users can override these global settings by configuring these same options in their user settings.
|
||||
|
||||
## Blacklist Content with Tags and Limit Content Blacklisted per Tag
|
||||
## Blocklist Content with Tags and Limit Content Blocklisted per Tag
|
||||
|
||||
These settings blacklist any TV shows or movies that have one of the entered tags. The "Process Blacklisted Tags" job adds entries to the blacklist based on the configured blacklisted tags. If a blacklisted tag is removed, any media blacklisted under that tag will be removed from the blacklist when the "Process Blacklisted Tags" job runs.
|
||||
These settings blocklist any TV shows or movies that have one of the entered tags. The "Process Blocklisted Tags" job adds entries to the blocklist based on the configured blocklisted tags. If a blocklisted tag is removed, any media blocklisted under that tag will be removed from the blocklist when the "Process Blocklisted Tags" job runs.
|
||||
|
||||
The limit setting determines how many pages per tag the job will process, with each page containing 20 entries. The job cycles through all 16 available discovery sort options, querying the defined number of pages to blacklist media that is most likely to appear at the top of each sort. Higher limits will create a more accurate blacklist, but will require more storage.
|
||||
The limit setting determines how many pages per tag the job will process, with each page containing 20 entries. The job cycles through all 16 available discovery sort options, querying the defined number of pages to blocklist media that is most likely to appear at the top of each sort. Higher limits will create a more accurate blocklist, but will require more storage.
|
||||
|
||||
Blacklisted tags are disabled until at least one tag is entered. These settings cannot be overridden in user settings.
|
||||
Blocklisted tags are disabled until at least one tag is entered. These settings cannot be overridden in user settings.
|
||||
|
||||
## Hide Available Media
|
||||
|
||||
@@ -78,9 +78,9 @@ Available media will still appear in search results, however, so it is possible
|
||||
|
||||
This setting is **disabled** by default.
|
||||
|
||||
## Hide Blacklisted Items
|
||||
## Hide Blocklisted Items
|
||||
|
||||
When enabled, media that has been blacklisted will not appear on the "Discover" home page, for all administrators. This can be useful to hide content that you don't want to see, such as content with specific tags or content that has been manually blacklisted when you have the "Manage Blacklist" permission.
|
||||
When enabled, media that has been blocklisted will not appear on the "Discover" home page, for all administrators. This can be useful to hide content that you don't want to see, such as content with specific tags or content that has been manually blocklisted when you have the "Manage Blocklist" permission.
|
||||
|
||||
This setting is **disabled** by default.
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ Seerr docs will be available at [docs.seerr.dev](https://docs.seerr.dev).
|
||||
### Installation
|
||||
|
||||
```
|
||||
$ pnpm
|
||||
$ pnpm install
|
||||
```
|
||||
|
||||
### Local Development
|
||||
|
||||
@@ -4,7 +4,7 @@ description: The official Seerr blog for release notes, technical updates, and c
|
||||
slug: welcome
|
||||
authors: [fallenbagel, gauthier-th]
|
||||
tags: [announcement, seerr, blog]
|
||||
image: https://raw.githubusercontent.com/seerr-team/seerr/refs/heads/develop/gen-docs/static/img/logo.svg
|
||||
image: https://raw.githubusercontent.com/seerr-team/seerr/refs/heads/develop/gen-docs/static/img/logo_full.svg
|
||||
hide_table_of_contents: false
|
||||
---
|
||||
|
||||
|
||||
BIN
gen-docs/blog/2026-02-10/dns-cache.png
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
gen-docs/blog/2026-02-10/metadata-providers.png
Normal file
|
After Width: | Height: | Size: 166 KiB |
127
gen-docs/blog/2026-02-10/seerr-release.md
Normal file
@@ -0,0 +1,127 @@
|
||||
---
|
||||
title: "Seerr Release: Unifying Overseerr and Jellyseerr"
|
||||
description: "Overseerr and Jellyseerr are merging into a unified project: Seerr"
|
||||
slug: seerr-release
|
||||
authors: [seerr-team]
|
||||
image: https://raw.githubusercontent.com/seerr-team/seerr/refs/heads/develop/gen-docs/static/img/logo_full.svg
|
||||
hide_table_of_contents: false
|
||||
---
|
||||
|
||||
We're excited to announce a major update: the Jellyseerr and Overseerr teams are officially merging into a single team called **Seerr**. This unification marks an important step forward as we bring our efforts together under one banner.
|
||||
|
||||
For users, this means one shared codebase combining all existing Overseerr functionalities with the latest Jellyseerr features, along with Jellyfin and Emby support, allowing us to deliver updates more efficiently and keep the project moving forward.
|
||||
|
||||
Please check how to migrate to Seerr in our [migration guide](https://docs.seerr.dev/migration-guide) and stay tuned for more updates on the project!
|
||||
|
||||
<!--truncate-->
|
||||
|
||||
## What's new in Seerr for Overseerr users
|
||||
|
||||
Seerr brings several features that were previously available in Jellyseerr but missing from Overseerr. These additions improve flexibility, performance, and overall control for admins and power users:
|
||||
|
||||
* **Alternative media solution:** Added support for Jellyfin and Emby in addition to the existing Plex integration.
|
||||
* **PostgreSQL support**: In addition to SQLite, you can now opt in to using a PostgreSQL database.
|
||||
* **Blocklist for movies, series, and tags**: Allows permitted users to hide movies, series, or tags from regular users.
|
||||
* **Override rules**: Adjust default request settings based on conditions such as user, tag, or other criteria.
|
||||
* **TVDB metadata**: Option to use TheTVDB metadata for series (as in Sonarr) instead of TMDB.
|
||||
* **DNS caching**: Reduces lookup times and external requests, especially useful when using systems like Pi-Hole/Adguard Home.
|
||||
* **Helm chart included**: Enables easier installation and maintenance in Kubernetes environments.
|
||||
* **ntfy.sh notifications**: Support for sending notifications via ntfy.sh.
|
||||
* **Disable special seasons:** Adds a setting to prevent special seasons from being shown or requested.
|
||||
* **New languages**: Turkish and Basque
|
||||
|
||||
## What's new since the previous Jellyseerr release
|
||||
|
||||
This release also brings several important improvements and long-requested features, including **TheTVDB metadata support**, **DNS caching**, and **dynamic webhook placeholders**, along with a few quality-of-life improvements for developers and users alike.
|
||||
|
||||
### PNPM v10 Upgrade
|
||||
|
||||
We're updating Seerr to **PNPM v10** to keep up-to-date development tools. If you are building Seerr from source or if you contribute to Seerr, you'll need to **update your local PNPM installation** before working on the project.
|
||||
|
||||
This doesn't concern you if you're using Docker.
|
||||
|
||||
To update, run the following command:
|
||||
`pnpm self-update`
|
||||
|
||||
After updating, verify your version with:
|
||||
`pnpm -v`
|
||||
|
||||
You should see version **10.x.x**.
|
||||
|
||||
### TVDB Metadata Provider (Experimental)
|
||||
|
||||
We're excited to introduce support for **TheTVDB** as a new metadata provider!
|
||||
Previously, Seerr relied solely on **TMDB** for movie and TV show information, which sometimes led to discrepancies in season and episode numbering when working with **Sonarr**, since Sonarr uses **TheTVDB** as its metadata source.
|
||||
|
||||
With this new integration, Seerr can now use **the same data source as Sonarr** for series and anime, ensuring consistent and accurate season and episode information across both platforms.
|
||||
|
||||
You can try this new experimental feature in the new “Metadata Providers” tab of the settings page:
|
||||
|
||||

|
||||
|
||||
### DNS Caching (Experimental)
|
||||
|
||||
By default, Node.js doesn't cache any DNS requests. Our DNS cache manager addresses the problems caused by extremely high DNS query rates, particularly for large Jellyfin libraries as each HTTP request was also resulting in another DNS request. Therefore, by caching these DNS lookups, **Seerr will now reduce stress on DNS servers** and avoid rate-limiting or blocks encountered with services like **Pi-Hole**/**Adguard Home**.
|
||||
|
||||
We will post another blog post soon on all the issues we encountered with DNS caching in Node.js.
|
||||
|
||||
You can enable this by checking the “DNS Cache” setting in the network tabs of the Seerr settings:
|
||||
|
||||

|
||||
|
||||
### AniDB for Jellyfin Libraries
|
||||
|
||||
This new version also brings additional metadata to Jellyfin-managed collections. When there's no provider ID from TMDB or TVDB, Seerr will automatically **fall back on AniDB**, expanding coverage for lesser-known or region-specific anime.
|
||||
|
||||
### Dynamic Placeholders in Webhook URLs
|
||||
|
||||
Webhook notifications are now more powerful and adaptable with **dynamic placeholder support in webhook URLs**. This allows Seerr to automatically replace placeholders in the webhook URL with real values at runtime.
|
||||
|
||||
For example, you can include the requester's username directly in your webhook URL to better integrate with third-party services or user-specific endpoints.
|
||||
|
||||
This feature can be enabled from the **Notifications** settings page, where available placeholders are listed for reference. It's currently marked as **experimental**, and we welcome community feedback to help refine and expand support for additional placeholders in future releases.
|
||||
|
||||
### Optional Images in Notifications
|
||||
|
||||
Another small feature: **images in notifications are now optional** (but still enabled by default). Previous versions always included images in notifications, which could lead to broken links or failed requests if images were missing or unavailable.
|
||||
|
||||
### Security improvement
|
||||
|
||||
Some outdated dependencies have been updated (some work is still in progress). Helm charts and containers are now cryptographically signed and can be verified and enforced client-side. Containers now run as rootless. Workflows have been completely reworked to minimize third-party actions. Permissions have been strengthened, and actions are now pinned to specific hashes for better traceability. The release process has been updated to remove many outdated and plugin dependencies, replacing them with more standard industry solutions.
|
||||
|
||||
:::important
|
||||
## Note for PostgreSQL users (optional)
|
||||
|
||||
If you're migrating Postgres from version 17 to 18 in Docker, note that the data mount point has changed. Instead of using `/var/lib/postgresql/data`, the correct mount path is now `/var/lib/postgresql`. This update of the mount point is required to ensure the container functions correctly after the upgrade.
|
||||
:::
|
||||
|
||||
## Conclusion
|
||||
|
||||
Seerr is built and maintained by dedicated volunteer contributors, whose skills and commitment make it all possible. Many thanks to everyone who contributed to this version:
|
||||
|
||||
* [0xsysr3ll](https://github.com/0xSysR3ll)
|
||||
* [ale183](https://github.com/ale183)
|
||||
* [Brandon Cohen](https://github.com/OwsleyJr)
|
||||
* [Disparate2761](https://github.com/Disparate2761)
|
||||
* [fallenbagel](https://github.com/fallenbagel)
|
||||
* [Gauthier](https://github.com/gauthier-th)
|
||||
* [Gauvain](https://github.com/Gauvino)
|
||||
* [Georgy](https://github.com/tarasverq)
|
||||
* [Ishan Jain](https://github.com/ishanjain28)
|
||||
* [James Kruger](https://github.com/theGunner295)
|
||||
* [Joe Harrison](https://github.com/sudo-kraken)
|
||||
* [J. Winters-Brown](https://github.com/ofgrenudo)
|
||||
* [Ludovic Ortega](https://github.com/M0NsTeRRR)
|
||||
* [RolliePollie18](https://github.com/RolliePollie18)
|
||||
* [Ryan Cohen](https://github.com/sct)
|
||||
* [salty](https://github.com/saltydk)
|
||||
* [samohtxotom](https://github.com/samohtxotom)
|
||||
* [Sergii Bogomolov](https://github.com/sbogomolov)
|
||||
* [Someone](https://github.com/InterN0te)
|
||||
* [TacoCake](https://github.com/TacoCake)
|
||||
* [Terry Sposato](https://github.com/tsposato)
|
||||
* [TheCatLady](https://github.com/TheCatLady)
|
||||
* [Thibaut Noah](https://github.com/tirrorex)
|
||||
* [THOMAS B](https://github.com/TOomaAh)
|
||||
|
||||
Keep an eye on our blog for in-depth looks at our work and upcoming releases!
|
||||
@@ -1,8 +1,8 @@
|
||||
fallenbagel:
|
||||
name: Fallenbagel
|
||||
page: true
|
||||
title: Developer & Maintainer of Jellyseerr
|
||||
description: Core Maintainer & Developer of Jellyseerr | Full-Stack Software Engineer | MSc Software Engineering Candidate.
|
||||
title: Developer & Maintainer of Seerr
|
||||
description: Core Maintainer & Developer of Seerr | Full-Stack Software Engineer | MSc Software Engineering Student.
|
||||
url: https://github.com/fallenbagel
|
||||
image_url: https://github.com/fallenbagel.png
|
||||
email: hello@fallenbagel.com
|
||||
@@ -12,10 +12,18 @@ fallenbagel:
|
||||
gauthier-th:
|
||||
name: Gauthier
|
||||
page: true
|
||||
title: Co-Developer & Co-Maintainer of Jellyseerr
|
||||
description: Co-Maintainer & Developer of Jellyseerr | PhD Student in AI at ICB, Dijon
|
||||
title: Developer & Maintainer of Seerr
|
||||
description: Core Maintainer & Developer of Seerr | PhD Student in AI at ICB, Dijon
|
||||
url: https://gauthierth.fr
|
||||
image_url: https://github.com/gauthier-th.png
|
||||
email: mail@gauthierth.fr
|
||||
socials:
|
||||
github: gauthier-th
|
||||
|
||||
seerr-team:
|
||||
name: Seerr Team
|
||||
title: The team behind Seerr, formerly known as the Jellyseerr and Overseerr teams.
|
||||
url: https://seerr.dev
|
||||
image_url: https://github.com/seerr-team.png
|
||||
socials:
|
||||
github: seerr-team
|
||||
|
||||
@@ -64,7 +64,7 @@ const config: Config = {
|
||||
navbar: {
|
||||
logo: {
|
||||
alt: 'Seerr',
|
||||
src: 'img/logo.svg',
|
||||
src: 'img/logo_full.svg',
|
||||
},
|
||||
items: [
|
||||
{
|
||||
@@ -72,6 +72,11 @@ const config: Config = {
|
||||
label: 'Blog',
|
||||
position: 'right',
|
||||
},
|
||||
{
|
||||
href: 'https://discord.gg/seerr',
|
||||
label: 'Discord',
|
||||
position: 'right',
|
||||
},
|
||||
{
|
||||
href: 'https://github.com/seerr-team/seerr',
|
||||
label: 'GitHub',
|
||||
|
||||
269
gen-docs/pnpm-lock.yaml
generated
@@ -34,7 +34,7 @@ importers:
|
||||
version: 18.3.1(react@18.3.1)
|
||||
tailwindcss:
|
||||
specifier: ^3.4.4
|
||||
version: 3.4.17
|
||||
version: 3.4.19(yaml@2.8.1)
|
||||
devDependencies:
|
||||
'@docusaurus/module-type-aliases':
|
||||
specifier: 3.9.1
|
||||
@@ -708,8 +708,8 @@ packages:
|
||||
resolution: {integrity: sha512-h7iEYiW4HebClDEhtvFObtPmIvrd1SSfpI9EhOeKk4CtIK/ngBWFpuhCzhdmRKtg71ylcue+9I6dv54XYO1epQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/runtime@7.28.4':
|
||||
resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==}
|
||||
'@babel/runtime@7.28.6':
|
||||
resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/template@7.27.2':
|
||||
@@ -1224,10 +1224,6 @@ packages:
|
||||
'@hapi/topo@5.1.0':
|
||||
resolution: {integrity: sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==}
|
||||
|
||||
'@isaacs/cliui@8.0.2':
|
||||
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
'@jest/schemas@29.6.3':
|
||||
resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==}
|
||||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||
@@ -1409,10 +1405,6 @@ packages:
|
||||
resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==}
|
||||
engines: {node: '>=8.0.0'}
|
||||
|
||||
'@pkgjs/parseargs@0.11.0':
|
||||
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
'@pnpm/config.env-replace@1.1.0':
|
||||
resolution: {integrity: sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==}
|
||||
engines: {node: '>=12.22.0'}
|
||||
@@ -1943,9 +1935,6 @@ packages:
|
||||
brace-expansion@1.1.12:
|
||||
resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==}
|
||||
|
||||
brace-expansion@2.0.2:
|
||||
resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==}
|
||||
|
||||
braces@3.0.3:
|
||||
resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -2684,8 +2673,8 @@ packages:
|
||||
fast-uri@3.1.0:
|
||||
resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==}
|
||||
|
||||
fastq@1.19.1:
|
||||
resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==}
|
||||
fastq@1.20.1:
|
||||
resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==}
|
||||
|
||||
fault@2.0.1:
|
||||
resolution: {integrity: sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==}
|
||||
@@ -2694,6 +2683,15 @@ packages:
|
||||
resolution: {integrity: sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==}
|
||||
engines: {node: '>=0.8.0'}
|
||||
|
||||
fdir@6.5.0:
|
||||
resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
peerDependencies:
|
||||
picomatch: ^3 || ^4
|
||||
peerDependenciesMeta:
|
||||
picomatch:
|
||||
optional: true
|
||||
|
||||
feed@4.2.2:
|
||||
resolution: {integrity: sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
@@ -2737,10 +2735,6 @@ packages:
|
||||
debug:
|
||||
optional: true
|
||||
|
||||
foreground-child@3.3.1:
|
||||
resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
form-data-encoder@2.1.4:
|
||||
resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==}
|
||||
engines: {node: '>= 14.17'}
|
||||
@@ -2815,10 +2809,6 @@ packages:
|
||||
glob-to-regexp@0.4.1:
|
||||
resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==}
|
||||
|
||||
glob@10.4.5:
|
||||
resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==}
|
||||
hasBin: true
|
||||
|
||||
global-dirs@3.0.1:
|
||||
resolution: {integrity: sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -3202,9 +3192,6 @@ packages:
|
||||
resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
jackspeak@3.4.3:
|
||||
resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
|
||||
|
||||
jest-util@29.7.0:
|
||||
resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==}
|
||||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||
@@ -3333,9 +3320,6 @@ packages:
|
||||
resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==}
|
||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
|
||||
lru-cache@10.4.3:
|
||||
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
|
||||
|
||||
lru-cache@5.1.1:
|
||||
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
|
||||
|
||||
@@ -3628,17 +3612,9 @@ packages:
|
||||
minimatch@3.1.2:
|
||||
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
|
||||
|
||||
minimatch@9.0.5:
|
||||
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
|
||||
minimist@1.2.8:
|
||||
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
|
||||
|
||||
minipass@7.1.2:
|
||||
resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
|
||||
mrmime@2.0.1:
|
||||
resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -3793,9 +3769,6 @@ packages:
|
||||
resolution: {integrity: sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
package-json-from-dist@1.0.1:
|
||||
resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
|
||||
|
||||
package-json@8.1.1:
|
||||
resolution: {integrity: sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==}
|
||||
engines: {node: '>=14.16'}
|
||||
@@ -3847,10 +3820,6 @@ packages:
|
||||
path-parse@1.0.7:
|
||||
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
|
||||
|
||||
path-scurry@1.11.1:
|
||||
resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
|
||||
engines: {node: '>=16 || 14 >=14.18'}
|
||||
|
||||
path-to-regexp@0.1.12:
|
||||
resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==}
|
||||
|
||||
@@ -3871,6 +3840,10 @@ packages:
|
||||
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
|
||||
engines: {node: '>=8.6'}
|
||||
|
||||
picomatch@4.0.3:
|
||||
resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
pify@2.3.0:
|
||||
resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -4038,16 +4011,22 @@ packages:
|
||||
peerDependencies:
|
||||
postcss: ^8.4
|
||||
|
||||
postcss-load-config@4.0.2:
|
||||
resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==}
|
||||
engines: {node: '>= 14'}
|
||||
postcss-load-config@6.0.1:
|
||||
resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==}
|
||||
engines: {node: '>= 18'}
|
||||
peerDependencies:
|
||||
jiti: '>=1.21.0'
|
||||
postcss: '>=8.0.9'
|
||||
ts-node: '>=9.0.0'
|
||||
tsx: ^4.8.1
|
||||
yaml: ^2.4.2
|
||||
peerDependenciesMeta:
|
||||
jiti:
|
||||
optional: true
|
||||
postcss:
|
||||
optional: true
|
||||
ts-node:
|
||||
tsx:
|
||||
optional: true
|
||||
yaml:
|
||||
optional: true
|
||||
|
||||
postcss-loader@7.3.4:
|
||||
@@ -4269,8 +4248,8 @@ packages:
|
||||
resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
postcss-selector-parser@7.1.0:
|
||||
resolution: {integrity: sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==}
|
||||
postcss-selector-parser@7.1.1:
|
||||
resolution: {integrity: sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
postcss-sort-media-queries@5.2.0:
|
||||
@@ -4541,8 +4520,8 @@ packages:
|
||||
resolve-pathname@3.0.0:
|
||||
resolution: {integrity: sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==}
|
||||
|
||||
resolve@1.22.10:
|
||||
resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==}
|
||||
resolve@1.22.11:
|
||||
resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
hasBin: true
|
||||
|
||||
@@ -4689,10 +4668,6 @@ packages:
|
||||
signal-exit@3.0.7:
|
||||
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
|
||||
|
||||
signal-exit@4.1.0:
|
||||
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
sirv@2.0.4:
|
||||
resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==}
|
||||
engines: {node: '>= 10'}
|
||||
@@ -4827,8 +4802,8 @@ packages:
|
||||
peerDependencies:
|
||||
postcss: ^8.4.31
|
||||
|
||||
sucrase@3.35.0:
|
||||
resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==}
|
||||
sucrase@3.35.1:
|
||||
resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
hasBin: true
|
||||
|
||||
@@ -4857,8 +4832,8 @@ packages:
|
||||
peerDependencies:
|
||||
react: ^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
|
||||
tailwindcss@3.4.17:
|
||||
resolution: {integrity: sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==}
|
||||
tailwindcss@3.4.19:
|
||||
resolution: {integrity: sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
hasBin: true
|
||||
|
||||
@@ -4913,6 +4888,10 @@ packages:
|
||||
tiny-warning@1.0.3:
|
||||
resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==}
|
||||
|
||||
tinyglobby@0.2.15:
|
||||
resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
|
||||
tinypool@1.1.1:
|
||||
resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==}
|
||||
engines: {node: ^18.0.0 || >=20.0.0}
|
||||
@@ -5169,6 +5148,7 @@ packages:
|
||||
whatwg-encoding@3.1.1:
|
||||
resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==}
|
||||
engines: {node: '>=18'}
|
||||
deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation
|
||||
|
||||
whatwg-mimetype@4.0.0:
|
||||
resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==}
|
||||
@@ -5465,7 +5445,7 @@ snapshots:
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
debug: 4.4.3
|
||||
lodash.debounce: 4.0.8
|
||||
resolve: 1.22.10
|
||||
resolve: 1.22.11
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -6118,7 +6098,7 @@ snapshots:
|
||||
dependencies:
|
||||
core-js-pure: 3.45.1
|
||||
|
||||
'@babel/runtime@7.28.4': {}
|
||||
'@babel/runtime@7.28.6': {}
|
||||
|
||||
'@babel/template@7.27.2':
|
||||
dependencies:
|
||||
@@ -6187,9 +6167,9 @@ snapshots:
|
||||
|
||||
'@csstools/postcss-cascade-layers@5.0.2(postcss@8.5.6)':
|
||||
dependencies:
|
||||
'@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.0)
|
||||
'@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.1)
|
||||
postcss: 8.5.6
|
||||
postcss-selector-parser: 7.1.0
|
||||
postcss-selector-parser: 7.1.1
|
||||
|
||||
'@csstools/postcss-color-function-display-p3-linear@1.0.1(postcss@8.5.6)':
|
||||
dependencies:
|
||||
@@ -6295,9 +6275,9 @@ snapshots:
|
||||
|
||||
'@csstools/postcss-is-pseudo-class@5.0.3(postcss@8.5.6)':
|
||||
dependencies:
|
||||
'@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.0)
|
||||
'@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.1)
|
||||
postcss: 8.5.6
|
||||
postcss-selector-parser: 7.1.0
|
||||
postcss-selector-parser: 7.1.1
|
||||
|
||||
'@csstools/postcss-light-dark-function@2.0.11(postcss@8.5.6)':
|
||||
dependencies:
|
||||
@@ -6389,7 +6369,7 @@ snapshots:
|
||||
'@csstools/postcss-scope-pseudo-class@4.0.1(postcss@8.5.6)':
|
||||
dependencies:
|
||||
postcss: 8.5.6
|
||||
postcss-selector-parser: 7.1.0
|
||||
postcss-selector-parser: 7.1.1
|
||||
|
||||
'@csstools/postcss-sign-functions@1.1.4(postcss@8.5.6)':
|
||||
dependencies:
|
||||
@@ -6422,13 +6402,13 @@ snapshots:
|
||||
dependencies:
|
||||
postcss: 8.5.6
|
||||
|
||||
'@csstools/selector-resolve-nested@3.1.0(postcss-selector-parser@7.1.0)':
|
||||
'@csstools/selector-resolve-nested@3.1.0(postcss-selector-parser@7.1.1)':
|
||||
dependencies:
|
||||
postcss-selector-parser: 7.1.0
|
||||
postcss-selector-parser: 7.1.1
|
||||
|
||||
'@csstools/selector-specificity@5.0.0(postcss-selector-parser@7.1.0)':
|
||||
'@csstools/selector-specificity@5.0.0(postcss-selector-parser@7.1.1)':
|
||||
dependencies:
|
||||
postcss-selector-parser: 7.1.0
|
||||
postcss-selector-parser: 7.1.1
|
||||
|
||||
'@csstools/utilities@2.0.0(postcss@8.5.6)':
|
||||
dependencies:
|
||||
@@ -6464,7 +6444,7 @@ snapshots:
|
||||
'@babel/preset-env': 7.28.3(@babel/core@7.28.4)
|
||||
'@babel/preset-react': 7.27.1(@babel/core@7.28.4)
|
||||
'@babel/preset-typescript': 7.27.1(@babel/core@7.28.4)
|
||||
'@babel/runtime': 7.28.4
|
||||
'@babel/runtime': 7.28.6
|
||||
'@babel/runtime-corejs3': 7.28.4
|
||||
'@babel/traverse': 7.28.4
|
||||
'@docusaurus/logger': 3.9.1
|
||||
@@ -7272,15 +7252,6 @@ snapshots:
|
||||
dependencies:
|
||||
'@hapi/hoek': 9.3.0
|
||||
|
||||
'@isaacs/cliui@8.0.2':
|
||||
dependencies:
|
||||
string-width: 5.1.2
|
||||
string-width-cjs: string-width@4.2.3
|
||||
strip-ansi: 7.1.2
|
||||
strip-ansi-cjs: strip-ansi@6.0.1
|
||||
wrap-ansi: 8.1.0
|
||||
wrap-ansi-cjs: wrap-ansi@7.0.0
|
||||
|
||||
'@jest/schemas@29.6.3':
|
||||
dependencies:
|
||||
'@sinclair/typebox': 0.27.8
|
||||
@@ -7469,13 +7440,10 @@ snapshots:
|
||||
'@nodelib/fs.walk@1.2.8':
|
||||
dependencies:
|
||||
'@nodelib/fs.scandir': 2.1.5
|
||||
fastq: 1.19.1
|
||||
fastq: 1.20.1
|
||||
|
||||
'@opentelemetry/api@1.9.0': {}
|
||||
|
||||
'@pkgjs/parseargs@0.11.0':
|
||||
optional: true
|
||||
|
||||
'@pnpm/config.env-replace@1.1.0': {}
|
||||
|
||||
'@pnpm/network.ca-file@1.0.2':
|
||||
@@ -7506,7 +7474,7 @@ snapshots:
|
||||
|
||||
'@slorber/react-helmet-async@1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.28.4
|
||||
'@babel/runtime': 7.28.6
|
||||
invariant: 2.2.4
|
||||
prop-types: 15.8.1
|
||||
react: 18.3.1
|
||||
@@ -7759,7 +7727,7 @@ snapshots:
|
||||
|
||||
'@types/sax@1.2.7':
|
||||
dependencies:
|
||||
'@types/node': 17.0.45
|
||||
'@types/node': 24.5.2
|
||||
|
||||
'@types/send@0.17.5':
|
||||
dependencies:
|
||||
@@ -8108,10 +8076,6 @@ snapshots:
|
||||
balanced-match: 1.0.2
|
||||
concat-map: 0.0.1
|
||||
|
||||
brace-expansion@2.0.2:
|
||||
dependencies:
|
||||
balanced-match: 1.0.2
|
||||
|
||||
braces@3.0.3:
|
||||
dependencies:
|
||||
fill-range: 7.1.1
|
||||
@@ -8398,7 +8362,7 @@ snapshots:
|
||||
css-blank-pseudo@7.0.1(postcss@8.5.6):
|
||||
dependencies:
|
||||
postcss: 8.5.6
|
||||
postcss-selector-parser: 7.1.0
|
||||
postcss-selector-parser: 7.1.1
|
||||
|
||||
css-declaration-sorter@7.3.0(postcss@8.5.6):
|
||||
dependencies:
|
||||
@@ -8406,9 +8370,9 @@ snapshots:
|
||||
|
||||
css-has-pseudo@7.0.3(postcss@8.5.6):
|
||||
dependencies:
|
||||
'@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.0)
|
||||
'@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.1)
|
||||
postcss: 8.5.6
|
||||
postcss-selector-parser: 7.1.0
|
||||
postcss-selector-parser: 7.1.1
|
||||
postcss-value-parser: 4.2.0
|
||||
|
||||
css-loader@6.11.0(webpack@5.101.3):
|
||||
@@ -8881,7 +8845,7 @@ snapshots:
|
||||
|
||||
fast-uri@3.1.0: {}
|
||||
|
||||
fastq@1.19.1:
|
||||
fastq@1.20.1:
|
||||
dependencies:
|
||||
reusify: 1.1.0
|
||||
|
||||
@@ -8893,6 +8857,10 @@ snapshots:
|
||||
dependencies:
|
||||
websocket-driver: 0.7.4
|
||||
|
||||
fdir@6.5.0(picomatch@4.0.3):
|
||||
optionalDependencies:
|
||||
picomatch: 4.0.3
|
||||
|
||||
feed@4.2.2:
|
||||
dependencies:
|
||||
xml-js: 1.6.11
|
||||
@@ -8939,11 +8907,6 @@ snapshots:
|
||||
optionalDependencies:
|
||||
debug: 4.4.3
|
||||
|
||||
foreground-child@3.3.1:
|
||||
dependencies:
|
||||
cross-spawn: 7.0.6
|
||||
signal-exit: 4.1.0
|
||||
|
||||
form-data-encoder@2.1.4: {}
|
||||
|
||||
format@0.2.2: {}
|
||||
@@ -9011,15 +8974,6 @@ snapshots:
|
||||
|
||||
glob-to-regexp@0.4.1: {}
|
||||
|
||||
glob@10.4.5:
|
||||
dependencies:
|
||||
foreground-child: 3.3.1
|
||||
jackspeak: 3.4.3
|
||||
minimatch: 9.0.5
|
||||
minipass: 7.1.2
|
||||
package-json-from-dist: 1.0.1
|
||||
path-scurry: 1.11.1
|
||||
|
||||
global-dirs@3.0.1:
|
||||
dependencies:
|
||||
ini: 2.0.0
|
||||
@@ -9186,7 +9140,7 @@ snapshots:
|
||||
|
||||
history@4.10.1:
|
||||
dependencies:
|
||||
'@babel/runtime': 7.28.4
|
||||
'@babel/runtime': 7.28.6
|
||||
loose-envify: 1.4.0
|
||||
resolve-pathname: 3.0.0
|
||||
tiny-invariant: 1.3.3
|
||||
@@ -9452,12 +9406,6 @@ snapshots:
|
||||
|
||||
isobject@3.0.1: {}
|
||||
|
||||
jackspeak@3.4.3:
|
||||
dependencies:
|
||||
'@isaacs/cliui': 8.0.2
|
||||
optionalDependencies:
|
||||
'@pkgjs/parseargs': 0.11.0
|
||||
|
||||
jest-util@29.7.0:
|
||||
dependencies:
|
||||
'@jest/types': 29.6.3
|
||||
@@ -9580,8 +9528,6 @@ snapshots:
|
||||
|
||||
lowercase-keys@3.0.0: {}
|
||||
|
||||
lru-cache@10.4.3: {}
|
||||
|
||||
lru-cache@5.1.1:
|
||||
dependencies:
|
||||
yallist: 3.1.1
|
||||
@@ -10153,14 +10099,8 @@ snapshots:
|
||||
dependencies:
|
||||
brace-expansion: 1.1.12
|
||||
|
||||
minimatch@9.0.5:
|
||||
dependencies:
|
||||
brace-expansion: 2.0.2
|
||||
|
||||
minimist@1.2.8: {}
|
||||
|
||||
minipass@7.1.2: {}
|
||||
|
||||
mrmime@2.0.1: {}
|
||||
|
||||
ms@2.0.0: {}
|
||||
@@ -10299,8 +10239,6 @@ snapshots:
|
||||
dependencies:
|
||||
p-finally: 1.0.0
|
||||
|
||||
package-json-from-dist@1.0.1: {}
|
||||
|
||||
package-json@8.1.1:
|
||||
dependencies:
|
||||
got: 12.6.1
|
||||
@@ -10364,11 +10302,6 @@ snapshots:
|
||||
|
||||
path-parse@1.0.7: {}
|
||||
|
||||
path-scurry@1.11.1:
|
||||
dependencies:
|
||||
lru-cache: 10.4.3
|
||||
minipass: 7.1.2
|
||||
|
||||
path-to-regexp@0.1.12: {}
|
||||
|
||||
path-to-regexp@1.9.0:
|
||||
@@ -10383,6 +10316,8 @@ snapshots:
|
||||
|
||||
picomatch@2.3.1: {}
|
||||
|
||||
picomatch@4.0.3: {}
|
||||
|
||||
pify@2.3.0: {}
|
||||
|
||||
pirates@4.0.7: {}
|
||||
@@ -10394,7 +10329,7 @@ snapshots:
|
||||
postcss-attribute-case-insensitive@7.0.1(postcss@8.5.6):
|
||||
dependencies:
|
||||
postcss: 8.5.6
|
||||
postcss-selector-parser: 7.1.0
|
||||
postcss-selector-parser: 7.1.1
|
||||
|
||||
postcss-calc@9.0.1(postcss@8.5.6):
|
||||
dependencies:
|
||||
@@ -10465,12 +10400,12 @@ snapshots:
|
||||
'@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4)
|
||||
'@csstools/css-tokenizer': 3.0.4
|
||||
postcss: 8.5.6
|
||||
postcss-selector-parser: 7.1.0
|
||||
postcss-selector-parser: 7.1.1
|
||||
|
||||
postcss-dir-pseudo-class@9.0.1(postcss@8.5.6):
|
||||
dependencies:
|
||||
postcss: 8.5.6
|
||||
postcss-selector-parser: 7.1.0
|
||||
postcss-selector-parser: 7.1.1
|
||||
|
||||
postcss-discard-comments@6.0.2(postcss@8.5.6):
|
||||
dependencies:
|
||||
@@ -10503,12 +10438,12 @@ snapshots:
|
||||
postcss-focus-visible@10.0.1(postcss@8.5.6):
|
||||
dependencies:
|
||||
postcss: 8.5.6
|
||||
postcss-selector-parser: 7.1.0
|
||||
postcss-selector-parser: 7.1.1
|
||||
|
||||
postcss-focus-within@9.0.1(postcss@8.5.6):
|
||||
dependencies:
|
||||
postcss: 8.5.6
|
||||
postcss-selector-parser: 7.1.0
|
||||
postcss-selector-parser: 7.1.1
|
||||
|
||||
postcss-font-variant@5.0.0(postcss@8.5.6):
|
||||
dependencies:
|
||||
@@ -10529,7 +10464,7 @@ snapshots:
|
||||
postcss: 8.5.6
|
||||
postcss-value-parser: 4.2.0
|
||||
read-cache: 1.0.0
|
||||
resolve: 1.22.10
|
||||
resolve: 1.22.11
|
||||
|
||||
postcss-js@4.1.0(postcss@8.5.6):
|
||||
dependencies:
|
||||
@@ -10545,12 +10480,13 @@ snapshots:
|
||||
'@csstools/utilities': 2.0.0(postcss@8.5.6)
|
||||
postcss: 8.5.6
|
||||
|
||||
postcss-load-config@4.0.2(postcss@8.5.6):
|
||||
postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.6)(yaml@2.8.1):
|
||||
dependencies:
|
||||
lilconfig: 3.1.3
|
||||
yaml: 2.8.1
|
||||
optionalDependencies:
|
||||
jiti: 1.21.7
|
||||
postcss: 8.5.6
|
||||
yaml: 2.8.1
|
||||
|
||||
postcss-loader@7.3.4(postcss@8.5.6)(typescript@5.2.2)(webpack@5.101.3):
|
||||
dependencies:
|
||||
@@ -10619,13 +10555,13 @@ snapshots:
|
||||
dependencies:
|
||||
icss-utils: 5.1.0(postcss@8.5.6)
|
||||
postcss: 8.5.6
|
||||
postcss-selector-parser: 7.1.0
|
||||
postcss-selector-parser: 7.1.1
|
||||
postcss-value-parser: 4.2.0
|
||||
|
||||
postcss-modules-scope@3.2.1(postcss@8.5.6):
|
||||
dependencies:
|
||||
postcss: 8.5.6
|
||||
postcss-selector-parser: 7.1.0
|
||||
postcss-selector-parser: 7.1.1
|
||||
|
||||
postcss-modules-values@4.0.0(postcss@8.5.6):
|
||||
dependencies:
|
||||
@@ -10639,10 +10575,10 @@ snapshots:
|
||||
|
||||
postcss-nesting@13.0.2(postcss@8.5.6):
|
||||
dependencies:
|
||||
'@csstools/selector-resolve-nested': 3.1.0(postcss-selector-parser@7.1.0)
|
||||
'@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.0)
|
||||
'@csstools/selector-resolve-nested': 3.1.0(postcss-selector-parser@7.1.1)
|
||||
'@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.1)
|
||||
postcss: 8.5.6
|
||||
postcss-selector-parser: 7.1.0
|
||||
postcss-selector-parser: 7.1.1
|
||||
|
||||
postcss-normalize-charset@6.0.2(postcss@8.5.6):
|
||||
dependencies:
|
||||
@@ -10787,7 +10723,7 @@ snapshots:
|
||||
postcss-pseudo-class-any-link@10.0.1(postcss@8.5.6):
|
||||
dependencies:
|
||||
postcss: 8.5.6
|
||||
postcss-selector-parser: 7.1.0
|
||||
postcss-selector-parser: 7.1.1
|
||||
|
||||
postcss-reduce-idents@6.0.3(postcss@8.5.6):
|
||||
dependencies:
|
||||
@@ -10812,14 +10748,14 @@ snapshots:
|
||||
postcss-selector-not@8.0.1(postcss@8.5.6):
|
||||
dependencies:
|
||||
postcss: 8.5.6
|
||||
postcss-selector-parser: 7.1.0
|
||||
postcss-selector-parser: 7.1.1
|
||||
|
||||
postcss-selector-parser@6.1.2:
|
||||
dependencies:
|
||||
cssesc: 3.0.0
|
||||
util-deprecate: 1.0.2
|
||||
|
||||
postcss-selector-parser@7.1.0:
|
||||
postcss-selector-parser@7.1.1:
|
||||
dependencies:
|
||||
cssesc: 3.0.0
|
||||
util-deprecate: 1.0.2
|
||||
@@ -10943,19 +10879,19 @@ snapshots:
|
||||
|
||||
react-loadable-ssr-addon-v5-slorber@1.0.1(@docusaurus/react-loadable@6.0.0(react@18.3.1))(webpack@5.101.3):
|
||||
dependencies:
|
||||
'@babel/runtime': 7.28.4
|
||||
'@babel/runtime': 7.28.6
|
||||
react-loadable: '@docusaurus/react-loadable@6.0.0(react@18.3.1)'
|
||||
webpack: 5.101.3
|
||||
|
||||
react-router-config@5.1.1(react-router@5.3.4(react@18.3.1))(react@18.3.1):
|
||||
dependencies:
|
||||
'@babel/runtime': 7.28.4
|
||||
'@babel/runtime': 7.28.6
|
||||
react: 18.3.1
|
||||
react-router: 5.3.4(react@18.3.1)
|
||||
|
||||
react-router-dom@5.3.4(react@18.3.1):
|
||||
dependencies:
|
||||
'@babel/runtime': 7.28.4
|
||||
'@babel/runtime': 7.28.6
|
||||
history: 4.10.1
|
||||
loose-envify: 1.4.0
|
||||
prop-types: 15.8.1
|
||||
@@ -10966,7 +10902,7 @@ snapshots:
|
||||
|
||||
react-router@5.3.4(react@18.3.1):
|
||||
dependencies:
|
||||
'@babel/runtime': 7.28.4
|
||||
'@babel/runtime': 7.28.6
|
||||
history: 4.10.1
|
||||
hoist-non-react-statics: 3.3.2
|
||||
loose-envify: 1.4.0
|
||||
@@ -11168,7 +11104,7 @@ snapshots:
|
||||
|
||||
resolve-pathname@3.0.0: {}
|
||||
|
||||
resolve@1.22.10:
|
||||
resolve@1.22.11:
|
||||
dependencies:
|
||||
is-core-module: 2.16.1
|
||||
path-parse: 1.0.7
|
||||
@@ -11354,8 +11290,6 @@ snapshots:
|
||||
|
||||
signal-exit@3.0.7: {}
|
||||
|
||||
signal-exit@4.1.0: {}
|
||||
|
||||
sirv@2.0.4:
|
||||
dependencies:
|
||||
'@polka/url': 1.0.0-next.29
|
||||
@@ -11497,14 +11431,14 @@ snapshots:
|
||||
postcss: 8.5.6
|
||||
postcss-selector-parser: 6.1.2
|
||||
|
||||
sucrase@3.35.0:
|
||||
sucrase@3.35.1:
|
||||
dependencies:
|
||||
'@jridgewell/gen-mapping': 0.3.13
|
||||
commander: 4.1.1
|
||||
glob: 10.4.5
|
||||
lines-and-columns: 1.2.4
|
||||
mz: 2.7.0
|
||||
pirates: 4.0.7
|
||||
tinyglobby: 0.2.15
|
||||
ts-interface-checker: 0.1.13
|
||||
|
||||
supports-color@7.2.0:
|
||||
@@ -11535,7 +11469,7 @@ snapshots:
|
||||
react: 18.3.1
|
||||
use-sync-external-store: 1.5.0(react@18.3.1)
|
||||
|
||||
tailwindcss@3.4.17:
|
||||
tailwindcss@3.4.19(yaml@2.8.1):
|
||||
dependencies:
|
||||
'@alloc/quick-lru': 5.2.0
|
||||
arg: 5.0.2
|
||||
@@ -11554,13 +11488,14 @@ snapshots:
|
||||
postcss: 8.5.6
|
||||
postcss-import: 15.1.0(postcss@8.5.6)
|
||||
postcss-js: 4.1.0(postcss@8.5.6)
|
||||
postcss-load-config: 4.0.2(postcss@8.5.6)
|
||||
postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.6)(yaml@2.8.1)
|
||||
postcss-nested: 6.2.0(postcss@8.5.6)
|
||||
postcss-selector-parser: 6.1.2
|
||||
resolve: 1.22.10
|
||||
sucrase: 3.35.0
|
||||
resolve: 1.22.11
|
||||
sucrase: 3.35.1
|
||||
transitivePeerDependencies:
|
||||
- ts-node
|
||||
- tsx
|
||||
- yaml
|
||||
|
||||
tapable@2.2.3: {}
|
||||
|
||||
@@ -11600,6 +11535,11 @@ snapshots:
|
||||
|
||||
tiny-warning@1.0.3: {}
|
||||
|
||||
tinyglobby@0.2.15:
|
||||
dependencies:
|
||||
fdir: 6.5.0(picomatch@4.0.3)
|
||||
picomatch: 4.0.3
|
||||
|
||||
tinypool@1.1.1: {}
|
||||
|
||||
to-regex-range@5.0.1:
|
||||
@@ -11965,7 +11905,8 @@ snapshots:
|
||||
|
||||
yallist@3.1.1: {}
|
||||
|
||||
yaml@2.8.1: {}
|
||||
yaml@2.8.1:
|
||||
optional: true
|
||||
|
||||
yocto-queue@1.2.1: {}
|
||||
|
||||
|
||||
@@ -60,12 +60,12 @@
|
||||
|
||||
.table-of-contents__link--active,
|
||||
a:not(
|
||||
.card,
|
||||
.menu__link,
|
||||
.menu__link--sublist,
|
||||
.menu__link--sublist-item,
|
||||
.table-of-contents__link
|
||||
) {
|
||||
.card,
|
||||
.menu__link,
|
||||
.menu__link--sublist,
|
||||
.menu__link--sublist-item,
|
||||
.table-of-contents__link
|
||||
) {
|
||||
/* color: #793ae8; */
|
||||
color: #6366f1;
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 25 KiB |
21
gen-docs/static/img/logo_full.svg
Normal file
@@ -0,0 +1,21 @@
|
||||
<svg width="322" height="96" viewBox="0 0 322 96" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="52" cy="52" r="28" fill="#131928"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M48 96C74.5097 96 96 74.5097 96 48C96 21.4903 74.5097 0 48 0C21.4903 0 0 21.4903 0 48C0 74.5097 21.4903 96 48 96ZM80.0001 52C80.0001 67.464 67.4641 80 52.0001 80C36.5361 80 24.0001 67.464 24.0001 52C24.0001 49.1303 24.4318 46.3615 25.2338 43.7548C27.4288 48.6165 32.3194 52 38.0001 52C45.7321 52 52.0001 45.732 52.0001 38C52.0001 32.3192 48.6166 27.4287 43.755 25.2337C46.3616 24.4317 49.1304 24 52.0001 24C67.4641 24 80.0001 36.536 80.0001 52Z" fill="url(#paint0_linear_311_158)"/>
|
||||
<path opacity="0.2" fill-rule="evenodd" clip-rule="evenodd" d="M80.0002 52C80.0002 67.464 67.4642 80 52.0002 80C36.864 80 24.5329 67.9897 24.017 52.9791C24.0057 53.318 24 53.6583 24 54C24 70.5685 37.4315 84 54 84C70.5685 84 84 70.5685 84 54C84 37.4315 70.5685 24 54 24C53.6597 24 53.3207 24.0057 52.9831 24.0169C67.9919 24.5347 80.0002 36.865 80.0002 52Z" fill="#131928"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M48 12C28.1177 12 12 28.1177 12 48C12 50.2091 10.2091 52 8 52C5.79086 52 4 50.2091 4 48C4 23.6995 23.6995 4 48 4C50.2091 4 52 5.79086 52 8C52 10.2091 50.2091 12 48 12Z" fill="url(#paint1_linear_311_158)"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M298.984 30.8668V70.2724H308.169V46.8278C308.169 42.3005 309.082 39.1207 310.909 37.2882C312.789 35.4558 315.528 34.5395 319.127 34.5395H321.463V25C318.402 25 315.743 25.6467 313.487 26.9402C311.285 28.1798 309.512 29.9315 308.169 32.1951V25.7276H307.886L298.984 30.8668Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M269.573 31.1166V70.2724H278.758V46.8278C278.758 42.3005 279.671 39.1207 281.498 37.2882C283.377 35.4558 286.117 34.5395 289.716 34.5395H292.052V25C288.99 25 286.332 25.6467 284.076 26.9402C281.874 28.1798 280.101 29.9315 278.758 32.1951V25.8137L269.573 31.1166Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M260.689 43.8748C260.922 45.5294 261.026 47.0387 261 48.4029L232.595 52.395L233.533 44.7524L250.79 42.3272C250.264 38.9722 248.689 36.4452 246.063 34.746C243.438 33.0468 240.396 32.4402 236.939 32.9261C233.801 33.3671 231.257 34.7587 229.308 37.1008C227.756 38.9167 226.837 41.1061 226.55 43.6692C226.192 46.3457 226.195 50.8608 227.977 55.1055C228.886 57.629 230.398 59.6138 232.513 61.0602C235.153 62.8661 238.176 63.5299 241.58 63.0514C246.473 62.3637 249.642 59.823 251.085 55.4294L260.899 54.0501C260.139 58.2932 258.188 61.9691 255.045 65.0776C251.948 68.1254 247.819 70.0118 242.66 70.7369C238.458 71.3274 234.55 70.9242 230.936 69.5272C227.369 68.0693 224.387 65.767 221.992 62.6204C219.643 59.4129 218.15 55.5408 217.512 51.0043C216.875 46.4677 217.22 42.3645 218.549 38.6946C219.923 34.9638 222.127 31.9327 225.163 29.6012C228.251 27.2623 231.949 25.7901 236.258 25.1846C240.407 24.6015 244.231 24.9892 247.731 26.3479C251.23 27.7065 254.117 29.9132 256.39 32.9681C258.656 35.9696 260.089 39.6051 260.689 43.8748Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M209.921 43.8748C210.154 45.5293 210.258 47.0387 210.232 48.4029L181.827 52.395L182.765 44.7524L200.022 42.3272C199.496 38.9722 197.921 36.4452 195.295 34.746C192.67 33.0468 189.628 32.4402 186.171 32.9261C183.033 33.3671 180.489 34.7587 178.54 37.1008C176.988 38.9166 176.069 41.1059 175.782 43.6688C175.424 46.3453 175.427 50.8605 177.209 55.1055C178.118 57.629 179.63 59.6138 181.745 61.0602C184.385 62.8661 187.407 63.5299 190.812 63.0514C195.705 62.3637 198.874 59.823 200.317 55.4294L210.131 54.0501C209.371 58.2932 207.42 61.9691 204.277 65.0776C201.18 68.1254 197.051 70.0118 191.892 70.7369C187.69 71.3274 183.782 70.9242 180.168 69.5272C176.601 68.0693 173.619 65.767 171.224 62.6204C168.875 59.4129 167.382 55.5408 166.744 51.0043C166.107 46.4677 166.452 42.3645 167.78 38.6946C169.155 34.9638 171.359 31.9327 174.395 29.6012C177.483 27.2623 181.181 25.7901 185.49 25.1846C189.639 24.6015 193.463 24.9892 196.962 26.3479C200.462 27.7065 203.349 29.9132 205.622 32.9681C207.888 35.9696 209.321 39.6051 209.921 43.8748Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M143.297 71C139.806 71 136.664 70.3802 133.87 69.1406C131.131 67.8471 128.956 66.1224 127.344 63.9666C126.751 63.153 126.26 62.3066 125.87 61.4272L134.397 57.451C134.721 58.9735 135.566 60.2831 136.932 61.3796C138.597 62.6192 140.665 63.239 143.136 63.239C145.714 63.239 147.702 62.754 149.098 61.7838C150.548 60.7598 151.273 59.4663 151.273 57.9033C151.273 56.2326 150.468 54.993 148.856 54.1845C147.299 53.3761 144.801 52.4868 141.363 51.5167C138.033 50.6005 135.321 49.7112 133.226 48.8489C131.131 47.9865 129.305 46.6661 127.747 44.8875C126.243 43.109 125.491 40.7645 125.491 37.8541C125.491 35.4827 126.189 33.3269 127.586 31.3866C128.983 29.3925 130.97 27.8295 133.548 26.6977C136.18 25.5659 139.188 25 142.572 25C147.621 25 151.676 26.2935 154.738 28.8805C156.667 30.4488 158.04 32.3787 158.857 34.6701L150.459 38.5862C150.177 36.9271 149.402 35.5782 148.131 34.5395C146.681 33.3538 144.72 32.761 142.25 32.761C139.833 32.761 137.979 33.2191 136.69 34.1353C135.401 35.0516 134.757 36.2642 134.757 37.7733C134.757 38.959 135.186 39.9561 136.046 40.7645C136.905 41.5729 137.953 42.2197 139.188 42.7047C140.423 43.1359 142.25 43.7018 144.667 44.4025C147.89 45.2648 150.521 46.1541 152.563 47.0703C154.657 47.9326 156.457 49.2261 157.961 50.9508C159.465 52.6755 160.244 54.966 160.297 57.8225C160.297 60.3556 159.599 62.6192 158.202 64.6134C156.806 66.6075 154.818 68.1705 152.24 69.3023C149.716 70.4341 146.735 71 143.297 71Z" fill="white"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_311_158" x1="48" y1="-2.07126e-06" x2="117.5" y2="69.5" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#C395FC"/>
|
||||
<stop offset="1" stop-color="#4F65F5"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_311_158" x1="28" y1="8" x2="28" y2="48" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white" stop-opacity="0.4"/>
|
||||
<stop offset="1" stop-color="white" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.0 KiB |
1
gen-docs/static/img/os_icon.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" fill="none" viewBox="0 0 96 96"><path fill="url(#paint0_linear)" fill-rule="evenodd" d="M48 96C74.5097 96 96 74.5097 96 48C96 21.4903 74.5097 0 48 0C21.4903 0 0 21.4903 0 48C0 74.5097 21.4903 96 48 96ZM80.0001 52C80.0001 67.464 67.4641 80 52.0001 80C36.5361 80 24.0001 67.464 24.0001 52C24.0001 49.1303 24.4318 46.3615 25.2338 43.7548C27.4288 48.6165 32.3194 52 38.0001 52C45.7321 52 52.0001 45.732 52.0001 38C52.0001 32.3192 48.6166 27.4287 43.755 25.2337C46.3616 24.4317 49.1304 24 52.0001 24C67.4641 24 80.0001 36.536 80.0001 52Z" clip-rule="evenodd"/><path fill="#131928" fill-rule="evenodd" d="M80.0002 52C80.0002 67.464 67.4642 80 52.0002 80C36.864 80 24.5329 67.9897 24.017 52.9791C24.0057 53.318 24 53.6583 24 54C24 70.5685 37.4315 84 54 84C70.5685 84 84 70.5685 84 54C84 37.4315 70.5685 24 54 24C53.6597 24 53.3207 24.0057 52.9831 24.0169C67.9919 24.5347 80.0002 36.865 80.0002 52Z" clip-rule="evenodd" opacity=".2"/><path fill="url(#paint1_linear)" fill-rule="evenodd" d="M48 12C28.1177 12 12 28.1177 12 48C12 50.2091 10.2091 52 8 52C5.79086 52 4 50.2091 4 48C4 23.6995 23.6995 4 48 4C50.2091 4 52 5.79086 52 8C52 10.2091 50.2091 12 48 12Z" clip-rule="evenodd"/><defs><linearGradient id="paint0_linear" x1="48" x2="117.5" y1="0" y2="69.5" gradientUnits="userSpaceOnUse"><stop stop-color="#C395FC"/><stop offset="1" stop-color="#4F65F5"/></linearGradient><linearGradient id="paint1_linear" x1="28" x2="28" y1="8" y2="48" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" stop-opacity=".4"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></linearGradient></defs></svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
@@ -1,21 +0,0 @@
|
||||
/* eslint-disable */
|
||||
const tailwind = require('prettier-plugin-tailwindcss');
|
||||
const organizeImports = require('prettier-plugin-organize-imports');
|
||||
|
||||
const combinedFormatter = {
|
||||
...tailwind,
|
||||
parsers: {
|
||||
...tailwind.parsers,
|
||||
...Object.keys(organizeImports.parsers).reduce((acc, key) => {
|
||||
acc[key] = {
|
||||
...tailwind.parsers[key],
|
||||
preprocess(code, options) {
|
||||
return organizeImports.parsers[key].preprocess(code, options);
|
||||
},
|
||||
};
|
||||
return acc;
|
||||
}, {}),
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = combinedFormatter;
|
||||
@@ -24,6 +24,6 @@ module.exports = {
|
||||
},
|
||||
experimental: {
|
||||
scrollRestoration: true,
|
||||
largePageDataBytes: 256000,
|
||||
largePageDataBytes: 512 * 1000,
|
||||
},
|
||||
};
|
||||
|
||||
162
package.json
@@ -2,10 +2,9 @@
|
||||
"name": "seerr",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"packageManager": "pnpm@10.17.1",
|
||||
"packageManager": "pnpm@10.24.0",
|
||||
"scripts": {
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
"postinstall": "node postinstall-win.js",
|
||||
"dev": "nodemon -e ts --watch server --watch seerr-api.yml -e .json,.ts,.yml -x ts-node -r tsconfig-paths/register --files --project server/tsconfig.json server/index.ts",
|
||||
"build:server": "tsc --project server/tsconfig.json && copyfiles -u 2 server/templates/**/*.{html,pug} dist/templates && tsc-alias -p server/tsconfig.json",
|
||||
"build:next": "next build",
|
||||
@@ -17,7 +16,7 @@
|
||||
"migration:generate": "ts-node -r tsconfig-paths/register --project server/tsconfig.json ./node_modules/typeorm/cli.js migration:generate -d server/datasource.ts",
|
||||
"migration:create": "ts-node -r tsconfig-paths/register --project server/tsconfig.json ./node_modules/typeorm/cli.js migration:create -d server/datasource.ts",
|
||||
"migration:run": "ts-node -r tsconfig-paths/register --project server/tsconfig.json ./node_modules/typeorm/cli.js migration:run -d server/datasource.ts",
|
||||
"format": "prettier --loglevel warn --write --cache .",
|
||||
"format": "prettier --log-level warn --write --cache .",
|
||||
"format:check": "prettier --check --cache .",
|
||||
"typecheck": "pnpm typecheck:server && pnpm typecheck:client",
|
||||
"typecheck:server": "tsc --project server/tsconfig.json --noEmit",
|
||||
@@ -33,156 +32,150 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@dr.pogodin/csurf": "^1.14.1",
|
||||
"@formatjs/intl-displaynames": "6.2.6",
|
||||
"@dr.pogodin/csurf": "^1.16.6",
|
||||
"@formatjs/intl-displaynames": "6.8.13",
|
||||
"@formatjs/intl-locale": "3.1.1",
|
||||
"@formatjs/intl-pluralrules": "5.1.10",
|
||||
"@formatjs/intl-pluralrules": "5.4.6",
|
||||
"@formatjs/intl-utils": "3.8.4",
|
||||
"@formatjs/swc-plugin-experimental": "^0.4.0",
|
||||
"@headlessui/react": "1.7.12",
|
||||
"@heroicons/react": "2.0.16",
|
||||
"@heroicons/react": "2.2.0",
|
||||
"@seerr-team/react-tailwindcss-datepicker": "^1.3.4",
|
||||
"@supercharge/request-ip": "1.2.0",
|
||||
"@svgr/webpack": "6.5.1",
|
||||
"@tanem/react-nprogress": "5.0.30",
|
||||
"@tanem/react-nprogress": "5.0.56",
|
||||
"@types/ua-parser-js": "^0.7.36",
|
||||
"@types/wink-jaro-distance": "^2.0.2",
|
||||
"ace-builds": "1.15.2",
|
||||
"axios": "1.10.0",
|
||||
"axios-rate-limit": "1.3.0",
|
||||
"bcrypt": "5.1.0",
|
||||
"bowser": "2.11.0",
|
||||
"ace-builds": "1.43.4",
|
||||
"axios": "1.13.3",
|
||||
"axios-rate-limit": "1.4.0",
|
||||
"bcrypt": "6.0.0",
|
||||
"bowser": "2.13.1",
|
||||
"connect-typeorm": "1.1.4",
|
||||
"cookie-parser": "1.4.7",
|
||||
"copy-to-clipboard": "3.3.3",
|
||||
"country-flag-icons": "1.5.5",
|
||||
"country-flag-icons": "1.6.4",
|
||||
"cronstrue": "2.23.0",
|
||||
"date-fns": "2.29.3",
|
||||
"dayjs": "1.11.7",
|
||||
"dns-caching": "^0.2.7",
|
||||
"email-templates": "12.0.1",
|
||||
"email-templates": "12.0.3",
|
||||
"express": "4.21.2",
|
||||
"express-openapi-validator": "4.13.8",
|
||||
"express-rate-limit": "6.7.0",
|
||||
"express-session": "1.17.3",
|
||||
"formik": "^2.4.6",
|
||||
"express-session": "1.18.2",
|
||||
"formik": "^2.4.9",
|
||||
"gravatar-url": "3.1.0",
|
||||
"http-proxy-agent": "^7.0.2",
|
||||
"https-proxy-agent": "^7.0.6",
|
||||
"lodash": "4.17.21",
|
||||
"lodash": "4.17.23",
|
||||
"mime": "3",
|
||||
"next": "^14.2.25",
|
||||
"next": "^14.2.35",
|
||||
"node-cache": "5.1.2",
|
||||
"node-gyp": "9.3.1",
|
||||
"node-schedule": "2.1.1",
|
||||
"nodemailer": "6.10.0",
|
||||
"openpgp": "5.11.2",
|
||||
"pg": "8.11.0",
|
||||
"plex-api": "5.3.2",
|
||||
"nodemailer": "7.0.12",
|
||||
"openpgp": "6.3.0",
|
||||
"pg": "8.17.2",
|
||||
"pug": "3.0.3",
|
||||
"react": "^18.3.1",
|
||||
"react-ace": "10.1.0",
|
||||
"react-animate-height": "2.1.2",
|
||||
"react-aria": "3.23.0",
|
||||
"react-aria": "3.44.0",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-intersection-observer": "9.4.3",
|
||||
"react-intl": "^6.6.8",
|
||||
"react-markdown": "8.0.5",
|
||||
"react-popper-tooltip": "4.4.2",
|
||||
"react-select": "5.7.0",
|
||||
"react-select": "5.10.2",
|
||||
"react-spring": "9.7.1",
|
||||
"react-tailwindcss-datepicker-sct": "1.3.4",
|
||||
"react-toast-notifications": "2.5.1",
|
||||
"react-transition-group": "^4.4.5",
|
||||
"react-truncate-markup": "5.1.2",
|
||||
"react-use-clipboard": "1.0.9",
|
||||
"reflect-metadata": "0.1.13",
|
||||
"secure-random-password": "0.2.3",
|
||||
"semver": "7.7.1",
|
||||
"semver": "7.7.3",
|
||||
"sharp": "^0.33.4",
|
||||
"sqlite3": "5.1.7",
|
||||
"swagger-ui-express": "4.6.2",
|
||||
"swr": "2.2.5",
|
||||
"swr": "2.3.8",
|
||||
"tailwind-merge": "^2.6.0",
|
||||
"typeorm": "0.3.12",
|
||||
"typeorm": "0.3.28",
|
||||
"ua-parser-js": "^1.0.35",
|
||||
"undici": "^7.3.0",
|
||||
"validator": "^13.15.15",
|
||||
"web-push": "3.5.0",
|
||||
"undici": "^7.18.2",
|
||||
"validator": "^13.15.23",
|
||||
"web-push": "3.6.7",
|
||||
"wink-jaro-distance": "^2.0.0",
|
||||
"winston": "3.8.2",
|
||||
"winston": "3.19.0",
|
||||
"winston-daily-rotate-file": "4.7.1",
|
||||
"xml2js": "0.4.23",
|
||||
"xml2js": "0.5.0",
|
||||
"yamljs": "0.3.0",
|
||||
"yup": "0.32.11",
|
||||
"zod": "3.24.2"
|
||||
"zod": "4.3.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "17.4.4",
|
||||
"@commitlint/config-conventional": "17.4.4",
|
||||
"@tailwindcss/aspect-ratio": "0.4.2",
|
||||
"@tailwindcss/forms": "0.5.10",
|
||||
"@tailwindcss/typography": "0.5.16",
|
||||
"@types/bcrypt": "5.0.0",
|
||||
"@types/cookie-parser": "1.4.3",
|
||||
"@types/country-flag-icons": "1.2.0",
|
||||
"@types/csurf": "1.11.2",
|
||||
"@tailwindcss/aspect-ratio": "^0.4.2",
|
||||
"@tailwindcss/forms": "^0.5.10",
|
||||
"@tailwindcss/typography": "^0.5.16",
|
||||
"@types/bcrypt": "6.0.0",
|
||||
"@types/cookie-parser": "1.4.10",
|
||||
"@types/country-flag-icons": "1.2.2",
|
||||
"@types/csurf": "1.11.5",
|
||||
"@types/email-templates": "8.0.4",
|
||||
"@types/express": "4.17.17",
|
||||
"@types/express-session": "1.17.6",
|
||||
"@types/lodash": "4.14.191",
|
||||
"@types/express-session": "1.18.2",
|
||||
"@types/lodash": "4.17.21",
|
||||
"@types/mime": "3",
|
||||
"@types/node": "22.10.5",
|
||||
"@types/node-schedule": "2.1.0",
|
||||
"@types/nodemailer": "6.4.7",
|
||||
"@types/node-schedule": "2.1.8",
|
||||
"@types/nodemailer": "7",
|
||||
"@types/react": "^18.3.3",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@types/react-transition-group": "4.4.5",
|
||||
"@types/react-transition-group": "4.4.12",
|
||||
"@types/secure-random-password": "0.2.1",
|
||||
"@types/semver": "7.3.13",
|
||||
"@types/swagger-ui-express": "4.1.3",
|
||||
"@types/validator": "^13.15.3",
|
||||
"@types/web-push": "3.3.2",
|
||||
"@types/xml2js": "0.4.11",
|
||||
"@types/semver": "7.7.1",
|
||||
"@types/swagger-ui-express": "4.1.8",
|
||||
"@types/validator": "^13.15.10",
|
||||
"@types/web-push": "3.6.4",
|
||||
"@types/xml2js": "0.4.14",
|
||||
"@types/yamljs": "0.2.31",
|
||||
"@types/yup": "0.29.14",
|
||||
"@typescript-eslint/eslint-plugin": "5.54.0",
|
||||
"@typescript-eslint/parser": "5.54.0",
|
||||
"autoprefixer": "10.4.13",
|
||||
"commitizen": "4.3.0",
|
||||
"@typescript-eslint/eslint-plugin": "7.18.0",
|
||||
"@typescript-eslint/parser": "7.18.0",
|
||||
"autoprefixer": "^10.4.23",
|
||||
"baseline-browser-mapping": "^2.8.32",
|
||||
"commitizen": "4.3.1",
|
||||
"copyfiles": "2.4.1",
|
||||
"cy-mobile-commands": "0.3.0",
|
||||
"cypress": "14.1.0",
|
||||
"cypress": "14.5.4",
|
||||
"cz-conventional-changelog": "3.3.0",
|
||||
"eslint": "8.35.0",
|
||||
"eslint-config-next": "^14.2.4",
|
||||
"eslint": "8.57.1",
|
||||
"eslint-config-next": "^14.2.35",
|
||||
"eslint-config-prettier": "8.6.0",
|
||||
"eslint-plugin-formatjs": "4.9.0",
|
||||
"eslint-plugin-jsx-a11y": "6.7.1",
|
||||
"eslint-plugin-no-relative-import-paths": "1.5.2",
|
||||
"eslint-plugin-jsx-a11y": "6.10.2",
|
||||
"eslint-plugin-no-relative-import-paths": "1.6.1",
|
||||
"eslint-plugin-prettier": "4.2.1",
|
||||
"eslint-plugin-react": "7.32.2",
|
||||
"eslint-plugin-react": "7.37.5",
|
||||
"eslint-plugin-react-hooks": "4.6.0",
|
||||
"husky": "8.0.3",
|
||||
"lint-staged": "13.1.2",
|
||||
"nodemon": "3.1.9",
|
||||
"postcss": "8.4.31",
|
||||
"prettier": "2.8.4",
|
||||
"prettier-plugin-organize-imports": "3.2.2",
|
||||
"prettier-plugin-tailwindcss": "0.2.3",
|
||||
"tailwindcss": "3.2.7",
|
||||
"ts-node": "10.9.1",
|
||||
"tsc-alias": "1.8.2",
|
||||
"tsconfig-paths": "4.1.2",
|
||||
"typescript": "4.9.5"
|
||||
"nodemon": "3.1.11",
|
||||
"postcss": "^8.5.6",
|
||||
"prettier": "3.8.1",
|
||||
"prettier-plugin-organize-imports": "4.3.0",
|
||||
"prettier-plugin-tailwindcss": "0.6.14",
|
||||
"tailwindcss": "3.4.19",
|
||||
"ts-node": "10.9.2",
|
||||
"tsc-alias": "1.8.16",
|
||||
"tsconfig-paths": "4.2.0",
|
||||
"typescript": "5.4.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^22.0.0",
|
||||
"pnpm": "^10.0.0"
|
||||
},
|
||||
"overrides": {
|
||||
"sqlite3/node-gyp": "8.4.1",
|
||||
"@types/express-session": "1.17.6"
|
||||
},
|
||||
"config": {
|
||||
"commitizen": {
|
||||
"path": "./node_modules/cz-conventional-changelog"
|
||||
@@ -204,8 +197,15 @@
|
||||
},
|
||||
"pnpm": {
|
||||
"onlyBuiltDependencies": [
|
||||
"sqlite3",
|
||||
"bcrypt"
|
||||
]
|
||||
"@swc/core",
|
||||
"bcrypt",
|
||||
"cypress",
|
||||
"sharp",
|
||||
"sqlite3"
|
||||
],
|
||||
"overrides": {
|
||||
"sqlite3>node-gyp": "8.4.1",
|
||||
"@types/express-session": "1.18.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
9373
pnpm-lock.yaml
generated
@@ -1,13 +0,0 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { execSync } = require('child_process');
|
||||
|
||||
if (process.platform === 'win32') {
|
||||
const typeormPath = path.resolve('node_modules/typeorm');
|
||||
|
||||
if (fs.existsSync(typeormPath)) {
|
||||
process.stdout.write('> Installing typeorm@0.3.11 for Windows\n');
|
||||
execSync('pnpm add typeorm@0.3.11', { stdio: 'inherit' });
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 7.9 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 8.0 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 40 KiB |