"use client"; interface Props { bucketLabels: string[]; shares: number[]; // длина = bucketLabels.length, сумма ≈ 100 recommended: number[]; // оригинальные share_pct из API onChange: (next: number[]) => void; onReset: () => void; } /** * Auto-rescale slider group. Когда пользователь двигает один слайдер до X%, * остальные пересчитываются пропорционально к (100 - X)%, сохраняя их * относительные доли. Если у других нет массы (sum=0) — распределяем поровну. */ export function RecommendShareSliders({ bucketLabels, shares, recommended, onChange, onReset, }: Props) { const handle = (idx: number, raw: number) => { const v = Math.max(0, Math.min(100, raw)); const next = [...shares]; next[idx] = v; const remaining = 100 - v; const others = shares.filter((_, i) => i !== idx); const otherSum = others.reduce((a, b) => a + b, 0); if (otherSum <= 0) { const each = remaining / others.length; for (let i = 0; i < next.length; i++) { if (i !== idx) next[i] = each; } } else { for (let i = 0; i < next.length; i++) { if (i !== idx) next[i] = (shares[i] * remaining) / otherSum; } } // round to 1 decimal, fix sum-rounding drift on the changed slider const rounded = next.map((x) => Math.round(x * 10) / 10); const drift = 100 - rounded.reduce((a, b) => a + b, 0); rounded[idx] = Math.round((rounded[idx] + drift) * 10) / 10; onChange(rounded); }; const dirty = shares.some( (s, i) => Math.abs(s - (recommended[i] ?? 0)) > 0.05, ); return (