/* ClinicFlow AI — shared components. Exports to window. */

const { useState, useEffect, useMemo, useRef } = React;

// ---------- ICONS (inline lucide-style strokes) ----------
const Icon = ({ d, size = 16, className = '', stroke = 'currentColor', fill = 'none', sw = 2, children, ...rest }) => (
  <svg width={size} height={size} viewBox="0 0 24 24" fill={fill} stroke={stroke} strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round" className={className} aria-hidden="true" {...rest}>
    {children || <path d={d} />}
  </svg>
);

const I = {
  // nav
  layout:    (p) => <Icon size={p?.size} {...p}><rect x="3" y="3" width="7" height="9" rx="1"/><rect x="14" y="3" width="7" height="5" rx="1"/><rect x="14" y="12" width="7" height="9" rx="1"/><rect x="3" y="16" width="7" height="5" rx="1"/></Icon>,
  users:     (p) => <Icon size={p?.size} {...p}><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></Icon>,
  user:      (p) => <Icon size={p?.size} {...p}><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></Icon>,
  calendar:  (p) => <Icon size={p?.size} {...p}><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></Icon>,
  zap:       (p) => <Icon size={p?.size} {...p}><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></Icon>,
  chart:     (p) => <Icon size={p?.size} {...p}><path d="M3 3v18h18"/><path d="M7 15l4-4 4 4 6-6"/></Icon>,
  message:   (p) => <Icon size={p?.size} {...p}><path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"/></Icon>,
  settings:  (p) => <Icon size={p?.size} {...p}><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"/></Icon>,
  bell:      (p) => <Icon size={p?.size} {...p}><path d="M18 8a6 6 0 0 0-12 0c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/></Icon>,
  search:    (p) => <Icon size={p?.size} {...p}><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></Icon>,
  plus:      (p) => <Icon size={p?.size} {...p}><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></Icon>,
  arrowUp:   (p) => <Icon size={p?.size} {...p}><line x1="12" y1="19" x2="12" y2="5"/><polyline points="5 12 12 5 19 12"/></Icon>,
  arrowDown: (p) => <Icon size={p?.size} {...p}><line x1="12" y1="5" x2="12" y2="19"/><polyline points="19 12 12 19 5 12"/></Icon>,
  arrowRight:(p) => <Icon size={p?.size} {...p}><line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/></Icon>,
  trendUp:   (p) => <Icon size={p?.size} {...p}><polyline points="22 7 13.5 15.5 8.5 10.5 2 17"/><polyline points="16 7 22 7 22 13"/></Icon>,
  trendDown: (p) => <Icon size={p?.size} {...p}><polyline points="22 17 13.5 8.5 8.5 13.5 2 7"/><polyline points="16 17 22 17 22 11"/></Icon>,
  check:     (p) => <Icon size={p?.size} {...p}><polyline points="20 6 9 17 4 12"/></Icon>,
  x:         (p) => <Icon size={p?.size} {...p}><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></Icon>,
  send:      (p) => <Icon size={p?.size} {...p}><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></Icon>,
  edit:      (p) => <Icon size={p?.size} {...p}><path d="M17 3a2.85 2.85 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z"/></Icon>,
  more:      (p) => <Icon size={p?.size} {...p}><circle cx="12" cy="12" r="1"/><circle cx="19" cy="12" r="1"/><circle cx="5" cy="12" r="1"/></Icon>,
  refresh:   (p) => <Icon size={p?.size} {...p}><polyline points="23 4 23 10 17 10"/><polyline points="1 20 1 14 7 14"/><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"/></Icon>,
  retry:     (p) => <Icon size={p?.size} {...p}><polyline points="1 4 1 10 7 10"/><path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"/></Icon>,
  chevL:     (p) => <Icon size={p?.size} {...p}><polyline points="15 18 9 12 15 6"/></Icon>,
  chevR:     (p) => <Icon size={p?.size} {...p}><polyline points="9 18 15 12 9 6"/></Icon>,
  chevDown:  (p) => <Icon size={p?.size} {...p}><polyline points="6 9 12 15 18 9"/></Icon>,
  phone:     (p) => <Icon size={p?.size} {...p}><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"/></Icon>,
  mail:      (p) => <Icon size={p?.size} {...p}><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></Icon>,
  cake:      (p) => <Icon size={p?.size} {...p}><path d="M20 21v-8a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v8"/><path d="M4 16s.5-1 2-1 2.5 2 4 2 2.5-2 4-2 2.5 2 4 2 2-1 2-1"/><path d="M2 21h20"/><path d="M7 8v2"/><path d="M12 8v2"/><path d="M17 8v2"/><path d="M7 4h.01M12 4h.01M17 4h.01"/></Icon>,
  wa:        (p) => <Icon size={p?.size} {...p} fill="currentColor" sw="0"><path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.198-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51l-.57-.01c-.198 0-.52.074-.792.372s-1.04 1.016-1.04 2.479 1.065 2.876 1.213 3.074c.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347zM12.057 21.785h-.004a9.87 9.87 0 0 1-5.031-1.378l-.361-.214-3.741.982.999-3.648-.235-.374a9.86 9.86 0 0 1-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 0 1 2.893 6.994c-.003 5.45-4.437 9.884-9.886 9.884"/></Icon>,
  list:      (p) => <Icon size={p?.size} {...p}><line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/></Icon>,
  filter:    (p) => <Icon size={p?.size} {...p}><polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"/></Icon>,
  pill:      (p) => <Icon size={p?.size} {...p}><path d="m10.5 20.5 10-10a4.95 4.95 0 1 0-7-7l-10 10a4.95 4.95 0 1 0 7 7Z"/><path d="m8.5 8.5 7 7"/></Icon>,
  beaker:    (p) => <Icon size={p?.size} {...p}><path d="M9 2v6.5a3 3 0 0 1-.5 1.67L4 18a2 2 0 0 0 1.7 3h12.6a2 2 0 0 0 1.7-3l-4.5-7.83A3 3 0 0 1 15 8.5V2"/><path d="M8 2h8"/></Icon>,
  heart:     (p) => <Icon size={p?.size} {...p}><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/></Icon>,
  sparkles:  (p) => <Icon size={p?.size} {...p}><path d="m12 3-1.9 5.8a2 2 0 0 1-1.3 1.3L3 12l5.8 1.9a2 2 0 0 1 1.3 1.3L12 21l1.9-5.8a2 2 0 0 1 1.3-1.3L21 12l-5.8-1.9a2 2 0 0 1-1.3-1.3L12 3Z"/><path d="M5 3v4M3 5h4M19 17v4M17 19h4"/></Icon>,
  building:  (p) => <Icon size={p?.size} {...p}><rect x="4" y="2" width="16" height="20" rx="2"/><path d="M9 22v-4h6v4M8 6h.01M16 6h.01M12 6h.01M12 10h.01M12 14h.01M16 10h.01M16 14h.01M8 10h.01M8 14h.01"/></Icon>,
};

