From 02f6de4adc1b57627258bfd86399f12f2ec589bb Mon Sep 17 00:00:00 2001 From: maziggy Date: Tue, 20 Jan 2026 15:37:20 +0100 Subject: [PATCH] New Features: - Print from File Manager with plate selection, AMS mapping, and print options. Closes #94 - Add to queue without creating archive (reduces clutter) - Queue displays library file name, thumbnail, and print time Fixes: Queue items from File Manager now reference library files directly instead of creating archives upfront. Archives are created automatically when prints start. --- CHANGELOG.md | 16 +- README.md | 8 + backend/app/api/routes/library.py | 530 +++++++++++++++++- backend/app/api/routes/print_queue.py | 55 +- backend/app/core/database.py | 62 ++ backend/app/models/print_queue.py | 10 +- backend/app/schemas/library.py | 6 +- backend/app/schemas/print_queue.py | 11 +- .../tests/integration/test_print_queue_api.py | 194 +++++++ frontend/src/api/client.ts | 67 ++- .../components/PrintModal/FilamentMapping.tsx | 11 +- .../components/PrintModal/PrinterSelector.tsx | 102 ++-- frontend/src/components/PrintModal/index.tsx | 238 ++++---- frontend/src/components/PrintModal/types.ts | 39 +- frontend/src/pages/FileManagerPage.tsx | 58 +- frontend/src/pages/QueuePage.tsx | 58 +- scripts/mqtt_sniffer.py | 4 +- static/assets/index-5D76qqt8.css | 1 + .../{index-DE9m9l_f.js => index-BJM8SBBV.js} | 228 ++++---- static/assets/index-t4RhRNeD.css | 1 - static/index.html | 4 +- 21 files changed, 1322 insertions(+), 381 deletions(-) create mode 100644 static/assets/index-5D76qqt8.css rename static/assets/{index-DE9m9l_f.js => index-BJM8SBBV.js} (51%) delete mode 100644 static/assets/index-t4RhRNeD.css diff --git a/CHANGELOG.md b/CHANGELOG.md index 13a577bda..f753b4207 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to Bambuddy will be documented in this file. -## [0.1.6b11] - 2026-01-20 +## [Unreleased] ### New Features - **Unified Print Modal** - Consolidated three separate modals into one unified component: @@ -18,11 +18,25 @@ All notable changes to Bambuddy will be documented in this file. - **Enhanced Add-to-Queue** - Now includes plate selection and print options: - Configure all print settings upfront instead of editing afterward - Filament mapping with manual override capability +- **Print from File Manager** - Full print configuration when printing from library files: + - Plate selection for multi-plate 3MF files with thumbnails + - Filament slot mapping with comparison to loaded filaments + - All print options (bed levelling, flow calibration, etc.) +- **Deferred archive creation** - Queue items from File Manager no longer create archives upfront: + - Queue items store `library_file_id` directly + - Archives are created automatically when prints start + - Reduces clutter in Archives from unprinted queued files + - Queue displays library file name, thumbnail, and print time + +### Changed +- **Edit Queue Item modal** - Single printer selection only (reassigns item, doesn't duplicate) +- **Edit Queue Item button** - Changed from "Print to X Printers" to "Save" ### Fixed - **File Manager folder navigation** - Fixed bug where opening a folder would briefly show files then jump back to root: - Removed `selectedFolderId` from useEffect dependency array that was causing a reset loop - Folder navigation now works correctly without resetting +- **Queue items with library files** - Fixed 500 errors when listing/updating queue items from File Manager ## [0.1.6b10] - 2026-01-20 diff --git a/README.md b/README.md index ff6223ca9..20ce960f1 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,14 @@ - Auto power-on before print - Auto power-off after cooldown +### 📁 File Manager (Library) +- Upload and organize sliced files (3MF, gcode) +- Folder structure with drag-and-drop +- Print directly to any printer with full options +- Add to queue without creating archive upfront +- Plate selection for multi-plate 3MF files +- Duplicate detection via file hash + ### 📁 Projects - Group related prints (e.g., "Voron Build") - Track plates (print jobs) and parts separately diff --git a/backend/app/api/routes/library.py b/backend/app/api/routes/library.py index 44321d747..6ed105b21 100644 --- a/backend/app/api/routes/library.py +++ b/backend/app/api/routes/library.py @@ -30,6 +30,7 @@ from backend.app.schemas.library import ( FileDuplicate, FileListResponse, FileMoveRequest, + FilePrintRequest, FileResponse as FileResponseSchema, FileUpdate, FileUploadResponse, @@ -755,10 +756,7 @@ async def add_files_to_queue( """Add library files to the print queue. Only sliced files (.gcode or .gcode.3mf) can be added to the queue. - For each file: - 1. Validates it's a sliced file - 2. Creates an archive from the library file - 3. Creates a queue item pointing to that archive + The archive will be created automatically when the print starts. """ added: list[AddToQueueResult] = [] errors: list[AddToQueueError] = [] @@ -771,8 +769,6 @@ async def add_files_to_queue( pos_result = await db.execute(select(func.coalesce(func.max(PrintQueueItem.position), 0))) max_position = pos_result.scalar() or 0 - archive_service = ArchiveService(db) - for file_id in request.file_ids: lib_file = files.get(file_id) @@ -792,7 +788,7 @@ async def add_files_to_queue( continue try: - # Get the full file path + # Verify file exists on disk file_path = Path(app_settings.base_dir) / lib_file.file_path if not file_path.exists(): @@ -801,23 +797,11 @@ async def add_files_to_queue( ) continue - # Create archive from the library file - archive = await archive_service.archive_print( - printer_id=None, # Unassigned - source_file=file_path, - ) - - if not archive: - errors.append( - AddToQueueError(file_id=file_id, filename=lib_file.filename, error="Failed to create archive") - ) - continue - - # Create queue item + # Create queue item referencing library file (archive created at print start) max_position += 1 queue_item = PrintQueueItem( printer_id=None, # Unassigned - archive_id=archive.id, + library_file_id=file_id, position=max_position, status="pending", ) @@ -830,7 +814,6 @@ async def add_files_to_queue( file_id=file_id, filename=lib_file.filename, queue_item_id=queue_item.id, - archive_id=archive.id, ) ) @@ -843,6 +826,509 @@ async def add_files_to_queue( return AddToQueueResponse(added=added, errors=errors) +@router.get("/files/{file_id}/plates") +async def get_library_file_plates( + file_id: int, + db: AsyncSession = Depends(get_db), +): + """Get available plates from a multi-plate 3MF library file. + + Returns a list of plates with their index, name, thumbnail availability, + and filament requirements. For single-plate exports, returns a single plate. + """ + import xml.etree.ElementTree as ET + import zipfile + + # Get the library file + result = await db.execute(select(LibraryFile).where(LibraryFile.id == file_id)) + lib_file = result.scalar_one_or_none() + + if not lib_file: + raise HTTPException(status_code=404, detail="File not found") + + file_path = Path(app_settings.base_dir) / lib_file.file_path + if not file_path.exists(): + raise HTTPException(status_code=404, detail="File not found on disk") + + # Only 3MF files have plates + if not lib_file.filename.lower().endswith(".3mf"): + return {"file_id": file_id, "filename": lib_file.filename, "plates": [], "is_multi_plate": False} + + plates = [] + + try: + with zipfile.ZipFile(file_path, "r") as zf: + namelist = zf.namelist() + + # Find all plate gcode files to determine available plates + gcode_files = [n for n in namelist if n.startswith("Metadata/plate_") and n.endswith(".gcode")] + + if not gcode_files: + # No sliced plates found + return {"file_id": file_id, "filename": lib_file.filename, "plates": [], "is_multi_plate": False} + + # Extract plate indices from gcode filenames + plate_indices = [] + for gf in gcode_files: + try: + plate_str = gf[15:-6] # Remove "Metadata/plate_" and ".gcode" + plate_indices.append(int(plate_str)) + except ValueError: + pass + + plate_indices.sort() + + # Parse model_settings.config for plate names + plate_names = {} + if "Metadata/model_settings.config" in namelist: + try: + model_content = zf.read("Metadata/model_settings.config").decode() + model_root = ET.fromstring(model_content) + for plate_elem in model_root.findall(".//plate"): + plater_id = None + plater_name = None + for meta in plate_elem.findall("metadata"): + key = meta.get("key") + value = meta.get("value") + if key == "plater_id" and value: + try: + plater_id = int(value) + except ValueError: + pass + elif key == "plater_name" and value: + plater_name = value.strip() + if plater_id is not None and plater_name: + plate_names[plater_id] = plater_name + except Exception: + pass + + # Parse slice_info.config for plate metadata + plate_metadata = {} + if "Metadata/slice_info.config" in namelist: + content = zf.read("Metadata/slice_info.config").decode() + root = ET.fromstring(content) + + for plate_elem in root.findall(".//plate"): + plate_info = {"filaments": [], "prediction": None, "weight": None, "name": None, "objects": []} + + plate_index = None + for meta in plate_elem.findall("metadata"): + key = meta.get("key") + value = meta.get("value") + if key == "index" and value: + try: + plate_index = int(value) + except ValueError: + pass + elif key == "prediction" and value: + try: + plate_info["prediction"] = int(value) + except ValueError: + pass + elif key == "weight" and value: + try: + plate_info["weight"] = float(value) + except ValueError: + pass + + # Get filaments used in this plate + for filament_elem in plate_elem.findall("filament"): + filament_id = filament_elem.get("id") + filament_type = filament_elem.get("type", "") + filament_color = filament_elem.get("color", "") + used_g = filament_elem.get("used_g", "0") + used_m = filament_elem.get("used_m", "0") + + try: + used_grams = float(used_g) + except (ValueError, TypeError): + used_grams = 0 + + if used_grams > 0 and filament_id: + plate_info["filaments"].append( + { + "slot_id": int(filament_id), + "type": filament_type, + "color": filament_color, + "used_grams": round(used_grams, 1), + "used_meters": float(used_m) if used_m else 0, + } + ) + + plate_info["filaments"].sort(key=lambda x: x["slot_id"]) + + # Collect object names + for obj_elem in plate_elem.findall("object"): + obj_name = obj_elem.get("name") + if obj_name and obj_name not in plate_info["objects"]: + plate_info["objects"].append(obj_name) + + # Set plate name + if plate_index is not None: + custom_name = plate_names.get(plate_index) + if custom_name: + plate_info["name"] = custom_name + elif plate_info["objects"]: + plate_info["name"] = plate_info["objects"][0] + plate_metadata[plate_index] = plate_info + + # Build plate list + for idx in plate_indices: + meta = plate_metadata.get(idx, {}) + has_thumbnail = f"Metadata/plate_{idx}.png" in namelist + + plates.append( + { + "index": idx, + "name": meta.get("name"), + "objects": meta.get("objects", []), + "has_thumbnail": has_thumbnail, + "thumbnail_url": f"/api/v1/library/files/{file_id}/plate-thumbnail/{idx}" + if has_thumbnail + else None, + "print_time_seconds": meta.get("prediction"), + "filament_used_grams": meta.get("weight"), + "filaments": meta.get("filaments", []), + } + ) + + except Exception as e: + logger.warning(f"Failed to parse plates from library file {file_id}: {e}") + + return { + "file_id": file_id, + "filename": lib_file.filename, + "plates": plates, + "is_multi_plate": len(plates) > 1, + } + + +@router.get("/files/{file_id}/plate-thumbnail/{plate_index}") +async def get_library_file_plate_thumbnail( + file_id: int, + plate_index: int, + db: AsyncSession = Depends(get_db), +): + """Get the thumbnail image for a specific plate from a library file.""" + import zipfile + + from starlette.responses import Response + + result = await db.execute(select(LibraryFile).where(LibraryFile.id == file_id)) + lib_file = result.scalar_one_or_none() + + if not lib_file: + raise HTTPException(status_code=404, detail="File not found") + + file_path = Path(app_settings.base_dir) / lib_file.file_path + if not file_path.exists(): + raise HTTPException(status_code=404, detail="File not found on disk") + + try: + with zipfile.ZipFile(file_path, "r") as zf: + thumb_path = f"Metadata/plate_{plate_index}.png" + if thumb_path in zf.namelist(): + data = zf.read(thumb_path) + return Response(content=data, media_type="image/png") + except Exception: + pass + + raise HTTPException(status_code=404, detail=f"Thumbnail for plate {plate_index} not found") + + +@router.get("/files/{file_id}/filament-requirements") +async def get_library_file_filament_requirements( + file_id: int, + plate_id: int | None = None, + db: AsyncSession = Depends(get_db), +): + """Get filament requirements from a library file. + + Parses the 3MF file to extract filament slot IDs, types, colors, and usage. + This enables AMS slot assignment when printing from the file manager. + + Args: + file_id: The library file ID + plate_id: Optional plate index to get filaments for a specific plate + """ + import xml.etree.ElementTree as ET + import zipfile + + # Get the library file + result = await db.execute(select(LibraryFile).where(LibraryFile.id == file_id)) + lib_file = result.scalar_one_or_none() + + if not lib_file: + raise HTTPException(status_code=404, detail="File not found") + + # Get the full file path + file_path = Path(app_settings.base_dir) / lib_file.file_path + + if not file_path.exists(): + raise HTTPException(status_code=404, detail="File not found on disk") + + # Only 3MF files have parseable filament info + if not lib_file.filename.lower().endswith(".3mf"): + return {"file_id": file_id, "filename": lib_file.filename, "plate_id": plate_id, "filaments": []} + + filaments = [] + + try: + with zipfile.ZipFile(file_path, "r") as zf: + # Parse slice_info.config for filament requirements + if "Metadata/slice_info.config" in zf.namelist(): + content = zf.read("Metadata/slice_info.config").decode() + root = ET.fromstring(content) + + if plate_id is not None: + # Find filaments for specific plate + for plate_elem in root.findall(".//plate"): + # Check if this is the requested plate + plate_index = None + for meta in plate_elem.findall("metadata"): + if meta.get("key") == "index": + try: + plate_index = int(meta.get("value", "")) + except ValueError: + pass + break + + if plate_index == plate_id: + # Extract filaments from this plate + for filament_elem in plate_elem.findall("filament"): + filament_id = filament_elem.get("id") + filament_type = filament_elem.get("type", "") + filament_color = filament_elem.get("color", "") + used_g = filament_elem.get("used_g", "0") + used_m = filament_elem.get("used_m", "0") + + try: + used_grams = float(used_g) + except (ValueError, TypeError): + used_grams = 0 + + if used_grams > 0 and filament_id: + filaments.append( + { + "slot_id": int(filament_id), + "type": filament_type, + "color": filament_color, + "used_grams": round(used_grams, 1), + "used_meters": float(used_m) if used_m else 0, + } + ) + break + else: + # Extract all filaments with used_g > 0 (for single-plate or overview) + for filament_elem in root.findall(".//filament"): + filament_id = filament_elem.get("id") + filament_type = filament_elem.get("type", "") + filament_color = filament_elem.get("color", "") + used_g = filament_elem.get("used_g", "0") + used_m = filament_elem.get("used_m", "0") + + try: + used_grams = float(used_g) + except (ValueError, TypeError): + used_grams = 0 + + if used_grams > 0 and filament_id: + filaments.append( + { + "slot_id": int(filament_id), + "type": filament_type, + "color": filament_color, + "used_grams": round(used_grams, 1), + "used_meters": float(used_m) if used_m else 0, + } + ) + + # Sort by slot ID + filaments.sort(key=lambda x: x["slot_id"]) + + except Exception as e: + logger.warning(f"Failed to parse filament requirements from library file {file_id}: {e}") + + return { + "file_id": file_id, + "filename": lib_file.filename, + "plate_id": plate_id, + "filaments": filaments, + } + + +@router.post("/files/{file_id}/print") +async def print_library_file( + file_id: int, + printer_id: int, + body: FilePrintRequest | None = None, + db: AsyncSession = Depends(get_db), +): + """Print a library file directly. + + This endpoint: + 1. Creates an archive from the library file + 2. Uploads the file to the printer + 3. Starts the print + + Only sliced files (.gcode or .gcode.3mf) can be printed. + """ + import zipfile + + from backend.app.main import register_expected_print + from backend.app.models.printer import Printer + from backend.app.services.bambu_ftp import ( + delete_file_async, + get_ftp_retry_settings, + upload_file_async, + with_ftp_retry, + ) + from backend.app.services.printer_manager import printer_manager + + # Use defaults if no body provided + if body is None: + body = FilePrintRequest() + + # Get the library file + result = await db.execute(select(LibraryFile).where(LibraryFile.id == file_id)) + lib_file = result.scalar_one_or_none() + + if not lib_file: + raise HTTPException(status_code=404, detail="File not found") + + # Validate file is sliced + if not is_sliced_file(lib_file.filename): + raise HTTPException( + status_code=400, + detail="Not a sliced file. Only .gcode or .gcode.3mf files can be printed.", + ) + + # Get the full file path + file_path = Path(app_settings.base_dir) / lib_file.file_path + + if not file_path.exists(): + raise HTTPException(status_code=404, detail="File not found on disk") + + # Get printer + result = await db.execute(select(Printer).where(Printer.id == printer_id)) + printer = result.scalar_one_or_none() + if not printer: + raise HTTPException(status_code=404, detail="Printer not found") + + # Check printer is connected + if not printer_manager.is_connected(printer_id): + raise HTTPException(status_code=400, detail="Printer is not connected") + + # Create archive from the library file + archive_service = ArchiveService(db) + archive = await archive_service.archive_print( + printer_id=printer_id, + source_file=file_path, + ) + + if not archive: + raise HTTPException(status_code=500, detail="Failed to create archive") + + await db.flush() + + # Prepare remote filename + base_name = lib_file.filename + if base_name.endswith(".gcode.3mf"): + base_name = base_name[:-10] + elif base_name.endswith(".3mf"): + base_name = base_name[:-4] + remote_filename = f"{base_name}.3mf" + remote_path = f"/{remote_filename}" + + # Get FTP retry settings + ftp_retry_enabled, ftp_retry_count, ftp_retry_delay, ftp_timeout = await get_ftp_retry_settings() + + # Delete existing file if present (avoids 553 error) + await delete_file_async( + printer.ip_address, + printer.access_code, + remote_path, + socket_timeout=ftp_timeout, + printer_model=printer.model, + ) + + # Upload file to printer + if ftp_retry_enabled: + uploaded = await with_ftp_retry( + upload_file_async, + printer.ip_address, + printer.access_code, + file_path, + remote_path, + socket_timeout=ftp_timeout, + printer_model=printer.model, + max_retries=ftp_retry_count, + retry_delay=ftp_retry_delay, + operation_name=f"Upload for print to {printer.name}", + ) + else: + uploaded = await upload_file_async( + printer.ip_address, + printer.access_code, + file_path, + remote_path, + socket_timeout=ftp_timeout, + printer_model=printer.model, + ) + + if not uploaded: + raise HTTPException(status_code=500, detail="Failed to upload file to printer") + + # Register this as an expected print so we don't create a duplicate archive + register_expected_print(printer_id, remote_filename, archive.id) + + # Determine plate ID + if body.plate_id is not None: + plate_id = body.plate_id + else: + plate_id = 1 + try: + with zipfile.ZipFile(file_path, "r") as zf: + for name in zf.namelist(): + if name.startswith("Metadata/plate_") and name.endswith(".gcode"): + plate_str = name[15:-6] + plate_id = int(plate_str) + break + except Exception: + pass + + logger.info( + f"Print library file {file_id}: archive_id={archive.id}, plate_id={plate_id}, " + f"ams_mapping={body.ams_mapping}, bed_levelling={body.bed_levelling}" + ) + + # Start the print + started = printer_manager.start_print( + printer_id, + remote_filename, + plate_id, + ams_mapping=body.ams_mapping, + timelapse=body.timelapse, + bed_levelling=body.bed_levelling, + flow_cali=body.flow_cali, + vibration_cali=body.vibration_cali, + layer_inspect=body.layer_inspect, + use_ams=body.use_ams, + ) + + if not started: + raise HTTPException(status_code=500, detail="Failed to start print") + + await db.commit() + + return { + "status": "printing", + "printer_id": printer_id, + "archive_id": archive.id, + "filename": lib_file.filename, + } + + # ============ File Detail Endpoints ============ diff --git a/backend/app/api/routes/print_queue.py b/backend/app/api/routes/print_queue.py index 4d95a091d..d5f7e9e68 100644 --- a/backend/app/api/routes/print_queue.py +++ b/backend/app/api/routes/print_queue.py @@ -11,6 +11,7 @@ from sqlalchemy.orm import selectinload from backend.app.core.database import get_db from backend.app.models.archive import PrintArchive +from backend.app.models.library import LibraryFile from backend.app.models.print_queue import PrintQueueItem from backend.app.models.printer import Printer from backend.app.schemas.print_queue import ( @@ -26,7 +27,7 @@ router = APIRouter(prefix="/queue", tags=["queue"]) def _enrich_response(item: PrintQueueItem) -> PrintQueueItemResponse: - """Add nested archive/printer info to response.""" + """Add nested archive/printer/library_file info to response.""" # Parse ams_mapping from JSON string BEFORE model_validate ams_mapping_parsed = None if item.ams_mapping: @@ -40,6 +41,7 @@ def _enrich_response(item: PrintQueueItem) -> PrintQueueItemResponse: "id": item.id, "printer_id": item.printer_id, "archive_id": item.archive_id, + "library_file_id": item.library_file_id, "position": item.position, "scheduled_time": item.scheduled_time, "require_previous_success": item.require_previous_success, @@ -64,6 +66,16 @@ def _enrich_response(item: PrintQueueItem) -> PrintQueueItemResponse: response.archive_name = item.archive.print_name or item.archive.filename response.archive_thumbnail = item.archive.thumbnail_path response.print_time_seconds = item.archive.print_time_seconds + if item.library_file: + response.library_file_name = ( + item.library_file.file_metadata.get("print_name") if item.library_file.file_metadata else None + ) + if not response.library_file_name: + response.library_file_name = item.library_file.filename + response.library_file_thumbnail = item.library_file.thumbnail_path + # Get print time from library file metadata if no archive + if not item.archive and item.library_file.file_metadata: + response.print_time_seconds = item.library_file.file_metadata.get("print_time_seconds") if item.printer: response.printer_name = item.printer.name return response @@ -78,7 +90,11 @@ async def list_queue( """List all queue items, optionally filtered by printer or status.""" query = ( select(PrintQueueItem) - .options(selectinload(PrintQueueItem.archive), selectinload(PrintQueueItem.printer)) + .options( + selectinload(PrintQueueItem.archive), + selectinload(PrintQueueItem.printer), + selectinload(PrintQueueItem.library_file), + ) .order_by(PrintQueueItem.printer_id.nulls_first(), PrintQueueItem.position) ) @@ -102,16 +118,27 @@ async def add_to_queue( db: AsyncSession = Depends(get_db), ): """Add an item to the print queue.""" + # Validate that either archive_id or library_file_id is provided + if not data.archive_id and not data.library_file_id: + raise HTTPException(400, "Either archive_id or library_file_id must be provided") + # Validate printer exists (if assigned) if data.printer_id is not None: result = await db.execute(select(Printer).where(Printer.id == data.printer_id)) if not result.scalar_one_or_none(): raise HTTPException(400, "Printer not found") - # Validate archive exists - result = await db.execute(select(PrintArchive).where(PrintArchive.id == data.archive_id)) - if not result.scalar_one_or_none(): - raise HTTPException(400, "Archive not found") + # Validate archive exists (if provided) + if data.archive_id: + result = await db.execute(select(PrintArchive).where(PrintArchive.id == data.archive_id)) + if not result.scalar_one_or_none(): + raise HTTPException(400, "Archive not found") + + # Validate library file exists (if provided) + if data.library_file_id: + result = await db.execute(select(LibraryFile).where(LibraryFile.id == data.library_file_id)) + if not result.scalar_one_or_none(): + raise HTTPException(400, "Library file not found") # Get next position for this printer (or for unassigned items) if data.printer_id is not None: @@ -132,6 +159,7 @@ async def add_to_queue( item = PrintQueueItem( printer_id=data.printer_id, archive_id=data.archive_id, + library_file_id=data.library_file_id, scheduled_time=data.scheduled_time, require_previous_success=data.require_previous_success, auto_off_after=data.auto_off_after, @@ -152,9 +180,10 @@ async def add_to_queue( await db.refresh(item) # Load relationships for response - await db.refresh(item, ["archive", "printer"]) + await db.refresh(item, ["archive", "printer", "library_file"]) - logger.info(f"Added archive {data.archive_id} to queue for printer {data.printer_id or 'unassigned'}") + source_name = f"archive {data.archive_id}" if data.archive_id else f"library file {data.library_file_id}" + logger.info(f"Added {source_name} to queue for printer {data.printer_id or 'unassigned'}") # MQTT relay - publish queue job added try: @@ -177,7 +206,11 @@ async def get_queue_item(item_id: int, db: AsyncSession = Depends(get_db)): """Get a specific queue item.""" result = await db.execute( select(PrintQueueItem) - .options(selectinload(PrintQueueItem.archive), selectinload(PrintQueueItem.printer)) + .options( + selectinload(PrintQueueItem.archive), + selectinload(PrintQueueItem.printer), + selectinload(PrintQueueItem.library_file), + ) .where(PrintQueueItem.id == item_id) ) item = result.scalar_one_or_none() @@ -217,7 +250,7 @@ async def update_queue_item( setattr(item, field, value) await db.commit() - await db.refresh(item, ["archive", "printer"]) + await db.refresh(item, ["archive", "printer", "library_file"]) logger.info(f"Updated queue item {item_id}") return _enrich_response(item) @@ -372,7 +405,7 @@ async def start_queue_item( # Clear manual_start flag so scheduler picks it up item.manual_start = False await db.commit() - await db.refresh(item, ["archive", "printer"]) + await db.refresh(item, ["archive", "printer", "library_file"]) logger.info(f"Manually started queue item {item_id} (cleared manual_start flag)") return _enrich_response(item) diff --git a/backend/app/core/database.py b/backend/app/core/database.py index 1a6011fe3..0da968cac 100644 --- a/backend/app/core/database.py +++ b/backend/app/core/database.py @@ -579,6 +579,68 @@ async def run_migrations(conn): except Exception: pass + # Migration: Add library_file_id column to print_queue and make archive_id nullable + # This allows queue items to reference library files directly (archive created at print start) + try: + await conn.execute( + text( + "ALTER TABLE print_queue ADD COLUMN library_file_id INTEGER REFERENCES library_files(id) ON DELETE CASCADE" + ) + ) + except Exception: + pass + + # Check if archive_id needs to be made nullable (requires table recreation in SQLite) + try: + result = await conn.execute(text("SELECT sql FROM sqlite_master WHERE type='table' AND name='print_queue'")) + row = result.fetchone() + if row and "archive_id INTEGER NOT NULL" in (row[0] or ""): + # Need to migrate - archive_id is currently NOT NULL + await conn.execute( + text(""" + CREATE TABLE print_queue_new2 ( + id INTEGER PRIMARY KEY, + printer_id INTEGER REFERENCES printers(id) ON DELETE CASCADE, + archive_id INTEGER REFERENCES print_archives(id) ON DELETE CASCADE, + library_file_id INTEGER REFERENCES library_files(id) ON DELETE CASCADE, + project_id INTEGER REFERENCES projects(id) ON DELETE SET NULL, + position INTEGER DEFAULT 0, + scheduled_time DATETIME, + manual_start BOOLEAN DEFAULT 0, + require_previous_success BOOLEAN DEFAULT 0, + auto_off_after BOOLEAN DEFAULT 0, + ams_mapping TEXT, + plate_id INTEGER, + bed_levelling BOOLEAN DEFAULT 1, + flow_cali BOOLEAN DEFAULT 0, + vibration_cali BOOLEAN DEFAULT 1, + layer_inspect BOOLEAN DEFAULT 0, + timelapse BOOLEAN DEFAULT 0, + use_ams BOOLEAN DEFAULT 1, + status VARCHAR(20) DEFAULT 'pending', + started_at DATETIME, + completed_at DATETIME, + error_message TEXT, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP + ) + """) + ) + await conn.execute( + text(""" + INSERT INTO print_queue_new2 + SELECT id, printer_id, archive_id, NULL, project_id, position, scheduled_time, + manual_start, require_previous_success, auto_off_after, ams_mapping, plate_id, + COALESCE(bed_levelling, 1), COALESCE(flow_cali, 0), COALESCE(vibration_cali, 1), + COALESCE(layer_inspect, 0), COALESCE(timelapse, 0), COALESCE(use_ams, 1), + status, started_at, completed_at, error_message, created_at + FROM print_queue + """) + ) + await conn.execute(text("DROP TABLE print_queue")) + await conn.execute(text("ALTER TABLE print_queue_new2 RENAME TO print_queue")) + except Exception: + pass + async def seed_notification_templates(): """Seed default notification templates if they don't exist.""" diff --git a/backend/app/models/print_queue.py b/backend/app/models/print_queue.py index 3062ce771..64ccc4980 100644 --- a/backend/app/models/print_queue.py +++ b/backend/app/models/print_queue.py @@ -15,7 +15,11 @@ class PrintQueueItem(Base): # Links printer_id: Mapped[int | None] = mapped_column(ForeignKey("printers.id", ondelete="CASCADE"), nullable=True) - archive_id: Mapped[int] = mapped_column(ForeignKey("print_archives.id", ondelete="CASCADE")) + # Either archive_id OR library_file_id must be set (archive created at print start from library file) + archive_id: Mapped[int | None] = mapped_column(ForeignKey("print_archives.id", ondelete="CASCADE"), nullable=True) + library_file_id: Mapped[int | None] = mapped_column( + ForeignKey("library_files.id", ondelete="CASCADE"), nullable=True + ) project_id: Mapped[int | None] = mapped_column(ForeignKey("projects.id", ondelete="SET NULL"), nullable=True) # Scheduling @@ -57,10 +61,12 @@ class PrintQueueItem(Base): # Relationships printer: Mapped["Printer"] = relationship() - archive: Mapped["PrintArchive"] = relationship() + archive: Mapped["PrintArchive | None"] = relationship() + library_file: Mapped["LibraryFile | None"] = relationship() project: Mapped["Project | None"] = relationship(back_populates="queue_items") from backend.app.models.archive import PrintArchive # noqa: E402 +from backend.app.models.library import LibraryFile # noqa: E402 from backend.app.models.printer import Printer # noqa: E402 from backend.app.models.project import Project # noqa: E402 diff --git a/backend/app/schemas/library.py b/backend/app/schemas/library.py index b72b58805..b78ce9a5f 100644 --- a/backend/app/schemas/library.py +++ b/backend/app/schemas/library.py @@ -159,9 +159,10 @@ class FileMoveRequest(BaseModel): class FilePrintRequest(BaseModel): - """Schema for printing a file from the library.""" + """Schema for printing a file from the library. - printer_id: str # Printer serial number + Note: printer_id is passed as a query parameter, not in the body. + """ # Print options (same as archive reprint) plate_id: int | None = None @@ -218,7 +219,6 @@ class AddToQueueResult(BaseModel): file_id: int filename: str queue_item_id: int - archive_id: int class AddToQueueError(BaseModel): diff --git a/backend/app/schemas/print_queue.py b/backend/app/schemas/print_queue.py index 8f3a77950..4cc2ce80e 100644 --- a/backend/app/schemas/print_queue.py +++ b/backend/app/schemas/print_queue.py @@ -17,7 +17,9 @@ UTCDatetime = Annotated[datetime | None, PlainSerializer(serialize_utc_datetime) class PrintQueueItemCreate(BaseModel): printer_id: int | None = None # None = unassigned, user assigns later - archive_id: int + # Either archive_id OR library_file_id must be provided + archive_id: int | None = None + library_file_id: int | None = None scheduled_time: datetime | None = None # None = ASAP (next when idle) require_previous_success: bool = False auto_off_after: bool = False # Power off printer after print completes @@ -57,7 +59,8 @@ class PrintQueueItemUpdate(BaseModel): class PrintQueueItemResponse(BaseModel): id: int printer_id: int | None # None = unassigned - archive_id: int + archive_id: int | None # None if library_file_id is set (archive created at print start) + library_file_id: int | None # For queue items from library files position: int scheduled_time: UTCDatetime require_previous_success: bool @@ -81,8 +84,10 @@ class PrintQueueItemResponse(BaseModel): # Nested info for UI (populated in route) archive_name: str | None = None archive_thumbnail: str | None = None + library_file_name: str | None = None # Name of library file (if library_file_id is set) + library_file_thumbnail: str | None = None # Thumbnail of library file printer_name: str | None = None - print_time_seconds: int | None = None # Estimated print time from archive + print_time_seconds: int | None = None # Estimated print time from archive or library file class Config: from_attributes = True diff --git a/backend/tests/integration/test_print_queue_api.py b/backend/tests/integration/test_print_queue_api.py index 5ec94c31e..712d33152 100644 --- a/backend/tests/integration/test_print_queue_api.py +++ b/backend/tests/integration/test_print_queue_api.py @@ -540,3 +540,197 @@ class TestQueueCancelEndpoint: response = await async_client.post(f"/api/v1/queue/{item.id}/cancel") assert response.status_code == 400 + + +class TestQueueLibraryFileSupport: + """Tests for queue items with library_file_id (instead of archive_id).""" + + @pytest.fixture + async def printer_factory(self, db_session): + """Factory to create test printers.""" + _counter = [0] + + async def _create_printer(**kwargs): + from backend.app.models.printer import Printer + + _counter[0] += 1 + counter = _counter[0] + + defaults = { + "name": f"Library Test Printer {counter}", + "ip_address": f"192.168.1.{150 + counter}", + "serial_number": f"TESTLIB{counter:04d}", + "access_code": "12345678", + "model": "X1C", + } + defaults.update(kwargs) + + printer = Printer(**defaults) + db_session.add(printer) + await db_session.commit() + await db_session.refresh(printer) + return printer + + return _create_printer + + @pytest.fixture + async def library_file_factory(self, db_session): + """Factory to create test library files.""" + _counter = [0] + + async def _create_library_file(**kwargs): + from backend.app.models.library import LibraryFile + + _counter[0] += 1 + counter = _counter[0] + + defaults = { + "filename": f"library_test_{counter}.3mf", + "file_path": f"/test/library/library_test_{counter}.3mf", + "file_size": 2048, + "file_type": "3mf", + "file_metadata": {"print_name": f"Library Print {counter}", "print_time_seconds": 3600}, + } + defaults.update(kwargs) + + lib_file = LibraryFile(**defaults) + db_session.add(lib_file) + await db_session.commit() + await db_session.refresh(lib_file) + return lib_file + + return _create_library_file + + @pytest.mark.asyncio + @pytest.mark.integration + async def test_add_to_queue_with_library_file( + self, async_client: AsyncClient, printer_factory, library_file_factory, db_session + ): + """Verify item can be added to queue using library_file_id instead of archive_id.""" + printer = await printer_factory() + lib_file = await library_file_factory() + + data = { + "printer_id": printer.id, + "library_file_id": lib_file.id, + } + response = await async_client.post("/api/v1/queue/", json=data) + assert response.status_code == 200 + result = response.json() + assert result["printer_id"] == printer.id + assert result["library_file_id"] == lib_file.id + assert result["archive_id"] is None + assert result["status"] == "pending" + assert result["library_file_name"] == "Library Print 1" + assert result["print_time_seconds"] == 3600 + + @pytest.mark.asyncio + @pytest.mark.integration + async def test_add_to_queue_library_file_with_options( + self, async_client: AsyncClient, printer_factory, library_file_factory, db_session + ): + """Verify library file queue item can have all options set.""" + printer = await printer_factory() + lib_file = await library_file_factory() + + data = { + "printer_id": printer.id, + "library_file_id": lib_file.id, + "ams_mapping": [1, 2, -1, -1], + "plate_id": 2, + "bed_levelling": False, + "timelapse": True, + "manual_start": True, + } + response = await async_client.post("/api/v1/queue/", json=data) + assert response.status_code == 200 + result = response.json() + assert result["library_file_id"] == lib_file.id + assert result["ams_mapping"] == [1, 2, -1, -1] + assert result["plate_id"] == 2 + assert result["bed_levelling"] is False + assert result["timelapse"] is True + assert result["manual_start"] is True + + @pytest.mark.asyncio + @pytest.mark.integration + async def test_add_to_queue_requires_archive_or_library_file( + self, async_client: AsyncClient, printer_factory, db_session + ): + """Verify 400 error when neither archive_id nor library_file_id provided.""" + printer = await printer_factory() + + data = { + "printer_id": printer.id, + } + response = await async_client.post("/api/v1/queue/", json=data) + assert response.status_code == 400 + assert ( + "archive_id" in response.json()["detail"].lower() or "library_file_id" in response.json()["detail"].lower() + ) + + @pytest.mark.asyncio + @pytest.mark.integration + async def test_update_queue_item_with_library_file( + self, async_client: AsyncClient, printer_factory, library_file_factory, db_session + ): + """Verify queue item with library_file_id can be updated.""" + from backend.app.models.print_queue import PrintQueueItem + + printer = await printer_factory() + lib_file = await library_file_factory() + + # Create queue item directly + item = PrintQueueItem( + printer_id=printer.id, + library_file_id=lib_file.id, + status="pending", + position=1, + ) + db_session.add(item) + await db_session.commit() + await db_session.refresh(item) + + # Update the item + response = await async_client.patch( + f"/api/v1/queue/{item.id}", + json={"auto_off_after": True, "plate_id": 3}, + ) + assert response.status_code == 200 + result = response.json() + assert result["auto_off_after"] is True + assert result["plate_id"] == 3 + assert result["library_file_id"] == lib_file.id + + @pytest.mark.asyncio + @pytest.mark.integration + async def test_list_queue_includes_library_file_info( + self, async_client: AsyncClient, printer_factory, library_file_factory, db_session + ): + """Verify queue list includes library file metadata.""" + from backend.app.models.print_queue import PrintQueueItem + + printer = await printer_factory() + lib_file = await library_file_factory( + file_metadata={"print_name": "Custom Print Name", "print_time_seconds": 7200} + ) + + item = PrintQueueItem( + printer_id=printer.id, + library_file_id=lib_file.id, + status="pending", + position=1, + ) + db_session.add(item) + await db_session.commit() + + response = await async_client.get("/api/v1/queue/") + assert response.status_code == 200 + items = response.json() + assert len(items) >= 1 + + # Find our item + our_item = next((i for i in items if i["library_file_id"] == lib_file.id), None) + assert our_item is not None + assert our_item["library_file_name"] == "Custom Print Name" + assert our_item["print_time_seconds"] == 7200 diff --git a/frontend/src/api/client.ts b/frontend/src/api/client.ts index 2539442d7..042eb8b5e 100644 --- a/frontend/src/api/client.ts +++ b/frontend/src/api/client.ts @@ -845,7 +845,9 @@ export interface DiscoveredTasmotaDevice { export interface PrintQueueItem { id: number; printer_id: number | null; // null = unassigned - archive_id: number; + // Either archive_id OR library_file_id must be set (archive created at print start) + archive_id: number | null; + library_file_id: number | null; position: number; scheduled_time: string | null; require_previous_success: boolean; @@ -867,13 +869,17 @@ export interface PrintQueueItem { created_at: string; archive_name?: string | null; archive_thumbnail?: string | null; + library_file_name?: string | null; + library_file_thumbnail?: string | null; printer_name?: string | null; - print_time_seconds?: number | null; // Estimated print time from archive + print_time_seconds?: number | null; // Estimated print time from archive or library file } export interface PrintQueueItemCreate { printer_id?: number | null; // null = unassigned - archive_id: number; + // Either archive_id OR library_file_id must be provided + archive_id?: number | null; + library_file_id?: number | null; scheduled_time?: string | null; require_previous_success?: boolean; auto_off_after?: boolean; @@ -2594,6 +2600,61 @@ export const api = { method: 'POST', body: JSON.stringify({ file_ids: fileIds }), }), + printLibraryFile: ( + fileId: number, + printerId: number, + options?: { + plate_id?: number; + ams_mapping?: number[]; + bed_levelling?: boolean; + flow_cali?: boolean; + vibration_cali?: boolean; + layer_inspect?: boolean; + timelapse?: boolean; + use_ams?: boolean; + } + ) => + request<{ status: string; printer_id: number; archive_id: number; filename: string }>( + `/library/files/${fileId}/print?printer_id=${printerId}`, + { + method: 'POST', + body: options ? JSON.stringify(options) : undefined, + } + ), + getLibraryFilePlates: (fileId: number) => + request<{ + file_id: number; + filename: string; + plates: Array<{ + index: number; + name: string | null; + objects: string[]; + has_thumbnail: boolean; + thumbnail_url: string | null; + print_time_seconds: number | null; + filament_used_grams: number | null; + filaments: Array<{ + slot_id: number; + type: string; + color: string; + used_grams: number; + used_meters: number; + }>; + }>; + is_multi_plate: boolean; + }>(`/library/files/${fileId}/plates`), + getLibraryFileFilamentRequirements: (fileId: number, plateId?: number) => + request<{ + file_id: number; + filename: string; + filaments: Array<{ + slot_id: number; + type: string; + color: string; + used_grams: number; + used_meters: number; + }>; + }>(`/library/files/${fileId}/filament-requirements${plateId !== undefined ? `?plate_id=${plateId}` : ''}`), }; // AMS History types diff --git a/frontend/src/components/PrintModal/FilamentMapping.tsx b/frontend/src/components/PrintModal/FilamentMapping.tsx index 07511f68d..5d1145154 100644 --- a/frontend/src/components/PrintModal/FilamentMapping.tsx +++ b/frontend/src/components/PrintModal/FilamentMapping.tsx @@ -12,9 +12,7 @@ import type { FilamentMappingProps } from './types'; */ export function FilamentMapping({ printerId, - archiveId, - selectedPlate, - isMultiPlate, + filamentReqs, manualMappings, onManualMappingChange, }: FilamentMappingProps) { @@ -22,13 +20,6 @@ export function FilamentMapping({ const [isRefreshing, setIsRefreshing] = useState(false); const [isExpanded, setIsExpanded] = useState(false); - // Fetch filament requirements from the archived 3MF (filtered by plate if selected) - const { data: filamentReqs } = useQuery({ - queryKey: ['archive-filaments', archiveId, selectedPlate], - queryFn: () => api.getArchiveFilamentRequirements(archiveId, selectedPlate ?? undefined), - enabled: selectedPlate !== null || !isMultiPlate, - }); - // Fetch printer status const { data: printerStatus } = useQuery({ queryKey: ['printer-status', printerId], diff --git a/frontend/src/components/PrintModal/PrinterSelector.tsx b/frontend/src/components/PrintModal/PrinterSelector.tsx index 4d91ccde8..614970b05 100644 --- a/frontend/src/components/PrintModal/PrinterSelector.tsx +++ b/frontend/src/components/PrintModal/PrinterSelector.tsx @@ -2,21 +2,19 @@ import { Printer as PrinterIcon, Loader2, AlertCircle, Check } from 'lucide-reac import type { PrinterSelectorProps } from './types'; /** - * Printer selection component with multiple modes: - * - Grid mode (default): Shows printers as selectable cards (single or multi-select) - * - Dropdown mode: Shows printers in a select dropdown (used when allowUnassigned is true) + * Printer selection component with grid-based UI. + * Supports single or multi-select modes. */ export function PrinterSelector({ printers, - selectedPrinterId, - selectedPrinterIds = [], - onSelect, + selectedPrinterIds, onMultiSelect, isLoading = false, - allowUnassigned = false, allowMultiple = false, + showInactive = false, }: PrinterSelectorProps) { - const activePrinters = printers.filter((p) => p.is_active); + // Filter printers based on showInactive flag + const displayPrinters = showInactive ? printers : printers.filter((p) => p.is_active); if (isLoading) { return ( @@ -26,53 +24,17 @@ export function PrinterSelector({ ); } - // Use dropdown mode for edit scenarios (allows unassigning printer) - if (allowUnassigned) { + if (displayPrinters.length === 0) { return ( -
- - {printers.length === 0 ? ( -
- - No printers configured -
- ) : ( - <> - - {selectedPrinterId === null && ( -

- - Assign a printer to enable printing -

- )} - - )} +
+ + No {showInactive ? '' : 'active '}printers available
); } - // Grid mode for reprint/add-to-queue (only active printers) - if (activePrinters.length === 0) { - return ( -
No active printers available
- ); - } - const handlePrinterClick = (printerId: number) => { - if (allowMultiple && onMultiSelect) { + if (allowMultiple) { // Multi-select mode: toggle printer in selection if (selectedPrinterIds.includes(printerId)) { onMultiSelect(selectedPrinterIds.filter((id) => id !== printerId)); @@ -80,36 +42,27 @@ export function PrinterSelector({ onMultiSelect([...selectedPrinterIds, printerId]); } } else { - // Single-select mode - onSelect(printerId); + // Single-select mode: replace selection + onMultiSelect([printerId]); } }; const handleSelectAll = () => { - if (onMultiSelect) { - onMultiSelect(activePrinters.map((p) => p.id)); - } + onMultiSelect(displayPrinters.map((p) => p.id)); }; const handleDeselectAll = () => { - if (onMultiSelect) { - onMultiSelect([]); - } + onMultiSelect([]); }; - const isSelected = (printerId: number) => { - if (allowMultiple) { - return selectedPrinterIds.includes(printerId); - } - return selectedPrinterId === printerId; - }; + const isSelected = (printerId: number) => selectedPrinterIds.includes(printerId); - const selectedCount = allowMultiple ? selectedPrinterIds.length : (selectedPrinterId ? 1 : 0); + const selectedCount = selectedPrinterIds.length; return (
{/* Multi-select header */} - {allowMultiple && activePrinters.length > 1 && ( + {allowMultiple && displayPrinters.length > 1 && (
{selectedCount === 0 @@ -117,7 +70,7 @@ export function PrinterSelector({ : `${selectedCount} printer${selectedCount !== 1 ? 's' : ''} selected`}
- {selectedCount < activePrinters.length && ( + {selectedCount < displayPrinters.length && ( ))} + + {/* Warning when no printer selected */} + {selectedCount === 0 && ( +

+ + Select at least one printer +

+ )}
); } diff --git a/frontend/src/components/PrintModal/index.tsx b/frontend/src/components/PrintModal/index.tsx index 62ed763d8..1a9a2b885 100644 --- a/frontend/src/components/PrintModal/index.tsx +++ b/frontend/src/components/PrintModal/index.tsx @@ -23,13 +23,17 @@ import { DEFAULT_PRINT_OPTIONS, DEFAULT_SCHEDULE_OPTIONS } from './types'; /** * Unified PrintModal component that handles three modes: - * - 'reprint': Immediate print from archive (supports multi-printer) - * - 'add-to-queue': Schedule print to queue (supports multi-printer) - * - 'edit-queue-item': Edit existing queue item (single printer only) + * - 'reprint': Immediate print from archive or library file (supports multi-printer) + * - 'add-to-queue': Schedule print to queue from archive or library file (supports multi-printer) + * - 'edit-queue-item': Edit existing queue item (supports multi-printer) + * + * Both archiveId and libraryFileId are supported. Library files can be printed immediately + * or added to queue (archive is created at print start time, not when queued). */ export function PrintModal({ mode, archiveId, + libraryFileId, archiveName, queueItem, onClose, @@ -38,16 +42,17 @@ export function PrintModal({ const queryClient = useQueryClient(); const { showToast } = useToast(); - // Single printer selection (for edit mode and backward compatibility) - const [selectedPrinter, setSelectedPrinter] = useState(() => { - if (mode === 'edit-queue-item' && queueItem) { - return queueItem.printer_id; - } - return null; - }); + // Determine if we're printing a library file + const isLibraryFile = !!libraryFileId && !archiveId; - // Multiple printer selection (for reprint and add-to-queue modes) - const [selectedPrinters, setSelectedPrinters] = useState([]); + // Multiple printer selection (used for all modes now) + const [selectedPrinters, setSelectedPrinters] = useState(() => { + // Initialize with the queue item's printer if editing + if (mode === 'edit-queue-item' && queueItem?.printer_id) { + return [queueItem.printer_id]; + } + return []; + }); const [selectedPlate, setSelectedPlate] = useState(() => { if (mode === 'edit-queue-item' && queueItem) { @@ -109,20 +114,17 @@ export function PrintModal({ }); // Track initial values for clearing mappings on change (edit mode only) - const [initialPrinterId] = useState(() => (mode === 'edit-queue-item' && queueItem ? queueItem.printer_id : null)); + const [initialPrinterIds] = useState(() => (mode === 'edit-queue-item' && queueItem?.printer_id ? [queueItem.printer_id] : [])); const [initialPlateId] = useState(() => (mode === 'edit-queue-item' && queueItem ? queueItem.plate_id : null)); // Submission state for multi-printer const [isSubmitting, setIsSubmitting] = useState(false); const [submitProgress, setSubmitProgress] = useState({ current: 0, total: 0 }); - // Determine if we're in multi-printer mode - const isMultiPrinterMode = mode !== 'edit-queue-item'; - const effectivePrinterCount = isMultiPrinterMode ? selectedPrinters.length : (selectedPrinter ? 1 : 0); + // Printer counts and effective printer for filament mapping + const effectivePrinterCount = selectedPrinters.length; // For filament mapping, use first selected printer (mapping applies to all) - const effectivePrinterId = isMultiPrinterMode - ? (selectedPrinters.length > 0 ? selectedPrinters[0] : null) - : selectedPrinter; + const effectivePrinterId = selectedPrinters.length > 0 ? selectedPrinters[0] : null; // Queries const { data: printers, isLoading: loadingPrinters } = useQuery({ @@ -130,17 +132,45 @@ export function PrintModal({ queryFn: api.getPrinters, }); - const { data: platesData } = useQuery({ + // Fetch plates for archives + const { data: archivePlatesData, isError: archivePlatesError } = useQuery({ queryKey: ['archive-plates', archiveId], - queryFn: () => api.getArchivePlates(archiveId), + queryFn: () => api.getArchivePlates(archiveId!), + enabled: !!archiveId && !isLibraryFile, + retry: false, }); - const { data: filamentReqs } = useQuery({ - queryKey: ['archive-filaments', archiveId, selectedPlate], - queryFn: () => api.getArchiveFilamentRequirements(archiveId, selectedPlate ?? undefined), - enabled: selectedPlate !== null || !platesData?.is_multi_plate, + // Fetch plates for library files + const { data: libraryPlatesData } = useQuery({ + queryKey: ['library-file-plates', libraryFileId], + queryFn: () => api.getLibraryFilePlates(libraryFileId!), + enabled: isLibraryFile && !!libraryFileId, }); + // Combine plates data from either source + const platesData = isLibraryFile ? libraryPlatesData : archivePlatesData; + + // Fetch filament requirements for archives + const { data: archiveFilamentReqs, isError: archiveFilamentReqsError } = useQuery({ + queryKey: ['archive-filaments', archiveId, selectedPlate], + queryFn: () => api.getArchiveFilamentRequirements(archiveId!, selectedPlate ?? undefined), + enabled: !!archiveId && !isLibraryFile && (selectedPlate !== null || !platesData?.is_multi_plate), + retry: false, + }); + + // Fetch filament requirements for library files (with plate support) + const { data: libraryFilamentReqs } = useQuery({ + queryKey: ['library-file-filaments', libraryFileId, selectedPlate], + queryFn: () => api.getLibraryFileFilamentRequirements(libraryFileId!, selectedPlate ?? undefined), + enabled: isLibraryFile && !!libraryFileId && (selectedPlate !== null || !platesData?.is_multi_plate), + }); + + // Track if archive data couldn't be loaded (archive deleted or file missing) + const archiveDataMissing = !isLibraryFile && (archivePlatesError || archiveFilamentReqsError); + + // Combine filament requirements from either source + const effectiveFilamentReqs = isLibraryFile ? libraryFilamentReqs : archiveFilamentReqs; + // Only fetch printer status when single printer selected (for filament mapping) const { data: printerStatus } = useQuery({ queryKey: ['printer-status', effectivePrinterId], @@ -149,7 +179,7 @@ export function PrintModal({ }); // Get AMS mapping from hook (only when single printer selected) - const { amsMapping } = useFilamentMapping(filamentReqs, printerStatus, manualMappings); + const { amsMapping } = useFilamentMapping(effectiveFilamentReqs, printerStatus, manualMappings); // Auto-select first plate for single-plate files useEffect(() => { @@ -158,8 +188,9 @@ export function PrintModal({ } }, [platesData, selectedPlate]); - // Auto-select first printer when only one available (non-multi mode) + // Auto-select first printer when only one available useEffect(() => { + // Skip auto-select for edit mode (already initialized from queueItem) if (mode === 'edit-queue-item') return; const activePrinters = printers?.filter(p => p.is_active) || []; if (activePrinters.length === 1 && selectedPrinters.length === 0) { @@ -170,13 +201,15 @@ export function PrintModal({ // Clear manual mappings when printer or plate changes useEffect(() => { if (mode === 'edit-queue-item') { - if (selectedPrinter !== initialPrinterId || selectedPlate !== initialPlateId) { + // For edit mode, clear mappings if printer selection or plate changed from initial + const printersChanged = JSON.stringify(selectedPrinters.sort()) !== JSON.stringify(initialPrinterIds.sort()); + if (printersChanged || selectedPlate !== initialPlateId) { setManualMappings({}); } } else { setManualMappings({}); } - }, [mode, selectedPrinter, selectedPrinters, selectedPlate, initialPrinterId, initialPlateId]); + }, [mode, selectedPrinters, selectedPlate, initialPrinterIds, initialPlateId]); // Close on Escape key useEffect(() => { @@ -212,29 +245,7 @@ export function PrintModal({ const handleSubmit = async (e?: React.FormEvent) => { e?.preventDefault(); - if (mode === 'edit-queue-item') { - // Edit mode - single printer update - const data: PrintQueueItemUpdate = { - printer_id: selectedPrinter, - require_previous_success: scheduleOptions.requirePreviousSuccess, - auto_off_after: scheduleOptions.autoOffAfter, - manual_start: scheduleOptions.scheduleType === 'manual', - ams_mapping: amsMapping, - plate_id: selectedPlate, - ...printOptions, - }; - - if (scheduleOptions.scheduleType === 'scheduled' && scheduleOptions.scheduledTime) { - data.scheduled_time = new Date(scheduleOptions.scheduledTime).toISOString(); - } else { - data.scheduled_time = null; - } - - updateQueueMutation.mutate(data); - return; - } - - // Multi-printer modes (reprint or add-to-queue) + // Validate printer selection if (selectedPrinters.length === 0) { showToast('Please select at least one printer', 'error'); return; @@ -249,37 +260,60 @@ export function PrintModal({ errors: [], }; + // Common queue data for add-to-queue and edit modes + const getQueueData = (printerId: number): PrintQueueItemCreate => ({ + printer_id: printerId, + // Use library_file_id for library files, archive_id for archives + archive_id: isLibraryFile ? undefined : archiveId, + library_file_id: isLibraryFile ? libraryFileId : undefined, + require_previous_success: scheduleOptions.requirePreviousSuccess, + auto_off_after: scheduleOptions.autoOffAfter, + manual_start: scheduleOptions.scheduleType === 'manual', + ams_mapping: amsMapping, + plate_id: selectedPlate, + scheduled_time: scheduleOptions.scheduleType === 'scheduled' && scheduleOptions.scheduledTime + ? new Date(scheduleOptions.scheduledTime).toISOString() + : undefined, + ...printOptions, + }); + for (let i = 0; i < selectedPrinters.length; i++) { const printerId = selectedPrinters[i]; setSubmitProgress({ current: i + 1, total: selectedPrinters.length }); try { - // Use the same AMS mapping for all printers (configured via UI based on first printer) - // This assumes all printers have the same filament configuration if (mode === 'reprint') { - await api.reprintArchive(archiveId, printerId, { - plate_id: selectedPlate ?? undefined, - ams_mapping: amsMapping, - ...printOptions, - }); - } else { - // add-to-queue mode - const data: PrintQueueItemCreate = { + // Reprint mode - start print immediately + if (isLibraryFile) { + await api.printLibraryFile(libraryFileId!, printerId, { + ams_mapping: amsMapping, + ...printOptions, + }); + } else { + await api.reprintArchive(archiveId!, printerId, { + plate_id: selectedPlate ?? undefined, + ams_mapping: amsMapping, + ...printOptions, + }); + } + } else if (mode === 'edit-queue-item' && i === 0) { + // Edit mode - update the original queue item for the first printer + const updateData: PrintQueueItemUpdate = { printer_id: printerId, - archive_id: archiveId, require_previous_success: scheduleOptions.requirePreviousSuccess, auto_off_after: scheduleOptions.autoOffAfter, manual_start: scheduleOptions.scheduleType === 'manual', ams_mapping: amsMapping, plate_id: selectedPlate, + scheduled_time: scheduleOptions.scheduleType === 'scheduled' && scheduleOptions.scheduledTime + ? new Date(scheduleOptions.scheduledTime).toISOString() + : null, ...printOptions, }; - - if (scheduleOptions.scheduleType === 'scheduled' && scheduleOptions.scheduledTime) { - data.scheduled_time = new Date(scheduleOptions.scheduledTime).toISOString(); - } - - await addToQueueMutation.mutateAsync(data); + await updateQueueMutation.mutateAsync(updateData); + } else { + // Add-to-queue mode OR edit mode with additional printers + await addToQueueMutation.mutateAsync(getQueueData(printerId)); } results.success++; } catch (error) { @@ -293,9 +327,9 @@ export function PrintModal({ // Show result toast if (results.failed === 0) { - const action = mode === 'reprint' ? 'sent to' : 'queued for'; + const action = mode === 'reprint' ? 'sent to' : (mode === 'edit-queue-item' ? 'updated/queued for' : 'queued for'); if (results.success === 1) { - showToast(`Print ${action} printer`); + showToast(mode === 'edit-queue-item' ? 'Queue item updated' : `Print ${action} printer`); } else { showToast(`Print ${action} ${results.success} printers`); } @@ -315,27 +349,22 @@ export function PrintModal({ const canSubmit = useMemo(() => { if (isPending) return false; - // For edit mode, printer can be null (unassigned) - if (mode === 'edit-queue-item') { - return (printers?.length ?? 0) > 0; - } - - // For reprint and add-to-queue, need at least one selected printer + // Need at least one selected printer if (selectedPrinters.length === 0) return false; - // For multi-plate files, need a selected plate - if (isMultiPlate && !selectedPlate) return false; + // For multi-plate archive files, need a selected plate (library files skip this) + if (!isLibraryFile && isMultiPlate && !selectedPlate) return false; return true; - }, [mode, selectedPrinters.length, isMultiPlate, selectedPlate, isPending, printers]); + }, [selectedPrinters.length, isMultiPlate, selectedPlate, isPending, isLibraryFile]); // Modal title and action button text based on mode const getModalConfig = () => { - const printerCount = isMultiPrinterMode ? selectedPrinters.length : 1; + const printerCount = selectedPrinters.length; if (mode === 'reprint') { return { - title: 'Re-print', + title: isLibraryFile ? 'Print' : 'Re-print', icon: Printer, submitText: printerCount > 1 ? `Print to ${printerCount} Printers` : 'Print', submitIcon: Printer, @@ -355,12 +384,15 @@ export function PrintModal({ : 'Adding...', }; } + // edit-queue-item mode return { title: 'Edit Queue Item', icon: Pencil, - submitText: 'Save Changes', + submitText: 'Save', submitIcon: Pencil, - loadingText: 'Saving...', + loadingText: submitProgress.total > 1 + ? `Saving ${submitProgress.current}/${submitProgress.total}...` + : 'Saving...', }; }; @@ -368,8 +400,13 @@ export function PrintModal({ const TitleIcon = modalConfig.icon; const SubmitIcon = modalConfig.submitIcon; - // Show filament mapping only when single printer selected - const showFilamentMapping = effectivePrinterId && (isMultiPlate ? selectedPlate !== null : true); + // Show filament mapping when: + // - Single printer selected + // - For archives: plate is selected (for multi-plate) or not required (single-plate) + // - For library files: always show (no plate selection) + const showFilamentMapping = effectivePrinterId && ( + isLibraryFile || (isMultiPlate ? selectedPlate !== null : true) + ); return (
{mode === 'reprint' ? ( <> - Send {archiveName} to{' '} - {isMultiPrinterMode ? 'printer(s)' : 'a printer'} + Send {archiveName} to printer(s) ) : ( <> @@ -415,17 +451,15 @@ export function PrintModal({ {/* Printer selection */} {/* Multi-printer filament mapping note */} - {isMultiPrinterMode && selectedPrinters.length > 1 && ( + {selectedPrinters.length > 1 && (

@@ -442,13 +476,21 @@ export function PrintModal({ onSelect={setSelectedPlate} /> - {/* Filament mapping - show when single printer selected and plate ready */} - {showFilamentMapping && ( + {/* Warning when archive data couldn't be loaded */} + {archiveDataMissing && ( +

+ +

+ Archive data unavailable. The source file may have been deleted. Filament mapping is disabled. +

+
+ )} + + {/* Filament mapping - show when printer selected and filament requirements available */} + {showFilamentMapping && !archiveDataMissing && ( diff --git a/frontend/src/components/PrintModal/types.ts b/frontend/src/components/PrintModal/types.ts index c73d7d08e..b48caa41e 100644 --- a/frontend/src/components/PrintModal/types.ts +++ b/frontend/src/components/PrintModal/types.ts @@ -10,13 +10,19 @@ export type PrintModalMode = 'reprint' | 'add-to-queue' | 'edit-queue-item'; /** * Props for the unified PrintModal component. + * + * Either archiveId or libraryFileId must be provided. + * - archiveId: For reprinting/queueing archives + * - libraryFileId: For printing library files directly */ export interface PrintModalProps { /** Modal operation mode */ mode: PrintModalMode; - /** Archive ID to print */ - archiveId: number; - /** Archive display name */ + /** Archive ID to print (mutually exclusive with libraryFileId) */ + archiveId?: number; + /** Library file ID to print (mutually exclusive with archiveId) */ + libraryFileId?: number; + /** Display name for the print */ archiveName: string; /** Existing queue item (only for edit-queue-item mode) */ queueItem?: PrintQueueItem; @@ -103,13 +109,12 @@ export interface PlatesResponse { */ export interface PrinterSelectorProps { printers: Printer[]; - selectedPrinterId: number | null; - selectedPrinterIds?: number[]; - onSelect: (printerId: number | null) => void; - onMultiSelect?: (printerIds: number[]) => void; + selectedPrinterIds: number[]; + onMultiSelect: (printerIds: number[]) => void; isLoading?: boolean; - allowUnassigned?: boolean; allowMultiple?: boolean; + /** Show inactive printers (for edit mode where original assignment may be inactive) */ + showInactive?: boolean; } /** @@ -122,14 +127,26 @@ export interface PlateSelectorProps { onSelect: (plateIndex: number) => void; } +/** + * Filament requirement data structure. + */ +export interface FilamentReqsData { + filaments: Array<{ + slot_id: number; + type: string; + color: string; + used_grams: number; + used_meters: number; + }>; +} + /** * Props for the FilamentMapping component. */ export interface FilamentMappingProps { printerId: number; - archiveId: number; - selectedPlate: number | null; - isMultiPlate: boolean; + /** Pre-fetched filament requirements data */ + filamentReqs: FilamentReqsData | undefined; manualMappings: Record; onManualMappingChange: (mappings: Record) => void; } diff --git a/frontend/src/pages/FileManagerPage.tsx b/frontend/src/pages/FileManagerPage.tsx index 57c3e5128..13bfc0613 100644 --- a/frontend/src/pages/FileManagerPage.tsx +++ b/frontend/src/pages/FileManagerPage.tsx @@ -46,6 +46,7 @@ import type { } from '../api/client'; import { Button } from '../components/Button'; import { ConfirmModal } from '../components/ConfirmModal'; +import { PrintModal } from '../components/PrintModal'; import { useToast } from '../contexts/ToastContext'; type SortField = 'name' | 'date' | 'size' | 'type' | 'prints'; @@ -695,9 +696,10 @@ interface FileCardProps { onDelete: (id: number) => void; onDownload: (id: number) => void; onAddToQueue?: (id: number) => void; + onPrint?: (file: LibraryFileListItem) => void; } -function FileCard({ file, isSelected, onSelect, onDelete, onDownload, onAddToQueue }: FileCardProps) { +function FileCard({ file, isSelected, onSelect, onDelete, onDownload, onAddToQueue, onPrint }: FileCardProps) { const [showActions, setShowActions] = useState(false); return ( @@ -771,12 +773,21 @@ function FileCard({ file, isSelected, onSelect, onDelete, onDownload, onAddToQue <>
setShowActions(false)} />
- {onAddToQueue && isSlicedFilename(file.filename) && ( + {onPrint && isSlicedFilename(file.filename) && ( + )} + {onAddToQueue && isSlicedFilename(file.filename) && ( + )} @@ -828,6 +839,7 @@ export function FileManagerPage() { const [showUploadModal, setShowUploadModal] = useState(false); const [linkFolder, setLinkFolder] = useState(null); const [deleteConfirm, setDeleteConfirm] = useState<{ type: 'file' | 'folder' | 'bulk'; id: number; count?: number } | null>(null); + const [printFile, setPrintFile] = useState(null); const [viewMode, setViewMode] = useState<'grid' | 'list'>(() => { return (localStorage.getItem('library-view-mode') as 'grid' | 'list') || 'grid'; }); @@ -1416,6 +1428,7 @@ export function FileManagerPage() { onDelete={(id) => setDeleteConfirm({ type: 'file', id })} onDownload={handleDownload} onAddToQueue={(id) => addToQueueMutation.mutate([id])} + onPrint={setPrintFile} /> ))}
@@ -1506,14 +1519,23 @@ export function FileManagerPage() { {/* Actions */}
e.stopPropagation()}> {isSlicedFilename(file.filename) && ( - + <> + + + )}
); } diff --git a/frontend/src/pages/QueuePage.tsx b/frontend/src/pages/QueuePage.tsx index 85736ae29..ec6f30d53 100644 --- a/frontend/src/pages/QueuePage.tsx +++ b/frontend/src/pages/QueuePage.tsx @@ -167,7 +167,13 @@ function SortableQueueItem({
{item.archive_thumbnail ? ( + ) : item.library_file_thumbnail ? ( + @@ -182,15 +188,25 @@ function SortableQueueItem({

- {item.archive_name || `Archive #${item.archive_id}`} + {item.archive_name || item.library_file_name || `File #${item.archive_id || item.library_file_id}`}

- - - + {item.archive_id ? ( + + + + ) : item.library_file_id ? ( + + + + ) : null}
@@ -472,7 +488,9 @@ export function QueuePage() { return [...items].sort((a, b) => { let cmp: number; if (pendingSortBy === 'name') { - cmp = (a.archive_name || '').localeCompare(b.archive_name || ''); + const aName = a.archive_name || a.library_file_name || ''; + const bName = b.archive_name || b.library_file_name || ''; + cmp = aName.localeCompare(bName); } else if (pendingSortBy === 'printer') { cmp = (a.printer_name || '').localeCompare(b.printer_name || ''); } else if (pendingSortBy === 'time') { @@ -490,7 +508,9 @@ export function QueuePage() { return [...items].sort((a, b) => { let cmp: number; if (historySortBy === 'name') { - cmp = (a.archive_name || '').localeCompare(b.archive_name || ''); + const aName = a.archive_name || a.library_file_name || ''; + const bName = b.archive_name || b.library_file_name || ''; + cmp = aName.localeCompare(bName); } else if (historySortBy === 'printer') { cmp = (a.printer_name || '').localeCompare(b.printer_name || ''); } else { @@ -803,8 +823,9 @@ export function QueuePage() { {editItem && ( setEditItem(null)} /> @@ -814,8 +835,9 @@ export function QueuePage() { {requeueItem && ( setRequeueItem(null)} /> )} @@ -830,10 +852,10 @@ export function QueuePage() { } message={ confirmAction.type === 'cancel' - ? `Are you sure you want to cancel "${confirmAction.item.archive_name || 'this print'}"?` + ? `Are you sure you want to cancel "${confirmAction.item.archive_name || confirmAction.item.library_file_name || 'this print'}"?` : confirmAction.type === 'stop' - ? `Are you sure you want to stop the current print "${confirmAction.item.archive_name || 'this print'}"? This will cancel the print job on the printer.` - : `Are you sure you want to remove "${confirmAction.item.archive_name || 'this item'}" from the queue history?` + ? `Are you sure you want to stop the current print "${confirmAction.item.archive_name || confirmAction.item.library_file_name || 'this print'}"? This will cancel the print job on the printer.` + : `Are you sure you want to remove "${confirmAction.item.archive_name || confirmAction.item.library_file_name || 'this item'}" from the queue history?` } confirmText={ confirmAction.type === 'cancel' ? 'Cancel Print' : diff --git a/scripts/mqtt_sniffer.py b/scripts/mqtt_sniffer.py index 88d515634..405864d79 100644 --- a/scripts/mqtt_sniffer.py +++ b/scripts/mqtt_sniffer.py @@ -52,12 +52,12 @@ def on_message(client, userdata, msg): # Always log calibration messages with full detail if is_cali_msg: - print(f"\n{'='*80}") + print(f"\n{'=' * 80}") print(f"[{datetime.now().strftime('%H:%M:%S.%f')[:-3]}] *** CALIBRATION COMMAND: {command} ***") print(f"Topic: {msg.topic}") print("Full payload:") print(json.dumps(payload, indent=2)) - print(f"{'='*80}\n") + print(f"{'=' * 80}\n") else: # For other messages, just show a brief summary if "print" in payload: diff --git a/static/assets/index-5D76qqt8.css b/static/assets/index-5D76qqt8.css new file mode 100644 index 000000000..2bc7e8c5e --- /dev/null +++ b/static/assets/index-5D76qqt8.css @@ -0,0 +1 @@ +@import"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap";@layer properties,theme,base,components,utilities;@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-100:oklch(93.6% .032 17.717);--color-red-200:oklch(88.5% .062 18.334);--color-red-300:oklch(80.8% .114 19.571);--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-red-700:oklch(50.5% .213 27.518);--color-orange-200:oklch(90.1% .076 70.697);--color-orange-300:oklch(83.7% .128 66.29);--color-orange-400:oklch(75% .183 55.934);--color-orange-500:oklch(70.5% .213 47.604);--color-orange-600:oklch(64.6% .222 41.116);--color-orange-700:oklch(55.3% .195 38.402);--color-amber-50:oklch(98.7% .022 95.277);--color-amber-200:oklch(92.4% .12 95.746);--color-amber-300:oklch(87.9% .169 91.605);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-500:oklch(76.9% .188 70.08);--color-amber-600:oklch(66.6% .179 58.318);--color-yellow-200:oklch(94.5% .129 101.54);--color-yellow-400:oklch(85.2% .199 91.936);--color-yellow-500:oklch(79.5% .184 86.047);--color-yellow-600:oklch(68.1% .162 75.834);--color-yellow-700:oklch(55.4% .135 66.442);--color-green-100:oklch(96.2% .044 156.743);--color-green-300:oklch(87.1% .15 154.449);--color-green-400:oklch(79.2% .209 151.711);--color-green-500:oklch(72.3% .219 149.579);--color-green-600:oklch(62.7% .194 149.214);--color-emerald-400:oklch(76.5% .177 163.223);--color-emerald-500:oklch(69.6% .17 162.48);--color-cyan-300:oklch(86.5% .127 207.078);--color-cyan-400:oklch(78.9% .154 211.53);--color-cyan-500:oklch(71.5% .143 215.221);--color-cyan-600:oklch(60.9% .126 221.723);--color-blue-50:oklch(97% .014 254.604);--color-blue-100:oklch(93.2% .032 255.585);--color-blue-200:oklch(88.2% .059 254.128);--color-blue-300:oklch(80.9% .105 251.813);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-blue-700:oklch(48.8% .243 264.376);--color-indigo-400:oklch(67.3% .182 276.935);--color-indigo-500:oklch(58.5% .233 277.117);--color-purple-400:oklch(71.4% .203 305.504);--color-purple-500:oklch(62.7% .265 303.9);--color-rose-400:oklch(71.2% .194 13.428);--color-rose-500:oklch(64.5% .246 16.439);--color-gray-50:oklch(98.5% .002 247.839);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-500:oklch(55.1% .027 264.364);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-900:oklch(21% .034 264.665);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-sm:24rem;--container-md:28rem;--container-lg:32rem;--container-xl:36rem;--container-2xl:42rem;--container-3xl:48rem;--container-4xl:56rem;--container-5xl:64rem;--container-6xl:72rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--text-3xl:1.875rem;--text-3xl--line-height: 1.2 ;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-wide:.025em;--tracking-wider:.05em;--tracking-widest:.1em;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--radius-2xl:1rem;--ease-out:cubic-bezier(0,0,.2,1);--ease-in-out:cubic-bezier(.4,0,.2,1);--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4,0,.6,1)infinite;--blur-sm:8px;--aspect-video:16/9;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-bambu-green:var(--accent);--color-bambu-green-light:var(--accent-light);--color-bambu-green-dark:var(--accent-dark);--color-bambu-dark:var(--bg-primary);--color-bambu-dark-secondary:var(--bg-secondary);--color-bambu-dark-tertiary:var(--bg-tertiary);--color-bambu-gray:var(--text-muted);--color-bambu-gray-light:var(--text-secondary);--color-bambu-gray-dark:var(--text-tertiary)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing)*0)}.inset-x-0{inset-inline:calc(var(--spacing)*0)}.inset-y-0{inset-block:calc(var(--spacing)*0)}.-top-1{top:calc(var(--spacing)*-1)}.-top-1\.5{top:calc(var(--spacing)*-1.5)}.top-0{top:calc(var(--spacing)*0)}.top-0\.5{top:calc(var(--spacing)*.5)}.top-1{top:calc(var(--spacing)*1)}.top-1\.5{top:calc(var(--spacing)*1.5)}.top-1\/2{top:50%}.top-2{top:calc(var(--spacing)*2)}.top-4{top:calc(var(--spacing)*4)}.top-8{top:calc(var(--spacing)*8)}.top-\[2px\]{top:2px}.top-\[3px\]{top:3px}.top-full{top:100%}.-right-1{right:calc(var(--spacing)*-1)}.-right-1\.5{right:calc(var(--spacing)*-1.5)}.right-0{right:calc(var(--spacing)*0)}.right-1{right:calc(var(--spacing)*1)}.right-1\.5{right:calc(var(--spacing)*1.5)}.right-2{right:calc(var(--spacing)*2)}.right-3{right:calc(var(--spacing)*3)}.right-4{right:calc(var(--spacing)*4)}.right-6{right:calc(var(--spacing)*6)}.right-12{right:calc(var(--spacing)*12)}.right-full{right:100%}.bottom-0{bottom:calc(var(--spacing)*0)}.bottom-1{bottom:calc(var(--spacing)*1)}.bottom-2{bottom:calc(var(--spacing)*2)}.bottom-4{bottom:calc(var(--spacing)*4)}.bottom-6{bottom:calc(var(--spacing)*6)}.bottom-8{bottom:calc(var(--spacing)*8)}.bottom-full{bottom:100%}.left-0{left:calc(var(--spacing)*0)}.left-1{left:calc(var(--spacing)*1)}.left-1\/2{left:50%}.left-2{left:calc(var(--spacing)*2)}.left-2\.5{left:calc(var(--spacing)*2.5)}.left-3{left:calc(var(--spacing)*3)}.left-4{left:calc(var(--spacing)*4)}.left-10{left:calc(var(--spacing)*10)}.left-12{left:calc(var(--spacing)*12)}.left-\[2px\]{left:2px}.left-\[3px\]{left:3px}.left-full{left:100%}.z-0{z-index:0}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-40{z-index:40}.z-50{z-index:50}.z-60,.z-\[60\]{z-index:60}.col-span-1{grid-column:span 1/span 1}.col-span-2{grid-column:span 2/span 2}.col-span-3{grid-column:span 3/span 3}.col-span-4{grid-column:span 4/span 4}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.-mx-4{margin-inline:calc(var(--spacing)*-4)}.mx-1{margin-inline:calc(var(--spacing)*1)}.mx-2{margin-inline:calc(var(--spacing)*2)}.mx-4{margin-inline:calc(var(--spacing)*4)}.mx-auto{margin-inline:auto}.my-1{margin-block:calc(var(--spacing)*1)}.my-8{margin-block:calc(var(--spacing)*8)}.-mt-2{margin-top:calc(var(--spacing)*-2)}.mt-0\.5{margin-top:calc(var(--spacing)*.5)}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-1\.5{margin-top:calc(var(--spacing)*1.5)}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-3{margin-top:calc(var(--spacing)*3)}.mt-4{margin-top:calc(var(--spacing)*4)}.mt-6{margin-top:calc(var(--spacing)*6)}.mt-14{margin-top:calc(var(--spacing)*14)}.mr-1{margin-right:calc(var(--spacing)*1)}.mr-2{margin-right:calc(var(--spacing)*2)}.mr-3{margin-right:calc(var(--spacing)*3)}.mr-4{margin-right:calc(var(--spacing)*4)}.-mb-px{margin-bottom:-1px}.mb-0\.5{margin-bottom:calc(var(--spacing)*.5)}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-1\.5{margin-bottom:calc(var(--spacing)*1.5)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-3{margin-bottom:calc(var(--spacing)*3)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.mb-5{margin-bottom:calc(var(--spacing)*5)}.mb-6{margin-bottom:calc(var(--spacing)*6)}.mb-8{margin-bottom:calc(var(--spacing)*8)}.-ml-1{margin-left:calc(var(--spacing)*-1)}.-ml-2{margin-left:calc(var(--spacing)*-2)}.ml-0\.5{margin-left:calc(var(--spacing)*.5)}.ml-1{margin-left:calc(var(--spacing)*1)}.ml-1\.5{margin-left:calc(var(--spacing)*1.5)}.ml-2{margin-left:calc(var(--spacing)*2)}.ml-3{margin-left:calc(var(--spacing)*3)}.ml-4{margin-left:calc(var(--spacing)*4)}.ml-14{margin-left:calc(var(--spacing)*14)}.ml-16{margin-left:calc(var(--spacing)*16)}.ml-64{margin-left:calc(var(--spacing)*64)}.ml-auto{margin-left:auto}.line-clamp-1{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.aspect-square{aspect-ratio:1}.aspect-video{aspect-ratio:var(--aspect-video)}.h-0{height:calc(var(--spacing)*0)}.h-1{height:calc(var(--spacing)*1)}.h-1\.5{height:calc(var(--spacing)*1.5)}.h-2{height:calc(var(--spacing)*2)}.h-2\.5{height:calc(var(--spacing)*2.5)}.h-3{height:calc(var(--spacing)*3)}.h-3\.5{height:calc(var(--spacing)*3.5)}.h-4{height:calc(var(--spacing)*4)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-7{height:calc(var(--spacing)*7)}.h-8{height:calc(var(--spacing)*8)}.h-10{height:calc(var(--spacing)*10)}.h-12{height:calc(var(--spacing)*12)}.h-14{height:calc(var(--spacing)*14)}.h-16{height:calc(var(--spacing)*16)}.h-20{height:calc(var(--spacing)*20)}.h-48{height:calc(var(--spacing)*48)}.h-64{height:calc(var(--spacing)*64)}.h-80{height:calc(var(--spacing)*80)}.h-\[18px\]{height:18px}.h-\[80vh\]{height:80vh}.h-\[160px\]{height:160px}.h-\[300px\]{height:300px}.h-\[calc\(100\%-40px\)\]{height:calc(100% - 40px)}.h-\[calc\(100vh-64px\)\]{height:calc(100vh - 64px)}.h-full{height:100%}.h-px{height:1px}.max-h-40{max-height:calc(var(--spacing)*40)}.max-h-48{max-height:calc(var(--spacing)*48)}.max-h-60{max-height:calc(var(--spacing)*60)}.max-h-64{max-height:calc(var(--spacing)*64)}.max-h-80{max-height:calc(var(--spacing)*80)}.max-h-96{max-height:calc(var(--spacing)*96)}.max-h-\[60vh\]{max-height:60vh}.max-h-\[80vh\]{max-height:80vh}.max-h-\[85vh\]{max-height:85vh}.max-h-\[90vh\]{max-height:90vh}.max-h-\[300px\]{max-height:300px}.max-h-\[400px\]{max-height:400px}.max-h-\[calc\(90vh-80px\)\]{max-height:calc(90vh - 80px)}.max-h-\[calc\(100vh-320px\)\]{max-height:calc(100vh - 320px)}.max-h-full{max-height:100%}.min-h-0{min-height:calc(var(--spacing)*0)}.min-h-\[44px\]{min-height:44px}.min-h-\[48px\]{min-height:48px}.min-h-\[120px\]{min-height:120px}.min-h-\[400px\]{min-height:400px}.min-h-full{min-height:100%}.min-h-screen{min-height:100vh}.w-0{width:calc(var(--spacing)*0)}.w-0\.5{width:calc(var(--spacing)*.5)}.w-1\.5{width:calc(var(--spacing)*1.5)}.w-1\/3{width:33.3333%}.w-2{width:calc(var(--spacing)*2)}.w-2\.5{width:calc(var(--spacing)*2.5)}.w-3{width:calc(var(--spacing)*3)}.w-3\.5{width:calc(var(--spacing)*3.5)}.w-4{width:calc(var(--spacing)*4)}.w-4\.5{width:calc(var(--spacing)*4.5)}.w-5{width:calc(var(--spacing)*5)}.w-6{width:calc(var(--spacing)*6)}.w-7{width:calc(var(--spacing)*7)}.w-8{width:calc(var(--spacing)*8)}.w-9{width:calc(var(--spacing)*9)}.w-10{width:calc(var(--spacing)*10)}.w-11{width:calc(var(--spacing)*11)}.w-12{width:calc(var(--spacing)*12)}.w-14{width:calc(var(--spacing)*14)}.w-16{width:calc(var(--spacing)*16)}.w-20{width:calc(var(--spacing)*20)}.w-24{width:calc(var(--spacing)*24)}.w-32{width:calc(var(--spacing)*32)}.w-36{width:calc(var(--spacing)*36)}.w-40{width:calc(var(--spacing)*40)}.w-48{width:calc(var(--spacing)*48)}.w-52{width:calc(var(--spacing)*52)}.w-56{width:calc(var(--spacing)*56)}.w-64{width:calc(var(--spacing)*64)}.w-72{width:calc(var(--spacing)*72)}.w-\[560px\]{width:560px}.w-auto{width:auto}.w-fit{width:fit-content}.w-full{width:100%}.w-px{width:1px}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-5xl{max-width:var(--container-5xl)}.max-w-6xl{max-width:var(--container-6xl)}.max-w-32{max-width:calc(var(--spacing)*32)}.max-w-\[40\%\]{max-width:40%}.max-w-\[80px\]{max-width:80px}.max-w-\[90vw\]{max-width:90vw}.max-w-\[100px\]{max-width:100px}.max-w-\[120px\]{max-width:120px}.max-w-\[150px\]{max-width:150px}.max-w-\[160px\]{max-width:160px}.max-w-\[200px\]{max-width:200px}.max-w-\[280px\]{max-width:280px}.max-w-full{max-width:100%}.max-w-lg{max-width:var(--container-lg)}.max-w-md{max-width:var(--container-md)}.max-w-none{max-width:none}.max-w-sm{max-width:var(--container-sm)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:calc(var(--spacing)*0)}.min-w-48{min-width:calc(var(--spacing)*48)}.min-w-\[16px\]{min-width:16px}.min-w-\[18px\]{min-width:18px}.min-w-\[80px\]{min-width:80px}.min-w-\[100px\]{min-width:100px}.min-w-\[120px\]{min-width:120px}.min-w-\[140px\]{min-width:140px}.min-w-\[150px\]{min-width:150px}.min-w-\[160px\]{min-width:160px}.min-w-\[180px\]{min-width:180px}.flex-1{flex:1}.flex-shrink{flex-shrink:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.-translate-x-1\/2{--tw-translate-x: -50% ;translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-x-full{--tw-translate-x:-100%;translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-0{--tw-translate-x:calc(var(--spacing)*0);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-0\.5{--tw-translate-x:calc(var(--spacing)*.5);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-3\.5{--tw-translate-x:calc(var(--spacing)*3.5);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-4{--tw-translate-x:calc(var(--spacing)*4);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-5{--tw-translate-x:calc(var(--spacing)*5);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-6{--tw-translate-x:calc(var(--spacing)*6);translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y: -50% ;translate:var(--tw-translate-x)var(--tw-translate-y)}.scale-110{--tw-scale-x:110%;--tw-scale-y:110%;--tw-scale-z:110%;scale:var(--tw-scale-x)var(--tw-scale-y)}.scale-\[1\.02\]{scale:1.02}.-rotate-90{rotate:-90deg}.rotate-90{rotate:90deg}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-default{cursor:default}.cursor-ew-resize{cursor:ew-resize}.cursor-grab{cursor:grab}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.cursor-se-resize{cursor:se-resize}.touch-manipulation{touch-action:manipulation}.resize{resize:both}.resize-none{resize:none}.resize-y{resize:vertical}.list-inside{list-style-position:inside}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.appearance-none{appearance:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.grid-cols-12{grid-template-columns:repeat(12,minmax(0,1fr))}.grid-cols-\[auto_1fr_100px_100px_100px_80px\]{grid-template-columns:auto 1fr 100px 100px 100px 80px}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0\.5{gap:calc(var(--spacing)*.5)}.gap-1{gap:calc(var(--spacing)*1)}.gap-1\.5{gap:calc(var(--spacing)*1.5)}.gap-2{gap:calc(var(--spacing)*2)}.gap-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}.gap-6{gap:calc(var(--spacing)*6)}.gap-8{gap:calc(var(--spacing)*8)}:where(.space-y-0\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*.5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*.5)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2.5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2.5)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*3)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*3)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*4)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*6)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*6)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-8>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*8)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*8)*calc(1 - var(--tw-space-y-reverse)))}.gap-x-6{column-gap:calc(var(--spacing)*6)}.gap-y-1{row-gap:calc(var(--spacing)*1)}.gap-y-3{row-gap:calc(var(--spacing)*3)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px*var(--tw-divide-y-reverse));border-bottom-width:calc(1px*calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-bambu-dark-tertiary>:not(:last-child)){border-color:var(--color-bambu-dark-tertiary)}:where(.divide-bambu-gray\/20>:not(:last-child)){border-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){:where(.divide-bambu-gray\/20>:not(:last-child)){border-color:color-mix(in oklab,var(--color-bambu-gray)20%,transparent)}}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-t-lg{border-top-left-radius:var(--radius-lg);border-top-right-radius:var(--radius-lg)}.rounded-t-xl{border-top-left-radius:var(--radius-xl);border-top-right-radius:var(--radius-xl)}.rounded-l{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.rounded-l-lg{border-top-left-radius:var(--radius-lg);border-bottom-left-radius:var(--radius-lg)}.rounded-tl{border-top-left-radius:.25rem}.rounded-r{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.rounded-r-lg{border-top-right-radius:var(--radius-lg);border-bottom-right-radius:var(--radius-lg)}.rounded-b-lg{border-bottom-right-radius:var(--radius-lg);border-bottom-left-radius:var(--radius-lg)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-4{border-style:var(--tw-border-style);border-width:4px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-t-\[5px\]{border-top-style:var(--tw-border-style);border-top-width:5px}.border-t-\[6px\]{border-top-style:var(--tw-border-style);border-top-width:6px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-r-\[5px\]{border-right-style:var(--tw-border-style);border-right-width:5px}.border-r-\[6px\]{border-right-style:var(--tw-border-style);border-right-width:6px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-b-\[6px\]{border-bottom-style:var(--tw-border-style);border-bottom-width:6px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-l-4{border-left-style:var(--tw-border-style);border-left-width:4px}.border-l-\[5px\]{border-left-style:var(--tw-border-style);border-left-width:5px}.border-l-\[6px\]{border-left-style:var(--tw-border-style);border-left-width:6px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-amber-500\/20{border-color:#f99c0033}@supports (color:color-mix(in lab,red,red)){.border-amber-500\/20{border-color:color-mix(in oklab,var(--color-amber-500)20%,transparent)}}.border-amber-500\/30{border-color:#f99c004d}@supports (color:color-mix(in lab,red,red)){.border-amber-500\/30{border-color:color-mix(in oklab,var(--color-amber-500)30%,transparent)}}.border-bambu-dark-tertiary,.border-bambu-dark-tertiary\/30{border-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.border-bambu-dark-tertiary\/30{border-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)30%,transparent)}}.border-bambu-gray,.border-bambu-gray\/30{border-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.border-bambu-gray\/30{border-color:color-mix(in oklab,var(--color-bambu-gray)30%,transparent)}}.border-bambu-gray\/50{border-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.border-bambu-gray\/50{border-color:color-mix(in oklab,var(--color-bambu-gray)50%,transparent)}}.border-bambu-green,.border-bambu-green\/20{border-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.border-bambu-green\/20{border-color:color-mix(in oklab,var(--color-bambu-green)20%,transparent)}}.border-bambu-green\/30{border-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.border-bambu-green\/30{border-color:color-mix(in oklab,var(--color-bambu-green)30%,transparent)}}.border-bambu-green\/50{border-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.border-bambu-green\/50{border-color:color-mix(in oklab,var(--color-bambu-green)50%,transparent)}}.border-blue-400\/20{border-color:#54a2ff33}@supports (color:color-mix(in lab,red,red)){.border-blue-400\/20{border-color:color-mix(in oklab,var(--color-blue-400)20%,transparent)}}.border-blue-500\/20{border-color:#3080ff33}@supports (color:color-mix(in lab,red,red)){.border-blue-500\/20{border-color:color-mix(in oklab,var(--color-blue-500)20%,transparent)}}.border-blue-500\/30{border-color:#3080ff4d}@supports (color:color-mix(in lab,red,red)){.border-blue-500\/30{border-color:color-mix(in oklab,var(--color-blue-500)30%,transparent)}}.border-blue-500\/50{border-color:#3080ff80}@supports (color:color-mix(in lab,red,red)){.border-blue-500\/50{border-color:color-mix(in oklab,var(--color-blue-500)50%,transparent)}}.border-gray-200{border-color:var(--color-gray-200)}.border-gray-300{border-color:var(--color-gray-300)}.border-gray-400\/20{border-color:#99a1af33}@supports (color:color-mix(in lab,red,red)){.border-gray-400\/20{border-color:color-mix(in oklab,var(--color-gray-400)20%,transparent)}}.border-gray-500\/20{border-color:#6a728233}@supports (color:color-mix(in lab,red,red)){.border-gray-500\/20{border-color:color-mix(in oklab,var(--color-gray-500)20%,transparent)}}.border-gray-700{border-color:var(--color-gray-700)}.border-green-300{border-color:var(--color-green-300)}.border-green-400\/20{border-color:#05df7233}@supports (color:color-mix(in lab,red,red)){.border-green-400\/20{border-color:color-mix(in oklab,var(--color-green-400)20%,transparent)}}.border-green-500\/30{border-color:#00c7584d}@supports (color:color-mix(in lab,red,red)){.border-green-500\/30{border-color:color-mix(in oklab,var(--color-green-500)30%,transparent)}}.border-green-500\/50{border-color:#00c75880}@supports (color:color-mix(in lab,red,red)){.border-green-500\/50{border-color:color-mix(in oklab,var(--color-green-500)50%,transparent)}}.border-orange-400\/20{border-color:#ff8b1a33}@supports (color:color-mix(in lab,red,red)){.border-orange-400\/20{border-color:color-mix(in oklab,var(--color-orange-400)20%,transparent)}}.border-orange-400\/50{border-color:#ff8b1a80}@supports (color:color-mix(in lab,red,red)){.border-orange-400\/50{border-color:color-mix(in oklab,var(--color-orange-400)50%,transparent)}}.border-orange-500\/20{border-color:#fe6e0033}@supports (color:color-mix(in lab,red,red)){.border-orange-500\/20{border-color:color-mix(in oklab,var(--color-orange-500)20%,transparent)}}.border-orange-500\/30{border-color:#fe6e004d}@supports (color:color-mix(in lab,red,red)){.border-orange-500\/30{border-color:color-mix(in oklab,var(--color-orange-500)30%,transparent)}}.border-purple-500\/20{border-color:#ac4bff33}@supports (color:color-mix(in lab,red,red)){.border-purple-500\/20{border-color:color-mix(in oklab,var(--color-purple-500)20%,transparent)}}.border-red-300{border-color:var(--color-red-300)}.border-red-400\/20{border-color:#ff656833}@supports (color:color-mix(in lab,red,red)){.border-red-400\/20{border-color:color-mix(in oklab,var(--color-red-400)20%,transparent)}}.border-red-500{border-color:var(--color-red-500)}.border-red-500\/20{border-color:#fb2c3633}@supports (color:color-mix(in lab,red,red)){.border-red-500\/20{border-color:color-mix(in oklab,var(--color-red-500)20%,transparent)}}.border-red-500\/30{border-color:#fb2c364d}@supports (color:color-mix(in lab,red,red)){.border-red-500\/30{border-color:color-mix(in oklab,var(--color-red-500)30%,transparent)}}.border-red-500\/50{border-color:#fb2c3680}@supports (color:color-mix(in lab,red,red)){.border-red-500\/50{border-color:color-mix(in oklab,var(--color-red-500)50%,transparent)}}.border-transparent{border-color:#0000}.border-white\/10{border-color:#ffffff1a}@supports (color:color-mix(in lab,red,red)){.border-white\/10{border-color:color-mix(in oklab,var(--color-white)10%,transparent)}}.border-white\/20{border-color:#fff3}@supports (color:color-mix(in lab,red,red)){.border-white\/20{border-color:color-mix(in oklab,var(--color-white)20%,transparent)}}.border-white\/30{border-color:#ffffff4d}@supports (color:color-mix(in lab,red,red)){.border-white\/30{border-color:color-mix(in oklab,var(--color-white)30%,transparent)}}.border-yellow-400\/20{border-color:#fac80033}@supports (color:color-mix(in lab,red,red)){.border-yellow-400\/20{border-color:color-mix(in oklab,var(--color-yellow-400)20%,transparent)}}.border-yellow-400\/50{border-color:#fac80080}@supports (color:color-mix(in lab,red,red)){.border-yellow-400\/50{border-color:color-mix(in oklab,var(--color-yellow-400)50%,transparent)}}.border-yellow-500{border-color:var(--color-yellow-500)}.border-yellow-500\/20{border-color:#edb20033}@supports (color:color-mix(in lab,red,red)){.border-yellow-500\/20{border-color:color-mix(in oklab,var(--color-yellow-500)20%,transparent)}}.border-yellow-500\/30{border-color:#edb2004d}@supports (color:color-mix(in lab,red,red)){.border-yellow-500\/30{border-color:color-mix(in oklab,var(--color-yellow-500)30%,transparent)}}.border-yellow-500\/50{border-color:#edb20080}@supports (color:color-mix(in lab,red,red)){.border-yellow-500\/50{border-color:color-mix(in oklab,var(--color-yellow-500)50%,transparent)}}.border-t-bambu-dark-tertiary{border-top-color:var(--color-bambu-dark-tertiary)}.border-t-transparent{border-top-color:#0000}.border-r-transparent{border-right-color:#0000}.border-b-bambu-dark-tertiary{border-bottom-color:var(--color-bambu-dark-tertiary)}.border-l-transparent{border-left-color:#0000}.border-l-yellow-500{border-left-color:var(--color-yellow-500)}.bg-amber-50{background-color:var(--color-amber-50)}.bg-amber-500{background-color:var(--color-amber-500)}.bg-amber-500\/5{background-color:#f99c000d}@supports (color:color-mix(in lab,red,red)){.bg-amber-500\/5{background-color:color-mix(in oklab,var(--color-amber-500)5%,transparent)}}.bg-amber-500\/10{background-color:#f99c001a}@supports (color:color-mix(in lab,red,red)){.bg-amber-500\/10{background-color:color-mix(in oklab,var(--color-amber-500)10%,transparent)}}.bg-amber-500\/20{background-color:#f99c0033}@supports (color:color-mix(in lab,red,red)){.bg-amber-500\/20{background-color:color-mix(in oklab,var(--color-amber-500)20%,transparent)}}.bg-amber-500\/90{background-color:#f99c00e6}@supports (color:color-mix(in lab,red,red)){.bg-amber-500\/90{background-color:color-mix(in oklab,var(--color-amber-500)90%,transparent)}}.bg-amber-600\/20{background-color:#dd740033}@supports (color:color-mix(in lab,red,red)){.bg-amber-600\/20{background-color:color-mix(in oklab,var(--color-amber-600)20%,transparent)}}.bg-bambu-dark{background-color:var(--color-bambu-dark)}.bg-bambu-dark-secondary,.bg-bambu-dark-secondary\/50{background-color:var(--color-bambu-dark-secondary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-secondary\/50{background-color:color-mix(in oklab,var(--color-bambu-dark-secondary)50%,transparent)}}.bg-bambu-dark-secondary\/90{background-color:var(--color-bambu-dark-secondary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-secondary\/90{background-color:color-mix(in oklab,var(--color-bambu-dark-secondary)90%,transparent)}}.bg-bambu-dark-secondary\/95{background-color:var(--color-bambu-dark-secondary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-secondary\/95{background-color:color-mix(in oklab,var(--color-bambu-dark-secondary)95%,transparent)}}.bg-bambu-dark-tertiary,.bg-bambu-dark-tertiary\/30{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-tertiary\/30{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)30%,transparent)}}.bg-bambu-dark-tertiary\/50{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-tertiary\/50{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)50%,transparent)}}.bg-bambu-dark-tertiary\/80{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-tertiary\/80{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)80%,transparent)}}.bg-bambu-dark\/20{background-color:var(--color-bambu-dark)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark\/20{background-color:color-mix(in oklab,var(--color-bambu-dark)20%,transparent)}}.bg-bambu-dark\/30{background-color:var(--color-bambu-dark)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark\/30{background-color:color-mix(in oklab,var(--color-bambu-dark)30%,transparent)}}.bg-bambu-dark\/50{background-color:var(--color-bambu-dark)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark\/50{background-color:color-mix(in oklab,var(--color-bambu-dark)50%,transparent)}}.bg-bambu-dark\/80{background-color:var(--color-bambu-dark)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark\/80{background-color:color-mix(in oklab,var(--color-bambu-dark)80%,transparent)}}.bg-bambu-dark\/90{background-color:var(--color-bambu-dark)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark\/90{background-color:color-mix(in oklab,var(--color-bambu-dark)90%,transparent)}}.bg-bambu-gray\/10{background-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-gray\/10{background-color:color-mix(in oklab,var(--color-bambu-gray)10%,transparent)}}.bg-bambu-gray\/20{background-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-gray\/20{background-color:color-mix(in oklab,var(--color-bambu-gray)20%,transparent)}}.bg-bambu-gray\/30{background-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-gray\/30{background-color:color-mix(in oklab,var(--color-bambu-gray)30%,transparent)}}.bg-bambu-gray\/90{background-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-gray\/90{background-color:color-mix(in oklab,var(--color-bambu-gray)90%,transparent)}}.bg-bambu-green,.bg-bambu-green\/5{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-green\/5{background-color:color-mix(in oklab,var(--color-bambu-green)5%,transparent)}}.bg-bambu-green\/10{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-green\/10{background-color:color-mix(in oklab,var(--color-bambu-green)10%,transparent)}}.bg-bambu-green\/20{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-green\/20{background-color:color-mix(in oklab,var(--color-bambu-green)20%,transparent)}}.bg-bambu-green\/30{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-green\/30{background-color:color-mix(in oklab,var(--color-bambu-green)30%,transparent)}}.bg-bambu-green\/50{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-green\/50{background-color:color-mix(in oklab,var(--color-bambu-green)50%,transparent)}}.bg-bambu-green\/75{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-green\/75{background-color:color-mix(in oklab,var(--color-bambu-green)75%,transparent)}}.bg-bambu-green\/90{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-green\/90{background-color:color-mix(in oklab,var(--color-bambu-green)90%,transparent)}}.bg-black{background-color:var(--color-black)}.bg-black\/30{background-color:#0000004d}@supports (color:color-mix(in lab,red,red)){.bg-black\/30{background-color:color-mix(in oklab,var(--color-black)30%,transparent)}}.bg-black\/40{background-color:#0006}@supports (color:color-mix(in lab,red,red)){.bg-black\/40{background-color:color-mix(in oklab,var(--color-black)40%,transparent)}}.bg-black\/50{background-color:#00000080}@supports (color:color-mix(in lab,red,red)){.bg-black\/50{background-color:color-mix(in oklab,var(--color-black)50%,transparent)}}.bg-black\/60{background-color:#0009}@supports (color:color-mix(in lab,red,red)){.bg-black\/60{background-color:color-mix(in oklab,var(--color-black)60%,transparent)}}.bg-black\/70{background-color:#000000b3}@supports (color:color-mix(in lab,red,red)){.bg-black\/70{background-color:color-mix(in oklab,var(--color-black)70%,transparent)}}.bg-black\/80{background-color:#000c}@supports (color:color-mix(in lab,red,red)){.bg-black\/80{background-color:color-mix(in oklab,var(--color-black)80%,transparent)}}.bg-black\/90{background-color:#000000e6}@supports (color:color-mix(in lab,red,red)){.bg-black\/90{background-color:color-mix(in oklab,var(--color-black)90%,transparent)}}.bg-blue-50{background-color:var(--color-blue-50)}.bg-blue-100{background-color:var(--color-blue-100)}.bg-blue-400{background-color:var(--color-blue-400)}.bg-blue-400\/10{background-color:#54a2ff1a}@supports (color:color-mix(in lab,red,red)){.bg-blue-400\/10{background-color:color-mix(in oklab,var(--color-blue-400)10%,transparent)}}.bg-blue-500{background-color:var(--color-blue-500)}.bg-blue-500\/10{background-color:#3080ff1a}@supports (color:color-mix(in lab,red,red)){.bg-blue-500\/10{background-color:color-mix(in oklab,var(--color-blue-500)10%,transparent)}}.bg-blue-500\/20{background-color:#3080ff33}@supports (color:color-mix(in lab,red,red)){.bg-blue-500\/20{background-color:color-mix(in oklab,var(--color-blue-500)20%,transparent)}}.bg-blue-500\/30{background-color:#3080ff4d}@supports (color:color-mix(in lab,red,red)){.bg-blue-500\/30{background-color:color-mix(in oklab,var(--color-blue-500)30%,transparent)}}.bg-blue-500\/90{background-color:#3080ffe6}@supports (color:color-mix(in lab,red,red)){.bg-blue-500\/90{background-color:color-mix(in oklab,var(--color-blue-500)90%,transparent)}}.bg-blue-600{background-color:var(--color-blue-600)}.bg-blue-600\/20{background-color:#155dfc33}@supports (color:color-mix(in lab,red,red)){.bg-blue-600\/20{background-color:color-mix(in oklab,var(--color-blue-600)20%,transparent)}}.bg-cyan-500\/10{background-color:#00b7d71a}@supports (color:color-mix(in lab,red,red)){.bg-cyan-500\/10{background-color:color-mix(in oklab,var(--color-cyan-500)10%,transparent)}}.bg-cyan-500\/20{background-color:#00b7d733}@supports (color:color-mix(in lab,red,red)){.bg-cyan-500\/20{background-color:color-mix(in oklab,var(--color-cyan-500)20%,transparent)}}.bg-cyan-600\/20{background-color:#0092b533}@supports (color:color-mix(in lab,red,red)){.bg-cyan-600\/20{background-color:color-mix(in oklab,var(--color-cyan-600)20%,transparent)}}.bg-emerald-500\/20{background-color:#00bb7f33}@supports (color:color-mix(in lab,red,red)){.bg-emerald-500\/20{background-color:color-mix(in oklab,var(--color-emerald-500)20%,transparent)}}.bg-gray-50{background-color:var(--color-gray-50)}.bg-gray-100{background-color:var(--color-gray-100)}.bg-gray-400{background-color:var(--color-gray-400)}.bg-gray-400\/10{background-color:#99a1af1a}@supports (color:color-mix(in lab,red,red)){.bg-gray-400\/10{background-color:color-mix(in oklab,var(--color-gray-400)10%,transparent)}}.bg-gray-500{background-color:var(--color-gray-500)}.bg-gray-500\/20{background-color:#6a728233}@supports (color:color-mix(in lab,red,red)){.bg-gray-500\/20{background-color:color-mix(in oklab,var(--color-gray-500)20%,transparent)}}.bg-gray-900{background-color:var(--color-gray-900)}.bg-green-100{background-color:var(--color-green-100)}.bg-green-400{background-color:var(--color-green-400)}.bg-green-400\/10{background-color:#05df721a}@supports (color:color-mix(in lab,red,red)){.bg-green-400\/10{background-color:color-mix(in oklab,var(--color-green-400)10%,transparent)}}.bg-green-500{background-color:var(--color-green-500)}.bg-green-500\/10{background-color:#00c7581a}@supports (color:color-mix(in lab,red,red)){.bg-green-500\/10{background-color:color-mix(in oklab,var(--color-green-500)10%,transparent)}}.bg-green-500\/20{background-color:#00c75833}@supports (color:color-mix(in lab,red,red)){.bg-green-500\/20{background-color:color-mix(in oklab,var(--color-green-500)20%,transparent)}}.bg-indigo-500\/20{background-color:#625fff33}@supports (color:color-mix(in lab,red,red)){.bg-indigo-500\/20{background-color:color-mix(in oklab,var(--color-indigo-500)20%,transparent)}}.bg-orange-400\/10{background-color:#ff8b1a1a}@supports (color:color-mix(in lab,red,red)){.bg-orange-400\/10{background-color:color-mix(in oklab,var(--color-orange-400)10%,transparent)}}.bg-orange-500{background-color:var(--color-orange-500)}.bg-orange-500\/10{background-color:#fe6e001a}@supports (color:color-mix(in lab,red,red)){.bg-orange-500\/10{background-color:color-mix(in oklab,var(--color-orange-500)10%,transparent)}}.bg-orange-500\/20{background-color:#fe6e0033}@supports (color:color-mix(in lab,red,red)){.bg-orange-500\/20{background-color:color-mix(in oklab,var(--color-orange-500)20%,transparent)}}.bg-orange-600{background-color:var(--color-orange-600)}.bg-orange-600\/20{background-color:#f0510033}@supports (color:color-mix(in lab,red,red)){.bg-orange-600\/20{background-color:color-mix(in oklab,var(--color-orange-600)20%,transparent)}}.bg-purple-500\/10{background-color:#ac4bff1a}@supports (color:color-mix(in lab,red,red)){.bg-purple-500\/10{background-color:color-mix(in oklab,var(--color-purple-500)10%,transparent)}}.bg-purple-500\/20{background-color:#ac4bff33}@supports (color:color-mix(in lab,red,red)){.bg-purple-500\/20{background-color:color-mix(in oklab,var(--color-purple-500)20%,transparent)}}.bg-purple-500\/80{background-color:#ac4bffcc}@supports (color:color-mix(in lab,red,red)){.bg-purple-500\/80{background-color:color-mix(in oklab,var(--color-purple-500)80%,transparent)}}.bg-purple-500\/90{background-color:#ac4bffe6}@supports (color:color-mix(in lab,red,red)){.bg-purple-500\/90{background-color:color-mix(in oklab,var(--color-purple-500)90%,transparent)}}.bg-red-50{background-color:var(--color-red-50)}.bg-red-100{background-color:var(--color-red-100)}.bg-red-400{background-color:var(--color-red-400)}.bg-red-400\/10{background-color:#ff65681a}@supports (color:color-mix(in lab,red,red)){.bg-red-400\/10{background-color:color-mix(in oklab,var(--color-red-400)10%,transparent)}}.bg-red-500{background-color:var(--color-red-500)}.bg-red-500\/5{background-color:#fb2c360d}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/5{background-color:color-mix(in oklab,var(--color-red-500)5%,transparent)}}.bg-red-500\/10{background-color:#fb2c361a}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/10{background-color:color-mix(in oklab,var(--color-red-500)10%,transparent)}}.bg-red-500\/15{background-color:#fb2c3626}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/15{background-color:color-mix(in oklab,var(--color-red-500)15%,transparent)}}.bg-red-500\/20{background-color:#fb2c3633}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/20{background-color:color-mix(in oklab,var(--color-red-500)20%,transparent)}}.bg-red-500\/30{background-color:#fb2c364d}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/30{background-color:color-mix(in oklab,var(--color-red-500)30%,transparent)}}.bg-red-500\/40{background-color:#fb2c3666}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/40{background-color:color-mix(in oklab,var(--color-red-500)40%,transparent)}}.bg-red-500\/80{background-color:#fb2c36cc}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/80{background-color:color-mix(in oklab,var(--color-red-500)80%,transparent)}}.bg-red-600{background-color:var(--color-red-600)}.bg-rose-500\/20{background-color:#ff235733}@supports (color:color-mix(in lab,red,red)){.bg-rose-500\/20{background-color:color-mix(in oklab,var(--color-rose-500)20%,transparent)}}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.bg-white\/50{background-color:#ffffff80}@supports (color:color-mix(in lab,red,red)){.bg-white\/50{background-color:color-mix(in oklab,var(--color-white)50%,transparent)}}.bg-white\/90{background-color:#ffffffe6}@supports (color:color-mix(in lab,red,red)){.bg-white\/90{background-color:color-mix(in oklab,var(--color-white)90%,transparent)}}.bg-yellow-400{background-color:var(--color-yellow-400)}.bg-yellow-400\/10{background-color:#fac8001a}@supports (color:color-mix(in lab,red,red)){.bg-yellow-400\/10{background-color:color-mix(in oklab,var(--color-yellow-400)10%,transparent)}}.bg-yellow-400\/20{background-color:#fac80033}@supports (color:color-mix(in lab,red,red)){.bg-yellow-400\/20{background-color:color-mix(in oklab,var(--color-yellow-400)20%,transparent)}}.bg-yellow-500{background-color:var(--color-yellow-500)}.bg-yellow-500\/5{background-color:#edb2000d}@supports (color:color-mix(in lab,red,red)){.bg-yellow-500\/5{background-color:color-mix(in oklab,var(--color-yellow-500)5%,transparent)}}.bg-yellow-500\/10{background-color:#edb2001a}@supports (color:color-mix(in lab,red,red)){.bg-yellow-500\/10{background-color:color-mix(in oklab,var(--color-yellow-500)10%,transparent)}}.bg-yellow-500\/20{background-color:#edb20033}@supports (color:color-mix(in lab,red,red)){.bg-yellow-500\/20{background-color:color-mix(in oklab,var(--color-yellow-500)20%,transparent)}}.bg-gradient-to-b{--tw-gradient-position:to bottom in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.bg-gradient-to-br{--tw-gradient-position:to bottom right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.bg-gradient-to-r{--tw-gradient-position:to right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.bg-gradient-to-t{--tw-gradient-position:to top in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-bambu-green\/10{--tw-gradient-from:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.from-bambu-green\/10{--tw-gradient-from:color-mix(in oklab,var(--color-bambu-green)10%,transparent)}}.from-bambu-green\/10{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-black\/80{--tw-gradient-from:#000c}@supports (color:color-mix(in lab,red,red)){.from-black\/80{--tw-gradient-from:color-mix(in oklab,var(--color-black)80%,transparent)}}.from-black\/80{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-blue-500{--tw-gradient-from:var(--color-blue-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-blue-500\/5{--tw-gradient-from:#3080ff0d}@supports (color:color-mix(in lab,red,red)){.from-blue-500\/5{--tw-gradient-from:color-mix(in oklab,var(--color-blue-500)5%,transparent)}}.from-blue-500\/5{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-blue-500\/10{--tw-gradient-from:#3080ff1a}@supports (color:color-mix(in lab,red,red)){.from-blue-500\/10{--tw-gradient-from:color-mix(in oklab,var(--color-blue-500)10%,transparent)}}.from-blue-500\/10{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-gray-500\/10{--tw-gradient-from:#6a72821a}@supports (color:color-mix(in lab,red,red)){.from-gray-500\/10{--tw-gradient-from:color-mix(in oklab,var(--color-gray-500)10%,transparent)}}.from-gray-500\/10{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-white\/10{--tw-gradient-from:#ffffff1a}@supports (color:color-mix(in lab,red,red)){.from-white\/10{--tw-gradient-from:color-mix(in oklab,var(--color-white)10%,transparent)}}.from-white\/10{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-yellow-500\/10{--tw-gradient-from:#edb2001a}@supports (color:color-mix(in lab,red,red)){.from-yellow-500\/10{--tw-gradient-from:color-mix(in oklab,var(--color-yellow-500)10%,transparent)}}.from-yellow-500\/10{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-bambu-dark-secondary{--tw-gradient-to:var(--color-bambu-dark-secondary);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-blue-400{--tw-gradient-to:var(--color-blue-400);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-transparent{--tw-gradient-to:transparent;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.bg-cover{background-size:cover}.bg-center{background-position:50%}.fill-yellow-400{fill:var(--color-yellow-400)}.object-contain{object-fit:contain}.object-cover{object-fit:cover}.object-left{object-position:left}.p-0{padding:calc(var(--spacing)*0)}.p-0\.5{padding:calc(var(--spacing)*.5)}.p-1{padding:calc(var(--spacing)*1)}.p-1\.5{padding:calc(var(--spacing)*1.5)}.p-2{padding:calc(var(--spacing)*2)}.p-2\.5{padding:calc(var(--spacing)*2.5)}.p-3{padding:calc(var(--spacing)*3)}.p-4{padding:calc(var(--spacing)*4)}.p-5{padding:calc(var(--spacing)*5)}.p-6{padding:calc(var(--spacing)*6)}.p-8{padding:calc(var(--spacing)*8)}.p-12{padding:calc(var(--spacing)*12)}.\!px-3{padding-inline:calc(var(--spacing)*3)!important}.px-1{padding-inline:calc(var(--spacing)*1)}.px-1\.5{padding-inline:calc(var(--spacing)*1.5)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-2\.5{padding-inline:calc(var(--spacing)*2.5)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-6{padding-inline:calc(var(--spacing)*6)}.py-0\.5{padding-block:calc(var(--spacing)*.5)}.py-1{padding-block:calc(var(--spacing)*1)}.py-1\.5{padding-block:calc(var(--spacing)*1.5)}.py-2{padding-block:calc(var(--spacing)*2)}.py-2\.5{padding-block:calc(var(--spacing)*2.5)}.py-3{padding-block:calc(var(--spacing)*3)}.py-4{padding-block:calc(var(--spacing)*4)}.py-6{padding-block:calc(var(--spacing)*6)}.py-8{padding-block:calc(var(--spacing)*8)}.py-12{padding-block:calc(var(--spacing)*12)}.py-16{padding-block:calc(var(--spacing)*16)}.py-20{padding-block:calc(var(--spacing)*20)}.py-24{padding-block:calc(var(--spacing)*24)}.pt-0{padding-top:calc(var(--spacing)*0)}.pt-1{padding-top:calc(var(--spacing)*1)}.pt-2{padding-top:calc(var(--spacing)*2)}.pt-3{padding-top:calc(var(--spacing)*3)}.pt-4{padding-top:calc(var(--spacing)*4)}.pr-1{padding-right:calc(var(--spacing)*1)}.pr-2{padding-right:calc(var(--spacing)*2)}.pr-3{padding-right:calc(var(--spacing)*3)}.pr-4{padding-right:calc(var(--spacing)*4)}.pr-6{padding-right:calc(var(--spacing)*6)}.pr-8{padding-right:calc(var(--spacing)*8)}.pr-10{padding-right:calc(var(--spacing)*10)}.pb-1{padding-bottom:calc(var(--spacing)*1)}.pb-2{padding-bottom:calc(var(--spacing)*2)}.pb-4{padding-bottom:calc(var(--spacing)*4)}.pl-2{padding-left:calc(var(--spacing)*2)}.pl-4{padding-left:calc(var(--spacing)*4)}.pl-6{padding-left:calc(var(--spacing)*6)}.pl-8{padding-left:calc(var(--spacing)*8)}.pl-9{padding-left:calc(var(--spacing)*9)}.pl-10{padding-left:calc(var(--spacing)*10)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.font-sans{font-family:var(--font-sans)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[8px\]{font-size:8px}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-amber-200{color:var(--color-amber-200)}.text-amber-300{color:var(--color-amber-300)}.text-amber-300\/60{color:#ffd23699}@supports (color:color-mix(in lab,red,red)){.text-amber-300\/60{color:color-mix(in oklab,var(--color-amber-300)60%,transparent)}}.text-amber-300\/70{color:#ffd236b3}@supports (color:color-mix(in lab,red,red)){.text-amber-300\/70{color:color-mix(in oklab,var(--color-amber-300)70%,transparent)}}.text-amber-300\/80{color:#ffd236cc}@supports (color:color-mix(in lab,red,red)){.text-amber-300\/80{color:color-mix(in oklab,var(--color-amber-300)80%,transparent)}}.text-amber-400{color:var(--color-amber-400)}.text-amber-400\/70{color:#fcbb00b3}@supports (color:color-mix(in lab,red,red)){.text-amber-400\/70{color:color-mix(in oklab,var(--color-amber-400)70%,transparent)}}.text-amber-500{color:var(--color-amber-500)}.text-amber-500\/80{color:#f99c00cc}@supports (color:color-mix(in lab,red,red)){.text-amber-500\/80{color:color-mix(in oklab,var(--color-amber-500)80%,transparent)}}.text-amber-600{color:var(--color-amber-600)}.text-bambu-dark-tertiary{color:var(--color-bambu-dark-tertiary)}.text-bambu-gray{color:var(--color-bambu-gray)}.text-bambu-gray-dark{color:var(--color-bambu-gray-dark)}.text-bambu-gray-light{color:var(--color-bambu-gray-light)}.text-bambu-gray\/30{color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.text-bambu-gray\/30{color:color-mix(in oklab,var(--color-bambu-gray)30%,transparent)}}.text-bambu-gray\/50{color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.text-bambu-gray\/50{color:color-mix(in oklab,var(--color-bambu-gray)50%,transparent)}}.text-bambu-gray\/60{color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.text-bambu-gray\/60{color:color-mix(in oklab,var(--color-bambu-gray)60%,transparent)}}.text-bambu-gray\/70{color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.text-bambu-gray\/70{color:color-mix(in oklab,var(--color-bambu-gray)70%,transparent)}}.text-bambu-gray\/80{color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.text-bambu-gray\/80{color:color-mix(in oklab,var(--color-bambu-gray)80%,transparent)}}.text-bambu-green,.text-bambu-green\/70{color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.text-bambu-green\/70{color:color-mix(in oklab,var(--color-bambu-green)70%,transparent)}}.text-black{color:var(--color-black)}.text-black\/80{color:#000c}@supports (color:color-mix(in lab,red,red)){.text-black\/80{color:color-mix(in oklab,var(--color-black)80%,transparent)}}.text-blue-300{color:var(--color-blue-300)}.text-blue-300\/80{color:#90c5ffcc}@supports (color:color-mix(in lab,red,red)){.text-blue-300\/80{color:color-mix(in oklab,var(--color-blue-300)80%,transparent)}}.text-blue-400{color:var(--color-blue-400)}.text-blue-500{color:var(--color-blue-500)}.text-blue-500\/70{color:#3080ffb3}@supports (color:color-mix(in lab,red,red)){.text-blue-500\/70{color:color-mix(in oklab,var(--color-blue-500)70%,transparent)}}.text-blue-600{color:var(--color-blue-600)}.text-blue-700{color:var(--color-blue-700)}.text-cyan-300{color:var(--color-cyan-300)}.text-cyan-400{color:var(--color-cyan-400)}.text-emerald-400{color:var(--color-emerald-400)}.text-gray-300{color:var(--color-gray-300)}.text-gray-400{color:var(--color-gray-400)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-gray-700{color:var(--color-gray-700)}.text-gray-900{color:var(--color-gray-900)}.text-green-300{color:var(--color-green-300)}.text-green-400{color:var(--color-green-400)}.text-green-500{color:var(--color-green-500)}.text-green-500\/60{color:#00c75899}@supports (color:color-mix(in lab,red,red)){.text-green-500\/60{color:color-mix(in oklab,var(--color-green-500)60%,transparent)}}.text-green-600{color:var(--color-green-600)}.text-indigo-400{color:var(--color-indigo-400)}.text-orange-200{color:var(--color-orange-200)}.text-orange-300{color:var(--color-orange-300)}.text-orange-400{color:var(--color-orange-400)}.text-orange-500{color:var(--color-orange-500)}.text-orange-600{color:var(--color-orange-600)}.text-orange-700{color:var(--color-orange-700)}.text-purple-400{color:var(--color-purple-400)}.text-red-300{color:var(--color-red-300)}.text-red-300\/80{color:#ffa3a3cc}@supports (color:color-mix(in lab,red,red)){.text-red-300\/80{color:color-mix(in oklab,var(--color-red-300)80%,transparent)}}.text-red-400{color:var(--color-red-400)}.text-red-400\/60{color:#ff656899}@supports (color:color-mix(in lab,red,red)){.text-red-400\/60{color:color-mix(in oklab,var(--color-red-400)60%,transparent)}}.text-red-400\/70{color:#ff6568b3}@supports (color:color-mix(in lab,red,red)){.text-red-400\/70{color:color-mix(in oklab,var(--color-red-400)70%,transparent)}}.text-red-500{color:var(--color-red-500)}.text-red-600{color:var(--color-red-600)}.text-rose-400{color:var(--color-rose-400)}.text-white{color:var(--color-white)}.text-white\/60{color:#fff9}@supports (color:color-mix(in lab,red,red)){.text-white\/60{color:color-mix(in oklab,var(--color-white)60%,transparent)}}.text-white\/80{color:#fffc}@supports (color:color-mix(in lab,red,red)){.text-white\/80{color:color-mix(in oklab,var(--color-white)80%,transparent)}}.text-white\/90{color:#ffffffe6}@supports (color:color-mix(in lab,red,red)){.text-white\/90{color:color-mix(in oklab,var(--color-white)90%,transparent)}}.text-yellow-200{color:var(--color-yellow-200)}.text-yellow-400{color:var(--color-yellow-400)}.text-yellow-500{color:var(--color-yellow-500)}.text-yellow-500\/70{color:#edb200b3}@supports (color:color-mix(in lab,red,red)){.text-yellow-500\/70{color:color-mix(in oklab,var(--color-yellow-500)70%,transparent)}}.text-yellow-600{color:var(--color-yellow-600)}.text-yellow-700{color:var(--color-yellow-700)}.capitalize{text-transform:capitalize}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,)var(--tw-slashed-zero,)var(--tw-numeric-figure,)var(--tw-numeric-spacing,)var(--tw-numeric-fraction,)}.line-through{text-decoration-line:line-through}.underline{text-decoration-line:underline}.placeholder-bambu-gray::placeholder{color:var(--color-bambu-gray)}.placeholder-bambu-gray-dark::placeholder{color:var(--color-bambu-gray-dark)}.placeholder-bambu-gray\/50::placeholder{color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.placeholder-bambu-gray\/50::placeholder{color:color-mix(in oklab,var(--color-bambu-gray)50%,transparent)}}.accent-bambu-green{accent-color:var(--color-bambu-green)}.opacity-0{opacity:0}.opacity-20{opacity:.2}.opacity-30{opacity:.3}.opacity-40{opacity:.4}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-80{opacity:.8}.opacity-100{opacity:1}.opacity-\[0\.65\]{opacity:.65}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a),0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-1{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-2{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-bambu-green\/25{--tw-shadow-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.shadow-bambu-green\/25{--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--color-bambu-green)25%,transparent)var(--tw-shadow-alpha),transparent)}}.ring-bambu-green{--tw-ring-color:var(--color-bambu-green)}.ring-blue-400\/50{--tw-ring-color:#54a2ff80}@supports (color:color-mix(in lab,red,red)){.ring-blue-400\/50{--tw-ring-color:color-mix(in oklab,var(--color-blue-400)50%,transparent)}}.ring-white{--tw-ring-color:var(--color-white)}.ring-offset-1{--tw-ring-offset-width:1px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.ring-offset-2{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.ring-offset-bambu-dark{--tw-ring-offset-color:var(--color-bambu-dark)}.ring-offset-bambu-dark-secondary{--tw-ring-offset-color:var(--color-bambu-dark-secondary)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.invert{--tw-invert:invert(100%);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.duration-500{--tw-duration:.5s;transition-duration:.5s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}@media(hover:hover){.group-hover\:bg-bambu-green\/20:is(:where(.group):hover *){background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.group-hover\:bg-bambu-green\/20:is(:where(.group):hover *){background-color:color-mix(in oklab,var(--color-bambu-green)20%,transparent)}}.group-hover\:text-bambu-gray:is(:where(.group):hover *){color:var(--color-bambu-gray)}.group-hover\:text-bambu-green:is(:where(.group):hover *){color:var(--color-bambu-green)}.group-hover\:opacity-50:is(:where(.group):hover *){opacity:.5}.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}.group-hover\/thumb\:block:is(:where(.group\/thumb):hover *){display:block}}.peer-checked\:bg-bambu-green:is(:where(.peer):checked~*){background-color:var(--color-bambu-green)}.peer-focus\:outline-none:is(:where(.peer):focus~*){--tw-outline-style:none;outline-style:none}.placeholder\:text-bambu-gray::placeholder{color:var(--color-bambu-gray)}.before\:absolute:before{content:var(--tw-content);position:absolute}.before\:top-0:before{content:var(--tw-content);top:calc(var(--spacing)*0)}.before\:right-0:before{content:var(--tw-content);right:calc(var(--spacing)*0)}.before\:left-0:before{content:var(--tw-content);left:calc(var(--spacing)*0)}.before\:h-0\.5:before{content:var(--tw-content);height:calc(var(--spacing)*.5)}.before\:bg-bambu-green:before{content:var(--tw-content);background-color:var(--color-bambu-green)}.after\:absolute:after{content:var(--tw-content);position:absolute}.after\:top-\[2px\]:after{content:var(--tw-content);top:2px}.after\:left-\[2px\]:after{content:var(--tw-content);left:2px}.after\:h-4:after{content:var(--tw-content);height:calc(var(--spacing)*4)}.after\:h-5:after{content:var(--tw-content);height:calc(var(--spacing)*5)}.after\:w-4:after{content:var(--tw-content);width:calc(var(--spacing)*4)}.after\:w-5:after{content:var(--tw-content);width:calc(var(--spacing)*5)}.after\:rounded-full:after{content:var(--tw-content);border-radius:3.40282e38px}.after\:bg-white:after{content:var(--tw-content);background-color:var(--color-white)}.after\:transition-all:after{content:var(--tw-content);transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.after\:content-\[\'\'\]:after{--tw-content:"";content:var(--tw-content)}.peer-checked\:after\:translate-x-full:is(:where(.peer):checked~*):after{content:var(--tw-content);--tw-translate-x:100%;translate:var(--tw-translate-x)var(--tw-translate-y)}.peer-checked\:after\:border-white:is(:where(.peer):checked~*):after{content:var(--tw-content);border-color:var(--color-white)}.last\:border-0:last-child{border-style:var(--tw-border-style);border-width:0}.last\:border-b-0:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}@media(hover:hover){.hover\:border-bambu-dark-tertiary\/80:hover{border-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.hover\:border-bambu-dark-tertiary\/80:hover{border-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)80%,transparent)}}.hover\:border-bambu-gray:hover{border-color:var(--color-bambu-gray)}.hover\:border-bambu-gray-dark:hover{border-color:var(--color-bambu-gray-dark)}.hover\:border-bambu-green:hover,.hover\:border-bambu-green\/50:hover{border-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:border-bambu-green\/50:hover{border-color:color-mix(in oklab,var(--color-bambu-green)50%,transparent)}}.hover\:border-white\/40:hover{border-color:#fff6}@supports (color:color-mix(in lab,red,red)){.hover\:border-white\/40:hover{border-color:color-mix(in oklab,var(--color-white)40%,transparent)}}.hover\:bg-amber-500\/30:hover{background-color:#f99c004d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-amber-500\/30:hover{background-color:color-mix(in oklab,var(--color-amber-500)30%,transparent)}}.hover\:bg-bambu-dark:hover{background-color:var(--color-bambu-dark)}.hover\:bg-bambu-dark-secondary:hover{background-color:var(--color-bambu-dark-secondary)}.hover\:bg-bambu-dark-tertiary:hover,.hover\:bg-bambu-dark-tertiary\/30:hover{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-dark-tertiary\/30:hover{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)30%,transparent)}}.hover\:bg-bambu-dark-tertiary\/50:hover{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-dark-tertiary\/50:hover{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)50%,transparent)}}.hover\:bg-bambu-dark-tertiary\/70:hover{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-dark-tertiary\/70:hover{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)70%,transparent)}}.hover\:bg-bambu-dark-tertiary\/80:hover{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-dark-tertiary\/80:hover{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)80%,transparent)}}.hover\:bg-bambu-dark\/50:hover{background-color:var(--color-bambu-dark)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-dark\/50:hover{background-color:color-mix(in oklab,var(--color-bambu-dark)50%,transparent)}}.hover\:bg-bambu-gray-dark:hover{background-color:var(--color-bambu-gray-dark)}.hover\:bg-bambu-green:hover{background-color:var(--color-bambu-green)}.hover\:bg-bambu-green-dark:hover{background-color:var(--color-bambu-green-dark)}.hover\:bg-bambu-green-light:hover{background-color:var(--color-bambu-green-light)}.hover\:bg-bambu-green\/10:hover{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-green\/10:hover{background-color:color-mix(in oklab,var(--color-bambu-green)10%,transparent)}}.hover\:bg-bambu-green\/20:hover{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-green\/20:hover{background-color:color-mix(in oklab,var(--color-bambu-green)20%,transparent)}}.hover\:bg-bambu-green\/30:hover{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-green\/30:hover{background-color:color-mix(in oklab,var(--color-bambu-green)30%,transparent)}}.hover\:bg-bambu-green\/80:hover{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-green\/80:hover{background-color:color-mix(in oklab,var(--color-bambu-green)80%,transparent)}}.hover\:bg-black\/40:hover{background-color:#0006}@supports (color:color-mix(in lab,red,red)){.hover\:bg-black\/40:hover{background-color:color-mix(in oklab,var(--color-black)40%,transparent)}}.hover\:bg-black\/70:hover{background-color:#000000b3}@supports (color:color-mix(in lab,red,red)){.hover\:bg-black\/70:hover{background-color:color-mix(in oklab,var(--color-black)70%,transparent)}}.hover\:bg-black\/80:hover{background-color:#000c}@supports (color:color-mix(in lab,red,red)){.hover\:bg-black\/80:hover{background-color:color-mix(in oklab,var(--color-black)80%,transparent)}}.hover\:bg-blue-500\/30:hover{background-color:#3080ff4d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-blue-500\/30:hover{background-color:color-mix(in oklab,var(--color-blue-500)30%,transparent)}}.hover\:bg-gray-50:hover{background-color:var(--color-gray-50)}.hover\:bg-gray-100:hover{background-color:var(--color-gray-100)}.hover\:bg-gray-700:hover{background-color:var(--color-gray-700)}.hover\:bg-orange-400\/20:hover{background-color:#ff8b1a33}@supports (color:color-mix(in lab,red,red)){.hover\:bg-orange-400\/20:hover{background-color:color-mix(in oklab,var(--color-orange-400)20%,transparent)}}.hover\:bg-red-200:hover{background-color:var(--color-red-200)}.hover\:bg-red-400\/10:hover{background-color:#ff65681a}@supports (color:color-mix(in lab,red,red)){.hover\:bg-red-400\/10:hover{background-color:color-mix(in oklab,var(--color-red-400)10%,transparent)}}.hover\:bg-red-500\/10:hover{background-color:#fb2c361a}@supports (color:color-mix(in lab,red,red)){.hover\:bg-red-500\/10:hover{background-color:color-mix(in oklab,var(--color-red-500)10%,transparent)}}.hover\:bg-red-500\/20:hover{background-color:#fb2c3633}@supports (color:color-mix(in lab,red,red)){.hover\:bg-red-500\/20:hover{background-color:color-mix(in oklab,var(--color-red-500)20%,transparent)}}.hover\:bg-red-500\/30:hover{background-color:#fb2c364d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-red-500\/30:hover{background-color:color-mix(in oklab,var(--color-red-500)30%,transparent)}}.hover\:bg-red-600:hover{background-color:var(--color-red-600)}.hover\:bg-red-700:hover{background-color:var(--color-red-700)}.hover\:bg-white\/10:hover{background-color:#ffffff1a}@supports (color:color-mix(in lab,red,red)){.hover\:bg-white\/10:hover{background-color:color-mix(in oklab,var(--color-white)10%,transparent)}}.hover\:bg-yellow-500\/30:hover{background-color:#edb2004d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-yellow-500\/30:hover{background-color:color-mix(in oklab,var(--color-yellow-500)30%,transparent)}}.hover\:bg-yellow-600:hover{background-color:var(--color-yellow-600)}.hover\:text-amber-300:hover{color:var(--color-amber-300)}.hover\:text-bambu-gray:hover{color:var(--color-bambu-gray)}.hover\:text-bambu-green:hover{color:var(--color-bambu-green)}.hover\:text-bambu-green-light:hover{color:var(--color-bambu-green-light)}.hover\:text-bambu-green\/70:hover{color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:text-bambu-green\/70:hover{color:color-mix(in oklab,var(--color-bambu-green)70%,transparent)}}.hover\:text-bambu-green\/80:hover{color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:text-bambu-green\/80:hover{color:color-mix(in oklab,var(--color-bambu-green)80%,transparent)}}.hover\:text-blue-300:hover{color:var(--color-blue-300)}.hover\:text-gray-900:hover{color:var(--color-gray-900)}.hover\:text-orange-300:hover{color:var(--color-orange-300)}.hover\:text-red-300:hover{color:var(--color-red-300)}.hover\:text-red-400:hover{color:var(--color-red-400)}.hover\:text-white:hover{color:var(--color-white)}.hover\:text-white\/80:hover{color:#fffc}@supports (color:color-mix(in lab,red,red)){.hover\:text-white\/80:hover{color:color-mix(in oklab,var(--color-white)80%,transparent)}}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-70:hover{opacity:.7}.hover\:opacity-80:hover{opacity:.8}.hover\:shadow-lg:hover{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hover\:shadow-bambu-green\/5:hover{--tw-shadow-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:shadow-bambu-green\/5:hover{--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--color-bambu-green)5%,transparent)var(--tw-shadow-alpha),transparent)}}}.focus\:border-bambu-green:focus{border-color:var(--color-bambu-green)}.focus\:border-red-500:focus{border-color:var(--color-red-500)}.focus\:ring-1:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-bambu-gray:focus{--tw-ring-color:var(--color-bambu-gray)}.focus\:ring-bambu-green:focus{--tw-ring-color:var(--color-bambu-green)}.focus\:ring-red-500:focus{--tw-ring-color:var(--color-red-500)}.focus\:ring-offset-0:focus{--tw-ring-offset-width:0px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.focus\:ring-offset-2:focus{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.focus\:ring-offset-bambu-dark:focus{--tw-ring-offset-color:var(--color-bambu-dark)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.active\:cursor-grabbing:active{cursor:grabbing}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-30:disabled{opacity:.3}.disabled\:opacity-50:disabled{opacity:.5}@media(min-width:40rem){.sm\:inline{display:inline}.sm\:h-4{height:calc(var(--spacing)*4)}.sm\:w-4{width:calc(var(--spacing)*4)}.sm\:w-auto{width:auto}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:items-center{align-items:center}.sm\:p-1\.5{padding:calc(var(--spacing)*1.5)}}@media(min-width:48rem){.md\:top-\[2px\]{top:2px}.md\:left-\[2px\]{left:2px}.md\:mx-0{margin-inline:calc(var(--spacing)*0)}.md\:block{display:block}.md\:inline{display:inline}.md\:h-4{height:calc(var(--spacing)*4)}.md\:h-5{height:calc(var(--spacing)*5)}.md\:h-8{height:calc(var(--spacing)*8)}.md\:min-h-0{min-height:calc(var(--spacing)*0)}.md\:w-4{width:calc(var(--spacing)*4)}.md\:w-8{width:calc(var(--spacing)*8)}.md\:w-9{width:calc(var(--spacing)*9)}.md\:min-w-\[200px\]{min-width:200px}.md\:flex-1{flex:1}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.md\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.md\:flex-row{flex-direction:row}.md\:flex-wrap{flex-wrap:wrap}.md\:items-center{align-items:center}.md\:gap-4{gap:calc(var(--spacing)*4)}.md\:p-8{padding:calc(var(--spacing)*8)}.md\:px-0{padding-inline:calc(var(--spacing)*0)}.md\:py-2{padding-block:calc(var(--spacing)*2)}.md\:pb-0{padding-bottom:calc(var(--spacing)*0)}}@media(min-width:64rem){.lg\:col-span-2{grid-column:span 2/span 2}.lg\:w-80{width:calc(var(--spacing)*80)}.lg\:w-\[480px\]{width:480px}.lg\:max-w-md{max-width:var(--container-md)}.lg\:max-w-sm{max-width:var(--container-sm)}.lg\:max-w-xl{max-width:var(--container-xl)}.lg\:flex-shrink-0{flex-shrink:0}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.lg\:flex-row{flex-direction:row}.lg\:gap-8{gap:calc(var(--spacing)*8)}.lg\:p-8{padding:calc(var(--spacing)*8)}}@media(min-width:80rem){.xl\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.xl\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.xl\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.xl\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.xl\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}}@media(min-width:96rem){.\32xl\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}}.dark\:border-bambu-dark-tertiary:where(.dark,.dark *),.dark\:border-bambu-dark-tertiary\/50:where(.dark,.dark *){border-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.dark\:border-bambu-dark-tertiary\/50:where(.dark,.dark *){border-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)50%,transparent)}}.dark\:border-bambu-green\/40:where(.dark,.dark *){border-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.dark\:border-bambu-green\/40:where(.dark,.dark *){border-color:color-mix(in oklab,var(--color-bambu-green)40%,transparent)}}.dark\:border-gray-600:where(.dark,.dark *){border-color:var(--color-gray-600)}.dark\:border-red-500\/30:where(.dark,.dark *){border-color:#fb2c364d}@supports (color:color-mix(in lab,red,red)){.dark\:border-red-500\/30:where(.dark,.dark *){border-color:color-mix(in oklab,var(--color-red-500)30%,transparent)}}.dark\:border-red-500\/40:where(.dark,.dark *){border-color:#fb2c3666}@supports (color:color-mix(in lab,red,red)){.dark\:border-red-500\/40:where(.dark,.dark *){border-color:color-mix(in oklab,var(--color-red-500)40%,transparent)}}.dark\:bg-amber-500\/10:where(.dark,.dark *){background-color:#f99c001a}@supports (color:color-mix(in lab,red,red)){.dark\:bg-amber-500\/10:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-amber-500)10%,transparent)}}.dark\:bg-bambu-dark:where(.dark,.dark *){background-color:var(--color-bambu-dark)}.dark\:bg-bambu-dark-secondary:where(.dark,.dark *){background-color:var(--color-bambu-dark-secondary)}.dark\:bg-bambu-green\/20:where(.dark,.dark *){background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.dark\:bg-bambu-green\/20:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-bambu-green)20%,transparent)}}.dark\:bg-black\/80:where(.dark,.dark *){background-color:#000c}@supports (color:color-mix(in lab,red,red)){.dark\:bg-black\/80:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-black)80%,transparent)}}.dark\:bg-blue-500\/10:where(.dark,.dark *){background-color:#3080ff1a}@supports (color:color-mix(in lab,red,red)){.dark\:bg-blue-500\/10:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-blue-500)10%,transparent)}}.dark\:bg-blue-500\/20:where(.dark,.dark *){background-color:#3080ff33}@supports (color:color-mix(in lab,red,red)){.dark\:bg-blue-500\/20:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-blue-500)20%,transparent)}}.dark\:bg-gray-500\/40:where(.dark,.dark *){background-color:#6a728266}@supports (color:color-mix(in lab,red,red)){.dark\:bg-gray-500\/40:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-gray-500)40%,transparent)}}.dark\:bg-gray-900:where(.dark,.dark *){background-color:var(--color-gray-900)}.dark\:bg-red-500\/10:where(.dark,.dark *){background-color:#fb2c361a}@supports (color:color-mix(in lab,red,red)){.dark\:bg-red-500\/10:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-red-500)10%,transparent)}}.dark\:bg-red-500\/20:where(.dark,.dark *){background-color:#fb2c3633}@supports (color:color-mix(in lab,red,red)){.dark\:bg-red-500\/20:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-red-500)20%,transparent)}}.dark\:text-amber-400:where(.dark,.dark *){color:var(--color-amber-400)}.dark\:text-bambu-gray:where(.dark,.dark *),.dark\:text-bambu-gray\/30:where(.dark,.dark *){color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.dark\:text-bambu-gray\/30:where(.dark,.dark *){color:color-mix(in oklab,var(--color-bambu-gray)30%,transparent)}}.dark\:text-bambu-gray\/50:where(.dark,.dark *){color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.dark\:text-bambu-gray\/50:where(.dark,.dark *){color:color-mix(in oklab,var(--color-bambu-gray)50%,transparent)}}.dark\:text-bambu-green:where(.dark,.dark *),.dark\:text-bambu-green\/60:where(.dark,.dark *){color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.dark\:text-bambu-green\/60:where(.dark,.dark *){color:color-mix(in oklab,var(--color-bambu-green)60%,transparent)}}.dark\:text-blue-200:where(.dark,.dark *){color:var(--color-blue-200)}.dark\:text-blue-200\/80:where(.dark,.dark *){color:#bedbffcc}@supports (color:color-mix(in lab,red,red)){.dark\:text-blue-200\/80:where(.dark,.dark *){color:color-mix(in oklab,var(--color-blue-200)80%,transparent)}}.dark\:text-blue-300:where(.dark,.dark *){color:var(--color-blue-300)}.dark\:text-blue-300\/60:where(.dark,.dark *){color:#90c5ff99}@supports (color:color-mix(in lab,red,red)){.dark\:text-blue-300\/60:where(.dark,.dark *){color:color-mix(in oklab,var(--color-blue-300)60%,transparent)}}.dark\:text-blue-400:where(.dark,.dark *){color:var(--color-blue-400)}.dark\:text-orange-200:where(.dark,.dark *){color:var(--color-orange-200)}.dark\:text-orange-400:where(.dark,.dark *){color:var(--color-orange-400)}.dark\:text-red-400:where(.dark,.dark *){color:var(--color-red-400)}.dark\:text-red-400\/70:where(.dark,.dark *){color:#ff6568b3}@supports (color:color-mix(in lab,red,red)){.dark\:text-red-400\/70:where(.dark,.dark *){color:color-mix(in oklab,var(--color-red-400)70%,transparent)}}.dark\:text-white:where(.dark,.dark *){color:var(--color-white)}.dark\:text-yellow-200:where(.dark,.dark *){color:var(--color-yellow-200)}.dark\:text-yellow-200\/70:where(.dark,.dark *){color:#fff085b3}@supports (color:color-mix(in lab,red,red)){.dark\:text-yellow-200\/70:where(.dark,.dark *){color:color-mix(in oklab,var(--color-yellow-200)70%,transparent)}}@media(hover:hover){.dark\:hover\:bg-bambu-dark-tertiary:where(.dark,.dark *):hover{background-color:var(--color-bambu-dark-tertiary)}.dark\:hover\:bg-bambu-dark\/50:where(.dark,.dark *):hover{background-color:var(--color-bambu-dark)}@supports (color:color-mix(in lab,red,red)){.dark\:hover\:bg-bambu-dark\/50:where(.dark,.dark *):hover{background-color:color-mix(in oklab,var(--color-bambu-dark)50%,transparent)}}.dark\:hover\:bg-red-500\/30:where(.dark,.dark *):hover{background-color:#fb2c364d}@supports (color:color-mix(in lab,red,red)){.dark\:hover\:bg-red-500\/30:where(.dark,.dark *):hover{background-color:color-mix(in oklab,var(--color-red-500)30%,transparent)}}.dark\:hover\:text-white:where(.dark,.dark *):hover{color:var(--color-white)}}.\[\&\:\:-webkit-slider-thumb\]\:h-3::-webkit-slider-thumb{height:calc(var(--spacing)*3)}.\[\&\:\:-webkit-slider-thumb\]\:w-3::-webkit-slider-thumb{width:calc(var(--spacing)*3)}.\[\&\:\:-webkit-slider-thumb\]\:cursor-pointer::-webkit-slider-thumb{cursor:pointer}.\[\&\:\:-webkit-slider-thumb\]\:appearance-none::-webkit-slider-thumb{appearance:none}.\[\&\:\:-webkit-slider-thumb\]\:rounded-full::-webkit-slider-thumb{border-radius:3.40282e38px}.\[\&\:\:-webkit-slider-thumb\]\:bg-bambu-green::-webkit-slider-thumb{background-color:var(--color-bambu-green)}}:root{--accent:#00ae42;--accent-light:#00c64d;--accent-dark:#009438;--bg-primary:#f5f5f5;--bg-secondary:#fff;--bg-tertiary:#e5e5e5;--text-primary:#1a1a1a;--text-secondary:#4a4a4a;--text-muted:#6b6b6b;--text-tertiary:gray;--border-color:#d4d4d4;--card-shadow:0 2px 8px #00000014;--glow-color:transparent;font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:Inter,system-ui,sans-serif;font-weight:400;line-height:1.5}.dark{--bg-primary:#1a1a1a;--bg-secondary:#2d2d2d;--bg-tertiary:#3d3d3d;--text-primary:#fff;--text-secondary:#a0a0a0;--text-muted:gray;--text-tertiary:#4a4a4a;--border-color:#3d3d3d;--card-shadow:0 4px 16px #0006}.bg-warm{--bg-primary:#faf8f5;--bg-secondary:#fffefa;--bg-tertiary:#e8e4dd;--text-primary:#2d2a26;--text-secondary:#5c5750;--text-muted:#7a756c;--text-tertiary:#9a9590;--border-color:#d8d4cc}.bg-cool{--bg-primary:#f0f4f8;--bg-secondary:#fff;--bg-tertiary:#dce4ec;--text-primary:#1a2530;--text-secondary:#4a5568;--text-muted:#6b7a8a;--text-tertiary:#8a9aaa;--border-color:#c8d4e0}.dark.bg-neutral{--bg-primary:#1a1a1a;--bg-secondary:#2d2d2d;--bg-tertiary:#3d3d3d;--text-primary:#fff;--text-secondary:#a0a0a0;--text-muted:gray;--text-tertiary:#4a4a4a;--border-color:#3d3d3d}.dark.bg-warm{--bg-primary:#1c1a18;--bg-secondary:#2e2a26;--bg-tertiary:#3e3a36;--text-primary:#f5f0ea;--text-secondary:#b0a898;--text-muted:#8a8278;--text-tertiary:#5a5248;--border-color:#3e3a36}.dark.bg-cool{--bg-primary:#181c20;--bg-secondary:#262c32;--bg-tertiary:#363e46;--text-primary:#f0f4f8;--text-secondary:#98a8b8;--text-muted:#788898;--text-tertiary:#4a5a6a;--border-color:#363e46}.dark.bg-oled{--bg-primary:#000;--bg-secondary:#141414;--bg-tertiary:#1f1f1f;--text-primary:#fff;--text-secondary:#a0a0a0;--text-muted:#707070;--text-tertiary:#404040;--border-color:#2a2a2a}.dark.bg-slate{--bg-primary:#0f172a;--bg-secondary:#1e293b;--bg-tertiary:#334155;--text-primary:#f1f5f9;--text-secondary:#94a3b8;--text-muted:#64748b;--text-tertiary:#475569;--border-color:#334155}.dark.bg-forest{--bg-primary:#121a16;--bg-secondary:#1c2a22;--bg-tertiary:#2a3d30;--text-primary:#e8f5ec;--text-secondary:#8aa894;--text-muted:#6a8874;--text-tertiary:#4a6854;--border-color:#2a3d30}.style-glow{--card-shadow:0 2px 8px #00000014,0 0 25px var(--accent)}@supports (color:color-mix(in lab,red,red)){.style-glow{--card-shadow:0 2px 8px #00000014,0 0 25px color-mix(in srgb,var(--accent)12%,transparent)}}.dark.style-glow{--card-shadow:0 4px 20px #00000080,0 0 40px var(--accent)}@supports (color:color-mix(in lab,red,red)){.dark.style-glow{--card-shadow:0 4px 20px #00000080,0 0 40px color-mix(in srgb,var(--accent)15%,transparent)}}.style-vibrant{--card-shadow:0 8px 30px #00000026,0 2px 8px #0000001a}.dark.style-vibrant{--card-shadow:0 10px 40px #0009,0 4px 12px #0006}.accent-green{--accent:#00ae42;--accent-light:#00c64d;--accent-dark:#009438}.accent-teal{--accent:#14b8a6;--accent-light:#2dd4bf;--accent-dark:#0d9488}.accent-blue{--accent:#3b82f6;--accent-light:#60a5fa;--accent-dark:#2563eb}.accent-orange{--accent:#f97316;--accent-light:#fb923c;--accent-dark:#ea580c}.accent-purple{--accent:#8b5cf6;--accent-light:#a78bfa;--accent-dark:#7c3aed}.accent-red{--accent:#ef4444;--accent-light:#f87171;--accent-dark:#dc2626}body{background-color:var(--bg-primary);color:var(--text-primary);min-height:100vh;margin:0;transition:background-color .2s,color .2s}#root{min-height:100vh}.text-white{color:var(--text-primary)}.bg-bambu-dark,.bg-bambu-dark-secondary,.bg-bambu-dark-tertiary,.border-bambu-dark-tertiary{transition:background-color .2s,border-color .2s}@keyframes slide-in{0%{opacity:0;transform:translate(100%)}to{opacity:1;transform:translate(0)}}.animate-slide-in{animation:.2s ease-out slide-in}.icon-theme{opacity:.5}.dark .icon-theme{filter:invert();opacity:.4}.icon-green{filter:invert(48%)sepia(89%)saturate(459%)hue-rotate(93deg)brightness(95%)contrast(92%);opacity:1}.icon-heating{filter:invert(50%)sepia()saturate(1000%)hue-rotate(360deg)brightness()contrast();opacity:1}.dark .jogpad-theme{filter:brightness(.35)contrast(1.2)}.ams-empty-slot{background:repeating-linear-gradient(45deg,#444,#444 2px,#222 2px 4px)}.dark .ams-empty-slot{background:repeating-linear-gradient(45deg,#555,#555 2px,#333 2px 4px)}.touch-manipulation{touch-action:manipulation}.safe-area-bottom{padding-bottom:env(safe-area-inset-bottom,0)}.safe-area-top{padding-top:env(safe-area-inset-top,0)}.scrollbar-hide{-ms-overflow-style:none;scrollbar-width:none}.scrollbar-hide::-webkit-scrollbar{display:none}@keyframes slide-in-left{0%{transform:translate(-100%)}to{transform:translate(0)}}.animate-slide-in-left{animation:.3s ease-out slide-in-left}.card-shadow{box-shadow:var(--card-shadow)}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"";inherits:false;initial-value:100%}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-content:""}}} diff --git a/static/assets/index-DE9m9l_f.js b/static/assets/index-BJM8SBBV.js similarity index 51% rename from static/assets/index-DE9m9l_f.js rename to static/assets/index-BJM8SBBV.js index bd10cffdc..719f42553 100644 --- a/static/assets/index-DE9m9l_f.js +++ b/static/assets/index-BJM8SBBV.js @@ -1,20 +1,20 @@ -function Hie(t,e){for(var n=0;nr[i]})}}}return Object.freeze(Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}))}(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))r(i);new MutationObserver(i=>{for(const a of i)if(a.type==="childList")for(const o of a.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&r(o)}).observe(document,{childList:!0,subtree:!0});function n(i){const a={};return i.integrity&&(a.integrity=i.integrity),i.referrerPolicy&&(a.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?a.credentials="include":i.crossOrigin==="anonymous"?a.credentials="omit":a.credentials="same-origin",a}function r(i){if(i.ep)return;i.ep=!0;const a=n(i);fetch(i.href,a)}})();var Fv=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function Co(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var iA={exports:{}},Dx={};var VF;function Vie(){if(VF)return Dx;VF=1;var t=Symbol.for("react.transitional.element"),e=Symbol.for("react.fragment");function n(r,i,a){var o=null;if(a!==void 0&&(o=""+a),i.key!==void 0&&(o=""+i.key),"key"in i){a={};for(var l in i)l!=="key"&&(a[l]=i[l])}else a=i;return i=a.ref,{$$typeof:t,type:r,key:o,ref:i!==void 0?i:null,props:a}}return Dx.Fragment=e,Dx.jsx=n,Dx.jsxs=n,Dx}var GF;function Gie(){return GF||(GF=1,iA.exports=Vie()),iA.exports}var s=Gie(),aA={exports:{}},rn={};var WF;function Wie(){if(WF)return rn;WF=1;var t=Symbol.for("react.transitional.element"),e=Symbol.for("react.portal"),n=Symbol.for("react.fragment"),r=Symbol.for("react.strict_mode"),i=Symbol.for("react.profiler"),a=Symbol.for("react.consumer"),o=Symbol.for("react.context"),l=Symbol.for("react.forward_ref"),c=Symbol.for("react.suspense"),u=Symbol.for("react.memo"),d=Symbol.for("react.lazy"),f=Symbol.for("react.activity"),p=Symbol.iterator;function g(z){return z===null||typeof z!="object"?null:(z=p&&z[p]||z["@@iterator"],typeof z=="function"?z:null)}var b={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},v=Object.assign,x={};function y(z,G,te){this.props=z,this.context=G,this.refs=x,this.updater=te||b}y.prototype.isReactComponent={},y.prototype.setState=function(z,G){if(typeof z!="object"&&typeof z!="function"&&z!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,z,G,"setState")},y.prototype.forceUpdate=function(z){this.updater.enqueueForceUpdate(this,z,"forceUpdate")};function E(){}E.prototype=y.prototype;function w(z,G,te){this.props=z,this.context=G,this.refs=x,this.updater=te||b}var A=w.prototype=new E;A.constructor=w,v(A,y.prototype),A.isPureReactComponent=!0;var N=Array.isArray;function k(){}var T={H:null,A:null,T:null,S:null},D=Object.prototype.hasOwnProperty;function C(z,G,te){var ne=te.ref;return{$$typeof:t,type:z,key:G,ref:ne!==void 0?ne:null,props:te}}function P(z,G){return C(z.type,G,z.props)}function U(z){return typeof z=="object"&&z!==null&&z.$$typeof===t}function L(z){var G={"=":"=0",":":"=2"};return"$"+z.replace(/[=:]/g,function(te){return G[te]})}var W=/\/+/g;function R(z,G){return typeof z=="object"&&z!==null&&z.key!=null?L(""+z.key):G.toString(36)}function K(z){switch(z.status){case"fulfilled":return z.value;case"rejected":throw z.reason;default:switch(typeof z.status=="string"?z.then(k,k):(z.status="pending",z.then(function(G){z.status==="pending"&&(z.status="fulfilled",z.value=G)},function(G){z.status==="pending"&&(z.status="rejected",z.reason=G)})),z.status){case"fulfilled":return z.value;case"rejected":throw z.reason}}throw z}function Q(z,G,te,ne,oe){var ue=typeof z;(ue==="undefined"||ue==="boolean")&&(z=null);var fe=!1;if(z===null)fe=!0;else switch(ue){case"bigint":case"string":case"number":fe=!0;break;case"object":switch(z.$$typeof){case t:case e:fe=!0;break;case d:return fe=z._init,Q(fe(z._payload),G,te,ne,oe)}}if(fe)return oe=oe(z),fe=ne===""?"."+R(z,0):ne,N(oe)?(te="",fe!=null&&(te=fe.replace(W,"$&/")+"/"),Q(oe,G,te,"",function(Ee){return Ee})):oe!=null&&(U(oe)&&(oe=P(oe,te+(oe.key==null||z&&z.key===oe.key?"":(""+oe.key).replace(W,"$&/")+"/")+fe)),G.push(oe)),1;fe=0;var Te=ne===""?".":ne+":";if(N(z))for(var me=0;me>>1,re=Q[ie];if(0>>1;iei(te,J))nei(oe,te)?(Q[ie]=oe,Q[ne]=J,ie=ne):(Q[ie]=te,Q[G]=J,ie=G);else if(nei(oe,J))Q[ie]=oe,Q[ne]=J,ie=ne;else break e}}return q}function i(Q,q){var J=Q.sortIndex-q.sortIndex;return J!==0?J:Q.id-q.id}if(t.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var a=performance;t.unstable_now=function(){return a.now()}}else{var o=Date,l=o.now();t.unstable_now=function(){return o.now()-l}}var c=[],u=[],d=1,f=null,p=3,g=!1,b=!1,v=!1,x=!1,y=typeof setTimeout=="function"?setTimeout:null,E=typeof clearTimeout=="function"?clearTimeout:null,w=typeof setImmediate<"u"?setImmediate:null;function A(Q){for(var q=n(u);q!==null;){if(q.callback===null)r(u);else if(q.startTime<=Q)r(u),q.sortIndex=q.expirationTime,e(c,q);else break;q=n(u)}}function N(Q){if(v=!1,A(Q),!b)if(n(c)!==null)b=!0,k||(k=!0,L());else{var q=n(u);q!==null&&K(N,q.startTime-Q)}}var k=!1,T=-1,D=5,C=-1;function P(){return x?!0:!(t.unstable_now()-CQ&&P());){var ie=f.callback;if(typeof ie=="function"){f.callback=null,p=f.priorityLevel;var re=ie(f.expirationTime<=Q);if(Q=t.unstable_now(),typeof re=="function"){f.callback=re,A(Q),q=!0;break t}f===n(c)&&r(c),A(Q)}else r(c);f=n(c)}if(f!==null)q=!0;else{var z=n(u);z!==null&&K(N,z.startTime-Q),q=!1}}break e}finally{f=null,p=J,g=!1}q=void 0}}finally{q?L():k=!1}}}var L;if(typeof w=="function")L=function(){w(U)};else if(typeof MessageChannel<"u"){var W=new MessageChannel,R=W.port2;W.port1.onmessage=U,L=function(){R.postMessage(null)}}else L=function(){y(U,0)};function K(Q,q){T=y(function(){Q(t.unstable_now())},q)}t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(Q){Q.callback=null},t.unstable_forceFrameRate=function(Q){0>Q||125ie?(Q.sortIndex=J,e(u,Q),n(c)===null&&Q===n(u)&&(v?(E(T),T=-1):v=!0,K(N,J-ie))):(Q.sortIndex=re,e(c,Q),b||g||(b=!0,k||(k=!0,L()))),Q},t.unstable_shouldYield=P,t.unstable_wrapCallback=function(Q){var q=p;return function(){var J=p;p=q;try{return Q.apply(this,arguments)}finally{p=J}}}})(lA)),lA}var XF;function Xie(){return XF||(XF=1,oA.exports=Kie()),oA.exports}var cA={exports:{}},ga={};var YF;function Yie(){if(YF)return ga;YF=1;var t=yg();function e(c){var u="https://react.dev/errors/"+c;if(1"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(t)}catch(e){console.error(e)}}return t(),cA.exports=Yie(),cA.exports}var ZF;function Qie(){if(ZF)return Ox;ZF=1;var t=Xie(),e=yg(),n=NG();function r(h){var m="https://react.dev/errors/"+h;if(1re||(h.current=ie[re],ie[re]=null,re--)}function te(h,m){re++,ie[re]=h.current,h.current=m}var ne=z(null),oe=z(null),ue=z(null),fe=z(null);function Te(h,m){switch(te(ue,m),te(oe,h),te(ne,null),m.nodeType){case 9:case 11:h=(h=m.documentElement)&&(h=h.namespaceURI)?fF(h):0;break;default:if(h=m.tagName,m=m.namespaceURI)m=fF(m),h=mF(m,h);else switch(h){case"svg":h=1;break;case"math":h=2;break;default:h=0}}G(ne),te(ne,h)}function me(){G(ne),G(oe),G(ue)}function Ee(h){h.memoizedState!==null&&te(fe,h);var m=ne.current,_=mF(m,h.type);m!==_&&(te(oe,h),te(ne,_))}function be(h){oe.current===h&&(G(ne),G(oe)),fe.current===h&&(G(fe),kx._currentValue=J)}var Z,Be;function V(h){if(Z===void 0)try{throw Error()}catch(_){var m=_.stack.trim().match(/\n( *(at )?)/);Z=m&&m[1]||"",Be=-1<_.stack.indexOf(` +function Hie(t,e){for(var n=0;nr[i]})}}}return Object.freeze(Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}))}(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))r(i);new MutationObserver(i=>{for(const a of i)if(a.type==="childList")for(const o of a.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&r(o)}).observe(document,{childList:!0,subtree:!0});function n(i){const a={};return i.integrity&&(a.integrity=i.integrity),i.referrerPolicy&&(a.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?a.credentials="include":i.crossOrigin==="anonymous"?a.credentials="omit":a.credentials="same-origin",a}function r(i){if(i.ep)return;i.ep=!0;const a=n(i);fetch(i.href,a)}})();var Fv=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function Co(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var iA={exports:{}},Dx={};var GF;function Vie(){if(GF)return Dx;GF=1;var t=Symbol.for("react.transitional.element"),e=Symbol.for("react.fragment");function n(r,i,a){var o=null;if(a!==void 0&&(o=""+a),i.key!==void 0&&(o=""+i.key),"key"in i){a={};for(var l in i)l!=="key"&&(a[l]=i[l])}else a=i;return i=a.ref,{$$typeof:t,type:r,key:o,ref:i!==void 0?i:null,props:a}}return Dx.Fragment=e,Dx.jsx=n,Dx.jsxs=n,Dx}var WF;function Gie(){return WF||(WF=1,iA.exports=Vie()),iA.exports}var s=Gie(),aA={exports:{}},rn={};var qF;function Wie(){if(qF)return rn;qF=1;var t=Symbol.for("react.transitional.element"),e=Symbol.for("react.portal"),n=Symbol.for("react.fragment"),r=Symbol.for("react.strict_mode"),i=Symbol.for("react.profiler"),a=Symbol.for("react.consumer"),o=Symbol.for("react.context"),l=Symbol.for("react.forward_ref"),c=Symbol.for("react.suspense"),u=Symbol.for("react.memo"),d=Symbol.for("react.lazy"),f=Symbol.for("react.activity"),m=Symbol.iterator;function g(U){return U===null||typeof U!="object"?null:(U=m&&U[m]||U["@@iterator"],typeof U=="function"?U:null)}var b={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},v=Object.assign,x={};function y(U,G,te){this.props=U,this.context=G,this.refs=x,this.updater=te||b}y.prototype.isReactComponent={},y.prototype.setState=function(U,G){if(typeof U!="object"&&typeof U!="function"&&U!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,U,G,"setState")},y.prototype.forceUpdate=function(U){this.updater.enqueueForceUpdate(this,U,"forceUpdate")};function M(){}M.prototype=y.prototype;function w(U,G,te){this.props=U,this.context=G,this.refs=x,this.updater=te||b}var A=w.prototype=new M;A.constructor=w,v(A,y.prototype),A.isPureReactComponent=!0;var N=Array.isArray;function k(){}var T={H:null,A:null,T:null,S:null},D=Object.prototype.hasOwnProperty;function C(U,G,te){var ne=te.ref;return{$$typeof:t,type:U,key:G,ref:ne!==void 0?ne:null,props:te}}function P(U,G){return C(U.type,G,U.props)}function F(U){return typeof U=="object"&&U!==null&&U.$$typeof===t}function L(U){var G={"=":"=0",":":"=2"};return"$"+U.replace(/[=:]/g,function(te){return G[te]})}var q=/\/+/g;function R(U,G){return typeof U=="object"&&U!==null&&U.key!=null?L(""+U.key):G.toString(36)}function K(U){switch(U.status){case"fulfilled":return U.value;case"rejected":throw U.reason;default:switch(typeof U.status=="string"?U.then(k,k):(U.status="pending",U.then(function(G){U.status==="pending"&&(U.status="fulfilled",U.value=G)},function(G){U.status==="pending"&&(U.status="rejected",U.reason=G)})),U.status){case"fulfilled":return U.value;case"rejected":throw U.reason}}throw U}function Y(U,G,te,ne,se){var ue=typeof U;(ue==="undefined"||ue==="boolean")&&(U=null);var pe=!1;if(U===null)pe=!0;else switch(ue){case"bigint":case"string":case"number":pe=!0;break;case"object":switch(U.$$typeof){case t:case e:pe=!0;break;case d:return pe=U._init,Y(pe(U._payload),G,te,ne,se)}}if(pe)return se=se(U),pe=ne===""?"."+R(U,0):ne,N(se)?(te="",pe!=null&&(te=pe.replace(q,"$&/")+"/"),Y(se,G,te,"",function(Ne){return Ne})):se!=null&&(F(se)&&(se=P(se,te+(se.key==null||U&&U.key===se.key?"":(""+se.key).replace(q,"$&/")+"/")+pe)),G.push(se)),1;pe=0;var Ce=ne===""?".":ne+":";if(N(U))for(var ge=0;ge>>1,re=Y[ie];if(0>>1;iei(te,Z))nei(se,te)?(Y[ie]=se,Y[ne]=Z,ie=ne):(Y[ie]=te,Y[G]=Z,ie=G);else if(nei(se,Z))Y[ie]=se,Y[ne]=Z,ie=ne;else break e}}return W}function i(Y,W){var Z=Y.sortIndex-W.sortIndex;return Z!==0?Z:Y.id-W.id}if(t.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var a=performance;t.unstable_now=function(){return a.now()}}else{var o=Date,l=o.now();t.unstable_now=function(){return o.now()-l}}var c=[],u=[],d=1,f=null,m=3,g=!1,b=!1,v=!1,x=!1,y=typeof setTimeout=="function"?setTimeout:null,M=typeof clearTimeout=="function"?clearTimeout:null,w=typeof setImmediate<"u"?setImmediate:null;function A(Y){for(var W=n(u);W!==null;){if(W.callback===null)r(u);else if(W.startTime<=Y)r(u),W.sortIndex=W.expirationTime,e(c,W);else break;W=n(u)}}function N(Y){if(v=!1,A(Y),!b)if(n(c)!==null)b=!0,k||(k=!0,L());else{var W=n(u);W!==null&&K(N,W.startTime-Y)}}var k=!1,T=-1,D=5,C=-1;function P(){return x?!0:!(t.unstable_now()-CY&&P());){var ie=f.callback;if(typeof ie=="function"){f.callback=null,m=f.priorityLevel;var re=ie(f.expirationTime<=Y);if(Y=t.unstable_now(),typeof re=="function"){f.callback=re,A(Y),W=!0;break t}f===n(c)&&r(c),A(Y)}else r(c);f=n(c)}if(f!==null)W=!0;else{var U=n(u);U!==null&&K(N,U.startTime-Y),W=!1}}break e}finally{f=null,m=Z,g=!1}W=void 0}}finally{W?L():k=!1}}}var L;if(typeof w=="function")L=function(){w(F)};else if(typeof MessageChannel<"u"){var q=new MessageChannel,R=q.port2;q.port1.onmessage=F,L=function(){R.postMessage(null)}}else L=function(){y(F,0)};function K(Y,W){T=y(function(){Y(t.unstable_now())},W)}t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(Y){Y.callback=null},t.unstable_forceFrameRate=function(Y){0>Y||125ie?(Y.sortIndex=Z,e(u,Y),n(c)===null&&Y===n(u)&&(v?(M(T),T=-1):v=!0,K(N,Z-ie))):(Y.sortIndex=re,e(c,Y),b||g||(b=!0,k||(k=!0,L()))),Y},t.unstable_shouldYield=P,t.unstable_wrapCallback=function(Y){var W=m;return function(){var Z=m;m=W;try{return Y.apply(this,arguments)}finally{m=Z}}}})(lA)),lA}var YF;function Xie(){return YF||(YF=1,oA.exports=Kie()),oA.exports}var cA={exports:{}},ga={};var QF;function Yie(){if(QF)return ga;QF=1;var t=yg();function e(c){var u="https://react.dev/errors/"+c;if(1"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(t)}catch(e){console.error(e)}}return t(),cA.exports=Yie(),cA.exports}var JF;function Qie(){if(JF)return Ox;JF=1;var t=Xie(),e=yg(),n=AG();function r(h){var p="https://react.dev/errors/"+h;if(1re||(h.current=ie[re],ie[re]=null,re--)}function te(h,p){re++,ie[re]=h.current,h.current=p}var ne=U(null),se=U(null),ue=U(null),pe=U(null);function Ce(h,p){switch(te(ue,p),te(se,h),te(ne,null),p.nodeType){case 9:case 11:h=(h=p.documentElement)&&(h=h.namespaceURI)?mF(h):0;break;default:if(h=p.tagName,p=p.namespaceURI)p=mF(p),h=pF(p,h);else switch(h){case"svg":h=1;break;case"math":h=2;break;default:h=0}}G(ne),te(ne,h)}function ge(){G(ne),G(se),G(ue)}function Ne(h){h.memoizedState!==null&&te(pe,h);var p=ne.current,_=pF(p,h.type);p!==_&&(te(se,h),te(ne,_))}function ve(h){se.current===h&&(G(ne),G(se)),pe.current===h&&(G(pe),kx._currentValue=Z)}var ee,$e;function V(h){if(ee===void 0)try{throw Error()}catch(_){var p=_.stack.trim().match(/\n( *(at )?)/);ee=p&&p[1]||"",$e=-1<_.stack.indexOf(` at`)?" ()":-1<_.stack.indexOf("@")?"@unknown:0:0":""}return` -`+Z+h+Be}var $=!1;function Y(h,m){if(!h||$)return"";$=!0;var _=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{var M={DetermineComponentFrameRoot:function(){try{if(m){var xt=function(){throw Error()};if(Object.defineProperty(xt.prototype,"props",{set:function(){throw Error()}}),typeof Reflect=="object"&&Reflect.construct){try{Reflect.construct(xt,[])}catch(ot){var it=ot}Reflect.construct(h,[],xt)}else{try{xt.call()}catch(ot){it=ot}h.call(xt.prototype)}}else{try{throw Error()}catch(ot){it=ot}(xt=h())&&typeof xt.catch=="function"&&xt.catch(function(){})}}catch(ot){if(ot&&it&&typeof ot.stack=="string")return[ot.stack,it.stack]}return[null,null]}};M.DetermineComponentFrameRoot.displayName="DetermineComponentFrameRoot";var j=Object.getOwnPropertyDescriptor(M.DetermineComponentFrameRoot,"name");j&&j.configurable&&Object.defineProperty(M.DetermineComponentFrameRoot,"name",{value:"DetermineComponentFrameRoot"});var O=M.DetermineComponentFrameRoot(),ee=O[0],de=O[1];if(ee&&de){var ke=ee.split(` -`),nt=de.split(` -`);for(j=M=0;Mj||ke[M]!==nt[j]){var dt=` -`+ke[M].replace(" at new "," at ");return h.displayName&&dt.includes("")&&(dt=dt.replace("",h.displayName)),dt}while(1<=M&&0<=j);break}}}finally{$=!1,Error.prepareStackTrace=_}return(_=h?h.displayName||h.name:"")?V(_):""}function B(h,m){switch(h.tag){case 26:case 27:case 5:return V(h.type);case 16:return V("Lazy");case 13:return h.child!==m&&m!==null?V("Suspense Fallback"):V("Suspense");case 19:return V("SuspenseList");case 0:case 15:return Y(h.type,!1);case 11:return Y(h.type.render,!1);case 1:return Y(h.type,!0);case 31:return V("Activity");default:return""}}function F(h){try{var m="",_=null;do m+=B(h,_),_=h,h=h.return;while(h);return m}catch(M){return` -Error generating stack: `+M.message+` -`+M.stack}}var X=Object.prototype.hasOwnProperty,Me=t.unstable_scheduleCallback,Ce=t.unstable_cancelCallback,pe=t.unstable_shouldYield,H=t.unstable_requestPaint,I=t.unstable_now,le=t.unstable_getCurrentPriorityLevel,_e=t.unstable_ImmediatePriority,Se=t.unstable_UserBlockingPriority,ve=t.unstable_NormalPriority,Ye=t.unstable_LowPriority,He=t.unstable_IdlePriority,at=t.log,ut=t.unstable_setDisableYieldValue,Le=null,he=null;function Ke(h){if(typeof at=="function"&&ut(h),he&&typeof he.setStrictMode=="function")try{he.setStrictMode(Le,h)}catch{}}var Xe=Math.clz32?Math.clz32:se,Je=Math.log,ct=Math.LN2;function se(h){return h>>>=0,h===0?32:31-(Je(h)/ct|0)|0}var Ve=256,xe=262144,$e=4194304;function De(h){var m=h&42;if(m!==0)return m;switch(h&-h){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:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return h&261888;case 262144:case 524288:case 1048576:case 2097152:return h&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return h&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return h}}function Ne(h,m,_){var M=h.pendingLanes;if(M===0)return 0;var j=0,O=h.suspendedLanes,ee=h.pingedLanes;h=h.warmLanes;var de=M&134217727;return de!==0?(M=de&~O,M!==0?j=De(M):(ee&=de,ee!==0?j=De(ee):_||(_=de&~h,_!==0&&(j=De(_))))):(de=M&~O,de!==0?j=De(de):ee!==0?j=De(ee):_||(_=M&~h,_!==0&&(j=De(_)))),j===0?0:m!==0&&m!==j&&(m&O)===0&&(O=j&-j,_=m&-m,O>=_||O===32&&(_&4194048)!==0)?m:j}function Ge(h,m){return(h.pendingLanes&~(h.suspendedLanes&~h.pingedLanes)&m)===0}function pt(h,m){switch(h){case 1:case 2:case 4:case 8:case 64:return m+250;case 16:case 32: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 m+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function Nt(){var h=$e;return $e<<=1,($e&62914560)===0&&($e=4194304),h}function kt(h){for(var m=[],_=0;31>_;_++)m.push(h);return m}function Xt(h,m){h.pendingLanes|=m,m!==268435456&&(h.suspendedLanes=0,h.pingedLanes=0,h.warmLanes=0)}function Ot(h,m,_,M,j,O){var ee=h.pendingLanes;h.pendingLanes=_,h.suspendedLanes=0,h.pingedLanes=0,h.warmLanes=0,h.expiredLanes&=_,h.entangledLanes&=_,h.errorRecoveryDisabledLanes&=_,h.shellSuspendCounter=0;var de=h.entanglements,ke=h.expirationTimes,nt=h.hiddenUpdates;for(_=ee&~_;0<_;){var dt=31-Xe(_),xt=1<"u")return null;try{return h.activeElement||h.body}catch{return h.body}}var ei=/[\n"\\]/g;function Hn(h){return h.replace(ei,function(m){return"\\"+m.charCodeAt(0).toString(16)+" "})}function jo(h,m,_,M,j,O,ee,de){h.name="",ee!=null&&typeof ee!="function"&&typeof ee!="symbol"&&typeof ee!="boolean"?h.type=ee:h.removeAttribute("type"),m!=null?ee==="number"?(m===0&&h.value===""||h.value!=m)&&(h.value=""+vn(m)):h.value!==""+vn(m)&&(h.value=""+vn(m)):ee!=="submit"&&ee!=="reset"||h.removeAttribute("value"),m!=null?Ii(h,ee,vn(m)):_!=null?Ii(h,ee,vn(_)):M!=null&&h.removeAttribute("value"),j==null&&O!=null&&(h.defaultChecked=!!O),j!=null&&(h.checked=j&&typeof j!="function"&&typeof j!="symbol"),de!=null&&typeof de!="function"&&typeof de!="symbol"&&typeof de!="boolean"?h.name=""+vn(de):h.removeAttribute("name")}function qn(h,m,_,M,j,O,ee,de){if(O!=null&&typeof O!="function"&&typeof O!="symbol"&&typeof O!="boolean"&&(h.type=O),m!=null||_!=null){if(!(O!=="submit"&&O!=="reset"||m!=null)){nn(h);return}_=_!=null?""+vn(_):"",m=m!=null?""+vn(m):_,de||m===h.value||(h.value=m),h.defaultValue=m}M=M??j,M=typeof M!="function"&&typeof M!="symbol"&&!!M,h.checked=de?h.checked:!!M,h.defaultChecked=!!M,ee!=null&&typeof ee!="function"&&typeof ee!="symbol"&&typeof ee!="boolean"&&(h.name=ee),nn(h)}function Ii(h,m,_){m==="number"&&$r(h.ownerDocument)===h||h.defaultValue===""+_||(h.defaultValue=""+_)}function _i(h,m,_,M){if(h=h.options,m){m={};for(var j=0;j<_.length;j++)m["$"+_[j]]=!0;for(_=0;_"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),iE=!1;if(Wl)try{var Kg={};Object.defineProperty(Kg,"passive",{get:function(){iE=!0}}),window.addEventListener("test",Kg,Kg),window.removeEventListener("test",Kg,Kg)}catch{iE=!1}var hu=null,aE=null,ky=null;function mL(){if(ky)return ky;var h,m=aE,_=m.length,M,j="value"in hu?hu.value:hu.textContent,O=j.length;for(h=0;h<_&&m[h]===j[h];h++);var ee=_-h;for(M=1;M<=ee&&m[_-M]===j[O-M];M++);return ky=j.slice(h,1=Qg),vL=" ",_L=!1;function wL(h,m){switch(h){case"keyup":return dre.indexOf(m.keyCode)!==-1;case"keydown":return m.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function SL(h){return h=h.detail,typeof h=="object"&&"data"in h?h.data:null}var Gf=!1;function fre(h,m){switch(h){case"compositionend":return SL(m);case"keypress":return m.which!==32?null:(_L=!0,vL);case"textInput":return h=m.data,h===vL&&_L?null:h;default:return null}}function mre(h,m){if(Gf)return h==="compositionend"||!uE&&wL(h,m)?(h=mL(),ky=aE=hu=null,Gf=!1,h):null;switch(h){case"paste":return null;case"keypress":if(!(m.ctrlKey||m.altKey||m.metaKey)||m.ctrlKey&&m.altKey){if(m.char&&1=m)return{node:_,offset:m-h};h=M}e:{for(;_;){if(_.nextSibling){_=_.nextSibling;break e}_=_.parentNode}_=void 0}_=jL(_)}}function RL(h,m){return h&&m?h===m?!0:h&&h.nodeType===3?!1:m&&m.nodeType===3?RL(h,m.parentNode):"contains"in h?h.contains(m):h.compareDocumentPosition?!!(h.compareDocumentPosition(m)&16):!1:!1}function DL(h){h=h!=null&&h.ownerDocument!=null&&h.ownerDocument.defaultView!=null?h.ownerDocument.defaultView:window;for(var m=$r(h.document);m instanceof h.HTMLIFrameElement;){try{var _=typeof m.contentWindow.location.href=="string"}catch{_=!1}if(_)h=m.contentWindow;else break;m=$r(h.document)}return m}function fE(h){var m=h&&h.nodeName&&h.nodeName.toLowerCase();return m&&(m==="input"&&(h.type==="text"||h.type==="search"||h.type==="tel"||h.type==="url"||h.type==="password")||m==="textarea"||h.contentEditable==="true")}var wre=Wl&&"documentMode"in document&&11>=document.documentMode,Wf=null,mE=null,tx=null,pE=!1;function OL(h,m,_){var M=_.window===_?_.document:_.nodeType===9?_:_.ownerDocument;pE||Wf==null||Wf!==$r(M)||(M=Wf,"selectionStart"in M&&fE(M)?M={start:M.selectionStart,end:M.selectionEnd}:(M=(M.ownerDocument&&M.ownerDocument.defaultView||window).getSelection(),M={anchorNode:M.anchorNode,anchorOffset:M.anchorOffset,focusNode:M.focusNode,focusOffset:M.focusOffset}),tx&&ex(tx,M)||(tx=M,M=Sv(mE,"onSelect"),0>=ee,j-=ee,sl=1<<32-Xe(m)+j|_<un?(Cn=Ft,Ft=null):Cn=Ft.sibling;var Ln=it(We,Ft,tt[un],mt);if(Ln===null){Ft===null&&(Ft=Cn);break}h&&Ft&&Ln.alternate===null&&m(We,Ft),Ie=O(Ln,Ie,un),On===null?Ht=Ln:On.sibling=Ln,On=Ln,Ft=Cn}if(un===tt.length)return _(We,Ft),kn&&Kl(We,un),Ht;if(Ft===null){for(;unun?(Cn=Ft,Ft=null):Cn=Ft.sibling;var Du=it(We,Ft,Ln.value,mt);if(Du===null){Ft===null&&(Ft=Cn);break}h&&Ft&&Du.alternate===null&&m(We,Ft),Ie=O(Du,Ie,un),On===null?Ht=Du:On.sibling=Du,On=Du,Ft=Cn}if(Ln.done)return _(We,Ft),kn&&Kl(We,un),Ht;if(Ft===null){for(;!Ln.done;un++,Ln=tt.next())Ln=xt(We,Ln.value,mt),Ln!==null&&(Ie=O(Ln,Ie,un),On===null?Ht=Ln:On.sibling=Ln,On=Ln);return kn&&Kl(We,un),Ht}for(Ft=M(Ft);!Ln.done;un++,Ln=tt.next())Ln=ot(Ft,We,un,Ln.value,mt),Ln!==null&&(h&&Ln.alternate!==null&&Ft.delete(Ln.key===null?un:Ln.key),Ie=O(Ln,Ie,un),On===null?Ht=Ln:On.sibling=Ln,On=Ln);return h&&Ft.forEach(function($ie){return m(We,$ie)}),kn&&Kl(We,un),Ht}function rr(We,Ie,tt,mt){if(typeof tt=="object"&&tt!==null&&tt.type===v&&tt.key===null&&(tt=tt.props.children),typeof tt=="object"&&tt!==null){switch(tt.$$typeof){case g:e:{for(var Ht=tt.key;Ie!==null;){if(Ie.key===Ht){if(Ht=tt.type,Ht===v){if(Ie.tag===7){_(We,Ie.sibling),mt=j(Ie,tt.props.children),mt.return=We,We=mt;break e}}else if(Ie.elementType===Ht||typeof Ht=="object"&&Ht!==null&&Ht.$$typeof===D&&ah(Ht)===Ie.type){_(We,Ie.sibling),mt=j(Ie,tt.props),ox(mt,tt),mt.return=We,We=mt;break e}_(We,Ie);break}else m(We,Ie);Ie=Ie.sibling}tt.type===v?(mt=eh(tt.props.children,We.mode,mt,tt.key),mt.return=We,We=mt):(mt=zy(tt.type,tt.key,tt.props,null,We.mode,mt),ox(mt,tt),mt.return=We,We=mt)}return ee(We);case b:e:{for(Ht=tt.key;Ie!==null;){if(Ie.key===Ht)if(Ie.tag===4&&Ie.stateNode.containerInfo===tt.containerInfo&&Ie.stateNode.implementation===tt.implementation){_(We,Ie.sibling),mt=j(Ie,tt.children||[]),mt.return=We,We=mt;break e}else{_(We,Ie);break}else m(We,Ie);Ie=Ie.sibling}mt=wE(tt,We.mode,mt),mt.return=We,We=mt}return ee(We);case D:return tt=ah(tt),rr(We,Ie,tt,mt)}if(K(tt))return It(We,Ie,tt,mt);if(L(tt)){if(Ht=L(tt),typeof Ht!="function")throw Error(r(150));return tt=Ht.call(tt),qt(We,Ie,tt,mt)}if(typeof tt.then=="function")return rr(We,Ie,qy(tt),mt);if(tt.$$typeof===w)return rr(We,Ie,Hy(We,tt),mt);Ky(We,tt)}return typeof tt=="string"&&tt!==""||typeof tt=="number"||typeof tt=="bigint"?(tt=""+tt,Ie!==null&&Ie.tag===6?(_(We,Ie.sibling),mt=j(Ie,tt),mt.return=We,We=mt):(_(We,Ie),mt=_E(tt,We.mode,mt),mt.return=We,We=mt),ee(We)):_(We,Ie)}return function(We,Ie,tt,mt){try{sx=0;var Ht=rr(We,Ie,tt,mt);return rm=null,Ht}catch(Ft){if(Ft===nm||Ft===Gy)throw Ft;var On=gs(29,Ft,null,We.mode);return On.lanes=mt,On.return=We,On}finally{}}}var oh=iI(!0),aI=iI(!1),xu=!1;function DE(h){h.updateQueue={baseState:h.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function OE(h,m){h=h.updateQueue,m.updateQueue===h&&(m.updateQueue={baseState:h.baseState,firstBaseUpdate:h.firstBaseUpdate,lastBaseUpdate:h.lastBaseUpdate,shared:h.shared,callbacks:null})}function bu(h){return{lane:h,tag:0,payload:null,callback:null,next:null}}function yu(h,m,_){var M=h.updateQueue;if(M===null)return null;if(M=M.shared,(zn&2)!==0){var j=M.pending;return j===null?m.next=m:(m.next=j.next,j.next=m),M.pending=m,m=Uy(h),$L(h,null,_),m}return Fy(h,M,m,_),Uy(h)}function lx(h,m,_){if(m=m.updateQueue,m!==null&&(m=m.shared,(_&4194048)!==0)){var M=m.lanes;M&=h.pendingLanes,_|=M,m.lanes=_,Bt(h,_)}}function LE(h,m){var _=h.updateQueue,M=h.alternate;if(M!==null&&(M=M.updateQueue,_===M)){var j=null,O=null;if(_=_.firstBaseUpdate,_!==null){do{var ee={lane:_.lane,tag:_.tag,payload:_.payload,callback:null,next:null};O===null?j=O=ee:O=O.next=ee,_=_.next}while(_!==null);O===null?j=O=m:O=O.next=m}else j=O=m;_={baseState:M.baseState,firstBaseUpdate:j,lastBaseUpdate:O,shared:M.shared,callbacks:M.callbacks},h.updateQueue=_;return}h=_.lastBaseUpdate,h===null?_.firstBaseUpdate=m:h.next=m,_.lastBaseUpdate=m}var IE=!1;function cx(){if(IE){var h=tm;if(h!==null)throw h}}function ux(h,m,_,M){IE=!1;var j=h.updateQueue;xu=!1;var O=j.firstBaseUpdate,ee=j.lastBaseUpdate,de=j.shared.pending;if(de!==null){j.shared.pending=null;var ke=de,nt=ke.next;ke.next=null,ee===null?O=nt:ee.next=nt,ee=ke;var dt=h.alternate;dt!==null&&(dt=dt.updateQueue,de=dt.lastBaseUpdate,de!==ee&&(de===null?dt.firstBaseUpdate=nt:de.next=nt,dt.lastBaseUpdate=ke))}if(O!==null){var xt=j.baseState;ee=0,dt=nt=ke=null,de=O;do{var it=de.lane&-536870913,ot=it!==de.lane;if(ot?(Tn&it)===it:(M&it)===it){it!==0&&it===em&&(IE=!0),dt!==null&&(dt=dt.next={lane:0,tag:de.tag,payload:de.payload,callback:null,next:null});e:{var It=h,qt=de;it=m;var rr=_;switch(qt.tag){case 1:if(It=qt.payload,typeof It=="function"){xt=It.call(rr,xt,it);break e}xt=It;break e;case 3:It.flags=It.flags&-65537|128;case 0:if(It=qt.payload,it=typeof It=="function"?It.call(rr,xt,it):It,it==null)break e;xt=f({},xt,it);break e;case 2:xu=!0}}it=de.callback,it!==null&&(h.flags|=64,ot&&(h.flags|=8192),ot=j.callbacks,ot===null?j.callbacks=[it]:ot.push(it))}else ot={lane:it,tag:de.tag,payload:de.payload,callback:de.callback,next:null},dt===null?(nt=dt=ot,ke=xt):dt=dt.next=ot,ee|=it;if(de=de.next,de===null){if(de=j.shared.pending,de===null)break;ot=de,de=ot.next,ot.next=null,j.lastBaseUpdate=ot,j.shared.pending=null}}while(!0);dt===null&&(ke=xt),j.baseState=ke,j.firstBaseUpdate=nt,j.lastBaseUpdate=dt,O===null&&(j.shared.lanes=0),Mu|=ee,h.lanes=ee,h.memoizedState=xt}}function sI(h,m){if(typeof h!="function")throw Error(r(191,h));h.call(m)}function oI(h,m){var _=h.callbacks;if(_!==null)for(h.callbacks=null,h=0;h<_.length;h++)sI(_[h],m)}var im=z(null),Xy=z(0);function lI(h,m){h=ac,te(Xy,h),te(im,m),ac=h|m.baseLanes}function FE(){te(Xy,ac),te(im,im.current)}function UE(){ac=Xy.current,G(im),G(Xy)}var xs=z(null),Ys=null;function vu(h){var m=h.alternate;te(ti,ti.current&1),te(xs,h),Ys===null&&(m===null||im.current!==null||m.memoizedState!==null)&&(Ys=h)}function zE(h){te(ti,ti.current),te(xs,h),Ys===null&&(Ys=h)}function cI(h){h.tag===22?(te(ti,ti.current),te(xs,h),Ys===null&&(Ys=h)):_u()}function _u(){te(ti,ti.current),te(xs,xs.current)}function bs(h){G(xs),Ys===h&&(Ys=null),G(ti)}var ti=z(0);function Yy(h){for(var m=h;m!==null;){if(m.tag===13){var _=m.memoizedState;if(_!==null&&(_=_.dehydrated,_===null||WN(_)||qN(_)))return m}else if(m.tag===19&&(m.memoizedProps.revealOrder==="forwards"||m.memoizedProps.revealOrder==="backwards"||m.memoizedProps.revealOrder==="unstable_legacy-backwards"||m.memoizedProps.revealOrder==="together")){if((m.flags&128)!==0)return m}else if(m.child!==null){m.child.return=m,m=m.child;continue}if(m===h)break;for(;m.sibling===null;){if(m.return===null||m.return===h)return null;m=m.return}m.sibling.return=m.return,m=m.sibling}return null}var Ql=0,cn=null,tr=null,oi=null,Qy=!1,am=!1,lh=!1,Zy=0,dx=0,sm=null,Pre=0;function Hr(){throw Error(r(321))}function BE(h,m){if(m===null)return!1;for(var _=0;_O?O:8;var ee=Q.T,de={};Q.T=de,nN(h,!1,m,_);try{var ke=j(),nt=Q.S;if(nt!==null&&nt(de,ke),ke!==null&&typeof ke=="object"&&typeof ke.then=="function"){var dt=jre(ke,M);fx(h,m,dt,_s(h))}else fx(h,m,M,_s(h))}catch(xt){fx(h,m,{then:function(){},status:"rejected",reason:xt},_s())}finally{q.p=O,ee!==null&&de.types!==null&&(ee.types=de.types),Q.T=ee}}function Ire(){}function eN(h,m,_,M){if(h.tag!==5)throw Error(r(476));var j=UI(h).queue;FI(h,j,m,J,_===null?Ire:function(){return zI(h),_(M)})}function UI(h){var m=h.memoizedState;if(m!==null)return m;m={memoizedState:J,baseState:J,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Zl,lastRenderedState:J},next:null};var _={};return m.next={memoizedState:_,baseState:_,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Zl,lastRenderedState:_},next:null},h.memoizedState=m,h=h.alternate,h!==null&&(h.memoizedState=m),m}function zI(h){var m=UI(h);m.next===null&&(m=h.alternate.memoizedState),fx(h,m.next.queue,{},_s())}function tN(){return ea(kx)}function BI(){return ni().memoizedState}function $I(){return ni().memoizedState}function Fre(h){for(var m=h.return;m!==null;){switch(m.tag){case 24:case 3:var _=_s();h=bu(_);var M=yu(m,h,_);M!==null&&(Ja(M,m,_),lx(M,m,_)),m={cache:kE()},h.payload=m;return}m=m.return}}function Ure(h,m,_){var M=_s();_={lane:M,revertLane:0,gesture:null,action:_,hasEagerState:!1,eagerState:null,next:null},iv(h)?VI(m,_):(_=yE(h,m,_,M),_!==null&&(Ja(_,h,M),GI(_,m,M)))}function HI(h,m,_){var M=_s();fx(h,m,_,M)}function fx(h,m,_,M){var j={lane:M,revertLane:0,gesture:null,action:_,hasEagerState:!1,eagerState:null,next:null};if(iv(h))VI(m,j);else{var O=h.alternate;if(h.lanes===0&&(O===null||O.lanes===0)&&(O=m.lastRenderedReducer,O!==null))try{var ee=m.lastRenderedState,de=O(ee,_);if(j.hasEagerState=!0,j.eagerState=de,ps(de,ee))return Fy(h,m,j,0),fr===null&&Iy(),!1}catch{}finally{}if(_=yE(h,m,j,M),_!==null)return Ja(_,h,M),GI(_,m,M),!0}return!1}function nN(h,m,_,M){if(M={lane:2,revertLane:DN(),gesture:null,action:M,hasEagerState:!1,eagerState:null,next:null},iv(h)){if(m)throw Error(r(479))}else m=yE(h,_,M,2),m!==null&&Ja(m,h,2)}function iv(h){var m=h.alternate;return h===cn||m!==null&&m===cn}function VI(h,m){am=Qy=!0;var _=h.pending;_===null?m.next=m:(m.next=_.next,_.next=m),h.pending=m}function GI(h,m,_){if((_&4194048)!==0){var M=m.lanes;M&=h.pendingLanes,_|=M,m.lanes=_,Bt(h,_)}}var mx={readContext:ea,use:ev,useCallback:Hr,useContext:Hr,useEffect:Hr,useImperativeHandle:Hr,useLayoutEffect:Hr,useInsertionEffect:Hr,useMemo:Hr,useReducer:Hr,useRef:Hr,useState:Hr,useDebugValue:Hr,useDeferredValue:Hr,useTransition:Hr,useSyncExternalStore:Hr,useId:Hr,useHostTransitionStatus:Hr,useFormState:Hr,useActionState:Hr,useOptimistic:Hr,useMemoCache:Hr,useCacheRefresh:Hr};mx.useEffectEvent=Hr;var WI={readContext:ea,use:ev,useCallback:function(h,m){return ja().memoizedState=[h,m===void 0?null:m],h},useContext:ea,useEffect:CI,useImperativeHandle:function(h,m,_){_=_!=null?_.concat([h]):null,nv(4194308,4,RI.bind(null,m,h),_)},useLayoutEffect:function(h,m){return nv(4194308,4,h,m)},useInsertionEffect:function(h,m){nv(4,2,h,m)},useMemo:function(h,m){var _=ja();m=m===void 0?null:m;var M=h();if(lh){Ke(!0);try{h()}finally{Ke(!1)}}return _.memoizedState=[M,m],M},useReducer:function(h,m,_){var M=ja();if(_!==void 0){var j=_(m);if(lh){Ke(!0);try{_(m)}finally{Ke(!1)}}}else j=m;return M.memoizedState=M.baseState=j,h={pending:null,lanes:0,dispatch:null,lastRenderedReducer:h,lastRenderedState:j},M.queue=h,h=h.dispatch=Ure.bind(null,cn,h),[M.memoizedState,h]},useRef:function(h){var m=ja();return h={current:h},m.memoizedState=h},useState:function(h){h=XE(h);var m=h.queue,_=HI.bind(null,cn,m);return m.dispatch=_,[h.memoizedState,_]},useDebugValue:ZE,useDeferredValue:function(h,m){var _=ja();return JE(_,h,m)},useTransition:function(){var h=XE(!1);return h=FI.bind(null,cn,h.queue,!0,!1),ja().memoizedState=h,[!1,h]},useSyncExternalStore:function(h,m,_){var M=cn,j=ja();if(kn){if(_===void 0)throw Error(r(407));_=_()}else{if(_=m(),fr===null)throw Error(r(349));(Tn&127)!==0||fI(M,m,_)}j.memoizedState=_;var O={value:_,getSnapshot:m};return j.queue=O,CI(pI.bind(null,M,O,h),[h]),M.flags|=2048,om(9,{destroy:void 0},mI.bind(null,M,O,_,m),null),_},useId:function(){var h=ja(),m=fr.identifierPrefix;if(kn){var _=ol,M=sl;_=(M&~(1<<32-Xe(M)-1)).toString(32)+_,m="_"+m+"R_"+_,_=Zy++,0<_&&(m+="H"+_.toString(32)),m+="_"}else _=Pre++,m="_"+m+"r_"+_.toString(32)+"_";return h.memoizedState=m},useHostTransitionStatus:tN,useFormState:MI,useActionState:MI,useOptimistic:function(h){var m=ja();m.memoizedState=m.baseState=h;var _={pending:null,lanes:0,dispatch:null,lastRenderedReducer:null,lastRenderedState:null};return m.queue=_,m=nN.bind(null,cn,!0,_),_.dispatch=m,[h,m]},useMemoCache:WE,useCacheRefresh:function(){return ja().memoizedState=Fre.bind(null,cn)},useEffectEvent:function(h){var m=ja(),_={impl:h};return m.memoizedState=_,function(){if((zn&2)!==0)throw Error(r(440));return _.impl.apply(void 0,arguments)}}},rN={readContext:ea,use:ev,useCallback:OI,useContext:ea,useEffect:QE,useImperativeHandle:DI,useInsertionEffect:jI,useLayoutEffect:PI,useMemo:LI,useReducer:tv,useRef:TI,useState:function(){return tv(Zl)},useDebugValue:ZE,useDeferredValue:function(h,m){var _=ni();return II(_,tr.memoizedState,h,m)},useTransition:function(){var h=tv(Zl)[0],m=ni().memoizedState;return[typeof h=="boolean"?h:hx(h),m]},useSyncExternalStore:hI,useId:BI,useHostTransitionStatus:tN,useFormState:EI,useActionState:EI,useOptimistic:function(h,m){var _=ni();return bI(_,tr,h,m)},useMemoCache:WE,useCacheRefresh:$I};rN.useEffectEvent=kI;var qI={readContext:ea,use:ev,useCallback:OI,useContext:ea,useEffect:QE,useImperativeHandle:DI,useInsertionEffect:jI,useLayoutEffect:PI,useMemo:LI,useReducer:KE,useRef:TI,useState:function(){return KE(Zl)},useDebugValue:ZE,useDeferredValue:function(h,m){var _=ni();return tr===null?JE(_,h,m):II(_,tr.memoizedState,h,m)},useTransition:function(){var h=KE(Zl)[0],m=ni().memoizedState;return[typeof h=="boolean"?h:hx(h),m]},useSyncExternalStore:hI,useId:BI,useHostTransitionStatus:tN,useFormState:AI,useActionState:AI,useOptimistic:function(h,m){var _=ni();return tr!==null?bI(_,tr,h,m):(_.baseState=h,[h,_.queue.dispatch])},useMemoCache:WE,useCacheRefresh:$I};qI.useEffectEvent=kI;function iN(h,m,_,M){m=h.memoizedState,_=_(M,m),_=_==null?m:f({},m,_),h.memoizedState=_,h.lanes===0&&(h.updateQueue.baseState=_)}var aN={enqueueSetState:function(h,m,_){h=h._reactInternals;var M=_s(),j=bu(M);j.payload=m,_!=null&&(j.callback=_),m=yu(h,j,M),m!==null&&(Ja(m,h,M),lx(m,h,M))},enqueueReplaceState:function(h,m,_){h=h._reactInternals;var M=_s(),j=bu(M);j.tag=1,j.payload=m,_!=null&&(j.callback=_),m=yu(h,j,M),m!==null&&(Ja(m,h,M),lx(m,h,M))},enqueueForceUpdate:function(h,m){h=h._reactInternals;var _=_s(),M=bu(_);M.tag=2,m!=null&&(M.callback=m),m=yu(h,M,_),m!==null&&(Ja(m,h,_),lx(m,h,_))}};function KI(h,m,_,M,j,O,ee){return h=h.stateNode,typeof h.shouldComponentUpdate=="function"?h.shouldComponentUpdate(M,O,ee):m.prototype&&m.prototype.isPureReactComponent?!ex(_,M)||!ex(j,O):!0}function XI(h,m,_,M){h=m.state,typeof m.componentWillReceiveProps=="function"&&m.componentWillReceiveProps(_,M),typeof m.UNSAFE_componentWillReceiveProps=="function"&&m.UNSAFE_componentWillReceiveProps(_,M),m.state!==h&&aN.enqueueReplaceState(m,m.state,null)}function ch(h,m){var _=m;if("ref"in m){_={};for(var M in m)M!=="ref"&&(_[M]=m[M])}if(h=h.defaultProps){_===m&&(_=f({},_));for(var j in h)_[j]===void 0&&(_[j]=h[j])}return _}function YI(h){Ly(h)}function QI(h){console.error(h)}function ZI(h){Ly(h)}function av(h,m){try{var _=h.onUncaughtError;_(m.value,{componentStack:m.stack})}catch(M){setTimeout(function(){throw M})}}function JI(h,m,_){try{var M=h.onCaughtError;M(_.value,{componentStack:_.stack,errorBoundary:m.tag===1?m.stateNode:null})}catch(j){setTimeout(function(){throw j})}}function sN(h,m,_){return _=bu(_),_.tag=3,_.payload={element:null},_.callback=function(){av(h,m)},_}function e5(h){return h=bu(h),h.tag=3,h}function t5(h,m,_,M){var j=_.type.getDerivedStateFromError;if(typeof j=="function"){var O=M.value;h.payload=function(){return j(O)},h.callback=function(){JI(m,_,M)}}var ee=_.stateNode;ee!==null&&typeof ee.componentDidCatch=="function"&&(h.callback=function(){JI(m,_,M),typeof j!="function"&&(Eu===null?Eu=new Set([this]):Eu.add(this));var de=M.stack;this.componentDidCatch(M.value,{componentStack:de!==null?de:""})})}function zre(h,m,_,M,j){if(_.flags|=32768,M!==null&&typeof M=="object"&&typeof M.then=="function"){if(m=_.alternate,m!==null&&Jf(m,_,j,!0),_=xs.current,_!==null){switch(_.tag){case 31:case 13:return Ys===null?xv():_.alternate===null&&Vr===0&&(Vr=3),_.flags&=-257,_.flags|=65536,_.lanes=j,M===Wy?_.flags|=16384:(m=_.updateQueue,m===null?_.updateQueue=new Set([M]):m.add(M),jN(h,M,j)),!1;case 22:return _.flags|=65536,M===Wy?_.flags|=16384:(m=_.updateQueue,m===null?(m={transitions:null,markerInstances:null,retryQueue:new Set([M])},_.updateQueue=m):(_=m.retryQueue,_===null?m.retryQueue=new Set([M]):_.add(M)),jN(h,M,j)),!1}throw Error(r(435,_.tag))}return jN(h,M,j),xv(),!1}if(kn)return m=xs.current,m!==null?((m.flags&65536)===0&&(m.flags|=256),m.flags|=65536,m.lanes=j,M!==EE&&(h=Error(r(422),{cause:M}),rx(Ws(h,_)))):(M!==EE&&(m=Error(r(423),{cause:M}),rx(Ws(m,_))),h=h.current.alternate,h.flags|=65536,j&=-j,h.lanes|=j,M=Ws(M,_),j=sN(h.stateNode,M,j),LE(h,j),Vr!==4&&(Vr=2)),!1;var O=Error(r(520),{cause:M});if(O=Ws(O,_),wx===null?wx=[O]:wx.push(O),Vr!==4&&(Vr=2),m===null)return!0;M=Ws(M,_),_=m;do{switch(_.tag){case 3:return _.flags|=65536,h=j&-j,_.lanes|=h,h=sN(_.stateNode,M,h),LE(_,h),!1;case 1:if(m=_.type,O=_.stateNode,(_.flags&128)===0&&(typeof m.getDerivedStateFromError=="function"||O!==null&&typeof O.componentDidCatch=="function"&&(Eu===null||!Eu.has(O))))return _.flags|=65536,j&=-j,_.lanes|=j,j=e5(j),t5(j,h,_,M),LE(_,j),!1}_=_.return}while(_!==null);return!1}var oN=Error(r(461)),li=!1;function ta(h,m,_,M){m.child=h===null?aI(m,null,_,M):oh(m,h.child,_,M)}function n5(h,m,_,M,j){_=_.render;var O=m.ref;if("ref"in M){var ee={};for(var de in M)de!=="ref"&&(ee[de]=M[de])}else ee=M;return rh(m),M=$E(h,m,_,ee,O,j),de=HE(),h!==null&&!li?(VE(h,m,j),Jl(h,m,j)):(kn&&de&&SE(m),m.flags|=1,ta(h,m,M,j),m.child)}function r5(h,m,_,M,j){if(h===null){var O=_.type;return typeof O=="function"&&!vE(O)&&O.defaultProps===void 0&&_.compare===null?(m.tag=15,m.type=O,i5(h,m,O,M,j)):(h=zy(_.type,null,M,m,m.mode,j),h.ref=m.ref,h.return=m,m.child=h)}if(O=h.child,!pN(h,j)){var ee=O.memoizedProps;if(_=_.compare,_=_!==null?_:ex,_(ee,M)&&h.ref===m.ref)return Jl(h,m,j)}return m.flags|=1,h=ql(O,M),h.ref=m.ref,h.return=m,m.child=h}function i5(h,m,_,M,j){if(h!==null){var O=h.memoizedProps;if(ex(O,M)&&h.ref===m.ref)if(li=!1,m.pendingProps=M=O,pN(h,j))(h.flags&131072)!==0&&(li=!0);else return m.lanes=h.lanes,Jl(h,m,j)}return lN(h,m,_,M,j)}function a5(h,m,_,M){var j=M.children,O=h!==null?h.memoizedState:null;if(h===null&&m.stateNode===null&&(m.stateNode={_visibility:1,_pendingMarkers:null,_retryCache:null,_transitions:null}),M.mode==="hidden"){if((m.flags&128)!==0){if(O=O!==null?O.baseLanes|_:_,h!==null){for(M=m.child=h.child,j=0;M!==null;)j=j|M.lanes|M.childLanes,M=M.sibling;M=j&~O}else M=0,m.child=null;return s5(h,m,O,_,M)}if((_&536870912)!==0)m.memoizedState={baseLanes:0,cachePool:null},h!==null&&Vy(m,O!==null?O.cachePool:null),O!==null?lI(m,O):FE(),cI(m);else return M=m.lanes=536870912,s5(h,m,O!==null?O.baseLanes|_:_,_,M)}else O!==null?(Vy(m,O.cachePool),lI(m,O),_u(),m.memoizedState=null):(h!==null&&Vy(m,null),FE(),_u());return ta(h,m,j,_),m.child}function px(h,m){return h!==null&&h.tag===22||m.stateNode!==null||(m.stateNode={_visibility:1,_pendingMarkers:null,_retryCache:null,_transitions:null}),m.sibling}function s5(h,m,_,M,j){var O=PE();return O=O===null?null:{parent:si._currentValue,pool:O},m.memoizedState={baseLanes:_,cachePool:O},h!==null&&Vy(m,null),FE(),cI(m),h!==null&&Jf(h,m,M,!0),m.childLanes=j,null}function sv(h,m){return m=lv({mode:m.mode,children:m.children},h.mode),m.ref=h.ref,h.child=m,m.return=h,m}function o5(h,m,_){return oh(m,h.child,null,_),h=sv(m,m.pendingProps),h.flags|=2,bs(m),m.memoizedState=null,h}function Bre(h,m,_){var M=m.pendingProps,j=(m.flags&128)!==0;if(m.flags&=-129,h===null){if(kn){if(M.mode==="hidden")return h=sv(m,M),m.lanes=536870912,px(null,h);if(zE(m),(h=wr)?(h=yF(h,Xs),h=h!==null&&h.data==="&"?h:null,h!==null&&(m.memoizedState={dehydrated:h,treeContext:fu!==null?{id:sl,overflow:ol}:null,retryLane:536870912,hydrationErrors:null},_=VL(h),_.return=m,m.child=_,Ji=m,wr=null)):h=null,h===null)throw pu(m);return m.lanes=536870912,null}return sv(m,M)}var O=h.memoizedState;if(O!==null){var ee=O.dehydrated;if(zE(m),j)if(m.flags&256)m.flags&=-257,m=o5(h,m,_);else if(m.memoizedState!==null)m.child=h.child,m.flags|=128,m=null;else throw Error(r(558));else if(li||Jf(h,m,_,!1),j=(_&h.childLanes)!==0,li||j){if(M=fr,M!==null&&(ee=Gn(M,_),ee!==0&&ee!==O.retryLane))throw O.retryLane=ee,Jd(h,ee),Ja(M,h,ee),oN;xv(),m=o5(h,m,_)}else h=O.treeContext,wr=Qs(ee.nextSibling),Ji=m,kn=!0,mu=null,Xs=!1,h!==null&&qL(m,h),m=sv(m,M),m.flags|=4096;return m}return h=ql(h.child,{mode:M.mode,children:M.children}),h.ref=m.ref,m.child=h,h.return=m,h}function ov(h,m){var _=m.ref;if(_===null)h!==null&&h.ref!==null&&(m.flags|=4194816);else{if(typeof _!="function"&&typeof _!="object")throw Error(r(284));(h===null||h.ref!==_)&&(m.flags|=4194816)}}function lN(h,m,_,M,j){return rh(m),_=$E(h,m,_,M,void 0,j),M=HE(),h!==null&&!li?(VE(h,m,j),Jl(h,m,j)):(kn&&M&&SE(m),m.flags|=1,ta(h,m,_,j),m.child)}function l5(h,m,_,M,j,O){return rh(m),m.updateQueue=null,_=dI(m,M,_,j),uI(h),M=HE(),h!==null&&!li?(VE(h,m,O),Jl(h,m,O)):(kn&&M&&SE(m),m.flags|=1,ta(h,m,_,O),m.child)}function c5(h,m,_,M,j){if(rh(m),m.stateNode===null){var O=Xf,ee=_.contextType;typeof ee=="object"&&ee!==null&&(O=ea(ee)),O=new _(M,O),m.memoizedState=O.state!==null&&O.state!==void 0?O.state:null,O.updater=aN,m.stateNode=O,O._reactInternals=m,O=m.stateNode,O.props=M,O.state=m.memoizedState,O.refs={},DE(m),ee=_.contextType,O.context=typeof ee=="object"&&ee!==null?ea(ee):Xf,O.state=m.memoizedState,ee=_.getDerivedStateFromProps,typeof ee=="function"&&(iN(m,_,ee,M),O.state=m.memoizedState),typeof _.getDerivedStateFromProps=="function"||typeof O.getSnapshotBeforeUpdate=="function"||typeof O.UNSAFE_componentWillMount!="function"&&typeof O.componentWillMount!="function"||(ee=O.state,typeof O.componentWillMount=="function"&&O.componentWillMount(),typeof O.UNSAFE_componentWillMount=="function"&&O.UNSAFE_componentWillMount(),ee!==O.state&&aN.enqueueReplaceState(O,O.state,null),ux(m,M,O,j),cx(),O.state=m.memoizedState),typeof O.componentDidMount=="function"&&(m.flags|=4194308),M=!0}else if(h===null){O=m.stateNode;var de=m.memoizedProps,ke=ch(_,de);O.props=ke;var nt=O.context,dt=_.contextType;ee=Xf,typeof dt=="object"&&dt!==null&&(ee=ea(dt));var xt=_.getDerivedStateFromProps;dt=typeof xt=="function"||typeof O.getSnapshotBeforeUpdate=="function",de=m.pendingProps!==de,dt||typeof O.UNSAFE_componentWillReceiveProps!="function"&&typeof O.componentWillReceiveProps!="function"||(de||nt!==ee)&&XI(m,O,M,ee),xu=!1;var it=m.memoizedState;O.state=it,ux(m,M,O,j),cx(),nt=m.memoizedState,de||it!==nt||xu?(typeof xt=="function"&&(iN(m,_,xt,M),nt=m.memoizedState),(ke=xu||KI(m,_,ke,M,it,nt,ee))?(dt||typeof O.UNSAFE_componentWillMount!="function"&&typeof O.componentWillMount!="function"||(typeof O.componentWillMount=="function"&&O.componentWillMount(),typeof O.UNSAFE_componentWillMount=="function"&&O.UNSAFE_componentWillMount()),typeof O.componentDidMount=="function"&&(m.flags|=4194308)):(typeof O.componentDidMount=="function"&&(m.flags|=4194308),m.memoizedProps=M,m.memoizedState=nt),O.props=M,O.state=nt,O.context=ee,M=ke):(typeof O.componentDidMount=="function"&&(m.flags|=4194308),M=!1)}else{O=m.stateNode,OE(h,m),ee=m.memoizedProps,dt=ch(_,ee),O.props=dt,xt=m.pendingProps,it=O.context,nt=_.contextType,ke=Xf,typeof nt=="object"&&nt!==null&&(ke=ea(nt)),de=_.getDerivedStateFromProps,(nt=typeof de=="function"||typeof O.getSnapshotBeforeUpdate=="function")||typeof O.UNSAFE_componentWillReceiveProps!="function"&&typeof O.componentWillReceiveProps!="function"||(ee!==xt||it!==ke)&&XI(m,O,M,ke),xu=!1,it=m.memoizedState,O.state=it,ux(m,M,O,j),cx();var ot=m.memoizedState;ee!==xt||it!==ot||xu||h!==null&&h.dependencies!==null&&$y(h.dependencies)?(typeof de=="function"&&(iN(m,_,de,M),ot=m.memoizedState),(dt=xu||KI(m,_,dt,M,it,ot,ke)||h!==null&&h.dependencies!==null&&$y(h.dependencies))?(nt||typeof O.UNSAFE_componentWillUpdate!="function"&&typeof O.componentWillUpdate!="function"||(typeof O.componentWillUpdate=="function"&&O.componentWillUpdate(M,ot,ke),typeof O.UNSAFE_componentWillUpdate=="function"&&O.UNSAFE_componentWillUpdate(M,ot,ke)),typeof O.componentDidUpdate=="function"&&(m.flags|=4),typeof O.getSnapshotBeforeUpdate=="function"&&(m.flags|=1024)):(typeof O.componentDidUpdate!="function"||ee===h.memoizedProps&&it===h.memoizedState||(m.flags|=4),typeof O.getSnapshotBeforeUpdate!="function"||ee===h.memoizedProps&&it===h.memoizedState||(m.flags|=1024),m.memoizedProps=M,m.memoizedState=ot),O.props=M,O.state=ot,O.context=ke,M=dt):(typeof O.componentDidUpdate!="function"||ee===h.memoizedProps&&it===h.memoizedState||(m.flags|=4),typeof O.getSnapshotBeforeUpdate!="function"||ee===h.memoizedProps&&it===h.memoizedState||(m.flags|=1024),M=!1)}return O=M,ov(h,m),M=(m.flags&128)!==0,O||M?(O=m.stateNode,_=M&&typeof _.getDerivedStateFromError!="function"?null:O.render(),m.flags|=1,h!==null&&M?(m.child=oh(m,h.child,null,j),m.child=oh(m,null,_,j)):ta(h,m,_,j),m.memoizedState=O.state,h=m.child):h=Jl(h,m,j),h}function u5(h,m,_,M){return th(),m.flags|=256,ta(h,m,_,M),m.child}var cN={dehydrated:null,treeContext:null,retryLane:0,hydrationErrors:null};function uN(h){return{baseLanes:h,cachePool:JL()}}function dN(h,m,_){return h=h!==null?h.childLanes&~_:0,m&&(h|=vs),h}function d5(h,m,_){var M=m.pendingProps,j=!1,O=(m.flags&128)!==0,ee;if((ee=O)||(ee=h!==null&&h.memoizedState===null?!1:(ti.current&2)!==0),ee&&(j=!0,m.flags&=-129),ee=(m.flags&32)!==0,m.flags&=-33,h===null){if(kn){if(j?vu(m):_u(),(h=wr)?(h=yF(h,Xs),h=h!==null&&h.data!=="&"?h:null,h!==null&&(m.memoizedState={dehydrated:h,treeContext:fu!==null?{id:sl,overflow:ol}:null,retryLane:536870912,hydrationErrors:null},_=VL(h),_.return=m,m.child=_,Ji=m,wr=null)):h=null,h===null)throw pu(m);return qN(h)?m.lanes=32:m.lanes=536870912,null}var de=M.children;return M=M.fallback,j?(_u(),j=m.mode,de=lv({mode:"hidden",children:de},j),M=eh(M,j,_,null),de.return=m,M.return=m,de.sibling=M,m.child=de,M=m.child,M.memoizedState=uN(_),M.childLanes=dN(h,ee,_),m.memoizedState=cN,px(null,M)):(vu(m),hN(m,de))}var ke=h.memoizedState;if(ke!==null&&(de=ke.dehydrated,de!==null)){if(O)m.flags&256?(vu(m),m.flags&=-257,m=fN(h,m,_)):m.memoizedState!==null?(_u(),m.child=h.child,m.flags|=128,m=null):(_u(),de=M.fallback,j=m.mode,M=lv({mode:"visible",children:M.children},j),de=eh(de,j,_,null),de.flags|=2,M.return=m,de.return=m,M.sibling=de,m.child=M,oh(m,h.child,null,_),M=m.child,M.memoizedState=uN(_),M.childLanes=dN(h,ee,_),m.memoizedState=cN,m=px(null,M));else if(vu(m),qN(de)){if(ee=de.nextSibling&&de.nextSibling.dataset,ee)var nt=ee.dgst;ee=nt,M=Error(r(419)),M.stack="",M.digest=ee,rx({value:M,source:null,stack:null}),m=fN(h,m,_)}else if(li||Jf(h,m,_,!1),ee=(_&h.childLanes)!==0,li||ee){if(ee=fr,ee!==null&&(M=Gn(ee,_),M!==0&&M!==ke.retryLane))throw ke.retryLane=M,Jd(h,M),Ja(ee,h,M),oN;WN(de)||xv(),m=fN(h,m,_)}else WN(de)?(m.flags|=192,m.child=h.child,m=null):(h=ke.treeContext,wr=Qs(de.nextSibling),Ji=m,kn=!0,mu=null,Xs=!1,h!==null&&qL(m,h),m=hN(m,M.children),m.flags|=4096);return m}return j?(_u(),de=M.fallback,j=m.mode,ke=h.child,nt=ke.sibling,M=ql(ke,{mode:"hidden",children:M.children}),M.subtreeFlags=ke.subtreeFlags&65011712,nt!==null?de=ql(nt,de):(de=eh(de,j,_,null),de.flags|=2),de.return=m,M.return=m,M.sibling=de,m.child=M,px(null,M),M=m.child,de=h.child.memoizedState,de===null?de=uN(_):(j=de.cachePool,j!==null?(ke=si._currentValue,j=j.parent!==ke?{parent:ke,pool:ke}:j):j=JL(),de={baseLanes:de.baseLanes|_,cachePool:j}),M.memoizedState=de,M.childLanes=dN(h,ee,_),m.memoizedState=cN,px(h.child,M)):(vu(m),_=h.child,h=_.sibling,_=ql(_,{mode:"visible",children:M.children}),_.return=m,_.sibling=null,h!==null&&(ee=m.deletions,ee===null?(m.deletions=[h],m.flags|=16):ee.push(h)),m.child=_,m.memoizedState=null,_)}function hN(h,m){return m=lv({mode:"visible",children:m},h.mode),m.return=h,h.child=m}function lv(h,m){return h=gs(22,h,null,m),h.lanes=0,h}function fN(h,m,_){return oh(m,h.child,null,_),h=hN(m,m.pendingProps.children),h.flags|=2,m.memoizedState=null,h}function h5(h,m,_){h.lanes|=m;var M=h.alternate;M!==null&&(M.lanes|=m),TE(h.return,m,_)}function mN(h,m,_,M,j,O){var ee=h.memoizedState;ee===null?h.memoizedState={isBackwards:m,rendering:null,renderingStartTime:0,last:M,tail:_,tailMode:j,treeForkCount:O}:(ee.isBackwards=m,ee.rendering=null,ee.renderingStartTime=0,ee.last=M,ee.tail=_,ee.tailMode=j,ee.treeForkCount=O)}function f5(h,m,_){var M=m.pendingProps,j=M.revealOrder,O=M.tail;M=M.children;var ee=ti.current,de=(ee&2)!==0;if(de?(ee=ee&1|2,m.flags|=128):ee&=1,te(ti,ee),ta(h,m,M,_),M=kn?nx:0,!de&&h!==null&&(h.flags&128)!==0)e:for(h=m.child;h!==null;){if(h.tag===13)h.memoizedState!==null&&h5(h,_,m);else if(h.tag===19)h5(h,_,m);else if(h.child!==null){h.child.return=h,h=h.child;continue}if(h===m)break e;for(;h.sibling===null;){if(h.return===null||h.return===m)break e;h=h.return}h.sibling.return=h.return,h=h.sibling}switch(j){case"forwards":for(_=m.child,j=null;_!==null;)h=_.alternate,h!==null&&Yy(h)===null&&(j=_),_=_.sibling;_=j,_===null?(j=m.child,m.child=null):(j=_.sibling,_.sibling=null),mN(m,!1,j,_,O,M);break;case"backwards":case"unstable_legacy-backwards":for(_=null,j=m.child,m.child=null;j!==null;){if(h=j.alternate,h!==null&&Yy(h)===null){m.child=j;break}h=j.sibling,j.sibling=_,_=j,j=h}mN(m,!0,_,null,O,M);break;case"together":mN(m,!1,null,null,void 0,M);break;default:m.memoizedState=null}return m.child}function Jl(h,m,_){if(h!==null&&(m.dependencies=h.dependencies),Mu|=m.lanes,(_&m.childLanes)===0)if(h!==null){if(Jf(h,m,_,!1),(_&m.childLanes)===0)return null}else return null;if(h!==null&&m.child!==h.child)throw Error(r(153));if(m.child!==null){for(h=m.child,_=ql(h,h.pendingProps),m.child=_,_.return=m;h.sibling!==null;)h=h.sibling,_=_.sibling=ql(h,h.pendingProps),_.return=m;_.sibling=null}return m.child}function pN(h,m){return(h.lanes&m)!==0?!0:(h=h.dependencies,!!(h!==null&&$y(h)))}function $re(h,m,_){switch(m.tag){case 3:Te(m,m.stateNode.containerInfo),gu(m,si,h.memoizedState.cache),th();break;case 27:case 5:Ee(m);break;case 4:Te(m,m.stateNode.containerInfo);break;case 10:gu(m,m.type,m.memoizedProps.value);break;case 31:if(m.memoizedState!==null)return m.flags|=128,zE(m),null;break;case 13:var M=m.memoizedState;if(M!==null)return M.dehydrated!==null?(vu(m),m.flags|=128,null):(_&m.child.childLanes)!==0?d5(h,m,_):(vu(m),h=Jl(h,m,_),h!==null?h.sibling:null);vu(m);break;case 19:var j=(h.flags&128)!==0;if(M=(_&m.childLanes)!==0,M||(Jf(h,m,_,!1),M=(_&m.childLanes)!==0),j){if(M)return f5(h,m,_);m.flags|=128}if(j=m.memoizedState,j!==null&&(j.rendering=null,j.tail=null,j.lastEffect=null),te(ti,ti.current),M)break;return null;case 22:return m.lanes=0,a5(h,m,_,m.pendingProps);case 24:gu(m,si,h.memoizedState.cache)}return Jl(h,m,_)}function m5(h,m,_){if(h!==null)if(h.memoizedProps!==m.pendingProps)li=!0;else{if(!pN(h,_)&&(m.flags&128)===0)return li=!1,$re(h,m,_);li=(h.flags&131072)!==0}else li=!1,kn&&(m.flags&1048576)!==0&&WL(m,nx,m.index);switch(m.lanes=0,m.tag){case 16:e:{var M=m.pendingProps;if(h=ah(m.elementType),m.type=h,typeof h=="function")vE(h)?(M=ch(h,M),m.tag=1,m=c5(null,m,h,M,_)):(m.tag=0,m=lN(null,m,h,M,_));else{if(h!=null){var j=h.$$typeof;if(j===A){m.tag=11,m=n5(null,m,h,M,_);break e}else if(j===T){m.tag=14,m=r5(null,m,h,M,_);break e}}throw m=R(h)||h,Error(r(306,m,""))}}return m;case 0:return lN(h,m,m.type,m.pendingProps,_);case 1:return M=m.type,j=ch(M,m.pendingProps),c5(h,m,M,j,_);case 3:e:{if(Te(m,m.stateNode.containerInfo),h===null)throw Error(r(387));M=m.pendingProps;var O=m.memoizedState;j=O.element,OE(h,m),ux(m,M,null,_);var ee=m.memoizedState;if(M=ee.cache,gu(m,si,M),M!==O.cache&&CE(m,[si],_,!0),cx(),M=ee.element,O.isDehydrated)if(O={element:M,isDehydrated:!1,cache:ee.cache},m.updateQueue.baseState=O,m.memoizedState=O,m.flags&256){m=u5(h,m,M,_);break e}else if(M!==j){j=Ws(Error(r(424)),m),rx(j),m=u5(h,m,M,_);break e}else{switch(h=m.stateNode.containerInfo,h.nodeType){case 9:h=h.body;break;default:h=h.nodeName==="HTML"?h.ownerDocument.body:h}for(wr=Qs(h.firstChild),Ji=m,kn=!0,mu=null,Xs=!0,_=aI(m,null,M,_),m.child=_;_;)_.flags=_.flags&-3|4096,_=_.sibling}else{if(th(),M===j){m=Jl(h,m,_);break e}ta(h,m,M,_)}m=m.child}return m;case 26:return ov(h,m),h===null?(_=EF(m.type,null,m.pendingProps,null))?m.memoizedState=_:kn||(_=m.type,h=m.pendingProps,M=Mv(ue.current).createElement(_),M[Dn]=m,M[gt]=h,na(M,_,h),Oe(M),m.stateNode=M):m.memoizedState=EF(m.type,h.memoizedProps,m.pendingProps,h.memoizedState),null;case 27:return Ee(m),h===null&&kn&&(M=m.stateNode=wF(m.type,m.pendingProps,ue.current),Ji=m,Xs=!0,j=wr,Cu(m.type)?(KN=j,wr=Qs(M.firstChild)):wr=j),ta(h,m,m.pendingProps.children,_),ov(h,m),h===null&&(m.flags|=4194304),m.child;case 5:return h===null&&kn&&((j=M=wr)&&(M=bie(M,m.type,m.pendingProps,Xs),M!==null?(m.stateNode=M,Ji=m,wr=Qs(M.firstChild),Xs=!1,j=!0):j=!1),j||pu(m)),Ee(m),j=m.type,O=m.pendingProps,ee=h!==null?h.memoizedProps:null,M=O.children,HN(j,O)?M=null:ee!==null&&HN(j,ee)&&(m.flags|=32),m.memoizedState!==null&&(j=$E(h,m,Rre,null,null,_),kx._currentValue=j),ov(h,m),ta(h,m,M,_),m.child;case 6:return h===null&&kn&&((h=_=wr)&&(_=yie(_,m.pendingProps,Xs),_!==null?(m.stateNode=_,Ji=m,wr=null,h=!0):h=!1),h||pu(m)),null;case 13:return d5(h,m,_);case 4:return Te(m,m.stateNode.containerInfo),M=m.pendingProps,h===null?m.child=oh(m,null,M,_):ta(h,m,M,_),m.child;case 11:return n5(h,m,m.type,m.pendingProps,_);case 7:return ta(h,m,m.pendingProps,_),m.child;case 8:return ta(h,m,m.pendingProps.children,_),m.child;case 12:return ta(h,m,m.pendingProps.children,_),m.child;case 10:return M=m.pendingProps,gu(m,m.type,M.value),ta(h,m,M.children,_),m.child;case 9:return j=m.type._context,M=m.pendingProps.children,rh(m),j=ea(j),M=M(j),m.flags|=1,ta(h,m,M,_),m.child;case 14:return r5(h,m,m.type,m.pendingProps,_);case 15:return i5(h,m,m.type,m.pendingProps,_);case 19:return f5(h,m,_);case 31:return Bre(h,m,_);case 22:return a5(h,m,_,m.pendingProps);case 24:return rh(m),M=ea(si),h===null?(j=PE(),j===null&&(j=fr,O=kE(),j.pooledCache=O,O.refCount++,O!==null&&(j.pooledCacheLanes|=_),j=O),m.memoizedState={parent:M,cache:j},DE(m),gu(m,si,j)):((h.lanes&_)!==0&&(OE(h,m),ux(m,null,null,_),cx()),j=h.memoizedState,O=m.memoizedState,j.parent!==M?(j={parent:M,cache:M},m.memoizedState=j,m.lanes===0&&(m.memoizedState=m.updateQueue.baseState=j),gu(m,si,M)):(M=O.cache,gu(m,si,M),M!==j.cache&&CE(m,[si],_,!0))),ta(h,m,m.pendingProps.children,_),m.child;case 29:throw m.pendingProps}throw Error(r(156,m.tag))}function ec(h){h.flags|=4}function gN(h,m,_,M,j){if((m=(h.mode&32)!==0)&&(m=!1),m){if(h.flags|=16777216,(j&335544128)===j)if(h.stateNode.complete)h.flags|=8192;else if(B5())h.flags|=8192;else throw sh=Wy,RE}else h.flags&=-16777217}function p5(h,m){if(m.type!=="stylesheet"||(m.state.loading&4)!==0)h.flags&=-16777217;else if(h.flags|=16777216,!kF(m))if(B5())h.flags|=8192;else throw sh=Wy,RE}function cv(h,m){m!==null&&(h.flags|=4),h.flags&16384&&(m=h.tag!==22?Nt():536870912,h.lanes|=m,dm|=m)}function gx(h,m){if(!kn)switch(h.tailMode){case"hidden":m=h.tail;for(var _=null;m!==null;)m.alternate!==null&&(_=m),m=m.sibling;_===null?h.tail=null:_.sibling=null;break;case"collapsed":_=h.tail;for(var M=null;_!==null;)_.alternate!==null&&(M=_),_=_.sibling;M===null?m||h.tail===null?h.tail=null:h.tail.sibling=null:M.sibling=null}}function Sr(h){var m=h.alternate!==null&&h.alternate.child===h.child,_=0,M=0;if(m)for(var j=h.child;j!==null;)_|=j.lanes|j.childLanes,M|=j.subtreeFlags&65011712,M|=j.flags&65011712,j.return=h,j=j.sibling;else for(j=h.child;j!==null;)_|=j.lanes|j.childLanes,M|=j.subtreeFlags,M|=j.flags,j.return=h,j=j.sibling;return h.subtreeFlags|=M,h.childLanes=_,m}function Hre(h,m,_){var M=m.pendingProps;switch(ME(m),m.tag){case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return Sr(m),null;case 1:return Sr(m),null;case 3:return _=m.stateNode,M=null,h!==null&&(M=h.memoizedState.cache),m.memoizedState.cache!==M&&(m.flags|=2048),Yl(si),me(),_.pendingContext&&(_.context=_.pendingContext,_.pendingContext=null),(h===null||h.child===null)&&(Zf(m)?ec(m):h===null||h.memoizedState.isDehydrated&&(m.flags&256)===0||(m.flags|=1024,NE())),Sr(m),null;case 26:var j=m.type,O=m.memoizedState;return h===null?(ec(m),O!==null?(Sr(m),p5(m,O)):(Sr(m),gN(m,j,null,M,_))):O?O!==h.memoizedState?(ec(m),Sr(m),p5(m,O)):(Sr(m),m.flags&=-16777217):(h=h.memoizedProps,h!==M&&ec(m),Sr(m),gN(m,j,h,M,_)),null;case 27:if(be(m),_=ue.current,j=m.type,h!==null&&m.stateNode!=null)h.memoizedProps!==M&&ec(m);else{if(!M){if(m.stateNode===null)throw Error(r(166));return Sr(m),null}h=ne.current,Zf(m)?KL(m):(h=wF(j,M,_),m.stateNode=h,ec(m))}return Sr(m),null;case 5:if(be(m),j=m.type,h!==null&&m.stateNode!=null)h.memoizedProps!==M&&ec(m);else{if(!M){if(m.stateNode===null)throw Error(r(166));return Sr(m),null}if(O=ne.current,Zf(m))KL(m);else{var ee=Mv(ue.current);switch(O){case 1:O=ee.createElementNS("http://www.w3.org/2000/svg",j);break;case 2:O=ee.createElementNS("http://www.w3.org/1998/Math/MathML",j);break;default:switch(j){case"svg":O=ee.createElementNS("http://www.w3.org/2000/svg",j);break;case"math":O=ee.createElementNS("http://www.w3.org/1998/Math/MathML",j);break;case"script":O=ee.createElement("div"),O.innerHTML=" - + +