/* ============================================================
   CRUIG — Shared UI (window globals)
   ============================================================ */
const { useState, useEffect, useRef, useMemo } = React;

/* ---------- Icons ---------- */
const PATHS = {
  search:"M11 4a7 7 0 1 0 0 14 7 7 0 0 0 0-14Zm9 16-4.3-4.3",
  heart:"M12 20s-7-4.6-9.3-8.4C1 8.5 2.6 5 6 5c2 0 3.2 1.2 4 2.4C10.8 6.2 12 5 14 5c3.4 0 5 3.5 3.3 6.6C19 15.4 12 20 12 20Z",
  star:"M12 3.5l2.6 5.4 5.9.8-4.3 4.1 1 5.9-5.2-2.8-5.2 2.8 1-5.9L3.5 9.7l5.9-.8L12 3.5Z",
  check:"M5 12.5l4.5 4.5L19 7",
  lock:"M6 10V8a6 6 0 0 1 12 0v2m-13 0h14a1 1 0 0 1 1 1v8a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-8a1 1 0 0 1 1-1Z",
  msg:"M4 5h16a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H9l-4 4v-4H4a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1Z",
  plus:"M12 5v14M5 12h14",
  close:"M6 6l12 12M18 6 6 18",
  arrow:"M5 12h14m-6-7 7 7-7 7",
  arrowL:"M19 12H5m6 7-7-7 7-7",
  bolt:"M13 3 4 14h7l-1 7 9-11h-7l1-7Z",
  users:"M16 17v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2M9 7a3 3 0 1 0 0 6 3 3 0 0 0 0-6Zm13 10v-2a4 4 0 0 0-3-3.8M16 4.2A3 3 0 0 1 16 10",
  chart:"M4 20V10m5 10V4m5 16v-7m5 7V8",
  cash:"M3 7h18v10H3zM12 9a3 3 0 1 0 0 6 3 3 0 0 0 0-6Z",
  gear:"M12 9a3 3 0 1 0 0 6 3 3 0 0 0 0-6Zm8.4 3a8.4 8.4 0 0 0-.1-1.3l2-1.5-2-3.4-2.3 1a8 8 0 0 0-2.3-1.3l-.3-2.5H8.9l-.3 2.5A8 8 0 0 0 6.3 6.3l-2.3-1-2 3.4 2 1.5a8.4 8.4 0 0 0 0 2.6l-2 1.5 2 3.4 2.3-1a8 8 0 0 0 2.3 1.3l.3 2.5h5.2l.3-2.5a8 8 0 0 0 2.3-1.3l2.3 1 2-3.4-2-1.5c.06-.43.1-.86.1-1.3Z",
  grid:"M4 4h7v7H4zM13 4h7v7h-7zM4 13h7v7H4zM13 13h7v7h-7z",
  flag:"M5 21V4m0 0 4 1.5L13 4l5 1.5V14l-5-1.5L9 14 5 12.5",
  link:"M9 15l6-6m-4-3 1-1a4 4 0 1 1 6 6l-1 1m-8 8-1 1a4 4 0 1 1-6-6l1-1",
  play:"M8 5v14l11-7-11-7Z",
  bell:"M18 8a6 6 0 1 0-12 0c0 7-3 9-3 9h18s-3-2-3-9M13.7 21a2 2 0 0 1-3.4 0",
  verified:"M12 2.5l2.4 1.7 2.9-.2 1 2.8 2.4 1.6-.9 2.8.9 2.8-2.4 1.6-1 2.8-2.9-.2L12 21.5l-2.4-1.7-2.9.2-1-2.8L3.3 15.6l.9-2.8-.9-2.8 2.4-1.6 1-2.8 2.9.2L12 2.5Z",
  filter:"M3 5h18l-7 8v6l-4-2v-4L3 5Z",
  map:"M12 21s-7-6-7-11a7 7 0 0 1 14 0c0 5-7 11-7 11Zm0-8.5a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5Z",
  edit:"M4 20h4L19 9l-4-4L4 16v4ZM14 6l4 4",
  logout:"M14 8V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2v-2m3-3 3-3-3-3m-7 3h10",
  eye:"M2 12s4-7 10-7 10 7 10 7-4 7-10 7S2 12 2 12Zm10 3a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z",
  trend:"M3 17l6-6 4 4 8-8m0 0h-5m5 0v5",
};
function Icon({name, size=20, sw=1.9, fill=false, style, className}){
  const d = PATHS[name]; if(!d) return null;
  return React.createElement('svg',{width:size,height:size,viewBox:"0 0 24 24",
    fill: fill?"currentColor":"none", stroke: fill?"none":"currentColor",
    strokeWidth:sw, strokeLinecap:"round", strokeLinejoin:"round", style, className, "aria-hidden":true},
    React.createElement('path',{d}));
}

