diff --git a/data/aniworld.db-shm b/data/aniworld.db-shm deleted file mode 100644 index 28bdbff..0000000 Binary files a/data/aniworld.db-shm and /dev/null differ diff --git a/data/aniworld.db-wal b/data/aniworld.db-wal deleted file mode 100644 index 88239f6..0000000 Binary files a/data/aniworld.db-wal and /dev/null differ diff --git a/data/config.json b/data/config.json index 00f0f90..962f090 100644 --- a/data/config.json +++ b/data/config.json @@ -17,7 +17,8 @@ "keep_days": 30 }, "other": { - "master_password_hash": "$pbkdf2-sha256$29000$MoYQ4tx7D8FY631P6b3Xeg$Lkk9WJI928F4EzBrUe1VnRD9LgKzy31zoygoIGQwqKY" + "master_password_hash": "$pbkdf2-sha256$29000$aq3VOsfY21sLwfgfQwghJA$d33KHoETVV5.zpCfR.BqM.ICe.DwjDcfATrsrsZ/3yM", + "anime_directory": "/mnt/server/serien/Serien/" }, "version": "1.0.0" } \ No newline at end of file diff --git a/data/config_backups/config_backup_20251224_213449.json b/data/config_backups/config_backup_20251224_213449.json deleted file mode 100644 index a7ff8d9..0000000 --- a/data/config_backups/config_backup_20251224_213449.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "Aniworld", - "data_dir": "data", - "scheduler": { - "enabled": true, - "interval_minutes": 60 - }, - "logging": { - "level": "INFO", - "file": null, - "max_bytes": null, - "backup_count": 3 - }, - "backup": { - "enabled": false, - "path": "data/backups", - "keep_days": 30 - }, - "other": { - "master_password_hash": "$pbkdf2-sha256$29000$4tyb09q7F.I8JwSgtPYe4w$MpmQLy0b1tYvjqNwwbHy4b59AxtjZdQ8eqrYlbrwmO4" - }, - "version": "1.0.0" -} \ No newline at end of file diff --git a/data/config_backups/config_backup_20251224_213458.json b/data/config_backups/config_backup_20251224_213458.json deleted file mode 100644 index e265d49..0000000 --- a/data/config_backups/config_backup_20251224_213458.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "Aniworld", - "data_dir": "data", - "scheduler": { - "enabled": true, - "interval_minutes": 60 - }, - "logging": { - "level": "INFO", - "file": null, - "max_bytes": null, - "backup_count": 3 - }, - "backup": { - "enabled": false, - "path": "data/backups", - "keep_days": 30 - }, - "other": { - "master_password_hash": "$pbkdf2-sha256$29000$vBdCKMUYA.Dc.7.3NqbUGg$2GOV4HuUcrl8Dolk3bzmXsOqG/xC/rCmzd1G2lIWtog" - }, - "version": "1.0.0" -} \ No newline at end of file diff --git a/data/config_backups/config_backup_20251225_134617.json b/data/config_backups/config_backup_20251225_134617.json deleted file mode 100644 index 2df654f..0000000 --- a/data/config_backups/config_backup_20251225_134617.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "Aniworld", - "data_dir": "data", - "scheduler": { - "enabled": true, - "interval_minutes": 60 - }, - "logging": { - "level": "INFO", - "file": null, - "max_bytes": null, - "backup_count": 3 - }, - "backup": { - "enabled": false, - "path": "data/backups", - "keep_days": 30 - }, - "other": { - "master_password_hash": "$pbkdf2-sha256$29000$gvDe27t3TilFiHHOuZeSMg$zEPyA6XcqVVTz7raeXZnMtGt/Q5k8ZCl204K0hx5z0w" - }, - "version": "1.0.0" -} \ No newline at end of file diff --git a/data/config_backups/config_backup_20251225_134748.json b/data/config_backups/config_backup_20251225_134748.json deleted file mode 100644 index af12236..0000000 --- a/data/config_backups/config_backup_20251225_134748.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "Aniworld", - "data_dir": "data", - "scheduler": { - "enabled": true, - "interval_minutes": 60 - }, - "logging": { - "level": "INFO", - "file": null, - "max_bytes": null, - "backup_count": 3 - }, - "backup": { - "enabled": false, - "path": "data/backups", - "keep_days": 30 - }, - "other": { - "master_password_hash": "$pbkdf2-sha256$29000$1pqTMkaoFSLEWKsVAmBsDQ$DHVcHMFFYJxzYmc.7LnDru61mYtMv9PMoxPgfuKed/c" - }, - "version": "1.0.0" -} \ No newline at end of file diff --git a/data/config_backups/config_backup_20251225_180408.json b/data/config_backups/config_backup_20251225_180408.json deleted file mode 100644 index 7686eb1..0000000 --- a/data/config_backups/config_backup_20251225_180408.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "Aniworld", - "data_dir": "data", - "scheduler": { - "enabled": true, - "interval_minutes": 60 - }, - "logging": { - "level": "INFO", - "file": null, - "max_bytes": null, - "backup_count": 3 - }, - "backup": { - "enabled": false, - "path": "data/backups", - "keep_days": 30 - }, - "other": { - "master_password_hash": "$pbkdf2-sha256$29000$ndM6hxDC.F8LYUxJCSGEEA$UHGXMaEruWVgpRp8JI/siGETH8gOb20svhjy9plb0Wo" - }, - "version": "1.0.0" -} \ No newline at end of file diff --git a/docs/instructions.md b/docs/instructions.md index f55bfd7..27ac236 100644 --- a/docs/instructions.md +++ b/docs/instructions.md @@ -105,786 +105,3 @@ For each task completed: - [ ] Take the next task --- - -## Task: Refactor CSS & JavaScript Files (Single Responsibility Principle) ✅ COMPLETED - -### Status: COMPLETED - -The CSS and JavaScript files have been successfully refactored into modular structures. - -### Summary of Changes - -**CSS Refactoring:** - -- Created 17 modular CSS files organized into `base/`, `components/`, `pages/`, and `utilities/` directories -- `styles.css` now serves as an entry point with @import statements -- All CSS files under 500 lines (largest: helpers.css at 368 lines) -- Total: 3,146 lines across 17 files - -**JavaScript Refactoring:** - -- Created 6 shared utility modules in `js/shared/` -- Created 11 index page modules in `js/index/` -- Created 5 queue page modules in `js/queue/` -- Uses IIFE pattern with `AniWorld` namespace for browser compatibility -- All JS files under 500 lines (largest: scan-manager.js at 439 lines) -- Total: 4,795 lines across 22 modules - -**Updated Files:** - -- `index.html` - Updated script tags for modular JS -- `queue.html` - Updated script tags for modular JS -- `test_static_files.py` - Updated tests for modular architecture -- `test_template_integration.py` - Updated tests for new JS structure -- `ARCHITECTURE.md` - Added frontend architecture documentation - -**Old Files (kept for reference):** - -- `app.js` - Original monolithic file (can be deleted) -- `queue.js` - Original monolithic file (can be deleted) - -### Original Overview - -Split monolithic `styles.css` (~2,135 lines), `app.js` (~2,305 lines), and `queue.js` (~993 lines) into smaller, focused files following the Single Responsibility Principle. Maximum 500 lines per file. All changes must maintain full backward compatibility with existing templates. - -### Prerequisites - -- Server is running and functional before starting -- All existing functionality works (login, index, queue pages) -- Backup current files before making changes - ---- - -### Task 1: Analyze Current File Structure - -**Objective**: Understand the current codebase before making changes. - -**Steps**: - -1. Open and read `src/server/web/static/css/styles.css` -2. Open and read `src/server/web/static/js/app.js` -3. Open and read `src/server/web/static/js/queue.js` -4. Open and read `src/server/web/templates/index.html` -5. Open and read `src/server/web/templates/queue.html` -6. Open and read `src/server/web/templates/login.html` -7. Document all CSS sections (look for comment headers) -8. Document all JavaScript functions and their dependencies -9. Identify shared utilities vs page-specific code - -**Deliverable**: A mental map of all functions, styles, and their relationships. - ---- - -### Task 2: Create CSS Directory Structure - -**Objective**: Set up the new CSS file organization. - -**Steps**: - -1. Create directory: `src/server/web/static/css/base/` -2. Create directory: `src/server/web/static/css/components/` -3. Create directory: `src/server/web/static/css/pages/` -4. Create directory: `src/server/web/static/css/utilities/` - -**File Structure to Create**: - -``` -src/server/web/static/css/ -├── styles.css # Main entry point with @import statements -├── base/ -│ ├── variables.css # CSS custom properties (colors, fonts, spacing) -│ ├── reset.css # CSS reset and normalize styles -│ └── typography.css # Font styles, headings, text utilities -├── components/ -│ ├── buttons.css # All button styles -│ ├── cards.css # Card and panel components -│ ├── forms.css # Form inputs, labels, validation styles -│ ├── modals.css # Modal and overlay styles -│ ├── navigation.css # Header, nav, sidebar styles -│ ├── progress.css # Progress bars, loading indicators -│ ├── notifications.css # Toast, alerts, messages -│ └── tables.css # Table and list styles -├── pages/ -│ ├── login.css # Login page specific styles -│ ├── index.css # Index/library page specific styles -│ └── queue.css # Queue page specific styles -└── utilities/ - ├── animations.css # Keyframes and animation classes - ├── responsive.css # Media queries and breakpoints - └── helpers.css # Utility classes (hidden, flex, spacing) -``` - ---- - -### Task 3: Split styles.css into Modular Files - -**Objective**: Extract styles from `styles.css` into appropriate module files. - -**Steps**: - -1. **Extract variables.css**: - - - Find all `:root` CSS custom properties - - Extract color variables, font variables, spacing variables - - Include dark mode variables (`.dark-mode` or `[data-theme="dark"]`) - -2. **Extract reset.css**: - - - Extract `*`, `body`, `html` base resets - - Extract box-sizing rules - - Extract default margin/padding resets - -3. **Extract typography.css**: - - - Extract `h1-h6` styles - - Extract paragraph, link, text styles - - Extract font-related utility classes - -4. **Extract buttons.css**: - - - Find all `.btn`, `button`, `.button` related styles - - Include hover, active, disabled states - - Include button variants (primary, secondary, danger, etc.) - -5. **Extract cards.css**: - - - Extract `.card`, `.panel`, `.box` related styles - - Include card headers, bodies, footers - -6. **Extract forms.css**: - - - Extract `input`, `select`, `textarea` styles - - Extract `.form-group`, `.form-control` styles - - Extract validation states (error, success) - -7. **Extract modals.css**: - - - Extract `.modal`, `.overlay`, `.dialog` styles - - Include backdrop styles - - Include modal animations - -8. **Extract navigation.css**: - - - Extract `header`, `nav`, `.navbar` styles - - Extract menu and navigation link styles - -9. **Extract progress.css**: - - - Extract `.progress`, `.progress-bar` styles - - Extract loading spinners and indicators - -10. **Extract notifications.css**: - - - Extract `.toast`, `.alert`, `.notification` styles - - Include success, error, warning, info variants - -11. **Extract tables.css**: - - - Extract `table`, `.table` styles - - Extract list styles if table-like - -12. **Extract page-specific styles**: - - - `login.css`: Styles only used on login page - - `index.css`: Styles only used on index/library page (series cards, search) - - `queue.css`: Styles only used on queue page (queue items, download status) - -13. **Extract animations.css**: - - - Extract all `@keyframes` rules - - Extract animation utility classes - -14. **Extract responsive.css**: - - - Extract all `@media` queries - - Organize by breakpoint - -15. **Extract helpers.css**: - - - Extract utility classes (.hidden, .flex, .text-center, etc.) - - Extract spacing utilities - -16. **Update main styles.css**: - - Replace all content with `@import` statements - - Order imports correctly (variables first, then reset, then components) - -**Import Order in styles.css**: - -```css -/* Base */ -@import "base/variables.css"; -@import "base/reset.css"; -@import "base/typography.css"; - -/* Components */ -@import "components/buttons.css"; -@import "components/cards.css"; -@import "components/forms.css"; -@import "components/modals.css"; -@import "components/navigation.css"; -@import "components/progress.css"; -@import "components/notifications.css"; -@import "components/tables.css"; - -/* Pages */ -@import "pages/login.css"; -@import "pages/index.css"; -@import "pages/queue.css"; - -/* Utilities (load last to allow overrides) */ -@import "utilities/animations.css"; -@import "utilities/responsive.css"; -@import "utilities/helpers.css"; -``` - -**Verification**: - -- Start the server -- Check login page styling -- Check index page styling -- Check queue page styling -- Verify dark mode toggle works -- Verify responsive design works - ---- - -### Task 4: Create JavaScript Directory Structure - -**Objective**: Set up the new JavaScript file organization. - -**Steps**: - -1. Create directory: `src/server/web/static/js/shared/` -2. Create directory: `src/server/web/static/js/index/` -3. Create directory: `src/server/web/static/js/queue/` - -**File Structure to Create**: - -``` -src/server/web/static/js/ -├── app.js # Main entry point for index page -├── queue.js # Main entry point for queue page -├── shared/ -│ ├── auth.js # Authentication utilities -│ ├── api-client.js # HTTP request wrapper with auth -│ ├── websocket-client.js # WebSocket connection management -│ ├── theme.js # Dark/light mode management -│ ├── ui-utils.js # Toast, loading overlay, formatters -│ └── constants.js # Shared constants and config -├── index/ -│ ├── series-manager.js # Series loading, filtering, rendering -│ ├── search.js # Search functionality -│ ├── scan-manager.js # Library scan operations -│ ├── config-manager.js # Configuration modal handling -│ └── selection.js # Series/episode selection logic -└── queue/ - ├── queue-api.js # Queue API operations - ├── queue-renderer.js # Render queue items (pending, active, etc.) - └── progress-handler.js # Real-time progress updates -``` - ---- - -### Task 5: Extract Shared JavaScript Utilities - -**Objective**: Create reusable utility modules used by both index and queue pages. - -**Steps**: - -1. **Create constants.js**: - - - Extract API endpoint URLs - - Extract localStorage keys - - Extract any magic strings or numbers - -2. **Create auth.js**: - - - Extract `checkAuth()` function - - Extract `logout()` function - - Extract `getAuthHeaders()` or token retrieval logic - - Extract token storage/retrieval from localStorage - -3. **Create api-client.js**: - - - Extract `fetchWithAuth()` wrapper function - - Handle automatic token injection - - Handle 401 redirect to login - - Handle common error responses - -4. **Create websocket-client.js**: - - - Extract WebSocket connection setup - - Extract message handling dispatcher - - Extract reconnection logic - - Extract connection state management - -5. **Create theme.js**: - - - Extract `initTheme()` function - - Extract `toggleTheme()` function - - Extract `setTheme()` function - - Extract theme persistence to localStorage - -6. **Create ui-utils.js**: - - Extract `showToast()` function - - Extract `showLoadingOverlay()` / `hideLoadingOverlay()` - - Extract `formatBytes()` function - - Extract `formatDuration()` function - - Extract `formatDate()` function - - Extract any other shared UI helpers - -**Pattern to Use (IIFE with Global Namespace)**: - -```javascript -// Example: shared/auth.js -var AniWorld = window.AniWorld || {}; - -AniWorld.Auth = (function () { - "use strict"; - - const TOKEN_KEY = "auth_token"; - - function getToken() { - return localStorage.getItem(TOKEN_KEY); - } - - function setToken(token) { - localStorage.setItem(TOKEN_KEY, token); - } - - function removeToken() { - localStorage.removeItem(TOKEN_KEY); - } - - function getAuthHeaders() { - const token = getToken(); - return token ? { Authorization: "Bearer " + token } : {}; - } - - async function checkAuth() { - // Implementation - } - - function logout() { - removeToken(); - window.location.href = "/login"; - } - - // Public API - return { - getToken: getToken, - setToken: setToken, - getAuthHeaders: getAuthHeaders, - checkAuth: checkAuth, - logout: logout, - }; -})(); -``` - ---- - -### Task 6: Split app.js into Index Page Modules - -**Objective**: Break down `app.js` into focused modules for the index/library page. - -**Steps**: - -1. **Create series-manager.js**: - - - Extract series loading from API - - Extract series filtering logic - - Extract series rendering/DOM updates - - Extract series card click handlers - -2. **Create search.js**: - - - Extract search input handling - - Extract search API calls - - Extract search results rendering - - Extract search result selection - -3. **Create scan-manager.js**: - - - Extract scan initiation logic - - Extract scan progress overlay - - Extract scan progress updates (WebSocket) - - Extract scan completion handling - -4. **Create config-manager.js**: - - - Extract config modal open/close - - Extract config loading from API - - Extract config form handling - - Extract config save logic - - Extract scheduler configuration - - Extract backup management - -5. **Create selection.js**: - - - Extract episode selection logic - - Extract "select all" functionality - - Extract selection state management - - Extract "add to queue" from selection - -6. **Update main app.js**: - - Import all modules via script tags - - Initialize all modules on DOMContentLoaded - - Wire up event listeners to module functions - - Keep this file as thin as possible (orchestration only) - -**Example main app.js structure**: - -```javascript -// filepath: src/server/web/static/js/app.js -document.addEventListener("DOMContentLoaded", async function () { - "use strict"; - - // Initialize shared modules - AniWorld.Theme.init(); - - // Check authentication - const isAuth = await AniWorld.Auth.checkAuth(); - if (!isAuth) return; - - // Initialize page-specific modules - AniWorld.SeriesManager.init(); - AniWorld.Search.init(); - AniWorld.ScanManager.init(); - AniWorld.ConfigManager.init(); - AniWorld.Selection.init(); - - // Initialize WebSocket for real-time updates - AniWorld.WebSocketClient.init(); - - // Load initial data - AniWorld.SeriesManager.loadSeries(); -}); -``` - ---- - -### Task 7: Split queue.js into Queue Page Modules - -**Objective**: Break down `queue.js` into focused modules for the queue page. - -**Steps**: - -1. **Create queue-api.js**: - - - Extract `loadQueueStatus()` API call - - Extract `startDownload()` API call - - Extract `stopDownload()` API call - - Extract `removeFromQueue()` API call - - Extract `clearCompleted()` API call - - Extract `clearFailed()` API call - - Extract `retryFailed()` API call - -2. **Create queue-renderer.js**: - - - Extract `renderActiveDownload()` function - - Extract `renderPendingQueue()` function - - Extract `renderCompletedList()` function - - Extract `renderFailedList()` function - - Extract `updateQueueCounts()` function - - Extract queue item template generation - -3. **Create progress-handler.js**: - - - Extract WebSocket message handling for queue - - Extract progress bar updates - - Extract status text updates - - Extract ETA calculations - - Extract speed display formatting - -4. **Update main queue.js**: - - Import all modules via script tags - - Initialize all modules on DOMContentLoaded - - Wire up button click handlers to API functions - - Set up WebSocket handlers for progress - - Keep this file as thin as possible - -**Example main queue.js structure**: - -```javascript -// filepath: src/server/web/static/js/queue.js -document.addEventListener("DOMContentLoaded", async function () { - "use strict"; - - // Initialize shared modules - AniWorld.Theme.init(); - - // Check authentication - const isAuth = await AniWorld.Auth.checkAuth(); - if (!isAuth) return; - - // Initialize queue modules - AniWorld.QueueApi.init(); - AniWorld.QueueRenderer.init(); - AniWorld.ProgressHandler.init(); - - // Initialize WebSocket with queue-specific handlers - AniWorld.WebSocketClient.init({ - onProgress: AniWorld.ProgressHandler.handleProgress, - onQueueUpdate: AniWorld.QueueRenderer.refresh, - }); - - // Load initial queue status - await AniWorld.QueueApi.loadStatus(); - AniWorld.QueueRenderer.refresh(); - - // Wire up UI buttons - document - .getElementById("start-btn") - ?.addEventListener("click", AniWorld.QueueApi.startDownload); - document - .getElementById("stop-btn") - ?.addEventListener("click", AniWorld.QueueApi.stopDownload); - document - .getElementById("clear-completed-btn") - ?.addEventListener("click", AniWorld.QueueApi.clearCompleted); - document - .getElementById("clear-failed-btn") - ?.addEventListener("click", AniWorld.QueueApi.clearFailed); -}); -``` - ---- - -### Task 8: Update HTML Templates - -**Objective**: Update templates to load the new modular JavaScript files. - -**Steps**: - -1. **Update index.html**: - - - Add script tags for shared modules (in order) - - Add script tags for index-specific modules (in order) - - Keep main app.js as the last script - - Ensure correct load order (dependencies first) - - ```html - - - - - - - - - - - - - - - - - - ``` - -2. **Update queue.html**: - - - Add script tags for shared modules (in order) - - Add script tags for queue-specific modules (in order) - - Keep main queue.js as the last script - - ```html - - - - - - - - - - - - - - - - ``` - -3. **Update login.html** (if applicable): - - Only include shared modules needed for login - - Likely just theme.js and minimal utilities - ---- - -### Task 9: Verification and Testing - -**Objective**: Ensure all functionality works after refactoring. - -**Steps**: - -1. **Start the server**: - - ```bash - conda run -n AniWorld python -m uvicorn src.server.fastapi_app:app --host 127.0.0.1 --port 8000 --reload - ``` - -2. **Test Login Page**: - - - [ ] Page loads with correct styling - - [ ] Dark/light mode toggle works - - [ ] Login form submits correctly - - [ ] Error messages display correctly - - [ ] Successful login redirects to index - -3. **Test Index Page**: - - - [ ] Page loads with correct styling - - [ ] Series list loads and displays - - [ ] Series filtering works - - [ ] Search functionality works - - [ ] Series selection works - - [ ] Episode selection works - - [ ] Add to queue works - - [ ] Scan library works - - [ ] Scan progress displays - - [ ] Config modal opens/closes - - [ ] Config saves correctly - - [ ] Dark/light mode toggle works - - [ ] Logout works - - [ ] WebSocket connection established - -4. **Test Queue Page**: - - - [ ] Page loads with correct styling - - [ ] Queue status loads - - [ ] Pending items display - - [ ] Active download displays - - [ ] Completed items display - - [ ] Failed items display - - [ ] Start download works - - [ ] Stop download works - - [ ] Remove from queue works - - [ ] Clear completed works - - [ ] Clear failed works - - [ ] Retry failed works - - [ ] Progress updates in real-time - - [ ] Dark/light mode toggle works - - [ ] WebSocket connection established - -5. **Test Responsive Design**: - - - [ ] All pages work on mobile viewport - - [ ] All pages work on tablet viewport - - [ ] All pages work on desktop viewport - -6. **Browser Console Check**: - - [ ] No JavaScript errors in console - - [ ] No 404 errors for static files - - [ ] No CSS loading errors - ---- - -### Task 10: Cleanup and Documentation - -**Objective**: Finalize the refactoring with cleanup and documentation. - -**Steps**: - -1. **Remove backup files** (if any were created) - -2. **Verify file sizes**: - - - No file should exceed 500 lines - - If any file exceeds, split further - -3. **Add file headers**: - - - Add comment header to each new file explaining its purpose - - ```javascript - /** - * AniWorld - Series Manager Module - * - * Handles loading, filtering, and rendering of anime series - * on the index/library page. - * - * Dependencies: auth.js, api-client.js, ui-utils.js - */ - ``` - - ```css - /** - * AniWorld - Button Styles - * - * All button-related styles including variants, - * states, and sizes. - */ - ``` - -4. **Update infrastructure.md** (if exists): - - - Document new file structure - - Document module dependencies - -5. **Commit changes**: - ```bash - git add . - git commit -m "refactor: split CSS and JS into modular files (SRP)" - ``` - ---- - -### Summary of New Files - -**CSS Files (14 files)**: - -- `css/styles.css` (entry point with imports) -- `css/base/variables.css` -- `css/base/reset.css` -- `css/base/typography.css` -- `css/components/buttons.css` -- `css/components/cards.css` -- `css/components/forms.css` -- `css/components/modals.css` -- `css/components/navigation.css` -- `css/components/progress.css` -- `css/components/notifications.css` -- `css/components/tables.css` -- `css/pages/login.css` -- `css/pages/index.css` -- `css/pages/queue.css` -- `css/utilities/animations.css` -- `css/utilities/responsive.css` -- `css/utilities/helpers.css` - -**JavaScript Files (15 files)**: - -- `js/app.js` (entry point for index) -- `js/queue.js` (entry point for queue) -- `js/shared/constants.js` -- `js/shared/auth.js` -- `js/shared/api-client.js` -- `js/shared/websocket-client.js` -- `js/shared/theme.js` -- `js/shared/ui-utils.js` -- `js/index/series-manager.js` -- `js/index/search.js` -- `js/index/scan-manager.js` -- `js/index/config-manager.js` -- `js/index/selection.js` -- `js/queue/queue-api.js` -- `js/queue/queue-renderer.js` -- `js/queue/progress-handler.js` - ---- - -### Important Notes - -1. **IIFE Pattern**: Use the IIFE (Immediately Invoked Function Expression) pattern with a global namespace (`AniWorld`) for browser compatibility without requiring a build step. - -2. **No Build Tools Required**: This approach uses native CSS `@import` and multiple `