// ---------- AVATAR ----------
function PatientAvatar({ name, size }) {
  const meta = window.avatarFor(name);
  const cls = `avatar ${size || ''}`.trim();
  return (
    <span className={cls} style={{ background: meta.bg }}>{meta.initials}</span>
  );
}

// ---------- STATUS BADGE ----------
const STATUS_MAP = {
  confirmed: { cls: 'badge-success', label: 'Confirmed' },
  pending:   { cls: 'badge-warning', label: 'Pending' },
  missed:    { cls: 'badge-danger',  label: 'Missed' },
  failed:    { cls: 'badge-danger',  label: 'Failed' },
  sent:      { cls: 'badge-success', label: 'Sent' },
  Active:    { cls: 'badge-success', label: 'Active' },
  'At Risk': { cls: 'badge-warning', label: 'At Risk' },
  New:       { cls: 'badge-purple',  label: 'New' },
  Inactive:  { cls: 'badge-neutral', label: 'Inactive' },
  Low:       { cls: 'badge-success', label: 'Low' },
  Medium:    { cls: 'badge-warning', label: 'Medium' },
  High:      { cls: 'badge-danger',  label: 'High' },
  Medication:{ cls: 'badge-lavender', label: 'Medication' },
  Revisit:   { cls: 'badge-blue',     label: 'Revisit' },
  Test:      { cls: 'badge-teal',     label: 'Test' },
};
function StatusBadge({ value, dot }) {
  const m = STATUS_MAP[value] || { cls: 'badge-neutral', label: value };
  return <span className={`badge ${m.cls}`}>{dot && <span className="status-dot" style={{ background: 'currentColor' }} />}{m.label}</span>;
}

// ---------- AI BADGE ----------
function AIBadge() {
  return <span className="ai-badge"><I.sparkles size={10} sw={2.5} />AI</span>;
}

// ---------- WA TICK ----------
function WaTicks({ state }) {
  // single gray = sent, double gray = delivered, double blue = read
  const color = state === 'read' ? '#34B7F1' : '#9CA3AF';
  if (state === 'sent') {
    return (
      <svg width="14" height="10" viewBox="0 0 14 10" fill="none" stroke={color} strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
        <polyline points="2,5 5,8 11,2"/>
      </svg>
    );
  }
  return (
    <svg width="16" height="10" viewBox="0 0 16 10" fill="none" stroke={color} strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      <polyline points="1,5 4,8 10,2"/>
      <polyline points="5,5 8,8 14,2"/>
    </svg>
  );
}