/* Social platform glyphs */
function PlatIcon({type, size=15}){
  const c = {instagram:"#d6388a", tiktok:"#111", youtube:"#e23"}[type];
  const G = {
    instagram:<><rect x="3" y="3" width="18" height="18" rx="5"/><circle cx="12" cy="12" r="4"/><circle cx="17.3" cy="6.7" r="1.1" fill="#fff" stroke="none"/></>,
    tiktok:<path d="M14 4c.4 2.4 1.9 3.9 4.2 4.1v2.6c-1.4.1-2.8-.3-4.1-1.1v5.6a4.9 4.9 0 1 1-4.9-4.9c.3 0 .6 0 .9.1v2.7a2.2 2.2 0 1 0 1.5 2.1V4H14Z"/>,
    youtube:<><rect x="3" y="6" width="18" height="12" rx="3.5"/><path d="M11 9.5v5l4-2.5-4-2.5Z" fill="#fff" stroke="none"/></>,
  }[type];
  return React.createElement('svg',{width:size,height:size,viewBox:"0 0 24 24",fill:type==='tiktok'?c:'none',stroke:c,strokeWidth:1.7,style:{flexShrink:0}}, G);
}

/* ---------- Logo ---------- */
function Logo({variant="green", height=30, style}){
  const src = {green:"assets/logo-green.png", white:"assets/logo-white.png", gray:"assets/logo-gray.png", dark:"assets/logo-darkgreen.png"}[variant];
  return React.createElement('img',{src, alt:"Cruig", style:{height, width:'auto', display:'block', ...style}});
}

/* ---------- Avatar (initials OR uploaded photo) ---------- */
function Avatar({name, size=44, colorIdx=0, ring=false, verified=false, src=null}){
  const initials = name.split(' ').slice(0,2).map(w=>w[0]).join('').toUpperCase();
  const bg = CRUIG.avColors[colorIdx % CRUIG.avColors.length];
  const dark = ['#FFA732','#94C700'].includes(bg);
  const ringSh = ring?'0 0 0 3px #fff, 0 0 0 5px var(--lime)':'none';
  return (
    <span style={{position:'relative', display:'inline-block', flexShrink:0}}>
      {src
        ? <img className="av" src={src} alt={name} style={{width:size, height:size, objectFit:'cover', boxShadow:ringSh}}/>
        : <span className="av" style={{width:size, height:size, background:bg, color: dark?'#003900':'#fff',
            display:'flex', alignItems:'center', justifyContent:'center',
            fontFamily:'var(--display)', fontWeight:600, fontSize:size*0.38, boxShadow:ringSh}}>{initials}</span>}
      {verified && <span style={{position:'absolute', right:-2, bottom:-2, width:size*0.42, height:size*0.42,
        background:'#94C700', color:'#fff', borderRadius:'50%', display:'flex', alignItems:'center', justifyContent:'center',
        border:'2px solid #fff'}}><Icon name="check" size={size*0.24} sw={3}/></span>}
    </span>
  );
}

/* ---------- Niche chip + selectable system ---------- */
function NicheChip({label, on, onClick, sm, static_}){
  const color = CRUIG.nicheColor(label);
  return (
    <button type="button" className={`chip ${sm?'chip-sm':''} ${on?'is-on':''} ${static_?'chip-static':''}`}
      onClick={onClick} style={static_?{cursor:'default'}:undefined}>
      <span style={{width:8,height:8,borderRadius:'50%',background:on?'#003900':color,flexShrink:0}}></span>
      {label}
      {on!==undefined && on && <Icon name="check" size={13} sw={3} style={{marginLeft:-1}}/>}
    </button>
  );
}

