{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "param-sandbox",
  "type": "registry:ui",
  "title": "ParamSandbox",
  "description": "Interactive slider sandbox for mathematical formulas and live reactive system calculations.",
  "registryDependencies": [
    "https://ui.arpitbhayani.me/r/aui.json"
  ],
  "files": [
    {
      "path": "ui/param-sandbox.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nexport interface SandboxInput {\n  id: string;\n  label: string;\n  min: number;\n  max: number;\n  step?: number;\n  unit?: string;\n  defaultValue?: number;\n}\n\nexport interface SandboxOutput {\n  label: string;\n  compute?: ((vals: Record<string, number>) => string | number) | null;\n  value?: string | number;\n}\n\nexport interface ParamSandboxProps extends React.HTMLAttributes<HTMLDivElement> {\n  formula: string;\n  inputs: SandboxInput[];\n  outputs: SandboxOutput[];\n}\n\nexport function ParamSandbox({\n  formula,\n  inputs = [],\n  outputs = [],\n  className,\n  ...props\n}: ParamSandboxProps) {\n  const initialVals: Record<string, number> = {};\n  (inputs || []).forEach((inp) => {\n    initialVals[inp.id] = inp.defaultValue ?? inp.min;\n  });\n\n  const [values, setValues] = React.useState<Record<string, number>>(initialVals);\n\n  const handleChange = (id: string, val: number) => {\n    setValues((prev) => ({ ...prev, [id]: val }));\n  };\n\n  const getOutputValue = (out: SandboxOutput) => {\n    if (typeof out.compute === \"function\") {\n      try {\n        return out.compute(values);\n      } catch {\n        return \"—\";\n      }\n    }\n    const nodes = values[\"nodes\"] ?? Object.values(values)[0] ?? 5;\n    if (out.label.toLowerCase().includes(\"quorum\")) {\n      return Math.floor(nodes / 2) + 1;\n    }\n    if (out.label.toLowerCase().includes(\"failure\") || out.label.toLowerCase().includes(\"tolerable\")) {\n      return Math.floor((nodes - 1) / 2);\n    }\n    if (out.value !== undefined) {\n      return out.value;\n    }\n    return \"—\";\n  };\n\n  return (\n    <div\n      className={cn(\n        \"rounded-lg border border-border bg-card overflow-hidden my-4 shadow-xs\",\n        className\n      )}\n      {...props}\n    >\n      <div className=\"flex items-center gap-2.5 px-4 py-2.5 border-b border-border bg-muted/30\">\n        <span className=\"font-mono text-xs uppercase font-medium text-muted-foreground\">\n          Formula:\n        </span>\n        <code className=\"font-mono text-xs font-medium text-foreground\">\n          {formula}\n        </code>\n      </div>\n\n      <div className=\"grid grid-cols-1 md:grid-cols-2 gap-5 p-5\">\n        <div className=\"space-y-4\">\n          {(inputs || []).map((inp) => (\n            <div key={inp.id} className=\"space-y-1.5\">\n              <div className=\"flex items-center justify-between text-xs\">\n                <span className=\"font-mono font-medium text-foreground\">\n                  {inp.label}\n                </span>\n                <span className=\"font-mono font-medium text-primary\">\n                  {values[inp.id] ?? inp.defaultValue ?? inp.min} {inp.unit ?? \"\"}\n                </span>\n              </div>\n              <input\n                type=\"range\"\n                min={inp.min}\n                max={inp.max}\n                step={inp.step ?? 1}\n                value={values[inp.id] ?? inp.defaultValue ?? inp.min}\n                className=\"w-full accent-primary cursor-pointer\"\n                onChange={(e) =>\n                  handleChange(inp.id, parseFloat(e.target.value))\n                }\n              />\n            </div>\n          ))}\n        </div>\n\n        <div className=\"flex flex-col justify-center gap-3\">\n          {(outputs || []).map((out, idx) => (\n            <div\n              key={idx}\n              className=\"flex items-center justify-between p-3.5 rounded-md border border-border bg-muted/20\"\n            >\n              <span className=\"font-mono text-xs text-muted-foreground\">\n                {out.label}\n              </span>\n              <span className=\"font-mono text-base font-medium text-foreground\">\n                {getOutputValue(out)}\n              </span>\n            </div>\n          ))}\n        </div>\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:ui"
    }
  ]
}