// ---------- KPI CARD ----------
function KPICard({ label, value, trend, trendDir = 'up', children, icon, foot }) {
  return (
    <div className="kpi-card">
      <div className="kpi-label">
        {icon}
        {label}
      </div>
      <div className="kpi-value-row">
        <div className="kpi-value">{value}</div>
        {trend && (
          <span className={`kpi-trend ${trendDir}`}>
            {trendDir === 'up' ? <I.arrowUp size={11} sw={2.5}/> : trendDir === 'down' ? <I.arrowDown size={11} sw={2.5}/> : null}
            {trend}
          </span>
        )}
      </div>
      {children}
      {foot && <div className="kpi-foot">{foot}</div>}
    </div>
  );
}

// ---------- SPARKLINE ----------
function Sparkline({ data, color = '#7C3AED', height = 32 }) {
  const w = 140;
  const max = Math.max(...data), min = Math.min(...data);
  const range = max - min || 1;
  const step = w / (data.length - 1);
  const points = data.map((v, i) => `${i * step},${height - 4 - ((v - min) / range) * (height - 8)}`).join(' ');
  const area = `M0,${height} L${points.split(' ').join(' L')} L${w},${height} Z`;
  return (
    <svg className="sparkline" viewBox={`0 0 ${w} ${height}`} preserveAspectRatio="none">
      <defs>
        <linearGradient id={`sg-${color.slice(1)}`} x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor={color} stopOpacity="0.25"/>
          <stop offset="100%" stopColor={color} stopOpacity="0"/>
        </linearGradient>
      </defs>
      <path d={area} fill={`url(#sg-${color.slice(1)})`} />
      <polyline points={points} fill="none" stroke={color} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" />
    </svg>
  );
}

// ---------- PROGRESS RING ----------
function ProgressRing({ pct, size = 56, color = '#7C3AED' }) {
  const r = (size - 8) / 2;
  const C = 2 * Math.PI * r;
  return (
    <div className="ring-wrap" style={{ width: size, height: size }}>
      <svg width={size} height={size}>
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke="#F1F3F5" strokeWidth="5" />
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke={color} strokeWidth="5"
          strokeDasharray={`${C * (pct/100)} ${C}`} strokeLinecap="round"
          transform={`rotate(-90 ${size/2} ${size/2})`} />
      </svg>
      <span className="ring-value">{pct}%</span>
    </div>
  );
}

// ---------- AREA CHART ----------
function AreaChart({ data, color = '#7C3AED', gradTo = '#A78BFA', height = 220 }) {
  const padX = 40, padY = 24;
  const w = 600;
  const max = Math.max(...data.map(d => d.y)) * 1.15;
  const min = 0;
  const step = (w - padX * 2) / (data.length - 1);
  const pts = data.map((d, i) => [padX + i * step, height - padY - ((d.y - min) / (max - min)) * (height - padY * 2)]);
  const path = pts.map((p, i) => (i === 0 ? `M${p[0]},${p[1]}` : `L${p[0]},${p[1]}`)).join(' ');
  const area = `${path} L${pts[pts.length-1][0]},${height - padY} L${pts[0][0]},${height - padY} Z`;
  const gid = `ar-${color.slice(1)}`;
  // y-axis ticks
  const yticks = [0, 0.25, 0.5, 0.75, 1].map(t => ({ y: padY + t * (height - padY * 2), v: Math.round(max - t * max) }));
  return (
    <svg viewBox={`0 0 ${w} ${height}`} style={{ width: '100%', height: 'auto' }} preserveAspectRatio="xMidYMid meet">
      <defs>
        <linearGradient id={gid} x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor={color} stopOpacity="0.35"/>
          <stop offset="100%" stopColor={gradTo} stopOpacity="0.02"/>
        </linearGradient>
      </defs>
      {yticks.map((t, i) => (
        <g key={i}>
          <line x1={padX} x2={w - padX} y1={t.y} y2={t.y} stroke="#F1F3F5" strokeDasharray="3 4" />
          <text x={padX - 8} y={t.y + 4} fontSize="10" textAnchor="end" fill="#9CA3AF" fontFamily="DM Sans">{t.v}</text>
        </g>
      ))}
      <path d={area} fill={`url(#${gid})`} />
      <path d={path} stroke={color} strokeWidth="2" fill="none" strokeLinecap="round" strokeLinejoin="round" />
      {pts.map((p, i) => (
        <g key={i}>
          <circle cx={p[0]} cy={p[1]} r="3" fill="#fff" stroke={color} strokeWidth="2"/>
        </g>
      ))}
      {data.map((d, i) => (
        <text key={`x-${i}`} x={pts[i][0]} y={height - 6} fontSize="10" textAnchor="middle" fill="#9CA3AF" fontFamily="DM Sans">{d.x}</text>
      ))}
    </svg>
  );
}