/* Multi-select niche filter used by both creator profile & company search */
function NicheFilter({selected, onChange, limit=null, columns=false}){
  const [q,setQ] = useState('');
  const list = CRUIG.NICHES.filter(n=> n.toLowerCase().includes(q.toLowerCase()));
  const toggle = (n)=>{
    if(selected.includes(n)) onChange(selected.filter(x=>x!==n));
    else { if(limit && selected.length>=limit) return; onChange([...selected, n]); }
  };
  return (
    <div>
      <div style={{position:'relative', marginBottom:14}}>
        <span style={{position:'absolute', left:13, top:'50%', transform:'translateY(-50%)', color:'var(--ink-faint)'}}><Icon name="search" size={17}/></span>
        <input className="input" style={{paddingLeft:38}} placeholder="Buscar nicho…" value={q} onChange={e=>setQ(e.target.value)}/>
      </div>
      <div style={{display:'flex', flexWrap:'wrap', gap:9, maxHeight: columns?320:'none', overflowY: columns?'auto':'visible'}}>
        {list.map(n=> <NicheChip key={n} label={n} on={selected.includes(n)} onClick={()=>toggle(n)} sm/>)}
        {list.length===0 && <span className="faint" style={{fontSize:13.5}}>Nenhum nicho encontrado para “{q}”.</span>}
      </div>
      {limit && <p className="faint" style={{fontSize:12.5, marginTop:12}}>{selected.length}/{limit} selecionados</p>}
    </div>
  );
}

/* ---------- Stat / metric ---------- */
function Stat({label, value, delta, icon, accent="var(--lime)"}){
  const up = delta!=null && delta>=0;
  return (
    <div className="card card-pad" style={{display:'flex', flexDirection:'column', gap:10}}>
      <div style={{display:'flex', justifyContent:'space-between', alignItems:'flex-start'}}>
        <span style={{fontSize:13, fontWeight:700, color:'var(--ink-soft)'}}>{label}</span>
        {icon && <span style={{width:34,height:34,borderRadius:10,background:accent+'22',color:accent,display:'flex',alignItems:'center',justifyContent:'center'}}><Icon name={icon} size={18}/></span>}
      </div>
      <div style={{display:'flex', alignItems:'baseline', gap:10, flexWrap:'wrap'}}>
        <span className="mono-num" style={{fontSize:28, fontWeight:700, color:'var(--green-dark)'}}>{value}</span>
        {delta!=null && <span className={`badge ${up?'badge-lime':'badge-danger'}`}><Icon name="trend" size={12} sw={2.4}/>{up?'+':''}{delta}%</span>}
      </div>
    </div>
  );
}

/* ---------- Modal ---------- */
function Modal({open, onClose, children, width=520, pad=true}){
  useEffect(()=>{
    if(!open) return;
    const h = (e)=>{ if(e.key==='Escape') onClose(); };
    window.addEventListener('keydown',h); return ()=>window.removeEventListener('keydown',h);
  },[open]);
  if(!open) return null;
  return (
    <div onClick={onClose} style={{position:'fixed', inset:0, zIndex:80, background:'rgba(0,40,0,.42)', backdropFilter:'blur(4px)',
      display:'flex', alignItems:'center', justifyContent:'center', padding:24, animation:'pop .2s ease'}}>
      <div onClick={e=>e.stopPropagation()} className="card pop" style={{width, maxWidth:'100%', maxHeight:'90vh', overflow:'hidden', borderRadius:'var(--r-xl)', padding: pad?30:0, boxShadow:'var(--sh-lg)'}}>
        {children}
      </div>
    </div>
  );
}

/* ---------- Toast ---------- */
function useToast(){
  const [msg,setMsg] = useState(null);
  const show = (m)=>{ setMsg(m); setTimeout(()=>setMsg(null), 2600); };
  const node = msg && (
    <div style={{position:'fixed', bottom:26, left:'50%', transform:'translateX(-50%)', zIndex:120,
      background:'var(--green-dark)', color:'#fff', padding:'13px 20px', borderRadius:'var(--r-pill)',
      boxShadow:'var(--sh-lg)', display:'flex', alignItems:'center', gap:10, fontWeight:600, fontSize:14, animation:'pop .25s ease'}}>
      <span style={{width:22,height:22,borderRadius:'50%',background:'var(--lime)',color:'var(--green-dark)',display:'flex',alignItems:'center',justifyContent:'center'}}><Icon name="check" size={14} sw={3}/></span>
      {msg}
    </div>
  );
  return [node, show];
}

