{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "clock-widget",
  "title": "Clock Widgets",
  "description": "Clock widgets including analog, digital, world clock, stopwatch, and timer with liquid glass styling.",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "https://ui.eindev.ir/r/base-widget.json"
  ],
  "files": [
    {
      "path": "registry/widgets/clock-widget.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"@/lib/utils\";\nimport { Sun, Moon, Play, Pause, RotateCcw } from \"lucide-react\";\nimport { GlassWidgetBase } from \"./base-widget\";\n\ninterface AnalogClockWidgetProps {\n  time?: Date;\n  showNumbers?: boolean;\n  size?: \"sm\" | \"md\" | \"lg\";\n  className?: string;\n}\n\nfunction AnalogClockWidget({\n  time,\n  showNumbers = true,\n  size = \"md\",\n  className,\n}: AnalogClockWidgetProps) {\n  const [currentTime, setCurrentTime] = React.useState<Date | undefined>(time);\n\n  React.useLayoutEffect(() => {\n    if (time) {\n      // eslint-disable-next-line react-hooks/set-state-in-effect\n      setCurrentTime(time);\n      return;\n    }\n     \n    setCurrentTime(new Date());\n    const interval = setInterval(() => {\n       \n      setCurrentTime(new Date());\n    }, 1000);\n    return () => clearInterval(interval);\n  }, [time]);\n\n  if (!currentTime) return null;\n\n  const seconds = currentTime.getSeconds();\n  const minutes = currentTime.getMinutes();\n  const hours = currentTime.getHours() % 12;\n\n  const secondDegrees = seconds * 6;\n  const minuteDegrees = minutes * 6 + seconds * 0.1;\n  const hourDegrees = hours * 30 + minutes * 0.5;\n\n  const sizeConfig = {\n    sm: { container: \"size-24\", numbers: \"text-[10px]\", radius: 36 },\n    md: { container: \"size-32\", numbers: \"text-xs\", radius: 42 },\n    lg: { container: \"size-36\", numbers: \"text-sm\", radius: 42 },\n  };\n\n  const config = sizeConfig[size];\n  const numbers = showNumbers ? [12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] : [];\n\n  return (\n    <GlassWidgetBase className={cn(\"p-3 w-full h-full flex items-center justify-center\", className)} size=\"sm\" glowColor=\"blue\">\n      <div className={cn(\"relative\", config.container)}>\n        {/* Clock face with glass effect */}\n        <div className=\"absolute inset-0 rounded-full border border-white/20  bg-white/5 backdrop-blur-sm shadow-inner\" />\n\n        {numbers.map((num, i) => {\n          const angle = (i * 30 - 90) * (Math.PI / 180);\n          const x = 50 + config.radius * Math.cos(angle);\n          const y = 50 + config.radius * Math.sin(angle);\n          return (\n            <span\n              key={num}\n              className={cn(\"absolute text-white/70 font-light\", config.numbers)}\n              style={{\n                left: `${x}%`,\n                top: `${y}%`,\n                transform: \"translate(-50%, -50%)\",\n              }}\n            >\n              {num}\n            </span>\n          );\n        })}\n\n        {!showNumbers &&\n          Array.from({ length: 12 }).map((_, i) => {\n            const angle = (i * 30 - 90) * (Math.PI / 180);\n            return (\n              <div\n                key={i}\n                className=\"absolute size-1.5 rounded-full bg-white/40\"\n                style={{\n                  left: `${50 + config.radius * Math.cos(angle)}%`,\n                  top: `${50 + config.radius * Math.sin(angle)}%`,\n                  transform: \"translate(-50%, -50%)\",\n                }}\n              />\n            );\n          })}\n\n        {/* Center dot */}\n        <div className=\"absolute left-1/2 top-1/2 w-2.5 h-2.5 -translate-x-1/2 -translate-y-1/2 rounded-full bg-white/90 z-20 shadow-lg\" />\n\n        {/* Hour hand */}\n        <div\n          className=\"absolute left-1/2 top-1/2 w-1 rounded-full bg-white/90 origin-bottom shadow-md\"\n          style={{\n            height: size === \"lg\" ? \"28px\" : size === \"md\" ? \"22px\" : \"18px\",\n            transform: `translateX(-50%) translateY(-100%) rotate(${hourDegrees}deg)`,\n          }}\n        />\n\n        {/* Minute hand */}\n        <div\n          className=\"absolute left-1/2 top-1/2 w-0.5 rounded-full bg-white/80 origin-bottom shadow-sm\"\n          style={{\n            height: size === \"lg\" ? \"36px\" : size === \"md\" ? \"28px\" : \"22px\",\n            transform: `translateX(-50%) translateY(-100%) rotate(${minuteDegrees}deg)`,\n          }}\n        />\n\n        {/* Second hand */}\n        <div\n          className=\"absolute left-1/2 top-1/2 w-px bg-cyan-400 origin-bottom\"\n          style={{\n            height: size === \"lg\" ? \"40px\" : size === \"md\" ? \"32px\" : \"26px\",\n            transform: `translateX(-50%) translateY(-100%) rotate(${secondDegrees}deg)`,\n          }}\n        />\n      </div>\n    </GlassWidgetBase>\n  );\n}\n\ninterface DigitalClockWidgetProps {\n  time?: Date;\n  showSeconds?: boolean;\n  format?: \"12h\" | \"24h\";\n  className?: string;\n}\n\nfunction DigitalClockWidget({\n  time,\n  showSeconds = true,\n  format = \"12h\",\n  className,\n}: DigitalClockWidgetProps) {\n  const [currentTime, setCurrentTime] = React.useState<Date | undefined>(time);\n\n  React.useLayoutEffect(() => {\n    if (time) {\n      // eslint-disable-next-line react-hooks/set-state-in-effect\n      setCurrentTime(time);\n      return;\n    }\n     \n    setCurrentTime(new Date());\n    const interval = setInterval(() => {\n       \n      setCurrentTime(new Date());\n    }, 1000);\n    return () => clearInterval(interval);\n  }, [time]);\n\n  if (!currentTime) return null;\n\n  const hours = currentTime.getHours();\n  const minutes = currentTime.getMinutes();\n  const seconds = currentTime.getSeconds();\n\n  const displayHours = format === \"12h\" ? hours % 12 || 12 : hours;\n  const period = hours >= 12 ? \"PM\" : \"AM\";\n\n  return (\n    <GlassWidgetBase\n      className={cn(\"w-full min-w-0\", className)}\n      glowColor=\"cyan\"\n    >\n      <div className=\"flex flex-col items-center justify-center h-full\">\n        <div className=\"flex items-baseline gap-1\">\n          <span className=\"text-4xl font-light text-white tabular-nums\">\n            {displayHours.toString().padStart(2, \"0\")}:{minutes.toString().padStart(2, \"0\")}\n          </span>\n          {showSeconds && (\n            <span className=\"text-xl text-white/60 tabular-nums\">\n              :{seconds.toString().padStart(2, \"0\")}\n            </span>\n          )}\n          {format === \"12h\" && <span className=\"text-sm text-white/50 ml-1\">{period}</span>}\n        </div>\n      </div>\n    </GlassWidgetBase>\n  );\n}\n\ninterface WorldClockWidgetProps {\n  clocks: Array<{\n    city: string;\n    timezone: string;\n    isDay?: boolean;\n  }>;\n  className?: string;\n}\n\nfunction WorldClockWidget({ clocks, className }: WorldClockWidgetProps) {\n  const [times, setTimes] = React.useState<string[]>([]);\n\n  React.useEffect(() => {\n    const updateTimes = () => {\n      const newTimes = clocks.map((clock) => {\n        try {\n          return new Date().toLocaleTimeString(\"en-US\", {\n            timeZone: clock.timezone,\n            hour: \"numeric\",\n            minute: \"2-digit\",\n            hour12: true,\n          });\n        } catch {\n          return \"--:--\";\n        }\n      });\n      setTimes(newTimes);\n    };\n    updateTimes();\n    const interval = setInterval(updateTimes, 1000);\n    return () => clearInterval(interval);\n  }, [clocks]);\n\n  return (\n    <GlassWidgetBase className={cn(\"min-w-45\", className)} glowColor=\"blue\">\n      <div className=\"space-y-3\">\n        {clocks.map((clock, i) => (\n          <div key={i} className=\"flex items-center justify-between\">\n            <div className=\"flex items-center gap-2\">\n              <span className=\"text-white font-medium\">{clock.city}</span>\n              {clock.isDay !== undefined &&\n                (clock.isDay ? (\n                  <Sun className=\"w-4 h-4 text-amber-400\" />\n                ) : (\n                  <Moon className=\"w-4 h-4 text-blue-300\" />\n                ))}\n            </div>\n            <span className=\"text-white/80 text-lg tabular-nums\">{times[i] || \"--:--\"}</span>\n          </div>\n        ))}\n      </div>\n    </GlassWidgetBase>\n  );\n}\n\ninterface StopwatchWidgetProps {\n  className?: string;\n}\n\nfunction StopwatchWidget({ className }: StopwatchWidgetProps) {\n  const [time, setTime] = React.useState(0);\n  const [isRunning, setIsRunning] = React.useState(false);\n\n  React.useEffect(() => {\n    let interval: NodeJS.Timeout;\n    if (isRunning) {\n      interval = setInterval(() => setTime((t) => t + 10), 10);\n    }\n    return () => clearInterval(interval);\n  }, [isRunning]);\n\n  const formatTime = (ms: number) => {\n    const minutes = Math.floor(ms / 60000);\n    const seconds = Math.floor((ms % 60000) / 1000);\n    const centiseconds = Math.floor((ms % 1000) / 10);\n    return `${minutes.toString().padStart(2, \"0\")}:${seconds\n      .toString()\n      .padStart(2, \"0\")}.${centiseconds.toString().padStart(2, \"0\")}`;\n  };\n\n  const reset = () => {\n    setIsRunning(false);\n    setTime(0);\n  };\n\n  return (\n    <GlassWidgetBase className={cn(className)} glowColor=\"cyan\">\n      <div className=\"text-3xl font-light text-white text-center mb-4 tabular-nums\">\n        {formatTime(time)}\n      </div>\n      <div className=\"flex items-center justify-center gap-3\">\n        <button\n          onClick={reset}\n          className=\"p-2.5 rounded-full bg-white/10 hover:bg-white/20 text-white/60 hover:text-white transition-colors\"\n          aria-label=\"Reset\"\n        >\n          <RotateCcw className=\"w-4 h-4\" />\n        </button>\n        <button\n          onClick={() => setIsRunning(!isRunning)}\n          className={cn(\n            \"p-3 rounded-full transition-colors\",\n            isRunning\n              ? \"bg-red-500/20 hover:bg-red-500/30 text-red-400\"\n              : \"bg-emerald-500/20 hover:bg-emerald-500/30 text-emerald-400\"\n          )}\n          aria-label={isRunning ? \"Pause\" : \"Start\"}\n        >\n          {isRunning ? <Pause className=\"w-5 h-5\" /> : <Play className=\"w-5 h-5 ml-0.5\" />}\n        </button>\n      </div>\n    </GlassWidgetBase>\n  );\n}\n\ninterface TimerWidgetProps {\n  initialMinutes?: number;\n  className?: string;\n}\n\nfunction TimerWidget({ initialMinutes = 5, className }: TimerWidgetProps) {\n  const [timeLeft, setTimeLeft] = React.useState(initialMinutes * 60 * 1000);\n  const [isRunning, setIsRunning] = React.useState(false);\n  const [initialTime] = React.useState(initialMinutes * 60 * 1000);\n\n  React.useEffect(() => {\n    let interval: NodeJS.Timeout;\n    if (isRunning && timeLeft > 0) {\n      interval = setInterval(() => setTimeLeft((t) => Math.max(0, t - 1000)), 1000);\n    }\n    return () => clearInterval(interval);\n  }, [isRunning, timeLeft]);\n\n  const formatTime = (ms: number) => {\n    const minutes = Math.floor(ms / 60000);\n    const seconds = Math.floor((ms % 60000) / 1000);\n    return `${minutes.toString().padStart(2, \"0\")}:${seconds.toString().padStart(2, \"0\")}`;\n  };\n\n  const reset = () => {\n    setIsRunning(false);\n    setTimeLeft(initialTime);\n  };\n\n  const progress = (timeLeft / initialTime) * 100;\n\n  return (\n    <GlassWidgetBase\n      className={cn(\"min-w-40\", className)}\n      glowColor={timeLeft === 0 ? \"red\" : \"green\"}\n    >\n      <div className=\"relative flex items-center justify-center mb-4 p-2\">\n        <svg className=\"w-24 h-24 -rotate-90\" viewBox=\"0 0 96 96\">\n          <circle\n            cx=\"48\"\n            cy=\"48\"\n            r=\"42\"\n            stroke=\"rgba(255,255,255,0.1)\"\n            strokeWidth=\"4\"\n            fill=\"none\"\n          />\n          <circle\n            cx=\"48\"\n            cy=\"48\"\n            r=\"42\"\n            stroke={timeLeft === 0 ? \"#ef4444\" : \"#22c55e\"}\n            strokeWidth=\"4\"\n            fill=\"none\"\n            strokeLinecap=\"round\"\n            strokeDasharray={263.89}\n            strokeDashoffset={263.89 * (1 - progress / 100)}\n            className=\"transition-all duration-1000\"\n          />\n        </svg>\n        <div className=\"absolute text-2xl font-light text-white tabular-nums\">\n          {formatTime(timeLeft)}\n        </div>\n      </div>\n      <div className=\"flex items-center justify-center gap-3\">\n        <button\n          onClick={reset}\n          className=\"p-2.5 rounded-full bg-white/10 hover:bg-white/20 text-white/60 hover:text-white transition-colors\"\n          aria-label=\"Reset\"\n        >\n          <RotateCcw className=\"w-4 h-4\" />\n        </button>\n        <button\n          onClick={() => setIsRunning(!isRunning)}\n          className={cn(\n            \"p-3 rounded-full transition-colors\",\n            isRunning\n              ? \"bg-red-500/20 hover:bg-red-500/30 text-red-400\"\n              : \"bg-emerald-500/20 hover:bg-emerald-500/30 text-emerald-400\"\n          )}\n          aria-label={isRunning ? \"Pause\" : \"Start\"}\n        >\n          {isRunning ? <Pause className=\"w-5 h-5\" /> : <Play className=\"w-5 h-5 ml-0.5\" />}\n        </button>\n      </div>\n    </GlassWidgetBase>\n  );\n}\n\nexport { AnalogClockWidget, DigitalClockWidget, WorldClockWidget, StopwatchWidget, TimerWidget };\n",
      "type": "registry:component"
    }
  ],
  "type": "registry:component"
}