// ---------- LINE CHART ----------
function LineChart({ data, color = '#7C3AED', height = 200 }) {
  const padX = 40, padY = 24;
  const w = 800;
  const max = Math.max(...data.map(d => d.y)) * 1.1;
  const min = Math.min(...data.map(d => d.y)) * 0.8;
  const step = (w - padX * 2) / (data.length - 1);
  const pts = data.map((d, i) => [padX + i * step, height - padY - ((d.y - min) / (max - min)) * (height - padY * 2)]);
  const path = pts.map((p, i) => (i === 0 ? `M${p[0]},${p[1]}` : `L${p[0]},${p[1]}`)).join(' ');
  const yticks = [0, 0.5, 1].map(t => ({ y: padY + t * (height - padY * 2), v: Math.round(max - t * (max - min)) }));
  return (
    <svg viewBox={`0 0 ${w} ${height}`} style={{ width: '100%', height: 'auto' }} preserveAspectRatio="xMidYMid meet">
      {yticks.map((t, i) => (
        <g key={i}>
          <line x1={padX} x2={w - padX} y1={t.y} y2={t.y} stroke="#F1F3F5" strokeDasharray="2 4" />
          <text x={padX - 8} y={t.y + 4} fontSize="11" textAnchor="end" fill="#9CA3AF" fontFamily="DM Sans">{t.v}%</text>
        </g>
      ))}
      <path d={path} stroke={color} strokeWidth="2.2" fill="none" strokeLinecap="round" strokeLinejoin="round"/>
      {pts.map((p, i) => (
        <circle key={i} cx={p[0]} cy={p[1]} r="4" fill="#fff" stroke={color} strokeWidth="2"/>
      ))}
      {data.map((d, i) => (
        <text key={i} x={pts[i][0]} y={height - 6} fontSize="11" textAnchor="middle" fill="#6B7280" fontFamily="DM Sans" fontWeight="500">{d.x}</text>
      ))}
    </svg>
  );
}

// ---------- DONUT ----------
function Donut({ segments, size = 180 }) {
  const r = size / 2 - 14;
  const C = 2 * Math.PI * r;
  const total = segments.reduce((s, x) => s + x.value, 0);
  let acc = 0;
  return (
    <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
      <circle cx={size/2} cy={size/2} r={r} fill="none" stroke="#F3F4F6" strokeWidth="18"/>
      {segments.map((s, i) => {
        const pct = s.value / total;
        const dash = `${C * pct} ${C}`;
        const offset = -C * acc;
        acc += pct;
        return (
          <circle key={i} cx={size/2} cy={size/2} r={r} fill="none"
            stroke={s.color} strokeWidth="18"
            strokeDasharray={dash} strokeDashoffset={offset}
            transform={`rotate(-90 ${size/2} ${size/2})`}
            strokeLinecap="butt" />
        );
      })}
      <text x={size/2} y={size/2 - 4} textAnchor="middle" fontFamily="Instrument Sans" fontWeight="700" fontSize="26" fill="#0C0714" letterSpacing="-0.02em">{total}</text>
      <text x={size/2} y={size/2 + 16} textAnchor="middle" fontFamily="DM Sans" fontWeight="500" fontSize="11" fill="#9CA3AF" letterSpacing="0.04em">TOTAL</text>
    </svg>
  );
}

// ---------- ORBIS LOGO ----------
function OrbisMark({ size = 28 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 64 64" fill="none">
      <g transform="translate(32, 32)">
        <circle cx="0" cy="0" r="26" stroke="#7C3AED" strokeWidth="4.5" fill="none"/>
        <path d="M-22,-18 A34,34 0 0,1 22,-18" stroke="url(#orbg)" strokeWidth="4" strokeLinecap="round" fill="none"/>
        <circle cx="0" cy="0" r="4.5" fill="#7C3AED"/>
      </g>
      <defs>
        <linearGradient id="orbg" x1="-22" y1="-18" x2="22" y2="-18">
          <stop offset="0%" stopColor="#A78BFA"/>
          <stop offset="100%" stopColor="#6D28D9"/>
        </linearGradient>
      </defs>
    </svg>
  );
}

Object.assign(window, {
  I, Icon, PatientAvatar, StatusBadge, AIBadge, WaTicks, KPICard,
  Sparkline, ProgressRing, AreaChart, LineChart, Donut, OrbisMark,
});
