diff --git a/consumer-guide/.gitignore b/consumer-guide/.gitignore
deleted file mode 100644
index 9b04f643a..000000000
--- a/consumer-guide/.gitignore
+++ /dev/null
@@ -1,17 +0,0 @@
-# v0 sandbox internal files
-__v0_runtime_loader.js
-__v0_devtools.tsx
-__v0_jsx-dev-runtime.ts
-.snowflake/
-.v0-trash/
-.vercel/
-next.user-config.*
-
-# Environment variables
-.env*.local
-
-# Common ignores
-node_modules
-.next/
-.DS_Store
-.vercel
diff --git a/consumer-guide/README.md b/consumer-guide/README.md
deleted file mode 100644
index f11272311..000000000
--- a/consumer-guide/README.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# FastVideo Consumer Guide
-
-A standalone Next.js consumer guide for FastVideo configuration selection and advanced tuning.
-
-## Requirements
-
-- Node.js 20 or newer
-- pnpm
-
-## Run Locally
-
-```bash
-pnpm install
-pnpm dev
-```
-
-Then open http://localhost:3000.
-
-## Build
-
-```bash
-pnpm build
-pnpm start
-```
-
-## Notes
-
-This app is independent from the main FastVideo Python package.
-Run commands from this `consumer-guide/` directory.
diff --git a/consumer-guide/app/globals.css b/consumer-guide/app/globals.css
deleted file mode 100644
index dc2aea17f..000000000
--- a/consumer-guide/app/globals.css
+++ /dev/null
@@ -1,125 +0,0 @@
-@import 'tailwindcss';
-@import 'tw-animate-css';
-
-@custom-variant dark (&:is(.dark *));
-
-:root {
- --background: oklch(1 0 0);
- --foreground: oklch(0.145 0 0);
- --card: oklch(1 0 0);
- --card-foreground: oklch(0.145 0 0);
- --popover: oklch(1 0 0);
- --popover-foreground: oklch(0.145 0 0);
- --primary: oklch(0.205 0 0);
- --primary-foreground: oklch(0.985 0 0);
- --secondary: oklch(0.97 0 0);
- --secondary-foreground: oklch(0.205 0 0);
- --muted: oklch(0.97 0 0);
- --muted-foreground: oklch(0.556 0 0);
- --accent: oklch(0.97 0 0);
- --accent-foreground: oklch(0.205 0 0);
- --destructive: oklch(0.577 0.245 27.325);
- --destructive-foreground: oklch(0.577 0.245 27.325);
- --border: oklch(0.922 0 0);
- --input: oklch(0.922 0 0);
- --ring: oklch(0.708 0 0);
- --chart-1: oklch(0.646 0.222 41.116);
- --chart-2: oklch(0.6 0.118 184.704);
- --chart-3: oklch(0.398 0.07 227.392);
- --chart-4: oklch(0.828 0.189 84.429);
- --chart-5: oklch(0.769 0.188 70.08);
- --radius: 0.625rem;
- --sidebar: oklch(0.985 0 0);
- --sidebar-foreground: oklch(0.145 0 0);
- --sidebar-primary: oklch(0.205 0 0);
- --sidebar-primary-foreground: oklch(0.985 0 0);
- --sidebar-accent: oklch(0.97 0 0);
- --sidebar-accent-foreground: oklch(0.205 0 0);
- --sidebar-border: oklch(0.922 0 0);
- --sidebar-ring: oklch(0.708 0 0);
-}
-
-.dark {
- --background: oklch(0.145 0 0);
- --foreground: oklch(0.985 0 0);
- --card: oklch(0.145 0 0);
- --card-foreground: oklch(0.985 0 0);
- --popover: oklch(0.145 0 0);
- --popover-foreground: oklch(0.985 0 0);
- --primary: oklch(0.985 0 0);
- --primary-foreground: oklch(0.205 0 0);
- --secondary: oklch(0.269 0 0);
- --secondary-foreground: oklch(0.985 0 0);
- --muted: oklch(0.269 0 0);
- --muted-foreground: oklch(0.708 0 0);
- --accent: oklch(0.269 0 0);
- --accent-foreground: oklch(0.985 0 0);
- --destructive: oklch(0.396 0.141 25.723);
- --destructive-foreground: oklch(0.637 0.237 25.331);
- --border: oklch(0.269 0 0);
- --input: oklch(0.269 0 0);
- --ring: oklch(0.439 0 0);
- --chart-1: oklch(0.488 0.243 264.376);
- --chart-2: oklch(0.696 0.17 162.48);
- --chart-3: oklch(0.769 0.188 70.08);
- --chart-4: oklch(0.627 0.265 303.9);
- --chart-5: oklch(0.645 0.246 16.439);
- --sidebar: oklch(0.205 0 0);
- --sidebar-foreground: oklch(0.985 0 0);
- --sidebar-primary: oklch(0.488 0.243 264.376);
- --sidebar-primary-foreground: oklch(0.985 0 0);
- --sidebar-accent: oklch(0.269 0 0);
- --sidebar-accent-foreground: oklch(0.985 0 0);
- --sidebar-border: oklch(0.269 0 0);
- --sidebar-ring: oklch(0.439 0 0);
-}
-
-@theme inline {
- --font-sans: 'Geist', 'Geist Fallback';
- --font-mono: 'Geist Mono', 'Geist Mono Fallback';
- --color-background: var(--background);
- --color-foreground: var(--foreground);
- --color-card: var(--card);
- --color-card-foreground: var(--card-foreground);
- --color-popover: var(--popover);
- --color-popover-foreground: var(--popover-foreground);
- --color-primary: var(--primary);
- --color-primary-foreground: var(--primary-foreground);
- --color-secondary: var(--secondary);
- --color-secondary-foreground: var(--secondary-foreground);
- --color-muted: var(--muted);
- --color-muted-foreground: var(--muted-foreground);
- --color-accent: var(--accent);
- --color-accent-foreground: var(--accent-foreground);
- --color-destructive: var(--destructive);
- --color-destructive-foreground: var(--destructive-foreground);
- --color-border: var(--border);
- --color-input: var(--input);
- --color-ring: var(--ring);
- --color-chart-1: var(--chart-1);
- --color-chart-2: var(--chart-2);
- --color-chart-3: var(--chart-3);
- --color-chart-4: var(--chart-4);
- --color-chart-5: var(--chart-5);
- --radius-sm: calc(var(--radius) - 4px);
- --radius-md: calc(var(--radius) - 2px);
- --radius-lg: var(--radius);
- --radius-xl: calc(var(--radius) + 4px);
- --color-sidebar: var(--sidebar);
- --color-sidebar-foreground: var(--sidebar-foreground);
- --color-sidebar-primary: var(--sidebar-primary);
- --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
- --color-sidebar-accent: var(--sidebar-accent);
- --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
- --color-sidebar-border: var(--sidebar-border);
- --color-sidebar-ring: var(--sidebar-ring);
-}
-
-@layer base {
- * {
- @apply border-border outline-ring/50;
- }
- body {
- @apply bg-background text-foreground;
- }
-}
diff --git a/consumer-guide/app/layout.tsx b/consumer-guide/app/layout.tsx
deleted file mode 100644
index 91eb9484e..000000000
--- a/consumer-guide/app/layout.tsx
+++ /dev/null
@@ -1,45 +0,0 @@
-import type { Metadata } from 'next'
-import { Geist, Geist_Mono } from 'next/font/google'
-import { Analytics } from '@vercel/analytics/next'
-import './globals.css'
-
-const _geist = Geist({ subsets: ["latin"] });
-const _geistMono = Geist_Mono({ subsets: ["latin"] });
-
-export const metadata: Metadata = {
- title: 'FastVideo Config Selector',
- description: 'Choose your hardware and task to get a recommended FastVideo configuration',
- generator: 'v0.app',
- icons: {
- icon: [
- {
- url: '/icon-light-32x32.png',
- media: '(prefers-color-scheme: light)',
- },
- {
- url: '/icon-dark-32x32.png',
- media: '(prefers-color-scheme: dark)',
- },
- {
- url: '/icon.svg',
- type: 'image/svg+xml',
- },
- ],
- apple: '/apple-icon.png',
- },
-}
-
-export default function RootLayout({
- children,
-}: Readonly<{
- children: React.ReactNode
-}>) {
- return (
-
-
- {children}
- {process.env.NODE_ENV === 'production' && }
-
-
- )
-}
diff --git a/consumer-guide/app/page.tsx b/consumer-guide/app/page.tsx
deleted file mode 100644
index 9c147e1ff..000000000
--- a/consumer-guide/app/page.tsx
+++ /dev/null
@@ -1,334 +0,0 @@
-"use client"
-
-import { useState, useMemo } from "react"
-import { Monitor, Cpu, HardDrive, Layers, Clock, Copy, Check, Film, Image, Sparkles, Gamepad2, Settings2 } from "lucide-react"
-import Link from "next/link"
-
-type Task = "t2v" | "i2v" | "ti2v" | "action"
-type Tier = "quick" | "daily" | "best"
-
-interface Config {
- model: string
- modelShort: string
- attn: string
- h: number
- w: number
- frames: number
- steps: number
- cfg: number
- vramMin: number
- ramMin: number
- time: string
- vram: string
- offload: boolean
- extra?: string
-}
-
-const CONFIGS: Record> = {
- t2v: {
- quick: { model: "FastVideo/FastWan2.1-T2V-1.3B-Diffusers", modelShort: "FastWan2.1-T2V-1.3B", attn: "VIDEO_SPARSE_ATTN", h: 480, w: 832, frames: 49, steps: 20, cfg: 5.0, vramMin: 8, ramMin: 16, time: "~60 s", vram: "~16 GB", offload: false },
- daily: { model: "FastVideo/FastWan2.1-T2V-1.3B-Diffusers", modelShort: "FastWan2.1-T2V-1.3B", attn: "FLASH_ATTN", h: 720, w: 1280, frames: 81, steps: 30, cfg: 5.0, vramMin: 20, ramMin: 32, time: "~3 min", vram: "~22 GB", offload: false },
- best: { model: "Wan-AI/Wan2.1-T2V-14B-Diffusers", modelShort: "Wan2.1-T2V-14B", attn: "FLASH_ATTN", h: 720, w: 1280, frames: 81, steps: 50, cfg: 6.0, vramMin: 16, ramMin: 40, time: "~15 min", vram: "~18 GB + ~40 GB RAM", offload: true }
- },
- i2v: {
- quick: { model: "Wan-AI/Wan2.1-I2V-14B-480P-Diffusers", modelShort: "Wan2.1-I2V-14B-480P", attn: "FLASH_ATTN", h: 480, w: 832, frames: 49, steps: 20, cfg: 5.0, vramMin: 16, ramMin: 32, time: "~2 min", vram: "~18 GB", offload: true, extra: "--image ./input.png" },
- daily: { model: "Wan-AI/Wan2.1-I2V-14B-480P-Diffusers", modelShort: "Wan2.1-I2V-14B-480P", attn: "FLASH_ATTN", h: 480, w: 832, frames: 81, steps: 30, cfg: 5.0, vramMin: 16, ramMin: 32, time: "~5 min", vram: "~20 GB", offload: true, extra: "--image ./input.png" },
- best: { model: "Wan-AI/Wan2.1-I2V-14B-720P-Diffusers", modelShort: "Wan2.1-I2V-14B-720P", attn: "FLASH_ATTN", h: 720, w: 1280, frames: 81, steps: 50, cfg: 6.0, vramMin: 16, ramMin: 40, time: "~20 min", vram: "~20 GB + ~40 GB RAM", offload: true, extra: "--image ./input.png" }
- },
- ti2v: {
- quick: { model: "FastVideo/FastWan2.2-TI2V-5B-FullAttn-Diffusers", modelShort: "FastWan2.2-TI2V-5B", attn: "FLASH_ATTN", h: 480, w: 832, frames: 49, steps: 20, cfg: 5.0, vramMin: 16, ramMin: 32, time: "~2 min", vram: "~18 GB", offload: false, extra: "--image ./input.png" },
- daily: { model: "FastVideo/FastWan2.2-TI2V-5B-FullAttn-Diffusers", modelShort: "FastWan2.2-TI2V-5B", attn: "FLASH_ATTN", h: 720, w: 1280, frames: 81, steps: 30, cfg: 5.0, vramMin: 20, ramMin: 32, time: "~5 min", vram: "~22 GB", offload: false, extra: "--image ./input.png" },
- best: { model: "Wan-AI/Wan2.2-TI2V-5B-Diffusers", modelShort: "Wan2.2-TI2V-5B", attn: "SAGE_ATTN", h: 720, w: 1280, frames: 81, steps: 50, cfg: 6.0, vramMin: 20, ramMin: 40, time: "~15 min", vram: "~22 GB + ~40 GB RAM", offload: true, extra: "--image ./input.png" }
- },
- action: {
- quick: { model: "FastVideo/Matrix-Game-2.0-Base-Diffusers", modelShort: "Matrix-Game-2.0-Base", attn: "FLASH_ATTN", h: 480, w: 832, frames: 49, steps: 20, cfg: 5.0, vramMin: 16, ramMin: 32, time: "~2 min", vram: "~18 GB", offload: false, extra: "--image ./input.png --action forward" },
- daily: { model: "FastVideo/Matrix-Game-2.0-Base-Diffusers", modelShort: "Matrix-Game-2.0-Base", attn: "FLASH_ATTN", h: 720, w: 1280, frames: 81, steps: 30, cfg: 5.0, vramMin: 20, ramMin: 32, time: "~5 min", vram: "~22 GB", offload: false, extra: "--image ./input.png --action forward" },
- best: { model: "FastVideo/Matrix-Game-2.0-GTA-Diffusers", modelShort: "Matrix-Game-2.0-GTA", attn: "FLASH_ATTN", h: 720, w: 1280, frames: 81, steps: 50, cfg: 6.0, vramMin: 20, ramMin: 40, time: "~15 min", vram: "~20 GB + ~40 GB RAM", offload: true, extra: "--image ./input.png --action forward" }
- }
-}
-
-const TASKS: { id: Task; label: string; sub: string; icon: typeof Film }[] = [
- { id: "t2v", label: "Text to Video", sub: "T2V", icon: Film },
- { id: "i2v", label: "Image to Video", sub: "I2V", icon: Image },
- { id: "ti2v", label: "Text + Image", sub: "TI2V", icon: Sparkles },
- { id: "action", label: "Action Control", sub: "Matrix Game", icon: Gamepad2 },
-]
-
-const TIERS: { id: Tier; name: string; desc: string; badge?: string }[] = [
- { id: "quick", name: "Quick Try", desc: "Fast preview. Lower resolution, fewer steps." },
- { id: "daily", name: "Daily Use", desc: "Balanced quality and speed.", badge: "Recommended" },
- { id: "best", name: "Best Quality", desc: "14B model, max fidelity. Requires offloading." },
-]
-
-export default function FastVideoConfigSelector() {
- const [task, setTask] = useState("t2v")
- const [tier, setTier] = useState("daily")
- const [gpu, setGpu] = useState("4090")
- const [vram, setVram] = useState(24)
- const [ram, setRam] = useState(64)
- const [ngpu, setNgpu] = useState(1)
- const [copied, setCopied] = useState(false)
-
- const config = CONFIGS[task][tier]
-
- const warning = useMemo(() => {
- if (vram < config.vramMin) {
- return `This mode requires ${config.vramMin} GB VRAM. Your selection is ${vram} GB — consider switching to Quick Try.`
- }
- if (ram < config.ramMin) {
- return `This mode requires ${config.ramMin} GB RAM. Your selection is ${ram} GB.`
- }
- return null
- }, [vram, ram, config])
-
- const command = useMemo(() => {
- let cmd = `# 1. install\npip install fastvideo\n\n`
- cmd += `# 2. download model\nhuggingface-cli download ${config.model} \\\n --local-dir ./models/${config.modelShort}\n\n`
- cmd += `# 3. run\nfastvideo generate \\\n`
- cmd += ` --model ./models/${config.modelShort} \\\n`
- cmd += ` --attention ${config.attn} \\\n`
- cmd += ` --height ${config.h} --width ${config.w} \\\n`
- cmd += ` --num_frames ${config.frames} \\\n`
- cmd += ` --num_inference_steps ${config.steps} \\\n`
- cmd += ` --guidance_scale ${config.cfg.toFixed(1)}`
- if (config.offload) {
- cmd += ` \\\n --dit_cpu_offload \\\n --vae_cpu_offload \\\n --pin_cpu_memory`
- }
- if (config.extra) {
- cmd += ` \\\n ${config.extra}`
- }
- cmd += ` \\\n --prompt "your prompt here"`
- return cmd
- }, [config])
-
- const copyCommand = async () => {
- await navigator.clipboard.writeText(command)
- setCopied(true)
- setTimeout(() => setCopied(false), 2000)
- }
-
- return (
-
- {/* Header */}
-
-
-
-
-
-
-
Config Selector
-
Choose your hardware and task to get a recommended configuration
-
-
-
-
- Advanced Tuning
-
-
-
-
-
-
- {/* Step 1: Task Selection */}
-
-
- 1
-
What do you want to make?
-
-
- {TASKS.map(({ id, label, sub, icon: Icon }) => (
-
setTask(id)}
- className={`group relative rounded-xl border p-4 text-left transition-all duration-200 ${
- task === id
- ? "border-sky-500/50 bg-sky-500/10 shadow-lg shadow-sky-500/10"
- : "border-white/5 bg-white/[0.02] hover:border-white/10 hover:bg-white/[0.04]"
- }`}
- >
-
-
-
-
- {label}
-
- {sub}
-
- ))}
-
-
-
- {/* Step 2: Machine Specs */}
-
-
- 2
-
Your machine specs
-
-
-
-
-
- GPU Model
-
-
setGpu(e.target.value)}
- className="w-full rounded-lg border border-white/10 bg-white/5 px-3 py-2 text-sm text-white outline-none transition-colors focus:border-sky-500/50"
- >
- RTX 4090
- RTX 4080
- RTX 3090
- RTX 3080
- Other
-
-
-
-
-
- VRAM (GB)
-
-
setVram(Number(e.target.value))}
- className="w-full rounded-lg border border-white/10 bg-white/5 px-3 py-2 text-sm text-white outline-none transition-colors focus:border-sky-500/50"
- >
- 24 GB
- 16 GB
- 12 GB
- 10 GB
- 8 GB
-
-
-
-
-
- RAM (GB)
-
-
setRam(Number(e.target.value))}
- className="w-full rounded-lg border border-white/10 bg-white/5 px-3 py-2 text-sm text-white outline-none transition-colors focus:border-sky-500/50"
- >
- 128 GB
- 64 GB
- 32 GB
- 16 GB
-
-
-
-
-
- Number of GPUs
-
-
setNgpu(Number(e.target.value))}
- className="w-full rounded-lg border border-white/10 bg-white/5 px-3 py-2 text-sm text-white outline-none transition-colors focus:border-sky-500/50"
- >
- 1 GPU
- 2 GPUs
- 4 GPUs
-
-
-
-
-
- {/* Step 3: Output Mode */}
-
-
- 3
-
Output mode
-
-
- {TIERS.map(({ id, name, desc, badge }) => {
- const tierConfig = CONFIGS[task][id]
- return (
-
setTier(id)}
- className={`group relative rounded-xl border p-4 text-left transition-all duration-200 ${
- tier === id
- ? "border-sky-500/50 bg-sky-500/10 shadow-lg shadow-sky-500/10"
- : "border-white/5 bg-white/[0.02] hover:border-white/10 hover:bg-white/[0.04]"
- }`}
- >
- {badge && (
-
- {badge}
-
- )}
-
- {name}
-
- {desc}
-
-
-
- {tierConfig.time}
-
-
-
- {tierConfig.vram}
-
-
-
- )
- })}
-
- {warning && (
-
- {warning}
-
- )}
-
-
- {/* Output Configuration */}
-
-
- ✓
-
Your configuration
-
-
- {/* Meta Cards */}
-
-
-
Model
-
{config.modelShort}
-
-
-
Est. Generation Time
-
{config.time}
-
-
-
Peak VRAM
-
{config.vram}
-
-
- {/* Command Block */}
-
-
- {copied ? : }
- {copied ? "Copied" : "Copy"}
-
-
- {command}
-
-
-
-
-
-
- )
-}
diff --git a/consumer-guide/app/tuning/page.tsx b/consumer-guide/app/tuning/page.tsx
deleted file mode 100644
index 526002d23..000000000
--- a/consumer-guide/app/tuning/page.tsx
+++ /dev/null
@@ -1,823 +0,0 @@
-"use client"
-
-import { useState, useMemo } from "react"
-import {
- Monitor, Cpu, Film, Sparkles, Zap, HardDrive, BarChart3,
- Copy, Check, Info, ChevronDown, ChevronUp, Settings2,
- Layers, Clock, Database, Gauge
-} from "lucide-react"
-import Link from "next/link"
-
-// Types
-interface Config {
- // Category A - Model & Hardware
- model_id: string
- workload_type: string
- gpu: string
- num_gpus: number
- // Category B - Video Spec
- height: number
- width: number
- num_frames: number
- fps: number
- // Category C - Quality
- num_inference_steps: number
- guidance_scale: number
- embedded_cfg_scale: number
- flow_shift: number | null
- seed: number
- // Category D - Speed
- attention_backend: string
- VSA_sparsity: number
- dmd_denoising_steps: string
- // Category E - Memory
- dit_cpu_offload: boolean
- dit_layerwise_offload: boolean
- vae_cpu_offload: boolean
- text_encoder_cpu_offload: boolean
- image_encoder_cpu_offload: boolean
- pin_cpu_memory: boolean
- use_fsdp_inference: boolean
-}
-
-const modelOptions = [
- { id: "FastVideo/FastWan2.1-T2V-1.3B-Diffusers", name: "FastWan 1.3B (T2V)", size: "1.3B" },
- { id: "Wan-AI/Wan2.1-T2V-14B-Diffusers", name: "Wan 14B (T2V)", size: "14B" },
- { id: "Wan-AI/Wan2.1-I2V-14B-480P-Diffusers", name: "Wan 14B I2V 480P", size: "14B" },
- { id: "Wan-AI/Wan2.1-I2V-14B-720P-Diffusers", name: "Wan 14B I2V 720P", size: "14B" },
-]
-
-const workloadOptions = [
- { id: "t2v", name: "Text to Video", icon: Film },
- { id: "i2v", name: "Image to Video", icon: Sparkles },
- { id: "ti2v", name: "Text+Image to Video", icon: Layers },
- { id: "action", name: "Action", icon: Zap },
-]
-
-const gpuOptions = [
- { id: "rtx4090", name: "RTX 4090", vram: "24GB" },
- { id: "rtx5090", name: "RTX 5090", vram: "32GB" },
- { id: "a100", name: "A100", vram: "40/80GB" },
- { id: "h100", name: "H100", vram: "80GB" },
-]
-
-const resolutionPresets = [
- { height: 480, width: 832, label: "480p (832×480)" },
- { height: 720, width: 1280, label: "720p (1280×720)" },
- { height: 1080, width: 1920, label: "1080p (1920×1080)" },
-]
-
-const framePresets = [
- { frames: 49, label: "49 frames (~2s @24fps)" },
- { frames: 81, label: "81 frames (~3.4s @24fps)" },
- { frames: 121, label: "121 frames (~5s @24fps)" },
-]
-
-const attentionBackends = [
- { id: "FLASH_ATTN", name: "Flash Attention", desc: "Best quality-speed trade-off", speed: "Baseline" },
- { id: "VIDEO_SPARSE_ATTN", name: "Video Sparse Attention", desc: "~30% faster, minimal quality loss", speed: "Fast" },
- { id: "SAGE_ATTN", name: "Sage Attention", desc: "~40% faster, visible at high motion", speed: "Faster" },
- { id: "SLA_ATTN", name: "Sliding Tile Attention", desc: "Check model compatibility", speed: "Fast" },
-]
-
-// Tooltip component
-function Tooltip({ content }: { content: string }) {
- const [show, setShow] = useState(false)
- return (
-
-
setShow(true)}
- onMouseLeave={() => setShow(false)}
- className="ml-1.5 text-slate-500 hover:text-sky-400 transition-colors"
- >
-
-
- {show && (
-
- )}
-
- )
-}
-
-// Collapsible section
-function Section({
- title,
- icon: Icon,
- number,
- children,
- defaultOpen = true,
- color = "sky"
-}: {
- title: string
- icon: React.ElementType
- number: string
- children: React.ReactNode
- defaultOpen?: boolean
- color?: "sky" | "emerald" | "amber" | "violet" | "rose" | "slate"
-}) {
- const [open, setOpen] = useState(defaultOpen)
- const colorClasses = {
- sky: "bg-sky-500/20 text-sky-400",
- emerald: "bg-emerald-500/20 text-emerald-400",
- amber: "bg-amber-500/20 text-amber-400",
- violet: "bg-violet-500/20 text-violet-400",
- rose: "bg-rose-500/20 text-rose-400",
- slate: "bg-slate-500/20 text-slate-400",
- }
- const textColors = {
- sky: "text-sky-400",
- emerald: "text-emerald-400",
- amber: "text-amber-400",
- violet: "text-violet-400",
- rose: "text-rose-400",
- slate: "text-slate-400",
- }
-
- return (
-
-
setOpen(!open)}
- className="w-full flex items-center justify-between p-4 hover:bg-white/[0.02] transition-colors"
- >
-
-
- {number}
-
-
-
{title}
-
- {open ? : }
-
- {open &&
{children}
}
-
- )
-}
-
-// Input components
-function NumberInput({
- label,
- value,
- onChange,
- min,
- max,
- step = 1,
- tooltip,
- unit
-}: {
- label: string
- value: number
- onChange: (v: number) => void
- min?: number
- max?: number
- step?: number
- tooltip?: string
- unit?: string
-}) {
- return (
-
-
- {label}
- {tooltip && }
-
-
- onChange(Number(e.target.value))}
- min={min}
- max={max}
- step={step}
- className="w-full rounded-lg border border-white/10 bg-slate-900/50 px-3 py-2.5 text-sm text-white focus:border-sky-500/50 focus:outline-none focus:ring-1 focus:ring-sky-500/50"
- />
- {unit && {unit} }
-
-
- )
-}
-
-function SelectInput({
- label,
- value,
- onChange,
- options,
- tooltip
-}: {
- label: string
- value: string
- onChange: (v: string) => void
- options: { id: string; name: string; desc?: string }[]
- tooltip?: string
-}) {
- return (
-
-
- {label}
- {tooltip && }
-
- onChange(e.target.value)}
- className="w-full rounded-lg border border-white/10 bg-slate-900/50 px-3 py-2.5 text-sm text-white focus:border-sky-500/50 focus:outline-none focus:ring-1 focus:ring-sky-500/50"
- >
- {options.map((opt) => (
- {opt.name}
- ))}
-
-
- )
-}
-
-function Toggle({
- label,
- checked,
- onChange,
- tooltip,
- disabled = false
-}: {
- label: string
- checked: boolean
- onChange: (v: boolean) => void
- tooltip?: string
- disabled?: boolean
-}) {
- return (
-
-
- {label}
- {tooltip && }
-
- !disabled && onChange(!checked)}
- className={`relative h-6 w-11 rounded-full transition-colors ${checked ? 'bg-sky-500' : 'bg-slate-700'}`}
- >
-
-
-
- )
-}
-
-export default function AdvancedTuningPage() {
- const [copied, setCopied] = useState(false)
- const [config, setConfig] = useState({
- // Category A
- model_id: "FastVideo/FastWan2.1-T2V-1.3B-Diffusers",
- workload_type: "t2v",
- gpu: "rtx4090",
- num_gpus: 1,
- // Category B
- height: 480,
- width: 832,
- num_frames: 49,
- fps: 24,
- // Category C
- num_inference_steps: 30,
- guidance_scale: 5.0,
- embedded_cfg_scale: 6.0,
- flow_shift: null,
- seed: -1,
- // Category D
- attention_backend: "FLASH_ATTN",
- VSA_sparsity: 0,
- dmd_denoising_steps: "1000,757,522",
- // Category E
- dit_cpu_offload: false,
- dit_layerwise_offload: false,
- vae_cpu_offload: false,
- text_encoder_cpu_offload: false,
- image_encoder_cpu_offload: false,
- pin_cpu_memory: false,
- use_fsdp_inference: false,
- })
-
- // Derived values
- const videoLength = useMemo(() => (config.num_frames / config.fps).toFixed(1), [config.num_frames, config.fps])
- const totalPixels = useMemo(() => config.height * config.width * config.num_frames, [config.height, config.width, config.num_frames])
- const computeCost = useMemo(() => totalPixels * config.num_inference_steps, [totalPixels, config.num_inference_steps])
-
- // Estimate generation time (rough approximation)
- const estimatedTime = useMemo(() => {
- const baseTime = (totalPixels / 19600000) * 60 * (config.num_inference_steps / 30)
- let multiplier = 1
- if (config.dit_cpu_offload) multiplier *= 2.5
- if (config.dit_layerwise_offload) multiplier *= 4
- if (config.attention_backend === "VIDEO_SPARSE_ATTN") multiplier *= 0.7
- if (config.attention_backend === "SAGE_ATTN") multiplier *= 0.6
- return Math.round(baseTime * multiplier)
- }, [totalPixels, config.num_inference_steps, config.dit_cpu_offload, config.dit_layerwise_offload, config.attention_backend])
-
- // Generate command
- const command = useMemo(() => {
- const lines = [
- "# 1. Install FastVideo",
- "pip install fastvideo",
- "",
- "# 2. Download model",
- `huggingface-cli download ${config.model_id} \\`,
- ` --local-dir ./models/${config.model_id.split('/').pop()}`,
- "",
- "# 3. Run generation",
- "fastvideo generate \\",
- ` --model ./models/${config.model_id.split('/').pop()} \\`,
- ` --attention ${config.attention_backend} \\`,
- ` --height ${config.height} --width ${config.width} \\`,
- ` --num_frames ${config.num_frames} \\`,
- ` --num_inference_steps ${config.num_inference_steps} \\`,
- ` --guidance_scale ${config.guidance_scale} \\`,
- ]
-
- if (config.embedded_cfg_scale !== 6.0) {
- lines.push(` --embedded_cfg_scale ${config.embedded_cfg_scale} \\`)
- }
- if (config.flow_shift !== null) {
- lines.push(` --flow_shift ${config.flow_shift} \\`)
- }
- if (config.seed !== -1) {
- lines.push(` --seed ${config.seed} \\`)
- }
- if (config.attention_backend === "VIDEO_SPARSE_ATTN" && config.VSA_sparsity > 0) {
- lines.push(` --vsa_sparsity ${config.VSA_sparsity} \\`)
- }
- if (config.dit_cpu_offload) lines.push(" --dit_cpu_offload \\")
- if (config.dit_layerwise_offload) lines.push(" --dit_layerwise_offload \\")
- if (config.vae_cpu_offload) lines.push(" --vae_cpu_offload \\")
- if (config.text_encoder_cpu_offload) lines.push(" --text_encoder_cpu_offload \\")
- if (config.image_encoder_cpu_offload && (config.workload_type === "i2v" || config.workload_type === "ti2v")) {
- lines.push(" --image_encoder_cpu_offload \\")
- }
- if (config.pin_cpu_memory) lines.push(" --pin_cpu_memory \\")
- if (config.use_fsdp_inference && config.num_gpus > 1) lines.push(" --use_fsdp_inference \\")
-
- if (config.workload_type === "i2v" || config.workload_type === "ti2v") {
- lines.push(" --image ./input.png \\")
- }
- lines.push(' --prompt "your prompt here"')
-
- return lines.join("\n")
- }, [config])
-
- const copyCommand = () => {
- navigator.clipboard.writeText(command)
- setCopied(true)
- setTimeout(() => setCopied(false), 2000)
- }
-
- const updateConfig = (key: K, value: Config[K]) => {
- setConfig((prev) => ({ ...prev, [key]: value }))
- }
-
- const isFastWanDMD = config.model_id.includes("FastWan")
- const isI2V = config.workload_type === "i2v" || config.workload_type === "ti2v"
-
- return (
-
- {/* Header */}
-
-
-
-
-
-
-
-
-
Advanced Tuning Guide
-
RTX 4090 / RTX 5090 - All 27 Parameters
-
-
-
- Quick Start
-
-
-
-
-
-
- {/* Stats Bar */}
-
-
-
-
-
- Video Length
-
-
{videoLength}s
-
-
-
-
- Est. Time
-
-
~{estimatedTime}s
-
-
-
-
- Total Pixels
-
-
{(totalPixels / 1000000).toFixed(1)}M
-
-
-
-
- Compute Cost
-
-
{(computeCost / 1000000000).toFixed(2)}G
-
-
-
-
-
- {/* Left Column - Parameters */}
-
- {/* Category A - Model & Hardware */}
-
-
-
- updateConfig("model_id", v)}
- options={modelOptions.map(m => ({ id: m.id, name: `${m.name} (${m.size})` }))}
- tooltip="HuggingFace model path - uniquely identifies the model weights and architecture."
- />
-
-
updateConfig("workload_type", v)}
- options={workloadOptions.map(w => ({ id: w.id, name: w.name }))}
- tooltip="Task category. Determines which pipeline stages run."
- />
- updateConfig("gpu", v)}
- options={gpuOptions.map(g => ({ id: g.id, name: `${g.name} (${g.vram})` }))}
- tooltip="GPU model. Used for benchmark tracking and hardware-aware configuration."
- />
- updateConfig("num_gpus", v)}
- min={1}
- max={8}
- tooltip="Values > 1 require use_fsdp_inference = true."
- />
-
-
-
- {/* Category B - Video Spec */}
-
-
-
-
Resolution Preset
-
- {resolutionPresets.map((preset) => (
- {
- updateConfig("height", preset.height)
- updateConfig("width", preset.width)
- }}
- className={`rounded-lg border px-3 py-2 text-sm transition-all ${
- config.height === preset.height && config.width === preset.width
- ? "border-emerald-500/50 bg-emerald-500/10 text-emerald-400"
- : "border-white/10 bg-white/[0.02] text-slate-400 hover:border-white/20"
- }`}
- >
- {preset.label}
-
- ))}
-
-
-
- updateConfig("height", v)}
- min={256}
- max={2160}
- step={8}
- unit="px"
- tooltip="Frame height in pixels. Must be divisible by 8 (VAE requirement)."
- />
- updateConfig("width", v)}
- min={256}
- max={3840}
- step={8}
- unit="px"
- tooltip="Frame width in pixels. Must be divisible by 8."
- />
-
-
-
Frame Count Preset
-
- {framePresets.map((preset) => (
- updateConfig("num_frames", preset.frames)}
- className={`rounded-lg border px-3 py-2 text-sm transition-all ${
- config.num_frames === preset.frames
- ? "border-emerald-500/50 bg-emerald-500/10 text-emerald-400"
- : "border-white/10 bg-white/[0.02] text-slate-400 hover:border-white/20"
- }`}
- >
- {preset.label}
-
- ))}
-
-
-
- updateConfig("num_frames", v)}
- min={1}
- max={240}
- tooltip="Total number of frames to generate. Directly sets video duration at a given fps."
- />
- updateConfig("fps", v)}
- min={1}
- max={60}
- tooltip="Frames per second for the output video. Does NOT affect generation time."
- />
-
-
-
-
- {/* Category C - Quality */}
-
-
-
-
- Inference Steps
-
-
-
- updateConfig("num_inference_steps", Number(e.target.value))}
- className="flex-1 h-2 rounded-full bg-slate-700 appearance-none cursor-pointer [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:h-4 [&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-amber-400"
- />
- {config.num_inference_steps}
-
-
- Draft (10)
- Balanced (30)
- High (80)
-
-
-
-
- Guidance Scale
-
-
-
- updateConfig("guidance_scale", Number(e.target.value))}
- className="flex-1 h-2 rounded-full bg-slate-700 appearance-none cursor-pointer [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:h-4 [&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-amber-400"
- />
- {config.guidance_scale}
-
-
- Loose (3)
- Balanced (5)
- Strict (8+)
-
-
-
- updateConfig("embedded_cfg_scale", v)}
- min={1}
- max={10}
- step={0.5}
- tooltip="Model-level CFG signal passed into the DiT. Default: 6.0. Rarely change."
- />
- updateConfig("seed", v)}
- min={-1}
- tooltip="Random seed. Set to -1 for random. Fix a seed for reproducibility."
- />
-
-
-
-
- {/* Category D - Speed */}
-
-
-
-
- Attention Backend
-
-
- {attentionBackends.map((backend) => (
-
updateConfig("attention_backend", backend.id)}
- className={`rounded-lg border p-3 text-left transition-all ${
- config.attention_backend === backend.id
- ? "border-violet-500/50 bg-violet-500/10"
- : "border-white/10 bg-white/[0.02] hover:border-white/20"
- }`}
- >
-
-
- {backend.name}
-
-
- {backend.speed}
-
-
- {backend.desc}
-
- ))}
-
-
- {config.attention_backend === "VIDEO_SPARSE_ATTN" && (
-
-
- VSA Sparsity
-
-
-
- updateConfig("VSA_sparsity", Number(e.target.value))}
- className="flex-1 h-2 rounded-full bg-slate-700 appearance-none cursor-pointer [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:h-4 [&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-violet-400"
- />
- {config.VSA_sparsity}
-
-
- )}
- {isFastWanDMD && config.gpu === "rtx4090" && (
-
-
-
- DMD Mode Available
-
-
- FastWan DMD uses 3-step distillation for ~10x faster generation.
-
-
- dmd_steps: {config.dmd_denoising_steps}
-
-
- )}
-
-
-
- {/* Category E - Memory */}
-
-
-
-
- Tip: For 24GB VRAM with 14B models, enable dit_cpu_offload + vae_cpu_offload + pin_cpu_memory.
-
-
-
updateConfig("dit_cpu_offload", v)}
- tooltip="Offload entire DiT to RAM. Saves ~4GB, ~2-3x slower."
- />
- updateConfig("dit_layerwise_offload", v)}
- tooltip="Layer-by-layer offload. Maximum VRAM saving (~8GB), ~4x slower."
- />
- updateConfig("vae_cpu_offload", v)}
- tooltip="Offload VAE decoder. Saves ~2GB. Minimal time penalty."
- />
- updateConfig("text_encoder_cpu_offload", v)}
- tooltip="Offload text encoder. Saves ~1-2GB. Runs once at start."
- />
- updateConfig("image_encoder_cpu_offload", v)}
- tooltip="I2V/TI2V only. Saves ~1-2GB."
- disabled={!isI2V}
- />
- updateConfig("pin_cpu_memory", v)}
- tooltip="Pins RAM pages for faster PCIe DMA transfers. Always enable with any offload flag."
- />
- updateConfig("use_fsdp_inference", v)}
- tooltip="Shards model weights across multiple GPUs via FSDP."
- disabled={config.num_gpus <= 1}
- />
-
-
-
-
- {/* Right Column - Output */}
-
-
- {/* Generated Command */}
-
-
-
-
-
-
-
Generated Command
-
-
- {copied ? : }
- {copied ? "Copied" : "Copy"}
-
-
-
-
-
- {/* Quick Reference */}
-
-
Quick Reference
-
-
- Resolution
- {config.width}x{config.height}
-
-
- Frames
- {config.num_frames}
-
-
- Steps
- {config.num_inference_steps}
-
-
- Backend
- {config.attention_backend}
-
-
- Offloading
-
- {[config.dit_cpu_offload && "DiT", config.vae_cpu_offload && "VAE"].filter(Boolean).join("+") || "None"}
-
-
-
-
-
-
-
-
-
- )
-}
diff --git a/consumer-guide/components.json b/consumer-guide/components.json
deleted file mode 100644
index 4ee62ee10..000000000
--- a/consumer-guide/components.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "$schema": "https://ui.shadcn.com/schema.json",
- "style": "new-york",
- "rsc": true,
- "tsx": true,
- "tailwind": {
- "config": "",
- "css": "app/globals.css",
- "baseColor": "neutral",
- "cssVariables": true,
- "prefix": ""
- },
- "aliases": {
- "components": "@/components",
- "utils": "@/lib/utils",
- "ui": "@/components/ui",
- "lib": "@/lib",
- "hooks": "@/hooks"
- },
- "iconLibrary": "lucide"
-}
diff --git a/consumer-guide/components/theme-provider.tsx b/consumer-guide/components/theme-provider.tsx
deleted file mode 100644
index 55c2f6eb6..000000000
--- a/consumer-guide/components/theme-provider.tsx
+++ /dev/null
@@ -1,11 +0,0 @@
-'use client'
-
-import * as React from 'react'
-import {
- ThemeProvider as NextThemesProvider,
- type ThemeProviderProps,
-} from 'next-themes'
-
-export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
- return {children}
-}
diff --git a/consumer-guide/components/ui/accordion.tsx b/consumer-guide/components/ui/accordion.tsx
deleted file mode 100644
index e538a33b9..000000000
--- a/consumer-guide/components/ui/accordion.tsx
+++ /dev/null
@@ -1,66 +0,0 @@
-'use client'
-
-import * as React from 'react'
-import * as AccordionPrimitive from '@radix-ui/react-accordion'
-import { ChevronDownIcon } from 'lucide-react'
-
-import { cn } from '@/lib/utils'
-
-function Accordion({
- ...props
-}: React.ComponentProps) {
- return
-}
-
-function AccordionItem({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
- )
-}
-
-function AccordionTrigger({
- className,
- children,
- ...props
-}: React.ComponentProps) {
- return (
-
- svg]:rotate-180',
- className,
- )}
- {...props}
- >
- {children}
-
-
-
- )
-}
-
-function AccordionContent({
- className,
- children,
- ...props
-}: React.ComponentProps) {
- return (
-
- {children}
-
- )
-}
-
-export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }
diff --git a/consumer-guide/components/ui/alert-dialog.tsx b/consumer-guide/components/ui/alert-dialog.tsx
deleted file mode 100644
index 970445266..000000000
--- a/consumer-guide/components/ui/alert-dialog.tsx
+++ /dev/null
@@ -1,157 +0,0 @@
-'use client'
-
-import * as React from 'react'
-import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog'
-
-import { cn } from '@/lib/utils'
-import { buttonVariants } from '@/components/ui/button'
-
-function AlertDialog({
- ...props
-}: React.ComponentProps) {
- return
-}
-
-function AlertDialogTrigger({
- ...props
-}: React.ComponentProps) {
- return (
-
- )
-}
-
-function AlertDialogPortal({
- ...props
-}: React.ComponentProps) {
- return (
-
- )
-}
-
-function AlertDialogOverlay({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
- )
-}
-
-function AlertDialogContent({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
-
-
-
- )
-}
-
-function AlertDialogHeader({
- className,
- ...props
-}: React.ComponentProps<'div'>) {
- return (
-
- )
-}
-
-function AlertDialogFooter({
- className,
- ...props
-}: React.ComponentProps<'div'>) {
- return (
-
- )
-}
-
-function AlertDialogTitle({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
- )
-}
-
-function AlertDialogDescription({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
- )
-}
-
-function AlertDialogAction({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
- )
-}
-
-function AlertDialogCancel({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
- )
-}
-
-export {
- AlertDialog,
- AlertDialogPortal,
- AlertDialogOverlay,
- AlertDialogTrigger,
- AlertDialogContent,
- AlertDialogHeader,
- AlertDialogFooter,
- AlertDialogTitle,
- AlertDialogDescription,
- AlertDialogAction,
- AlertDialogCancel,
-}
diff --git a/consumer-guide/components/ui/alert.tsx b/consumer-guide/components/ui/alert.tsx
deleted file mode 100644
index e6751abe6..000000000
--- a/consumer-guide/components/ui/alert.tsx
+++ /dev/null
@@ -1,66 +0,0 @@
-import * as React from 'react'
-import { cva, type VariantProps } from 'class-variance-authority'
-
-import { cn } from '@/lib/utils'
-
-const alertVariants = cva(
- 'relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current',
- {
- variants: {
- variant: {
- default: 'bg-card text-card-foreground',
- destructive:
- 'text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90',
- },
- },
- defaultVariants: {
- variant: 'default',
- },
- },
-)
-
-function Alert({
- className,
- variant,
- ...props
-}: React.ComponentProps<'div'> & VariantProps) {
- return (
-
- )
-}
-
-function AlertTitle({ className, ...props }: React.ComponentProps<'div'>) {
- return (
-
- )
-}
-
-function AlertDescription({
- className,
- ...props
-}: React.ComponentProps<'div'>) {
- return (
-
- )
-}
-
-export { Alert, AlertTitle, AlertDescription }
diff --git a/consumer-guide/components/ui/aspect-ratio.tsx b/consumer-guide/components/ui/aspect-ratio.tsx
deleted file mode 100644
index 40bb1208d..000000000
--- a/consumer-guide/components/ui/aspect-ratio.tsx
+++ /dev/null
@@ -1,11 +0,0 @@
-'use client'
-
-import * as AspectRatioPrimitive from '@radix-ui/react-aspect-ratio'
-
-function AspectRatio({
- ...props
-}: React.ComponentProps) {
- return
-}
-
-export { AspectRatio }
diff --git a/consumer-guide/components/ui/avatar.tsx b/consumer-guide/components/ui/avatar.tsx
deleted file mode 100644
index aa98465a3..000000000
--- a/consumer-guide/components/ui/avatar.tsx
+++ /dev/null
@@ -1,53 +0,0 @@
-'use client'
-
-import * as React from 'react'
-import * as AvatarPrimitive from '@radix-ui/react-avatar'
-
-import { cn } from '@/lib/utils'
-
-function Avatar({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
- )
-}
-
-function AvatarImage({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
- )
-}
-
-function AvatarFallback({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
- )
-}
-
-export { Avatar, AvatarImage, AvatarFallback }
diff --git a/consumer-guide/components/ui/badge.tsx b/consumer-guide/components/ui/badge.tsx
deleted file mode 100644
index fc4126b7a..000000000
--- a/consumer-guide/components/ui/badge.tsx
+++ /dev/null
@@ -1,46 +0,0 @@
-import * as React from 'react'
-import { Slot } from '@radix-ui/react-slot'
-import { cva, type VariantProps } from 'class-variance-authority'
-
-import { cn } from '@/lib/utils'
-
-const badgeVariants = cva(
- 'inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden',
- {
- variants: {
- variant: {
- default:
- 'border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90',
- secondary:
- 'border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90',
- destructive:
- 'border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60',
- outline:
- 'text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground',
- },
- },
- defaultVariants: {
- variant: 'default',
- },
- },
-)
-
-function Badge({
- className,
- variant,
- asChild = false,
- ...props
-}: React.ComponentProps<'span'> &
- VariantProps & { asChild?: boolean }) {
- const Comp = asChild ? Slot : 'span'
-
- return (
-
- )
-}
-
-export { Badge, badgeVariants }
diff --git a/consumer-guide/components/ui/breadcrumb.tsx b/consumer-guide/components/ui/breadcrumb.tsx
deleted file mode 100644
index 1750ff26a..000000000
--- a/consumer-guide/components/ui/breadcrumb.tsx
+++ /dev/null
@@ -1,109 +0,0 @@
-import * as React from 'react'
-import { Slot } from '@radix-ui/react-slot'
-import { ChevronRight, MoreHorizontal } from 'lucide-react'
-
-import { cn } from '@/lib/utils'
-
-function Breadcrumb({ ...props }: React.ComponentProps<'nav'>) {
- return
-}
-
-function BreadcrumbList({ className, ...props }: React.ComponentProps<'ol'>) {
- return (
-
- )
-}
-
-function BreadcrumbItem({ className, ...props }: React.ComponentProps<'li'>) {
- return (
-
- )
-}
-
-function BreadcrumbLink({
- asChild,
- className,
- ...props
-}: React.ComponentProps<'a'> & {
- asChild?: boolean
-}) {
- const Comp = asChild ? Slot : 'a'
-
- return (
-
- )
-}
-
-function BreadcrumbPage({ className, ...props }: React.ComponentProps<'span'>) {
- return (
-
- )
-}
-
-function BreadcrumbSeparator({
- children,
- className,
- ...props
-}: React.ComponentProps<'li'>) {
- return (
- svg]:size-3.5', className)}
- {...props}
- >
- {children ?? }
-
- )
-}
-
-function BreadcrumbEllipsis({
- className,
- ...props
-}: React.ComponentProps<'span'>) {
- return (
-
-
- More
-
- )
-}
-
-export {
- Breadcrumb,
- BreadcrumbList,
- BreadcrumbItem,
- BreadcrumbLink,
- BreadcrumbPage,
- BreadcrumbSeparator,
- BreadcrumbEllipsis,
-}
diff --git a/consumer-guide/components/ui/button-group.tsx b/consumer-guide/components/ui/button-group.tsx
deleted file mode 100644
index 09d443097..000000000
--- a/consumer-guide/components/ui/button-group.tsx
+++ /dev/null
@@ -1,83 +0,0 @@
-import { Slot } from '@radix-ui/react-slot'
-import { cva, type VariantProps } from 'class-variance-authority'
-
-import { cn } from '@/lib/utils'
-import { Separator } from '@/components/ui/separator'
-
-const buttonGroupVariants = cva(
- "flex w-fit items-stretch [&>*]:focus-visible:z-10 [&>*]:focus-visible:relative [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-md has-[>[data-slot=button-group]]:gap-2",
- {
- variants: {
- orientation: {
- horizontal:
- '[&>*:not(:first-child)]:rounded-l-none [&>*:not(:first-child)]:border-l-0 [&>*:not(:last-child)]:rounded-r-none',
- vertical:
- 'flex-col [&>*:not(:first-child)]:rounded-t-none [&>*:not(:first-child)]:border-t-0 [&>*:not(:last-child)]:rounded-b-none',
- },
- },
- defaultVariants: {
- orientation: 'horizontal',
- },
- },
-)
-
-function ButtonGroup({
- className,
- orientation,
- ...props
-}: React.ComponentProps<'div'> & VariantProps) {
- return (
-
- )
-}
-
-function ButtonGroupText({
- className,
- asChild = false,
- ...props
-}: React.ComponentProps<'div'> & {
- asChild?: boolean
-}) {
- const Comp = asChild ? Slot : 'div'
-
- return (
-
- )
-}
-
-function ButtonGroupSeparator({
- className,
- orientation = 'vertical',
- ...props
-}: React.ComponentProps) {
- return (
-
- )
-}
-
-export {
- ButtonGroup,
- ButtonGroupSeparator,
- ButtonGroupText,
- buttonGroupVariants,
-}
diff --git a/consumer-guide/components/ui/button.tsx b/consumer-guide/components/ui/button.tsx
deleted file mode 100644
index f64632d15..000000000
--- a/consumer-guide/components/ui/button.tsx
+++ /dev/null
@@ -1,60 +0,0 @@
-import * as React from 'react'
-import { Slot } from '@radix-ui/react-slot'
-import { cva, type VariantProps } from 'class-variance-authority'
-
-import { cn } from '@/lib/utils'
-
-const buttonVariants = cva(
- "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
- {
- variants: {
- variant: {
- default: 'bg-primary text-primary-foreground hover:bg-primary/90',
- destructive:
- 'bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60',
- outline:
- 'border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50',
- secondary:
- 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
- ghost:
- 'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50',
- link: 'text-primary underline-offset-4 hover:underline',
- },
- size: {
- default: 'h-9 px-4 py-2 has-[>svg]:px-3',
- sm: 'h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5',
- lg: 'h-10 rounded-md px-6 has-[>svg]:px-4',
- icon: 'size-9',
- 'icon-sm': 'size-8',
- 'icon-lg': 'size-10',
- },
- },
- defaultVariants: {
- variant: 'default',
- size: 'default',
- },
- },
-)
-
-function Button({
- className,
- variant,
- size,
- asChild = false,
- ...props
-}: React.ComponentProps<'button'> &
- VariantProps & {
- asChild?: boolean
- }) {
- const Comp = asChild ? Slot : 'button'
-
- return (
-
- )
-}
-
-export { Button, buttonVariants }
diff --git a/consumer-guide/components/ui/calendar.tsx b/consumer-guide/components/ui/calendar.tsx
deleted file mode 100644
index eaa373e25..000000000
--- a/consumer-guide/components/ui/calendar.tsx
+++ /dev/null
@@ -1,213 +0,0 @@
-'use client'
-
-import * as React from 'react'
-import {
- ChevronDownIcon,
- ChevronLeftIcon,
- ChevronRightIcon,
-} from 'lucide-react'
-import { DayButton, DayPicker, getDefaultClassNames } from 'react-day-picker'
-
-import { cn } from '@/lib/utils'
-import { Button, buttonVariants } from '@/components/ui/button'
-
-function Calendar({
- className,
- classNames,
- showOutsideDays = true,
- captionLayout = 'label',
- buttonVariant = 'ghost',
- formatters,
- components,
- ...props
-}: React.ComponentProps & {
- buttonVariant?: React.ComponentProps['variant']
-}) {
- const defaultClassNames = getDefaultClassNames()
-
- return (
- svg]:rotate-180`,
- String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
- className,
- )}
- captionLayout={captionLayout}
- formatters={{
- formatMonthDropdown: (date) =>
- date.toLocaleString('default', { month: 'short' }),
- ...formatters,
- }}
- classNames={{
- root: cn('w-fit', defaultClassNames.root),
- months: cn(
- 'flex gap-4 flex-col md:flex-row relative',
- defaultClassNames.months,
- ),
- month: cn('flex flex-col w-full gap-4', defaultClassNames.month),
- nav: cn(
- 'flex items-center gap-1 w-full absolute top-0 inset-x-0 justify-between',
- defaultClassNames.nav,
- ),
- button_previous: cn(
- buttonVariants({ variant: buttonVariant }),
- 'size-(--cell-size) aria-disabled:opacity-50 p-0 select-none',
- defaultClassNames.button_previous,
- ),
- button_next: cn(
- buttonVariants({ variant: buttonVariant }),
- 'size-(--cell-size) aria-disabled:opacity-50 p-0 select-none',
- defaultClassNames.button_next,
- ),
- month_caption: cn(
- 'flex items-center justify-center h-(--cell-size) w-full px-(--cell-size)',
- defaultClassNames.month_caption,
- ),
- dropdowns: cn(
- 'w-full flex items-center text-sm font-medium justify-center h-(--cell-size) gap-1.5',
- defaultClassNames.dropdowns,
- ),
- dropdown_root: cn(
- 'relative has-focus:border-ring border border-input shadow-xs has-focus:ring-ring/50 has-focus:ring-[3px] rounded-md',
- defaultClassNames.dropdown_root,
- ),
- dropdown: cn(
- 'absolute bg-popover inset-0 opacity-0',
- defaultClassNames.dropdown,
- ),
- caption_label: cn(
- 'select-none font-medium',
- captionLayout === 'label'
- ? 'text-sm'
- : 'rounded-md pl-2 pr-1 flex items-center gap-1 text-sm h-8 [&>svg]:text-muted-foreground [&>svg]:size-3.5',
- defaultClassNames.caption_label,
- ),
- table: 'w-full border-collapse',
- weekdays: cn('flex', defaultClassNames.weekdays),
- weekday: cn(
- 'text-muted-foreground rounded-md flex-1 font-normal text-[0.8rem] select-none',
- defaultClassNames.weekday,
- ),
- week: cn('flex w-full mt-2', defaultClassNames.week),
- week_number_header: cn(
- 'select-none w-(--cell-size)',
- defaultClassNames.week_number_header,
- ),
- week_number: cn(
- 'text-[0.8rem] select-none text-muted-foreground',
- defaultClassNames.week_number,
- ),
- day: cn(
- 'relative w-full h-full p-0 text-center [&:first-child[data-selected=true]_button]:rounded-l-md [&:last-child[data-selected=true]_button]:rounded-r-md group/day aspect-square select-none',
- defaultClassNames.day,
- ),
- range_start: cn(
- 'rounded-l-md bg-accent',
- defaultClassNames.range_start,
- ),
- range_middle: cn('rounded-none', defaultClassNames.range_middle),
- range_end: cn('rounded-r-md bg-accent', defaultClassNames.range_end),
- today: cn(
- 'bg-accent text-accent-foreground rounded-md data-[selected=true]:rounded-none',
- defaultClassNames.today,
- ),
- outside: cn(
- 'text-muted-foreground aria-selected:text-muted-foreground',
- defaultClassNames.outside,
- ),
- disabled: cn(
- 'text-muted-foreground opacity-50',
- defaultClassNames.disabled,
- ),
- hidden: cn('invisible', defaultClassNames.hidden),
- ...classNames,
- }}
- components={{
- Root: ({ className, rootRef, ...props }) => {
- return (
-
- )
- },
- Chevron: ({ className, orientation, ...props }) => {
- if (orientation === 'left') {
- return (
-
- )
- }
-
- if (orientation === 'right') {
- return (
-
- )
- }
-
- return (
-
- )
- },
- DayButton: CalendarDayButton,
- WeekNumber: ({ children, ...props }) => {
- return (
-
-
- {children}
-
-
- )
- },
- ...components,
- }}
- {...props}
- />
- )
-}
-
-function CalendarDayButton({
- className,
- day,
- modifiers,
- ...props
-}: React.ComponentProps) {
- const defaultClassNames = getDefaultClassNames()
-
- const ref = React.useRef(null)
- React.useEffect(() => {
- if (modifiers.focused) ref.current?.focus()
- }, [modifiers.focused])
-
- return (
- span]:text-xs [&>span]:opacity-70',
- defaultClassNames.day,
- className,
- )}
- {...props}
- />
- )
-}
-
-export { Calendar, CalendarDayButton }
diff --git a/consumer-guide/components/ui/card.tsx b/consumer-guide/components/ui/card.tsx
deleted file mode 100644
index db7dd3cc9..000000000
--- a/consumer-guide/components/ui/card.tsx
+++ /dev/null
@@ -1,92 +0,0 @@
-import * as React from 'react'
-
-import { cn } from '@/lib/utils'
-
-function Card({ className, ...props }: React.ComponentProps<'div'>) {
- return (
-
- )
-}
-
-function CardHeader({ className, ...props }: React.ComponentProps<'div'>) {
- return (
-
- )
-}
-
-function CardTitle({ className, ...props }: React.ComponentProps<'div'>) {
- return (
-
- )
-}
-
-function CardDescription({ className, ...props }: React.ComponentProps<'div'>) {
- return (
-
- )
-}
-
-function CardAction({ className, ...props }: React.ComponentProps<'div'>) {
- return (
-
- )
-}
-
-function CardContent({ className, ...props }: React.ComponentProps<'div'>) {
- return (
-
- )
-}
-
-function CardFooter({ className, ...props }: React.ComponentProps<'div'>) {
- return (
-
- )
-}
-
-export {
- Card,
- CardHeader,
- CardFooter,
- CardTitle,
- CardAction,
- CardDescription,
- CardContent,
-}
diff --git a/consumer-guide/components/ui/carousel.tsx b/consumer-guide/components/ui/carousel.tsx
deleted file mode 100644
index d4a768e7a..000000000
--- a/consumer-guide/components/ui/carousel.tsx
+++ /dev/null
@@ -1,241 +0,0 @@
-'use client'
-
-import * as React from 'react'
-import useEmblaCarousel, {
- type UseEmblaCarouselType,
-} from 'embla-carousel-react'
-import { ArrowLeft, ArrowRight } from 'lucide-react'
-
-import { cn } from '@/lib/utils'
-import { Button } from '@/components/ui/button'
-
-type CarouselApi = UseEmblaCarouselType[1]
-type UseCarouselParameters = Parameters
-type CarouselOptions = UseCarouselParameters[0]
-type CarouselPlugin = UseCarouselParameters[1]
-
-type CarouselProps = {
- opts?: CarouselOptions
- plugins?: CarouselPlugin
- orientation?: 'horizontal' | 'vertical'
- setApi?: (api: CarouselApi) => void
-}
-
-type CarouselContextProps = {
- carouselRef: ReturnType[0]
- api: ReturnType[1]
- scrollPrev: () => void
- scrollNext: () => void
- canScrollPrev: boolean
- canScrollNext: boolean
-} & CarouselProps
-
-const CarouselContext = React.createContext(null)
-
-function useCarousel() {
- const context = React.useContext(CarouselContext)
-
- if (!context) {
- throw new Error('useCarousel must be used within a ')
- }
-
- return context
-}
-
-function Carousel({
- orientation = 'horizontal',
- opts,
- setApi,
- plugins,
- className,
- children,
- ...props
-}: React.ComponentProps<'div'> & CarouselProps) {
- const [carouselRef, api] = useEmblaCarousel(
- {
- ...opts,
- axis: orientation === 'horizontal' ? 'x' : 'y',
- },
- plugins,
- )
- const [canScrollPrev, setCanScrollPrev] = React.useState(false)
- const [canScrollNext, setCanScrollNext] = React.useState(false)
-
- const onSelect = React.useCallback((api: CarouselApi) => {
- if (!api) return
- setCanScrollPrev(api.canScrollPrev())
- setCanScrollNext(api.canScrollNext())
- }, [])
-
- const scrollPrev = React.useCallback(() => {
- api?.scrollPrev()
- }, [api])
-
- const scrollNext = React.useCallback(() => {
- api?.scrollNext()
- }, [api])
-
- const handleKeyDown = React.useCallback(
- (event: React.KeyboardEvent) => {
- if (event.key === 'ArrowLeft') {
- event.preventDefault()
- scrollPrev()
- } else if (event.key === 'ArrowRight') {
- event.preventDefault()
- scrollNext()
- }
- },
- [scrollPrev, scrollNext],
- )
-
- React.useEffect(() => {
- if (!api || !setApi) return
- setApi(api)
- }, [api, setApi])
-
- React.useEffect(() => {
- if (!api) return
- onSelect(api)
- api.on('reInit', onSelect)
- api.on('select', onSelect)
-
- return () => {
- api?.off('select', onSelect)
- }
- }, [api, onSelect])
-
- return (
-
-
- {children}
-
-
- )
-}
-
-function CarouselContent({ className, ...props }: React.ComponentProps<'div'>) {
- const { carouselRef, orientation } = useCarousel()
-
- return (
-
- )
-}
-
-function CarouselItem({ className, ...props }: React.ComponentProps<'div'>) {
- const { orientation } = useCarousel()
-
- return (
-
- )
-}
-
-function CarouselPrevious({
- className,
- variant = 'outline',
- size = 'icon',
- ...props
-}: React.ComponentProps) {
- const { orientation, scrollPrev, canScrollPrev } = useCarousel()
-
- return (
-
-
- Previous slide
-
- )
-}
-
-function CarouselNext({
- className,
- variant = 'outline',
- size = 'icon',
- ...props
-}: React.ComponentProps) {
- const { orientation, scrollNext, canScrollNext } = useCarousel()
-
- return (
-
-
- Next slide
-
- )
-}
-
-export {
- type CarouselApi,
- Carousel,
- CarouselContent,
- CarouselItem,
- CarouselPrevious,
- CarouselNext,
-}
diff --git a/consumer-guide/components/ui/chart.tsx b/consumer-guide/components/ui/chart.tsx
deleted file mode 100644
index 56225f8e9..000000000
--- a/consumer-guide/components/ui/chart.tsx
+++ /dev/null
@@ -1,351 +0,0 @@
-'use client'
-
-import * as React from 'react'
-import * as RechartsPrimitive from 'recharts'
-
-import { cn } from '@/lib/utils'
-
-// Format: { THEME_NAME: CSS_SELECTOR }
-const THEMES = { light: '', dark: '.dark' } as const
-
-export type ChartConfig = {
- [k in string]: {
- label?: React.ReactNode
- icon?: React.ComponentType
- } & (
- | { color?: string; theme?: never }
- | { color?: never; theme: Record }
- )
-}
-
-type ChartContextProps = {
- config: ChartConfig
-}
-
-const ChartContext = React.createContext(null)
-
-function useChart() {
- const context = React.useContext(ChartContext)
-
- if (!context) {
- throw new Error('useChart must be used within a ')
- }
-
- return context
-}
-
-function ChartContainer({
- id,
- className,
- children,
- config,
- ...props
-}: React.ComponentProps<'div'> & {
- config: ChartConfig
- children: React.ComponentProps<
- typeof RechartsPrimitive.ResponsiveContainer
- >['children']
-}) {
- const uniqueId = React.useId()
- const chartId = `chart-${id || uniqueId.replace(/:/g, '')}`
-
- return (
-
-
-
-
- {children}
-
-
-
- )
-}
-
-const ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {
- const colorConfig = Object.entries(config).filter(
- ([, config]) => config.theme || config.color,
- )
-
- if (!colorConfig.length) {
- return null
- }
-
- return (
- 404
This page could not be found.