/* ---------- Lock / paywall pill ---------- */
function LockPill({children}){
  return <span className="badge badge-orange" style={{padding:'5px 11px'}}><Icon name="lock" size={12}/>{children}</span>;
}

/* ---------- Mini bar chart ---------- */
function BarChart({data, color="var(--lime)", height=120}){
  const max = Math.max(...data);
  return (
    <div style={{display:'flex', alignItems:'flex-end', gap:6, height}}>
      {data.map((v,i)=>(
        <div key={i} style={{flex:1, display:'flex', flexDirection:'column', justifyContent:'flex-end', height:'100%'}}>
          <div style={{height:`${(v/max)*100}%`, background: i===data.length-1?'var(--orange)':color, borderRadius:'6px 6px 3px 3px', transition:'height .5s ease'}}></div>
        </div>
      ))}
    </div>
  );
}

/* ---------- Donut ---------- */
function Donut({segments, size=132, thickness=20}){
  const total = segments.reduce((s,x)=>s+x.value,0);
  const r = (size-thickness)/2; const C = 2*Math.PI*r; let off=0;
  return (
    <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
      <g transform={`rotate(-90 ${size/2} ${size/2})`}>
        {segments.map((s,i)=>{
          const len = (s.value/total)*C;
          const el = <circle key={i} cx={size/2} cy={size/2} r={r} fill="none" stroke={s.color} strokeWidth={thickness}
            strokeDasharray={`${len} ${C-len}`} strokeDashoffset={-off} strokeLinecap="butt"/>;
          off+=len; return el;
        })}
      </g>
    </svg>
  );
}

/* scroll reveal */
function useReveal(){
  useEffect(()=>{
    const els = document.querySelectorAll('.reveal:not(.in)');
    const io = new IntersectionObserver((ents)=>{
      ents.forEach(e=>{ if(e.isIntersecting){ e.target.classList.add('in'); io.unobserve(e.target);} });
    },{threshold:.12});
    els.forEach(e=>io.observe(e));
    // Safety net: never leave content hidden (covers PDF/export & observers that don't fire)
    const t = setTimeout(()=>document.querySelectorAll('.reveal:not(.in)').forEach(e=>e.classList.add('in')), 2600);
    return ()=>{io.disconnect(); clearTimeout(t);};
  });
}

