{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "chips-handle-2",
  "type": "registry:block",
  "title": "Chips Handle 2",
  "author": "Kenney <https://kenney.nl>",
  "description": "A moderately extended sound of chips being handled, good for feedback during a drag-and-drop operation involving multiple items or a brief shuffling animation.",
  "files": [
    {
      "path": "registry/soundcn/sounds/chips-handle-2/chips-handle-2.ts",
      "content": "import type { SoundAsset } from \"@/lib/sound-types\";\n\nexport const chipsHandle2Sound: SoundAsset = {\n  name: \"chips-handle-2\",\n  dataUri: \"data:audio/mpeg;base64,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\",\n  duration: 0.546,\n  format: \"mp3\",\n  license: \"CC0\",\n  author: \"Kenney\",\n};\n",
      "type": "registry:lib"
    },
    {
      "path": "registry/soundcn/lib/sound-types.ts",
      "content": "export interface SoundAsset {\r\n  /** Unique identifier for the sound */\r\n  name: string;\r\n  /** Base64-encoded data URI (data:audio/mpeg;base64,...) */\r\n  dataUri: string;\r\n  /** Duration in seconds */\r\n  duration: number;\r\n  /** Audio format */\r\n  format: \"mp3\" | \"wav\" | \"ogg\";\r\n  /** License identifier */\r\n  license: \"CC0\" | \"OGA-BY\" | \"MIT\";\r\n  /** Original author/creator */\r\n  author: string;\r\n}\r\n\r\nexport interface UseSoundOptions {\r\n  /** Volume level from 0 to 1. Default: 1 */\r\n  volume?: number;\r\n  /** Playback speed multiplier. Default: 1 */\r\n  playbackRate?: number;\r\n  /** If true, calling play() stops current playback first. Default: false */\r\n  interrupt?: boolean;\r\n  /** If false, play() does nothing. Useful for user preferences. Default: true */\r\n  soundEnabled?: boolean;\r\n  /** Called when playback starts */\r\n  onPlay?: () => void;\r\n  /** Called when playback ends naturally */\r\n  onEnd?: () => void;\r\n  /** Called when pause() is called */\r\n  onPause?: () => void;\r\n  /** Called when stop() is called */\r\n  onStop?: () => void;\r\n}\r\n\r\nexport type PlayFunction = (overrides?: {\r\n  volume?: number;\r\n  playbackRate?: number;\r\n}) => void;\r\n\r\nexport interface SoundControls {\r\n  stop: () => void;\r\n  pause: () => void;\r\n  isPlaying: boolean;\r\n  duration: number | null;\r\n  sound: SoundAsset;\r\n}\r\n\r\nexport type UseSoundReturn = readonly [PlayFunction, SoundControls];\r\n",
      "type": "registry:lib"
    },
    {
      "path": "registry/soundcn/lib/sound-engine.ts",
      "content": "let audioContext: AudioContext | null = null;\nconst bufferCache = new Map<string, AudioBuffer>();\n\nexport function getAudioContext(): AudioContext {\n  if (!audioContext) {\n    audioContext = new AudioContext();\n  }\n  return audioContext;\n}\n\nexport async function decodeAudioData(dataUri: string): Promise<AudioBuffer> {\n  const cached = bufferCache.get(dataUri);\n  if (cached) return cached;\n\n  const ctx = getAudioContext();\n  const base64 = dataUri.split(\",\")[1];\n  const binaryString = atob(base64);\n  const bytes = new Uint8Array(binaryString.length);\n  for (let i = 0; i < binaryString.length; i++) {\n    bytes[i] = binaryString.charCodeAt(i);\n  }\n\n  const audioBuffer = await ctx.decodeAudioData(bytes.buffer.slice(0));\n  bufferCache.set(dataUri, audioBuffer);\n  return audioBuffer;\n}\n\nexport interface PlaySoundOptions {\n  volume?: number;\n  playbackRate?: number;\n  onEnd?: () => void;\n}\n\nexport interface SoundPlayback {\n  stop: () => void;\n}\n\nexport async function playSound(\n  dataUri: string,\n  options: PlaySoundOptions = {}\n): Promise<SoundPlayback> {\n  const { volume = 1, playbackRate = 1, onEnd } = options;\n  const ctx = getAudioContext();\n  if (ctx.state === \"suspended\") {\n    await ctx.resume();\n  }\n\n  const buffer = await decodeAudioData(dataUri);\n  const source = ctx.createBufferSource();\n  const gain = ctx.createGain();\n\n  source.buffer = buffer;\n  source.playbackRate.value = playbackRate;\n  gain.gain.value = volume;\n\n  source.connect(gain);\n  gain.connect(ctx.destination);\n\n  source.onended = () => {\n    onEnd?.();\n  };\n\n  source.start(0);\n\n  return {\n    stop: () => {\n      try {\n        source.stop();\n      } catch {\n        // No-op if already stopped.\n      }\n    },\n  };\n}\n",
      "type": "registry:lib"
    }
  ],
  "meta": {
    "duration": 0.546,
    "format": "mp3",
    "sizeKb": 5,
    "license": "CC0",
    "tags": [
      "chips",
      "handle",
      "2"
    ],
    "keywords": [
      "drag and drop",
      "multi-item",
      "shuffling",
      "ui interaction",
      "game ui",
      "handling",
      "tactile",
      "game",
      "tokens",
      "pieces",
      "inventory",
      "movement",
      "organize",
      "process",
      "dynamic",
      "realistic",
      "feedback",
      "animate",
      "manage",
      "medium"
    ]
  },
  "categories": [
    "chips"
  ]
}