{"owner":"EstrellaXD","repo":"Auto_Bangumi","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["CLAUDE.md"],"skills":{"CLAUDE.md":"# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Project Overview\n\nAutoBangumi is an RSS-based automatic anime downloading and organization tool. It monitors RSS feeds from anime torrent sites (Mikan, DMHY, Nyaa), downloads episodes via qBittorrent, and organizes files into a Plex/Jellyfin-compatible directory structure with automatic renaming.\n\n## Development Commands\n\n### Backend (Python)\n\n```bash\n# Install dependencies\ncd backend && uv sync\n\n# Install with dev tools\ncd backend && uv sync --group dev\n\n# Run development server (port 7892, API docs at /docs)\ncd backend/src && uv run python main.py\n\n# Run tests\ncd backend && uv run pytest\ncd backend && uv run pytest src/test/test_xxx.py -v  # run specific test\n\n# Linting and formatting\ncd backend && uv run ruff check src\ncd backend && uv run black src\n\n# Add a dependency\ncd backend && uv add <package>\n\n# Add a dev dependency\ncd backend && uv add --group dev <package>\n```\n\n### Frontend (Vue 3 + TypeScript)\n\n```bash\ncd webui\n\n# Install dependencies (uses pnpm, not npm)\npnpm install\n\n# Development server (port 5173)\npnpm dev\n\n# Build for production\npnpm build\n\n# Type checking\npnpm test:build\n\n# Linting and formatting\npnpm lint\npnpm lint:fix\npnpm format\n```\n\n### Docker\n\n```bash\ndocker build -t auto_bangumi:latest .\ndocker run -p 7892:7892 -v /path/to/config:/app/config -v /path/to/data:/app/data auto_bangumi:latest\n```\n\n## Architecture\n\n```\nbackend/src/\n├── main.py                 # FastAPI entry point, mounts API at /api\n├── module/\n│   ├── api/               # REST API routes (v1 prefix)\n│   │   ├── auth.py        # Authentication endpoints\n│   │   ├── bangumi.py     # Anime series CRUD\n│   │   ├── rss.py         # RSS feed management\n│   │   ├── config.py      # Configuration endpoints\n│   │   ├── program.py     # Program status/control\n│   │   └── search.py      # Torrent search\n│   ├── core/              # Application logic\n│   │   ├── context.py     # AppContext composition root (built in create_app, on app.state.ctx)\n│   │   ├── scheduler.py   # PeriodicTask + Scheduler (generic background-loop runner)\n│   │   ├── loops.py       # The individual periodic tick functions (rss/rename/offset/calendar)\n│   │   └── offset_scanner.py\n│   ├── models/            # SQLModel ORM models (Pydantic + SQLAlchemy)\n│   ├── database/          # Async DB (aiosqlite) — repos + Database + migrations.py\n│   ├── rss/               # RSS parsing and analysis\n│   ├── downloader/        # qBittorrent integration\n│   │   ├── base.py        # Downloader Protocol + DownloaderCapabilities\n│   │   └── client/        # Download client implementations (qb, aria2, mock)\n│   ├── searcher/          # Torrent search providers (Mikan, DMHY, Nyaa)\n│   ├── parser/            # Torrent name parsing, metadata extraction\n│   │   └── analyser/      # TMDB, Mikan, OpenAI parsers\n│   ├── manager/           # File organization and renaming\n│   ├── notification/      # Notification plugins (Telegram, Bark, etc.)\n│   ├── conf/              # Configuration management, settings\n│   ├── network/           # HTTP client utilities\n│   └── security/          # JWT authentication\n\nwebui/src/\n├── api/                   # Axios API client functions\n├── components/            # Vue components (basic/, layout/, setting/)\n├── pages/                 # Router-based page components\n├── router/                # Vue Router configuration\n├── store/                 # Pinia state management\n├── i18n/                  # Internationalization (zh-CN, en-US)\n└── hooks/                 # Custom Vue composables\n```\n\n## Key Data Flow\n\n1. RSS feeds are parsed by `module/rss/` to extract torrent information\n2. Torrent names are analyzed by `module/parser/analyser/` to extract anime metadata\n3. Downloads are managed via `module/downloader/` (qBittorrent API)\n4. Files are organized by `module/manager/` into standard directory structure\n5. Periodic loops (`module/core/loops.py`) run under a `Scheduler` owned by the lifespan `AppContext` (`module/core/context.py`)\n\n## Architecture conventions (3.3+)\n\n- **Async DB throughout.** Everything runs on the async engine (`sqlite+aiosqlite`, WAL). Repositories (`database/{bangumi,rss,torrent,user,passkey}.py`) take an `AsyncSession` and are `async def`. `Database` is an async context manager owning one session with the repos attached (`db.rss`, `db.bangumi`, …).\n- **Session per operation.** Get a session via `Depends(get_db)` in routes, or `async with Database() as db:` in loops/services. Never store a session on anything that outlives one request or one loop tick. `AppContext` holds no session.\n- **Services take dependencies in their constructor** (composition, not inheritance): `RSSEngine(db)`, `TorrentManager(db)`, `Renamer(client)`, `SearchTorrent()`. They use `self.db.<repo>` internally; callers that only need a repo use `db.<repo>` directly.\n- **Downloaders** implement the `Downloader` Protocol and declare `DownloaderCapabilities`; the facade (`DownloadClient`) skips-and-logs unsupported ops rather than crashing. The qB client is reused across operations (one login), not re-authed per call.\n- **Config reloads** go through `AppContext.reload_settings()` (settings + http client + notifier + scheduler), not ad-hoc `settings.load()`.\n\n## Code Style\n\n- Python: Black (88 char lines), Ruff linter (E, F, I rules), target Python 3.10+\n- TypeScript: ESLint + Prettier\n- Run formatters before committing\n\n## Git Branching\n\n- `main`: Stable releases only\n- `X.Y-dev` branches: Active development (e.g., `3.2-dev`)\n- Bug fixes → PR to current released version's `-dev` branch\n- New features → PR to next version's `-dev` branch\n\n## Releasing\n\nAll releases are triggered by manually pushing a tag — merging a PR never releases.\n\n### Beta Version\n\n1. Update version in `backend/pyproject.toml`\n2. Update `CHANGELOG.md` with the new version heading\n3. Commit and push to the dev branch\n4. Create and push a tag with the version name (e.g., `3.2.0-beta.4`):\n   ```bash\n   git tag 3.2.0-beta.4\n   git push origin 3.2.0-beta.4\n   ```\n5. The CI/CD workflow (`.github/workflows/build.yml`) detects the tag contains \"beta\", uses the tag name as the VERSION string, generates `module/__version__.py`, and builds the Docker image (tagged `<version>` + `dev-latest`)\n\n### Stable Version\n\n1. Merge the dev branch into `main` via PR (this only runs tests and a build test)\n2. Tag the merge commit on `main` with the bare semver version and push:\n   ```bash\n   git tag 3.3.2 <merge-commit-on-main>\n   git push origin 3.3.2\n   ```\n3. CI validates the tag is `X.Y.Z` **and** points to a commit on `main` (refuses otherwise), then builds and pushes Docker images (tagged `<version>` + `latest`) and creates the GitHub release with notes from `docs/changelog/<X.Y>.md`\n\nThe VERSION is injected at build time via CI — `module/__version__.py` does not exist in the repo. At runtime, `module/conf/config.py` imports it or falls back to `\"DEV_VERSION\"`.\n\n## Database Migrations\n\nSchema migrations are tracked via a `schema_version` table in SQLite. To add a new migration:\n\n1. Append a `Migration(version, \"description\", (…SQL…), already_applied=column_exists(\"table\", \"col\"))` entry to the `MIGRATIONS` tuple in `backend/src/module/database/migrations.py` (`CURRENT_SCHEMA_VERSION` is derived from the list — do not edit it by hand)\n2. Provide an `already_applied` guard (`column_exists` / `table_exists`) so a schema created out-of-band is detected and skipped\n3. Migrations run automatically on startup via `run_migrations()` (each in a SAVEPOINT, stopping on first failure)\n\n## Notes\n\n- Documentation and comments are in Chinese\n- Uses SQLModel (hybrid Pydantic + SQLAlchemy ORM)\n- External integrations: qBittorrent API, TMDB API, OpenAI API\n- Version tracked in `/config/version.info` (for cross-version upgrade detection)\n"},"files":{"CLAUDE.md":"# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Project Overview\n\nAutoBangumi is an RSS-based automatic anime downloading and organization tool. It monitors RSS feeds from anime torrent sites (Mikan, DMHY, Nyaa), downloads episodes via qBittorrent, and organizes files into a Plex/Jellyfin-compatible directory structure with automatic renaming.\n\n## Development Commands\n\n### Backend (Python)\n\n```bash\n# Install dependencies\ncd backend && uv sync\n\n# Install with dev tools\ncd backend && uv sync --group dev\n\n# Run development server (port 7892, API docs at /docs)\ncd backend/src && uv run python main.py\n\n# Run tests\ncd backend && uv run pytest\ncd backend && uv run pytest src/test/test_xxx.py -v  # run specific test\n\n# Linting and formatting\ncd backend && uv run ruff check src\ncd backend && uv run black src\n\n# Add a dependency\ncd backend && uv add <package>\n\n# Add a dev dependency\ncd backend && uv add --group dev <package>\n```\n\n### Frontend (Vue 3 + TypeScript)\n\n```bash\ncd webui\n\n# Install dependencies (uses pnpm, not npm)\npnpm install\n\n# Development server (port 5173)\npnpm dev\n\n# Build for production\npnpm build\n\n# Type checking\npnpm test:build\n\n# Linting and formatting\npnpm lint\npnpm lint:fix\npnpm format\n```\n\n### Docker\n\n```bash\ndocker build -t auto_bangumi:latest .\ndocker run -p 7892:7892 -v /path/to/config:/app/config -v /path/to/data:/app/data auto_bangumi:latest\n```\n\n## Architecture\n\n```\nbackend/src/\n├── main.py                 # FastAPI entry point, mounts API at /api\n├── module/\n│   ├── api/               # REST API routes (v1 prefix)\n│   │   ├── auth.py        # Authentication endpoints\n│   │   ├── bangumi.py     # Anime series CRUD\n│   │   ├── rss.py         # RSS feed management\n│   │   ├── config.py      # Configuration endpoints\n│   │   ├── program.py     # Program status/control\n│   │   └── search.py      # Torrent search\n│   ├── core/              # Application logic\n│   │   ├── context.py     # AppContext composition root (built in create_app, on app.state.ctx)\n│   │   ├── scheduler.py   # PeriodicTask + Scheduler (generic background-loop runner)\n│   │   ├── loops.py       # The individual periodic tick functions (rss/rename/offset/calendar)\n│   │   └── offset_scanner.py\n│   ├── models/            # SQLModel ORM models (Pydantic + SQLAlchemy)\n│   ├── database/          # Async DB (aiosqlite) — repos + Database + migrations.py\n│   ├── rss/               # RSS parsing and analysis\n│   ├── downloader/        # qBittorrent integration\n│   │   ├── base.py        # Downloader Protocol + DownloaderCapabilities\n│   │   └── client/        # Download client implementations (qb, aria2, mock)\n│   ├── searcher/          # Torrent search providers (Mikan, DMHY, Nyaa)\n│   ├── parser/            # Torrent name parsing, metadata extraction\n│   │   └── analyser/      # TMDB, Mikan, OpenAI parsers\n│   ├── manager/           # File organization and renaming\n│   ├── notification/      # Notification plugins (Telegram, Bark, etc.)\n│   ├── conf/              # Configuration management, settings\n│   ├── network/           # HTTP client utilities\n│   └── security/          # JWT authentication\n\nwebui/src/\n├── api/                   # Axios API client functions\n├── components/            # Vue components (basic/, layout/, setting/)\n├── pages/                 # Router-based page components\n├── router/                # Vue Router configuration\n├── store/                 # Pinia state management\n├── i18n/                  # Internationalization (zh-CN, en-US)\n└── hooks/                 # Custom Vue composables\n```\n\n## Key Data Flow\n\n1. RSS feeds are parsed by `module/rss/` to extract torrent information\n2. Torrent names are analyzed by `module/parser/analyser/` to extract anime metadata\n3. Downloads are managed via `module/downloader/` (qBittorrent API)\n4. Files are organized by `module/manager/` into standard directory structure\n5. Periodic loops (`module/core/loops.py`) run under a `Scheduler` owned by the lifespan `AppContext` (`module/core/context.py`)\n\n## Architecture conventions (3.3+)\n\n- **Async DB throughout.** Everything runs on the async engine (`sqlite+aiosqlite`, WAL). Repositories (`database/{bangumi,rss,torrent,user,passkey}.py`) take an `AsyncSession` and are `async def`. `Database` is an async context manager owning one session with the repos attached (`db.rss`, `db.bangumi`, …).\n- **Session per operation.** Get a session via `Depends(get_db)` in routes, or `async with Database() as db:` in loops/services. Never store a session on anything that outlives one request or one loop tick. `AppContext` holds no session.\n- **Services take dependencies in their constructor** (composition, not inheritance): `RSSEngine(db)`, `TorrentManager(db)`, `Renamer(client)`, `SearchTorrent()`. They use `self.db.<repo>` internally; callers that only need a repo use `db.<repo>` directly.\n- **Downloaders** implement the `Downloader` Protocol and declare `DownloaderCapabilities`; the facade (`DownloadClient`) skips-and-logs unsupported ops rather than crashing. The qB client is reused across operations (one login), not re-authed per call.\n- **Config reloads** go through `AppContext.reload_settings()` (settings + http client + notifier + scheduler), not ad-hoc `settings.load()`.\n\n## Code Style\n\n- Python: Black (88 char lines), Ruff linter (E, F, I rules), target Python 3.10+\n- TypeScript: ESLint + Prettier\n- Run formatters before committing\n\n## Git Branching\n\n- `main`: Stable releases only\n- `X.Y-dev` branches: Active development (e.g., `3.2-dev`)\n- Bug fixes → PR to current released version's `-dev` branch\n- New features → PR to next version's `-dev` branch\n\n## Releasing\n\nAll releases are triggered by manually pushing a tag — merging a PR never releases.\n\n### Beta Version\n\n1. Update version in `backend/pyproject.toml`\n2. Update `CHANGELOG.md` with the new version heading\n3. Commit and push to the dev branch\n4. Create and push a tag with the version name (e.g., `3.2.0-beta.4`):\n   ```bash\n   git tag 3.2.0-beta.4\n   git push origin 3.2.0-beta.4\n   ```\n5. The CI/CD workflow (`.github/workflows/build.yml`) detects the tag contains \"beta\", uses the tag name as the VERSION string, generates `module/__version__.py`, and builds the Docker image (tagged `<version>` + `dev-latest`)\n\n### Stable Version\n\n1. Merge the dev branch into `main` via PR (this only runs tests and a build test)\n2. Tag the merge commit on `main` with the bare semver version and push:\n   ```bash\n   git tag 3.3.2 <merge-commit-on-main>\n   git push origin 3.3.2\n   ```\n3. CI validates the tag is `X.Y.Z` **and** points to a commit on `main` (refuses otherwise), then builds and pushes Docker images (tagged `<version>` + `latest`) and creates the GitHub release with notes from `docs/changelog/<X.Y>.md`\n\nThe VERSION is injected at build time via CI — `module/__version__.py` does not exist in the repo. At runtime, `module/conf/config.py` imports it or falls back to `\"DEV_VERSION\"`.\n\n## Database Migrations\n\nSchema migrations are tracked via a `schema_version` table in SQLite. To add a new migration:\n\n1. Append a `Migration(version, \"description\", (…SQL…), already_applied=column_exists(\"table\", \"col\"))` entry to the `MIGRATIONS` tuple in `backend/src/module/database/migrations.py` (`CURRENT_SCHEMA_VERSION` is derived from the list — do not edit it by hand)\n2. Provide an `already_applied` guard (`column_exists` / `table_exists`) so a schema created out-of-band is detected and skipped\n3. Migrations run automatically on startup via `run_migrations()` (each in a SAVEPOINT, stopping on first failure)\n\n## Notes\n\n- Documentation and comments are in Chinese\n- Uses SQLModel (hybrid Pydantic + SQLAlchemy ORM)\n- External integrations: qBittorrent API, TMDB API, OpenAI API\n- Version tracked in `/config/version.info` (for cross-version upgrade detection)\n"},"items":[{"name":"CLAUDE.md","path":"CLAUDE.md","title":"CLAUDE.md","content":"# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Project Overview\n\nAutoBangumi is an RSS-based automatic anime downloading and organization tool. It monitors RSS feeds from anime torrent sites (Mikan, DMHY, Nyaa), downloads episodes via qBittorrent, and organizes files into a Plex/Jellyfin-compatible directory structure with automatic renaming.\n\n## Development Commands\n\n### Backend (Python)\n\n```bash\n# Install dependencies\ncd backend && uv sync\n\n# Install with dev tools\ncd backend && uv sync --group dev\n\n# Run development server (port 7892, API docs at /docs)\ncd backend/src && uv run python main.py\n\n# Run tests\ncd backend && uv run pytest\ncd backend && uv run pytest src/test/test_xxx.py -v  # run specific test\n\n# Linting and formatting\ncd backend && uv run ruff check src\ncd backend && uv run black src\n\n# Add a dependency\ncd backend && uv add <package>\n\n# Add a dev dependency\ncd backend && uv add --group dev <package>\n```\n\n### Frontend (Vue 3 + TypeScript)\n\n```bash\ncd webui\n\n# Install dependencies (uses pnpm, not npm)\npnpm install\n\n# Development server (port 5173)\npnpm dev\n\n# Build for production\npnpm build\n\n# Type checking\npnpm test:build\n\n# Linting and formatting\npnpm lint\npnpm lint:fix\npnpm format\n```\n\n### Docker\n\n```bash\ndocker build -t auto_bangumi:latest .\ndocker run -p 7892:7892 -v /path/to/config:/app/config -v /path/to/data:/app/data auto_bangumi:latest\n```\n\n## Architecture\n\n```\nbackend/src/\n├── main.py                 # FastAPI entry point, mounts API at /api\n├── module/\n│   ├── api/               # REST API routes (v1 prefix)\n│   │   ├── auth.py        # Authentication endpoints\n│   │   ├── bangumi.py     # Anime series CRUD\n│   │   ├── rss.py         # RSS feed management\n│   │   ├── config.py      # Configuration endpoints\n│   │   ├── program.py     # Program status/control\n│   │   └── search.py      # Torrent search\n│   ├── core/              # Application logic\n│   │   ├── context.py     # AppContext composition root (built in create_app, on app.state.ctx)\n│   │   ├── scheduler.py   # PeriodicTask + Scheduler (generic background-loop runner)\n│   │   ├── loops.py       # The individual periodic tick functions (rss/rename/offset/calendar)\n│   │   └── offset_scanner.py\n│   ├── models/            # SQLModel ORM models (Pydantic + SQLAlchemy)\n│   ├── database/          # Async DB (aiosqlite) — repos + Database + migrations.py\n│   ├── rss/               # RSS parsing and analysis\n│   ├── downloader/        # qBittorrent integration\n│   │   ├── base.py        # Downloader Protocol + DownloaderCapabilities\n│   │   └── client/        # Download client implementations (qb, aria2, mock)\n│   ├── searcher/          # Torrent search providers (Mikan, DMHY, Nyaa)\n│   ├── parser/            # Torrent name parsing, metadata extraction\n│   │   └── analyser/      # TMDB, Mikan, OpenAI parsers\n│   ├── manager/           # File organization and renaming\n│   ├── notification/      # Notification plugins (Telegram, Bark, etc.)\n│   ├── conf/              # Configuration management, settings\n│   ├── network/           # HTTP client utilities\n│   └── security/          # JWT authentication\n\nwebui/src/\n├── api/                   # Axios API client functions\n├── components/            # Vue components (basic/, layout/, setting/)\n├── pages/                 # Router-based page components\n├── router/                # Vue Router configuration\n├── store/                 # Pinia state management\n├── i18n/                  # Internationalization (zh-CN, en-US)\n└── hooks/                 # Custom Vue composables\n```\n\n## Key Data Flow\n\n1. RSS feeds are parsed by `module/rss/` to extract torrent information\n2. Torrent names are analyzed by `module/parser/analyser/` to extract anime metadata\n3. Downloads are managed via `module/downloader/` (qBittorrent API)\n4. Files are organized by `module/manager/` into standard directory structure\n5. Periodic loops (`module/core/loops.py`) run under a `Scheduler` owned by the lifespan `AppContext` (`module/core/context.py`)\n\n## Architecture conventions (3.3+)\n\n- **Async DB throughout.** Everything runs on the async engine (`sqlite+aiosqlite`, WAL). Repositories (`database/{bangumi,rss,torrent,user,passkey}.py`) take an `AsyncSession` and are `async def`. `Database` is an async context manager owning one session with the repos attached (`db.rss`, `db.bangumi`, …).\n- **Session per operation.** Get a session via `Depends(get_db)` in routes, or `async with Database() as db:` in loops/services. Never store a session on anything that outlives one request or one loop tick. `AppContext` holds no session.\n- **Services take dependencies in their constructor** (composition, not inheritance): `RSSEngine(db)`, `TorrentManager(db)`, `Renamer(client)`, `SearchTorrent()`. They use `self.db.<repo>` internally; callers that only need a repo use `db.<repo>` directly.\n- **Downloaders** implement the `Downloader` Protocol and declare `DownloaderCapabilities`; the facade (`DownloadClient`) skips-and-logs unsupported ops rather than crashing. The qB client is reused across operations (one login), not re-authed per call.\n- **Config reloads** go through `AppContext.reload_settings()` (settings + http client + notifier + scheduler), not ad-hoc `settings.load()`.\n\n## Code Style\n\n- Python: Black (88 char lines), Ruff linter (E, F, I rules), target Python 3.10+\n- TypeScript: ESLint + Prettier\n- Run formatters before committing\n\n## Git Branching\n\n- `main`: Stable releases only\n- `X.Y-dev` branches: Active development (e.g., `3.2-dev`)\n- Bug fixes → PR to current released version's `-dev` branch\n- New features → PR to next version's `-dev` branch\n\n## Releasing\n\nAll releases are triggered by manually pushing a tag — merging a PR never releases.\n\n### Beta Version\n\n1. Update version in `backend/pyproject.toml`\n2. Update `CHANGELOG.md` with the new version heading\n3. Commit and push to the dev branch\n4. Create and push a tag with the version name (e.g., `3.2.0-beta.4`):\n   ```bash\n   git tag 3.2.0-beta.4\n   git push origin 3.2.0-beta.4\n   ```\n5. The CI/CD workflow (`.github/workflows/build.yml`) detects the tag contains \"beta\", uses the tag name as the VERSION string, generates `module/__version__.py`, and builds the Docker image (tagged `<version>` + `dev-latest`)\n\n### Stable Version\n\n1. Merge the dev branch into `main` via PR (this only runs tests and a build test)\n2. Tag the merge commit on `main` with the bare semver version and push:\n   ```bash\n   git tag 3.3.2 <merge-commit-on-main>\n   git push origin 3.3.2\n   ```\n3. CI validates the tag is `X.Y.Z` **and** points to a commit on `main` (refuses otherwise), then builds and pushes Docker images (tagged `<version>` + `latest`) and creates the GitHub release with notes from `docs/changelog/<X.Y>.md`\n\nThe VERSION is injected at build time via CI — `module/__version__.py` does not exist in the repo. At runtime, `module/conf/config.py` imports it or falls back to `\"DEV_VERSION\"`.\n\n## Database Migrations\n\nSchema migrations are tracked via a `schema_version` table in SQLite. To add a new migration:\n\n1. Append a `Migration(version, \"description\", (…SQL…), already_applied=column_exists(\"table\", \"col\"))` entry to the `MIGRATIONS` tuple in `backend/src/module/database/migrations.py` (`CURRENT_SCHEMA_VERSION` is derived from the list — do not edit it by hand)\n2. Provide an `already_applied` guard (`column_exists` / `table_exists`) so a schema created out-of-band is detected and skipped\n3. Migrations run automatically on startup via `run_migrations()` (each in a SAVEPOINT, stopping on first failure)\n\n## Notes\n\n- Documentation and comments are in Chinese\n- Uses SQLModel (hybrid Pydantic + SQLAlchemy ORM)\n- External integrations: qBittorrent API, TMDB API, OpenAI API\n- Version tracked in `/config/version.info` (for cross-version upgrade detection)\n","category":"root","tokens":1971}]}