/* ---------- Notifications bell (dropdown) ---------- */
function NotificationsBell({items, accent="creator"}){
  const [open,setOpen] = useState(false);
  const ref = useRef();
  useEffect(()=>{
    const h=(e)=>{ if(ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener('mousedown',h); return ()=>document.removeEventListener('mousedown',h);
  },[]);
  const list = items || [
    {icon:'flag', text:'Nova campanha no seu nicho: Verdejar', time:'agora'},
    {icon:'msg', text:'NômadeBags respondeu sua mensagem', time:'10 min'},
    {icon:'cash', text:'Comissão de R$ 30 confirmada', time:'1 h'},
    {icon:'star', text:'FitMacros avaliou seu perfil ★★★★★', time:'ontem'},
  ];
  return (
    <div ref={ref} style={{position:'relative'}}>
      <button className="btn btn-ghost btn-sm" style={{padding:'9px 11px', position:'relative'}} onClick={()=>setOpen(o=>!o)}>
        <Icon name="bell" size={18}/>
        <span style={{position:'absolute', top:5, right:7, width:9, height:9, borderRadius:'50%', background:'var(--orange)', border:'2px solid var(--beige)'}}></span>
      </button>
      {open && (
        <div className="card pop" style={{position:'absolute', right:0, top:'calc(100% + 8px)', width:312, zIndex:70, boxShadow:'var(--sh-lg)', padding:8}}>
          <div style={{display:'flex', justifyContent:'space-between', alignItems:'center', padding:'8px 10px 6px'}}>
            <span style={{fontWeight:700, fontSize:13.5, color:'var(--green-dark)'}}>Notificações</span>
            <span className="badge badge-lime">{list.length} novas</span>
          </div>
          <div style={{display:'flex', flexDirection:'column'}}>
            {list.map((n,i)=>(
              <div key={i} style={{display:'flex', gap:11, alignItems:'center', padding:'10px', borderRadius:10, cursor:'pointer'}}
                onMouseEnter={e=>e.currentTarget.style.background='var(--beige-deep)'} onMouseLeave={e=>e.currentTarget.style.background='transparent'}>
                <span style={{width:34,height:34,borderRadius:10,background:'var(--lime-100)',color:'var(--lime-700)',display:'flex',alignItems:'center',justifyContent:'center',flexShrink:0}}><Icon name={n.icon} size={16}/></span>
                <div style={{flex:1, minWidth:0}}><div style={{fontSize:13, fontWeight:600, color:'var(--ink)', lineHeight:1.35}}>{n.text}</div><div className="faint" style={{fontSize:11, marginTop:2}}>{n.time}</div></div>
              </div>
            ))}
          </div>
          <button className="btn btn-ghost btn-sm btn-block" style={{marginTop:6}} onClick={()=>setOpen(false)}>Marcar todas como lidas</button>
        </div>
      )}
    </div>
  );
}

/* ---------- Per-network stat card (Instagram/TikTok/YouTube) ---------- */
function NetworkStatCard({platform, data, compact}){
  const label = (CRUIG.PLATFORM_LABEL && CRUIG.PLATFORM_LABEL[platform]) || 'seguidores';
  const accent = {instagram:'#d6388a', tiktok:'#111', youtube:'#e23'}[platform] || 'var(--green-dark)';
  const name = platform.charAt(0).toUpperCase()+platform.slice(1);
  return (
    <div style={{border:'1px solid var(--line)', borderRadius:'var(--r-md)', overflow:'hidden', background:'#fff'}}>
      {/* header */}
      <div style={{display:'flex', alignItems:'center', gap:11, padding:'13px 15px', borderBottom:'1px solid var(--line)'}}>
        <span style={{width:34, height:34, borderRadius:9, background:accent+'18', display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0}}><PlatIcon type={platform} size={19}/></span>
        <div style={{flex:1, minWidth:0}}>
          <div style={{fontWeight:700, fontSize:14.5, color:'var(--green-dark)'}}>{name}</div>
          <div className="faint" style={{fontSize:11.5}}>rede conectada</div>
        </div>
        <div style={{textAlign:'right'}}>
          <div className="mono-num" style={{fontWeight:700, fontSize:18, color:'var(--green-dark)', lineHeight:1}}>{CRUIG.fmt(data.followers)}</div>
          <div className="faint" style={{fontSize:11}}>{label}</div>
        </div>
      </div>
      {/* metrics */}
      <div style={{display:'grid', gridTemplateColumns:'repeat(3,1fr)'}}>
        {[
          ['Engajamento', data.engagement+'%', 'var(--lime-700)'],
          ['Views 30d', CRUIG.fmt(data.views30d), 'var(--orange-600)'],
          ['Audiência', data.audience, 'var(--ink)'],
        ].map(([l,v,col],i)=>(
          <div key={i} style={{padding:'11px 12px', borderRight: i<2?'1px solid var(--line)':'none'}}>
            <div className="faint" style={{fontSize:10.5, fontWeight:700, textTransform:'uppercase', letterSpacing:'.03em', marginBottom:4}}>{l}</div>
            <div style={{fontFamily: i===2?'var(--body)':'var(--display)', fontWeight: i===2?600:700, fontSize: i===2?12:15.5, color:col, lineHeight:1.25}}>{v}</div>
          </div>
        ))}
      </div>
    </div>
  );
}

/* ---------- Avatar com upload de foto ---------- */
function AvatarUpload({name, size=92, colorIdx=0, verified=false, src, onChange}){
  const inputRef = useRef();
  const pick = (e)=>{
    const f = e.target.files && e.target.files[0];
    if(!f) return;
    const reader = new FileReader();
    reader.onload = ()=> onChange(reader.result);
    reader.readAsDataURL(f);
  };
  return (
    <span style={{position:'relative', display:'inline-block'}}>
      <Avatar name={name} size={size} colorIdx={colorIdx} verified={verified} src={src}/>
      <button onClick={()=>inputRef.current && inputRef.current.click()} title="Trocar foto"
        style={{position:'absolute', right:-2, bottom:-2, width:Math.max(30,size*0.34), height:Math.max(30,size*0.34),
          borderRadius:'50%', background:'var(--green-dark)', color:'#fff', border:'3px solid #fff',
          display:'flex', alignItems:'center', justifyContent:'center', cursor:'pointer', zIndex:2}}>
        <Icon name="edit" size={Math.max(14,size*0.16)}/>
      </button>
      <input ref={inputRef} type="file" accept="image/*" onChange={pick} style={{display:'none'}}/>
    </span>
  );
}

/* ---------- Chat admin ↔ usuário (compartilhado via localStorage) ---------- */
const ADMIN_CHAT_KEY = 'cruig_admin_chat_v1';
const _defaultAdminChat = [
  {from:'admin', text:'Olá! Aqui é a equipe Cruig 👋 Estamos à disposição para ajudar.', time:'09:32'},
  {from:'user', text:'Oi! Queria entender melhor o programa de afiliados.', time:'09:40'},
  {from:'admin', text:'Claro! Você ganha R$ 30 por indicação ativa, com saque automático a partir de R$ 50. Posso te enviar seu link exclusivo?', time:'09:41'},
];
function loadAdminChat(){
  try{ const v = JSON.parse(localStorage.getItem(ADMIN_CHAT_KEY)); return Array.isArray(v)&&v.length? v : _defaultAdminChat.slice(); }
  catch(e){ return _defaultAdminChat.slice(); }
}
function saveAdminChat(msgs){ try{ localStorage.setItem(ADMIN_CHAT_KEY, JSON.stringify(msgs)); }catch(e){} }
function chatNow(){ const d=new Date(); return String(d.getHours()).padStart(2,'0')+':'+String(d.getMinutes()).padStart(2,'0'); }

/* Renderiza uma thread; destaca SEMPRE as mensagens do admin (Equipe Cruig) */
function ChatThread({msgs, viewer}){
  const endRef = useRef();
  useEffect(()=>{ if(endRef.current) endRef.current.scrollTop = endRef.current.scrollHeight; },[msgs]);
  return (
    <div ref={endRef} style={{display:'flex', flexDirection:'column', gap:11, overflowY:'auto', flex:1}}>
      {msgs.map((m,i)=>{
        const mine = m.from===viewer;
        const isAdmin = m.from==='admin';
        return (
          <div key={i} style={{alignSelf: mine?'flex-end':'flex-start', maxWidth:'80%'}}>
            {isAdmin && (
              <div style={{display:'flex', alignItems:'center', gap:5, marginBottom:4, justifyContent: mine?'flex-end':'flex-start'}}>
                <span className="badge" style={{background:'var(--green-dark)', color:'#fff', padding:'2px 9px', fontSize:10, letterSpacing:'.04em'}}><Icon name="verified" size={11} fill/> EQUIPE CRUIG</span>
              </div>
            )}
            <div style={{padding:'10px 14px', fontSize:14, lineHeight:1.45, boxShadow:'var(--sh-sm)',
              borderRadius: mine?'16px 16px 4px 16px':'16px 16px 16px 4px',
              background: isAdmin ? 'var(--green-dark)' : (mine?'var(--lime)':'#fff'),
              color: isAdmin ? '#fff' : (mine?'var(--green-dark)':'var(--ink)'),
              border: isAdmin ? '1.5px solid var(--lime)' : 'none'}}>
              {m.text}
              <div style={{fontSize:10, opacity:.55, marginTop:4, textAlign:'right'}}>{m.time}</div>
            </div>
          </div>
        );
      })}
    </div>
  );
}

Object.assign(window, {Icon, PlatIcon, Logo, Avatar, AvatarUpload, NicheChip, NicheFilter, Stat, Modal, useToast, LockPill, BarChart, Donut, useReveal, NotificationsBell, NetworkStatCard, loadAdminChat, saveAdminChat, chatNow, ChatThread});
