{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "wave-physics-loader",
  "type": "registry:ui",
  "title": "Wave Physics Loader",
  "description": "Wave Physics Loader loading animation.",
  "dependencies": [
    "framer-motion"
  ],
  "registryDependencies": [],
  "files": [
    {
      "path": "registry/ui/loading/wave-physics-loader.tsx",
      "type": "registry:ui",
      "target": "components/amicro/wave-physics-loader.tsx",
      "content": "import { motion } from 'framer-motion';\r\nimport { useMemo } from 'react';\r\n\r\nexport function WavePhysicsLoader({ theme = 'light' }: { theme?: 'light' | 'dark' }) {\r\n  const numBars = 15;\r\n  const barWidth = 12; \r\n  const barGap = 8; \r\n  const barTotalWidth = barWidth + barGap;\r\n  \r\n  const numFrames = 201;\r\n  const B = 4; \r\n  const maxBounce = 60; \r\n  const baseBarH = 16;\r\n  const wavePeakH = 48; \r\n\r\n  const { bars, ballX, ballY, ballScaleX, ballScaleY, times } = useMemo(() => {\r\n    const barsData = Array.from({ length: numBars }).map(() => ({ \r\n      heights: [] as string[],\r\n      colors: [] as string[],\r\n    }));\r\n    const bX: string[] = [];\r\n    const bY: string[] = [];\r\n    const bScaleX: number[] = [];\r\n    const bScaleY: number[] = [];\r\n    const tArr: number[] = [];\r\n    \r\n    for (let k = 0; k < numFrames; k++) {\r\n      const t = k / (numFrames - 1);\r\n      tArr.push(t);\r\n      \r\n      const x_frac = t < 0.5 ? t / 0.5 : (1 - t) / 0.5;\r\n      const ball_idx = x_frac * (numBars - 1);\r\n      \r\n      bX.push(`${ball_idx * barTotalWidth}px`);\r\n      \r\n      let bounce_f = (x_frac * B) % 1.0;\r\n      if (x_frac === 1 || x_frac === 0) bounce_f = 0;\r\n      \r\n      const bounce_h = 4 * bounce_f * (1 - bounce_f);\r\n      const height_factor = Math.max(0, 1 - bounce_h * 2);\r\n      \r\n      const ball_indent = height_factor * 20; \r\n      const ball_y = (baseBarH + wavePeakH - ball_indent) + bounce_h * maxBounce;\r\n      bY.push(`-${ball_y}px`);\r\n      \r\n      const squish = height_factor; \r\n      bScaleY.push(1 - squish * 0.3);\r\n      bScaleX.push(1 + squish * 0.25);\r\n      \r\n      for (let i = 0; i < numBars; i++) {\r\n        const dist = Math.abs(i - ball_idx);\r\n        \r\n        let wave_val = 0;\r\n        if (dist < 3) {\r\n          wave_val = Math.cos((dist / 3) * (Math.PI / 2));\r\n        }\r\n        \r\n        let indent = 0;\r\n        if (dist < 1.5) {\r\n          const indent_dist = Math.cos((dist / 1.5) * (Math.PI / 2));\r\n          indent = indent_dist * height_factor * 20;\r\n        }\r\n        \r\n        const bar_h = baseBarH + wave_val * wavePeakH - indent;\r\n        barsData[i].heights.push(`${Math.max(4, bar_h)}px`); \r\n        \r\n        // Colors for Light Theme: zinc-200 to zinc-800\r\n        const isDark = theme === 'dark';\r\n        let r, g, b;\r\n        if (isDark) {\r\n          r = Math.round(39 + wave_val * (228 - 39));\r\n          g = Math.round(39 + wave_val * (228 - 39));\r\n          b = Math.round(42 + wave_val * (231 - 42));\r\n        } else {\r\n          r = Math.round(228 - wave_val * (228 - 39));\r\n          g = Math.round(228 - wave_val * (228 - 39));\r\n          b = Math.round(231 - wave_val * (231 - 42));\r\n        }\r\n        barsData[i].colors.push(`rgb(${r}, ${g}, ${b})`);\r\n      }\r\n    }\r\n    \r\n    return { bars: barsData, ballX: bX, ballY: bY, ballScaleX: bScaleX, ballScaleY: bScaleY, times: tArr };\r\n  }, [theme]);\r\n\r\n  return (\r\n    <div className=\"relative flex flex-col items-center justify-center w-full scale-[0.6] sm:scale-75 md:scale-100\">\r\n      <div className=\"relative flex items-end justify-start h-48 space-x-2 w-[292px]\">\r\n        {bars.map((bar, i) => (\r\n          <motion.div\r\n            key={i}\r\n            className=\"w-3 rounded-full origin-bottom\"\r\n            style={{ height: '16px', backgroundColor: theme === 'dark' ? 'rgb(39, 39, 42)' : 'rgb(228, 228, 231)' }}\r\n            animate={{\r\n              height: bar.heights,\r\n              backgroundColor: bar.colors,\r\n            }}\r\n            transition={{\r\n              duration: 4,\r\n              repeat: Infinity,\r\n              times: times,\r\n              ease: 'linear',\r\n            }}\r\n          />\r\n        ))}\r\n        \r\n        <motion.div\r\n          className=\"absolute w-3 h-3 bg-zinc-900 dark:bg-white rounded-full z-10 shadow-sm\"\r\n          style={{ bottom: 0, left: 0, transformOrigin: 'bottom center' }}\r\n          animate={{\r\n            x: ballX,\r\n            y: ballY,\r\n            scaleX: ballScaleX,\r\n            scaleY: ballScaleY,\r\n          }}\r\n          transition={{\r\n            duration: 4,\r\n            repeat: Infinity,\r\n            times: times,\r\n            ease: 'linear',\r\n          }}\r\n        />\r\n      </div>\r\n    </div>\r\n  );\r\n}\r\n"
    }
  ]
}