{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "door-close-001",
  "type": "registry:block",
  "title": "Door Close 001",
  "author": "Kenney <https://kenney.nl>",
  "description": "A distinct sound of a door closing, suitable for signifying the completion of a process or a specific UI panel collapsing.",
  "files": [
    {
      "path": "registry/soundcn/sounds/door-close-001/door-close-001.ts",
      "content": "import type { SoundAsset } from \"@/lib/sound-types\";\n\nexport const doorClose001Sound: SoundAsset = {\n  name: \"door-close-001\",\n  dataUri: \"data:audio/mpeg;base64,SUQzBAAAAAAAIlRTU0UAAAAOAAADTGF2ZjYyLjMuMTAwAAAAAAAAAAAAAAD/+1DAAAAAAAAAAAAAAAAAAAAAAABJbmZvAAAADwAAABYAABLFABYWFhYhISEhISwsLCw3Nzc3N0JCQkJNTU1NTVhYWFhkZGRkZG9vb296enp6eoWFhYWQkJCQkJubm5ubpqamprKysrKyvb29vcjIyMjI09PT097e3t7e6enp6fT09PT0/////wAAAABMYXZjNjIuMTEAAAAAAAAAAAAAAAAkBbEAAAAAAAASxVwa9vIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//tQxAAACBA9DDSRgAGvn2w/ENBCAoEyeSAUCgUIECNGjRtznOaIiIiIgGLcHwfB8EAQBAEATB8HwfD7oIAhn8EHfwQ+J8EP///y5//6jgkOA/WCGQZGZGdWVUdUdo+/mDtkCbIBJgZgGTuZmXfsx6qMArJMJRJEBcPGpZp058vk5zUmmAnyy+7yeHMKaBDEzE5JyJu6DdSSDFLUZDgN0v/Ugggt9Zgj6vZnTUtlJ19Rv/3Ruo5/cXnLIamfU9X//Wq7bTWOSuNtABJ7SNhpyf/7UsQHAAvVkVm8k4AReTTrPMEeuLRNBAgXUnrDHEAJg6B6aaiPuNBozKUY9DyClC5G1UzzzlVGeYeeNzzHqcqT3s9+rnnqh5pppzOp7memjUVLM7Hn///qx////M/+//KG/+P/Tmz11dm0e7WyAAyFaCPiFEXR7Pzs7RGErW0av2DgmqYp569/omk7qhI4CqEfJV2rI4cDOcYd3Jr7MWQp3h21kvvVLnbIzp7fRIJSOhft9f///5yn/6P/w9P8fO/zBo+ImIeXRlttkkIHUwBQ//tSxAaAC0h5a+ewwdF6L6088YoyFAIjuVQ7RBKuMzQNUh4nLxLF5Z6MXV9rNr1GWTAYglTXrRzfueLPc9Iixoo8ewTvE6QW1pHn1hZrW4jLvL0sxKCwPtNWpFP/xH7PDXuiKlodGZZZI2yEGqKGqS0vaLL7GWjtgsioizrgWwhCFzRQEzBghV0KwIACQJhIVcwCHlwIEIBjGq+hHpIgS0o2vFWjUS/9FVCaJf60uQn/urMYxCf////6E/p/oN1+We/+3qbLfffbRAPgxDZYAEn/+1LECAAL2Y9l5gyzgYSzrHzzHfACUVAiSS4VIZDsQwZUdusXPuvHp+ghAAflkdDS76hwx3bax/JDQSGPL8oTveOUP+kRomVNPykOuq7q/qnRl6/K5Eb/9v/+v9f6gv6DuXB3ezKxniF31tjAOM6yZGKf6JdrbfEOVjzsqz+f6W9XNajzyZxqOb9ZndZkCzjkkrd9p7e7Zyq35XNoZZUVVdd7H6mHa5x1257vTtfrXT7c/19f////qae/mmN6h/4ob6Fn1t7O1GmXe63SMhPMDv/7UsQGAAuRm2XnhPmBfzLtPPQV+GbqIkLgbitXPhjfH0hTnFeZhy0rKzq9exvcv38ZpEeQ5I0a/WBAAMkRDWUcEBEwHsaAwd/M17Vbr7+bXu//T///8tf/Qz1IegGk/k/QcIthnv3NnceX+2+sALkvG+ujurY01WjxPAG0nRwpp+oqzxIYACnD1tYl7LOEWajWESGMaV7m01um1qXng16uGZLns1Ojkq907v3JTqlro7deSvp065/////+iv0L40N9X6i5av3bhrp3afWyMAnT//tSxAWAC42TZ+eEuUFQsS89gZZacoj4P40XFEJMUgYzMo4K/FjOVE4uWWLj2xHfxotrb/xAmf0nrXcZgCI0WZu01Sue2xQwLUe5ZFlv1tfyP+6/Kd//////9n0F+NARtQ8+QVzV9TLs8OzLbZJACqeEyyAIi0WAgIovKzp7tSWnbAwxordozer5TEsicSdn0IPKryV5UhLTlRqbvk22ppt6ZPSr2+9qV90rfsv/////////+i9OF8bhGoh2ZmRTP//AhdiYbqqkYixsVBzyw0T/+1LECwBKRYNtzISx2T6w7j2RlfMj1l2krEwrVqo7cNPy7QiIBhAIRIZNiK0SCUQSIzkOU1UGqvMvwfT+H6L8n7t//////////+h3q9g3VxDLOrMqoZySRU7uSlRw3rjHfZrWZW5jN1iwzK45GX+pqMDBHdDOkWsFtqo/yKWiBSNzdXOExZcVc6LuQ3//pf/b23p///////////56PB43God1VlVESSSSABmzDAaaFegEcu59Iy+UXiTIwCNLBBQUf6W22p9Tl7zazHe7lehdXv/7UsQYAAo5g3PsmEtZP7AufbYU466addOuqsSiOlHTbRtkTZ72tTm0a5v//////////9KQip6RWVmVkSSySMAywlOROlLXUhxmrSHLJJZAw0AVEJZVuvMi6yTxuUl12aV6WqrjDMY6ucq3mel6afp39b5q+lOyfb1////6///////9JwnM3a9LZrJJLJAAaJnA8O0sOLmjUaf6W6lVNTWrVWGQICFHVVV6qqXGVfjM3xmP6sbqqq+qr0kvU/39FH0f/pep/U///////////+it//tSxCUACdGDaawNr5mpMO908wqy1ixFIKe2233////ALanBQmYbqOSKWYVStvVXVzVEY6O/gXTlU41yLiK2PThIcDHJIjzR+LQ0n0zHIOYXJklTRa3RqU5TzUOTizOY8FSZLTRa2nZTlONT6cWZzHcyTJY3S1V///////////0qwEHd0ltstltttABdGgewOFl0lvkYroqIka+OcXc8vjuw7x90IY4rlBDbdBJHOlYlrlker1tnY3bl9Iaa5eRL8zcs579PMnplDX//////////+1LEJoAKUYV5pgxT0USwr/zwiqv//yIoyKl2ZmZlVZXbWAQ9j2N0M0BhDTUalUicSqtWVc0Q2aPLR5atpNYpuehZXNyAa4yAfM2Z2VTZOPMRdEhSRrJdDqdP/////////////1VLwxKdZyKnRWZUVEjkkjAMng7+WuO5PSKm+L2KaYYOKM7rI2gcdZG2V/kJVpKGocoFGJmWqQTTst60L/6JxNOyaFSC0+1AuMm6CY5RxE8kzet0HVT3/0DVJV+n//6KX///1N///9E2bZp3uf/7UsQygAwxlX/siauRXzKu/JCfmJhUsfZTAA2G6OGiJEjYIGB+jCzSAn0pC98JPz+ve1tx+7Dt5GOf2FRoxVUlJWlZI0cpS+8T//4xkJ80ICX/82tyeSnZRGi4+KiX///1G7f///UCJOqIZ1RVRE++sBFFgdCK4lAEJ4cksWQCyARvjdZeYh0o21OPKYSN/qUIjR6NXXedHIR89DlZr/zuz//Mqu/6xMzps9jnS1ttvcv///9f///+D7W5GU7Ktqcb4DhlCJAaDSQgdAoQlkJq//tSxDOACf2VgcYYpdFisq98kZ2ogKIGFE/COpcicM7Os7l/6jwOgkan9pnomt6L0MY2zevv10PTzTiTMVQ0eVJt2PY8oQcw84qPR83///+hD////USqmoiYiGRJZJG0BMZiQqkiQ1RaTnP/DzezDdmlPNActtRMwNn3yijSsHUjZLr3OZ+1sdfVTfSABonWqN19f+yO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\",\n  duration: 0.529,\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.529,
    "format": "mp3",
    "sizeKb": 5,
    "license": "CC0",
    "tags": [
      "door",
      "close",
      "001"
    ],
    "keywords": [
      "door",
      "close",
      "distinct",
      "ui",
      "panel close",
      "completion",
      "process end",
      "confirmation",
      "collapse",
      "transition",
      "feedback",
      "general",
      "soft",
      "click",
      "sound",
      "portal",
      "exit",
      "end",
      "action"
    ]
  },
  "categories": [
    "door"
  ]
}