Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4789f73ae7 | |||
| 24051a2794 | |||
| 3fc2087ee1 | |||
| 19d9bf3c9e | |||
| e9c710ec0b | |||
| e96aecfdf1 | |||
| f9438b10b6 | |||
| bc759dd99a | |||
| 3f35b84535 | |||
| 6edf526d27 | |||
| fc24b08505 | |||
| 0f78093ce2 | |||
| 029ed1c456 | |||
| 9ef622f29a |
@@ -0,0 +1,44 @@
|
||||
# ── Docker build context — loại bỏ mã nguồn/bí mật không cần vào image ──
|
||||
.git
|
||||
.gitignore
|
||||
.github
|
||||
|
||||
# Mã nguồn client (JSX) — image CHỈ chứa bản precompiled (minified)
|
||||
app/static/js/app.jsx
|
||||
app/static/js/app.jsx.new
|
||||
*.jsx
|
||||
|
||||
# Bí mật
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
|
||||
# Dependencies / build cache
|
||||
node_modules
|
||||
__pycache__
|
||||
*.pyc
|
||||
.cache
|
||||
.pytest_cache
|
||||
|
||||
# Tài liệu / kế hoạch / backup nội bộ
|
||||
wiki.md
|
||||
PLAN.md
|
||||
PLAN*
|
||||
plans/
|
||||
md/
|
||||
*.patch
|
||||
*.recovered
|
||||
index.html.recovered
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# Dữ liệu runtime (mount volume riêng — KHÔNG chép vào image)
|
||||
app/storage/uploads
|
||||
app/storage/processed
|
||||
app/storage/sonicforge.db
|
||||
celerybeat-schedule
|
||||
|
||||
# Test
|
||||
tests/
|
||||
tools/
|
||||
samples/
|
||||
@@ -0,0 +1,17 @@
|
||||
# ── SonicForge Studio — môi trường (SAO CHÉP sang .env — KHÔNG commit .env) ──
|
||||
|
||||
# Redis / Celery
|
||||
REDIS_URL=redis://redis:6379/0
|
||||
CELERY_BROKER_URL=redis://redis:6379/0
|
||||
CELERY_RESULT_BACKEND=redis://redis:6379/0
|
||||
|
||||
# LLM (server-side proxy — client không thấy key)
|
||||
OPENAI_API_BASE=http://localhost:11434/v1
|
||||
OPENAI_API_KEY=ollama
|
||||
|
||||
# Auth
|
||||
SECRET_KEY=thay-bang-chuoi-ngau-nhien-dai
|
||||
DEFAULT_ADMIN_PASSWORD=thay-mat-khau-admin
|
||||
|
||||
# Storage (đường dẫn trong container)
|
||||
STORAGE_DIR=/app/app/storage
|
||||
@@ -0,0 +1,63 @@
|
||||
name: windows-build
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
tags: ['v*']
|
||||
|
||||
jobs:
|
||||
build-windows:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
|
||||
- name: Setup Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
- name: Install backend deps
|
||||
run: |
|
||||
pip install pyinstaller pywin32
|
||||
pip install -r requirements.txt
|
||||
# pedalboard --no-deps: tránh supertonic (kéo onnx2tf/opencv/pocket-tts —
|
||||
# xung đột numpy<2 vs >=2 — 2026-08-08)
|
||||
pip install --no-deps pedalboard>=0.8.0
|
||||
|
||||
- name: Precompile JS (Babel)
|
||||
shell: bash
|
||||
run: |
|
||||
npm install --no-audit --no-fund 2>/dev/null || true
|
||||
node node_modules/@babel/cli/bin/babel.js app/static/js/app.jsx --config-file ./babel.config.json -o app/static/js/app.precompiled.js
|
||||
|
||||
- name: Build daw_engine.exe (PyInstaller)
|
||||
run: pyinstaller engine.spec --clean --noconfirm
|
||||
|
||||
- name: Stage sidecar binary (Tauri naming)
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p src-tauri/binaries
|
||||
cp dist/daw_engine.exe "src-tauri/binaries/daw_engine-x86_64-pc-windows-msvc.exe"
|
||||
|
||||
- name: Install Tauri CLI
|
||||
run: npm install -D @tauri-apps/cli@^2
|
||||
|
||||
- name: Build Windows installers (NSIS + MSI)
|
||||
run: npx tauri build --no-bundle 2>/dev/null || npx tauri build
|
||||
|
||||
- name: Upload installer artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: SonicForgeDAW-windows
|
||||
path: |
|
||||
src-tauri/target/release/bundle/nsis/*.exe
|
||||
src-tauri/target/release/bundle/msi/*.msi
|
||||
dist/daw_engine.exe
|
||||
@@ -0,0 +1,45 @@
|
||||
# BUILD WINDOWS — hướng dẫn build installer (.exe) trên máy Windows
|
||||
|
||||
## Yêu cầu trước khi build
|
||||
| Thành phần | Cài từ | Ghi chú |
|
||||
|---|---|---|
|
||||
| **Python 3.11+** | python.org | Tick **"Add to PATH"** |
|
||||
| **Node.js 20+** | nodejs.org | |
|
||||
| **Rust (MSVC toolchain)** | https://rustup.rs (hoặc script tự cài) | Cần cho Tauri |
|
||||
| **Visual Studio Build Tools** | visualstudio.microsoft.com | Workload **"Desktop development with C++"** (bắt buộc — MSVC linker cho Rust/Tauri) |
|
||||
| **WebView2 Runtime** | Windows 10/11 có sẵn; Windows 7/8 tải từ Microsoft | Tauri yêu cầu |
|
||||
|
||||
> Nếu lỗi `cargo: program not found` → chưa cài Rust: chạy `rustup-init.exe -y` rồi **mở cmd MỚI** (PATH refresh).
|
||||
|
||||
## Cách build — 1 lệnh
|
||||
```bat
|
||||
build_windows.bat
|
||||
```
|
||||
Script tự làm: cài Rust (nếu thiếu) → pip deps → Babel precompile → `pyinstaller engine.spec` (daw_engine.exe) → copy sidecar → `npx tauri build`.
|
||||
|
||||
## Kết quả
|
||||
```
|
||||
src-tauri\target\release\bundle\nsis\SonicForgeDAW_1.0.0_x64-setup.exe ← cài đặt (.exe)
|
||||
src-tauri\target\release\bundle\msi\SonicForgeDAW_1.0.0_x64_en-US.msi ← MSI
|
||||
dist\daw_engine.exe ← engine đơn (debug)
|
||||
```
|
||||
|
||||
## Thủ công (không dùng script)
|
||||
```bat
|
||||
pip install pyinstaller pywin32
|
||||
pip install -r requirements.txt
|
||||
pip install --no-deps pedalboard>=0.8.0
|
||||
node node_modules/@babel/cli/bin/babel.js app/static/js/app.jsx --config-file ./babel.config.json -o app/static/js/app.precompiled.js
|
||||
pyinstaller engine.spec --clean --noconfirm
|
||||
mkdir src-tauri\binaries
|
||||
copy dist\daw_engine.exe src-tauri\binaries\daw_engine-x86_64-pc-windows-msvc.exe
|
||||
npm install -D @tauri-apps/cli@^2
|
||||
npx tauri build
|
||||
```
|
||||
|
||||
## Kiểm thử sau cài (spec — mục IV)
|
||||
1. Mở app → Task Manager: `daw_engine.exe` chạy nền; đóng app → tiến trình tắt hẳn (không orphan).
|
||||
2. Browser ngoài mở `http://localhost:8000/docs` → Swagger hiển thị.
|
||||
3. Plugin Manager → path `C:\Program Files\Common Files\VST3` → Scan → tìm thấy VST3 (Vital, Surge XT...).
|
||||
4. Export WAV → file chứa tiếng VST3 (qua pedalboard).
|
||||
5. Dữ liệu lưu tại `%APPDATA%\SonicForgeDAW\`.
|
||||
@@ -0,0 +1,87 @@
|
||||
# DESKTOP INSTALL PLAN — SonicForge Studio (bản cài trực tiếp trên OS)
|
||||
|
||||
Mô hình: **server chạy nền trên máy người dùng (localhost), client mở bằng browser**.
|
||||
Không cần Electron — tận dụng stack hiện có (FastAPI + static JS precompiled).
|
||||
Soundfonts do **người dùng tự tải vào thư mục riêng** và **khai báo** cho ứng dụng.
|
||||
|
||||
---
|
||||
|
||||
## 1. KIẾN TRÚC
|
||||
|
||||
```
|
||||
┌─────────────────────────── NGƯỜI DÙNG (1 máy) ───────────────────────────┐
|
||||
│ Browser ──http://127.0.0.1:8000──▶ FastAPI (uvicorn, chạy NỀN) │
|
||||
│ │ │
|
||||
│ ~/SonicForgeStudio/ ├─ data/ (DB, uploads, cache) │
|
||||
│ ├─ data/sonicforge.db ├─ soundfonts/ (user tự bỏ .sf2) │
|
||||
│ ├─ soundfonts/*.sf2/.sf3 └─ quét nền 30s (scanner có sẵn) │
|
||||
│ └─ config.json ← khai báo folder soundfont │
|
||||
└──────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 2. ĐÓNG GÓI CÀI ĐẶT (per-OS) — server nền + browser client
|
||||
|
||||
### Thành phần đóng gói
|
||||
| Thành phần | Vai trò |
|
||||
|---|---|
|
||||
| Python backend (`app/`, `requirements.txt`) | Server — **PyInstaller `--onedir`** → binary (không cần Python trên máy user; bảo vệ source tốt hơn so với chạy .py) |
|
||||
| `app/static/` (precompiled.js + css + vendor) | Client — đóng vào package, server phục vụ |
|
||||
| VST3 plugins (`vst_plugins/`) | Copy theo platform (win .dll / mac .vst3 / linux .so) |
|
||||
| Service wrapper | Tự khởi động server nền + mở browser khi login |
|
||||
|
||||
### Cài đặt + service nền theo OS
|
||||
| OS | Installer | Service nền | Auto-open browser |
|
||||
|---|---|---|---|
|
||||
| **Windows** | Inno Setup (`.exe`) | Windows Service qua `NSSM`/`WinSW` hoặc Task Scheduler (logon) | `start http://127.0.0.1:8000` |
|
||||
| **macOS** | `.dmg` + `.app` (PyInstaller) | `launchd` LaunchAgent (`~/Library/LaunchAgents`) | `open http://127.0.0.1:8000` |
|
||||
| **Linux** | `.deb` / `.AppImage` | systemd **user** service (`~/.config/systemd/user/`) | `xdg-open http://127.0.0.1:8000` |
|
||||
|
||||
- Server bind **`127.0.0.1`** (không lộ mạng), port mặc định 8000 (config được).
|
||||
- App gồm 2 tiến trình nhỏ: `web` (uvicorn) + `worker` (celery) — hoặc gộp worker vào web ở chế độ desktop (đơn giản: `--pool=solo`, chạy celery trong tiến trình riêng nếu cần render nặng).
|
||||
|
||||
## 3. THƯ MỤC DỮ LIỆU NGƯỜI DÙNG
|
||||
```
|
||||
~/SonicForgeStudio/
|
||||
├── data/ # DB, uploads, processed (thay app/storage khi chạy desktop)
|
||||
├── soundfonts/ # USER tự tải .sf2/.sf3 vào đây (mặc định được quét)
|
||||
└── config.json # cấu hình: soundfont_dirs, port, autostart...
|
||||
```
|
||||
- `config.py`: thêm `DATA_DIR` (env `SFDATA_DIR`, mặc định `~/SonicForgeStudio/data`), `SOUNDFONT_DIRS`.
|
||||
|
||||
## 4. SOUNDFONT DO NGƯỜI DÙNG QUẢN LÝ (tải + khai báo)
|
||||
**Cơ chế hiện có (tận dụng):** `app/core/soundfont_scanner.py` — `SoundFontAutoScanner` quét nền 30s
|
||||
`/opt/daw_engine/soundfonts` + `storage/soundfonts` → catalog → API list qua `app/api/v1/plugins.py`.
|
||||
|
||||
**Việc cần làm (mở rộng):**
|
||||
1. **Scanner nhận folder người dùng:** constructor nhận thêm `user_dirs` (từ `SOUNDFONT_DIRS` env + `config.json`) — merge vào catalog (ưu tiên: user > system).
|
||||
2. **Khai báo folder — 2 cách:**
|
||||
- **UI** (chính): Settings → "Soundfonts" → nút **Add folder…** (chọn thư mục chứa .sf2) → lưu vào `config.json` → gọi scanner rescan.
|
||||
- **config.json** (thủ công): `{ "soundfont_dirs": ["D:/SF", "/Users/me/sf"] }`.
|
||||
3. **API:** thêm endpoint `POST /api/v1/plugins/soundfonts/dirs` (đăng ký folder) + `GET .../dirs` (liệt kê) — scanner reload.
|
||||
4. **UI danh sách:** hiển thị catalog (tên SF, kích thước, folder nguồn) — chọn = load vào FluidSynth (luồng có sẵn qua `SonicSF.selectInstrument`).
|
||||
5. **Số hóa:** không upload file — server đọc trực tiếp từ đường dẫn user khai báo (không nhân đôi dữ liệu).
|
||||
|
||||
## 5. BUILD + PHÁT HÀNH
|
||||
```
|
||||
code → build.mjs (precompiled + ?v=) → PyInstaller (server binary) → đóng installer theo OS
|
||||
→ ký số (tùy chọn) → phát hành (GitHub Releases / trang riêng)
|
||||
```
|
||||
- **GitHub Actions matrix** (windows-latest / macos-latest / ubuntu-latest): test → build → installer artifact.
|
||||
- Installer gồm: binary server, static/, VST plugins nền tảng, script tạo service + mở browser, mặc định tạo `~/SonicForgeStudio/` lần chạy đầu.
|
||||
|
||||
## 6. CẬP NHẬT
|
||||
- **Version check**: khi mở app, gọi endpoint version (file `version.json` đóng kèm + so sánh remote) → thông báo bản mới + link tải installer.
|
||||
- Cập nhật = chạy installer mới (ghi đè, GIỮ NGUYÊN `~/SonicForgeStudio/` — data + soundfonts không đụng).
|
||||
- `?v=` cache-bust JS mỗi bản (cơ chế đã có) — browser không dính cache cũ.
|
||||
|
||||
## 7. CHECKLIST CODE CẦN LÀM
|
||||
- [ ] `config.py`: `DATA_DIR`, `SOUNDFONT_DIRS` (env + config.json)
|
||||
- [ ] `soundfont_scanner.py`: nhận `user_dirs`, merge catalog, ưu tiên user
|
||||
- [ ] API: `POST/GET .../soundfonts/dirs` (đăng ký/liệt kê folder) + rescan
|
||||
- [ ] UI Settings → Soundfonts (Add folder, Browse, list, load)
|
||||
- [ ] `soundfontStorage.js`: chuyển hướng sang catalog folder-scan (giữ upload path cho dự án cũ)
|
||||
- [ ] PyInstaller spec: bundle static/ + vendor (libfluidsynth wasm, vst), bind 127.0.0.1
|
||||
- [ ] Service wrappers: Windows (NSSM/WinSW), macOS (launchd), Linux (systemd user) + auto-open browser
|
||||
- [ ] Installer scripts: Inno Setup (.exe), dmg (macOS), deb/AppImage (Linux)
|
||||
- [ ] CI matrix build 3 OS + release artifacts
|
||||
- [ ] `version.json` + in-app update check
|
||||
@@ -0,0 +1,85 @@
|
||||
# DISTRIBUTION PLAN — SonicForge Studio (Alpha → Beta → Production)
|
||||
|
||||
Mục tiêu: phân phối ứng dụng cho người dùng **không chia sẻ mã nguồn**, có pipeline
|
||||
cập nhật liên tục. Áp dụng cho backend Python/FastAPI + frontend JS (Babel precompiled).
|
||||
|
||||
---
|
||||
|
||||
## 1. TÁCH BÍ MẬT — FILE .env
|
||||
|
||||
| Biến | Dùng cho | Bắt buộc |
|
||||
|---|---|---|
|
||||
| `REDIS_URL` | Redis/Celery broker | ✓ |
|
||||
| `CELERY_BROKER_URL` / `CELERY_RESULT_BACKEND` | Celery | ✓ |
|
||||
| `OPENAI_API_BASE` / `OPENAI_API_KEY` | LLM server-side (client KHÔNG thấy key — `aiGateway.js` chỉ gọi proxy server) | ✓ |
|
||||
| `SECRET_KEY` | Auth token (app/core/auth.py) | ✓ (mặc định trống → phải set) |
|
||||
| `DEFAULT_ADMIN_PASSWORD` | Admin mặc định | thay đổi ở production |
|
||||
|
||||
- File `.env.example` đã tạo (commit được). `.env` thật KHÔNG commit (đã vào `.dockerignore`).
|
||||
- **Nguyên tắc:** client JS không bao giờ chứa secret — mọi API key nằm server (env) hoặc proxy.
|
||||
|
||||
## 2. BUILD IMAGE — KHÔNG CHIA SẺ MÃ NGUỒN
|
||||
|
||||
### 2.1 Chặn source khỏi image (`.dockerignore` — đã tạo)
|
||||
Loại khỏi build context: `.git`, `app/static/js/app.jsx` (source JSX), `wiki.md`, `plans/`, `*.patch`, `.env`, `tests/`, `node_modules`, backup...
|
||||
|
||||
### 2.2 Frontend — chỉ ship bản precompiled
|
||||
- Build JS: `node build.mjs` (Babel → `app.precompiled.js` minified) — **CHỈ bản minified vào image**, source `.jsx` bị `.dockerignore` chặn.
|
||||
- Bump `?v=` (cache-bust) mỗi bản phát hành — user cập nhật không dính cache cũ.
|
||||
|
||||
### 2.3 Backend Python — giới hạn đọc source
|
||||
- Python không biên dịch native mặc định → `.py` vẫn đọc được trong image. 3 lớp bảo vệ:
|
||||
1. **Registry riêng tư** (GHCR / Docker Hub private / Harbor) — image KHÔNG public — người dùng chỉ nhận qua pull có auth.
|
||||
2. **Secret chỉ qua env** — không hardcode gì trong image.
|
||||
3. *(Tùy chọn, giai đoạn sau)* compile Python bằng **Nuitka** → `.so` cho `app/core`, `app/api` (giữ `main.py`/`config.py` đọc được — không chứa bí mật).
|
||||
|
||||
### 2.4 Cách build + push
|
||||
```bash
|
||||
# 1. Precompile JS + bump ?v=
|
||||
node build.mjs # hoặc: NODE=... babel ... (xem wiki)
|
||||
# 2. Build image (tag theo version)
|
||||
docker build -t ghcr.io/<org>/sonicforge-studio:v1.0.0-alpha.1 .
|
||||
docker push ghcr.io/<org>/sonicforge-studio:v1.0.0-alpha.1
|
||||
# 3. Production chạy image đã push (KHÔNG mount source):
|
||||
docker compose -f docker-compose.prod.yml up -d
|
||||
```
|
||||
- Compose production (`docker-compose.prod.yml` — đã tạo): image từ registry, `env_file: .env`,
|
||||
volumes bền (uploads/processed/db), asset dirs qua env (`VST3_DIR`, `SOUNDFONTS_DIR`, `PIANOBOOK_DIR`),
|
||||
KHÔNG có `.:/app` (bỏ mount dev của compose cũ).
|
||||
|
||||
## 3. KẾ HOẠCH PHÁT HÀNH
|
||||
|
||||
### Giai đoạn 1 — ALPHA (nội bộ dev/QA)
|
||||
- Tag: `v0.x.x-alpha.N` — chạy `docker compose up --build` (dev mount OK).
|
||||
- Log verbose; chưa quan tâm bảo mật; test tính năng + thu hồi nhanh.
|
||||
- Mỗi thay đổi: bump `?v=` → build → tag → ghi wiki.md.
|
||||
|
||||
### Giai đoạn 2 — BETA (nhóm người dùng mời)
|
||||
- Tag: `v0.x.x-beta.N` — image push **registry riêng tư**.
|
||||
- Người dùng: `docker compose -f docker-compose.prod.yml pull && up -d` (chỉ cần `.env` + image).
|
||||
- Thu log lỗi: thêm endpoint `/health` + (tùy chọn) Sentry/self-host error tracking.
|
||||
- **Feature flags** (biến env `FEATURE_*`) để tắt tính năng rủi ro từ xa.
|
||||
|
||||
### Giai đoạn 3 — PRODUCTION
|
||||
- Tag: `vX.Y.Z` (semver) + `latest`.
|
||||
- **Trước khi release:** backup volumes (`docker run --rm -v sf_db:/data -v $PWD:/backup alpine tar czf /backup/db-<ver>.tgz /data`), migrate dữ liệu nếu schema đổi.
|
||||
- Triển khai: pull image mới → recreate (rolling — web trước, worker sau) → healthcheck.
|
||||
- `SECRET_KEY`, `DEFAULT_ADMIN_PASSWORD`, API keys: quản lý qua secret manager (Docker secrets / vault) — không ở compose file.
|
||||
|
||||
## 4. PIPELINE CẬP NHẬT (lặp lại mỗi release)
|
||||
```
|
||||
code mới → build.mjs (precompiled + ?v=) → docker build (tag mới)
|
||||
→ push registry → [beta/prod] pull + recreate → backup trước nếu prod → kiểm tra /health
|
||||
```
|
||||
- Phiên bản: `git tag vX.Y.Z` — build tag tự động từ git (`git describe --tags`).
|
||||
- Rollback: giữ tag cũ — `docker compose -f docker-compose.prod.yml up -d` với `IMAGE=...:<tag cũ>`.
|
||||
|
||||
## 5. VIỆC CẦN LÀM (checklist)
|
||||
- [x] `.env.example` — liệt kê đủ 7 biến
|
||||
- [x] `.dockerignore` — chặn source/secret/docs
|
||||
- [x] `docker-compose.prod.yml` — production (registry + env_file + volumes, bỏ mount source)
|
||||
- [ ] Kiểm tra endpoint `/health` (tạo nếu chưa có — healthcheck compose đang trỏ tới)
|
||||
- [ ] Chọn registry (GHCR/Docker Hub private/Harbor) + tạo token CI
|
||||
- [ ] Nuitka compile `app/core`+`app/api` (tùy chọn — nếu cần bảo vệ backend chặt hơn)
|
||||
- [ ] CI (GitHub Actions): test → build → push tag → deploy beta tự động
|
||||
- [ ] Backup script volumes trước mỗi production release
|
||||
+27
-22
@@ -2,28 +2,33 @@
|
||||
FROM python:3.11-slim
|
||||
|
||||
# Cài đặt các gói thư viện đồ hoạ và asound bắt buộc đối với JUCE / VST3 Linux (22_CLIENT_DESK.md)
|
||||
RUN apt-get update && apt-get install -y \
|
||||
libgl1 \
|
||||
libglx-mesa0 \
|
||||
libglu1-mesa \
|
||||
libasound2 \
|
||||
libjack-jackd2-0 \
|
||||
libfreetype6 \
|
||||
libfontconfig1 \
|
||||
libx11-6 \
|
||||
libxext6 \
|
||||
libxinerama1 \
|
||||
libxrandr2 \
|
||||
libxcursor1 \
|
||||
xvfb \
|
||||
ffmpeg \
|
||||
libsndfile1 \
|
||||
libfluidsynth3 \
|
||||
libcurl4 \
|
||||
build-essential \
|
||||
fluidsynth \
|
||||
vorbis-tools \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
# ⚠️ Check trước: package đã có (layer cache bị invalidation) → BỎ QUA apt-get (tiết kiệm thời gian build)
|
||||
RUN if command -v fluidsynth >/dev/null 2>&1 && command -v ffmpeg >/dev/null 2>&1 && command -v Xvfb >/dev/null 2>&1; then \
|
||||
echo "Apt packages already installed - skip apt-get update/install"; \
|
||||
else \
|
||||
apt-get update && apt-get install -y \
|
||||
libgl1 \
|
||||
libglx-mesa0 \
|
||||
libglu1-mesa \
|
||||
libasound2 \
|
||||
libjack-jackd2-0 \
|
||||
libfreetype6 \
|
||||
libfontconfig1 \
|
||||
libx11-6 \
|
||||
libxext6 \
|
||||
libxinerama1 \
|
||||
libxrandr2 \
|
||||
libxcursor1 \
|
||||
xvfb \
|
||||
ffmpeg \
|
||||
libsndfile1 \
|
||||
libfluidsynth3 \
|
||||
libcurl4 \
|
||||
build-essential \
|
||||
fluidsynth \
|
||||
vorbis-tools \
|
||||
&& rm -rf /var/lib/apt/lists/*; \
|
||||
fi
|
||||
|
||||
# Thiết lập biến môi trường hiển thị cho X11 ảo
|
||||
ENV DISPLAY=:99
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 SonicForge Studio contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
---
|
||||
|
||||
## Third-party components
|
||||
|
||||
Code viết riêng của dự án (app/static/js/services/*, components/*, app.jsx)
|
||||
thuộc license MIT trên.
|
||||
|
||||
Các thành phần bên thứ ba giữ license gốc:
|
||||
|
||||
- **React / react-dom** — MIT
|
||||
- **Babel** (@babel/cli, core, preset-react) — MIT
|
||||
- **jsdom** — MIT
|
||||
- **Tailwind CSS** (app/static/css/tailwind.min.css) — MIT
|
||||
- **Lucide icons** — ISC
|
||||
- **FluidSynth 2.3.0** (app/static/js/vendor/libfluidsynth-2.3.0-sf3.js/.wasm) —
|
||||
GNU LGPL v2.1+ — xem https://www.gnu.org/licenses/lgpl-2.1.html
|
||||
|
||||
Chi tiết + attribution từng thành phần: xem THIRD_PARTY_LICENSES.md.
|
||||
@@ -0,0 +1,37 @@
|
||||
# THIRD-PARTY LICENSES — SonicForgeStudio
|
||||
|
||||
Kiểm tra ngày 2026-08-07. Danh sách thành phần bên thứ ba + license.
|
||||
|
||||
## 1. Dependencies (npm — package.json)
|
||||
| Thành phần | License | Ghi chú |
|
||||
|---|---|---|
|
||||
| react / react-dom 19.x | MIT | OK |
|
||||
| @babel/cli, @babel/core, @babel/preset-react | MIT | Chỉ build-time |
|
||||
| jsdom | MIT | Chỉ build-time/test |
|
||||
|
||||
## 2. Thư viện nhúng (app/static)
|
||||
| File | Nguồn | License | Trạng thái |
|
||||
|---|---|---|---|
|
||||
| `css/tailwind.min.css` | Tailwind CSS | MIT | OK — nên giữ attribution |
|
||||
| `js/services/spessasynth_processor.min.js` | SpessaSynth (KHÔNG còn dùng — không được include trong index.html — chỉ FluidSynth) | MIT | ✅ KHÔNG có code nào gọi (chỉ còn comment cũ app.jsx:14276 + file chết) — có thể xóa file |
|
||||
| `js/vendor/libfluidsynth-2.3.0-sf3.js` + `.wasm` | FluidSynth 2.3.0 (Emscripten) | **LGPL-2.1+** | ⚠️ Bắt buộc giữ license notice + attribution + (nếu phân phối bản build) cung cấp link/tài liệu LGPL |
|
||||
| `js/services/fluidsynthLoader.js`, `worklets/fluidsynth-bridge.js` | Bản tự viết (bọc FluidSynth) | Dự án | OK |
|
||||
| Lucide icons (inline `data-lucide`) | Lucide | ISC (MIT-compatible) | OK |
|
||||
|
||||
## 3. Nội dung âm thanh (app/storage)
|
||||
| File | Nguồn | License | Trạng thái |
|
||||
|---|---|---|---|
|
||||
| `soundfonts/518e850f-...sf2` | "General MIDI SoundFont v3.0" — © 2006-2010 Rich "Weeds" Nagel — "Some rights reserved" | Không có text đầy đủ trong file (chỉ ICOP ngắn). Tuyên bố: "created from various **commercial**, custom, and freeware soundfonts and samples" | ⚠️ RỦI RO: (a) điều kiện "some rights reserved" không rõ ràng (thường là CC-BY — cần ghi attribution; có thể hạn chế thương mại); (b) samples gốc có nguồn commercial — quyền tái phân phối phụ thuộc tuyên bố tác giả. **Khuyến nghị: thay bằng SF2 license rõ (FluidR3_GM — MIT/GPL-2; GeneralUser GS — CC-BY-SA; Arachno — public domain) HOẶC giữ + ghi attribution đầy đủ.** |
|
||||
| `uploads/user_anonymous_*.mp3` | File người dùng upload | Thuộc người dùng | OK — không phải thành phần phân phối |
|
||||
| SGM-V2.01 (xuất hiện trong log `sfId: SGM-V2.01`) | SGM-V2.01 | Freeware — tác giả cho phép dùng nhưng **hạn chế redistribution** (cần permission) | ⚠️ Nếu vẫn dùng để phân phối bản build — cần permission từ tác giả; không nhúng vào sản phẩm |
|
||||
|
||||
## 4. Assets
|
||||
- `templates/favicon.svg`, `images/SonicForgeUI.png` — nội bộ (tự tạo) — OK.
|
||||
- Code trong `app/static/js/services/*`, `app/static/js/components/*`, `app.jsx` — tự viết — thuộc dự án.
|
||||
|
||||
## KẾT LUẬN
|
||||
- **Không phát hiện vi phạm bản quyền rõ ràng** (không có code GPL bị nhúng vào project MIT; LGPL của FluidSynth tương thích nếu giữ notice).
|
||||
- **3 điểm cần xử lý trước khi phân phối công khai:**
|
||||
1. Bổ sung `LICENSE` text (MIT + LGPL-2.1) + attribution cho SpessaSynth (MIT notice) và Tailwind.
|
||||
2. Ghi attribution SF2 Rich Nagel ("General MIDI SoundFont v3.0 — © 2006-2010 Rich 'Weeds' Nagel — Some rights reserved") hoặc thay soundfont khác license rõ.
|
||||
3. Không nhúng SGM-V2.01 vào bản phân phối (hạn chế redistribution).
|
||||
@@ -0,0 +1,40 @@
|
||||
import os
|
||||
import platform
|
||||
from fastapi import APIRouter, Depends
|
||||
from pydantic import BaseModel
|
||||
from typing import Optional
|
||||
from app.core.vst_scanner import NativePluginScanner
|
||||
from app.api.v1.auth import get_current_user
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
# Thư mục mặc định theo OS (spec desktop VST 2026-08-08)
|
||||
DEFAULT_PLUGIN_DIRS = {
|
||||
"Linux": ["/opt/daw_engine/vst3", os.path.expanduser("~/.vst3")],
|
||||
"Windows": [os.path.expandvars(r"%ProgramFiles%\Common Files\VST3")],
|
||||
"Darwin": ["/Library/Audio/Plug-Ins/Components", os.path.expanduser("~/Library/Audio/Plug-Ins/Components")],
|
||||
}
|
||||
|
||||
|
||||
class PluginScanRequest(BaseModel):
|
||||
custom_directories: Optional[list] = None
|
||||
scan_formats: Optional[list] = None
|
||||
force_rescan: Optional[bool] = False
|
||||
|
||||
|
||||
@router.post("/plugins/scan")
|
||||
async def scan_desktop_plugins(req: PluginScanRequest, current_user: dict = Depends(get_current_user)):
|
||||
"""Quét VST3/AU từ thư mục custom — spec: POST /api/v1/desktop/plugins/scan."""
|
||||
os_name = platform.system()
|
||||
dirs = req.custom_directories or DEFAULT_PLUGIN_DIRS.get(os_name, ["/opt/daw_engine/vst3"])
|
||||
if isinstance(dirs, str):
|
||||
dirs = [dirs]
|
||||
scanner = NativePluginScanner()
|
||||
plugins = scanner.scan_directories(dirs)
|
||||
return {
|
||||
"status": "success",
|
||||
"os": os_name,
|
||||
"scanned_directories": dirs,
|
||||
"total_found": len(plugins),
|
||||
"plugins": plugins,
|
||||
}
|
||||
@@ -18,6 +18,7 @@ os.makedirs(UPLOAD_SF_DIR, exist_ok=True)
|
||||
|
||||
SYSTEM_SF_DIR = "/opt/daw_engine/soundfonts"
|
||||
|
||||
|
||||
_inspector = None
|
||||
_scanner = None
|
||||
|
||||
|
||||
@@ -105,6 +105,7 @@ class PythonRenderEngine:
|
||||
# Parse synth_engine struct (Task C) — fall back to flat fields
|
||||
se = track.get("synth_engine", {}) or {}
|
||||
instrument_id = se.get("plugin_id") or track.get("instrument_id", "") or track.get("instrument", "")
|
||||
vst_path = se.get("plugin_path") or "" # spec desktop: load VST3 từ plugin_path
|
||||
instrument_source = se.get("type") or track.get("instrument_source", "soundfont")
|
||||
soundfont_bank = se.get("soundfont_bank") if se.get("soundfont_bank") is not None else track.get("soundfont_bank", 0)
|
||||
soundfont_program = se.get("soundfont_program") if se.get("soundfont_program") is not None else track.get("soundfont_program", 0)
|
||||
@@ -189,7 +190,8 @@ class PythonRenderEngine:
|
||||
if midi_events:
|
||||
try:
|
||||
plugin_mgr = PluginManager()
|
||||
vst = plugin_mgr.load_vst(instrument_id) if instrument_id else None
|
||||
# Ưu tiên plugin_path (spec desktop) — fallback plugin_id theo tên
|
||||
vst = plugin_mgr.load_vst(vst_path or instrument_id) if (vst_path or instrument_id) else None
|
||||
|
||||
if instrument_source == "pianobook":
|
||||
dspreset_path = track.get("dspreset_path", "")
|
||||
|
||||
+16
-2
@@ -216,6 +216,19 @@ class PluginManager:
|
||||
def load_vst(self, plugin_name: str, preset_data: dict = None):
|
||||
if not HAS_PEDALBOARD:
|
||||
return None
|
||||
# Ưu tiên PATH trực tiếp (spec desktop 2026-08-08: synth_engine.plugin_path)
|
||||
if plugin_name and (plugin_name.endswith(".vst3") or plugin_name.endswith(".so")
|
||||
or plugin_name.endswith(".component") or "/" in plugin_name or "\\" in plugin_name):
|
||||
if os.path.exists(plugin_name):
|
||||
vst = VST3Plugin(plugin_name)
|
||||
if preset_data:
|
||||
for k, v in preset_data.items():
|
||||
try:
|
||||
setattr(vst, k, v)
|
||||
except Exception:
|
||||
pass
|
||||
return vst
|
||||
return None
|
||||
plugins = self._scan_plugins()
|
||||
if plugin_name not in plugins:
|
||||
return None
|
||||
@@ -305,8 +318,9 @@ class PluginManager:
|
||||
def list_available(self) -> dict:
|
||||
return {
|
||||
"vst_instruments": [
|
||||
{"id": k, "name": k, "type": "VST3", "has_native_support": HAS_PEDALBOARD}
|
||||
for k in self._scan_plugins().keys()
|
||||
{"id": "vst3_" + k.lower().replace(" ", "_"), "name": k, "type": "VST3",
|
||||
"path": p, "has_native_support": HAS_PEDALBOARD}
|
||||
for k, p in self._scan_plugins().items()
|
||||
],
|
||||
"soundfonts": self._scan_soundfonts()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
import os
|
||||
import platform
|
||||
import logging
|
||||
from typing import List, Dict, Any
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class NativePluginScanner:
|
||||
"""Quét thư mục custom chứa VST3 (.vst3) / Audio Unit (.component trên macOS)
|
||||
— spec DESKTOP VST (2026-08-08): POST /api/v1/desktop/plugins/scan."""
|
||||
|
||||
def __init__(self):
|
||||
self.os_type = platform.system() # 'Linux', 'Windows', 'Darwin'
|
||||
|
||||
def scan_directories(self, target_paths: List[str]) -> List[Dict[str, Any]]:
|
||||
found_plugins = []
|
||||
seen = set()
|
||||
|
||||
for base_path in target_paths:
|
||||
if not base_path:
|
||||
continue
|
||||
if not os.path.exists(base_path):
|
||||
logger.warning(f"Scan path does not exist: {base_path}")
|
||||
continue
|
||||
|
||||
for root, dirs, files in os.walk(base_path):
|
||||
for dir_name in dirs:
|
||||
full_path = os.path.join(root, dir_name)
|
||||
|
||||
# VST3 = bundle directory *.vst3
|
||||
if dir_name.endswith('.vst3'):
|
||||
plugin_name = dir_name[:-5]
|
||||
pid = f"vst3_{plugin_name.lower().replace(' ', '_')}"
|
||||
if pid in seen:
|
||||
continue
|
||||
seen.add(pid)
|
||||
found_plugins.append({
|
||||
"id": pid,
|
||||
"name": plugin_name,
|
||||
"type": "VST3",
|
||||
"format": "VST3",
|
||||
"category": "Instrument",
|
||||
"vendor": self._read_vendor(full_path) or None,
|
||||
"path": full_path,
|
||||
"is_instrument": True,
|
||||
"has_native_gui": True
|
||||
})
|
||||
# Audio Unit = bundle *.component (macOS only)
|
||||
elif dir_name.endswith('.component') and self.os_type == 'Darwin':
|
||||
plugin_name = dir_name[:-10]
|
||||
pid = f"au_{plugin_name.lower().replace(' ', '_')}"
|
||||
if pid in seen:
|
||||
continue
|
||||
seen.add(pid)
|
||||
found_plugins.append({
|
||||
"id": pid,
|
||||
"name": plugin_name,
|
||||
"type": "AU",
|
||||
"format": "AudioUnit",
|
||||
"category": "Instrument",
|
||||
"vendor": self._read_vendor(full_path) or None,
|
||||
"path": full_path,
|
||||
"is_instrument": True,
|
||||
"has_native_gui": True
|
||||
})
|
||||
|
||||
return found_plugins
|
||||
|
||||
@staticmethod
|
||||
def _read_vendor(bundle_path: str) -> str:
|
||||
"""Đọc vendor từ Info.plist nếu có (macOS) — best-effort."""
|
||||
try:
|
||||
plist = os.path.join(bundle_path, "Contents", "Info.plist")
|
||||
if os.path.exists(plist):
|
||||
with open(plist, "rb") as f:
|
||||
raw = f.read(65536)
|
||||
import plistlib
|
||||
try:
|
||||
data = plistlib.loads(raw)
|
||||
return data.get("CFBundleManufacturer") or data.get("NSHumanReadableCopyright")
|
||||
except Exception:
|
||||
return None
|
||||
except Exception:
|
||||
return None
|
||||
return None
|
||||
@@ -17,6 +17,7 @@ from app.api.v1.user_config import router as user_config_router
|
||||
from app.api.v1.ai_proxy import router as ai_proxy_router
|
||||
from app.api.v1.ai_presets import router as ai_presets_router
|
||||
from app.api.v1.plugins import router as plugins_router
|
||||
from app.api.v1.desktop_plugins import router as desktop_plugins_router
|
||||
from app.api.v1.media import router as media_router
|
||||
from app.core.auth import seed_admin
|
||||
from app.core.soundfont_scanner import SoundFontAutoScanner
|
||||
@@ -72,9 +73,14 @@ app.include_router(user_config_router, prefix="/api/v1/user", tags=["user_config
|
||||
app.include_router(ai_proxy_router, prefix="/api/v1/ai", tags=["ai"])
|
||||
app.include_router(ai_presets_router, prefix="/api/v1/ai", tags=["ai"])
|
||||
app.include_router(plugins_router, prefix="/api/v1/plugins", tags=["plugins"])
|
||||
app.include_router(desktop_plugins_router, prefix="/api/v1/desktop", tags=["desktop"])
|
||||
app.include_router(media_router, prefix="/api/v1/media", tags=["media"])
|
||||
|
||||
|
||||
@app.get("/health")
|
||||
async def health():
|
||||
return {"status": "ok"}
|
||||
|
||||
@app.get("/", response_class=HTMLResponse)
|
||||
async def get_index():
|
||||
index_path = os.path.join(settings.TEMPLATES_DIR, "index.html")
|
||||
|
||||
+185
-40
@@ -4899,7 +4899,6 @@ const AuthModal = ({
|
||||
onClose,
|
||||
onSuccess
|
||||
}) => {
|
||||
if (!isOpen) return null;
|
||||
const [activeTab, setActiveTab] = useState(mode || 'login');
|
||||
const [username, setUsername] = useState('admin');
|
||||
const [email, setEmail] = useState('');
|
||||
@@ -4965,6 +4964,10 @@ const AuthModal = ({
|
||||
};
|
||||
const isForceMode = activeTab === 'force_change';
|
||||
const canClose = !forceMandatory && !isForceMode;
|
||||
// return null SAU tất cả hooks (Rules of Hooks — bug 10:05: if !isOpen return
|
||||
// null TRƯỚC hooks → mở login lần đầu (false→true) → hook order đổi → React
|
||||
// crash → unmount → MÀN ĐEN)
|
||||
if (!isOpen) return null;
|
||||
return /*#__PURE__*/React.createElement("div", {
|
||||
className: "fixed inset-0 z-50 flex items-center justify-center bg-black/80 backdrop-blur-md"
|
||||
}, /*#__PURE__*/React.createElement("div", {
|
||||
@@ -5065,7 +5068,6 @@ const AIConfigModal = ({
|
||||
onClose,
|
||||
onConfigSaved
|
||||
}) => {
|
||||
if (!isOpen) return null;
|
||||
const defaultProvidersList = [{
|
||||
id: 'openai_default',
|
||||
name: 'OpenAI Official',
|
||||
@@ -5148,6 +5150,8 @@ const AIConfigModal = ({
|
||||
} : p));
|
||||
};
|
||||
const activeProvider = providers.find(p => p.id === selectedId) || providers[0];
|
||||
// return null SAU hooks (Rules of Hooks — bug 10:05)
|
||||
if (!isOpen) return null;
|
||||
return /*#__PURE__*/React.createElement("div", {
|
||||
className: "fixed inset-0 z-50 flex items-center justify-center bg-black/70 backdrop-blur-sm select-none"
|
||||
}, /*#__PURE__*/React.createElement("div", {
|
||||
@@ -5280,7 +5284,6 @@ const AIConfigModal = ({
|
||||
};
|
||||
|
||||
const PluginManagerModal = ({ isOpen, onClose, pluginsData }) => {
|
||||
if (!isOpen) return null;
|
||||
const [localData, setLocalData] = React.useState(pluginsData);
|
||||
const [sfUploadStatus, setSfUploadStatus] = React.useState('');
|
||||
const [sfToDelete, setSfToDelete] = React.useState(null);
|
||||
@@ -5311,6 +5314,8 @@ const PluginManagerModal = ({ isOpen, onClose, pluginsData }) => {
|
||||
}
|
||||
};
|
||||
const [pmTab, setPmTab] = React.useState('soundfont');
|
||||
// return null SAU hooks (Rules of Hooks — bug 10:05)
|
||||
if (!isOpen) return null;
|
||||
return React.createElement('div', {
|
||||
className: 'fixed inset-0 z-50 flex items-center justify-center bg-black/70 backdrop-blur-sm',
|
||||
onClick: onClose
|
||||
@@ -5548,7 +5553,6 @@ const ProfileModal = ({
|
||||
setSubTabs,
|
||||
trackMidiChannelsRef
|
||||
}) => {
|
||||
if (!isOpen) return null;
|
||||
const [activeTab, setActiveTab] = useState('account');
|
||||
const [profile, setProfile] = useState(null);
|
||||
const [oldPassword, setOldPassword] = useState('');
|
||||
@@ -5838,6 +5842,8 @@ const ProfileModal = ({
|
||||
top: `calc(50% + ${dragOfs.y}px)`,
|
||||
transform: 'translate(-50%, -50%)'
|
||||
};
|
||||
// return null SAU hooks (Rules of Hooks — bug 10:05)
|
||||
if (!isOpen) return null;
|
||||
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
|
||||
key: "backdrop",
|
||||
className: "fixed inset-0 z-40 bg-black/70 backdrop-blur-sm",
|
||||
@@ -6079,7 +6085,6 @@ const SaveProjectModal = ({
|
||||
onSaveLocal,
|
||||
projectName
|
||||
}) => {
|
||||
if (!isOpen) return null;
|
||||
const [name, setName] = useState(projectName || '');
|
||||
const [saveType, setSaveType] = useState(localStorage.getItem('sonic_token') ? 'cloud' : 'local');
|
||||
const [cloudProjects, setCloudProjects] = useState([]);
|
||||
@@ -6105,6 +6110,8 @@ const SaveProjectModal = ({
|
||||
else { onSaveLocal(name.trim()); onClose(); }
|
||||
}
|
||||
};
|
||||
// return null SAU hooks (Rules of Hooks — bug 10:05)
|
||||
if (!isOpen) return null;
|
||||
if (confirmOverwriteProject) {
|
||||
return React.createElement("div", {
|
||||
className: "fixed inset-0 z-50 flex items-center justify-center bg-black/70 backdrop-blur-sm"
|
||||
@@ -6182,7 +6189,6 @@ const SaveProjectModal = ({
|
||||
};
|
||||
|
||||
const OpenProjectModal = ({ isOpen, onClose, onOpenCloud, onOpenLocal }) => {
|
||||
if (!isOpen) return null;
|
||||
const [tab, setTab] = useState('cloud');
|
||||
const [projects, setProjects] = useState([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
@@ -6196,6 +6202,8 @@ const OpenProjectModal = ({ isOpen, onClose, onOpenCloud, onOpenLocal }) => {
|
||||
} else { setLoading(false); }
|
||||
}
|
||||
}, [isOpen, tab]);
|
||||
// return null SAU hooks (Rules of Hooks — bug 10:05)
|
||||
if (!isOpen) return null;
|
||||
return React.createElement("div", {
|
||||
className: "fixed inset-0 z-50 flex items-center justify-center bg-black/70 backdrop-blur-sm"
|
||||
}, React.createElement("div", {
|
||||
@@ -6256,7 +6264,6 @@ const SaveAsModal = ({
|
||||
onSaveCloud,
|
||||
onSaveLocal
|
||||
}) => {
|
||||
if (!isOpen) return null;
|
||||
const [name, setName] = useState(projectName || '');
|
||||
const [saveType, setSaveType] = useState('cloud');
|
||||
const handleSubmit = (e) => {
|
||||
@@ -6269,6 +6276,8 @@ const SaveAsModal = ({
|
||||
}
|
||||
onClose();
|
||||
};
|
||||
// return null SAU hooks (Rules of Hooks — bug 10:05)
|
||||
if (!isOpen) return null;
|
||||
return /*#__PURE__*/React.createElement("div", {
|
||||
className: "fixed inset-0 z-50 flex items-center justify-center bg-black/70 backdrop-blur-sm"
|
||||
}, /*#__PURE__*/React.createElement("div", {
|
||||
@@ -6336,7 +6345,6 @@ const SystemManagerModal = ({
|
||||
isOpen,
|
||||
onClose
|
||||
}) => {
|
||||
if (!isOpen) return null;
|
||||
const [users, setUsers] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [msg, setMsg] = useState('');
|
||||
@@ -6388,6 +6396,8 @@ const SystemManagerModal = ({
|
||||
setError(err.message || 'Lỗi khi xóa người dùng');
|
||||
}
|
||||
};
|
||||
// return null SAU hooks (Rules of Hooks — bug 10:05)
|
||||
if (!isOpen) return null;
|
||||
return /*#__PURE__*/React.createElement("div", {
|
||||
className: "fixed inset-0 z-50 flex items-center justify-center bg-black/70 backdrop-blur-sm"
|
||||
}, /*#__PURE__*/React.createElement("div", {
|
||||
@@ -6470,7 +6480,6 @@ const SystemManagerModal = ({
|
||||
};
|
||||
|
||||
const AIPresetModal = ({ isOpen, onClose }) => {
|
||||
if (!isOpen) return null;
|
||||
|
||||
const mgrRef = React.useRef(null);
|
||||
if (!mgrRef.current) mgrRef.current = new window.PromptTemplateManager();
|
||||
@@ -6688,6 +6697,8 @@ const AIPresetModal = ({ isOpen, onClose }) => {
|
||||
if (showFavoritesOnly) matchesCategory = matchesCategory && p.is_favorite;
|
||||
return matchesSearch && matchesCategory;
|
||||
});
|
||||
// return null SAU hooks (Rules of Hooks — bug 10:05)
|
||||
if (!isOpen) return null;
|
||||
|
||||
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
|
||||
className: "fixed inset-0 z-50 flex items-center justify-center bg-black/75 backdrop-blur-sm p-4 animate-fade-in"
|
||||
@@ -10419,12 +10430,10 @@ const FXRackModal = ({ track, onUpdateTrack, onClose }) => {
|
||||
const eqCurveRef = React.useRef(null);
|
||||
const scopeStateRef = React.useRef({ L: null, R: null, head: 0, len: 0, tmpL: null, tmpR: null, freq: null });
|
||||
|
||||
if (!track) return null;
|
||||
|
||||
const chain = track.fxChain || [];
|
||||
const chain = track ? (track.fxChain || []) : [];
|
||||
const setChain = (next) => {
|
||||
if (onUpdateTrack) onUpdateTrack(track.id, { fxChain: next });
|
||||
if (window.__rebuildTrackFxGraph) window.__rebuildTrackFxGraph(track.id);
|
||||
if (onUpdateTrack && track) onUpdateTrack(track.id, { fxChain: next });
|
||||
if (track && window.__rebuildTrackFxGraph) window.__rebuildTrackFxGraph(track.id);
|
||||
};
|
||||
const paramsOf = (m) => ({ ...(TRACK_FX_DEFAULTS[m.type] || {}), ...(m.params || {}) });
|
||||
const setParams = (idx, patch) => {
|
||||
@@ -10645,6 +10654,8 @@ const FXRackModal = ({ track, onUpdateTrack, onClose }) => {
|
||||
ctx.fillText('20kHz', w - 38, h - 2);
|
||||
}, [ap.g1, ap.g2, ap.g3, ap.g4, activeMod]);
|
||||
|
||||
if (!track) return null;
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-[115] bg-black/80 backdrop-blur-sm flex items-center justify-center p-4" onClick={onClose}>
|
||||
<div className="w-full max-w-4xl bg-slate-900 border border-slate-700 rounded-2xl p-5 space-y-4 shadow-2xl flex flex-col max-h-[90vh] text-slate-200" onClick={e => e.stopPropagation()}>
|
||||
@@ -14193,6 +14204,12 @@ const App = () => {
|
||||
const [selectedSoundFontId, setSelectedSoundFontId] = useState(null);
|
||||
const [sfPresets, setSfPresets] = useState(null); // presets from SoundFont
|
||||
const [instrumentDropdownTrackId, setInstrumentDropdownTrackId] = useState(null);
|
||||
// Plugin Manager — VST scan (spec desktop 2026-08-08)
|
||||
const [vstScanOpen, setVstScanOpen] = useState(false);
|
||||
const [vstScanPath, setVstScanPath] = useState('/opt/daw_engine/vst3');
|
||||
const [vstScanning, setVstScanning] = useState(false);
|
||||
const [vstPlugins, setVstPlugins] = useState([]);
|
||||
const [vstScanError, setVstScanError] = useState(null);
|
||||
const [instrumentDropdownBtnRect, setInstrumentDropdownBtnRect] = useState(null);
|
||||
const [instrumentSearchQuery, setInstrumentSearchQuery] = useState('');
|
||||
const [sfPresetSearchQuery, setSfPresetSearchQuery] = useState('');
|
||||
@@ -14249,8 +14266,9 @@ const App = () => {
|
||||
"Tinkle Bell","Agogo","Steel Drums","Woodblock","Taiko Drum","Melodic Tom","Synth Drum","Reverse Cymbal",
|
||||
"Guitar Fret Noise","Breath Noise","Seashore","Bird Tweet","Telephone Ring","Helicopter","Applause","Gunshot"
|
||||
];
|
||||
const setTrackInstrumentWithProgram = (trackId, instrumentId, programNumber, displayName, bankNumber) => {
|
||||
const setTrackInstrumentWithProgram = (trackId, instrumentId, programNumber, displayName, bankNumber, vstMeta) => {
|
||||
const isSfInstrument = instrumentId && typeof instrumentId === 'string' && instrumentId.startsWith('sf_');
|
||||
const isVstInstrument = instrumentId && typeof instrumentId === 'string' && (instrumentId.startsWith('vst3_') || instrumentId.startsWith('au_') || (vstMeta && vstMeta.format));
|
||||
const sfBank = bankNumber !== undefined ? bankNumber : (isSfInstrument ? 0 : undefined);
|
||||
const sfProg = programNumber !== undefined ? programNumber : undefined;
|
||||
var mt = activeTracksRef.current || tracks;
|
||||
@@ -14264,6 +14282,12 @@ const App = () => {
|
||||
const synthEngine = hasInstrument ? {
|
||||
type: instrType,
|
||||
plugin_id: instrumentId,
|
||||
// spec desktop 2026-08-08: synth_engine đầy đủ {type, plugin_id, plugin_name, format, plugin_path}
|
||||
...(isVstInstrument ? {
|
||||
plugin_name: (vstMeta && vstMeta.plugin_name) || (displayName || instrumentId).replace(/\s*\((VST3|AU|AudioUnit)\)\s*$/, ''),
|
||||
format: (vstMeta && vstMeta.format) || (instrumentId.startsWith('au_') ? 'AudioUnit' : 'VST3'),
|
||||
plugin_path: (vstMeta && vstMeta.plugin_path) || ''
|
||||
} : {}),
|
||||
soundfont_bank: sfBank !== undefined ? sfBank : 0,
|
||||
soundfont_program: sfProg !== undefined ? sfProg : 0,
|
||||
soundfont_id: isSfInstrument ? instrumentId.replace('sf_', '') : ''
|
||||
@@ -14273,7 +14297,7 @@ const App = () => {
|
||||
setInstrumentDropdownTrackId(null);
|
||||
setInstrumentDropdownBtnRect(null);
|
||||
setSynthCategory(null);
|
||||
// Trigger SpessaSynth load + program change when soundfont instrument selected
|
||||
// Trigger FluidSynth load + program change when soundfont instrument selected
|
||||
if (window.SonicSF && window.SonicSF.selectInstrument && instrumentId && isSfInstrument) {
|
||||
const sfId = instrumentId.replace('sf_', '');
|
||||
window.SonicSF.selectInstrument(mch, sfBank || 0, sfProg || 0, sfId);
|
||||
@@ -15114,7 +15138,7 @@ const App = () => {
|
||||
setAiPrompt(newText);
|
||||
};
|
||||
|
||||
const setTrackInstrumentWithUndo = (trackId, instrumentId, displayName, bankNumber, programNumber) => {
|
||||
const setTrackInstrumentWithUndo = (trackId, instrumentId, displayName, bankNumber, programNumber, vstMeta) => {
|
||||
const track = activeTracks.find(t => t.id === trackId);
|
||||
if (!track) return;
|
||||
const oldInstrumentId = track.instrumentId;
|
||||
@@ -15136,7 +15160,7 @@ const App = () => {
|
||||
}
|
||||
};
|
||||
if (window.UndoRedoEngine) window.UndoRedoEngine.execute(entry);
|
||||
setTrackInstrumentWithProgram(trackId, instrumentId, programNumber, displayName, bankNumber);
|
||||
setTrackInstrumentWithProgram(trackId, instrumentId, programNumber, displayName, bankNumber, vstMeta);
|
||||
};
|
||||
|
||||
const createSectionWithUndo = (trackId, section) => {
|
||||
@@ -15530,6 +15554,25 @@ const App = () => {
|
||||
// ── Auth / User State ──
|
||||
const [currentUser, setCurrentUser] = useState(null);
|
||||
const [authModalOpen, setAuthModalOpen] = useState(false);
|
||||
// 401 bất kỳ → mở màn login (bug 09:45 — màn đen khi token hỏng/hết hạn)
|
||||
React.useEffect(() => {
|
||||
window.__onAuthFail = () => {
|
||||
console.log('[AUTH] __onAuthFail — mở login');
|
||||
setCurrentUser(null);
|
||||
setIsMandatoryLogin(true);
|
||||
setAuthMode('login');
|
||||
setAuthModalOpen(true);
|
||||
};
|
||||
return () => { delete window.__onAuthFail; };
|
||||
}, []);
|
||||
// Chẩn đoán: sau mount — root có nội dung không (bug màn đen 10:20)
|
||||
React.useEffect(() => {
|
||||
try {
|
||||
const rootEl = document.getElementById('root');
|
||||
console.log('[APP] mounted — root children:', rootEl ? rootEl.children.length : -1,
|
||||
'| authModalOpen:', authModalOpen, '| currentUser:', currentUser ? currentUser.username : null);
|
||||
} catch (e) { console.log('[APP] diag err', e.message); }
|
||||
});
|
||||
const [authMode, setAuthMode] = useState('login'); // 'login' | 'register' | 'force_change'
|
||||
const [isMandatoryLogin, setIsMandatoryLogin] = useState(false);
|
||||
const [profileModalOpen, setProfileModalOpen] = useState(false);
|
||||
@@ -15813,8 +15856,10 @@ const App = () => {
|
||||
|
||||
useEffect(() => {
|
||||
const checkAuthStatus = async () => {
|
||||
console.log('[AUTH] checkAuthStatus bắt đầu, token=', (localStorage.getItem('sonic_token') || '(rỗng)').slice(0, 12));
|
||||
const savedToken = localStorage.getItem('sonic_token');
|
||||
if (!savedToken) {
|
||||
console.log('[AUTH] không có token → mở login');
|
||||
setIsMandatoryLogin(true);
|
||||
setAuthMode('login');
|
||||
setAuthModalOpen(true);
|
||||
@@ -15822,6 +15867,7 @@ const App = () => {
|
||||
}
|
||||
try {
|
||||
const profile = await window.SonicAPI.getProfile();
|
||||
console.log('[AUTH] profile OK:', profile && profile.username);
|
||||
setCurrentUser(profile);
|
||||
localStorage.setItem('sonic_user', JSON.stringify(profile));
|
||||
if (profile.must_change_password) {
|
||||
@@ -15834,20 +15880,29 @@ const App = () => {
|
||||
restoreLastSessionProject();
|
||||
}
|
||||
} catch (err) {
|
||||
const cached = localStorage.getItem('sonic_user');
|
||||
if (cached) {
|
||||
try { setCurrentUser(JSON.parse(cached)); } catch (_) { }
|
||||
setIsMandatoryLogin(false);
|
||||
setAuthModalOpen(false);
|
||||
restoreLastSessionProject();
|
||||
} else {
|
||||
localStorage.removeItem('sonic_token');
|
||||
localStorage.removeItem('sonic_user');
|
||||
setCurrentUser(null);
|
||||
setIsMandatoryLogin(true);
|
||||
setAuthMode('login');
|
||||
setAuthModalOpen(true);
|
||||
console.log('[AUTH] profile lỗi:', String((err && err.message) || err).slice(0, 80));
|
||||
// 401 (token hỏng/đổi SECRET_KEY — bug 09:45: dùng cached user → vào app
|
||||
// nhưng mọi API 401 → màn đen không login) → BỎ qua cached → mở LOGIN.
|
||||
// detail server: "Thiếu Token xác thực..." / "Token đã hết hạn..." (auth.py)
|
||||
const errMsg = String((err && err.message) || err || '');
|
||||
const isAuthErr = errMsg.includes('Token') || errMsg.includes('401') || errMsg.includes('Unauthorized') || errMsg.includes('unauthorized') || errMsg.includes('Không xác thực');
|
||||
console.log('[AUTH] isAuthErr=', isAuthErr, 'errMsg=', errMsg.slice(0, 60));
|
||||
if (!isAuthErr) {
|
||||
const cached = localStorage.getItem('sonic_user');
|
||||
if (cached) {
|
||||
try { setCurrentUser(JSON.parse(cached)); } catch (_) { }
|
||||
setIsMandatoryLogin(false);
|
||||
setAuthModalOpen(false);
|
||||
restoreLastSessionProject();
|
||||
return;
|
||||
}
|
||||
}
|
||||
localStorage.removeItem('sonic_token');
|
||||
localStorage.removeItem('sonic_user');
|
||||
setCurrentUser(null);
|
||||
setIsMandatoryLogin(true);
|
||||
setAuthMode('login');
|
||||
setAuthModalOpen(true);
|
||||
}
|
||||
};
|
||||
checkAuthStatus();
|
||||
@@ -25948,6 +26003,7 @@ STRICT CONSTRAINTS:
|
||||
});
|
||||
};
|
||||
|
||||
console.log('[APP] return UI — bắt đầu render');
|
||||
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
|
||||
className: "h-full w-full flex flex-col bg-[#1e1e1e]"
|
||||
}, /*#__PURE__*/React.createElement("header", {
|
||||
@@ -26824,6 +26880,7 @@ STRICT CONSTRAINTS:
|
||||
else if (id === 'midi_events') setShowMidiEvents(false);
|
||||
};
|
||||
const renderPanelContent = panelId => {
|
||||
console.log('[FN] renderPanelContent bắt đầu, panel=', panelId);
|
||||
const h = id => e => {
|
||||
startPanelDrag(id, e);
|
||||
};
|
||||
@@ -27394,6 +27451,7 @@ STRICT CONSTRAINTS:
|
||||
return null;
|
||||
};
|
||||
const renderDock = (pos, title) => {
|
||||
console.log('[FN] renderDock bắt đầu, pos=', pos);
|
||||
const panels = dockPanels[pos];
|
||||
if (panels.length === 0) return null;
|
||||
const isSide = pos === 'left' || pos === 'right';
|
||||
@@ -27456,7 +27514,7 @@ STRICT CONSTRAINTS:
|
||||
className: "w-3.5 h-3.5 text-cyan-400"
|
||||
})), dragGhostPanel === 'export' ? 'Export Panel' : dragGhostPanel === 'ai' ? 'AI Panel' : dragGhostPanel === 'python_tools' ? 'Audio Processing Panel' : 'Selection Panel'), /*#__PURE__*/React.createElement("div", {
|
||||
className: "text-xs text-zinc-500 mt-1"
|
||||
}, "Drop at edge to dock")), renderDock('top', 'Top'), /*#__PURE__*/React.createElement("div", {
|
||||
}, "Drop at edge to dock")), renderDock('top', 'Top'), console.log('[SEQ] dock-top xong'), /*#__PURE__*/React.createElement("div", {
|
||||
className: "flex-1 flex overflow-hidden"
|
||||
}, renderDock('left', 'Left'), /*#__PURE__*/React.createElement("div", {
|
||||
className: "flex-1 flex flex-col overflow-hidden min-w-0"
|
||||
@@ -28585,7 +28643,7 @@ STRICT CONSTRAINTS:
|
||||
})())), /*#__PURE__*/React.createElement("div", {
|
||||
className: "w-1 cursor-ew-resize hover:bg-cyan-500/50 active:bg-cyan-400 transition-colors shrink-0 z-10",
|
||||
onMouseDown: startColResize
|
||||
}), renderDock('right', 'Right')), renderDock('bottom', 'Bottom'), showMixer && /*#__PURE__*/React.createElement("div", {
|
||||
}), renderDock('right', 'Right')), renderDock('bottom', 'Bottom'), console.log('[SEQ] dock-bottom xong'), showMixer && /*#__PURE__*/React.createElement("div", {
|
||||
className: "flex flex-col border-t border-zinc-700 bg-slate-900 shrink-0 select-none",
|
||||
style: { height: mixerHeight + 'px' }
|
||||
}, /*#__PURE__*/React.createElement("div", {
|
||||
@@ -29093,7 +29151,7 @@ STRICT CONSTRAINTS:
|
||||
className: "flex-1"
|
||||
}, "Delete"), /*#__PURE__*/React.createElement("span", {
|
||||
className: "text-amber-400 text-xs font-semibold font-mono ml-auto pl-8"
|
||||
}, "Del")))), toastMessage && /*#__PURE__*/React.createElement("div", {
|
||||
}, "Del")))), console.log('[SEQ] trước toastMessage'), toastMessage && /*#__PURE__*/React.createElement("div", {
|
||||
className: "absolute top-14 right-4 z-50 px-4 py-2.5 rounded shadow-lg text-xs font-semibold flex items-center gap-2 border bg-zinc-900 text-zinc-100 border-zinc-800"
|
||||
}, /*#__PURE__*/React.createElement("span", {
|
||||
className: "inline-flex items-center shrink-0"
|
||||
@@ -29155,7 +29213,7 @@ STRICT CONSTRAINTS:
|
||||
handleSetTabColor(tabContextMenu.tabId, tabContextMenu.tabType, color);
|
||||
setTabContextMenu(null);
|
||||
}
|
||||
})))), /*#__PURE__*/React.createElement(AuthModal, {
|
||||
})))), console.log('[SEQ] trước AuthModal'), /*#__PURE__*/React.createElement(AuthModal, {
|
||||
isOpen: authModalOpen,
|
||||
mode: authMode,
|
||||
forceMandatory: isMandatoryLogin,
|
||||
@@ -29370,12 +29428,99 @@ STRICT CONSTRAINTS:
|
||||
filteredInstruments.vst.length > 0 && /*#__PURE__*/React.createElement("div", { className: "text-[10px] text-zinc-500 px-3 py-1 mt-1 uppercase font-bold" }, "VST Instruments"),
|
||||
filteredInstruments.vst.map((v, i) => /*#__PURE__*/React.createElement("button", {
|
||||
key: "vstd_" + i,
|
||||
onClick: () => { setInstrumentDropdownTrackId(null); setInstrumentDropdownBtnRect(null); setTrackInstrumentWithUndo(instrumentDropdownTrackId, v.id, v.name || v.id); },
|
||||
onClick: () => { setInstrumentDropdownTrackId(null); setInstrumentDropdownBtnRect(null); setTrackInstrumentWithUndo(instrumentDropdownTrackId, v.id, v.name || v.id, undefined, undefined, { plugin_name: v.name || v.id, format: v.type || 'VST3', plugin_path: v.path || '' }); },
|
||||
className: "w-full text-left px-3 py-1.5 text-xs bg-zinc-800 hover:bg-violet-800 text-zinc-200 flex items-center justify-between"
|
||||
}, /*#__PURE__*/React.createElement("span", { className: "truncate" }, v.name || v.id), /*#__PURE__*/React.createElement("span", { className: "text-[10px] text-cyan-400 shrink-0 ml-1" }, v.type || "VST"))),
|
||||
(!filteredInstruments.soundfonts.length && !filteredInstruments.vst.length) && /*#__PURE__*/React.createElement("p", { className: "text-xs text-zinc-500 py-4 text-center" }, "Kh\u00f4ng t\u00ecm th\u1ea5y nh\u1ea1c c\u1ee5 n\u00e0o")
|
||||
)));
|
||||
/*#__PURE__*/React.createElement("button", {
|
||||
onClick: () => { setInstrumentDropdownBtnRect(null); setVstScanOpen(true); },
|
||||
className: "w-full text-left px-3 py-1.5 text-xs bg-purple-900/40 hover:bg-purple-800/60 text-purple-300 border-t border-zinc-700"
|
||||
}, "\uD83D\uDD0C Quét VST Directory\u2026"),
|
||||
(!filteredInstruments.soundfonts.length && !filteredInstruments.vst.length) && /*#__PURE__*/React.createElement("p", { className: "text-xs text-zinc-500 py-4 text-center" }, "Kh\u00f4ng t\u00ecm th\u1EA5y nh\u1EA1c c\u1EE5 n\u00E0o")
|
||||
))),
|
||||
/* Plugin Manager Modal — scan VST3/AU (spec desktop 2026-08-08) */
|
||||
vstScanOpen && /*#__PURE__*/React.createElement("div", {
|
||||
className: "fixed inset-0 bg-black/80 backdrop-blur-sm z-[120] flex items-center justify-center p-4",
|
||||
onMouseDown: e => e.stopPropagation(),
|
||||
onClick: e => e.stopPropagation()
|
||||
}, /*#__PURE__*/React.createElement("div", { className: "w-full max-w-2xl bg-[#1e1e24] border border-zinc-700 rounded-2xl p-5 shadow-2xl space-y-4 text-zinc-200" },
|
||||
/*#__PURE__*/React.createElement("div", { className: "flex items-center justify-between border-b border-zinc-700 pb-3" },
|
||||
/*#__PURE__*/React.createElement("h2", { className: "text-sm font-bold text-purple-400 flex items-center gap-2" }, "\uD83D\uDD0C Plugin Manager (VST3 / AU)"),
|
||||
/*#__PURE__*/React.createElement("button", { onClick: () => setVstScanOpen(false), className: "text-zinc-400 hover:text-white text-lg" }, "\u2715")
|
||||
),
|
||||
/*#__PURE__*/React.createElement("div", { className: "space-y-2 max-h-[50vh] overflow-y-auto" },
|
||||
vstPlugins.length === 0 && !vstScanning && /*#__PURE__*/React.createElement("p", { className: "text-xs text-zinc-500 text-center py-6" }, "Ch\u01B0a qu\u00E9t — nh\u1EADp \u0111\u01B0\u1EDDng d\u1EABn th\u01B0 m\u1EE5c ch\u1EE9a plugin (m\u1EB7c \u0111\u1ECBnh /opt/daw_engine/vst3) r\u1ED3i b\u1EA5m Scan."),
|
||||
vstPlugins.map((plg) => /*#__PURE__*/React.createElement("div", {
|
||||
key: plg.id,
|
||||
onClick: () => {
|
||||
setTrackInstrumentWithUndo(instrumentDropdownTrackId, plg.id, plg.name + " (" + plg.format + ")", undefined, undefined, { plugin_name: plg.name, format: plg.format, plugin_path: plg.path });
|
||||
setVstScanOpen(false);
|
||||
setVstPlugins([]);
|
||||
},
|
||||
className: "bg-[#22222a] hover:bg-[#2c2c36] border border-zinc-700/60 p-3 rounded-xl flex items-center justify-between cursor-pointer transition-all"
|
||||
}, /*#__PURE__*/React.createElement("div", { className: "flex items-center gap-3" },
|
||||
/*#__PURE__*/React.createElement("div", { className: "w-8 h-8 rounded-lg bg-purple-950/80 border border-purple-800 flex items-center justify-center text-purple-400 text-xs" }, "\uD83C\uDFB5"),
|
||||
/*#__PURE__*/React.createElement("div", null,
|
||||
/*#__PURE__*/React.createElement("div", { className: "text-xs font-bold text-white" }, plg.name),
|
||||
/*#__PURE__*/React.createElement("div", { className: "text-[10px] text-zinc-400 font-mono" }, plg.path)
|
||||
)
|
||||
), /*#__PURE__*/React.createElement("span", { className: "text-[10px] font-mono font-bold bg-purple-950 text-purple-300 border border-purple-800 px-2 py-0.5 rounded-full" }, plg.format)))
|
||||
),
|
||||
/*#__PURE__*/React.createElement("div", { className: "pt-3 border-t border-zinc-700/80 space-y-1" },
|
||||
/*#__PURE__*/React.createElement("label", { className: "block text-[10px] font-bold text-zinc-400 uppercase" }, "ADD VST DIRECTORY"),
|
||||
/*#__PURE__*/React.createElement("div", { className: "flex gap-2" },
|
||||
/*#__PURE__*/React.createElement("input", {
|
||||
type: "text", value: vstScanPath,
|
||||
onChange: e => setVstScanPath(e.target.value),
|
||||
className: "flex-1 bg-[#141418] border border-zinc-700 rounded-lg px-3 py-1.5 text-xs text-zinc-200 font-mono outline-none focus:border-purple-500"
|
||||
}),
|
||||
/*#__PURE__*/React.createElement("button", {
|
||||
onClick: async () => {
|
||||
setVstScanning(true);
|
||||
setVstScanError(null);
|
||||
try {
|
||||
const resp = await fetch('/api/v1/desktop/plugins/scan', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ custom_directories: [vstScanPath], scan_formats: ['VST3', 'AU'], force_rescan: true })
|
||||
});
|
||||
const data = await resp.json();
|
||||
if (data.status === 'success') setVstPlugins(data.plugins || []);
|
||||
else setVstScanError(data.detail || 'Scan thất bại');
|
||||
} catch (err) {
|
||||
setVstScanError('Lỗi kết nối: ' + err.message);
|
||||
} finally {
|
||||
setVstScanning(false);
|
||||
}
|
||||
},
|
||||
disabled: vstScanning,
|
||||
className: "px-5 py-1.5 bg-purple-600 hover:bg-purple-500 disabled:bg-zinc-700 text-white rounded-lg text-xs font-bold transition-all flex items-center gap-2"
|
||||
}, vstScanning ? "Scanning..." : "Scan")
|
||||
),
|
||||
vstScanError && /*#__PURE__*/React.createElement("p", { className: "text-[10px] text-red-400" }, vstScanError),
|
||||
/*#__PURE__*/React.createElement("p", { className: "text-[10px] text-zinc-600" }, "Windows: C:\\Program Files\\Common Files\\VST3 · macOS: /Library/Audio/Plug-Ins/Components · Linux: /opt/daw_engine/vst3, ~/.vst3"),
|
||||
console.log('[SEQ] cuối children — evaluate xong')
|
||||
)
|
||||
))
|
||||
};
|
||||
const root = ReactDOM.createRoot(document.getElementById('root'));
|
||||
root.render(/*#__PURE__*/React.createElement(App, null));
|
||||
// Legacy render — ĐỒNG BỘ COMMIT (createRoot/concurrent có vấn đề commit trên
|
||||
// môi trường này — root children 0 dù render chạy — bug màn đen 10:35)
|
||||
window.addEventListener('error', function(ev) {
|
||||
console.log('[GLOBAL-ERR]', ev.message, ev.filename, ev.lineno);
|
||||
});
|
||||
window.addEventListener('unhandledrejection', function(ev) {
|
||||
console.log('[GLOBAL-REJECT]', String(ev.reason && ev.reason.message || ev.reason).slice(0, 200));
|
||||
});
|
||||
class ErrorBoundary extends React.Component {
|
||||
constructor(props) { super(props); this.state = { err: null }; }
|
||||
static getDerivedStateFromError(err) { return { err: err }; }
|
||||
componentDidCatch(err, info) { console.log('[BOUNDARY-ERR]', err && err.message, info && info.componentStack ? info.componentStack.slice(0, 300) : ''); }
|
||||
render() {
|
||||
if (this.state.err) {
|
||||
return React.createElement('div', { style: { padding: 20, color: '#fbb', fontFamily: 'monospace', fontSize: 12, whiteSpace: 'pre-wrap' } },
|
||||
'⚠️ LỖI RENDER: ' + (this.state.err && this.state.err.message) + '\n' + (this.state.err && this.state.err.stack || '').slice(0, 600));
|
||||
}
|
||||
return this.props.children;
|
||||
}
|
||||
}
|
||||
ReactDOM.render(React.createElement(ErrorBoundary, null, React.createElement(App, null)), document.getElementById('root'));
|
||||
setTimeout(() => lucide.createIcons(), 300);
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -22,6 +22,8 @@ window.API_BASE_URL = window.API_BASE_URL || window.location.origin;
|
||||
if (response.status === 401) {
|
||||
localStorage.removeItem('sonic_token');
|
||||
localStorage.removeItem('sonic_user');
|
||||
// Mở màn hình đăng nhập ngay (bug 09:45 — màn đen khi session hết hạn)
|
||||
if (window.__onAuthFail) window.__onAuthFail();
|
||||
}
|
||||
|
||||
const data = await response.json().catch(() => ({}));
|
||||
|
||||
Vendored
+12
File diff suppressed because one or more lines are too long
+29924
File diff suppressed because it is too large
Load Diff
+267
@@ -0,0 +1,267 @@
|
||||
/**
|
||||
* @license React
|
||||
* react-dom.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
(function(){/*
|
||||
Modernizr 3.0.0pre (Custom Build) | MIT
|
||||
*/
|
||||
'use strict';(function(Q,mb){"object"===typeof exports&&"undefined"!==typeof module?mb(exports,require("react")):"function"===typeof define&&define.amd?define(["exports","react"],mb):(Q=Q||self,mb(Q.ReactDOM={},Q.React))})(this,function(Q,mb){function n(a){for(var b="https://reactjs.org/docs/error-decoder.html?invariant="+a,c=1;c<arguments.length;c++)b+="&args[]="+encodeURIComponent(arguments[c]);return"Minified React error #"+a+"; visit "+b+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}
|
||||
function nb(a,b){Ab(a,b);Ab(a+"Capture",b)}function Ab(a,b){$b[a]=b;for(a=0;a<b.length;a++)cg.add(b[a])}function cj(a){if(Zd.call(dg,a))return!0;if(Zd.call(eg,a))return!1;if(dj.test(a))return dg[a]=!0;eg[a]=!0;return!1}function ej(a,b,c,d){if(null!==c&&0===c.type)return!1;switch(typeof b){case "function":case "symbol":return!0;case "boolean":if(d)return!1;if(null!==c)return!c.acceptsBooleans;a=a.toLowerCase().slice(0,5);return"data-"!==a&&"aria-"!==a;default:return!1}}function fj(a,b,c,d){if(null===
|
||||
b||"undefined"===typeof b||ej(a,b,c,d))return!0;if(d)return!1;if(null!==c)switch(c.type){case 3:return!b;case 4:return!1===b;case 5:return isNaN(b);case 6:return isNaN(b)||1>b}return!1}function Y(a,b,c,d,e,f,g){this.acceptsBooleans=2===b||3===b||4===b;this.attributeName=d;this.attributeNamespace=e;this.mustUseProperty=c;this.propertyName=a;this.type=b;this.sanitizeURL=f;this.removeEmptyString=g}function $d(a,b,c,d){var e=R.hasOwnProperty(b)?R[b]:null;if(null!==e?0!==e.type:d||!(2<b.length)||"o"!==
|
||||
b[0]&&"O"!==b[0]||"n"!==b[1]&&"N"!==b[1])fj(b,c,e,d)&&(c=null),d||null===e?cj(b)&&(null===c?a.removeAttribute(b):a.setAttribute(b,""+c)):e.mustUseProperty?a[e.propertyName]=null===c?3===e.type?!1:"":c:(b=e.attributeName,d=e.attributeNamespace,null===c?a.removeAttribute(b):(e=e.type,c=3===e||4===e&&!0===c?"":""+c,d?a.setAttributeNS(d,b,c):a.setAttribute(b,c)))}function ac(a){if(null===a||"object"!==typeof a)return null;a=fg&&a[fg]||a["@@iterator"];return"function"===typeof a?a:null}function bc(a,b,
|
||||
c){if(void 0===ae)try{throw Error();}catch(d){ae=(b=d.stack.trim().match(/\n( *(at )?)/))&&b[1]||""}return"\n"+ae+a}function be(a,b){if(!a||ce)return"";ce=!0;var c=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(b)if(b=function(){throw Error();},Object.defineProperty(b.prototype,"props",{set:function(){throw Error();}}),"object"===typeof Reflect&&Reflect.construct){try{Reflect.construct(b,[])}catch(m){var d=m}Reflect.construct(a,[],b)}else{try{b.call()}catch(m){d=m}a.call(b.prototype)}else{try{throw Error();
|
||||
}catch(m){d=m}a()}}catch(m){if(m&&d&&"string"===typeof m.stack){for(var e=m.stack.split("\n"),f=d.stack.split("\n"),g=e.length-1,h=f.length-1;1<=g&&0<=h&&e[g]!==f[h];)h--;for(;1<=g&&0<=h;g--,h--)if(e[g]!==f[h]){if(1!==g||1!==h){do if(g--,h--,0>h||e[g]!==f[h]){var k="\n"+e[g].replace(" at new "," at ");a.displayName&&k.includes("<anonymous>")&&(k=k.replace("<anonymous>",a.displayName));return k}while(1<=g&&0<=h)}break}}}finally{ce=!1,Error.prepareStackTrace=c}return(a=a?a.displayName||a.name:"")?bc(a):
|
||||
""}function gj(a){switch(a.tag){case 5:return bc(a.type);case 16:return bc("Lazy");case 13:return bc("Suspense");case 19:return bc("SuspenseList");case 0:case 2:case 15:return a=be(a.type,!1),a;case 11:return a=be(a.type.render,!1),a;case 1:return a=be(a.type,!0),a;default:return""}}function de(a){if(null==a)return null;if("function"===typeof a)return a.displayName||a.name||null;if("string"===typeof a)return a;switch(a){case Bb:return"Fragment";case Cb:return"Portal";case ee:return"Profiler";case fe:return"StrictMode";
|
||||
case ge:return"Suspense";case he:return"SuspenseList"}if("object"===typeof a)switch(a.$$typeof){case gg:return(a.displayName||"Context")+".Consumer";case hg:return(a._context.displayName||"Context")+".Provider";case ie:var b=a.render;a=a.displayName;a||(a=b.displayName||b.name||"",a=""!==a?"ForwardRef("+a+")":"ForwardRef");return a;case je:return b=a.displayName||null,null!==b?b:de(a.type)||"Memo";case Ta:b=a._payload;a=a._init;try{return de(a(b))}catch(c){}}return null}function hj(a){var b=a.type;
|
||||
switch(a.tag){case 24:return"Cache";case 9:return(b.displayName||"Context")+".Consumer";case 10:return(b._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return a=b.render,a=a.displayName||a.name||"",b.displayName||(""!==a?"ForwardRef("+a+")":"ForwardRef");case 7:return"Fragment";case 5:return b;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return de(b);case 8:return b===fe?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";
|
||||
case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if("function"===typeof b)return b.displayName||b.name||null;if("string"===typeof b)return b}return null}function Ua(a){switch(typeof a){case "boolean":case "number":case "string":case "undefined":return a;case "object":return a;default:return""}}function ig(a){var b=a.type;return(a=a.nodeName)&&"input"===a.toLowerCase()&&("checkbox"===b||"radio"===
|
||||
b)}function ij(a){var b=ig(a)?"checked":"value",c=Object.getOwnPropertyDescriptor(a.constructor.prototype,b),d=""+a[b];if(!a.hasOwnProperty(b)&&"undefined"!==typeof c&&"function"===typeof c.get&&"function"===typeof c.set){var e=c.get,f=c.set;Object.defineProperty(a,b,{configurable:!0,get:function(){return e.call(this)},set:function(a){d=""+a;f.call(this,a)}});Object.defineProperty(a,b,{enumerable:c.enumerable});return{getValue:function(){return d},setValue:function(a){d=""+a},stopTracking:function(){a._valueTracker=
|
||||
null;delete a[b]}}}}function Pc(a){a._valueTracker||(a._valueTracker=ij(a))}function jg(a){if(!a)return!1;var b=a._valueTracker;if(!b)return!0;var c=b.getValue();var d="";a&&(d=ig(a)?a.checked?"true":"false":a.value);a=d;return a!==c?(b.setValue(a),!0):!1}function Qc(a){a=a||("undefined"!==typeof document?document:void 0);if("undefined"===typeof a)return null;try{return a.activeElement||a.body}catch(b){return a.body}}function ke(a,b){var c=b.checked;return E({},b,{defaultChecked:void 0,defaultValue:void 0,
|
||||
value:void 0,checked:null!=c?c:a._wrapperState.initialChecked})}function kg(a,b){var c=null==b.defaultValue?"":b.defaultValue,d=null!=b.checked?b.checked:b.defaultChecked;c=Ua(null!=b.value?b.value:c);a._wrapperState={initialChecked:d,initialValue:c,controlled:"checkbox"===b.type||"radio"===b.type?null!=b.checked:null!=b.value}}function lg(a,b){b=b.checked;null!=b&&$d(a,"checked",b,!1)}function le(a,b){lg(a,b);var c=Ua(b.value),d=b.type;if(null!=c)if("number"===d){if(0===c&&""===a.value||a.value!=
|
||||
c)a.value=""+c}else a.value!==""+c&&(a.value=""+c);else if("submit"===d||"reset"===d){a.removeAttribute("value");return}b.hasOwnProperty("value")?me(a,b.type,c):b.hasOwnProperty("defaultValue")&&me(a,b.type,Ua(b.defaultValue));null==b.checked&&null!=b.defaultChecked&&(a.defaultChecked=!!b.defaultChecked)}function mg(a,b,c){if(b.hasOwnProperty("value")||b.hasOwnProperty("defaultValue")){var d=b.type;if(!("submit"!==d&&"reset"!==d||void 0!==b.value&&null!==b.value))return;b=""+a._wrapperState.initialValue;
|
||||
c||b===a.value||(a.value=b);a.defaultValue=b}c=a.name;""!==c&&(a.name="");a.defaultChecked=!!a._wrapperState.initialChecked;""!==c&&(a.name=c)}function me(a,b,c){if("number"!==b||Qc(a.ownerDocument)!==a)null==c?a.defaultValue=""+a._wrapperState.initialValue:a.defaultValue!==""+c&&(a.defaultValue=""+c)}function Db(a,b,c,d){a=a.options;if(b){b={};for(var e=0;e<c.length;e++)b["$"+c[e]]=!0;for(c=0;c<a.length;c++)e=b.hasOwnProperty("$"+a[c].value),a[c].selected!==e&&(a[c].selected=e),e&&d&&(a[c].defaultSelected=
|
||||
!0)}else{c=""+Ua(c);b=null;for(e=0;e<a.length;e++){if(a[e].value===c){a[e].selected=!0;d&&(a[e].defaultSelected=!0);return}null!==b||a[e].disabled||(b=a[e])}null!==b&&(b.selected=!0)}}function ne(a,b){if(null!=b.dangerouslySetInnerHTML)throw Error(n(91));return E({},b,{value:void 0,defaultValue:void 0,children:""+a._wrapperState.initialValue})}function ng(a,b){var c=b.value;if(null==c){c=b.children;b=b.defaultValue;if(null!=c){if(null!=b)throw Error(n(92));if(cc(c)){if(1<c.length)throw Error(n(93));
|
||||
c=c[0]}b=c}null==b&&(b="");c=b}a._wrapperState={initialValue:Ua(c)}}function og(a,b){var c=Ua(b.value),d=Ua(b.defaultValue);null!=c&&(c=""+c,c!==a.value&&(a.value=c),null==b.defaultValue&&a.defaultValue!==c&&(a.defaultValue=c));null!=d&&(a.defaultValue=""+d)}function pg(a,b){b=a.textContent;b===a._wrapperState.initialValue&&""!==b&&null!==b&&(a.value=b)}function qg(a){switch(a){case "svg":return"http://www.w3.org/2000/svg";case "math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}
|
||||
function oe(a,b){return null==a||"http://www.w3.org/1999/xhtml"===a?qg(b):"http://www.w3.org/2000/svg"===a&&"foreignObject"===b?"http://www.w3.org/1999/xhtml":a}function rg(a,b,c){return null==b||"boolean"===typeof b||""===b?"":c||"number"!==typeof b||0===b||dc.hasOwnProperty(a)&&dc[a]?(""+b).trim():b+"px"}function sg(a,b){a=a.style;for(var c in b)if(b.hasOwnProperty(c)){var d=0===c.indexOf("--"),e=rg(c,b[c],d);"float"===c&&(c="cssFloat");d?a.setProperty(c,e):a[c]=e}}function pe(a,b){if(b){if(jj[a]&&
|
||||
(null!=b.children||null!=b.dangerouslySetInnerHTML))throw Error(n(137,a));if(null!=b.dangerouslySetInnerHTML){if(null!=b.children)throw Error(n(60));if("object"!==typeof b.dangerouslySetInnerHTML||!("__html"in b.dangerouslySetInnerHTML))throw Error(n(61));}if(null!=b.style&&"object"!==typeof b.style)throw Error(n(62));}}function qe(a,b){if(-1===a.indexOf("-"))return"string"===typeof b.is;switch(a){case "annotation-xml":case "color-profile":case "font-face":case "font-face-src":case "font-face-uri":case "font-face-format":case "font-face-name":case "missing-glyph":return!1;
|
||||
default:return!0}}function re(a){a=a.target||a.srcElement||window;a.correspondingUseElement&&(a=a.correspondingUseElement);return 3===a.nodeType?a.parentNode:a}function tg(a){if(a=ec(a)){if("function"!==typeof se)throw Error(n(280));var b=a.stateNode;b&&(b=Rc(b),se(a.stateNode,a.type,b))}}function ug(a){Eb?Fb?Fb.push(a):Fb=[a]:Eb=a}function vg(){if(Eb){var a=Eb,b=Fb;Fb=Eb=null;tg(a);if(b)for(a=0;a<b.length;a++)tg(b[a])}}function wg(a,b,c){if(te)return a(b,c);te=!0;try{return xg(a,b,c)}finally{if(te=
|
||||
!1,null!==Eb||null!==Fb)yg(),vg()}}function fc(a,b){var c=a.stateNode;if(null===c)return null;var d=Rc(c);if(null===d)return null;c=d[b];a:switch(b){case "onClick":case "onClickCapture":case "onDoubleClick":case "onDoubleClickCapture":case "onMouseDown":case "onMouseDownCapture":case "onMouseMove":case "onMouseMoveCapture":case "onMouseUp":case "onMouseUpCapture":case "onMouseEnter":(d=!d.disabled)||(a=a.type,d=!("button"===a||"input"===a||"select"===a||"textarea"===a));a=!d;break a;default:a=!1}if(a)return null;
|
||||
if(c&&"function"!==typeof c)throw Error(n(231,b,typeof c));return c}function kj(a,b,c,d,e,f,g,h,k){gc=!1;Sc=null;lj.apply(mj,arguments)}function nj(a,b,c,d,e,f,g,h,k){kj.apply(this,arguments);if(gc){if(gc){var m=Sc;gc=!1;Sc=null}else throw Error(n(198));Tc||(Tc=!0,ue=m)}}function ob(a){var b=a,c=a;if(a.alternate)for(;b.return;)b=b.return;else{a=b;do b=a,0!==(b.flags&4098)&&(c=b.return),a=b.return;while(a)}return 3===b.tag?c:null}function zg(a){if(13===a.tag){var b=a.memoizedState;null===b&&(a=a.alternate,
|
||||
null!==a&&(b=a.memoizedState));if(null!==b)return b.dehydrated}return null}function Ag(a){if(ob(a)!==a)throw Error(n(188));}function oj(a){var b=a.alternate;if(!b){b=ob(a);if(null===b)throw Error(n(188));return b!==a?null:a}for(var c=a,d=b;;){var e=c.return;if(null===e)break;var f=e.alternate;if(null===f){d=e.return;if(null!==d){c=d;continue}break}if(e.child===f.child){for(f=e.child;f;){if(f===c)return Ag(e),a;if(f===d)return Ag(e),b;f=f.sibling}throw Error(n(188));}if(c.return!==d.return)c=e,d=f;
|
||||
else{for(var g=!1,h=e.child;h;){if(h===c){g=!0;c=e;d=f;break}if(h===d){g=!0;d=e;c=f;break}h=h.sibling}if(!g){for(h=f.child;h;){if(h===c){g=!0;c=f;d=e;break}if(h===d){g=!0;d=f;c=e;break}h=h.sibling}if(!g)throw Error(n(189));}}if(c.alternate!==d)throw Error(n(190));}if(3!==c.tag)throw Error(n(188));return c.stateNode.current===c?a:b}function Bg(a){a=oj(a);return null!==a?Cg(a):null}function Cg(a){if(5===a.tag||6===a.tag)return a;for(a=a.child;null!==a;){var b=Cg(a);if(null!==b)return b;a=a.sibling}return null}
|
||||
function pj(a,b){if(Ca&&"function"===typeof Ca.onCommitFiberRoot)try{Ca.onCommitFiberRoot(Uc,a,void 0,128===(a.current.flags&128))}catch(c){}}function qj(a){a>>>=0;return 0===a?32:31-(rj(a)/sj|0)|0}function hc(a){switch(a&-a){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return a&
|
||||
4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return a&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return a}}function Vc(a,b){var c=a.pendingLanes;if(0===c)return 0;var d=0,e=a.suspendedLanes,f=a.pingedLanes,g=c&268435455;if(0!==g){var h=g&~e;0!==h?d=hc(h):(f&=g,0!==f&&(d=hc(f)))}else g=c&~e,0!==g?d=hc(g):0!==f&&(d=hc(f));if(0===d)return 0;if(0!==b&&b!==d&&0===(b&e)&&
|
||||
(e=d&-d,f=b&-b,e>=f||16===e&&0!==(f&4194240)))return b;0!==(d&4)&&(d|=c&16);b=a.entangledLanes;if(0!==b)for(a=a.entanglements,b&=d;0<b;)c=31-ta(b),e=1<<c,d|=a[c],b&=~e;return d}function tj(a,b){switch(a){case 1:case 2:case 4:return b+250;case 8:case 16:case 32:case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return b+5E3;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return-1;
|
||||
case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function uj(a,b){for(var c=a.suspendedLanes,d=a.pingedLanes,e=a.expirationTimes,f=a.pendingLanes;0<f;){var g=31-ta(f),h=1<<g,k=e[g];if(-1===k){if(0===(h&c)||0!==(h&d))e[g]=tj(h,b)}else k<=b&&(a.expiredLanes|=h);f&=~h}}function ve(a){a=a.pendingLanes&-1073741825;return 0!==a?a:a&1073741824?1073741824:0}function Dg(){var a=Wc;Wc<<=1;0===(Wc&4194240)&&(Wc=64);return a}function we(a){for(var b=[],c=0;31>c;c++)b.push(a);
|
||||
return b}function ic(a,b,c){a.pendingLanes|=b;536870912!==b&&(a.suspendedLanes=0,a.pingedLanes=0);a=a.eventTimes;b=31-ta(b);a[b]=c}function vj(a,b){var c=a.pendingLanes&~b;a.pendingLanes=b;a.suspendedLanes=0;a.pingedLanes=0;a.expiredLanes&=b;a.mutableReadLanes&=b;a.entangledLanes&=b;b=a.entanglements;var d=a.eventTimes;for(a=a.expirationTimes;0<c;){var e=31-ta(c),f=1<<e;b[e]=0;d[e]=-1;a[e]=-1;c&=~f}}function xe(a,b){var c=a.entangledLanes|=b;for(a=a.entanglements;c;){var d=31-ta(c),e=1<<d;e&b|a[d]&
|
||||
b&&(a[d]|=b);c&=~e}}function Eg(a){a&=-a;return 1<a?4<a?0!==(a&268435455)?16:536870912:4:1}function Fg(a,b){switch(a){case "focusin":case "focusout":Va=null;break;case "dragenter":case "dragleave":Wa=null;break;case "mouseover":case "mouseout":Xa=null;break;case "pointerover":case "pointerout":jc.delete(b.pointerId);break;case "gotpointercapture":case "lostpointercapture":kc.delete(b.pointerId)}}function lc(a,b,c,d,e,f){if(null===a||a.nativeEvent!==f)return a={blockedOn:b,domEventName:c,eventSystemFlags:d,
|
||||
nativeEvent:f,targetContainers:[e]},null!==b&&(b=ec(b),null!==b&&Gg(b)),a;a.eventSystemFlags|=d;b=a.targetContainers;null!==e&&-1===b.indexOf(e)&&b.push(e);return a}function wj(a,b,c,d,e){switch(b){case "focusin":return Va=lc(Va,a,b,c,d,e),!0;case "dragenter":return Wa=lc(Wa,a,b,c,d,e),!0;case "mouseover":return Xa=lc(Xa,a,b,c,d,e),!0;case "pointerover":var f=e.pointerId;jc.set(f,lc(jc.get(f)||null,a,b,c,d,e));return!0;case "gotpointercapture":return f=e.pointerId,kc.set(f,lc(kc.get(f)||null,a,b,
|
||||
c,d,e)),!0}return!1}function Hg(a){var b=pb(a.target);if(null!==b){var c=ob(b);if(null!==c)if(b=c.tag,13===b){if(b=zg(c),null!==b){a.blockedOn=b;xj(a.priority,function(){yj(c)});return}}else if(3===b&&c.stateNode.current.memoizedState.isDehydrated){a.blockedOn=3===c.tag?c.stateNode.containerInfo:null;return}}a.blockedOn=null}function Xc(a){if(null!==a.blockedOn)return!1;for(var b=a.targetContainers;0<b.length;){var c=ye(a.domEventName,a.eventSystemFlags,b[0],a.nativeEvent);if(null===c){c=a.nativeEvent;
|
||||
var d=new c.constructor(c.type,c);ze=d;c.target.dispatchEvent(d);ze=null}else return b=ec(c),null!==b&&Gg(b),a.blockedOn=c,!1;b.shift()}return!0}function Ig(a,b,c){Xc(a)&&c.delete(b)}function zj(){Ae=!1;null!==Va&&Xc(Va)&&(Va=null);null!==Wa&&Xc(Wa)&&(Wa=null);null!==Xa&&Xc(Xa)&&(Xa=null);jc.forEach(Ig);kc.forEach(Ig)}function mc(a,b){a.blockedOn===b&&(a.blockedOn=null,Ae||(Ae=!0,Jg(Kg,zj)))}function nc(a){if(0<Yc.length){mc(Yc[0],a);for(var b=1;b<Yc.length;b++){var c=Yc[b];c.blockedOn===a&&(c.blockedOn=
|
||||
null)}}null!==Va&&mc(Va,a);null!==Wa&&mc(Wa,a);null!==Xa&&mc(Xa,a);b=function(b){return mc(b,a)};jc.forEach(b);kc.forEach(b);for(b=0;b<Ya.length;b++)c=Ya[b],c.blockedOn===a&&(c.blockedOn=null);for(;0<Ya.length&&(b=Ya[0],null===b.blockedOn);)Hg(b),null===b.blockedOn&&Ya.shift()}function Aj(a,b,c,d){var e=z,f=Gb.transition;Gb.transition=null;try{z=1,Be(a,b,c,d)}finally{z=e,Gb.transition=f}}function Bj(a,b,c,d){var e=z,f=Gb.transition;Gb.transition=null;try{z=4,Be(a,b,c,d)}finally{z=e,Gb.transition=
|
||||
f}}function Be(a,b,c,d){if(Zc){var e=ye(a,b,c,d);if(null===e)Ce(a,b,d,$c,c),Fg(a,d);else if(wj(e,a,b,c,d))d.stopPropagation();else if(Fg(a,d),b&4&&-1<Cj.indexOf(a)){for(;null!==e;){var f=ec(e);null!==f&&Dj(f);f=ye(a,b,c,d);null===f&&Ce(a,b,d,$c,c);if(f===e)break;e=f}null!==e&&d.stopPropagation()}else Ce(a,b,d,null,c)}}function ye(a,b,c,d){$c=null;a=re(d);a=pb(a);if(null!==a)if(b=ob(a),null===b)a=null;else if(c=b.tag,13===c){a=zg(b);if(null!==a)return a;a=null}else if(3===c){if(b.stateNode.current.memoizedState.isDehydrated)return 3===
|
||||
b.tag?b.stateNode.containerInfo:null;a=null}else b!==a&&(a=null);$c=a;return null}function Lg(a){switch(a){case "cancel":case "click":case "close":case "contextmenu":case "copy":case "cut":case "auxclick":case "dblclick":case "dragend":case "dragstart":case "drop":case "focusin":case "focusout":case "input":case "invalid":case "keydown":case "keypress":case "keyup":case "mousedown":case "mouseup":case "paste":case "pause":case "play":case "pointercancel":case "pointerdown":case "pointerup":case "ratechange":case "reset":case "resize":case "seeked":case "submit":case "touchcancel":case "touchend":case "touchstart":case "volumechange":case "change":case "selectionchange":case "textInput":case "compositionstart":case "compositionend":case "compositionupdate":case "beforeblur":case "afterblur":case "beforeinput":case "blur":case "fullscreenchange":case "focus":case "hashchange":case "popstate":case "select":case "selectstart":return 1;
|
||||
case "drag":case "dragenter":case "dragexit":case "dragleave":case "dragover":case "mousemove":case "mouseout":case "mouseover":case "pointermove":case "pointerout":case "pointerover":case "scroll":case "toggle":case "touchmove":case "wheel":case "mouseenter":case "mouseleave":case "pointerenter":case "pointerleave":return 4;case "message":switch(Ej()){case De:return 1;case Mg:return 4;case ad:case Fj:return 16;case Ng:return 536870912;default:return 16}default:return 16}}function Og(){if(bd)return bd;
|
||||
var a,b=Ee,c=b.length,d,e="value"in Za?Za.value:Za.textContent,f=e.length;for(a=0;a<c&&b[a]===e[a];a++);var g=c-a;for(d=1;d<=g&&b[c-d]===e[f-d];d++);return bd=e.slice(a,1<d?1-d:void 0)}function cd(a){var b=a.keyCode;"charCode"in a?(a=a.charCode,0===a&&13===b&&(a=13)):a=b;10===a&&(a=13);return 32<=a||13===a?a:0}function dd(){return!0}function Pg(){return!1}function ka(a){function b(b,d,e,f,g){this._reactName=b;this._targetInst=e;this.type=d;this.nativeEvent=f;this.target=g;this.currentTarget=null;
|
||||
for(var c in a)a.hasOwnProperty(c)&&(b=a[c],this[c]=b?b(f):f[c]);this.isDefaultPrevented=(null!=f.defaultPrevented?f.defaultPrevented:!1===f.returnValue)?dd:Pg;this.isPropagationStopped=Pg;return this}E(b.prototype,{preventDefault:function(){this.defaultPrevented=!0;var a=this.nativeEvent;a&&(a.preventDefault?a.preventDefault():"unknown"!==typeof a.returnValue&&(a.returnValue=!1),this.isDefaultPrevented=dd)},stopPropagation:function(){var a=this.nativeEvent;a&&(a.stopPropagation?a.stopPropagation():
|
||||
"unknown"!==typeof a.cancelBubble&&(a.cancelBubble=!0),this.isPropagationStopped=dd)},persist:function(){},isPersistent:dd});return b}function Gj(a){var b=this.nativeEvent;return b.getModifierState?b.getModifierState(a):(a=Hj[a])?!!b[a]:!1}function Fe(a){return Gj}function Qg(a,b){switch(a){case "keyup":return-1!==Ij.indexOf(b.keyCode);case "keydown":return 229!==b.keyCode;case "keypress":case "mousedown":case "focusout":return!0;default:return!1}}function Rg(a){a=a.detail;return"object"===typeof a&&
|
||||
"data"in a?a.data:null}function Jj(a,b){switch(a){case "compositionend":return Rg(b);case "keypress":if(32!==b.which)return null;Sg=!0;return Tg;case "textInput":return a=b.data,a===Tg&&Sg?null:a;default:return null}}function Kj(a,b){if(Hb)return"compositionend"===a||!Ge&&Qg(a,b)?(a=Og(),bd=Ee=Za=null,Hb=!1,a):null;switch(a){case "paste":return null;case "keypress":if(!(b.ctrlKey||b.altKey||b.metaKey)||b.ctrlKey&&b.altKey){if(b.char&&1<b.char.length)return b.char;if(b.which)return String.fromCharCode(b.which)}return null;
|
||||
case "compositionend":return Ug&&"ko"!==b.locale?null:b.data;default:return null}}function Vg(a){var b=a&&a.nodeName&&a.nodeName.toLowerCase();return"input"===b?!!Lj[a.type]:"textarea"===b?!0:!1}function Mj(a){if(!Ia)return!1;a="on"+a;var b=a in document;b||(b=document.createElement("div"),b.setAttribute(a,"return;"),b="function"===typeof b[a]);return b}function Wg(a,b,c,d){ug(d);b=ed(b,"onChange");0<b.length&&(c=new He("onChange","change",null,c,d),a.push({event:c,listeners:b}))}function Nj(a){Xg(a,
|
||||
0)}function fd(a){var b=Ib(a);if(jg(b))return a}function Oj(a,b){if("change"===a)return b}function Yg(){oc&&(oc.detachEvent("onpropertychange",Zg),pc=oc=null)}function Zg(a){if("value"===a.propertyName&&fd(pc)){var b=[];Wg(b,pc,a,re(a));wg(Nj,b)}}function Pj(a,b,c){"focusin"===a?(Yg(),oc=b,pc=c,oc.attachEvent("onpropertychange",Zg)):"focusout"===a&&Yg()}function Qj(a,b){if("selectionchange"===a||"keyup"===a||"keydown"===a)return fd(pc)}function Rj(a,b){if("click"===a)return fd(b)}function Sj(a,b){if("input"===
|
||||
a||"change"===a)return fd(b)}function Tj(a,b){return a===b&&(0!==a||1/a===1/b)||a!==a&&b!==b}function qc(a,b){if(ua(a,b))return!0;if("object"!==typeof a||null===a||"object"!==typeof b||null===b)return!1;var c=Object.keys(a),d=Object.keys(b);if(c.length!==d.length)return!1;for(d=0;d<c.length;d++){var e=c[d];if(!Zd.call(b,e)||!ua(a[e],b[e]))return!1}return!0}function $g(a){for(;a&&a.firstChild;)a=a.firstChild;return a}function ah(a,b){var c=$g(a);a=0;for(var d;c;){if(3===c.nodeType){d=a+c.textContent.length;
|
||||
if(a<=b&&d>=b)return{node:c,offset:b-a};a=d}a:{for(;c;){if(c.nextSibling){c=c.nextSibling;break a}c=c.parentNode}c=void 0}c=$g(c)}}function bh(a,b){return a&&b?a===b?!0:a&&3===a.nodeType?!1:b&&3===b.nodeType?bh(a,b.parentNode):"contains"in a?a.contains(b):a.compareDocumentPosition?!!(a.compareDocumentPosition(b)&16):!1:!1}function ch(){for(var a=window,b=Qc();b instanceof a.HTMLIFrameElement;){try{var c="string"===typeof b.contentWindow.location.href}catch(d){c=!1}if(c)a=b.contentWindow;else break;
|
||||
b=Qc(a.document)}return b}function Ie(a){var b=a&&a.nodeName&&a.nodeName.toLowerCase();return b&&("input"===b&&("text"===a.type||"search"===a.type||"tel"===a.type||"url"===a.type||"password"===a.type)||"textarea"===b||"true"===a.contentEditable)}function Uj(a){var b=ch(),c=a.focusedElem,d=a.selectionRange;if(b!==c&&c&&c.ownerDocument&&bh(c.ownerDocument.documentElement,c)){if(null!==d&&Ie(c))if(b=d.start,a=d.end,void 0===a&&(a=b),"selectionStart"in c)c.selectionStart=b,c.selectionEnd=Math.min(a,c.value.length);
|
||||
else if(a=(b=c.ownerDocument||document)&&b.defaultView||window,a.getSelection){a=a.getSelection();var e=c.textContent.length,f=Math.min(d.start,e);d=void 0===d.end?f:Math.min(d.end,e);!a.extend&&f>d&&(e=d,d=f,f=e);e=ah(c,f);var g=ah(c,d);e&&g&&(1!==a.rangeCount||a.anchorNode!==e.node||a.anchorOffset!==e.offset||a.focusNode!==g.node||a.focusOffset!==g.offset)&&(b=b.createRange(),b.setStart(e.node,e.offset),a.removeAllRanges(),f>d?(a.addRange(b),a.extend(g.node,g.offset)):(b.setEnd(g.node,g.offset),
|
||||
a.addRange(b)))}b=[];for(a=c;a=a.parentNode;)1===a.nodeType&&b.push({element:a,left:a.scrollLeft,top:a.scrollTop});"function"===typeof c.focus&&c.focus();for(c=0;c<b.length;c++)a=b[c],a.element.scrollLeft=a.left,a.element.scrollTop=a.top}}function dh(a,b,c){var d=c.window===c?c.document:9===c.nodeType?c:c.ownerDocument;Je||null==Jb||Jb!==Qc(d)||(d=Jb,"selectionStart"in d&&Ie(d)?d={start:d.selectionStart,end:d.selectionEnd}:(d=(d.ownerDocument&&d.ownerDocument.defaultView||window).getSelection(),d=
|
||||
{anchorNode:d.anchorNode,anchorOffset:d.anchorOffset,focusNode:d.focusNode,focusOffset:d.focusOffset}),rc&&qc(rc,d)||(rc=d,d=ed(Ke,"onSelect"),0<d.length&&(b=new He("onSelect","select",null,b,c),a.push({event:b,listeners:d}),b.target=Jb)))}function gd(a,b){var c={};c[a.toLowerCase()]=b.toLowerCase();c["Webkit"+a]="webkit"+b;c["Moz"+a]="moz"+b;return c}function hd(a){if(Le[a])return Le[a];if(!Kb[a])return a;var b=Kb[a],c;for(c in b)if(b.hasOwnProperty(c)&&c in eh)return Le[a]=b[c];return a}function $a(a,
|
||||
b){fh.set(a,b);nb(b,[a])}function gh(a,b,c){var d=a.type||"unknown-event";a.currentTarget=c;nj(d,b,void 0,a);a.currentTarget=null}function Xg(a,b){b=0!==(b&4);for(var c=0;c<a.length;c++){var d=a[c],e=d.event;d=d.listeners;a:{var f=void 0;if(b)for(var g=d.length-1;0<=g;g--){var h=d[g],k=h.instance,m=h.currentTarget;h=h.listener;if(k!==f&&e.isPropagationStopped())break a;gh(e,h,m);f=k}else for(g=0;g<d.length;g++){h=d[g];k=h.instance;m=h.currentTarget;h=h.listener;if(k!==f&&e.isPropagationStopped())break a;
|
||||
gh(e,h,m);f=k}}}if(Tc)throw a=ue,Tc=!1,ue=null,a;}function B(a,b){var c=b[Me];void 0===c&&(c=b[Me]=new Set);var d=a+"__bubble";c.has(d)||(hh(b,a,2,!1),c.add(d))}function Ne(a,b,c){var d=0;b&&(d|=4);hh(c,a,d,b)}function sc(a){if(!a[id]){a[id]=!0;cg.forEach(function(b){"selectionchange"!==b&&(Vj.has(b)||Ne(b,!1,a),Ne(b,!0,a))});var b=9===a.nodeType?a:a.ownerDocument;null===b||b[id]||(b[id]=!0,Ne("selectionchange",!1,b))}}function hh(a,b,c,d,e){switch(Lg(b)){case 1:e=Aj;break;case 4:e=Bj;break;default:e=
|
||||
Be}c=e.bind(null,b,c,a);e=void 0;!Oe||"touchstart"!==b&&"touchmove"!==b&&"wheel"!==b||(e=!0);d?void 0!==e?a.addEventListener(b,c,{capture:!0,passive:e}):a.addEventListener(b,c,!0):void 0!==e?a.addEventListener(b,c,{passive:e}):a.addEventListener(b,c,!1)}function Ce(a,b,c,d,e){var f=d;if(0===(b&1)&&0===(b&2)&&null!==d)a:for(;;){if(null===d)return;var g=d.tag;if(3===g||4===g){var h=d.stateNode.containerInfo;if(h===e||8===h.nodeType&&h.parentNode===e)break;if(4===g)for(g=d.return;null!==g;){var k=g.tag;
|
||||
if(3===k||4===k)if(k=g.stateNode.containerInfo,k===e||8===k.nodeType&&k.parentNode===e)return;g=g.return}for(;null!==h;){g=pb(h);if(null===g)return;k=g.tag;if(5===k||6===k){d=f=g;continue a}h=h.parentNode}}d=d.return}wg(function(){var d=f,e=re(c),g=[];a:{var h=fh.get(a);if(void 0!==h){var k=He,n=a;switch(a){case "keypress":if(0===cd(c))break a;case "keydown":case "keyup":k=Wj;break;case "focusin":n="focus";k=Pe;break;case "focusout":n="blur";k=Pe;break;case "beforeblur":case "afterblur":k=Pe;break;
|
||||
case "click":if(2===c.button)break a;case "auxclick":case "dblclick":case "mousedown":case "mousemove":case "mouseup":case "mouseout":case "mouseover":case "contextmenu":k=ih;break;case "drag":case "dragend":case "dragenter":case "dragexit":case "dragleave":case "dragover":case "dragstart":case "drop":k=Xj;break;case "touchcancel":case "touchend":case "touchmove":case "touchstart":k=Yj;break;case jh:case kh:case lh:k=Zj;break;case mh:k=ak;break;case "scroll":k=bk;break;case "wheel":k=ck;break;case "copy":case "cut":case "paste":k=
|
||||
dk;break;case "gotpointercapture":case "lostpointercapture":case "pointercancel":case "pointerdown":case "pointermove":case "pointerout":case "pointerover":case "pointerup":k=nh}var l=0!==(b&4),p=!l&&"scroll"===a,A=l?null!==h?h+"Capture":null:h;l=[];for(var v=d,q;null!==v;){q=v;var M=q.stateNode;5===q.tag&&null!==M&&(q=M,null!==A&&(M=fc(v,A),null!=M&&l.push(tc(v,M,q))));if(p)break;v=v.return}0<l.length&&(h=new k(h,n,null,c,e),g.push({event:h,listeners:l}))}}if(0===(b&7)){a:{h="mouseover"===a||"pointerover"===
|
||||
a;k="mouseout"===a||"pointerout"===a;if(h&&c!==ze&&(n=c.relatedTarget||c.fromElement)&&(pb(n)||n[Ja]))break a;if(k||h){h=e.window===e?e:(h=e.ownerDocument)?h.defaultView||h.parentWindow:window;if(k){if(n=c.relatedTarget||c.toElement,k=d,n=n?pb(n):null,null!==n&&(p=ob(n),n!==p||5!==n.tag&&6!==n.tag))n=null}else k=null,n=d;if(k!==n){l=ih;M="onMouseLeave";A="onMouseEnter";v="mouse";if("pointerout"===a||"pointerover"===a)l=nh,M="onPointerLeave",A="onPointerEnter",v="pointer";p=null==k?h:Ib(k);q=null==
|
||||
n?h:Ib(n);h=new l(M,v+"leave",k,c,e);h.target=p;h.relatedTarget=q;M=null;pb(e)===d&&(l=new l(A,v+"enter",n,c,e),l.target=q,l.relatedTarget=p,M=l);p=M;if(k&&n)b:{l=k;A=n;v=0;for(q=l;q;q=Lb(q))v++;q=0;for(M=A;M;M=Lb(M))q++;for(;0<v-q;)l=Lb(l),v--;for(;0<q-v;)A=Lb(A),q--;for(;v--;){if(l===A||null!==A&&l===A.alternate)break b;l=Lb(l);A=Lb(A)}l=null}else l=null;null!==k&&oh(g,h,k,l,!1);null!==n&&null!==p&&oh(g,p,n,l,!0)}}}a:{h=d?Ib(d):window;k=h.nodeName&&h.nodeName.toLowerCase();if("select"===k||"input"===
|
||||
k&&"file"===h.type)var ma=Oj;else if(Vg(h))if(ph)ma=Sj;else{ma=Qj;var va=Pj}else(k=h.nodeName)&&"input"===k.toLowerCase()&&("checkbox"===h.type||"radio"===h.type)&&(ma=Rj);if(ma&&(ma=ma(a,d))){Wg(g,ma,c,e);break a}va&&va(a,h,d);"focusout"===a&&(va=h._wrapperState)&&va.controlled&&"number"===h.type&&me(h,"number",h.value)}va=d?Ib(d):window;switch(a){case "focusin":if(Vg(va)||"true"===va.contentEditable)Jb=va,Ke=d,rc=null;break;case "focusout":rc=Ke=Jb=null;break;case "mousedown":Je=!0;break;case "contextmenu":case "mouseup":case "dragend":Je=
|
||||
!1;dh(g,c,e);break;case "selectionchange":if(ek)break;case "keydown":case "keyup":dh(g,c,e)}var ab;if(Ge)b:{switch(a){case "compositionstart":var da="onCompositionStart";break b;case "compositionend":da="onCompositionEnd";break b;case "compositionupdate":da="onCompositionUpdate";break b}da=void 0}else Hb?Qg(a,c)&&(da="onCompositionEnd"):"keydown"===a&&229===c.keyCode&&(da="onCompositionStart");da&&(Ug&&"ko"!==c.locale&&(Hb||"onCompositionStart"!==da?"onCompositionEnd"===da&&Hb&&(ab=Og()):(Za=e,Ee=
|
||||
"value"in Za?Za.value:Za.textContent,Hb=!0)),va=ed(d,da),0<va.length&&(da=new qh(da,a,null,c,e),g.push({event:da,listeners:va}),ab?da.data=ab:(ab=Rg(c),null!==ab&&(da.data=ab))));if(ab=fk?Jj(a,c):Kj(a,c))d=ed(d,"onBeforeInput"),0<d.length&&(e=new gk("onBeforeInput","beforeinput",null,c,e),g.push({event:e,listeners:d}),e.data=ab)}Xg(g,b)})}function tc(a,b,c){return{instance:a,listener:b,currentTarget:c}}function ed(a,b){for(var c=b+"Capture",d=[];null!==a;){var e=a,f=e.stateNode;5===e.tag&&null!==
|
||||
f&&(e=f,f=fc(a,c),null!=f&&d.unshift(tc(a,f,e)),f=fc(a,b),null!=f&&d.push(tc(a,f,e)));a=a.return}return d}function Lb(a){if(null===a)return null;do a=a.return;while(a&&5!==a.tag);return a?a:null}function oh(a,b,c,d,e){for(var f=b._reactName,g=[];null!==c&&c!==d;){var h=c,k=h.alternate,m=h.stateNode;if(null!==k&&k===d)break;5===h.tag&&null!==m&&(h=m,e?(k=fc(c,f),null!=k&&g.unshift(tc(c,k,h))):e||(k=fc(c,f),null!=k&&g.push(tc(c,k,h))));c=c.return}0!==g.length&&a.push({event:b,listeners:g})}function rh(a){return("string"===
|
||||
typeof a?a:""+a).replace(hk,"\n").replace(ik,"")}function jd(a,b,c,d){b=rh(b);if(rh(a)!==b&&c)throw Error(n(425));}function kd(){}function Qe(a,b){return"textarea"===a||"noscript"===a||"string"===typeof b.children||"number"===typeof b.children||"object"===typeof b.dangerouslySetInnerHTML&&null!==b.dangerouslySetInnerHTML&&null!=b.dangerouslySetInnerHTML.__html}function jk(a){setTimeout(function(){throw a;})}function Re(a,b){var c=b,d=0;do{var e=c.nextSibling;a.removeChild(c);if(e&&8===e.nodeType)if(c=
|
||||
e.data,"/$"===c){if(0===d){a.removeChild(e);nc(b);return}d--}else"$"!==c&&"$?"!==c&&"$!"!==c||d++;c=e}while(c);nc(b)}function Ka(a){for(;null!=a;a=a.nextSibling){var b=a.nodeType;if(1===b||3===b)break;if(8===b){b=a.data;if("$"===b||"$!"===b||"$?"===b)break;if("/$"===b)return null}}return a}function sh(a){a=a.previousSibling;for(var b=0;a;){if(8===a.nodeType){var c=a.data;if("$"===c||"$!"===c||"$?"===c){if(0===b)return a;b--}else"/$"===c&&b++}a=a.previousSibling}return null}function pb(a){var b=a[Da];
|
||||
if(b)return b;for(var c=a.parentNode;c;){if(b=c[Ja]||c[Da]){c=b.alternate;if(null!==b.child||null!==c&&null!==c.child)for(a=sh(a);null!==a;){if(c=a[Da])return c;a=sh(a)}return b}a=c;c=a.parentNode}return null}function ec(a){a=a[Da]||a[Ja];return!a||5!==a.tag&&6!==a.tag&&13!==a.tag&&3!==a.tag?null:a}function Ib(a){if(5===a.tag||6===a.tag)return a.stateNode;throw Error(n(33));}function Rc(a){return a[uc]||null}function bb(a){return{current:a}}function w(a,b){0>Mb||(a.current=Se[Mb],Se[Mb]=null,Mb--)}
|
||||
function y(a,b,c){Mb++;Se[Mb]=a.current;a.current=b}function Nb(a,b){var c=a.type.contextTypes;if(!c)return cb;var d=a.stateNode;if(d&&d.__reactInternalMemoizedUnmaskedChildContext===b)return d.__reactInternalMemoizedMaskedChildContext;var e={},f;for(f in c)e[f]=b[f];d&&(a=a.stateNode,a.__reactInternalMemoizedUnmaskedChildContext=b,a.__reactInternalMemoizedMaskedChildContext=e);return e}function ea(a){a=a.childContextTypes;return null!==a&&void 0!==a}function th(a,b,c){if(J.current!==cb)throw Error(n(168));
|
||||
y(J,b);y(S,c)}function uh(a,b,c){var d=a.stateNode;b=b.childContextTypes;if("function"!==typeof d.getChildContext)return c;d=d.getChildContext();for(var e in d)if(!(e in b))throw Error(n(108,hj(a)||"Unknown",e));return E({},c,d)}function ld(a){a=(a=a.stateNode)&&a.__reactInternalMemoizedMergedChildContext||cb;qb=J.current;y(J,a);y(S,S.current);return!0}function vh(a,b,c){var d=a.stateNode;if(!d)throw Error(n(169));c?(a=uh(a,b,qb),d.__reactInternalMemoizedMergedChildContext=a,w(S),w(J),y(J,a)):w(S);
|
||||
y(S,c)}function wh(a){null===La?La=[a]:La.push(a)}function kk(a){md=!0;wh(a)}function db(){if(!Te&&null!==La){Te=!0;var a=0,b=z;try{var c=La;for(z=1;a<c.length;a++){var d=c[a];do d=d(!0);while(null!==d)}La=null;md=!1}catch(e){throw null!==La&&(La=La.slice(a+1)),xh(De,db),e;}finally{z=b,Te=!1}}return null}function rb(a,b){Ob[Pb++]=nd;Ob[Pb++]=od;od=a;nd=b}function yh(a,b,c){na[oa++]=Ma;na[oa++]=Na;na[oa++]=sb;sb=a;var d=Ma;a=Na;var e=32-ta(d)-1;d&=~(1<<e);c+=1;var f=32-ta(b)+e;if(30<f){var g=e-e%5;
|
||||
f=(d&(1<<g)-1).toString(32);d>>=g;e-=g;Ma=1<<32-ta(b)+e|c<<e|d;Na=f+a}else Ma=1<<f|c<<e|d,Na=a}function Ue(a){null!==a.return&&(rb(a,1),yh(a,1,0))}function Ve(a){for(;a===od;)od=Ob[--Pb],Ob[Pb]=null,nd=Ob[--Pb],Ob[Pb]=null;for(;a===sb;)sb=na[--oa],na[oa]=null,Na=na[--oa],na[oa]=null,Ma=na[--oa],na[oa]=null}function zh(a,b){var c=pa(5,null,null,0);c.elementType="DELETED";c.stateNode=b;c.return=a;b=a.deletions;null===b?(a.deletions=[c],a.flags|=16):b.push(c)}function Ah(a,b){switch(a.tag){case 5:var c=
|
||||
a.type;b=1!==b.nodeType||c.toLowerCase()!==b.nodeName.toLowerCase()?null:b;return null!==b?(a.stateNode=b,la=a,fa=Ka(b.firstChild),!0):!1;case 6:return b=""===a.pendingProps||3!==b.nodeType?null:b,null!==b?(a.stateNode=b,la=a,fa=null,!0):!1;case 13:return b=8!==b.nodeType?null:b,null!==b?(c=null!==sb?{id:Ma,overflow:Na}:null,a.memoizedState={dehydrated:b,treeContext:c,retryLane:1073741824},c=pa(18,null,null,0),c.stateNode=b,c.return=a,a.child=c,la=a,fa=null,!0):!1;default:return!1}}function We(a){return 0!==
|
||||
(a.mode&1)&&0===(a.flags&128)}function Xe(a){if(D){var b=fa;if(b){var c=b;if(!Ah(a,b)){if(We(a))throw Error(n(418));b=Ka(c.nextSibling);var d=la;b&&Ah(a,b)?zh(d,c):(a.flags=a.flags&-4097|2,D=!1,la=a)}}else{if(We(a))throw Error(n(418));a.flags=a.flags&-4097|2;D=!1;la=a}}}function Bh(a){for(a=a.return;null!==a&&5!==a.tag&&3!==a.tag&&13!==a.tag;)a=a.return;la=a}function pd(a){if(a!==la)return!1;if(!D)return Bh(a),D=!0,!1;var b;(b=3!==a.tag)&&!(b=5!==a.tag)&&(b=a.type,b="head"!==b&&"body"!==b&&!Qe(a.type,
|
||||
a.memoizedProps));if(b&&(b=fa)){if(We(a)){for(a=fa;a;)a=Ka(a.nextSibling);throw Error(n(418));}for(;b;)zh(a,b),b=Ka(b.nextSibling)}Bh(a);if(13===a.tag){a=a.memoizedState;a=null!==a?a.dehydrated:null;if(!a)throw Error(n(317));a:{a=a.nextSibling;for(b=0;a;){if(8===a.nodeType){var c=a.data;if("/$"===c){if(0===b){fa=Ka(a.nextSibling);break a}b--}else"$"!==c&&"$!"!==c&&"$?"!==c||b++}a=a.nextSibling}fa=null}}else fa=la?Ka(a.stateNode.nextSibling):null;return!0}function Qb(){fa=la=null;D=!1}function Ye(a){null===
|
||||
wa?wa=[a]:wa.push(a)}function xa(a,b){if(a&&a.defaultProps){b=E({},b);a=a.defaultProps;for(var c in a)void 0===b[c]&&(b[c]=a[c]);return b}return b}function Ze(){$e=Rb=qd=null}function af(a,b){b=rd.current;w(rd);a._currentValue=b}function bf(a,b,c){for(;null!==a;){var d=a.alternate;(a.childLanes&b)!==b?(a.childLanes|=b,null!==d&&(d.childLanes|=b)):null!==d&&(d.childLanes&b)!==b&&(d.childLanes|=b);if(a===c)break;a=a.return}}function Sb(a,b){qd=a;$e=Rb=null;a=a.dependencies;null!==a&&null!==a.firstContext&&
|
||||
(0!==(a.lanes&b)&&(ha=!0),a.firstContext=null)}function qa(a){var b=a._currentValue;if($e!==a)if(a={context:a,memoizedValue:b,next:null},null===Rb){if(null===qd)throw Error(n(308));Rb=a;qd.dependencies={lanes:0,firstContext:a}}else Rb=Rb.next=a;return b}function cf(a){null===tb?tb=[a]:tb.push(a)}function Ch(a,b,c,d){var e=b.interleaved;null===e?(c.next=c,cf(b)):(c.next=e.next,e.next=c);b.interleaved=c;return Oa(a,d)}function Oa(a,b){a.lanes|=b;var c=a.alternate;null!==c&&(c.lanes|=b);c=a;for(a=a.return;null!==
|
||||
a;)a.childLanes|=b,c=a.alternate,null!==c&&(c.childLanes|=b),c=a,a=a.return;return 3===c.tag?c.stateNode:null}function df(a){a.updateQueue={baseState:a.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function Dh(a,b){a=a.updateQueue;b.updateQueue===a&&(b.updateQueue={baseState:a.baseState,firstBaseUpdate:a.firstBaseUpdate,lastBaseUpdate:a.lastBaseUpdate,shared:a.shared,effects:a.effects})}function Pa(a,b){return{eventTime:a,lane:b,
|
||||
tag:0,payload:null,callback:null,next:null}}function eb(a,b,c){var d=a.updateQueue;if(null===d)return null;d=d.shared;if(0!==(p&2)){var e=d.pending;null===e?b.next=b:(b.next=e.next,e.next=b);d.pending=b;return lk(a,c)}e=d.interleaved;null===e?(b.next=b,cf(d)):(b.next=e.next,e.next=b);d.interleaved=b;return Oa(a,c)}function sd(a,b,c){b=b.updateQueue;if(null!==b&&(b=b.shared,0!==(c&4194240))){var d=b.lanes;d&=a.pendingLanes;c|=d;b.lanes=c;xe(a,c)}}function Eh(a,b){var c=a.updateQueue,d=a.alternate;
|
||||
if(null!==d&&(d=d.updateQueue,c===d)){var e=null,f=null;c=c.firstBaseUpdate;if(null!==c){do{var g={eventTime:c.eventTime,lane:c.lane,tag:c.tag,payload:c.payload,callback:c.callback,next:null};null===f?e=f=g:f=f.next=g;c=c.next}while(null!==c);null===f?e=f=b:f=f.next=b}else e=f=b;c={baseState:d.baseState,firstBaseUpdate:e,lastBaseUpdate:f,shared:d.shared,effects:d.effects};a.updateQueue=c;return}a=c.lastBaseUpdate;null===a?c.firstBaseUpdate=b:a.next=b;c.lastBaseUpdate=b}function td(a,b,c,d){var e=
|
||||
a.updateQueue;fb=!1;var f=e.firstBaseUpdate,g=e.lastBaseUpdate,h=e.shared.pending;if(null!==h){e.shared.pending=null;var k=h,m=k.next;k.next=null;null===g?f=m:g.next=m;g=k;var n=a.alternate;null!==n&&(n=n.updateQueue,h=n.lastBaseUpdate,h!==g&&(null===h?n.firstBaseUpdate=m:h.next=m,n.lastBaseUpdate=k))}if(null!==f){var l=e.baseState;g=0;n=m=k=null;h=f;do{var r=h.lane,p=h.eventTime;if((d&r)===r){null!==n&&(n=n.next={eventTime:p,lane:0,tag:h.tag,payload:h.payload,callback:h.callback,next:null});a:{var x=
|
||||
a,F=h;r=b;p=c;switch(F.tag){case 1:x=F.payload;if("function"===typeof x){l=x.call(p,l,r);break a}l=x;break a;case 3:x.flags=x.flags&-65537|128;case 0:x=F.payload;r="function"===typeof x?x.call(p,l,r):x;if(null===r||void 0===r)break a;l=E({},l,r);break a;case 2:fb=!0}}null!==h.callback&&0!==h.lane&&(a.flags|=64,r=e.effects,null===r?e.effects=[h]:r.push(h))}else p={eventTime:p,lane:r,tag:h.tag,payload:h.payload,callback:h.callback,next:null},null===n?(m=n=p,k=l):n=n.next=p,g|=r;h=h.next;if(null===h)if(h=
|
||||
e.shared.pending,null===h)break;else r=h,h=r.next,r.next=null,e.lastBaseUpdate=r,e.shared.pending=null}while(1);null===n&&(k=l);e.baseState=k;e.firstBaseUpdate=m;e.lastBaseUpdate=n;b=e.shared.interleaved;if(null!==b){e=b;do g|=e.lane,e=e.next;while(e!==b)}else null===f&&(e.shared.lanes=0);ra|=g;a.lanes=g;a.memoizedState=l}}function Fh(a,b,c){a=b.effects;b.effects=null;if(null!==a)for(b=0;b<a.length;b++){var d=a[b],e=d.callback;if(null!==e){d.callback=null;d=c;if("function"!==typeof e)throw Error(n(191,
|
||||
e));e.call(d)}}}function ef(a,b,c,d){b=a.memoizedState;c=c(d,b);c=null===c||void 0===c?b:E({},b,c);a.memoizedState=c;0===a.lanes&&(a.updateQueue.baseState=c)}function Gh(a,b,c,d,e,f,g){a=a.stateNode;return"function"===typeof a.shouldComponentUpdate?a.shouldComponentUpdate(d,f,g):b.prototype&&b.prototype.isPureReactComponent?!qc(c,d)||!qc(e,f):!0}function Hh(a,b,c){var d=!1,e=cb;var f=b.contextType;"object"===typeof f&&null!==f?f=qa(f):(e=ea(b)?qb:J.current,d=b.contextTypes,f=(d=null!==d&&void 0!==
|
||||
d)?Nb(a,e):cb);b=new b(c,f);a.memoizedState=null!==b.state&&void 0!==b.state?b.state:null;b.updater=ud;a.stateNode=b;b._reactInternals=a;d&&(a=a.stateNode,a.__reactInternalMemoizedUnmaskedChildContext=e,a.__reactInternalMemoizedMaskedChildContext=f);return b}function Ih(a,b,c,d){a=b.state;"function"===typeof b.componentWillReceiveProps&&b.componentWillReceiveProps(c,d);"function"===typeof b.UNSAFE_componentWillReceiveProps&&b.UNSAFE_componentWillReceiveProps(c,d);b.state!==a&&ud.enqueueReplaceState(b,
|
||||
b.state,null)}function ff(a,b,c,d){var e=a.stateNode;e.props=c;e.state=a.memoizedState;e.refs=Jh;df(a);var f=b.contextType;"object"===typeof f&&null!==f?e.context=qa(f):(f=ea(b)?qb:J.current,e.context=Nb(a,f));e.state=a.memoizedState;f=b.getDerivedStateFromProps;"function"===typeof f&&(ef(a,b,f,c),e.state=a.memoizedState);"function"===typeof b.getDerivedStateFromProps||"function"===typeof e.getSnapshotBeforeUpdate||"function"!==typeof e.UNSAFE_componentWillMount&&"function"!==typeof e.componentWillMount||
|
||||
(b=e.state,"function"===typeof e.componentWillMount&&e.componentWillMount(),"function"===typeof e.UNSAFE_componentWillMount&&e.UNSAFE_componentWillMount(),b!==e.state&&ud.enqueueReplaceState(e,e.state,null),td(a,c,e,d),e.state=a.memoizedState);"function"===typeof e.componentDidMount&&(a.flags|=4194308)}function vc(a,b,c){a=c.ref;if(null!==a&&"function"!==typeof a&&"object"!==typeof a){if(c._owner){c=c._owner;if(c){if(1!==c.tag)throw Error(n(309));var d=c.stateNode}if(!d)throw Error(n(147,a));var e=
|
||||
d,f=""+a;if(null!==b&&null!==b.ref&&"function"===typeof b.ref&&b.ref._stringRef===f)return b.ref;b=function(a){var b=e.refs;b===Jh&&(b=e.refs={});null===a?delete b[f]:b[f]=a};b._stringRef=f;return b}if("string"!==typeof a)throw Error(n(284));if(!c._owner)throw Error(n(290,a));}return a}function vd(a,b){a=Object.prototype.toString.call(b);throw Error(n(31,"[object Object]"===a?"object with keys {"+Object.keys(b).join(", ")+"}":a));}function Kh(a){var b=a._init;return b(a._payload)}function Lh(a){function b(b,
|
||||
c){if(a){var d=b.deletions;null===d?(b.deletions=[c],b.flags|=16):d.push(c)}}function c(c,d){if(!a)return null;for(;null!==d;)b(c,d),d=d.sibling;return null}function d(a,b){for(a=new Map;null!==b;)null!==b.key?a.set(b.key,b):a.set(b.index,b),b=b.sibling;return a}function e(a,b){a=gb(a,b);a.index=0;a.sibling=null;return a}function f(b,c,d){b.index=d;if(!a)return b.flags|=1048576,c;d=b.alternate;if(null!==d)return d=d.index,d<c?(b.flags|=2,c):d;b.flags|=2;return c}function g(b){a&&null===b.alternate&&
|
||||
(b.flags|=2);return b}function h(a,b,c,d){if(null===b||6!==b.tag)return b=gf(c,a.mode,d),b.return=a,b;b=e(b,c);b.return=a;return b}function k(a,b,c,d){var f=c.type;if(f===Bb)return l(a,b,c.props.children,d,c.key);if(null!==b&&(b.elementType===f||"object"===typeof f&&null!==f&&f.$$typeof===Ta&&Kh(f)===b.type))return d=e(b,c.props),d.ref=vc(a,b,c),d.return=a,d;d=wd(c.type,c.key,c.props,null,a.mode,d);d.ref=vc(a,b,c);d.return=a;return d}function m(a,b,c,d){if(null===b||4!==b.tag||b.stateNode.containerInfo!==
|
||||
c.containerInfo||b.stateNode.implementation!==c.implementation)return b=hf(c,a.mode,d),b.return=a,b;b=e(b,c.children||[]);b.return=a;return b}function l(a,b,c,d,f){if(null===b||7!==b.tag)return b=ub(c,a.mode,d,f),b.return=a,b;b=e(b,c);b.return=a;return b}function u(a,b,c){if("string"===typeof b&&""!==b||"number"===typeof b)return b=gf(""+b,a.mode,c),b.return=a,b;if("object"===typeof b&&null!==b){switch(b.$$typeof){case xd:return c=wd(b.type,b.key,b.props,null,a.mode,c),c.ref=vc(a,null,b),c.return=
|
||||
a,c;case Cb:return b=hf(b,a.mode,c),b.return=a,b;case Ta:var d=b._init;return u(a,d(b._payload),c)}if(cc(b)||ac(b))return b=ub(b,a.mode,c,null),b.return=a,b;vd(a,b)}return null}function r(a,b,c,d){var e=null!==b?b.key:null;if("string"===typeof c&&""!==c||"number"===typeof c)return null!==e?null:h(a,b,""+c,d);if("object"===typeof c&&null!==c){switch(c.$$typeof){case xd:return c.key===e?k(a,b,c,d):null;case Cb:return c.key===e?m(a,b,c,d):null;case Ta:return e=c._init,r(a,b,e(c._payload),d)}if(cc(c)||
|
||||
ac(c))return null!==e?null:l(a,b,c,d,null);vd(a,c)}return null}function p(a,b,c,d,e){if("string"===typeof d&&""!==d||"number"===typeof d)return a=a.get(c)||null,h(b,a,""+d,e);if("object"===typeof d&&null!==d){switch(d.$$typeof){case xd:return a=a.get(null===d.key?c:d.key)||null,k(b,a,d,e);case Cb:return a=a.get(null===d.key?c:d.key)||null,m(b,a,d,e);case Ta:var f=d._init;return p(a,b,c,f(d._payload),e)}if(cc(d)||ac(d))return a=a.get(c)||null,l(b,a,d,e,null);vd(b,d)}return null}function x(e,g,h,k){for(var n=
|
||||
null,m=null,l=g,q=g=0,v=null;null!==l&&q<h.length;q++){l.index>q?(v=l,l=null):v=l.sibling;var A=r(e,l,h[q],k);if(null===A){null===l&&(l=v);break}a&&l&&null===A.alternate&&b(e,l);g=f(A,g,q);null===m?n=A:m.sibling=A;m=A;l=v}if(q===h.length)return c(e,l),D&&rb(e,q),n;if(null===l){for(;q<h.length;q++)l=u(e,h[q],k),null!==l&&(g=f(l,g,q),null===m?n=l:m.sibling=l,m=l);D&&rb(e,q);return n}for(l=d(e,l);q<h.length;q++)v=p(l,e,q,h[q],k),null!==v&&(a&&null!==v.alternate&&l.delete(null===v.key?q:v.key),g=f(v,
|
||||
g,q),null===m?n=v:m.sibling=v,m=v);a&&l.forEach(function(a){return b(e,a)});D&&rb(e,q);return n}function F(e,g,h,k){var m=ac(h);if("function"!==typeof m)throw Error(n(150));h=m.call(h);if(null==h)throw Error(n(151));for(var l=m=null,q=g,v=g=0,A=null,t=h.next();null!==q&&!t.done;v++,t=h.next()){q.index>v?(A=q,q=null):A=q.sibling;var x=r(e,q,t.value,k);if(null===x){null===q&&(q=A);break}a&&q&&null===x.alternate&&b(e,q);g=f(x,g,v);null===l?m=x:l.sibling=x;l=x;q=A}if(t.done)return c(e,q),D&&rb(e,v),m;
|
||||
if(null===q){for(;!t.done;v++,t=h.next())t=u(e,t.value,k),null!==t&&(g=f(t,g,v),null===l?m=t:l.sibling=t,l=t);D&&rb(e,v);return m}for(q=d(e,q);!t.done;v++,t=h.next())t=p(q,e,v,t.value,k),null!==t&&(a&&null!==t.alternate&&q.delete(null===t.key?v:t.key),g=f(t,g,v),null===l?m=t:l.sibling=t,l=t);a&&q.forEach(function(a){return b(e,a)});D&&rb(e,v);return m}function w(a,d,f,h){"object"===typeof f&&null!==f&&f.type===Bb&&null===f.key&&(f=f.props.children);if("object"===typeof f&&null!==f){switch(f.$$typeof){case xd:a:{for(var k=
|
||||
f.key,m=d;null!==m;){if(m.key===k){k=f.type;if(k===Bb){if(7===m.tag){c(a,m.sibling);d=e(m,f.props.children);d.return=a;a=d;break a}}else if(m.elementType===k||"object"===typeof k&&null!==k&&k.$$typeof===Ta&&Kh(k)===m.type){c(a,m.sibling);d=e(m,f.props);d.ref=vc(a,m,f);d.return=a;a=d;break a}c(a,m);break}else b(a,m);m=m.sibling}f.type===Bb?(d=ub(f.props.children,a.mode,h,f.key),d.return=a,a=d):(h=wd(f.type,f.key,f.props,null,a.mode,h),h.ref=vc(a,d,f),h.return=a,a=h)}return g(a);case Cb:a:{for(m=f.key;null!==
|
||||
d;){if(d.key===m)if(4===d.tag&&d.stateNode.containerInfo===f.containerInfo&&d.stateNode.implementation===f.implementation){c(a,d.sibling);d=e(d,f.children||[]);d.return=a;a=d;break a}else{c(a,d);break}else b(a,d);d=d.sibling}d=hf(f,a.mode,h);d.return=a;a=d}return g(a);case Ta:return m=f._init,w(a,d,m(f._payload),h)}if(cc(f))return x(a,d,f,h);if(ac(f))return F(a,d,f,h);vd(a,f)}return"string"===typeof f&&""!==f||"number"===typeof f?(f=""+f,null!==d&&6===d.tag?(c(a,d.sibling),d=e(d,f),d.return=a,a=d):
|
||||
(c(a,d),d=gf(f,a.mode,h),d.return=a,a=d),g(a)):c(a,d)}return w}function vb(a){if(a===wc)throw Error(n(174));return a}function jf(a,b){y(xc,b);y(yc,a);y(Ea,wc);a=b.nodeType;switch(a){case 9:case 11:b=(b=b.documentElement)?b.namespaceURI:oe(null,"");break;default:a=8===a?b.parentNode:b,b=a.namespaceURI||null,a=a.tagName,b=oe(b,a)}w(Ea);y(Ea,b)}function Tb(a){w(Ea);w(yc);w(xc)}function Mh(a){vb(xc.current);var b=vb(Ea.current);var c=oe(b,a.type);b!==c&&(y(yc,a),y(Ea,c))}function kf(a){yc.current===a&&
|
||||
(w(Ea),w(yc))}function yd(a){for(var b=a;null!==b;){if(13===b.tag){var c=b.memoizedState;if(null!==c&&(c=c.dehydrated,null===c||"$?"===c.data||"$!"===c.data))return b}else if(19===b.tag&&void 0!==b.memoizedProps.revealOrder){if(0!==(b.flags&128))return b}else if(null!==b.child){b.child.return=b;b=b.child;continue}if(b===a)break;for(;null===b.sibling;){if(null===b.return||b.return===a)return null;b=b.return}b.sibling.return=b.return;b=b.sibling}return null}function lf(){for(var a=0;a<mf.length;a++)mf[a]._workInProgressVersionPrimary=
|
||||
null;mf.length=0}function V(){throw Error(n(321));}function nf(a,b){if(null===b)return!1;for(var c=0;c<b.length&&c<a.length;c++)if(!ua(a[c],b[c]))return!1;return!0}function of(a,b,c,d,e,f){wb=f;C=b;b.memoizedState=null;b.updateQueue=null;b.lanes=0;zd.current=null===a||null===a.memoizedState?mk:nk;a=c(d,e);if(zc){f=0;do{zc=!1;Ac=0;if(25<=f)throw Error(n(301));f+=1;N=K=null;b.updateQueue=null;zd.current=ok;a=c(d,e)}while(zc)}zd.current=Ad;b=null!==K&&null!==K.next;wb=0;N=K=C=null;Bd=!1;if(b)throw Error(n(300));
|
||||
return a}function pf(){var a=0!==Ac;Ac=0;return a}function Fa(){var a={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};null===N?C.memoizedState=N=a:N=N.next=a;return N}function sa(){if(null===K){var a=C.alternate;a=null!==a?a.memoizedState:null}else a=K.next;var b=null===N?C.memoizedState:N.next;if(null!==b)N=b,K=a;else{if(null===a)throw Error(n(310));K=a;a={memoizedState:K.memoizedState,baseState:K.baseState,baseQueue:K.baseQueue,queue:K.queue,next:null};null===N?C.memoizedState=
|
||||
N=a:N=N.next=a}return N}function Bc(a,b){return"function"===typeof b?b(a):b}function qf(a,b,c){b=sa();c=b.queue;if(null===c)throw Error(n(311));c.lastRenderedReducer=a;var d=K,e=d.baseQueue,f=c.pending;if(null!==f){if(null!==e){var g=e.next;e.next=f.next;f.next=g}d.baseQueue=e=f;c.pending=null}if(null!==e){f=e.next;d=d.baseState;var h=g=null,k=null,m=f;do{var l=m.lane;if((wb&l)===l)null!==k&&(k=k.next={lane:0,action:m.action,hasEagerState:m.hasEagerState,eagerState:m.eagerState,next:null}),d=m.hasEagerState?
|
||||
m.eagerState:a(d,m.action);else{var u={lane:l,action:m.action,hasEagerState:m.hasEagerState,eagerState:m.eagerState,next:null};null===k?(h=k=u,g=d):k=k.next=u;C.lanes|=l;ra|=l}m=m.next}while(null!==m&&m!==f);null===k?g=d:k.next=h;ua(d,b.memoizedState)||(ha=!0);b.memoizedState=d;b.baseState=g;b.baseQueue=k;c.lastRenderedState=d}a=c.interleaved;if(null!==a){e=a;do f=e.lane,C.lanes|=f,ra|=f,e=e.next;while(e!==a)}else null===e&&(c.lanes=0);return[b.memoizedState,c.dispatch]}function rf(a,b,c){b=sa();
|
||||
c=b.queue;if(null===c)throw Error(n(311));c.lastRenderedReducer=a;var d=c.dispatch,e=c.pending,f=b.memoizedState;if(null!==e){c.pending=null;var g=e=e.next;do f=a(f,g.action),g=g.next;while(g!==e);ua(f,b.memoizedState)||(ha=!0);b.memoizedState=f;null===b.baseQueue&&(b.baseState=f);c.lastRenderedState=f}return[f,d]}function Nh(a,b,c){}function Oh(a,b,c){c=C;var d=sa(),e=b(),f=!ua(d.memoizedState,e);f&&(d.memoizedState=e,ha=!0);d=d.queue;sf(Ph.bind(null,c,d,a),[a]);if(d.getSnapshot!==b||f||null!==N&&
|
||||
N.memoizedState.tag&1){c.flags|=2048;Cc(9,Qh.bind(null,c,d,e,b),void 0,null);if(null===O)throw Error(n(349));0!==(wb&30)||Rh(c,b,e)}return e}function Rh(a,b,c){a.flags|=16384;a={getSnapshot:b,value:c};b=C.updateQueue;null===b?(b={lastEffect:null,stores:null},C.updateQueue=b,b.stores=[a]):(c=b.stores,null===c?b.stores=[a]:c.push(a))}function Qh(a,b,c,d){b.value=c;b.getSnapshot=d;Sh(b)&&Th(a)}function Ph(a,b,c){return c(function(){Sh(b)&&Th(a)})}function Sh(a){var b=a.getSnapshot;a=a.value;try{var c=
|
||||
b();return!ua(a,c)}catch(d){return!0}}function Th(a){var b=Oa(a,1);null!==b&&ya(b,a,1,-1)}function Uh(a){var b=Fa();"function"===typeof a&&(a=a());b.memoizedState=b.baseState=a;a={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:Bc,lastRenderedState:a};b.queue=a;a=a.dispatch=pk.bind(null,C,a);return[b.memoizedState,a]}function Cc(a,b,c,d){a={tag:a,create:b,destroy:c,deps:d,next:null};b=C.updateQueue;null===b?(b={lastEffect:null,stores:null},C.updateQueue=b,b.lastEffect=a.next=
|
||||
a):(c=b.lastEffect,null===c?b.lastEffect=a.next=a:(d=c.next,c.next=a,a.next=d,b.lastEffect=a));return a}function Vh(a){return sa().memoizedState}function Cd(a,b,c,d){var e=Fa();C.flags|=a;e.memoizedState=Cc(1|b,c,void 0,void 0===d?null:d)}function Dd(a,b,c,d){var e=sa();d=void 0===d?null:d;var f=void 0;if(null!==K){var g=K.memoizedState;f=g.destroy;if(null!==d&&nf(d,g.deps)){e.memoizedState=Cc(b,c,f,d);return}}C.flags|=a;e.memoizedState=Cc(1|b,c,f,d)}function Wh(a,b){return Cd(8390656,8,a,b)}function sf(a,
|
||||
b){return Dd(2048,8,a,b)}function Xh(a,b){return Dd(4,2,a,b)}function Yh(a,b){return Dd(4,4,a,b)}function Zh(a,b){if("function"===typeof b)return a=a(),b(a),function(){b(null)};if(null!==b&&void 0!==b)return a=a(),b.current=a,function(){b.current=null}}function $h(a,b,c){c=null!==c&&void 0!==c?c.concat([a]):null;return Dd(4,4,Zh.bind(null,b,a),c)}function tf(a,b){}function ai(a,b){var c=sa();b=void 0===b?null:b;var d=c.memoizedState;if(null!==d&&null!==b&&nf(b,d[1]))return d[0];c.memoizedState=[a,
|
||||
b];return a}function bi(a,b){var c=sa();b=void 0===b?null:b;var d=c.memoizedState;if(null!==d&&null!==b&&nf(b,d[1]))return d[0];a=a();c.memoizedState=[a,b];return a}function ci(a,b,c){if(0===(wb&21))return a.baseState&&(a.baseState=!1,ha=!0),a.memoizedState=c;ua(c,b)||(c=Dg(),C.lanes|=c,ra|=c,a.baseState=!0);return b}function qk(a,b,c){c=z;z=0!==c&&4>c?c:4;a(!0);var d=uf.transition;uf.transition={};try{a(!1),b()}finally{z=c,uf.transition=d}}function di(){return sa().memoizedState}function rk(a,b,
|
||||
c){var d=hb(a);c={lane:d,action:c,hasEagerState:!1,eagerState:null,next:null};if(ei(a))fi(b,c);else if(c=Ch(a,b,c,d),null!==c){var e=Z();ya(c,a,d,e);gi(c,b,d)}}function pk(a,b,c){var d=hb(a),e={lane:d,action:c,hasEagerState:!1,eagerState:null,next:null};if(ei(a))fi(b,e);else{var f=a.alternate;if(0===a.lanes&&(null===f||0===f.lanes)&&(f=b.lastRenderedReducer,null!==f))try{var g=b.lastRenderedState,h=f(g,c);e.hasEagerState=!0;e.eagerState=h;if(ua(h,g)){var k=b.interleaved;null===k?(e.next=e,cf(b)):
|
||||
(e.next=k.next,k.next=e);b.interleaved=e;return}}catch(m){}finally{}c=Ch(a,b,e,d);null!==c&&(e=Z(),ya(c,a,d,e),gi(c,b,d))}}function ei(a){var b=a.alternate;return a===C||null!==b&&b===C}function fi(a,b){zc=Bd=!0;var c=a.pending;null===c?b.next=b:(b.next=c.next,c.next=b);a.pending=b}function gi(a,b,c){if(0!==(c&4194240)){var d=b.lanes;d&=a.pendingLanes;c|=d;b.lanes=c;xe(a,c)}}function Ub(a,b){try{var c="",d=b;do c+=gj(d),d=d.return;while(d);var e=c}catch(f){e="\nError generating stack: "+f.message+
|
||||
"\n"+f.stack}return{value:a,source:b,stack:e,digest:null}}function vf(a,b,c){return{value:a,source:null,stack:null!=c?c:null,digest:null!=b?b:null}}function wf(a,b){try{console.error(b.value)}catch(c){setTimeout(function(){throw c;})}}function hi(a,b,c){c=Pa(-1,c);c.tag=3;c.payload={element:null};var d=b.value;c.callback=function(){Ed||(Ed=!0,xf=d);wf(a,b)};return c}function ii(a,b,c){c=Pa(-1,c);c.tag=3;var d=a.type.getDerivedStateFromError;if("function"===typeof d){var e=b.value;c.payload=function(){return d(e)};
|
||||
c.callback=function(){wf(a,b)}}var f=a.stateNode;null!==f&&"function"===typeof f.componentDidCatch&&(c.callback=function(){wf(a,b);"function"!==typeof d&&(null===ib?ib=new Set([this]):ib.add(this));var c=b.stack;this.componentDidCatch(b.value,{componentStack:null!==c?c:""})});return c}function ji(a,b,c){var d=a.pingCache;if(null===d){d=a.pingCache=new sk;var e=new Set;d.set(b,e)}else e=d.get(b),void 0===e&&(e=new Set,d.set(b,e));e.has(c)||(e.add(c),a=tk.bind(null,a,b,c),b.then(a,a))}function ki(a){do{var b;
|
||||
if(b=13===a.tag)b=a.memoizedState,b=null!==b?null!==b.dehydrated?!0:!1:!0;if(b)return a;a=a.return}while(null!==a);return null}function li(a,b,c,d,e){if(0===(a.mode&1))return a===b?a.flags|=65536:(a.flags|=128,c.flags|=131072,c.flags&=-52805,1===c.tag&&(null===c.alternate?c.tag=17:(b=Pa(-1,1),b.tag=2,eb(c,b,1))),c.lanes|=1),a;a.flags|=65536;a.lanes=e;return a}function aa(a,b,c,d){b.child=null===a?mi(b,null,c,d):Vb(b,a.child,c,d)}function ni(a,b,c,d,e){c=c.render;var f=b.ref;Sb(b,e);d=of(a,b,c,d,f,
|
||||
e);c=pf();if(null!==a&&!ha)return b.updateQueue=a.updateQueue,b.flags&=-2053,a.lanes&=~e,Qa(a,b,e);D&&c&&Ue(b);b.flags|=1;aa(a,b,d,e);return b.child}function oi(a,b,c,d,e){if(null===a){var f=c.type;if("function"===typeof f&&!yf(f)&&void 0===f.defaultProps&&null===c.compare&&void 0===c.defaultProps)return b.tag=15,b.type=f,pi(a,b,f,d,e);a=wd(c.type,null,d,b,b.mode,e);a.ref=b.ref;a.return=b;return b.child=a}f=a.child;if(0===(a.lanes&e)){var g=f.memoizedProps;c=c.compare;c=null!==c?c:qc;if(c(g,d)&&a.ref===
|
||||
b.ref)return Qa(a,b,e)}b.flags|=1;a=gb(f,d);a.ref=b.ref;a.return=b;return b.child=a}function pi(a,b,c,d,e){if(null!==a){var f=a.memoizedProps;if(qc(f,d)&&a.ref===b.ref)if(ha=!1,b.pendingProps=d=f,0!==(a.lanes&e))0!==(a.flags&131072)&&(ha=!0);else return b.lanes=a.lanes,Qa(a,b,e)}return zf(a,b,c,d,e)}function qi(a,b,c){var d=b.pendingProps,e=d.children,f=null!==a?a.memoizedState:null;if("hidden"===d.mode)if(0===(b.mode&1))b.memoizedState={baseLanes:0,cachePool:null,transitions:null},y(Ga,ba),ba|=c;
|
||||
else{if(0===(c&1073741824))return a=null!==f?f.baseLanes|c:c,b.lanes=b.childLanes=1073741824,b.memoizedState={baseLanes:a,cachePool:null,transitions:null},b.updateQueue=null,y(Ga,ba),ba|=a,null;b.memoizedState={baseLanes:0,cachePool:null,transitions:null};d=null!==f?f.baseLanes:c;y(Ga,ba);ba|=d}else null!==f?(d=f.baseLanes|c,b.memoizedState=null):d=c,y(Ga,ba),ba|=d;aa(a,b,e,c);return b.child}function ri(a,b){var c=b.ref;if(null===a&&null!==c||null!==a&&a.ref!==c)b.flags|=512,b.flags|=2097152}function zf(a,
|
||||
b,c,d,e){var f=ea(c)?qb:J.current;f=Nb(b,f);Sb(b,e);c=of(a,b,c,d,f,e);d=pf();if(null!==a&&!ha)return b.updateQueue=a.updateQueue,b.flags&=-2053,a.lanes&=~e,Qa(a,b,e);D&&d&&Ue(b);b.flags|=1;aa(a,b,c,e);return b.child}function si(a,b,c,d,e){if(ea(c)){var f=!0;ld(b)}else f=!1;Sb(b,e);if(null===b.stateNode)Fd(a,b),Hh(b,c,d),ff(b,c,d,e),d=!0;else if(null===a){var g=b.stateNode,h=b.memoizedProps;g.props=h;var k=g.context,m=c.contextType;"object"===typeof m&&null!==m?m=qa(m):(m=ea(c)?qb:J.current,m=Nb(b,
|
||||
m));var l=c.getDerivedStateFromProps,n="function"===typeof l||"function"===typeof g.getSnapshotBeforeUpdate;n||"function"!==typeof g.UNSAFE_componentWillReceiveProps&&"function"!==typeof g.componentWillReceiveProps||(h!==d||k!==m)&&Ih(b,g,d,m);fb=!1;var r=b.memoizedState;g.state=r;td(b,d,g,e);k=b.memoizedState;h!==d||r!==k||S.current||fb?("function"===typeof l&&(ef(b,c,l,d),k=b.memoizedState),(h=fb||Gh(b,c,h,d,r,k,m))?(n||"function"!==typeof g.UNSAFE_componentWillMount&&"function"!==typeof g.componentWillMount||
|
||||
("function"===typeof g.componentWillMount&&g.componentWillMount(),"function"===typeof g.UNSAFE_componentWillMount&&g.UNSAFE_componentWillMount()),"function"===typeof g.componentDidMount&&(b.flags|=4194308)):("function"===typeof g.componentDidMount&&(b.flags|=4194308),b.memoizedProps=d,b.memoizedState=k),g.props=d,g.state=k,g.context=m,d=h):("function"===typeof g.componentDidMount&&(b.flags|=4194308),d=!1)}else{g=b.stateNode;Dh(a,b);h=b.memoizedProps;m=b.type===b.elementType?h:xa(b.type,h);g.props=
|
||||
m;n=b.pendingProps;r=g.context;k=c.contextType;"object"===typeof k&&null!==k?k=qa(k):(k=ea(c)?qb:J.current,k=Nb(b,k));var p=c.getDerivedStateFromProps;(l="function"===typeof p||"function"===typeof g.getSnapshotBeforeUpdate)||"function"!==typeof g.UNSAFE_componentWillReceiveProps&&"function"!==typeof g.componentWillReceiveProps||(h!==n||r!==k)&&Ih(b,g,d,k);fb=!1;r=b.memoizedState;g.state=r;td(b,d,g,e);var x=b.memoizedState;h!==n||r!==x||S.current||fb?("function"===typeof p&&(ef(b,c,p,d),x=b.memoizedState),
|
||||
(m=fb||Gh(b,c,m,d,r,x,k)||!1)?(l||"function"!==typeof g.UNSAFE_componentWillUpdate&&"function"!==typeof g.componentWillUpdate||("function"===typeof g.componentWillUpdate&&g.componentWillUpdate(d,x,k),"function"===typeof g.UNSAFE_componentWillUpdate&&g.UNSAFE_componentWillUpdate(d,x,k)),"function"===typeof g.componentDidUpdate&&(b.flags|=4),"function"===typeof g.getSnapshotBeforeUpdate&&(b.flags|=1024)):("function"!==typeof g.componentDidUpdate||h===a.memoizedProps&&r===a.memoizedState||(b.flags|=
|
||||
4),"function"!==typeof g.getSnapshotBeforeUpdate||h===a.memoizedProps&&r===a.memoizedState||(b.flags|=1024),b.memoizedProps=d,b.memoizedState=x),g.props=d,g.state=x,g.context=k,d=m):("function"!==typeof g.componentDidUpdate||h===a.memoizedProps&&r===a.memoizedState||(b.flags|=4),"function"!==typeof g.getSnapshotBeforeUpdate||h===a.memoizedProps&&r===a.memoizedState||(b.flags|=1024),d=!1)}return Af(a,b,c,d,f,e)}function Af(a,b,c,d,e,f){ri(a,b);var g=0!==(b.flags&128);if(!d&&!g)return e&&vh(b,c,!1),
|
||||
Qa(a,b,f);d=b.stateNode;uk.current=b;var h=g&&"function"!==typeof c.getDerivedStateFromError?null:d.render();b.flags|=1;null!==a&&g?(b.child=Vb(b,a.child,null,f),b.child=Vb(b,null,h,f)):aa(a,b,h,f);b.memoizedState=d.state;e&&vh(b,c,!0);return b.child}function ti(a){var b=a.stateNode;b.pendingContext?th(a,b.pendingContext,b.pendingContext!==b.context):b.context&&th(a,b.context,!1);jf(a,b.containerInfo)}function ui(a,b,c,d,e){Qb();Ye(e);b.flags|=256;aa(a,b,c,d);return b.child}function Bf(a){return{baseLanes:a,
|
||||
cachePool:null,transitions:null}}function vi(a,b,c){var d=b.pendingProps,e=G.current,f=!1,g=0!==(b.flags&128),h;(h=g)||(h=null!==a&&null===a.memoizedState?!1:0!==(e&2));if(h)f=!0,b.flags&=-129;else if(null===a||null!==a.memoizedState)e|=1;y(G,e&1);if(null===a){Xe(b);a=b.memoizedState;if(null!==a&&(a=a.dehydrated,null!==a))return 0===(b.mode&1)?b.lanes=1:"$!"===a.data?b.lanes=8:b.lanes=1073741824,null;g=d.children;a=d.fallback;return f?(d=b.mode,f=b.child,g={mode:"hidden",children:g},0===(d&1)&&null!==
|
||||
f?(f.childLanes=0,f.pendingProps=g):f=Gd(g,d,0,null),a=ub(a,d,c,null),f.return=b,a.return=b,f.sibling=a,b.child=f,b.child.memoizedState=Bf(c),b.memoizedState=Cf,a):Df(b,g)}e=a.memoizedState;if(null!==e&&(h=e.dehydrated,null!==h))return vk(a,b,g,d,h,e,c);if(f){f=d.fallback;g=b.mode;e=a.child;h=e.sibling;var k={mode:"hidden",children:d.children};0===(g&1)&&b.child!==e?(d=b.child,d.childLanes=0,d.pendingProps=k,b.deletions=null):(d=gb(e,k),d.subtreeFlags=e.subtreeFlags&14680064);null!==h?f=gb(h,f):(f=
|
||||
ub(f,g,c,null),f.flags|=2);f.return=b;d.return=b;d.sibling=f;b.child=d;d=f;f=b.child;g=a.child.memoizedState;g=null===g?Bf(c):{baseLanes:g.baseLanes|c,cachePool:null,transitions:g.transitions};f.memoizedState=g;f.childLanes=a.childLanes&~c;b.memoizedState=Cf;return d}f=a.child;a=f.sibling;d=gb(f,{mode:"visible",children:d.children});0===(b.mode&1)&&(d.lanes=c);d.return=b;d.sibling=null;null!==a&&(c=b.deletions,null===c?(b.deletions=[a],b.flags|=16):c.push(a));b.child=d;b.memoizedState=null;return d}
|
||||
function Df(a,b,c){b=Gd({mode:"visible",children:b},a.mode,0,null);b.return=a;return a.child=b}function Hd(a,b,c,d){null!==d&&Ye(d);Vb(b,a.child,null,c);a=Df(b,b.pendingProps.children);a.flags|=2;b.memoizedState=null;return a}function vk(a,b,c,d,e,f,g){if(c){if(b.flags&256)return b.flags&=-257,d=vf(Error(n(422))),Hd(a,b,g,d);if(null!==b.memoizedState)return b.child=a.child,b.flags|=128,null;f=d.fallback;e=b.mode;d=Gd({mode:"visible",children:d.children},e,0,null);f=ub(f,e,g,null);f.flags|=2;d.return=
|
||||
b;f.return=b;d.sibling=f;b.child=d;0!==(b.mode&1)&&Vb(b,a.child,null,g);b.child.memoizedState=Bf(g);b.memoizedState=Cf;return f}if(0===(b.mode&1))return Hd(a,b,g,null);if("$!"===e.data){d=e.nextSibling&&e.nextSibling.dataset;if(d)var h=d.dgst;d=h;f=Error(n(419));d=vf(f,d,void 0);return Hd(a,b,g,d)}h=0!==(g&a.childLanes);if(ha||h){d=O;if(null!==d){switch(g&-g){case 4:e=2;break;case 16:e=8;break;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:e=
|
||||
32;break;case 536870912:e=268435456;break;default:e=0}e=0!==(e&(d.suspendedLanes|g))?0:e;0!==e&&e!==f.retryLane&&(f.retryLane=e,Oa(a,e),ya(d,a,e,-1))}Ef();d=vf(Error(n(421)));return Hd(a,b,g,d)}if("$?"===e.data)return b.flags|=128,b.child=a.child,b=wk.bind(null,a),e._reactRetry=b,null;a=f.treeContext;fa=Ka(e.nextSibling);la=b;D=!0;wa=null;null!==a&&(na[oa++]=Ma,na[oa++]=Na,na[oa++]=sb,Ma=a.id,Na=a.overflow,sb=b);b=Df(b,d.children);b.flags|=4096;return b}function wi(a,b,c){a.lanes|=b;var d=a.alternate;
|
||||
null!==d&&(d.lanes|=b);bf(a.return,b,c)}function Ff(a,b,c,d,e){var f=a.memoizedState;null===f?a.memoizedState={isBackwards:b,rendering:null,renderingStartTime:0,last:d,tail:c,tailMode:e}:(f.isBackwards=b,f.rendering=null,f.renderingStartTime=0,f.last=d,f.tail=c,f.tailMode=e)}function xi(a,b,c){var d=b.pendingProps,e=d.revealOrder,f=d.tail;aa(a,b,d.children,c);d=G.current;if(0!==(d&2))d=d&1|2,b.flags|=128;else{if(null!==a&&0!==(a.flags&128))a:for(a=b.child;null!==a;){if(13===a.tag)null!==a.memoizedState&&
|
||||
wi(a,c,b);else if(19===a.tag)wi(a,c,b);else if(null!==a.child){a.child.return=a;a=a.child;continue}if(a===b)break a;for(;null===a.sibling;){if(null===a.return||a.return===b)break a;a=a.return}a.sibling.return=a.return;a=a.sibling}d&=1}y(G,d);if(0===(b.mode&1))b.memoizedState=null;else switch(e){case "forwards":c=b.child;for(e=null;null!==c;)a=c.alternate,null!==a&&null===yd(a)&&(e=c),c=c.sibling;c=e;null===c?(e=b.child,b.child=null):(e=c.sibling,c.sibling=null);Ff(b,!1,e,c,f);break;case "backwards":c=
|
||||
null;e=b.child;for(b.child=null;null!==e;){a=e.alternate;if(null!==a&&null===yd(a)){b.child=e;break}a=e.sibling;e.sibling=c;c=e;e=a}Ff(b,!0,c,null,f);break;case "together":Ff(b,!1,null,null,void 0);break;default:b.memoizedState=null}return b.child}function Fd(a,b){0===(b.mode&1)&&null!==a&&(a.alternate=null,b.alternate=null,b.flags|=2)}function Qa(a,b,c){null!==a&&(b.dependencies=a.dependencies);ra|=b.lanes;if(0===(c&b.childLanes))return null;if(null!==a&&b.child!==a.child)throw Error(n(153));if(null!==
|
||||
b.child){a=b.child;c=gb(a,a.pendingProps);b.child=c;for(c.return=b;null!==a.sibling;)a=a.sibling,c=c.sibling=gb(a,a.pendingProps),c.return=b;c.sibling=null}return b.child}function xk(a,b,c){switch(b.tag){case 3:ti(b);Qb();break;case 5:Mh(b);break;case 1:ea(b.type)&&ld(b);break;case 4:jf(b,b.stateNode.containerInfo);break;case 10:var d=b.type._context,e=b.memoizedProps.value;y(rd,d._currentValue);d._currentValue=e;break;case 13:d=b.memoizedState;if(null!==d){if(null!==d.dehydrated)return y(G,G.current&
|
||||
1),b.flags|=128,null;if(0!==(c&b.child.childLanes))return vi(a,b,c);y(G,G.current&1);a=Qa(a,b,c);return null!==a?a.sibling:null}y(G,G.current&1);break;case 19:d=0!==(c&b.childLanes);if(0!==(a.flags&128)){if(d)return xi(a,b,c);b.flags|=128}e=b.memoizedState;null!==e&&(e.rendering=null,e.tail=null,e.lastEffect=null);y(G,G.current);if(d)break;else return null;case 22:case 23:return b.lanes=0,qi(a,b,c)}return Qa(a,b,c)}function Dc(a,b){if(!D)switch(a.tailMode){case "hidden":b=a.tail;for(var c=null;null!==
|
||||
b;)null!==b.alternate&&(c=b),b=b.sibling;null===c?a.tail=null:c.sibling=null;break;case "collapsed":c=a.tail;for(var d=null;null!==c;)null!==c.alternate&&(d=c),c=c.sibling;null===d?b||null===a.tail?a.tail=null:a.tail.sibling=null:d.sibling=null}}function W(a){var b=null!==a.alternate&&a.alternate.child===a.child,c=0,d=0;if(b)for(var e=a.child;null!==e;)c|=e.lanes|e.childLanes,d|=e.subtreeFlags&14680064,d|=e.flags&14680064,e.return=a,e=e.sibling;else for(e=a.child;null!==e;)c|=e.lanes|e.childLanes,
|
||||
d|=e.subtreeFlags,d|=e.flags,e.return=a,e=e.sibling;a.subtreeFlags|=d;a.childLanes=c;return b}function yk(a,b,c){var d=b.pendingProps;Ve(b);switch(b.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return W(b),null;case 1:return ea(b.type)&&(w(S),w(J)),W(b),null;case 3:d=b.stateNode;Tb();w(S);w(J);lf();d.pendingContext&&(d.context=d.pendingContext,d.pendingContext=null);if(null===a||null===a.child)pd(b)?b.flags|=4:null===a||a.memoizedState.isDehydrated&&0===(b.flags&
|
||||
256)||(b.flags|=1024,null!==wa&&(Gf(wa),wa=null));yi(a,b);W(b);return null;case 5:kf(b);var e=vb(xc.current);c=b.type;if(null!==a&&null!=b.stateNode)zk(a,b,c,d,e),a.ref!==b.ref&&(b.flags|=512,b.flags|=2097152);else{if(!d){if(null===b.stateNode)throw Error(n(166));W(b);return null}a=vb(Ea.current);if(pd(b)){d=b.stateNode;c=b.type;var f=b.memoizedProps;d[Da]=b;d[uc]=f;a=0!==(b.mode&1);switch(c){case "dialog":B("cancel",d);B("close",d);break;case "iframe":case "object":case "embed":B("load",d);break;
|
||||
case "video":case "audio":for(e=0;e<Ec.length;e++)B(Ec[e],d);break;case "source":B("error",d);break;case "img":case "image":case "link":B("error",d);B("load",d);break;case "details":B("toggle",d);break;case "input":kg(d,f);B("invalid",d);break;case "select":d._wrapperState={wasMultiple:!!f.multiple};B("invalid",d);break;case "textarea":ng(d,f),B("invalid",d)}pe(c,f);e=null;for(var g in f)if(f.hasOwnProperty(g)){var h=f[g];"children"===g?"string"===typeof h?d.textContent!==h&&(!0!==f.suppressHydrationWarning&&
|
||||
jd(d.textContent,h,a),e=["children",h]):"number"===typeof h&&d.textContent!==""+h&&(!0!==f.suppressHydrationWarning&&jd(d.textContent,h,a),e=["children",""+h]):$b.hasOwnProperty(g)&&null!=h&&"onScroll"===g&&B("scroll",d)}switch(c){case "input":Pc(d);mg(d,f,!0);break;case "textarea":Pc(d);pg(d);break;case "select":case "option":break;default:"function"===typeof f.onClick&&(d.onclick=kd)}d=e;b.updateQueue=d;null!==d&&(b.flags|=4)}else{g=9===e.nodeType?e:e.ownerDocument;"http://www.w3.org/1999/xhtml"===
|
||||
a&&(a=qg(c));"http://www.w3.org/1999/xhtml"===a?"script"===c?(a=g.createElement("div"),a.innerHTML="<script>\x3c/script>",a=a.removeChild(a.firstChild)):"string"===typeof d.is?a=g.createElement(c,{is:d.is}):(a=g.createElement(c),"select"===c&&(g=a,d.multiple?g.multiple=!0:d.size&&(g.size=d.size))):a=g.createElementNS(a,c);a[Da]=b;a[uc]=d;Ak(a,b,!1,!1);b.stateNode=a;a:{g=qe(c,d);switch(c){case "dialog":B("cancel",a);B("close",a);e=d;break;case "iframe":case "object":case "embed":B("load",a);e=d;break;
|
||||
case "video":case "audio":for(e=0;e<Ec.length;e++)B(Ec[e],a);e=d;break;case "source":B("error",a);e=d;break;case "img":case "image":case "link":B("error",a);B("load",a);e=d;break;case "details":B("toggle",a);e=d;break;case "input":kg(a,d);e=ke(a,d);B("invalid",a);break;case "option":e=d;break;case "select":a._wrapperState={wasMultiple:!!d.multiple};e=E({},d,{value:void 0});B("invalid",a);break;case "textarea":ng(a,d);e=ne(a,d);B("invalid",a);break;default:e=d}pe(c,e);h=e;for(f in h)if(h.hasOwnProperty(f)){var k=
|
||||
h[f];"style"===f?sg(a,k):"dangerouslySetInnerHTML"===f?(k=k?k.__html:void 0,null!=k&&zi(a,k)):"children"===f?"string"===typeof k?("textarea"!==c||""!==k)&&Fc(a,k):"number"===typeof k&&Fc(a,""+k):"suppressContentEditableWarning"!==f&&"suppressHydrationWarning"!==f&&"autoFocus"!==f&&($b.hasOwnProperty(f)?null!=k&&"onScroll"===f&&B("scroll",a):null!=k&&$d(a,f,k,g))}switch(c){case "input":Pc(a);mg(a,d,!1);break;case "textarea":Pc(a);pg(a);break;case "option":null!=d.value&&a.setAttribute("value",""+Ua(d.value));
|
||||
break;case "select":a.multiple=!!d.multiple;f=d.value;null!=f?Db(a,!!d.multiple,f,!1):null!=d.defaultValue&&Db(a,!!d.multiple,d.defaultValue,!0);break;default:"function"===typeof e.onClick&&(a.onclick=kd)}switch(c){case "button":case "input":case "select":case "textarea":d=!!d.autoFocus;break a;case "img":d=!0;break a;default:d=!1}}d&&(b.flags|=4)}null!==b.ref&&(b.flags|=512,b.flags|=2097152)}W(b);return null;case 6:if(a&&null!=b.stateNode)Bk(a,b,a.memoizedProps,d);else{if("string"!==typeof d&&null===
|
||||
b.stateNode)throw Error(n(166));c=vb(xc.current);vb(Ea.current);if(pd(b)){d=b.stateNode;c=b.memoizedProps;d[Da]=b;if(f=d.nodeValue!==c)if(a=la,null!==a)switch(a.tag){case 3:jd(d.nodeValue,c,0!==(a.mode&1));break;case 5:!0!==a.memoizedProps.suppressHydrationWarning&&jd(d.nodeValue,c,0!==(a.mode&1))}f&&(b.flags|=4)}else d=(9===c.nodeType?c:c.ownerDocument).createTextNode(d),d[Da]=b,b.stateNode=d}W(b);return null;case 13:w(G);d=b.memoizedState;if(null===a||null!==a.memoizedState&&null!==a.memoizedState.dehydrated){if(D&&
|
||||
null!==fa&&0!==(b.mode&1)&&0===(b.flags&128)){for(f=fa;f;)f=Ka(f.nextSibling);Qb();b.flags|=98560;f=!1}else if(f=pd(b),null!==d&&null!==d.dehydrated){if(null===a){if(!f)throw Error(n(318));f=b.memoizedState;f=null!==f?f.dehydrated:null;if(!f)throw Error(n(317));f[Da]=b}else Qb(),0===(b.flags&128)&&(b.memoizedState=null),b.flags|=4;W(b);f=!1}else null!==wa&&(Gf(wa),wa=null),f=!0;if(!f)return b.flags&65536?b:null}if(0!==(b.flags&128))return b.lanes=c,b;d=null!==d;d!==(null!==a&&null!==a.memoizedState)&&
|
||||
d&&(b.child.flags|=8192,0!==(b.mode&1)&&(null===a||0!==(G.current&1)?0===L&&(L=3):Ef()));null!==b.updateQueue&&(b.flags|=4);W(b);return null;case 4:return Tb(),yi(a,b),null===a&&sc(b.stateNode.containerInfo),W(b),null;case 10:return af(b.type._context),W(b),null;case 17:return ea(b.type)&&(w(S),w(J)),W(b),null;case 19:w(G);f=b.memoizedState;if(null===f)return W(b),null;d=0!==(b.flags&128);g=f.rendering;if(null===g)if(d)Dc(f,!1);else{if(0!==L||null!==a&&0!==(a.flags&128))for(a=b.child;null!==a;){g=
|
||||
yd(a);if(null!==g){b.flags|=128;Dc(f,!1);d=g.updateQueue;null!==d&&(b.updateQueue=d,b.flags|=4);b.subtreeFlags=0;d=c;for(c=b.child;null!==c;)f=c,a=d,f.flags&=14680066,g=f.alternate,null===g?(f.childLanes=0,f.lanes=a,f.child=null,f.subtreeFlags=0,f.memoizedProps=null,f.memoizedState=null,f.updateQueue=null,f.dependencies=null,f.stateNode=null):(f.childLanes=g.childLanes,f.lanes=g.lanes,f.child=g.child,f.subtreeFlags=0,f.deletions=null,f.memoizedProps=g.memoizedProps,f.memoizedState=g.memoizedState,
|
||||
f.updateQueue=g.updateQueue,f.type=g.type,a=g.dependencies,f.dependencies=null===a?null:{lanes:a.lanes,firstContext:a.firstContext}),c=c.sibling;y(G,G.current&1|2);return b.child}a=a.sibling}null!==f.tail&&P()>Hf&&(b.flags|=128,d=!0,Dc(f,!1),b.lanes=4194304)}else{if(!d)if(a=yd(g),null!==a){if(b.flags|=128,d=!0,c=a.updateQueue,null!==c&&(b.updateQueue=c,b.flags|=4),Dc(f,!0),null===f.tail&&"hidden"===f.tailMode&&!g.alternate&&!D)return W(b),null}else 2*P()-f.renderingStartTime>Hf&&1073741824!==c&&(b.flags|=
|
||||
128,d=!0,Dc(f,!1),b.lanes=4194304);f.isBackwards?(g.sibling=b.child,b.child=g):(c=f.last,null!==c?c.sibling=g:b.child=g,f.last=g)}if(null!==f.tail)return b=f.tail,f.rendering=b,f.tail=b.sibling,f.renderingStartTime=P(),b.sibling=null,c=G.current,y(G,d?c&1|2:c&1),b;W(b);return null;case 22:case 23:return ba=Ga.current,w(Ga),d=null!==b.memoizedState,null!==a&&null!==a.memoizedState!==d&&(b.flags|=8192),d&&0!==(b.mode&1)?0!==(ba&1073741824)&&(W(b),b.subtreeFlags&6&&(b.flags|=8192)):W(b),null;case 24:return null;
|
||||
case 25:return null}throw Error(n(156,b.tag));}function Ck(a,b,c){Ve(b);switch(b.tag){case 1:return ea(b.type)&&(w(S),w(J)),a=b.flags,a&65536?(b.flags=a&-65537|128,b):null;case 3:return Tb(),w(S),w(J),lf(),a=b.flags,0!==(a&65536)&&0===(a&128)?(b.flags=a&-65537|128,b):null;case 5:return kf(b),null;case 13:w(G);a=b.memoizedState;if(null!==a&&null!==a.dehydrated){if(null===b.alternate)throw Error(n(340));Qb()}a=b.flags;return a&65536?(b.flags=a&-65537|128,b):null;case 19:return w(G),null;case 4:return Tb(),
|
||||
null;case 10:return af(b.type._context),null;case 22:case 23:return ba=Ga.current,w(Ga),null;case 24:return null;default:return null}}function Wb(a,b){var c=a.ref;if(null!==c)if("function"===typeof c)try{c(null)}catch(d){H(a,b,d)}else c.current=null}function If(a,b,c){try{c()}catch(d){H(a,b,d)}}function Dk(a,b){Jf=Zc;a=ch();if(Ie(a)){if("selectionStart"in a)var c={start:a.selectionStart,end:a.selectionEnd};else a:{c=(c=a.ownerDocument)&&c.defaultView||window;var d=c.getSelection&&c.getSelection();
|
||||
if(d&&0!==d.rangeCount){c=d.anchorNode;var e=d.anchorOffset,f=d.focusNode;d=d.focusOffset;try{c.nodeType,f.nodeType}catch(M){c=null;break a}var g=0,h=-1,k=-1,m=0,t=0,u=a,r=null;b:for(;;){for(var p;;){u!==c||0!==e&&3!==u.nodeType||(h=g+e);u!==f||0!==d&&3!==u.nodeType||(k=g+d);3===u.nodeType&&(g+=u.nodeValue.length);if(null===(p=u.firstChild))break;r=u;u=p}for(;;){if(u===a)break b;r===c&&++m===e&&(h=g);r===f&&++t===d&&(k=g);if(null!==(p=u.nextSibling))break;u=r;r=u.parentNode}u=p}c=-1===h||-1===k?null:
|
||||
{start:h,end:k}}else c=null}c=c||{start:0,end:0}}else c=null;Kf={focusedElem:a,selectionRange:c};Zc=!1;for(l=b;null!==l;)if(b=l,a=b.child,0!==(b.subtreeFlags&1028)&&null!==a)a.return=b,l=a;else for(;null!==l;){b=l;try{var x=b.alternate;if(0!==(b.flags&1024))switch(b.tag){case 0:case 11:case 15:break;case 1:if(null!==x){var w=x.memoizedProps,z=x.memoizedState,A=b.stateNode,v=A.getSnapshotBeforeUpdate(b.elementType===b.type?w:xa(b.type,w),z);A.__reactInternalSnapshotBeforeUpdate=v}break;case 3:var q=
|
||||
b.stateNode.containerInfo;1===q.nodeType?q.textContent="":9===q.nodeType&&q.documentElement&&q.removeChild(q.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(n(163));}}catch(M){H(b,b.return,M)}a=b.sibling;if(null!==a){a.return=b.return;l=a;break}l=b.return}x=Ai;Ai=!1;return x}function Gc(a,b,c){var d=b.updateQueue;d=null!==d?d.lastEffect:null;if(null!==d){var e=d=d.next;do{if((e.tag&a)===a){var f=e.destroy;e.destroy=void 0;void 0!==f&&If(b,c,f)}e=e.next}while(e!==d)}}
|
||||
function Id(a,b){b=b.updateQueue;b=null!==b?b.lastEffect:null;if(null!==b){var c=b=b.next;do{if((c.tag&a)===a){var d=c.create;c.destroy=d()}c=c.next}while(c!==b)}}function Lf(a){var b=a.ref;if(null!==b){var c=a.stateNode;switch(a.tag){case 5:a=c;break;default:a=c}"function"===typeof b?b(a):b.current=a}}function Bi(a){var b=a.alternate;null!==b&&(a.alternate=null,Bi(b));a.child=null;a.deletions=null;a.sibling=null;5===a.tag&&(b=a.stateNode,null!==b&&(delete b[Da],delete b[uc],delete b[Me],delete b[Ek],
|
||||
delete b[Fk]));a.stateNode=null;a.return=null;a.dependencies=null;a.memoizedProps=null;a.memoizedState=null;a.pendingProps=null;a.stateNode=null;a.updateQueue=null}function Ci(a){return 5===a.tag||3===a.tag||4===a.tag}function Di(a){a:for(;;){for(;null===a.sibling;){if(null===a.return||Ci(a.return))return null;a=a.return}a.sibling.return=a.return;for(a=a.sibling;5!==a.tag&&6!==a.tag&&18!==a.tag;){if(a.flags&2)continue a;if(null===a.child||4===a.tag)continue a;else a.child.return=a,a=a.child}if(!(a.flags&
|
||||
2))return a.stateNode}}function Mf(a,b,c){var d=a.tag;if(5===d||6===d)a=a.stateNode,b?8===c.nodeType?c.parentNode.insertBefore(a,b):c.insertBefore(a,b):(8===c.nodeType?(b=c.parentNode,b.insertBefore(a,c)):(b=c,b.appendChild(a)),c=c._reactRootContainer,null!==c&&void 0!==c||null!==b.onclick||(b.onclick=kd));else if(4!==d&&(a=a.child,null!==a))for(Mf(a,b,c),a=a.sibling;null!==a;)Mf(a,b,c),a=a.sibling}function Nf(a,b,c){var d=a.tag;if(5===d||6===d)a=a.stateNode,b?c.insertBefore(a,b):c.appendChild(a);
|
||||
else if(4!==d&&(a=a.child,null!==a))for(Nf(a,b,c),a=a.sibling;null!==a;)Nf(a,b,c),a=a.sibling}function jb(a,b,c){for(c=c.child;null!==c;)Ei(a,b,c),c=c.sibling}function Ei(a,b,c){if(Ca&&"function"===typeof Ca.onCommitFiberUnmount)try{Ca.onCommitFiberUnmount(Uc,c)}catch(h){}switch(c.tag){case 5:X||Wb(c,b);case 6:var d=T,e=za;T=null;jb(a,b,c);T=d;za=e;null!==T&&(za?(a=T,c=c.stateNode,8===a.nodeType?a.parentNode.removeChild(c):a.removeChild(c)):T.removeChild(c.stateNode));break;case 18:null!==T&&(za?
|
||||
(a=T,c=c.stateNode,8===a.nodeType?Re(a.parentNode,c):1===a.nodeType&&Re(a,c),nc(a)):Re(T,c.stateNode));break;case 4:d=T;e=za;T=c.stateNode.containerInfo;za=!0;jb(a,b,c);T=d;za=e;break;case 0:case 11:case 14:case 15:if(!X&&(d=c.updateQueue,null!==d&&(d=d.lastEffect,null!==d))){e=d=d.next;do{var f=e,g=f.destroy;f=f.tag;void 0!==g&&(0!==(f&2)?If(c,b,g):0!==(f&4)&&If(c,b,g));e=e.next}while(e!==d)}jb(a,b,c);break;case 1:if(!X&&(Wb(c,b),d=c.stateNode,"function"===typeof d.componentWillUnmount))try{d.props=
|
||||
c.memoizedProps,d.state=c.memoizedState,d.componentWillUnmount()}catch(h){H(c,b,h)}jb(a,b,c);break;case 21:jb(a,b,c);break;case 22:c.mode&1?(X=(d=X)||null!==c.memoizedState,jb(a,b,c),X=d):jb(a,b,c);break;default:jb(a,b,c)}}function Fi(a){var b=a.updateQueue;if(null!==b){a.updateQueue=null;var c=a.stateNode;null===c&&(c=a.stateNode=new Gk);b.forEach(function(b){var d=Hk.bind(null,a,b);c.has(b)||(c.add(b),b.then(d,d))})}}function Aa(a,b,c){c=b.deletions;if(null!==c)for(var d=0;d<c.length;d++){var e=
|
||||
c[d];try{var f=a,g=b,h=g;a:for(;null!==h;){switch(h.tag){case 5:T=h.stateNode;za=!1;break a;case 3:T=h.stateNode.containerInfo;za=!0;break a;case 4:T=h.stateNode.containerInfo;za=!0;break a}h=h.return}if(null===T)throw Error(n(160));Ei(f,g,e);T=null;za=!1;var k=e.alternate;null!==k&&(k.return=null);e.return=null}catch(m){H(e,b,m)}}if(b.subtreeFlags&12854)for(b=b.child;null!==b;)Gi(b,a),b=b.sibling}function Gi(a,b,c){var d=a.alternate;c=a.flags;switch(a.tag){case 0:case 11:case 14:case 15:Aa(b,a);
|
||||
Ha(a);if(c&4){try{Gc(3,a,a.return),Id(3,a)}catch(F){H(a,a.return,F)}try{Gc(5,a,a.return)}catch(F){H(a,a.return,F)}}break;case 1:Aa(b,a);Ha(a);c&512&&null!==d&&Wb(d,d.return);break;case 5:Aa(b,a);Ha(a);c&512&&null!==d&&Wb(d,d.return);if(a.flags&32){var e=a.stateNode;try{Fc(e,"")}catch(F){H(a,a.return,F)}}if(c&4&&(e=a.stateNode,null!=e)){var f=a.memoizedProps,g=null!==d?d.memoizedProps:f,h=a.type,k=a.updateQueue;a.updateQueue=null;if(null!==k)try{"input"===h&&"radio"===f.type&&null!=f.name&&lg(e,f);
|
||||
qe(h,g);var m=qe(h,f);for(g=0;g<k.length;g+=2){var t=k[g],u=k[g+1];"style"===t?sg(e,u):"dangerouslySetInnerHTML"===t?zi(e,u):"children"===t?Fc(e,u):$d(e,t,u,m)}switch(h){case "input":le(e,f);break;case "textarea":og(e,f);break;case "select":var r=e._wrapperState.wasMultiple;e._wrapperState.wasMultiple=!!f.multiple;var p=f.value;null!=p?Db(e,!!f.multiple,p,!1):r!==!!f.multiple&&(null!=f.defaultValue?Db(e,!!f.multiple,f.defaultValue,!0):Db(e,!!f.multiple,f.multiple?[]:"",!1))}e[uc]=f}catch(F){H(a,a.return,
|
||||
F)}}break;case 6:Aa(b,a);Ha(a);if(c&4){if(null===a.stateNode)throw Error(n(162));e=a.stateNode;f=a.memoizedProps;try{e.nodeValue=f}catch(F){H(a,a.return,F)}}break;case 3:Aa(b,a);Ha(a);if(c&4&&null!==d&&d.memoizedState.isDehydrated)try{nc(b.containerInfo)}catch(F){H(a,a.return,F)}break;case 4:Aa(b,a);Ha(a);break;case 13:Aa(b,a);Ha(a);e=a.child;e.flags&8192&&(f=null!==e.memoizedState,e.stateNode.isHidden=f,!f||null!==e.alternate&&null!==e.alternate.memoizedState||(Of=P()));c&4&&Fi(a);break;case 22:t=
|
||||
null!==d&&null!==d.memoizedState;a.mode&1?(X=(m=X)||t,Aa(b,a),X=m):Aa(b,a);Ha(a);if(c&8192){m=null!==a.memoizedState;if((a.stateNode.isHidden=m)&&!t&&0!==(a.mode&1))for(l=a,t=a.child;null!==t;){for(u=l=t;null!==l;){r=l;p=r.child;switch(r.tag){case 0:case 11:case 14:case 15:Gc(4,r,r.return);break;case 1:Wb(r,r.return);var x=r.stateNode;if("function"===typeof x.componentWillUnmount){c=r;b=r.return;try{d=c,x.props=d.memoizedProps,x.state=d.memoizedState,x.componentWillUnmount()}catch(F){H(c,b,F)}}break;
|
||||
case 5:Wb(r,r.return);break;case 22:if(null!==r.memoizedState){Hi(u);continue}}null!==p?(p.return=r,l=p):Hi(u)}t=t.sibling}a:for(t=null,u=a;;){if(5===u.tag){if(null===t){t=u;try{e=u.stateNode,m?(f=e.style,"function"===typeof f.setProperty?f.setProperty("display","none","important"):f.display="none"):(h=u.stateNode,k=u.memoizedProps.style,g=void 0!==k&&null!==k&&k.hasOwnProperty("display")?k.display:null,h.style.display=rg("display",g))}catch(F){H(a,a.return,F)}}}else if(6===u.tag){if(null===t)try{u.stateNode.nodeValue=
|
||||
m?"":u.memoizedProps}catch(F){H(a,a.return,F)}}else if((22!==u.tag&&23!==u.tag||null===u.memoizedState||u===a)&&null!==u.child){u.child.return=u;u=u.child;continue}if(u===a)break a;for(;null===u.sibling;){if(null===u.return||u.return===a)break a;t===u&&(t=null);u=u.return}t===u&&(t=null);u.sibling.return=u.return;u=u.sibling}}break;case 19:Aa(b,a);Ha(a);c&4&&Fi(a);break;case 21:break;default:Aa(b,a),Ha(a)}}function Ha(a){var b=a.flags;if(b&2){try{a:{for(var c=a.return;null!==c;){if(Ci(c)){var d=c;
|
||||
break a}c=c.return}throw Error(n(160));}switch(d.tag){case 5:var e=d.stateNode;d.flags&32&&(Fc(e,""),d.flags&=-33);var f=Di(a);Nf(a,f,e);break;case 3:case 4:var g=d.stateNode.containerInfo,h=Di(a);Mf(a,h,g);break;default:throw Error(n(161));}}catch(k){H(a,a.return,k)}a.flags&=-3}b&4096&&(a.flags&=-4097)}function Ik(a,b,c){l=a;Ii(a,b,c)}function Ii(a,b,c){for(var d=0!==(a.mode&1);null!==l;){var e=l,f=e.child;if(22===e.tag&&d){var g=null!==e.memoizedState||Jd;if(!g){var h=e.alternate,k=null!==h&&null!==
|
||||
h.memoizedState||X;h=Jd;var m=X;Jd=g;if((X=k)&&!m)for(l=e;null!==l;)g=l,k=g.child,22===g.tag&&null!==g.memoizedState?Ji(e):null!==k?(k.return=g,l=k):Ji(e);for(;null!==f;)l=f,Ii(f,b,c),f=f.sibling;l=e;Jd=h;X=m}Ki(a,b,c)}else 0!==(e.subtreeFlags&8772)&&null!==f?(f.return=e,l=f):Ki(a,b,c)}}function Ki(a,b,c){for(;null!==l;){b=l;if(0!==(b.flags&8772)){c=b.alternate;try{if(0!==(b.flags&8772))switch(b.tag){case 0:case 11:case 15:X||Id(5,b);break;case 1:var d=b.stateNode;if(b.flags&4&&!X)if(null===c)d.componentDidMount();
|
||||
else{var e=b.elementType===b.type?c.memoizedProps:xa(b.type,c.memoizedProps);d.componentDidUpdate(e,c.memoizedState,d.__reactInternalSnapshotBeforeUpdate)}var f=b.updateQueue;null!==f&&Fh(b,f,d);break;case 3:var g=b.updateQueue;if(null!==g){c=null;if(null!==b.child)switch(b.child.tag){case 5:c=b.child.stateNode;break;case 1:c=b.child.stateNode}Fh(b,g,c)}break;case 5:var h=b.stateNode;if(null===c&&b.flags&4){c=h;var k=b.memoizedProps;switch(b.type){case "button":case "input":case "select":case "textarea":k.autoFocus&&
|
||||
c.focus();break;case "img":k.src&&(c.src=k.src)}}break;case 6:break;case 4:break;case 12:break;case 13:if(null===b.memoizedState){var m=b.alternate;if(null!==m){var t=m.memoizedState;if(null!==t){var p=t.dehydrated;null!==p&&nc(p)}}}break;case 19:case 17:case 21:case 22:case 23:case 25:break;default:throw Error(n(163));}X||b.flags&512&&Lf(b)}catch(r){H(b,b.return,r)}}if(b===a){l=null;break}c=b.sibling;if(null!==c){c.return=b.return;l=c;break}l=b.return}}function Hi(a){for(;null!==l;){var b=l;if(b===
|
||||
a){l=null;break}var c=b.sibling;if(null!==c){c.return=b.return;l=c;break}l=b.return}}function Ji(a){for(;null!==l;){var b=l;try{switch(b.tag){case 0:case 11:case 15:var c=b.return;try{Id(4,b)}catch(k){H(b,c,k)}break;case 1:var d=b.stateNode;if("function"===typeof d.componentDidMount){var e=b.return;try{d.componentDidMount()}catch(k){H(b,e,k)}}var f=b.return;try{Lf(b)}catch(k){H(b,f,k)}break;case 5:var g=b.return;try{Lf(b)}catch(k){H(b,g,k)}}}catch(k){H(b,b.return,k)}if(b===a){l=null;break}var h=b.sibling;
|
||||
if(null!==h){h.return=b.return;l=h;break}l=b.return}}function Hc(){Hf=P()+500}function Z(){return 0!==(p&6)?P():-1!==Kd?Kd:Kd=P()}function hb(a){if(0===(a.mode&1))return 1;if(0!==(p&2)&&0!==U)return U&-U;if(null!==Jk.transition)return 0===Ld&&(Ld=Dg()),Ld;a=z;if(0!==a)return a;a=window.event;a=void 0===a?16:Lg(a.type);return a}function ya(a,b,c,d){if(50<Ic)throw Ic=0,Pf=null,Error(n(185));ic(a,c,d);if(0===(p&2)||a!==O)a===O&&(0===(p&2)&&(Md|=c),4===L&&kb(a,U)),ia(a,d),1===c&&0===p&&0===(b.mode&1)&&
|
||||
(Hc(),md&&db())}function ia(a,b){var c=a.callbackNode;uj(a,b);var d=Vc(a,a===O?U:0);if(0===d)null!==c&&Li(c),a.callbackNode=null,a.callbackPriority=0;else if(b=d&-d,a.callbackPriority!==b){null!=c&&Li(c);if(1===b)0===a.tag?kk(Mi.bind(null,a)):wh(Mi.bind(null,a)),Kk(function(){0===(p&6)&&db()}),c=null;else{switch(Eg(d)){case 1:c=De;break;case 4:c=Mg;break;case 16:c=ad;break;case 536870912:c=Ng;break;default:c=ad}c=Ni(c,Oi.bind(null,a))}a.callbackPriority=b;a.callbackNode=c}}function Oi(a,b){Kd=-1;
|
||||
Ld=0;if(0!==(p&6))throw Error(n(327));var c=a.callbackNode;if(Xb()&&a.callbackNode!==c)return null;var d=Vc(a,a===O?U:0);if(0===d)return null;if(0!==(d&30)||0!==(d&a.expiredLanes)||b)b=Nd(a,d);else{b=d;var e=p;p|=2;var f=Pi();if(O!==a||U!==b)Ra=null,Hc(),xb(a,b);do try{Lk();break}catch(h){Qi(a,h)}while(1);Ze();Od.current=f;p=e;null!==I?b=0:(O=null,U=0,b=L)}if(0!==b){2===b&&(e=ve(a),0!==e&&(d=e,b=Qf(a,e)));if(1===b)throw c=Jc,xb(a,0),kb(a,d),ia(a,P()),c;if(6===b)kb(a,d);else{e=a.current.alternate;
|
||||
if(0===(d&30)&&!Mk(e)&&(b=Nd(a,d),2===b&&(f=ve(a),0!==f&&(d=f,b=Qf(a,f))),1===b))throw c=Jc,xb(a,0),kb(a,d),ia(a,P()),c;a.finishedWork=e;a.finishedLanes=d;switch(b){case 0:case 1:throw Error(n(345));case 2:yb(a,ja,Ra);break;case 3:kb(a,d);if((d&130023424)===d&&(b=Of+500-P(),10<b)){if(0!==Vc(a,0))break;e=a.suspendedLanes;if((e&d)!==d){Z();a.pingedLanes|=a.suspendedLanes&e;break}a.timeoutHandle=Rf(yb.bind(null,a,ja,Ra),b);break}yb(a,ja,Ra);break;case 4:kb(a,d);if((d&4194240)===d)break;b=a.eventTimes;
|
||||
for(e=-1;0<d;){var g=31-ta(d);f=1<<g;g=b[g];g>e&&(e=g);d&=~f}d=e;d=P()-d;d=(120>d?120:480>d?480:1080>d?1080:1920>d?1920:3E3>d?3E3:4320>d?4320:1960*Nk(d/1960))-d;if(10<d){a.timeoutHandle=Rf(yb.bind(null,a,ja,Ra),d);break}yb(a,ja,Ra);break;case 5:yb(a,ja,Ra);break;default:throw Error(n(329));}}}ia(a,P());return a.callbackNode===c?Oi.bind(null,a):null}function Qf(a,b){var c=Kc;a.current.memoizedState.isDehydrated&&(xb(a,b).flags|=256);a=Nd(a,b);2!==a&&(b=ja,ja=c,null!==b&&Gf(b));return a}function Gf(a){null===
|
||||
ja?ja=a:ja.push.apply(ja,a)}function Mk(a){for(var b=a;;){if(b.flags&16384){var c=b.updateQueue;if(null!==c&&(c=c.stores,null!==c))for(var d=0;d<c.length;d++){var e=c[d],f=e.getSnapshot;e=e.value;try{if(!ua(f(),e))return!1}catch(g){return!1}}}c=b.child;if(b.subtreeFlags&16384&&null!==c)c.return=b,b=c;else{if(b===a)break;for(;null===b.sibling;){if(null===b.return||b.return===a)return!0;b=b.return}b.sibling.return=b.return;b=b.sibling}}return!0}function kb(a,b){b&=~Sf;b&=~Md;a.suspendedLanes|=b;a.pingedLanes&=
|
||||
~b;for(a=a.expirationTimes;0<b;){var c=31-ta(b),d=1<<c;a[c]=-1;b&=~d}}function Mi(a){if(0!==(p&6))throw Error(n(327));Xb();var b=Vc(a,0);if(0===(b&1))return ia(a,P()),null;var c=Nd(a,b);if(0!==a.tag&&2===c){var d=ve(a);0!==d&&(b=d,c=Qf(a,d))}if(1===c)throw c=Jc,xb(a,0),kb(a,b),ia(a,P()),c;if(6===c)throw Error(n(345));a.finishedWork=a.current.alternate;a.finishedLanes=b;yb(a,ja,Ra);ia(a,P());return null}function Tf(a,b){var c=p;p|=1;try{return a(b)}finally{p=c,0===p&&(Hc(),md&&db())}}function zb(a){null!==
|
||||
lb&&0===lb.tag&&0===(p&6)&&Xb();var b=p;p|=1;var c=ca.transition,d=z;try{if(ca.transition=null,z=1,a)return a()}finally{z=d,ca.transition=c,p=b,0===(p&6)&&db()}}function xb(a,b){a.finishedWork=null;a.finishedLanes=0;var c=a.timeoutHandle;-1!==c&&(a.timeoutHandle=-1,Ok(c));if(null!==I)for(c=I.return;null!==c;){var d=c;Ve(d);switch(d.tag){case 1:d=d.type.childContextTypes;null!==d&&void 0!==d&&(w(S),w(J));break;case 3:Tb();w(S);w(J);lf();break;case 5:kf(d);break;case 4:Tb();break;case 13:w(G);break;
|
||||
case 19:w(G);break;case 10:af(d.type._context);break;case 22:case 23:ba=Ga.current,w(Ga)}c=c.return}O=a;I=a=gb(a.current,null);U=ba=b;L=0;Jc=null;Sf=Md=ra=0;ja=Kc=null;if(null!==tb){for(b=0;b<tb.length;b++)if(c=tb[b],d=c.interleaved,null!==d){c.interleaved=null;var e=d.next,f=c.pending;if(null!==f){var g=f.next;f.next=e;d.next=g}c.pending=d}tb=null}return a}function Qi(a,b){do{var c=I;try{Ze();zd.current=Ad;if(Bd){for(var d=C.memoizedState;null!==d;){var e=d.queue;null!==e&&(e.pending=null);d=d.next}Bd=
|
||||
!1}wb=0;N=K=C=null;zc=!1;Ac=0;Uf.current=null;if(null===c||null===c.return){L=1;Jc=b;I=null;break}a:{var f=a,g=c.return,h=c,k=b;b=U;h.flags|=32768;if(null!==k&&"object"===typeof k&&"function"===typeof k.then){var m=k,l=h,p=l.tag;if(0===(l.mode&1)&&(0===p||11===p||15===p)){var r=l.alternate;r?(l.updateQueue=r.updateQueue,l.memoizedState=r.memoizedState,l.lanes=r.lanes):(l.updateQueue=null,l.memoizedState=null)}var w=ki(g);if(null!==w){w.flags&=-257;li(w,g,h,f,b);w.mode&1&&ji(f,m,b);b=w;k=m;var x=b.updateQueue;
|
||||
if(null===x){var z=new Set;z.add(k);b.updateQueue=z}else x.add(k);break a}else{if(0===(b&1)){ji(f,m,b);Ef();break a}k=Error(n(426))}}else if(D&&h.mode&1){var y=ki(g);if(null!==y){0===(y.flags&65536)&&(y.flags|=256);li(y,g,h,f,b);Ye(Ub(k,h));break a}}f=k=Ub(k,h);4!==L&&(L=2);null===Kc?Kc=[f]:Kc.push(f);f=g;do{switch(f.tag){case 3:f.flags|=65536;b&=-b;f.lanes|=b;var A=hi(f,k,b);Eh(f,A);break a;case 1:h=k;var v=f.type,q=f.stateNode;if(0===(f.flags&128)&&("function"===typeof v.getDerivedStateFromError||
|
||||
null!==q&&"function"===typeof q.componentDidCatch&&(null===ib||!ib.has(q)))){f.flags|=65536;b&=-b;f.lanes|=b;var B=ii(f,h,b);Eh(f,B);break a}}f=f.return}while(null!==f)}Ri(c)}catch(ma){b=ma;I===c&&null!==c&&(I=c=c.return);continue}break}while(1)}function Pi(){var a=Od.current;Od.current=Ad;return null===a?Ad:a}function Ef(){if(0===L||3===L||2===L)L=4;null===O||0===(ra&268435455)&&0===(Md&268435455)||kb(O,U)}function Nd(a,b){var c=p;p|=2;var d=Pi();if(O!==a||U!==b)Ra=null,xb(a,b);do try{Pk();break}catch(e){Qi(a,
|
||||
e)}while(1);Ze();p=c;Od.current=d;if(null!==I)throw Error(n(261));O=null;U=0;return L}function Pk(){for(;null!==I;)Si(I)}function Lk(){for(;null!==I&&!Qk();)Si(I)}function Si(a){var b=Rk(a.alternate,a,ba);a.memoizedProps=a.pendingProps;null===b?Ri(a):I=b;Uf.current=null}function Ri(a){var b=a;do{var c=b.alternate;a=b.return;if(0===(b.flags&32768)){if(c=yk(c,b,ba),null!==c){I=c;return}}else{c=Ck(c,b);if(null!==c){c.flags&=32767;I=c;return}if(null!==a)a.flags|=32768,a.subtreeFlags=0,a.deletions=null;
|
||||
else{L=6;I=null;return}}b=b.sibling;if(null!==b){I=b;return}I=b=a}while(null!==b);0===L&&(L=5)}function yb(a,b,c){var d=z,e=ca.transition;try{ca.transition=null,z=1,Sk(a,b,c,d)}finally{ca.transition=e,z=d}return null}function Sk(a,b,c,d){do Xb();while(null!==lb);if(0!==(p&6))throw Error(n(327));c=a.finishedWork;var e=a.finishedLanes;if(null===c)return null;a.finishedWork=null;a.finishedLanes=0;if(c===a.current)throw Error(n(177));a.callbackNode=null;a.callbackPriority=0;var f=c.lanes|c.childLanes;
|
||||
vj(a,f);a===O&&(I=O=null,U=0);0===(c.subtreeFlags&2064)&&0===(c.flags&2064)||Pd||(Pd=!0,Ni(ad,function(){Xb();return null}));f=0!==(c.flags&15990);if(0!==(c.subtreeFlags&15990)||f){f=ca.transition;ca.transition=null;var g=z;z=1;var h=p;p|=4;Uf.current=null;Dk(a,c);Gi(c,a);Uj(Kf);Zc=!!Jf;Kf=Jf=null;a.current=c;Ik(c,a,e);Tk();p=h;z=g;ca.transition=f}else a.current=c;Pd&&(Pd=!1,lb=a,Qd=e);f=a.pendingLanes;0===f&&(ib=null);pj(c.stateNode,d);ia(a,P());if(null!==b)for(d=a.onRecoverableError,c=0;c<b.length;c++)e=
|
||||
b[c],d(e.value,{componentStack:e.stack,digest:e.digest});if(Ed)throw Ed=!1,a=xf,xf=null,a;0!==(Qd&1)&&0!==a.tag&&Xb();f=a.pendingLanes;0!==(f&1)?a===Pf?Ic++:(Ic=0,Pf=a):Ic=0;db();return null}function Xb(){if(null!==lb){var a=Eg(Qd),b=ca.transition,c=z;try{ca.transition=null;z=16>a?16:a;if(null===lb)var d=!1;else{a=lb;lb=null;Qd=0;if(0!==(p&6))throw Error(n(331));var e=p;p|=4;for(l=a.current;null!==l;){var f=l,g=f.child;if(0!==(l.flags&16)){var h=f.deletions;if(null!==h){for(var k=0;k<h.length;k++){var m=
|
||||
h[k];for(l=m;null!==l;){var t=l;switch(t.tag){case 0:case 11:case 15:Gc(8,t,f)}var u=t.child;if(null!==u)u.return=t,l=u;else for(;null!==l;){t=l;var r=t.sibling,w=t.return;Bi(t);if(t===m){l=null;break}if(null!==r){r.return=w;l=r;break}l=w}}}var x=f.alternate;if(null!==x){var y=x.child;if(null!==y){x.child=null;do{var C=y.sibling;y.sibling=null;y=C}while(null!==y)}}l=f}}if(0!==(f.subtreeFlags&2064)&&null!==g)g.return=f,l=g;else b:for(;null!==l;){f=l;if(0!==(f.flags&2048))switch(f.tag){case 0:case 11:case 15:Gc(9,
|
||||
f,f.return)}var A=f.sibling;if(null!==A){A.return=f.return;l=A;break b}l=f.return}}var v=a.current;for(l=v;null!==l;){g=l;var q=g.child;if(0!==(g.subtreeFlags&2064)&&null!==q)q.return=g,l=q;else b:for(g=v;null!==l;){h=l;if(0!==(h.flags&2048))try{switch(h.tag){case 0:case 11:case 15:Id(9,h)}}catch(ma){H(h,h.return,ma)}if(h===g){l=null;break b}var B=h.sibling;if(null!==B){B.return=h.return;l=B;break b}l=h.return}}p=e;db();if(Ca&&"function"===typeof Ca.onPostCommitFiberRoot)try{Ca.onPostCommitFiberRoot(Uc,
|
||||
a)}catch(ma){}d=!0}return d}finally{z=c,ca.transition=b}}return!1}function Ti(a,b,c){b=Ub(c,b);b=hi(a,b,1);a=eb(a,b,1);b=Z();null!==a&&(ic(a,1,b),ia(a,b))}function H(a,b,c){if(3===a.tag)Ti(a,a,c);else for(;null!==b;){if(3===b.tag){Ti(b,a,c);break}else if(1===b.tag){var d=b.stateNode;if("function"===typeof b.type.getDerivedStateFromError||"function"===typeof d.componentDidCatch&&(null===ib||!ib.has(d))){a=Ub(c,a);a=ii(b,a,1);b=eb(b,a,1);a=Z();null!==b&&(ic(b,1,a),ia(b,a));break}}b=b.return}}function tk(a,
|
||||
b,c){var d=a.pingCache;null!==d&&d.delete(b);b=Z();a.pingedLanes|=a.suspendedLanes&c;O===a&&(U&c)===c&&(4===L||3===L&&(U&130023424)===U&&500>P()-Of?xb(a,0):Sf|=c);ia(a,b)}function Ui(a,b){0===b&&(0===(a.mode&1)?b=1:(b=Rd,Rd<<=1,0===(Rd&130023424)&&(Rd=4194304)));var c=Z();a=Oa(a,b);null!==a&&(ic(a,b,c),ia(a,c))}function wk(a){var b=a.memoizedState,c=0;null!==b&&(c=b.retryLane);Ui(a,c)}function Hk(a,b){var c=0;switch(a.tag){case 13:var d=a.stateNode;var e=a.memoizedState;null!==e&&(c=e.retryLane);
|
||||
break;case 19:d=a.stateNode;break;default:throw Error(n(314));}null!==d&&d.delete(b);Ui(a,c)}function Ni(a,b){return xh(a,b)}function Uk(a,b,c,d){this.tag=a;this.key=c;this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null;this.index=0;this.ref=null;this.pendingProps=b;this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null;this.mode=d;this.subtreeFlags=this.flags=0;this.deletions=null;this.childLanes=this.lanes=0;this.alternate=null}function yf(a){a=
|
||||
a.prototype;return!(!a||!a.isReactComponent)}function Vk(a){if("function"===typeof a)return yf(a)?1:0;if(void 0!==a&&null!==a){a=a.$$typeof;if(a===ie)return 11;if(a===je)return 14}return 2}function gb(a,b){var c=a.alternate;null===c?(c=pa(a.tag,b,a.key,a.mode),c.elementType=a.elementType,c.type=a.type,c.stateNode=a.stateNode,c.alternate=a,a.alternate=c):(c.pendingProps=b,c.type=a.type,c.flags=0,c.subtreeFlags=0,c.deletions=null);c.flags=a.flags&14680064;c.childLanes=a.childLanes;c.lanes=a.lanes;c.child=
|
||||
a.child;c.memoizedProps=a.memoizedProps;c.memoizedState=a.memoizedState;c.updateQueue=a.updateQueue;b=a.dependencies;c.dependencies=null===b?null:{lanes:b.lanes,firstContext:b.firstContext};c.sibling=a.sibling;c.index=a.index;c.ref=a.ref;return c}function wd(a,b,c,d,e,f){var g=2;d=a;if("function"===typeof a)yf(a)&&(g=1);else if("string"===typeof a)g=5;else a:switch(a){case Bb:return ub(c.children,e,f,b);case fe:g=8;e|=8;break;case ee:return a=pa(12,c,b,e|2),a.elementType=ee,a.lanes=f,a;case ge:return a=
|
||||
pa(13,c,b,e),a.elementType=ge,a.lanes=f,a;case he:return a=pa(19,c,b,e),a.elementType=he,a.lanes=f,a;case Vi:return Gd(c,e,f,b);default:if("object"===typeof a&&null!==a)switch(a.$$typeof){case hg:g=10;break a;case gg:g=9;break a;case ie:g=11;break a;case je:g=14;break a;case Ta:g=16;d=null;break a}throw Error(n(130,null==a?a:typeof a,""));}b=pa(g,c,b,e);b.elementType=a;b.type=d;b.lanes=f;return b}function ub(a,b,c,d){a=pa(7,a,d,b);a.lanes=c;return a}function Gd(a,b,c,d){a=pa(22,a,d,b);a.elementType=
|
||||
Vi;a.lanes=c;a.stateNode={isHidden:!1};return a}function gf(a,b,c){a=pa(6,a,null,b);a.lanes=c;return a}function hf(a,b,c){b=pa(4,null!==a.children?a.children:[],a.key,b);b.lanes=c;b.stateNode={containerInfo:a.containerInfo,pendingChildren:null,implementation:a.implementation};return b}function Wk(a,b,c,d,e){this.tag=b;this.containerInfo=a;this.finishedWork=this.pingCache=this.current=this.pendingChildren=null;this.timeoutHandle=-1;this.callbackNode=this.pendingContext=this.context=null;this.callbackPriority=
|
||||
0;this.eventTimes=we(0);this.expirationTimes=we(-1);this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0;this.entanglements=we(0);this.identifierPrefix=d;this.onRecoverableError=e;this.mutableSourceEagerHydrationData=null}function Vf(a,b,c,d,e,f,g,h,k,m){a=new Wk(a,b,c,h,k);1===b?(b=1,!0===f&&(b|=8)):b=0;f=pa(3,null,null,b);a.current=f;f.stateNode=a;f.memoizedState={element:d,isDehydrated:c,cache:null,transitions:null,
|
||||
pendingSuspenseBoundaries:null};df(f);return a}function Xk(a,b,c){var d=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null;return{$$typeof:Cb,key:null==d?null:""+d,children:a,containerInfo:b,implementation:c}}function Wi(a){if(!a)return cb;a=a._reactInternals;a:{if(ob(a)!==a||1!==a.tag)throw Error(n(170));var b=a;do{switch(b.tag){case 3:b=b.stateNode.context;break a;case 1:if(ea(b.type)){b=b.stateNode.__reactInternalMemoizedMergedChildContext;break a}}b=b.return}while(null!==b);throw Error(n(171));
|
||||
}if(1===a.tag){var c=a.type;if(ea(c))return uh(a,c,b)}return b}function Xi(a,b,c,d,e,f,g,h,k,m){a=Vf(c,d,!0,a,e,f,g,h,k);a.context=Wi(null);c=a.current;d=Z();e=hb(c);f=Pa(d,e);f.callback=void 0!==b&&null!==b?b:null;eb(c,f,e);a.current.lanes=e;ic(a,e,d);ia(a,d);return a}function Sd(a,b,c,d){var e=b.current,f=Z(),g=hb(e);c=Wi(c);null===b.context?b.context=c:b.pendingContext=c;b=Pa(f,g);b.payload={element:a};d=void 0===d?null:d;null!==d&&(b.callback=d);a=eb(e,b,g);null!==a&&(ya(a,e,g,f),sd(a,e,g));return g}
|
||||
function Td(a){a=a.current;if(!a.child)return null;switch(a.child.tag){case 5:return a.child.stateNode;default:return a.child.stateNode}}function Yi(a,b){a=a.memoizedState;if(null!==a&&null!==a.dehydrated){var c=a.retryLane;a.retryLane=0!==c&&c<b?c:b}}function Wf(a,b){Yi(a,b);(a=a.alternate)&&Yi(a,b)}function Yk(a){a=Bg(a);return null===a?null:a.stateNode}function Zk(a){return null}function Xf(a){this._internalRoot=a}function Ud(a){this._internalRoot=a}function Yf(a){return!(!a||1!==a.nodeType&&9!==
|
||||
a.nodeType&&11!==a.nodeType)}function Vd(a){return!(!a||1!==a.nodeType&&9!==a.nodeType&&11!==a.nodeType&&(8!==a.nodeType||" react-mount-point-unstable "!==a.nodeValue))}function Zi(){}function $k(a,b,c,d,e){if(e){if("function"===typeof d){var f=d;d=function(){var a=Td(g);f.call(a)}}var g=Xi(b,d,a,0,null,!1,!1,"",Zi);a._reactRootContainer=g;a[Ja]=g.current;sc(8===a.nodeType?a.parentNode:a);zb();return g}for(;e=a.lastChild;)a.removeChild(e);if("function"===typeof d){var h=d;d=function(){var a=Td(k);
|
||||
h.call(a)}}var k=Vf(a,0,!1,null,null,!1,!1,"",Zi);a._reactRootContainer=k;a[Ja]=k.current;sc(8===a.nodeType?a.parentNode:a);zb(function(){Sd(b,k,c,d)});return k}function Wd(a,b,c,d,e){var f=c._reactRootContainer;if(f){var g=f;if("function"===typeof e){var h=e;e=function(){var a=Td(g);h.call(a)}}Sd(b,g,a,e)}else g=$k(c,b,a,e,d);return Td(g)}var cg=new Set,$b={},Ia=!("undefined"===typeof window||"undefined"===typeof window.document||"undefined"===typeof window.document.createElement),Zd=Object.prototype.hasOwnProperty,
|
||||
dj=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,eg={},dg={},R={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(a){R[a]=
|
||||
new Y(a,0,!1,a,null,!1,!1)});[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(a){var b=a[0];R[b]=new Y(b,1,!1,a[1],null,!1,!1)});["contentEditable","draggable","spellCheck","value"].forEach(function(a){R[a]=new Y(a,2,!1,a.toLowerCase(),null,!1,!1)});["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(a){R[a]=new Y(a,2,!1,a,null,!1,!1)});"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(a){R[a]=
|
||||
new Y(a,3,!1,a.toLowerCase(),null,!1,!1)});["checked","multiple","muted","selected"].forEach(function(a){R[a]=new Y(a,3,!0,a,null,!1,!1)});["capture","download"].forEach(function(a){R[a]=new Y(a,4,!1,a,null,!1,!1)});["cols","rows","size","span"].forEach(function(a){R[a]=new Y(a,6,!1,a,null,!1,!1)});["rowSpan","start"].forEach(function(a){R[a]=new Y(a,5,!1,a.toLowerCase(),null,!1,!1)});var Zf=/[\-:]([a-z])/g,$f=function(a){return a[1].toUpperCase()};"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(a){var b=
|
||||
a.replace(Zf,$f);R[b]=new Y(b,1,!1,a,null,!1,!1)});"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(a){var b=a.replace(Zf,$f);R[b]=new Y(b,1,!1,a,"http://www.w3.org/1999/xlink",!1,!1)});["xml:base","xml:lang","xml:space"].forEach(function(a){var b=a.replace(Zf,$f);R[b]=new Y(b,1,!1,a,"http://www.w3.org/XML/1998/namespace",!1,!1)});["tabIndex","crossOrigin"].forEach(function(a){R[a]=new Y(a,1,!1,a.toLowerCase(),null,!1,!1)});R.xlinkHref=new Y("xlinkHref",
|
||||
1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1);["src","href","action","formAction"].forEach(function(a){R[a]=new Y(a,1,!1,a.toLowerCase(),null,!0,!0)});var Sa=mb.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,xd=Symbol.for("react.element"),Cb=Symbol.for("react.portal"),Bb=Symbol.for("react.fragment"),fe=Symbol.for("react.strict_mode"),ee=Symbol.for("react.profiler"),hg=Symbol.for("react.provider"),gg=Symbol.for("react.context"),ie=Symbol.for("react.forward_ref"),ge=Symbol.for("react.suspense"),
|
||||
he=Symbol.for("react.suspense_list"),je=Symbol.for("react.memo"),Ta=Symbol.for("react.lazy");Symbol.for("react.scope");Symbol.for("react.debug_trace_mode");var Vi=Symbol.for("react.offscreen");Symbol.for("react.legacy_hidden");Symbol.for("react.cache");Symbol.for("react.tracing_marker");var fg=Symbol.iterator,E=Object.assign,ae,ce=!1,cc=Array.isArray,Xd,zi=function(a){return"undefined"!==typeof MSApp&&MSApp.execUnsafeLocalFunction?function(b,c,d,e){MSApp.execUnsafeLocalFunction(function(){return a(b,
|
||||
c,d,e)})}:a}(function(a,b){if("http://www.w3.org/2000/svg"!==a.namespaceURI||"innerHTML"in a)a.innerHTML=b;else{Xd=Xd||document.createElement("div");Xd.innerHTML="<svg>"+b.valueOf().toString()+"</svg>";for(b=Xd.firstChild;a.firstChild;)a.removeChild(a.firstChild);for(;b.firstChild;)a.appendChild(b.firstChild)}}),Fc=function(a,b){if(b){var c=a.firstChild;if(c&&c===a.lastChild&&3===c.nodeType){c.nodeValue=b;return}}a.textContent=b},dc={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,
|
||||
borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,
|
||||
strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},al=["Webkit","ms","Moz","O"];Object.keys(dc).forEach(function(a){al.forEach(function(b){b=b+a.charAt(0).toUpperCase()+a.substring(1);dc[b]=dc[a]})});var jj=E({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0}),ze=null,se=null,Eb=null,Fb=null,xg=function(a,b){return a(b)},yg=function(){},te=!1,Oe=!1;if(Ia)try{var Lc={};Object.defineProperty(Lc,
|
||||
"passive",{get:function(){Oe=!0}});window.addEventListener("test",Lc,Lc);window.removeEventListener("test",Lc,Lc)}catch(a){Oe=!1}var lj=function(a,b,c,d,e,f,g,h,k){var m=Array.prototype.slice.call(arguments,3);try{b.apply(c,m)}catch(t){this.onError(t)}},gc=!1,Sc=null,Tc=!1,ue=null,mj={onError:function(a){gc=!0;Sc=a}},Ba=mb.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler,Jg=Ba.unstable_scheduleCallback,Kg=Ba.unstable_NormalPriority,xh=Jg,Li=Ba.unstable_cancelCallback,Qk=Ba.unstable_shouldYield,
|
||||
Tk=Ba.unstable_requestPaint,P=Ba.unstable_now,Ej=Ba.unstable_getCurrentPriorityLevel,De=Ba.unstable_ImmediatePriority,Mg=Ba.unstable_UserBlockingPriority,ad=Kg,Fj=Ba.unstable_LowPriority,Ng=Ba.unstable_IdlePriority,Uc=null,Ca=null,ta=Math.clz32?Math.clz32:qj,rj=Math.log,sj=Math.LN2,Wc=64,Rd=4194304,z=0,Ae=!1,Yc=[],Va=null,Wa=null,Xa=null,jc=new Map,kc=new Map,Ya=[],Cj="mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset submit".split(" "),
|
||||
Gb=Sa.ReactCurrentBatchConfig,Zc=!0,$c=null,Za=null,Ee=null,bd=null,Yb={eventPhase:0,bubbles:0,cancelable:0,timeStamp:function(a){return a.timeStamp||Date.now()},defaultPrevented:0,isTrusted:0},He=ka(Yb),Mc=E({},Yb,{view:0,detail:0}),bk=ka(Mc),ag,bg,Nc,Yd=E({},Mc,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:Fe,button:0,buttons:0,relatedTarget:function(a){return void 0===a.relatedTarget?a.fromElement===a.srcElement?a.toElement:a.fromElement:
|
||||
a.relatedTarget},movementX:function(a){if("movementX"in a)return a.movementX;a!==Nc&&(Nc&&"mousemove"===a.type?(ag=a.screenX-Nc.screenX,bg=a.screenY-Nc.screenY):bg=ag=0,Nc=a);return ag},movementY:function(a){return"movementY"in a?a.movementY:bg}}),ih=ka(Yd),bl=E({},Yd,{dataTransfer:0}),Xj=ka(bl),cl=E({},Mc,{relatedTarget:0}),Pe=ka(cl),dl=E({},Yb,{animationName:0,elapsedTime:0,pseudoElement:0}),Zj=ka(dl),el=E({},Yb,{clipboardData:function(a){return"clipboardData"in a?a.clipboardData:window.clipboardData}}),
|
||||
dk=ka(el),fl=E({},Yb,{data:0}),qh=ka(fl),gk=qh,gl={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},hl={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",
|
||||
112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"},Hj={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"},il=E({},Mc,{key:function(a){if(a.key){var b=gl[a.key]||a.key;if("Unidentified"!==b)return b}return"keypress"===a.type?(a=cd(a),13===a?"Enter":String.fromCharCode(a)):"keydown"===a.type||"keyup"===a.type?hl[a.keyCode]||"Unidentified":""},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,
|
||||
metaKey:0,repeat:0,locale:0,getModifierState:Fe,charCode:function(a){return"keypress"===a.type?cd(a):0},keyCode:function(a){return"keydown"===a.type||"keyup"===a.type?a.keyCode:0},which:function(a){return"keypress"===a.type?cd(a):"keydown"===a.type||"keyup"===a.type?a.keyCode:0}}),Wj=ka(il),jl=E({},Yd,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0}),nh=ka(jl),kl=E({},Mc,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,
|
||||
ctrlKey:0,shiftKey:0,getModifierState:Fe}),Yj=ka(kl),ll=E({},Yb,{propertyName:0,elapsedTime:0,pseudoElement:0}),ak=ka(ll),ml=E({},Yd,{deltaX:function(a){return"deltaX"in a?a.deltaX:"wheelDeltaX"in a?-a.wheelDeltaX:0},deltaY:function(a){return"deltaY"in a?a.deltaY:"wheelDeltaY"in a?-a.wheelDeltaY:"wheelDelta"in a?-a.wheelDelta:0},deltaZ:0,deltaMode:0}),ck=ka(ml),Ij=[9,13,27,32],Ge=Ia&&"CompositionEvent"in window,Oc=null;Ia&&"documentMode"in document&&(Oc=document.documentMode);var fk=Ia&&"TextEvent"in
|
||||
window&&!Oc,Ug=Ia&&(!Ge||Oc&&8<Oc&&11>=Oc),Tg=String.fromCharCode(32),Sg=!1,Hb=!1,Lj={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0},oc=null,pc=null,ph=!1;Ia&&(ph=Mj("input")&&(!document.documentMode||9<document.documentMode));var ua="function"===typeof Object.is?Object.is:Tj,ek=Ia&&"documentMode"in document&&11>=document.documentMode,Jb=null,Ke=null,rc=null,Je=!1,Kb={animationend:gd("Animation","AnimationEnd"),
|
||||
animationiteration:gd("Animation","AnimationIteration"),animationstart:gd("Animation","AnimationStart"),transitionend:gd("Transition","TransitionEnd")},Le={},eh={};Ia&&(eh=document.createElement("div").style,"AnimationEvent"in window||(delete Kb.animationend.animation,delete Kb.animationiteration.animation,delete Kb.animationstart.animation),"TransitionEvent"in window||delete Kb.transitionend.transition);var jh=hd("animationend"),kh=hd("animationiteration"),lh=hd("animationstart"),mh=hd("transitionend"),
|
||||
fh=new Map,$i="abort auxClick cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel".split(" ");
|
||||
(function(){for(var a=0;a<$i.length;a++){var b=$i[a],c=b.toLowerCase();b=b[0].toUpperCase()+b.slice(1);$a(c,"on"+b)}$a(jh,"onAnimationEnd");$a(kh,"onAnimationIteration");$a(lh,"onAnimationStart");$a("dblclick","onDoubleClick");$a("focusin","onFocus");$a("focusout","onBlur");$a(mh,"onTransitionEnd")})();Ab("onMouseEnter",["mouseout","mouseover"]);Ab("onMouseLeave",["mouseout","mouseover"]);Ab("onPointerEnter",["pointerout","pointerover"]);Ab("onPointerLeave",["pointerout","pointerover"]);nb("onChange",
|
||||
"change click focusin focusout input keydown keyup selectionchange".split(" "));nb("onSelect","focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange".split(" "));nb("onBeforeInput",["compositionend","keypress","textInput","paste"]);nb("onCompositionEnd","compositionend focusout keydown keypress keyup mousedown".split(" "));nb("onCompositionStart","compositionstart focusout keydown keypress keyup mousedown".split(" "));nb("onCompositionUpdate","compositionupdate focusout keydown keypress keyup mousedown".split(" "));
|
||||
var Ec="abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange resize seeked seeking stalled suspend timeupdate volumechange waiting".split(" "),Vj=new Set("cancel close invalid load scroll toggle".split(" ").concat(Ec)),id="_reactListening"+Math.random().toString(36).slice(2),hk=/\r\n?/g,ik=/\u0000|\uFFFD/g,Jf=null,Kf=null,Rf="function"===typeof setTimeout?setTimeout:void 0,Ok="function"===typeof clearTimeout?
|
||||
clearTimeout:void 0,aj="function"===typeof Promise?Promise:void 0,Kk="function"===typeof queueMicrotask?queueMicrotask:"undefined"!==typeof aj?function(a){return aj.resolve(null).then(a).catch(jk)}:Rf,Zb=Math.random().toString(36).slice(2),Da="__reactFiber$"+Zb,uc="__reactProps$"+Zb,Ja="__reactContainer$"+Zb,Me="__reactEvents$"+Zb,Ek="__reactListeners$"+Zb,Fk="__reactHandles$"+Zb,Se=[],Mb=-1,cb={},J=bb(cb),S=bb(!1),qb=cb,La=null,md=!1,Te=!1,Ob=[],Pb=0,od=null,nd=0,na=[],oa=0,sb=null,Ma=1,Na="",la=
|
||||
null,fa=null,D=!1,wa=null,Jk=Sa.ReactCurrentBatchConfig,rd=bb(null),qd=null,Rb=null,$e=null,tb=null,lk=Oa,fb=!1,Jh=(new mb.Component).refs,ud={isMounted:function(a){return(a=a._reactInternals)?ob(a)===a:!1},enqueueSetState:function(a,b,c){a=a._reactInternals;var d=Z(),e=hb(a),f=Pa(d,e);f.payload=b;void 0!==c&&null!==c&&(f.callback=c);b=eb(a,f,e);null!==b&&(ya(b,a,e,d),sd(b,a,e))},enqueueReplaceState:function(a,b,c){a=a._reactInternals;var d=Z(),e=hb(a),f=Pa(d,e);f.tag=1;f.payload=b;void 0!==c&&null!==
|
||||
c&&(f.callback=c);b=eb(a,f,e);null!==b&&(ya(b,a,e,d),sd(b,a,e))},enqueueForceUpdate:function(a,b){a=a._reactInternals;var c=Z(),d=hb(a),e=Pa(c,d);e.tag=2;void 0!==b&&null!==b&&(e.callback=b);b=eb(a,e,d);null!==b&&(ya(b,a,d,c),sd(b,a,d))}},Vb=Lh(!0),mi=Lh(!1),wc={},Ea=bb(wc),yc=bb(wc),xc=bb(wc),G=bb(0),mf=[],zd=Sa.ReactCurrentDispatcher,uf=Sa.ReactCurrentBatchConfig,wb=0,C=null,K=null,N=null,Bd=!1,zc=!1,Ac=0,nl=0,Ad={readContext:qa,useCallback:V,useContext:V,useEffect:V,useImperativeHandle:V,useInsertionEffect:V,
|
||||
useLayoutEffect:V,useMemo:V,useReducer:V,useRef:V,useState:V,useDebugValue:V,useDeferredValue:V,useTransition:V,useMutableSource:V,useSyncExternalStore:V,useId:V,unstable_isNewReconciler:!1},mk={readContext:qa,useCallback:function(a,b){Fa().memoizedState=[a,void 0===b?null:b];return a},useContext:qa,useEffect:Wh,useImperativeHandle:function(a,b,c){c=null!==c&&void 0!==c?c.concat([a]):null;return Cd(4194308,4,Zh.bind(null,b,a),c)},useLayoutEffect:function(a,b){return Cd(4194308,4,a,b)},useInsertionEffect:function(a,
|
||||
b){return Cd(4,2,a,b)},useMemo:function(a,b){var c=Fa();b=void 0===b?null:b;a=a();c.memoizedState=[a,b];return a},useReducer:function(a,b,c){var d=Fa();b=void 0!==c?c(b):b;d.memoizedState=d.baseState=b;a={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:a,lastRenderedState:b};d.queue=a;a=a.dispatch=rk.bind(null,C,a);return[d.memoizedState,a]},useRef:function(a){var b=Fa();a={current:a};return b.memoizedState=a},useState:Uh,useDebugValue:tf,useDeferredValue:function(a){return Fa().memoizedState=
|
||||
a},useTransition:function(){var a=Uh(!1),b=a[0];a=qk.bind(null,a[1]);Fa().memoizedState=a;return[b,a]},useMutableSource:function(a,b,c){},useSyncExternalStore:function(a,b,c){var d=C,e=Fa();if(D){if(void 0===c)throw Error(n(407));c=c()}else{c=b();if(null===O)throw Error(n(349));0!==(wb&30)||Rh(d,b,c)}e.memoizedState=c;var f={value:c,getSnapshot:b};e.queue=f;Wh(Ph.bind(null,d,f,a),[a]);d.flags|=2048;Cc(9,Qh.bind(null,d,f,c,b),void 0,null);return c},useId:function(){var a=Fa(),b=O.identifierPrefix;
|
||||
if(D){var c=Na;var d=Ma;c=(d&~(1<<32-ta(d)-1)).toString(32)+c;b=":"+b+"R"+c;c=Ac++;0<c&&(b+="H"+c.toString(32));b+=":"}else c=nl++,b=":"+b+"r"+c.toString(32)+":";return a.memoizedState=b},unstable_isNewReconciler:!1},nk={readContext:qa,useCallback:ai,useContext:qa,useEffect:sf,useImperativeHandle:$h,useInsertionEffect:Xh,useLayoutEffect:Yh,useMemo:bi,useReducer:qf,useRef:Vh,useState:function(a){return qf(Bc)},useDebugValue:tf,useDeferredValue:function(a){var b=sa();return ci(b,K.memoizedState,a)},
|
||||
useTransition:function(){var a=qf(Bc)[0],b=sa().memoizedState;return[a,b]},useMutableSource:Nh,useSyncExternalStore:Oh,useId:di,unstable_isNewReconciler:!1},ok={readContext:qa,useCallback:ai,useContext:qa,useEffect:sf,useImperativeHandle:$h,useInsertionEffect:Xh,useLayoutEffect:Yh,useMemo:bi,useReducer:rf,useRef:Vh,useState:function(a){return rf(Bc)},useDebugValue:tf,useDeferredValue:function(a){var b=sa();return null===K?b.memoizedState=a:ci(b,K.memoizedState,a)},useTransition:function(){var a=rf(Bc)[0],
|
||||
b=sa().memoizedState;return[a,b]},useMutableSource:Nh,useSyncExternalStore:Oh,useId:di,unstable_isNewReconciler:!1},sk="function"===typeof WeakMap?WeakMap:Map,uk=Sa.ReactCurrentOwner,ha=!1,Cf={dehydrated:null,treeContext:null,retryLane:0};var Ak=function(a,b,c,d){for(c=b.child;null!==c;){if(5===c.tag||6===c.tag)a.appendChild(c.stateNode);else if(4!==c.tag&&null!==c.child){c.child.return=c;c=c.child;continue}if(c===b)break;for(;null===c.sibling;){if(null===c.return||c.return===b)return;c=c.return}c.sibling.return=
|
||||
c.return;c=c.sibling}};var yi=function(a,b){};var zk=function(a,b,c,d,e){var f=a.memoizedProps;if(f!==d){a=b.stateNode;vb(Ea.current);e=null;switch(c){case "input":f=ke(a,f);d=ke(a,d);e=[];break;case "select":f=E({},f,{value:void 0});d=E({},d,{value:void 0});e=[];break;case "textarea":f=ne(a,f);d=ne(a,d);e=[];break;default:"function"!==typeof f.onClick&&"function"===typeof d.onClick&&(a.onclick=kd)}pe(c,d);var g;c=null;for(m in f)if(!d.hasOwnProperty(m)&&f.hasOwnProperty(m)&&null!=f[m])if("style"===
|
||||
m){var h=f[m];for(g in h)h.hasOwnProperty(g)&&(c||(c={}),c[g]="")}else"dangerouslySetInnerHTML"!==m&&"children"!==m&&"suppressContentEditableWarning"!==m&&"suppressHydrationWarning"!==m&&"autoFocus"!==m&&($b.hasOwnProperty(m)?e||(e=[]):(e=e||[]).push(m,null));for(m in d){var k=d[m];h=null!=f?f[m]:void 0;if(d.hasOwnProperty(m)&&k!==h&&(null!=k||null!=h))if("style"===m)if(h){for(g in h)!h.hasOwnProperty(g)||k&&k.hasOwnProperty(g)||(c||(c={}),c[g]="");for(g in k)k.hasOwnProperty(g)&&h[g]!==k[g]&&(c||
|
||||
(c={}),c[g]=k[g])}else c||(e||(e=[]),e.push(m,c)),c=k;else"dangerouslySetInnerHTML"===m?(k=k?k.__html:void 0,h=h?h.__html:void 0,null!=k&&h!==k&&(e=e||[]).push(m,k)):"children"===m?"string"!==typeof k&&"number"!==typeof k||(e=e||[]).push(m,""+k):"suppressContentEditableWarning"!==m&&"suppressHydrationWarning"!==m&&($b.hasOwnProperty(m)?(null!=k&&"onScroll"===m&&B("scroll",a),e||h===k||(e=[])):(e=e||[]).push(m,k))}c&&(e=e||[]).push("style",c);var m=e;if(b.updateQueue=m)b.flags|=4}};var Bk=function(a,
|
||||
b,c,d){c!==d&&(b.flags|=4)};var Jd=!1,X=!1,Gk="function"===typeof WeakSet?WeakSet:Set,l=null,Ai=!1,T=null,za=!1,Nk=Math.ceil,Od=Sa.ReactCurrentDispatcher,Uf=Sa.ReactCurrentOwner,ca=Sa.ReactCurrentBatchConfig,p=0,O=null,I=null,U=0,ba=0,Ga=bb(0),L=0,Jc=null,ra=0,Md=0,Sf=0,Kc=null,ja=null,Of=0,Hf=Infinity,Ra=null,Ed=!1,xf=null,ib=null,Pd=!1,lb=null,Qd=0,Ic=0,Pf=null,Kd=-1,Ld=0;var Rk=function(a,b,c){if(null!==a)if(a.memoizedProps!==b.pendingProps||S.current)ha=!0;else{if(0===(a.lanes&c)&&0===(b.flags&
|
||||
128))return ha=!1,xk(a,b,c);ha=0!==(a.flags&131072)?!0:!1}else ha=!1,D&&0!==(b.flags&1048576)&&yh(b,nd,b.index);b.lanes=0;switch(b.tag){case 2:var d=b.type;Fd(a,b);a=b.pendingProps;var e=Nb(b,J.current);Sb(b,c);e=of(null,b,d,a,e,c);var f=pf();b.flags|=1;"object"===typeof e&&null!==e&&"function"===typeof e.render&&void 0===e.$$typeof?(b.tag=1,b.memoizedState=null,b.updateQueue=null,ea(d)?(f=!0,ld(b)):f=!1,b.memoizedState=null!==e.state&&void 0!==e.state?e.state:null,df(b),e.updater=ud,b.stateNode=
|
||||
e,e._reactInternals=b,ff(b,d,a,c),b=Af(null,b,d,!0,f,c)):(b.tag=0,D&&f&&Ue(b),aa(null,b,e,c),b=b.child);return b;case 16:d=b.elementType;a:{Fd(a,b);a=b.pendingProps;e=d._init;d=e(d._payload);b.type=d;e=b.tag=Vk(d);a=xa(d,a);switch(e){case 0:b=zf(null,b,d,a,c);break a;case 1:b=si(null,b,d,a,c);break a;case 11:b=ni(null,b,d,a,c);break a;case 14:b=oi(null,b,d,xa(d.type,a),c);break a}throw Error(n(306,d,""));}return b;case 0:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:xa(d,e),zf(a,b,d,e,c);
|
||||
case 1:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:xa(d,e),si(a,b,d,e,c);case 3:a:{ti(b);if(null===a)throw Error(n(387));d=b.pendingProps;f=b.memoizedState;e=f.element;Dh(a,b);td(b,d,null,c);var g=b.memoizedState;d=g.element;if(f.isDehydrated)if(f={element:d,isDehydrated:!1,cache:g.cache,pendingSuspenseBoundaries:g.pendingSuspenseBoundaries,transitions:g.transitions},b.updateQueue.baseState=f,b.memoizedState=f,b.flags&256){e=Ub(Error(n(423)),b);b=ui(a,b,d,c,e);break a}else if(d!==e){e=
|
||||
Ub(Error(n(424)),b);b=ui(a,b,d,c,e);break a}else for(fa=Ka(b.stateNode.containerInfo.firstChild),la=b,D=!0,wa=null,c=mi(b,null,d,c),b.child=c;c;)c.flags=c.flags&-3|4096,c=c.sibling;else{Qb();if(d===e){b=Qa(a,b,c);break a}aa(a,b,d,c)}b=b.child}return b;case 5:return Mh(b),null===a&&Xe(b),d=b.type,e=b.pendingProps,f=null!==a?a.memoizedProps:null,g=e.children,Qe(d,e)?g=null:null!==f&&Qe(d,f)&&(b.flags|=32),ri(a,b),aa(a,b,g,c),b.child;case 6:return null===a&&Xe(b),null;case 13:return vi(a,b,c);case 4:return jf(b,
|
||||
b.stateNode.containerInfo),d=b.pendingProps,null===a?b.child=Vb(b,null,d,c):aa(a,b,d,c),b.child;case 11:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:xa(d,e),ni(a,b,d,e,c);case 7:return aa(a,b,b.pendingProps,c),b.child;case 8:return aa(a,b,b.pendingProps.children,c),b.child;case 12:return aa(a,b,b.pendingProps.children,c),b.child;case 10:a:{d=b.type._context;e=b.pendingProps;f=b.memoizedProps;g=e.value;y(rd,d._currentValue);d._currentValue=g;if(null!==f)if(ua(f.value,g)){if(f.children===
|
||||
e.children&&!S.current){b=Qa(a,b,c);break a}}else for(f=b.child,null!==f&&(f.return=b);null!==f;){var h=f.dependencies;if(null!==h){g=f.child;for(var k=h.firstContext;null!==k;){if(k.context===d){if(1===f.tag){k=Pa(-1,c&-c);k.tag=2;var m=f.updateQueue;if(null!==m){m=m.shared;var l=m.pending;null===l?k.next=k:(k.next=l.next,l.next=k);m.pending=k}}f.lanes|=c;k=f.alternate;null!==k&&(k.lanes|=c);bf(f.return,c,b);h.lanes|=c;break}k=k.next}}else if(10===f.tag)g=f.type===b.type?null:f.child;else if(18===
|
||||
f.tag){g=f.return;if(null===g)throw Error(n(341));g.lanes|=c;h=g.alternate;null!==h&&(h.lanes|=c);bf(g,c,b);g=f.sibling}else g=f.child;if(null!==g)g.return=f;else for(g=f;null!==g;){if(g===b){g=null;break}f=g.sibling;if(null!==f){f.return=g.return;g=f;break}g=g.return}f=g}aa(a,b,e.children,c);b=b.child}return b;case 9:return e=b.type,d=b.pendingProps.children,Sb(b,c),e=qa(e),d=d(e),b.flags|=1,aa(a,b,d,c),b.child;case 14:return d=b.type,e=xa(d,b.pendingProps),e=xa(d.type,e),oi(a,b,d,e,c);case 15:return pi(a,
|
||||
b,b.type,b.pendingProps,c);case 17:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:xa(d,e),Fd(a,b),b.tag=1,ea(d)?(a=!0,ld(b)):a=!1,Sb(b,c),Hh(b,d,e),ff(b,d,e,c),Af(null,b,d,!0,a,c);case 19:return xi(a,b,c);case 22:return qi(a,b,c)}throw Error(n(156,b.tag));};var pa=function(a,b,c,d){return new Uk(a,b,c,d)},bj="function"===typeof reportError?reportError:function(a){console.error(a)};Ud.prototype.render=Xf.prototype.render=function(a){var b=this._internalRoot;if(null===b)throw Error(n(409));
|
||||
Sd(a,b,null,null)};Ud.prototype.unmount=Xf.prototype.unmount=function(){var a=this._internalRoot;if(null!==a){this._internalRoot=null;var b=a.containerInfo;zb(function(){Sd(null,a,null,null)});b[Ja]=null}};Ud.prototype.unstable_scheduleHydration=function(a){if(a){var b=ol();a={blockedOn:null,target:a,priority:b};for(var c=0;c<Ya.length&&0!==b&&b<Ya[c].priority;c++);Ya.splice(c,0,a);0===c&&Hg(a)}};var Dj=function(a){switch(a.tag){case 3:var b=a.stateNode;if(b.current.memoizedState.isDehydrated){var c=
|
||||
hc(b.pendingLanes);0!==c&&(xe(b,c|1),ia(b,P()),0===(p&6)&&(Hc(),db()))}break;case 13:zb(function(){var b=Oa(a,1);if(null!==b){var c=Z();ya(b,a,1,c)}}),Wf(a,1)}};var Gg=function(a){if(13===a.tag){var b=Oa(a,134217728);if(null!==b){var c=Z();ya(b,a,134217728,c)}Wf(a,134217728)}};var yj=function(a){if(13===a.tag){var b=hb(a),c=Oa(a,b);if(null!==c){var d=Z();ya(c,a,b,d)}Wf(a,b)}};var ol=function(){return z};var xj=function(a,b){var c=z;try{return z=a,b()}finally{z=c}};se=function(a,b,c){switch(b){case "input":le(a,
|
||||
c);b=c.name;if("radio"===c.type&&null!=b){for(c=a;c.parentNode;)c=c.parentNode;c=c.querySelectorAll("input[name="+JSON.stringify(""+b)+'][type="radio"]');for(b=0;b<c.length;b++){var d=c[b];if(d!==a&&d.form===a.form){var e=Rc(d);if(!e)throw Error(n(90));jg(d);le(d,e)}}}break;case "textarea":og(a,c);break;case "select":b=c.value,null!=b&&Db(a,!!c.multiple,b,!1)}};(function(a,b,c){xg=a;yg=c})(Tf,function(a,b,c,d,e){var f=z,g=ca.transition;try{return ca.transition=null,z=1,a(b,c,d,e)}finally{z=f,ca.transition=
|
||||
g,0===p&&Hc()}},zb);var pl={usingClientEntryPoint:!1,Events:[ec,Ib,Rc,ug,vg,Tf]};(function(a){a={bundleType:a.bundleType,version:a.version,rendererPackageName:a.rendererPackageName,rendererConfig:a.rendererConfig,overrideHookState:null,overrideHookStateDeletePath:null,overrideHookStateRenamePath:null,overrideProps:null,overridePropsDeletePath:null,overridePropsRenamePath:null,setErrorHandler:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:Sa.ReactCurrentDispatcher,findHostInstanceByFiber:Yk,
|
||||
findFiberByHostInstance:a.findFiberByHostInstance||Zk,findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null,reconcilerVersion:"18.2.0"};if("undefined"===typeof __REACT_DEVTOOLS_GLOBAL_HOOK__)a=!1;else{var b=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(b.isDisabled||!b.supportsFiber)a=!0;else{try{Uc=b.inject(a),Ca=b}catch(c){}a=b.checkDCE?!0:!1}}return a})({findFiberByHostInstance:pb,bundleType:0,version:"18.2.0-next-9e3b772b8-20220608",
|
||||
rendererPackageName:"react-dom"});Q.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=pl;Q.createPortal=function(a,b){var c=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null;if(!Yf(b))throw Error(n(200));return Xk(a,b,null,c)};Q.createRoot=function(a,b){if(!Yf(a))throw Error(n(299));var c=!1,d="",e=bj;null!==b&&void 0!==b&&(!0===b.unstable_strictMode&&(c=!0),void 0!==b.identifierPrefix&&(d=b.identifierPrefix),void 0!==b.onRecoverableError&&(e=b.onRecoverableError));b=Vf(a,1,!1,null,null,
|
||||
c,!1,d,e);a[Ja]=b.current;sc(8===a.nodeType?a.parentNode:a);return new Xf(b)};Q.findDOMNode=function(a){if(null==a)return null;if(1===a.nodeType)return a;var b=a._reactInternals;if(void 0===b){if("function"===typeof a.render)throw Error(n(188));a=Object.keys(a).join(",");throw Error(n(268,a));}a=Bg(b);a=null===a?null:a.stateNode;return a};Q.flushSync=function(a){return zb(a)};Q.hydrate=function(a,b,c){if(!Vd(b))throw Error(n(200));return Wd(null,a,b,!0,c)};Q.hydrateRoot=function(a,b,c){if(!Yf(a))throw Error(n(405));
|
||||
var d=null!=c&&c.hydratedSources||null,e=!1,f="",g=bj;null!==c&&void 0!==c&&(!0===c.unstable_strictMode&&(e=!0),void 0!==c.identifierPrefix&&(f=c.identifierPrefix),void 0!==c.onRecoverableError&&(g=c.onRecoverableError));b=Xi(b,null,a,1,null!=c?c:null,e,!1,f,g);a[Ja]=b.current;sc(a);if(d)for(a=0;a<d.length;a++)c=d[a],e=c._getVersion,e=e(c._source),null==b.mutableSourceEagerHydrationData?b.mutableSourceEagerHydrationData=[c,e]:b.mutableSourceEagerHydrationData.push(c,e);return new Ud(b)};Q.render=
|
||||
function(a,b,c){if(!Vd(b))throw Error(n(200));return Wd(null,a,b,!1,c)};Q.unmountComponentAtNode=function(a){if(!Vd(a))throw Error(n(40));return a._reactRootContainer?(zb(function(){Wd(null,null,a,!1,function(){a._reactRootContainer=null;a[Ja]=null})}),!0):!1};Q.unstable_batchedUpdates=Tf;Q.unstable_renderSubtreeIntoContainer=function(a,b,c,d){if(!Vd(c))throw Error(n(200));if(null==a||void 0===a._reactInternals)throw Error(n(38));return Wd(a,b,c,!1,d)};Q.version="18.2.0-next-9e3b772b8-20220608"});
|
||||
})();
|
||||
+3343
File diff suppressed because it is too large
Load Diff
+31
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* @license React
|
||||
* react.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
(function(){'use strict';(function(c,x){"object"===typeof exports&&"undefined"!==typeof module?x(exports):"function"===typeof define&&define.amd?define(["exports"],x):(c=c||self,x(c.React={}))})(this,function(c){function x(a){if(null===a||"object"!==typeof a)return null;a=V&&a[V]||a["@@iterator"];return"function"===typeof a?a:null}function w(a,b,e){this.props=a;this.context=b;this.refs=W;this.updater=e||X}function Y(){}function K(a,b,e){this.props=a;this.context=b;this.refs=W;this.updater=e||X}function Z(a,b,
|
||||
e){var m,d={},c=null,h=null;if(null!=b)for(m in void 0!==b.ref&&(h=b.ref),void 0!==b.key&&(c=""+b.key),b)aa.call(b,m)&&!ba.hasOwnProperty(m)&&(d[m]=b[m]);var l=arguments.length-2;if(1===l)d.children=e;else if(1<l){for(var f=Array(l),k=0;k<l;k++)f[k]=arguments[k+2];d.children=f}if(a&&a.defaultProps)for(m in l=a.defaultProps,l)void 0===d[m]&&(d[m]=l[m]);return{$$typeof:y,type:a,key:c,ref:h,props:d,_owner:L.current}}function na(a,b){return{$$typeof:y,type:a.type,key:b,ref:a.ref,props:a.props,_owner:a._owner}}
|
||||
function M(a){return"object"===typeof a&&null!==a&&a.$$typeof===y}function oa(a){var b={"=":"=0",":":"=2"};return"$"+a.replace(/[=:]/g,function(a){return b[a]})}function N(a,b){return"object"===typeof a&&null!==a&&null!=a.key?oa(""+a.key):b.toString(36)}function B(a,b,e,m,d){var c=typeof a;if("undefined"===c||"boolean"===c)a=null;var h=!1;if(null===a)h=!0;else switch(c){case "string":case "number":h=!0;break;case "object":switch(a.$$typeof){case y:case pa:h=!0}}if(h)return h=a,d=d(h),a=""===m?"."+
|
||||
N(h,0):m,ca(d)?(e="",null!=a&&(e=a.replace(da,"$&/")+"/"),B(d,b,e,"",function(a){return a})):null!=d&&(M(d)&&(d=na(d,e+(!d.key||h&&h.key===d.key?"":(""+d.key).replace(da,"$&/")+"/")+a)),b.push(d)),1;h=0;m=""===m?".":m+":";if(ca(a))for(var l=0;l<a.length;l++){c=a[l];var f=m+N(c,l);h+=B(c,b,e,f,d)}else if(f=x(a),"function"===typeof f)for(a=f.call(a),l=0;!(c=a.next()).done;)c=c.value,f=m+N(c,l++),h+=B(c,b,e,f,d);else if("object"===c)throw b=String(a),Error("Objects are not valid as a React child (found: "+
|
||||
("[object Object]"===b?"object with keys {"+Object.keys(a).join(", ")+"}":b)+"). If you meant to render a collection of children, use an array instead.");return h}function C(a,b,e){if(null==a)return a;var c=[],d=0;B(a,c,"","",function(a){return b.call(e,a,d++)});return c}function qa(a){if(-1===a._status){var b=a._result;b=b();b.then(function(b){if(0===a._status||-1===a._status)a._status=1,a._result=b},function(b){if(0===a._status||-1===a._status)a._status=2,a._result=b});-1===a._status&&(a._status=
|
||||
0,a._result=b)}if(1===a._status)return a._result.default;throw a._result;}function O(a,b){var e=a.length;a.push(b);a:for(;0<e;){var c=e-1>>>1,d=a[c];if(0<D(d,b))a[c]=b,a[e]=d,e=c;else break a}}function p(a){return 0===a.length?null:a[0]}function E(a){if(0===a.length)return null;var b=a[0],e=a.pop();if(e!==b){a[0]=e;a:for(var c=0,d=a.length,k=d>>>1;c<k;){var h=2*(c+1)-1,l=a[h],f=h+1,g=a[f];if(0>D(l,e))f<d&&0>D(g,l)?(a[c]=g,a[f]=e,c=f):(a[c]=l,a[h]=e,c=h);else if(f<d&&0>D(g,e))a[c]=g,a[f]=e,c=f;else break a}}return b}
|
||||
function D(a,b){var c=a.sortIndex-b.sortIndex;return 0!==c?c:a.id-b.id}function P(a){for(var b=p(r);null!==b;){if(null===b.callback)E(r);else if(b.startTime<=a)E(r),b.sortIndex=b.expirationTime,O(q,b);else break;b=p(r)}}function Q(a){z=!1;P(a);if(!u)if(null!==p(q))u=!0,R(S);else{var b=p(r);null!==b&&T(Q,b.startTime-a)}}function S(a,b){u=!1;z&&(z=!1,ea(A),A=-1);F=!0;var c=k;try{P(b);for(n=p(q);null!==n&&(!(n.expirationTime>b)||a&&!fa());){var m=n.callback;if("function"===typeof m){n.callback=null;
|
||||
k=n.priorityLevel;var d=m(n.expirationTime<=b);b=v();"function"===typeof d?n.callback=d:n===p(q)&&E(q);P(b)}else E(q);n=p(q)}if(null!==n)var g=!0;else{var h=p(r);null!==h&&T(Q,h.startTime-b);g=!1}return g}finally{n=null,k=c,F=!1}}function fa(){return v()-ha<ia?!1:!0}function R(a){G=a;H||(H=!0,I())}function T(a,b){A=ja(function(){a(v())},b)}var y=Symbol.for("react.element"),pa=Symbol.for("react.portal"),ra=Symbol.for("react.fragment"),sa=Symbol.for("react.strict_mode"),ta=Symbol.for("react.profiler"),
|
||||
ua=Symbol.for("react.provider"),va=Symbol.for("react.context"),wa=Symbol.for("react.forward_ref"),xa=Symbol.for("react.suspense"),ya=Symbol.for("react.memo"),za=Symbol.for("react.lazy"),V=Symbol.iterator,X={isMounted:function(a){return!1},enqueueForceUpdate:function(a,b,c){},enqueueReplaceState:function(a,b,c,m){},enqueueSetState:function(a,b,c,m){}},ka=Object.assign,W={};w.prototype.isReactComponent={};w.prototype.setState=function(a,b){if("object"!==typeof a&&"function"!==typeof a&&null!=a)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");
|
||||
this.updater.enqueueSetState(this,a,b,"setState")};w.prototype.forceUpdate=function(a){this.updater.enqueueForceUpdate(this,a,"forceUpdate")};Y.prototype=w.prototype;var t=K.prototype=new Y;t.constructor=K;ka(t,w.prototype);t.isPureReactComponent=!0;var ca=Array.isArray,aa=Object.prototype.hasOwnProperty,L={current:null},ba={key:!0,ref:!0,__self:!0,__source:!0},da=/\/+/g,g={current:null},J={transition:null};if("object"===typeof performance&&"function"===typeof performance.now){var Aa=performance;
|
||||
var v=function(){return Aa.now()}}else{var la=Date,Ba=la.now();v=function(){return la.now()-Ba}}var q=[],r=[],Ca=1,n=null,k=3,F=!1,u=!1,z=!1,ja="function"===typeof setTimeout?setTimeout:null,ea="function"===typeof clearTimeout?clearTimeout:null,ma="undefined"!==typeof setImmediate?setImmediate:null;"undefined"!==typeof navigator&&void 0!==navigator.scheduling&&void 0!==navigator.scheduling.isInputPending&&navigator.scheduling.isInputPending.bind(navigator.scheduling);var H=!1,G=null,A=-1,ia=5,ha=
|
||||
-1,U=function(){if(null!==G){var a=v();ha=a;var b=!0;try{b=G(!0,a)}finally{b?I():(H=!1,G=null)}}else H=!1};if("function"===typeof ma)var I=function(){ma(U)};else if("undefined"!==typeof MessageChannel){t=new MessageChannel;var Da=t.port2;t.port1.onmessage=U;I=function(){Da.postMessage(null)}}else I=function(){ja(U,0)};t={ReactCurrentDispatcher:g,ReactCurrentOwner:L,ReactCurrentBatchConfig:J,Scheduler:{__proto__:null,unstable_ImmediatePriority:1,unstable_UserBlockingPriority:2,unstable_NormalPriority:3,
|
||||
unstable_IdlePriority:5,unstable_LowPriority:4,unstable_runWithPriority:function(a,b){switch(a){case 1:case 2:case 3:case 4:case 5:break;default:a=3}var c=k;k=a;try{return b()}finally{k=c}},unstable_next:function(a){switch(k){case 1:case 2:case 3:var b=3;break;default:b=k}var c=k;k=b;try{return a()}finally{k=c}},unstable_scheduleCallback:function(a,b,c){var e=v();"object"===typeof c&&null!==c?(c=c.delay,c="number"===typeof c&&0<c?e+c:e):c=e;switch(a){case 1:var d=-1;break;case 2:d=250;break;case 5:d=
|
||||
1073741823;break;case 4:d=1E4;break;default:d=5E3}d=c+d;a={id:Ca++,callback:b,priorityLevel:a,startTime:c,expirationTime:d,sortIndex:-1};c>e?(a.sortIndex=c,O(r,a),null===p(q)&&a===p(r)&&(z?(ea(A),A=-1):z=!0,T(Q,c-e))):(a.sortIndex=d,O(q,a),u||F||(u=!0,R(S)));return a},unstable_cancelCallback:function(a){a.callback=null},unstable_wrapCallback:function(a){var b=k;return function(){var c=k;k=b;try{return a.apply(this,arguments)}finally{k=c}}},unstable_getCurrentPriorityLevel:function(){return k},unstable_shouldYield:fa,
|
||||
unstable_requestPaint:function(){},unstable_continueExecution:function(){u||F||(u=!0,R(S))},unstable_pauseExecution:function(){},unstable_getFirstCallbackNode:function(){return p(q)},get unstable_now(){return v},unstable_forceFrameRate:function(a){0>a||125<a?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):ia=0<a?Math.floor(1E3/a):5},unstable_Profiling:null}};c.Children={map:C,forEach:function(a,b,c){C(a,function(){b.apply(this,
|
||||
arguments)},c)},count:function(a){var b=0;C(a,function(){b++});return b},toArray:function(a){return C(a,function(a){return a})||[]},only:function(a){if(!M(a))throw Error("React.Children.only expected to receive a single React element child.");return a}};c.Component=w;c.Fragment=ra;c.Profiler=ta;c.PureComponent=K;c.StrictMode=sa;c.Suspense=xa;c.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=t;c.cloneElement=function(a,b,c){if(null===a||void 0===a)throw Error("React.cloneElement(...): The argument must be a React element, but you passed "+
|
||||
a+".");var e=ka({},a.props),d=a.key,k=a.ref,h=a._owner;if(null!=b){void 0!==b.ref&&(k=b.ref,h=L.current);void 0!==b.key&&(d=""+b.key);if(a.type&&a.type.defaultProps)var l=a.type.defaultProps;for(f in b)aa.call(b,f)&&!ba.hasOwnProperty(f)&&(e[f]=void 0===b[f]&&void 0!==l?l[f]:b[f])}var f=arguments.length-2;if(1===f)e.children=c;else if(1<f){l=Array(f);for(var g=0;g<f;g++)l[g]=arguments[g+2];e.children=l}return{$$typeof:y,type:a.type,key:d,ref:k,props:e,_owner:h}};c.createContext=function(a){a={$$typeof:va,
|
||||
_currentValue:a,_currentValue2:a,_threadCount:0,Provider:null,Consumer:null,_defaultValue:null,_globalName:null};a.Provider={$$typeof:ua,_context:a};return a.Consumer=a};c.createElement=Z;c.createFactory=function(a){var b=Z.bind(null,a);b.type=a;return b};c.createRef=function(){return{current:null}};c.forwardRef=function(a){return{$$typeof:wa,render:a}};c.isValidElement=M;c.lazy=function(a){return{$$typeof:za,_payload:{_status:-1,_result:a},_init:qa}};c.memo=function(a,b){return{$$typeof:ya,type:a,
|
||||
compare:void 0===b?null:b}};c.startTransition=function(a,b){b=J.transition;J.transition={};try{a()}finally{J.transition=b}};c.unstable_act=function(a){throw Error("act(...) is not supported in production builds of React.");};c.useCallback=function(a,b){return g.current.useCallback(a,b)};c.useContext=function(a){return g.current.useContext(a)};c.useDebugValue=function(a,b){};c.useDeferredValue=function(a){return g.current.useDeferredValue(a)};c.useEffect=function(a,b){return g.current.useEffect(a,
|
||||
b)};c.useId=function(){return g.current.useId()};c.useImperativeHandle=function(a,b,c){return g.current.useImperativeHandle(a,b,c)};c.useInsertionEffect=function(a,b){return g.current.useInsertionEffect(a,b)};c.useLayoutEffect=function(a,b){return g.current.useLayoutEffect(a,b)};c.useMemo=function(a,b){return g.current.useMemo(a,b)};c.useReducer=function(a,b,c){return g.current.useReducer(a,b,c)};c.useRef=function(a){return g.current.useRef(a)};c.useState=function(a){return g.current.useState(a)};
|
||||
c.useSyncExternalStore=function(a,b,c){return g.current.useSyncExternalStore(a,b,c)};c.useTransition=function(){return g.current.useTransition()};c.version="18.2.0"});
|
||||
})();
|
||||
+83
File diff suppressed because one or more lines are too long
@@ -6,13 +6,13 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>SonicForge Studio - Professional DAW Editor</title>
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<script src="/static/js/vendor/tailwindcss-cdn.js"></script>
|
||||
<script src="/static/js/vendor/lucide.min.js"></script>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css" crossorigin="anonymous" referrerpolicy="no-referrer">
|
||||
<script src="https://unpkg.com/react@18.3.1/umd/react.production.min.js"></script>
|
||||
<script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.production.min.js"></script>
|
||||
<script src="/static/js/vendor/react.production.min.js"></script>
|
||||
<script src="/static/js/vendor/react-dom.production.min.js"></script>
|
||||
<script src="/static/js/services/fluidsynthLoader.js?v=202607271245"></script>
|
||||
<script src="/static/js/services/api.js?v=202607271016"></script>
|
||||
<script src="/static/js/services/api.js?v=202608080950"></script>
|
||||
<script src="/static/js/services/audioEngine.js?v=202607271016"></script>
|
||||
<script src="/static/js/services/storage.js?v=202608038200"></script>
|
||||
<script src="/static/js/services/soundfontStorage.js?v=202607271016"></script>
|
||||
@@ -24,7 +24,7 @@
|
||||
<script src="/static/js/services/midiExtractor.js?v=202607281052"></script>
|
||||
<script src="/static/js/services/promptTemplateManager.js?v=202607281039"></script>
|
||||
<script src="/static/js/services/undoRedoEngine.js?v=202607290941"></script>
|
||||
<script src="/static/js/app.precompiled.js?v=202608070950" defer></script>
|
||||
<script src="/static/js/app.precompiled.js?v=202608081555" defer></script>
|
||||
<link rel="stylesheet" href="/static/css/styles.css?v=202607271016">
|
||||
<style>
|
||||
:root {
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
@echo off
|
||||
REM SonicForge DAW - Windows build (daw_engine.exe + Tauri shell)
|
||||
setlocal enabledelayedexpansion
|
||||
cd /d "%~dp0"
|
||||
|
||||
echo [1/6] Kiem tra Python + Node...
|
||||
python --version
|
||||
if errorlevel 1 (
|
||||
echo THIEU Python 3.11+ - cai tu python.org, tick Add to PATH
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
node --version
|
||||
if errorlevel 1 (
|
||||
echo THIEU Node 20+ - cai tu nodejs.org
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
echo [2/6] Kiem tra / cai Rust toolchain...
|
||||
where cargo >nul 2>nul
|
||||
if errorlevel 1 (
|
||||
echo Cai Rust qua rustup MSVC toolchain...
|
||||
powershell -Command "Invoke-WebRequest https://win.rustup.rs/x86_64 -OutFile rustup-init.exe"
|
||||
rustup-init.exe -y --default-toolchain stable --profile minimal
|
||||
del rustup-init.exe
|
||||
set "PATH=%USERPROFILE%\.cargo\bin;%PATH%"
|
||||
)
|
||||
cargo --version
|
||||
if errorlevel 1 (
|
||||
echo Rust cai that bai - can Visual Studio Build Tools voi C++ workload
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
echo [3/6] Cai Python deps...
|
||||
pip install pyinstaller pywin32
|
||||
if errorlevel 1 exit /b 1
|
||||
pip install -r requirements.txt
|
||||
if errorlevel 1 exit /b 1
|
||||
pip install --no-deps "pedalboard>=0.8.0"
|
||||
|
||||
echo [4/6] Precompile JS...
|
||||
npm install --no-audit --no-fund
|
||||
if errorlevel 1 (
|
||||
echo FAIL: npm install that bai - kiem tra internet / package.json
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
echo - npm OK, kiem tra babel...
|
||||
if not exist "node_modules\@babel\cli\bin\babel.js" (
|
||||
echo FAIL: thieu node_modules\@babel\cli\bin\babel.js - npm install khong hoan tat
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
echo - chay Babel...
|
||||
node node_modules/@babel/cli/bin/babel.js app/static/js/app.jsx --config-file ./babel.config.json -o app/static/js/app.precompiled.js
|
||||
if errorlevel 1 (
|
||||
echo FAIL: Babel precompile that bai - xem loi phia tren
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
echo - Babel OK
|
||||
|
||||
echo [5/6] Build daw_engine.exe...
|
||||
pyinstaller engine.spec --clean --noconfirm
|
||||
if errorlevel 1 exit /b 1
|
||||
if not exist "src-tauri\binaries" mkdir "src-tauri\binaries"
|
||||
copy /y dist\daw_engine.exe "src-tauri\binaries\daw_engine-x86_64-pc-windows-msvc.exe" >nul
|
||||
|
||||
echo [6/6] Build Tauri installer...
|
||||
taskkill /F /T /IM daw_engine.exe >nul 2>nul
|
||||
npm install -D @tauri-apps/cli@^2
|
||||
if errorlevel 1 (
|
||||
echo npm install tauri-cli that bai
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
call npx tauri build
|
||||
|
||||
echo.
|
||||
echo HOAN TAT - Installer:
|
||||
echo src-tauri\target\release\bundle\nsis\SonicForgeDAW_1.0.0_x64-setup.exe
|
||||
echo src-tauri\target\release\bundle\msi\SonicForgeDAW_1.0.0_x64_en-US.msi
|
||||
pause
|
||||
@@ -0,0 +1,55 @@
|
||||
# ── Production compose — KHÔNG mount source, image từ registry, bí mật qua .env ──
|
||||
# Dùng: docker compose -f docker-compose.prod.yml up -d
|
||||
services:
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
restart: unless-stopped
|
||||
|
||||
web:
|
||||
build: .
|
||||
image: ${IMAGE:-sonicforge-studio:latest}
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "${WEB_PORT:-8000}:8000"
|
||||
env_file: .env
|
||||
volumes:
|
||||
- sf_data:/app/app/storage
|
||||
- ${VST3_DIR:-./vst_plugins}:/opt/daw_engine/vst3:ro
|
||||
- ${SOUNDFONTS_DIR:-./soundfonts}:/opt/daw_engine/soundfonts:ro
|
||||
- ${PIANOBOOK_DIR:-./samples/pianobook}:/opt/daw_engine/samples/pianobook:ro
|
||||
healthcheck:
|
||||
test: ["CMD", "python", "-c", "import urllib.request;urllib.request.urlopen('http://localhost:8000/health')"]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 15s
|
||||
depends_on:
|
||||
- redis
|
||||
|
||||
worker:
|
||||
build: .
|
||||
image: ${IMAGE:-sonicforge-studio:latest}
|
||||
restart: unless-stopped
|
||||
command: celery -A app.tasks.worker.celery_app worker --loglevel=info
|
||||
env_file: .env
|
||||
volumes:
|
||||
- sf_data:/app/app/storage
|
||||
- ${VST3_DIR:-./vst_plugins}:/opt/daw_engine/vst3:ro
|
||||
- ${SOUNDFONTS_DIR:-./soundfonts}:/opt/daw_engine/soundfonts:ro
|
||||
- ${PIANOBOOK_DIR:-./samples/pianobook}:/opt/daw_engine/samples/pianobook:ro
|
||||
depends_on:
|
||||
- redis
|
||||
|
||||
beat:
|
||||
build: .
|
||||
image: ${IMAGE:-sonicforge-studio:latest}
|
||||
restart: unless-stopped
|
||||
command: celery -A app.tasks.worker.celery_app beat --loglevel=info
|
||||
env_file: .env
|
||||
volumes:
|
||||
- sf_data:/app/app/storage
|
||||
depends_on:
|
||||
- redis
|
||||
|
||||
volumes:
|
||||
sf_data:
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
# engine.spec — PyInstaller config (spec desktop 2026-08-08 — daw_engine.exe)
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
import os
|
||||
from PyInstaller.utils.hooks import collect_dynamic_libs, collect_data_files
|
||||
|
||||
block_cipher = None
|
||||
|
||||
# Collect native DLL files for pedalboard and soundfile
|
||||
binaries = collect_dynamic_libs('pedalboard')
|
||||
binaries += collect_dynamic_libs('soundfile')
|
||||
binaries += collect_dynamic_libs('fluidsynth')
|
||||
|
||||
# Collect configuration files and default soundfont catalogs
|
||||
datas = [
|
||||
('app/storage', 'app/storage'),
|
||||
('app/static', 'app/static'),
|
||||
('app/templates', 'app/templates'),
|
||||
]
|
||||
|
||||
a = Analysis(
|
||||
['main.py'],
|
||||
pathex=[],
|
||||
binaries=binaries,
|
||||
datas=datas,
|
||||
hiddenimports=[
|
||||
'uvicorn.logging',
|
||||
'uvicorn.loops',
|
||||
'uvicorn.loops.auto',
|
||||
'uvicorn.protocols',
|
||||
'uvicorn.protocols.http',
|
||||
'uvicorn.protocols.http.auto',
|
||||
'uvicorn.protocols.websockets',
|
||||
'uvicorn.protocols.websockets.auto',
|
||||
'pedalboard',
|
||||
'soundfile',
|
||||
'sf2utils',
|
||||
'mido.backends.rtmidi',
|
||||
'app.main',
|
||||
'app.config',
|
||||
'app.api.v1.desktop_plugins',
|
||||
'app.core.vst_scanner',
|
||||
'app.core.soundfont_scanner',
|
||||
# Celery dynamic imports (PyInstaller không bắt được — 2026-08-08)
|
||||
'celery.fixups',
|
||||
'celery.fixups.django',
|
||||
'celery.backends',
|
||||
'celery.backends.redis',
|
||||
'celery.schedules',
|
||||
'celery.app.builtins',
|
||||
'kombu.transport.redis',
|
||||
'billiard',
|
||||
'vine',
|
||||
'redis',
|
||||
],
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
win_no_prefer_redirects=False,
|
||||
win_private_assemblies=False,
|
||||
cipher=block_cipher,
|
||||
noarchive=False,
|
||||
)
|
||||
|
||||
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
|
||||
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.zipfiles,
|
||||
a.datas,
|
||||
[],
|
||||
name='daw_engine',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
runtime_tmpdir=None,
|
||||
console=False, # Set to True for Debugging, False for Production
|
||||
)
|
||||
@@ -0,0 +1,35 @@
|
||||
"""Entry point cho daw_engine.exe (PyInstaller — spec desktop 2026-08-08).
|
||||
Chạy FastAPI backend trên 127.0.0.1:8000 (Dual-Process Desktop Architecture).
|
||||
KHÔNG tự mở browser — Tauri shell (window url=localhost:8000) đảm nhiệm.
|
||||
SINGLE-INSTANCE: nếu port 8000 đã có server → EXIT ngay (bug 09:55 — mỗi lần mở
|
||||
app spawn thêm daw_engine → nhiều instance + port chiếm → màn đen)."""
|
||||
import os
|
||||
import socket
|
||||
import sys
|
||||
|
||||
os.environ.setdefault("SFDATA_DIR", os.path.join(os.path.expanduser("~"), "SonicForgeDAW"))
|
||||
|
||||
import uvicorn # noqa: E402
|
||||
|
||||
PORT = 8000
|
||||
|
||||
|
||||
def _port_in_use(port: int) -> bool:
|
||||
try:
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
try:
|
||||
s.bind(("127.0.0.1", port))
|
||||
return False
|
||||
except OSError:
|
||||
return True
|
||||
finally:
|
||||
s.close()
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if _port_in_use(PORT):
|
||||
# Server đang chạy (instance khác — window sẽ dùng nó). KHÔNG spawn thêm.
|
||||
sys.exit(0)
|
||||
uvicorn.run("app.main:app", host="127.0.0.1", port=PORT, log_level="warning")
|
||||
+3
-2
@@ -5,13 +5,14 @@ redis>=4.6.0
|
||||
python-multipart>=0.0.6
|
||||
librosa>=0.10.0
|
||||
pydub>=0.25.1
|
||||
numpy>=1.24.0
|
||||
numpy>=1.24.0,<2.0
|
||||
scipy>=1.10.0
|
||||
soundfile>=0.12.1
|
||||
jinja2>=3.1.2
|
||||
httpx>=0.24.0
|
||||
jsonschema>=4.18.0
|
||||
pedalboard>=0.8.0
|
||||
# pedalboard cài RIÊNG với --no-deps (tránh supertonic — kéo onnx2tf/opencv/pocket-tts
|
||||
# xung đột numpy<2 vs >=2 — dự án không dùng supertonic — 2026-08-08)
|
||||
mido>=1.3.0
|
||||
pyfluidsynth>=1.3.0
|
||||
sf2utils>=0.9.0
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
[package]
|
||||
name = "sonicforge-daw"
|
||||
version = "1.0.0"
|
||||
description = "Sonic Forge DAW - Desktop Studio"
|
||||
authors = ["SonicForge Studio"]
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
name = "sonicforge_daw_lib"
|
||||
crate-type = ["staticlib", "cdylib", "rlib"]
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { version = "2", features = [] }
|
||||
|
||||
[dependencies]
|
||||
tauri = { version = "2", features = [] }
|
||||
tauri-plugin-shell = "2"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
|
||||
[profile.release]
|
||||
codegen-units = 1
|
||||
lto = true
|
||||
opt-level = "s"
|
||||
strip = true
|
||||
@@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
tauri_build::build()
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"$schema": "../gen/schemas/desktop-schema.json",
|
||||
"identifier": "default",
|
||||
"description": "Capabilities for the main window",
|
||||
"windows": ["main"],
|
||||
"permissions": [
|
||||
"core:default",
|
||||
"shell:allow-spawn",
|
||||
"shell:allow-open"
|
||||
]
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 4.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 957 B |
Binary file not shown.
|
After Width: | Height: | Size: 4.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.6 KiB |
@@ -0,0 +1,40 @@
|
||||
use tauri::Manager;
|
||||
use tauri_plugin_shell::ShellExt;
|
||||
use tauri_plugin_shell::process::CommandChild;
|
||||
use std::sync::Mutex;
|
||||
|
||||
struct EngineProcess(Mutex<Option<CommandChild>>);
|
||||
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
pub fn run() {
|
||||
tauri::Builder::default()
|
||||
.plugin(tauri_plugin_shell::init())
|
||||
.setup(|app| {
|
||||
// 1. Spawn sidecar daw_engine.exe (background Python engine — 127.0.0.1:8000)
|
||||
let sidecar_command = app.shell().sidecar("daw_engine").unwrap();
|
||||
let (mut _rx, child) = sidecar_command.spawn().expect("Failed to spawn daw_engine sidecar");
|
||||
|
||||
app.manage(EngineProcess(Mutex::new(Some(child))));
|
||||
println!("Python Background Engine started successfully on localhost:8000");
|
||||
Ok(())
|
||||
})
|
||||
.on_window_event(|window, event| {
|
||||
if let tauri::WindowEvent::Destroyed = event {
|
||||
// 2. Terminate sidecar khi window đóng — kill CẢ TREE (PyInstaller
|
||||
// onefile = parent + child — child.kill() chỉ giết parent → child
|
||||
// orphan chạy mãi — bug 09:30). taskkill /T giết cả nhánh.
|
||||
let state = window.state::<EngineProcess>();
|
||||
if let Ok(mut lock) = state.0.lock() {
|
||||
if let Some(child) = lock.take() {
|
||||
let _ = child.kill();
|
||||
}
|
||||
};
|
||||
let _ = std::process::Command::new("taskkill")
|
||||
.args(["/F", "/T", "/IM", "daw_engine.exe"])
|
||||
.output();
|
||||
println!("daw_engine sidecar terminated (tree killed).");
|
||||
}
|
||||
})
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
|
||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
|
||||
fn main() {
|
||||
sonicforge_daw_lib::run()
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "SonicForgeDAW",
|
||||
"version": "1.0.0",
|
||||
"identifier": "com.sonicforge.daw",
|
||||
"build": {
|
||||
"frontendDist": "../app/templates",
|
||||
"devUrl": "http://localhost:8000"
|
||||
},
|
||||
"app": {
|
||||
"windows": [
|
||||
{
|
||||
"title": "Sonic Forge DAW - Professional Desktop Studio",
|
||||
"url": "http://localhost:8000",
|
||||
"width": 1440,
|
||||
"height": 900,
|
||||
"resizable": true,
|
||||
"fullscreen": false
|
||||
}
|
||||
],
|
||||
"security": {
|
||||
"csp": null
|
||||
}
|
||||
},
|
||||
"bundle": {
|
||||
"active": true,
|
||||
"targets": ["nsis", "msi"],
|
||||
"icon": [
|
||||
"icons/32x32.png",
|
||||
"icons/128x128.png",
|
||||
"icons/icon.ico"
|
||||
],
|
||||
"externalBin": [
|
||||
"binaries/daw_engine"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import struct, zlib, os
|
||||
|
||||
def make_png(path, size):
|
||||
w = h = size
|
||||
raw = b''
|
||||
for y in range(h):
|
||||
row = b'\x00'
|
||||
for x in range(w):
|
||||
cx, cy = x - w / 2, y - h / 2
|
||||
d = (cx * cx + cy * cy) ** 0.5 / (w / 2)
|
||||
r = int(120 + 60 * (1 - d))
|
||||
g = int(60 + 40 * (1 - d))
|
||||
b = int(200 + 40 * (1 - d))
|
||||
row += bytes((r, g, b, 255))
|
||||
raw += row
|
||||
def chunk(tag, data):
|
||||
c = tag + data
|
||||
return struct.pack('>I', len(data)) + c + struct.pack('>I', zlib.crc32(c) % 0x100000000)
|
||||
png = b'\x89PNG\r\n\x1a\n'
|
||||
png += chunk(b'IHDR', struct.pack('>IIBBBBB', w, h, 8, 6, 0, 0, 0))
|
||||
png += chunk(b'IDAT', zlib.compress(raw, 9))
|
||||
png += chunk(b'IEND', b'')
|
||||
open(path, 'wb').write(png)
|
||||
|
||||
os.makedirs('src-tauri/icons', exist_ok=True)
|
||||
make_png('src-tauri/icons/32x32.png', 32)
|
||||
make_png('src-tauri/icons/128x128.png', 128)
|
||||
png128 = open('src-tauri/icons/128x128.png', 'rb').read()
|
||||
ico = struct.pack('<HHH', 0, 1, 1) + struct.pack('<BBBBHHII', 128, 128, 0, 0, 1, 32, len(png128), 22) + png128
|
||||
open('src-tauri/icons/icon.ico', 'wb').write(ico)
|
||||
open('src-tauri/icons/icon.png', 'wb').write(png128)
|
||||
print('icons:', os.listdir('src-tauri/icons'))
|
||||
@@ -2925,3 +2925,219 @@
|
||||
- **FIX (app.jsx effect follow):** `const playing = isPlaying || !!st.isPlaying` — follow khi piano roll play LẪN main play; deps thêm `st.isPlaying`.
|
||||
- **Các file ảnh hưởng:** `app/static/js/app.jsx`, `app/templates/index.html` (?v=202608070950), `wiki.md`. Rebuild precompiled (build PASS).
|
||||
- **Ghi chú/Test:** hard refresh → PIANO ROLL → play (tab) → playhead ở giữa + notes trôi trái; stop → về đầu.
|
||||
|
||||
### [2026-08-08 08:15] Task: Desktop VST3/AU — scan + Plugin Manager (branch desktop-alone, spec 2026-08-08)
|
||||
- **Checkout:** branch `desktop-alone` ✓ — cài đặt tính năng VST plugin theo spec (scan/display/assign).
|
||||
- **Backend:**
|
||||
(1) `app/core/vst_scanner.py` — `NativePluginScanner.scan_directories(paths)` — quét .vst3 (mọi OS) + .component (macOS) → {id, name, type, format, category, vendor, path, is_instrument, has_native_gui} — đọc vendor từ Info.plist (best-effort).
|
||||
(2) `app/api/v1/desktop_plugins.py` — `POST /api/v1/desktop/plugins/scan` (router prefix /api/v1/desktop — đúng spec) — nhận custom_directories/scan_formats/force_rescan → response {status, os, scanned_directories, total_found, plugins[]}; thư mục mặc định theo OS (Linux /opt/daw_engine/vst3+~/.vst3; Windows %ProgramFiles%\Common Files\VST3; macOS /Library/Audio/Plug-Ins/Components).
|
||||
(3) `app/main.py` — include desktop_plugins_router.
|
||||
- **Frontend (app.jsx):** nút "🔌 Quét VST Directory…" (cuối instrument dropdown) → PluginManager Modal: input path + [Scan] (spinner/Scanning…) + list plugin (tên/path/format) → click plugin → `setTrackInstrumentWithUndo(trackId, plugin_id, "Name (VST3)")` (label track cập nhật) + đóng modal. Giữ instrumentDropdownTrackId khi mở modal (không null).
|
||||
- **Các file ảnh hưởng:** app/core/vst_scanner.py, app/api/v1/desktop_plugins.py, app/main.py, app/static/js/app.jsx, app/templates/index.html (?v=202608080815), wiki.md. Build precompiled PASS.
|
||||
- **Ghi chú/Test:** python test scanner (2 plugin giả OK). E2E: mở track instrument dropdown → Quét VST Directory → nhập /opt/daw_engine/vst3 → Scan → chọn plugin → label track thành "🎵 Name (VST3)".
|
||||
|
||||
### [2026-08-08 08:20] Task: VST3 — ĐỒNG BỘ state + render đúng tiếng (spec 2 điểm then chốt)
|
||||
- **User chỉ ra 2 điểm:** (A) synth_engine phải đầy đủ {type, plugin_id, plugin_name, format, plugin_path}; (B) render dùng `pedalboard.load_plugin(plugin_path)`.
|
||||
- **A — Frontend (app.jsx):**
|
||||
(1) `setTrackInstrumentWithProgram` — thêm param `vstMeta` ({plugin_name, format, plugin_path}) — synth_engine vst3 → spread đủ 5 field theo spec (isVstInstrument: id vst3_/au_ hoặc vstMeta.format).
|
||||
(2) `setTrackInstrumentWithUndo` — nhận + truyền vstMeta.
|
||||
(3) Dropdown VST + PluginManager modal — gọi với vstMeta (plugin_name/format/plugin_path từ item scan).
|
||||
(4) API `/available` (`vst_engine.list_available`) — vst_instruments thêm `path` + id chuẩn `vst3_<name>`.
|
||||
- **B — Backend:**
|
||||
(1) `vst_engine.load_vst` — NHẬN PATH trực tiếp (đuôi .vst3/.so/.component hoặc chứa dấu / hoặc \ → os.path.exists → VST3Plugin(path)) — fallback tên cũ.
|
||||
(2) `render_engine` — đọc `se.plugin_path` → `load_vst(vst_path or instrument_id)` — nhánh Pedalboard render (đã có — midi_messages + Pedalboard([vst])) giờ load đúng plugin.
|
||||
- **Các file ảnh hưởng:** app/core/vst_engine.py, app/core/render_engine.py, app/static/js/app.jsx, app/templates/index.html (?v=202608080820), wiki.md. Build PASS (plugin_path ×3) + ast OK.
|
||||
- **Ghi chú/Test:** chọn VST (dropdown hoặc modal) → track.synth_engine = {type:'vst3', plugin_id, plugin_name, format, plugin_path} → Render/Bounce → render_engine load VST3 qua pedalboard theo path → WAV đúng tiếng plugin (cần pedalboard cài + plugin thật ở path).
|
||||
|
||||
### [2026-08-08 08:30] Task: Windows .exe installer — packaging theo spec (PyInstaller + Tauri v2 sidecar)
|
||||
- **Spec 08-27:** Dual-Process Desktop — (1) daw_engine.exe (PyInstaller — FastAPI bind localhost:8000) + (2) Tauri v2 shell (WebView2) — sidecar — NSIS/MSI installer.
|
||||
- **Môi trường hiện tại = Linux → KHÔNG build .exe trực tiếp** → tạo ĐỦ file build + CI workflow (windows-latest) → artifact .exe tải xuống.
|
||||
- **Đã tạo:**
|
||||
(1) `main.py` (root entry — uvicorn 127.0.0.1:8000 + auto-open browser).
|
||||
(2) `engine.spec` (spec — collect pedalboard/soundfile/fluidsynth DLL + static/templates/storage datas + hiddenimports; console=False; upx).
|
||||
(3) `src-tauri/` — tauri.conf.json (window url=http://127.0.0.1:8000, externalBin daw_engine, targets nsis+msi), Cargo.toml (tauri 2 + tauri-plugin-shell), build.rs, src/main.rs, src/lib.rs (spawn sidecar + kill khi window destroyed — theo spec), capabilities/default.json (shell:allow-spawn/open), icons (32/128 png + icon.ico — tools/mkicons.py).
|
||||
(4) `.github/workflows/windows-build.yml` — windows-latest: python 3.11 + node + rust → pip deps → Babel precompile → pyinstaller engine.spec → copy sidecar (daw_engine-x86_64-pc-windows-msvc.exe) → npx tauri build → upload artifact (NSIS .exe + MSI + daw_engine.exe).
|
||||
- **Các file ảnh hưởng:** main.py, engine.spec, src-tauri/*, .github/workflows/windows-build.yml, tools/mkicons.py, wiki.md.
|
||||
- **Ghi chú/Test:** push lên GitHub (branch desktop-alone) → Actions → workflow_dispatch (hoặc tag v*) → tải artifact "SonicForgeDAW-windows" → chạy setup.exe trên máy Windows (test: daw_engine xuất hiện Task Manager, /docs mở, VST3 scan, Export WAV).
|
||||
|
||||
### [2026-08-08 08:35] Task: FIX build Windows — supertonic cần numpy<2.0
|
||||
- **Lỗi CI:** `supertonic 1.2.1 requires numpy<2.0,>=1.21.0, but you have numpy 2.2.6` — pedalboard kéo supertonic (ràng buộc numpy<2) — requirements `numpy>=1.24.0` cài 2.2.6 → conflict.
|
||||
- **FIX:** requirements.txt — `numpy>=1.24.0,<2.0`. Kiểm tra: code KHÔNG dùng API numpy 2.x (np.float_/np.int_...) → pin <2.0 an toàn.
|
||||
- **Các file ảnh hưởng:** requirements.txt, wiki.md.
|
||||
- **Ghi chú/Test:** chạy lại workflow windows-build — pip cài numpy 1.26.x — hết conflict supertonic.
|
||||
|
||||
### [2026-08-08 08:40] Task: FIX build Windows (2) — supertonic kéo onnx2tf/opencv/pocket-tts xung đột numpy
|
||||
- **Lỗi CI:** sau pin numpy<2.0 — conflict NGƯỢC: ml-dtypes/onnx2tf/opencv-python/pocket-tts yêu cầu numpy>=2 — supertonic (pedalboard dep) yêu cầu numpy<2 — KHÔNG có numpy nào thỏa cả 2.
|
||||
- **Nguyên nhân:** supertonic (AI synth — kéo onnx2tf/opencv/pocket-tts/ml-dtypes) — dự án KHÔNG dùng supertonic.
|
||||
- **FIX:** (1) requirements.txt — BỎ `pedalboard` (chú thích lý do); (2) CI — `pip install -r requirements.txt` + `pip install --no-deps pedalboard>=0.8.0` (chỉ pedalboard core — load_plugin VST3 KHÔNG cần supertonic).
|
||||
- **Các file ảnh hưởng:** requirements.txt, .github/workflows/windows-build.yml, wiki.md.
|
||||
- **Ghi chú/Test:** chạy lại workflow — hết conflict numpy; pedalboard (VST3 render) vẫn hoạt động qua --no-deps.
|
||||
|
||||
### [2026-08-08 08:45] Task: FIX build Windows (3) — cargo not found (thiếu Rust)
|
||||
- **Lỗi:** `npx tauri build — failed to run 'cargo metadata' ... program not found` — máy build thiếu Rust toolchain.
|
||||
- **FIX:** (1) `build_windows.bat` — script 1 lệnh: kiểm tra Python/Node → TỰ CÀI Rust (rustup -y) nếu thiếu → pip deps (+ pedalboard --no-deps) → Babel → pyinstaller engine.spec → copy sidecar → npx tauri build; (2) `BUILD_WINDOWS.md` — yêu cầu (Python, Node, Rust MSVC, VS Build Tools C++, WebView2) + build thủ công + checklist kiểm thử theo spec IV.
|
||||
- **Các file ảnh hưởng:** build_windows.bat, BUILD_WINDOWS.md, wiki.md.
|
||||
- **Ghi chú/Test:** trên máy Windows: chạy `build_windows.bat` (cmd) → sinh setup.exe; CI (windows-latest — dtolnay/rust-toolchain) không bị lỗi này.
|
||||
|
||||
### [2026-08-08 08:50] Task: FIX build_windows.bat — lỗi "was unexpected at this time"
|
||||
- **Lỗi:** `.\build_windows.bat` → `... was unexpected at this time.` — batch parse: dấu `(` `)` trong chuỗi echo (vd `(tick "Add to PATH")`) phá block `(...)`; `|| ( ... )` kết hợp cũng rủi ro.
|
||||
- **FIX:** viết lại batch an toàn: bỏ mọi ngoặc trong echo, dùng `if errorlevel 1 ( ... )` thuần, echo KHÔNG DẤU (tránh codepage), quote `"pedalboard>=0.8.0"` (dấu `>` = redirect trong cmd).
|
||||
- **Các file ảnh hưởng:** build_windows.bat, wiki.md.
|
||||
- **Ghi chú/Test:** chạy lại `build_windows.bat` trên Windows — hết lỗi parse; nếu thiếu Rust → tự cài rustup rồi tiếp tục.
|
||||
|
||||
### [2026-08-08 08:55] Task: FIX build_windows.bat — dừng im lặng ở [4/6] (npm install nuốt lỗi)
|
||||
- **Lỗi:** script dừng ở [4/6] Precompile JS không message — `npm install >nul 2>nul` nuốt lỗi → babel thiếu → `exit /b 1` im lặng.
|
||||
- **FIX (build_windows.bat):** (1) [4/6] — bỏ `>nul 2>nul` (hiện lỗi), check `if errorlevel 1` + check tồn tại `node_modules\@babel\cli\bin\babel.js` với message rõ; (2) [6/6] — tương tự cho `npm install -D @tauri-apps/cli` (bỏ nuốt lỗi + check).
|
||||
- **Các file ảnh hưởng:** build_windows.bat, wiki.md.
|
||||
- **Ghi chú/Test:** chạy lại `.\build_windows.bat` — nếu npm install fail sẽ thấy lỗi thật (network/registry) thay vì dừng im.
|
||||
|
||||
### [2026-08-08 09:00] Task: FIX build_windows.bat — Babel fail dừng im (exit /b 1 không message)
|
||||
- **Lỗi:** [4/6] npm OK ("up to date") — nhưng node babel fail → `if errorlevel 1 exit /b 1` — THOÁT im lặng về prompt.
|
||||
- **FIX (build_windows.bat bước 4):** in từng bước (npm OK → kiem tra babel → chay Babel) + MỌI điểm fail có `echo FAIL: ... + pause` (không exit im).
|
||||
- **Các file ảnh hưởng:** build_windows.bat, wiki.md.
|
||||
- **Ghi chú/Test:** chạy lại — nếu Babel fail sẽ THẤY lỗi thật (thường: node_modules thiếu @babel/cli hoặc lỗi syntax source). WORKAROUND: nếu chỉ env (không phải syntax) — bản `app.precompiled.js` hiện có vẫn dùng được (đã build sẵn) — có thể comment dòng babel trong script.
|
||||
|
||||
### [2026-08-08 09:10] Task: FIX tauri build — thiếu `use tauri::Manager`
|
||||
- **Lỗi Rust:** `no method named 'manage' found for &mut tauri::App` + `no method named 'state'` — trait `Manager` (cung cấp manage/state) chưa được import.
|
||||
- **FIX (src-tauri/src/lib.rs):** thêm `use tauri::Manager;`.
|
||||
- **Các file ảnh hưởng:** src-tauri/src/lib.rs, wiki.md.
|
||||
- **Ghi chú/Test:** chạy lại `npx tauri build` — compile tiếp (lỗi khác nếu có — thường là linker MSVC nếu thiếu VS Build Tools).
|
||||
|
||||
### [2026-08-08 09:15] Task: FIX tauri build (2) — lifetime `state` (thiếu ; sau if-let)
|
||||
- **Lỗi Rust:** `error[E0597]: state does not live long enough` — temporary (MutexGuard) của `state.0.lock()` drop muộn hơn state.
|
||||
- **FIX (src-tauri/src/lib.rs):** thêm `;` sau if-let block (temporary dropped sớm — theo gợi ý compiler).
|
||||
- **Các file ảnh hưởng:** src-tauri/src/lib.rs, wiki.md.
|
||||
- **Ghi chú/Test:** chạy lại `npx tauri build` — compile tiếp.
|
||||
|
||||
### [2026-08-08 09:20] Task: FIX daw_engine.exe — ModuleNotFoundError celery.fixups
|
||||
- **Lỗi chạy exe:** `No module named 'celery.fixups'` — celery import động qua kombu.symbol_by_name (app/tasks/worker.py) — PyInstaller không bắt được hidden module.
|
||||
- **FIX (engine.spec):** thêm hiddenimports celery family: celery.fixups(+django), celery.backends(+redis), celery.schedules, celery.app.builtins, kombu.transport.redis, billiard, vine, redis.
|
||||
- **Các file ảnh hưởng:** engine.spec, wiki.md.
|
||||
- **Ghi chú/Test:** build lại `pyinstaller engine.spec --clean --noconfirm` → chạy daw_engine.exe → server khởi động (localhost:8000).
|
||||
|
||||
### [2026-08-08 09:25] Task: FIX tauri build — Access denied khi copy sidecar (daw_engine đang chạy)
|
||||
- **Lỗi:** tauri-build panic `Os { code: 5, kind: PermissionDenied }` — không copy được externalBin — vì `daw_engine.exe` ĐANG CHẠY (test lần trước — tiến trình giữ file).
|
||||
- **FIX (build_windows.bat [6/6]):** thêm `taskkill /F /IM daw_engine.exe >nul 2>nul` trước `npx tauri build`.
|
||||
- **Các file ảnh hưởng:** build_windows.bat, wiki.md.
|
||||
- **Ghi chú/Test:** (1) tay: Task Manager → kết thúc mọi `daw_engine.exe` → `npx tauri build` lại; (2) script mới tự kill.
|
||||
|
||||
### [2026-08-08 09:30] Task: FIX daw_engine mở tab browser liên tục + không kill được process
|
||||
- **Lỗi:** (1) exe mở tab browser liên tục; (2) taskkill không giết được process.
|
||||
- **Nguyên nhân:** (1) main.py `threading.Timer(2.0, webbrowser.open)` — mở browser mỗi lần exe chạy (Tauri shell ĐÃ mở window localhost — thừa); (2) PyInstaller ONEFILE = parent + child — Tauri `child.kill()` chỉ giết PARENT → CHILD ORPHAN chạy mãi (server sống → vẫn mở tab qua timer cũ).
|
||||
- **FIX:**
|
||||
(1) `main.py` — XÓA auto-open browser (Tauri window url=localhost:8000 đảm nhiệm; standalone mở tay).
|
||||
(2) `src-tauri/src/lib.rs` — khi window destroyed: child.kill() + `taskkill /F /T /IM daw_engine.exe` (kill CẢ TREE — cả parent + child onefile).
|
||||
(3) `build_windows.bat` — `taskkill /F /T /IM` (tree).
|
||||
- **Các file ảnh hưởng:** main.py, src-tauri/src/lib.rs, build_windows.bat, wiki.md.
|
||||
- **Ghi chú/Test:** build lại exe + tauri → đóng app → Task Manager không còn daw_engine (cả tree) + không mở tab mới. Kill tay lúc này: `taskkill /F /T /IM daw_engine.exe`.
|
||||
|
||||
### [2026-08-08 09:40] Task: Docker compose không chạy — THIẾU .env (tạo ở task 08-07 nhưng chưa có file .env)
|
||||
- **Kiểm tra:** `docker-compose.prod.yml` (tạo task 08-07) — `env_file: .env` × 3 services (web/worker/beat) — NHƯNG **`.env` KHÔNG TỒN TẠI** (chỉ `.env.example` 516B) → `docker compose up` → lỗi `env file .env not found` → không chạy.
|
||||
- **FIX:**
|
||||
(1) TẠO `.env` (từ .env.example — REDIS_URL/CELERY/OPENAI/SECRET_KEY/IMAGE — SECRET_KEY đổi giá trị mặc định; ghi chú đổi trước production).
|
||||
(2) `docker-compose.prod.yml` — tối giản volumes: bỏ 3 volume chồng (sf_uploads/sf_processed/sf_db — sf_db bao cả storage) → **1 volume `sf_data:/app/app/storage`**.
|
||||
- **Lưu ý khác:** image `${IMAGE:-sonicforge-studio:latest}` — phải `docker build -t sonicforge-studio:latest .` TRƯỚC (hoặc set IMAGE=registry...); `docker-compose.prod.yml` dùng cho PRODUCTION (không mount source) — dev dùng `docker-compose.yml` cũ.
|
||||
- **Các file ảnh hưởng:** .env (mới), docker-compose.prod.yml, wiki.md.
|
||||
- **Ghi chú/Test:** `docker compose -f docker-compose.prod.yml up -d` — hết lỗi env file; nếu image chưa build → `docker build -t sonicforge-studio:latest .` trước.
|
||||
|
||||
### [2026-08-08 09:45] Task: FIX màn đen — 401 không mở màn login (dùng cached user sai)
|
||||
- **Log bản mới:** `GET /api/v1/auth/profile 401` + `/plugins/available 401` — root rỗng (màn đen).
|
||||
- **Kịch bản:** browser còn `sonic_token` CŨ (ký SECRET_KEY cũ — .env mới đổi secret) + `sonic_user` CACHED → `checkAuthStatus` profile 401 → `catch` DÙNG cached user → vào app "như đã login" → mọi API 401 (token đã bị xóa) → giao diện không dữ liệu = đen, KHÔNG mở login.
|
||||
- **FIX:**
|
||||
(1) `app.jsx checkAuthStatus catch` — phát hiện 401 (errMsg chứa 401/Unauthorized/Không xác thực) → BỎ QUA cached → xóa token + mở AuthModal(login); cached chỉ dùng khi lỗi MẠNG (offline).
|
||||
(2) `services/api.js` — 401 bất kỳ → `window.__onAuthFail()` (mở login ngay).
|
||||
(3) `app.jsx` — đăng ký `window.__onAuthFail` (setCurrentUser null + mở login).
|
||||
- **Các file ảnh hưởng:** app/static/js/app.jsx, app/static/js/services/api.js, app/templates/index.html (?v=202608080945), wiki.md. Build PASS.
|
||||
- **Ghi chú/Test:** hard refresh server → 401 → HIỆN MÀN ĐĂNG NHẬP (thay vì đen) → đăng nhập admin (DEFAULT_ADMIN_PASSWORD trong .env) → vào app. (User cũ có token hỏng → tự động về login.)
|
||||
|
||||
### [2026-08-08 09:50] Task: FIX màn đen (2) — 401 detail tiếng Việt không khớp matcher
|
||||
- **Vẫn đen sau 0945:** log `GET /api/v1/plugins/available 401` — checkAuthStatus catch — isAuthErr FALSE vì 401 detail của server (auth.py) = "Thiếu Token xác thực hoặc Token không hợp lệ" / "Token đã hết hạn hoặc không hợp lệ" — KHÔNG chứa '401'/'Unauthorized' → cached user vẫn được dùng → đen.
|
||||
- **FIX (app.jsx):** matcher thêm `errMsg.includes('Token')` (phủ cả 2 detail của auth.py).
|
||||
- **Các file ảnh hưởng:** app/static/js/app.jsx, app/templates/index.html (?v=202608080950), wiki.md. Build PASS.
|
||||
- **Ghi chú/Test:** hard refresh (Ctrl+Shift+R — nạp ?v=0950) → 401 → MÀN ĐĂNG NHẬP hiện → login admin/admin123 (hoặc DEFAULT_ADMIN_PASSWORD trong .env) → vào app.
|
||||
|
||||
### [2026-08-08 09:55] Task: FIX desktop — nhiều daw_engine + không tắt được + màn đen
|
||||
- **Lỗi:** mỗi lần mở app → spawn thêm daw_engine (cũ không tắt — kill thiếu /T hoặc Tauri crash không kịp kill) → nhiều instance → port 8000 chiếm → lần mở sau: window load vào server cũ / không bind được → MÀN ĐEN (giống docker — nhưng nguyên nhân khác: instance/port).
|
||||
- **FIX (main.py — entry daw_engine.exe):** SINGLE-INSTANCE — kiểm tra port 8000 (socket bind test) — NẾU ĐÃ CÓ server → `sys.exit(0)` (window dùng server đang chạy — không spawn thêm).
|
||||
- **SECRET_KEY:** đã ổn định (env > {STORAGE}/.secret_key persist > ephemeral) — không phải nguyên nhân.
|
||||
- **Các file ảnh hưởng:** main.py, wiki.md. (Cần build lại exe: pyinstaller engine.spec --clean --noconfirm → copy sidecar → npx tauri build.)
|
||||
- **Kill tay lúc này:** `taskkill /F /T /IM daw_engine.exe` (có /T — giết CẢ tree — PyInstaller onefile parent+child).
|
||||
|
||||
### [2026-08-08 10:00] Task: FIX docker không nhận bản 0950 — compose prod THIẾU build:
|
||||
- **Kết quả kiểm tra container:** index.html trỏ `?v=202608080820` (image CŨ) — dù build lại.
|
||||
- **Nguyên nhân:** `docker-compose.prod.yml` services CHỈ có `image:` — KHÔNG có `build:` → `docker compose build` KHÔNG build gì → image `sonicforge-studio:latest` giữ nguyên (0820) → up dùng image cũ.
|
||||
- **FIX:** thêm `build: .` vào web/worker/beat (compose build hoạt động; image: giữ cho registry prod).
|
||||
- **Các file ảnh hưởng:** docker-compose.prod.yml, wiki.md.
|
||||
- **Chạy lại trên server:**
|
||||
```
|
||||
docker compose -f docker-compose.prod.yml build --no-cache
|
||||
docker compose -f docker-compose.prod.yml up -d --force-recreate
|
||||
docker compose -f docker-compose.prod.yml exec web sh -c "grep -o 'precompiled.js?v=[0-9]*' app/templates/index.html" # phải = 0950
|
||||
```
|
||||
|
||||
### [2026-08-08 10:05] Task: FIX màn đen (3) — Rules of Hooks: `if (!isOpen) return null` TRƯỚC hooks ở MỌI modal
|
||||
- **Báo cáo:** 0950 load OK + CSS 200 + không lỗi console — vẫn đen trơn.
|
||||
- **NGUYÊN NHÂN GỐC (React crash → unmount → đen):** AuthModal có `if (!isOpen) return null;` TRƯỚC các hooks (useState/useEffect) — VI PHẠM Rules of Hooks — khi login MỞ lần đầu (isOpen false→true) → hook order thay đổi (0→11) → React throw "Rendered more hooks..." → App unmount → MÀN ĐEN. Trước đây không bao giờ mở login (token luôn OK) — fix 401 (09:45-09:50) mở login → LỘ BUG.
|
||||
- **FIX:** chuyển `if (!isOpen) return null;` XUỐNG SAU tất cả hooks (trước return JSX) cho **9 modal**: AuthModal, AIConfigModal, PluginManagerModal, ProfileModal, SaveProjectModal, OpenProjectModal, SaveAsModal, SystemManagerModal, AIPresetModal.
|
||||
- **Các file ảnh hưởng:** app/static/js/app.jsx, app/templates/index.html (?v=202608081005), wiki.md. Build PASS.
|
||||
- **Ghi chú/Test:** rebuild image (compose build --no-cache + up -d --force-recreate) → hard refresh → MÀN ĐĂNG NHẬP HIỆN (thay vì đen) → login admin/admin123 → vào app.
|
||||
|
||||
### [2026-08-08 10:10] Task: FIX màn đen (4) — tự host CDN (tailwind/lucide/react) — bỏ phụ thuộc mạng ngoài
|
||||
- **Báo cáo:** 1005 vẫn đen trơn + không log thêm. Log có `(index):64 cdn.tailwindcss.com should not be used in production` — index.html dòng 9 load **cdn.tailwindcss.com (CDN JIT)** — tailwind.min.css local = **0 bytes (rỗng)** — nếu CDN bị chặn/treo (mạng VN) → **TOÀN BỘ UI không có style → modal login text đen trên nền đen → "đen trơn"** (không phải lỗi JS).
|
||||
- **FIX (index.html):** tự host tất cả CDN → `/static/js/vendor/` (đã download):
|
||||
- `tailwindcss-cdn.js` (407KB — JIT script)
|
||||
- `react.production.min.js` + `react-dom.production.min.js` (18.3.1 UMD — bỏ unpkg)
|
||||
- `lucide.min.js` (bỏ unpkg)
|
||||
- Còn font-awesome (cdnjs) — chỉ icons — không chết app (để CDN).
|
||||
- **Các file ảnh hưởng:** app/templates/index.html, app/static/js/vendor/* (4 file mới), wiki.md.
|
||||
- **Ghi chú/Test:** rebuild image → hard refresh → UI có style (tailwind local JIT) → MÀN ĐĂNG NHẬP hiển thị bình thường → login admin/admin123.
|
||||
|
||||
### [2026-08-08 10:15] Task: Chẩn đoán màn đen — thêm log [AUTH]/[GLOBAL-ERR]/ErrorBoundary
|
||||
- **Bằng chứng user:** #root TRỐNG (React render rồi UNMOUNT — SFRoute logs có) — KHÔNG lỗi console — không profile request.
|
||||
- **Thêm chẩn đoán (app.jsx):**
|
||||
(1) `[AUTH]` logs — checkAuthStatus (token?/profile OK?/lỗi?/isAuthErr?) + __onAuthFail.
|
||||
(2) `window.addEventListener('error')` → `[GLOBAL-ERR]` + `unhandledrejection` → `[GLOBAL-REJECT]`.
|
||||
(3) **ErrorBoundary** bọc App — componentDidCatch → `[BOUNDARY-ERR]` + fallback hiển thị lỗi đỏ (thay vì đen).
|
||||
- **Các file ảnh hưởng:** app/static/js/app.jsx, app/templates/index.html (?v=202608081015), wiki.md. Build PASS.
|
||||
- **Ghi chú/Test:** rebuild image → hard refresh → dán MỌI dòng console (sẽ có [AUTH].../[GLOBAL-ERR]/[BOUNDARY-ERR] hoặc fallback đỏ — xác định chính xác điểm chết).
|
||||
|
||||
### [2026-08-08 10:20] Task: Chẩn đoán (2) — log root children sau mount
|
||||
- **Kết quả 1015:** KHÔNG lỗi (không GLOBAL-ERR/BOUNDARY) — [AUTH] token rỗng → mở login + __onAuthFail chạy — App mounted (effects) — NHƯNG root trống (1005) — App KHÔNG crash.
|
||||
- **Thêm (1020):** `[APP] mounted — root children: N | authModalOpen: ... | currentUser: ...` (mỗi render — bắt đầu useEffect không deps).
|
||||
- **Các file ảnh hưởng:** app/static/js/app.jsx, app/templates/index.html (?v=202608081020), wiki.md. Build PASS.
|
||||
- **Ghi chú/Test:** rebuild image → hard refresh → dán log `[APP] mounted` + MỌI dòng — biết root có children (render) hay 0 (App return null / chưa render).
|
||||
|
||||
### [2026-08-08 10:30] Task: Docker build — apt-get chạy lại mỗi lần → check skip + bỏ --no-cache
|
||||
- **Yêu cầu user:** `RUN apt-get update && apt-get install` chạy lại mỗi lần build (tốn thời gian) — kiểm tra đã cài thì bỏ qua.
|
||||
- **Nguyên nhân:** các lần build gần đây dùng `--no-cache` (hướng dẫn trước để ép lấy code mới) → MỌI layer chạy lại → apt chạy lại.
|
||||
- **FIX:**
|
||||
(1) `Dockerfile` — RUN apt: `if command -v fluidsynth && ffmpeg && Xvfb → echo skip; else apt-get update && install ...` (check trước — package đã có → bỏ qua apt).
|
||||
(2) **QUAN TRỌNG:** build THƯỜNG không dùng `--no-cache` — `docker compose -f docker-compose.prod.yml build` — layer apt + `pip install -r requirements.txt` CACHED (chỉ chạy khi requirements/Dockerfile/base đổi); `COPY . .` (code mới — precompiled/?v=) tự cache-bust → vẫn lấy bản mới. Chỉ dùng `--no-cache` khi thật sự cần (ép apt/pip cập nhật).
|
||||
- **Các file ảnh hưởng:** Dockerfile, wiki.md.
|
||||
- **Ghi chú/Test:** build 2 lần liên tiếp (không --no-cache) → lần 2: apt layer "CACHED" (không chạy) — nhanh hơn nhiều.
|
||||
|
||||
### [2026-08-08 10:30] Task: Chẩn đoán (3) — App render UI nhưng root children 0
|
||||
- **Kết quả 1025:** `[APP] return UI` XUẤT HIỆN (App return 26006 chạy — UI render) NHƯNG `root children: 0` mọi lần — App render nhưng DOM KHÔNG có con → nghi root.render không commit (hoặc render vào nơi khác).
|
||||
- **Thêm (1030):** log tại root.render — `[ROOT] render() vừa gọi — root children` + `[ROOT] sau 500ms — root children | html len` — xác định DOM có được commit hay không.
|
||||
- **Các file ảnh hưởng:** app/static/js/app.jsx, app/templates/index.html (?v=202608081030), wiki.md. Build PASS.
|
||||
- **Ghi chú/Test:** rebuild image (KHÔNG --no-cache — build thường) → hard refresh → dán log [ROOT].
|
||||
|
||||
### [2026-08-08 10:35] Task: FIX màn đen (5) — chuyển sang legacy render (ReactDOM.render — đồng bộ commit)
|
||||
- **Kết quả 1030:** `[ROOT] render() vừa gọi — root children: 0` + `sau 500ms — root children: 0 | html len: 0` — **createRoot render KHÔNG commit DOM** (App render chạy — return UI logs — mounted effects chạy — nhưng DOM rỗng) — môi trường/server lạ (browser VN — có thể liên quan scheduler/postMessage bị can thiệp).
|
||||
- **FIX (app.jsx cuối):** bỏ `ReactDOM.createRoot().render()` (concurrent) → **`ReactDOM.render()` (legacy — ĐỒNG BỘ commit)** + giữ ErrorBoundary (fallback đỏ) + GLOBAL-ERR/REJECT logs.
|
||||
- **Các file ảnh hưởng:** app/static/js/app.jsx, app/templates/index.html (?v=202608081035), wiki.md. Build PASS (createRoot còn = comment).
|
||||
- **Ghi chú/Test:** rebuild image (build thường — KHÔNG --no-cache) → hard refresh → nếu root children > 0 → UI hiện (login) → đăng nhập.
|
||||
|
||||
### [2026-08-08 11:00] Task: Màn đen — React 18.2.0 thay 18.3.1 + revert test biến
|
||||
- **Chuỗi chẩn đoán:** root children 0 dù App render chạy (return UI) + effects chạy (mounted) + không lỗi + ReactDOM commit OK (HELLO children 1) — bất khả thi về lý thuyết → nghi vấn vendor React 18.3.1 UMD (tự host từ unpkg) có vấn đề trên môi trường.
|
||||
- **Làm:** (1) revert `const _appResult` (build lỗi VarRedeclaration — loc lạ 29438) về return trực tiếp — build PASS; (2) đổi vendor → **React/react-dom 18.2.0 production** (tải từ unpkg — 10737/131882 bytes).
|
||||
- **Các file ảnh hưởng:** app/static/js/app.jsx, app/static/js/vendor/react*.production.min.js (18.2.0), app/templates/index.html (?v=202608081055), wiki.md.
|
||||
- **Ghi chú/Test:** rebuild image → hard refresh → nếu UI hiện (login) → 18.3.1 UMD là thủ phạm → giữ 18.2.0. Nếu vẫn 0 → thử: tab ẩn danh / trình duyệt khác (Edge/Firefox) → dán log.
|
||||
|
||||
### [2026-08-08 11:05] Task: Màn đen — trace xác nhận App render từ root.render bình thường
|
||||
- **Trace (1100):** `App @ 1551 → of → Rk → Si → ... → Q.render (react-dom:266) → anonymous 1583` — App render ĐÚNG từ ReactDOM.render (root) — không render lạ.
|
||||
- Vẫn root children 0 sau commit — bất khả thi lý thuyết — cần xem DOM thực (root có gì / App có trong body không).
|
||||
- **Bước:** user chạy trong console (trang đang đen):
|
||||
`JSON.stringify({rootHTML: document.getElementById('root').innerHTML.slice(0,200), rootChildren: document.getElementById('root').children.length, appInDOM: document.body.innerHTML.includes('SonicForge')})`
|
||||
- **Các file ảnh hưởng:** app/static/js/app.jsx (trace), app/templates/index.html (?v=202608081100), wiki.md. Build PASS.
|
||||
- **Ghi chú/Test:** dán kết quả JSON → xác định App render vào đâu (root? body? nơi khác?).
|
||||
|
||||
Reference in New Issue
Block a user