{"version":3,"sources":["../src/components/MoodMeter/MoodMeter.tsx"],"names":["useRef","useState","useCallback","jsxs","jsx","Fragment"],"mappings":"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","file":"chunk-I6L7OP7G.cjs","sourcesContent":["import { useCallback, useRef, useState } from \"react\";\n\n/**\n * MoodMeter — a 2D draggable pad that captures a value AND the\n * confidence in that value on the same handle.\n *\n *   <MoodMeter\n *     min={0} max={1}\n *     value={value} confidence={confidence}\n *     onChange={(v, c) => { setValue(v); setConfidence(c); }}\n *   />\n *\n *   • x-axis maps to [min..max]\n *   • y-axis maps to [0..1] confidence (top = sure)\n *   • the halo around the handle scales inversely with confidence —\n *     uncertain readings literally look fuzzier\n *\n * Why pair them in one control? When AIs post a number, humans\n * immediately ask \"how sure are you?\". Making confidence an explicit\n * sibling of value — and letting the user drag either independently —\n * turns vague \"AI suggestion\" UX into something you can argue with\n * precisely.\n *\n * The agent's posted value/confidence renders as a dashed ghost\n * handle alongside the live user handle, so the human can see where\n * the agent landed and how far they've drifted.\n */\nexport interface MoodMeterProps {\n  /** Range minimum. */\n  min: number;\n  /** Range maximum. */\n  max: number;\n  /** Step for value snapping. Defaults to (max-min)/100. */\n  step?: number;\n  /** Current value (controlled). */\n  value: number;\n  /** Current confidence 0..1 (controlled). */\n  confidence: number;\n  /** Called with (value, confidence) on drag / pointer events. */\n  onChange: (value: number, confidence: number) => void;\n  /** Optional agent post — renders as a dashed ghost handle. */\n  posted?: { value: number; confidence: number };\n  /** Pixel width of the pad. Defaults to 320. */\n  width?: number;\n  /** Pixel height of the pad. Defaults to 220. */\n  height?: number;\n  /** Show the grid + axis labels. Defaults to true. */\n  showGrid?: boolean;\n  /** Color of the user handle. Defaults to sky blue. */\n  color?: string;\n  /** Color of the posted-ghost handle. Defaults to violet. */\n  postedColor?: string;\n  /** Optional prefix for the value label (e.g. \"$\"). */\n  prefix?: string;\n  /** Optional suffix for the value label (e.g. \"k\", \"%\"). */\n  suffix?: string;\n  /** Optional label text override. Falls back to formatted value. */\n  formatValue?: (v: number) => string;\n  /** Optional className applied to the outer pad. */\n  className?: string;\n}\n\nexport function MoodMeter({\n  min,\n  max,\n  step,\n  value,\n  confidence,\n  onChange,\n  posted,\n  width = 320,\n  height = 220,\n  showGrid = true,\n  color = \"#0ea5e9\",\n  postedColor = \"#a855f7\",\n  prefix = \"\",\n  suffix = \"\",\n  formatValue,\n  className,\n}: MoodMeterProps) {\n  const ref = useRef<HTMLDivElement>(null);\n  const [dragging, setDragging] = useState(false);\n\n  const snapStep = step ?? (max - min) / 100;\n\n  const fmt = useCallback(\n    (v: number) => {\n      if (formatValue) return formatValue(v);\n      const num = snapStep < 1 ? v.toFixed(2) : Math.round(v).toString();\n      return `${prefix}${num}${suffix}`;\n    },\n    [formatValue, snapStep, prefix, suffix],\n  );\n\n  const set = useCallback(\n    (clientX: number, clientY: number) => {\n      const el = ref.current;\n      if (!el) return;\n      const rect = el.getBoundingClientRect();\n      const x = clamp((clientX - rect.left) / rect.width, 0, 1);\n      const y = clamp((clientY - rect.top) / rect.height, 0, 1);\n      const raw = min + x * (max - min);\n      const snapped = round(raw, snapStep, min);\n      const c = clamp(1 - y, 0, 1);\n      onChange(snapped, Math.round(c * 100) / 100);\n    },\n    [min, max, snapStep, onChange],\n  );\n\n  const onPointerDown = (e: React.PointerEvent<HTMLDivElement>) => {\n    (e.target as Element).setPointerCapture?.(e.pointerId);\n    setDragging(true);\n    set(e.clientX, e.clientY);\n  };\n  const onPointerMove = (e: React.PointerEvent<HTMLDivElement>) => {\n    if (!dragging) return;\n    set(e.clientX, e.clientY);\n  };\n  const onPointerUp = () => setDragging(false);\n\n  const xPct = ((value - min) / (max - min)) * 100;\n  const yPct = (1 - confidence) * 100;\n  const haloR = 18 + (1 - confidence) * 70;\n\n  const pxPct = posted ? ((posted.value - min) / (max - min)) * 100 : 0;\n  const pyPct = posted ? (1 - posted.confidence) * 100 : 0;\n  const pHaloR = posted ? 16 + (1 - posted.confidence) * 60 : 0;\n\n  return (\n    <div\n      ref={ref}\n      onPointerDown={onPointerDown}\n      onPointerMove={onPointerMove}\n      onPointerUp={onPointerUp}\n      onPointerCancel={onPointerUp}\n      className={`relative cursor-crosshair touch-none select-none overflow-hidden rounded-md border border-zinc-200 bg-zinc-50 dark:border-zinc-800 dark:bg-zinc-950 ${className ?? \"\"}`}\n      style={{ width, height }}\n    >\n      {showGrid && (\n        <svg className=\"pointer-events-none absolute inset-0 h-full w-full\" aria-hidden>\n          {[0.25, 0.5, 0.75].map((p, i) => (\n            <line\n              key={`v${i}`}\n              x1={`${p * 100}%`}\n              x2={`${p * 100}%`}\n              y1=\"0\"\n              y2=\"100%\"\n              stroke=\"#a1a1aa\"\n              strokeOpacity={0.18}\n              strokeDasharray=\"3 4\"\n            />\n          ))}\n          {[0.25, 0.5, 0.75].map((p, i) => (\n            <line\n              key={`h${i}`}\n              x1=\"0\"\n              x2=\"100%\"\n              y1={`${p * 100}%`}\n              y2={`${p * 100}%`}\n              stroke=\"#a1a1aa\"\n              strokeOpacity={0.18}\n              strokeDasharray=\"3 4\"\n            />\n          ))}\n        </svg>\n      )}\n\n      {showGrid && (\n        <>\n          <div className=\"pointer-events-none absolute left-1.5 top-1.5 text-[10px] uppercase tracking-wider text-zinc-400\">\n            ↑ sure\n          </div>\n          <div className=\"pointer-events-none absolute bottom-1.5 left-1.5 text-[10px] uppercase tracking-wider text-zinc-400\">\n            ↓ unsure\n          </div>\n          <div className=\"pointer-events-none absolute right-1.5 top-1.5 text-[10px] uppercase tracking-wider text-zinc-400\">\n            {fmt(max)} →\n          </div>\n          <div className=\"pointer-events-none absolute bottom-1.5 right-1.5 text-[10px] uppercase tracking-wider text-zinc-400\">\n            ← {fmt(min)}\n          </div>\n        </>\n      )}\n\n      {posted && (\n        <Handle\n          xPct={pxPct}\n          yPct={pyPct}\n          haloR={pHaloR}\n          color={postedColor}\n          dashed\n          label=\"agent\"\n        />\n      )}\n      <Handle\n        xPct={xPct}\n        yPct={yPct}\n        haloR={haloR}\n        color={color}\n        label={fmt(value)}\n      />\n    </div>\n  );\n}\n\nfunction Handle({\n  xPct,\n  yPct,\n  haloR,\n  color,\n  dashed = false,\n  label,\n}: {\n  xPct: number;\n  yPct: number;\n  haloR: number;\n  color: string;\n  dashed?: boolean;\n  label: string;\n}) {\n  return (\n    <>\n      <div\n        className=\"pointer-events-none absolute -translate-x-1/2 -translate-y-1/2 rounded-full\"\n        style={{\n          left: `${xPct}%`,\n          top: `${yPct}%`,\n          width: haloR * 2,\n          height: haloR * 2,\n          background: color + (dashed ? \"11\" : \"22\"),\n          border: dashed ? `1px dashed ${color}` : \"none\",\n        }}\n      />\n      <div\n        className=\"pointer-events-none absolute -translate-x-1/2 -translate-y-1/2 rounded-full ring-2 ring-white dark:ring-zinc-900\"\n        style={{\n          left: `${xPct}%`,\n          top: `${yPct}%`,\n          width: 14,\n          height: 14,\n          background: color,\n          opacity: dashed ? 0.6 : 1,\n        }}\n      />\n      <div\n        className=\"pointer-events-none absolute -translate-x-1/2 rounded px-1.5 py-0.5 font-mono text-[10px]\"\n        style={{\n          left: `${xPct}%`,\n          top: `calc(${yPct}% + 14px)`,\n          color,\n        }}\n      >\n        {label}\n      </div>\n    </>\n  );\n}\n\nfunction clamp(n: number, lo: number, hi: number) {\n  return Math.max(lo, Math.min(hi, n));\n}\n\nfunction round(n: number, step: number, min: number) {\n  if (step >= 1) return Math.round(n);\n  return Math.round((n - min) / step) * step + min;\n}\n"]}