PageSourceSearch

https://cdecad.com/assets/CdeMetricsPage-jO7Moz6-.js

js cdecad.com collected 2026-10-08 16:06:58 UTC 98,297 bytes, 6 lines download raw bytes

1import{j as e,r as v}from"./vendor-react-TXDxJ4pL.js";import{y as je}from"./vendor-toastify-zImE3QEX.js";import{O as Es,u as Rs,C as Ms,P as Ns,Q as Ls,R as Ps,S as zs,U as ce,V as Is,W as Bs,X as Os,Y as Hs,Z as _s,_ as Us,$ as qs,a0 as Gs}from"./CadHeader-Cjh972dt.js";import{c6 as t,b as Vs,c7 as Ks,eo as Ys,a7 as Qs}from"./index-DSQ6kcyn.js";import{b as C,N as ss,M as ts,c as G,d as X,E as P,f as S,T as ee,g as I,j as Z,D as B,P as z,k as rs,l as ae,m as E,B as O,n as J,a as ns,K as Ne,F as Se,o as as,C as Zs,p as Js,S as is,q as Xs,r as et}from"./kit-B0PIX36h.js";import{a as T,t as ne,f as _,b as ls,c as os}from"./adminApi-B4HViBm5.js";import{u as st,a as ds,b as Le,f as Pe,l as cs,L as le,c as tt,p as $e,d as hs,i as rt,m as nt,r as at,F as us,S as it,e as lt,t as ze,g as U,h as ot,j as V,C as dt,M as ct,s as ht,n as D,k as te,o as Ae,q as ps,v as ms,w as xe,I as ut,x as pt,y as mt,z as yt,A as q,B as Ue,D as xt,E as gt,G as Ie,H as Re,R as vt,N as jt,J as ft,K as bt,O as wt,P as kt,Q as Ct,T as ys,U as xs,V as St,W as qe,X as Ge,Y as gs,Z as vs,_ as Ve,$ as $t,a0 as At,a1 as Ft,a2 as Tt,a3 as Dt,a4 as Wt,a5 as he,a6 as Et,a7 as Rt,a8 as js,a9 as fs,aa as Mt,ab as Nt,ac as bs,ad as Me,ae as Te,af as Lt,ag as Ke,ah as ve,ai as Pt,aj as ws,ak as zt,al as It,am as Bt,an as Fe,ao as Ot,ap as Ht,aq as _t,ar as Ut,as as Ye,at as qt,au as Gt,av as Vt,aw as Kt,ax as Yt,ay as Qt,az as Zt,aA as Jt,aB as Qe,aC as Ee,aD as Ze,aE as Xt,aF as er,aG as sr,aH as tr,aI as ke,aJ as Je,aK as rr,aL as nr,aM as Xe,aN as ar,aO as ir,aP as lr}from"./charts-CAyre_f1.js";import{u as F}from"./useAdminQuery-DxEDGOCW.js";import{k as or}from"./vendor-icons--IBbgi4o.js";import{c as ks,d as dr,a as Cs}from"./vendor-router-BfSjmGu8.js";import"./vendor-CYhC9tBg.js";import"./brandTheme-D_FUAiDP.js";import"./departmentConfig-D0qdBJcF.js";import"./vendor-i18n-ZeuoPmU-.js";import"./vendor-axios-BCn5QfZZ.js";import"./vendor-socket-Kk_l3rvZ.js";import"./vendor-helmet-COw7OOqs.js";import"./Sheet-DFymStGV.js";import"./sheetGesture-BrdUEoTX.js";function ge({title:s,children:n,action:r}){return e.jsx(C,{padding:t.sp(6),style:{maxWidth:640,margin:`${t.sp(6)}px auto 0`},children:e.jsxs("div",{"data-metrics-refusal":"",children:[e.jsx("div",{"aria-hidden":"true",style:{width:40,height:40,borderRadius:20,background:t.press,color:t.sub,display:"inline-flex",alignItems:"center",justifyContent:"center",marginBottom:t.sp(4)},children:e.jsx(or,{})}),e.jsx("h2",{style:{margin:0,fontSize:"clamp(19px, 4.8vw, 22px)",fontWeight:750,letterSpacing:"-0.02em",lineHeight:1.25},children:s}),e.jsx("div",{style:{marginTop:t.sp(2),color:t.sub,fontSize:14.5,lineHeight:1.55},children:n}),r&&e.jsx("div",{style:{marginTop:t.sp(5),display:"flex",gap:t.sp(2),flexWrap:"wrap"},children:r})]})})}function be({row:s,access:n}){return n?.canOpenCommunities?e.jsx("a",{href:`/admin/communities?community=${encodeURIComponent(s.communityId)}`,style:{color:t.accent,fontWeight:600,textDecoration:"none",overflowWrap:"anywhere"},children:s.communityName}):e.jsx("span",{style:{fontWeight:600,overflowWrap:"anywhere"},children:s.communityName})}const N="/admin/cde-metrics/fivestatus",L=s=>s.data,cr=()=>T(`${N}/status`).then(L),hr=({horizon:s}={})=>T(`${N}/ecosystem`,{horizon:s}).then(L),ur=({days:s}={})=>T(`${N}/market`,{days:s}).then(L),pr=()=>T(`${N}/churn`).then(L),mr=({region:s,framework:n,page:r}={})=>T(`${N}/leads`,{region:s||void 0,framework:n||void 0,page:r||void 0}).then(L),yr=({scope:s,days:n}={})=>T(`${N}/changes`,{scope:s,days:n}).then(L),Ss=({days:s}={})=>T(`${N}/segments`,{days:s}).then(L),xr=s=>T(`${N}/server/${encodeURIComponent(s)}`).then(L),se=s=>s===""||s===null||s===void 0?void 0:s,gr=({resource:s,region:n,framework:r,minPlayers:c,page:i}={})=>T(`${N}/switch`,{resource:se(s),region:se(n),framework:se(r),minPlayers:se(c),page:se(i)}).then(L),vr=()=>T(`${N}/related`).then(L),jr=({days:s}={})=>T(`${N}/flows`,{days:s}).then(L),fr=({days:s}={})=>T(`${N}/newcomers`,{days:s}).then(L),br=({kind:s,segment:n,days:r}={})=>T(`${N}/segments/history`,{kind:s,segment:se(n),days:r}).then(L),wr=({kind:s,days:n}={})=>T(`${N}/segments/compare`,{kind:s,days:n}
1).then(L),kr=()=>T(`${N}/ecosystem/intraday`).then(L),Cr=({hours:s}={})=>T(`${N}/activity`,{hours:s}).then(L),Sr=({horizon:s}={})=>T(`${N}/revenue`,{horizon:s}).then(L),$r=({resource:s,action:n,days:r}={})=>T(`${N}/impact`,{resource:s,action:n,days:r}).then(L),$s=({days:s,joinCode:n}={})=>T(`${N}/distribution`,{days:se(s),joinCode:se(n)}).then(L),g=s=>s==null||!Number.isFinite(Number(s))?"-":Number(s).toLocaleString("en-US"),W={margin:`-${t.sp(1)}px 0 ${t.sp(3)}px`,color:t.sub,fontSize:14,lineHeight:1.5},j={fontSize:12.5,color:t.sub,lineHeight:1.5},re={color:t.accent,fontWeight:600,textDecoration:"none"},ie=s=>({display:"grid",gridTemplateColumns:`repeat(auto-fit, minmax(min(${s}px, 100%), 1fr))`,gap:t.sp(3)}),ue={fontSize:13.5,fontWeight:650,color:t.text,margin:`0 0 ${t.sp(1)}px`};function Be({data:s,section:n}){const r=tt(s?.attribution);return e.jsxs("p",{"data-fivestatus-credit":n,style:{...j,margin:`${t.sp(3)}px 0 0`},children:[e.jsx("a",{href:r.url,target:"_blank",rel:"noopener noreferrer",style:re,children:r.text}),s?.fetchedAt?`, read ${ne(s.fetchedAt)}.`:".",s?.stale?" FiveStatus did not answer, so this is the copy CDECAD stored last.":""," ","For CDECAD staff only: FiveStatus' terms do not allow republishing it."]})}function As(){return e.jsx(ge,{title:"FiveStatus is not set up",children:e.jsx("span",{"data-fivestatus-unconfigured":"",children:"Add the FiveStatus API key to the backend .env as FIVESTATUS and restart the backend. The key stays on the server; this page never sees it. The other CDE Metrics views read fivestats.io and work without it."})})}function k({off:s}){return e.jsxs(ss,{tone:"warn",children:[e.jsx("span",{"data-fivestatus-unavailable":s.code||"",children:st(s)}),s.code?e.jsxs(e.Fragment,{children:[" ",e.jsx(ts,{children:s.code})]}):null]})}function oe({id:s,query:n,fallback:r,children:c,after:i}){const{data:d,error:h,loading:p,reload:a}=n,u=d||ds(h),x=Le(u);if(u&&u.configured===!1)return e.jsx(As,{});const m=l=>$e(u,l);return e.jsxs("div",{"data-fivestatus-section":s,children:[!u&&e.jsx(G,{error:h,onRetry:a,fallback:r}),p&&!u&&e.jsx(X,{height:180}),u?.stopped&&e.jsx(k,{off:u.stopped}),x&&e.jsx(k,{off:x}),u&&!x&&c(u,m),u&&i,u&&e.jsx(Be,{data:u,section:s})]})}function Y({id:s,query:n,fallback:r,children:c,height:i=120}){const{data:d,error:h,loading:p,reload:a}=n,u=d||ds(h);if(u&&u.configured===!1)return null;const x=Le(u),m=l=>$e(u,l);return e.jsxs("div",{"data-fivestatus-part":s,children:[!u&&e.jsx(G,{error:h,onRetry:a,fallback:r}),p&&!u&&e.jsx(X,{height:i}),x&&e.jsx(k,{off:x}),u&&!x&&c(u,m)]})}function me({joinCode:s,name:n,onServer:r,style:c}){const i=n||(s?`cfx.re/join/${s}`:"Unnamed server");return!s||!r?e.jsx("span",{style:{fontWeight:600,overflowWrap:"anywhere",...c},children:i}):e.jsx("button",{type:"button",className:"adm-btn","data-fivestatus-open":s,onClick:()=>r({joinCode:s,name:n}),title:`Open ${i}`,style:{background:"none",border:"none",padding:0,margin:0,font:"inherit",fontWeight:600,color:t.accent,textAlign:"left",cursor:"pointer",overflowWrap:"anywhere",lineHeight:"inherit",...c},children:i})}function pe({points:s}){return s.length?e.jsxs("div",{"aria-hidden":"true",style:{display:"flex",justifyContent:"space-between",gap:t.sp(2),marginTop:t.sp(1.5),fontSize:11.5,color:t.subtle,paddingLeft:40},children:[e.jsx("span",{children:s[0].label}),e.jsx("span",{children:s[s.length-1].label})]}):null}function Fs({caption:s,points:n,unit:r,first:c="Day"}){return e.jsx("div",{className:"adm-sr",children:e.jsxs("table",{children:[e.jsx("caption",{children:s}),e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{scope:"col",children:c}),e.jsx("th",{scope:"col",children:r}),e.jsx("th",{scope:"col",children:"Likely range"})]})}),e.jsx("tbody",{children:n.map(i=>e.jsxs("tr",{children:[e.jsxs("td",{children:[i.label,i.projected?" (forecast)":""]}),e.jsx("td",{children:i.value===null?"No recording":g(i.value)}),e.jsx("td",{children:i.projected&&i.low!==null&&i.high!==null?`${g(i.low)} to ${g(i.high)}`:""})]},i.key))})]})})}function Oe({title:s="No forecast yet",text:n}){return e.jsxs("div",{"data-fivestatus-insufficient":"",style:{marginTop:t.sp(3),padding:`${t.sp(3)}px ${t.sp(4)}px`,borderRadius:t.r.control,background:t.press},children:[e.jsx("div",{style:{fontSize:13.5,fontWeight:650,color:t.text},children:s}),e.jsx("p",{style:{...j,margin:`${t.sp(1)}px 0 0`},children:n})]})}function Ar({forecast:s,points:n,what:r}){const c=hs(s);if(c==="insufficient")return e.jsx(Oe,{text:rt(s)});if(c==="unavailable")return e.jsx("div",{style:{marginTop:t.sp(3)},children:e.jsx(k,{off:s.unavailable})});if(c!=="ready")return null;const i=nt(s.mape,at(n));return e.jsxs(e.Fragment,{children:[e.jsx(us,{}),e.jsxs("p",{"data-fivestatus-mape":"",style:{...j,margin:`${t.sp(2)}px 0 0`},children:[i?e.jsxs(e.Fragment,{children:[e.jsxs("span",{style:{color:t.text,fontWeight:600},children:[i,"."]})," The forecast was fitted again without those days and checked against what ",r," actually did. "]}):null,"The shaded band is where 8 days in 10 should land, and it widens the further ahead it looks."]})]})}function De({daily:s,forecast:n,valueKey:r,ariaLabel:c,unit:i,what:d,height:h=160,days:p,markers:a,selectedMarker:u,onMarker:x}){const m=v.useMemo(()=>Pe(s,n,r),[s,n,r]),l=v.useMemo(()=>p?cs(m,p):m,[m,p]),o=v.useMemo(()=>typeof a=="function"?a(l):a,[a,l]);return l.length?e.jsxs("div",{"data-fivestatus-forecast-chart":"",children:[e.jsx(le,{gaps:!0,points:l,height:h,unit:i,ariaLabel:c,markers:o,selectedMarker:u,onMarker:x}),e.jsx(pe,{points:l}),e.jsx("p",{style:{...j,margin:`${t.sp(2)}px 0 0`},children:"A break in the line is a day with no recording, not a day with nobody on."}),e.jsx(Ar,{forecast:n,points:l,what:d}),e.jsx(Fs,{caption:c,points:l,unit:i})]}):e.jsx(P,{title:"Nothing recorded yet",body:"CDECAD stores FiveStatus' numbers once a day. The first day shows here after the next recording."})}const Q={marginTop:t.sp(4)}
1,He=s=>_(s,{time:!0});function Fr(){const s=F(()=>kr(),[]),n=v.useMemo(()=>xs(),[]),r=fs(n);return e.jsxs(C,{style:Q,"data-fivestatus-intraday":"",children:[e.jsx(S,{children:"Players every 10 minutes, last 14 days"}),e.jsx("p",{style:W,children:"Players on FiveM at each reading. FiveStatus keeps the highest count in each 10 minutes, so short peaks stay visible."}),e.jsx(Y,{id:"intraday",query:s,fallback:"Could not load FiveM's last 14 days from FiveStatus. Try again in a minute.",children:(c,i)=>{const d=ze(c.points,He),h=St(c.heatmap),p=qe(c.peak,n),a=qe(c.quiet,n),u=[p?`Busiest on ${Ge(p)}.`:"",a?`Quietest on ${Ge(a)}.`:"",`Times in ${r}, your time zone; FiveStatus counts in UTC.`].filter(Boolean).join(" "),x=i("points")||!d.length&&U(c);return!d.length&&!h&&U(c)?e.jsx(k,{off:U(c)}):e.jsxs(e.Fragment,{children:[x?e.jsx(k,{off:x}):d.length?e.jsxs(e.Fragment,{children:[e.jsx(le,{points:d,height:140,unit:"players",ariaLabel:"Players on FiveM every 10 minutes over the last 14 days"}),e.jsx(pe,{points:d})]}):e.jsx("p",{style:{...j,margin:0},children:"FiveStatus has no readings for the last 14 days."}),e.jsxs("div",{style:{marginTop:t.sp(5)},"data-fivestatus-heatmap":"",children:[e.jsx("h4",{style:ue,children:"Average players by weekday and hour"}),i("heatmap")?e.jsx(k,{off:i("heatmap")}):h?e.jsxs(e.Fragment,{children:[e.jsx("p",{"data-fivestatus-peak":"",style:{...j,margin:`0 0 ${t.sp(3)}px`},children:u}),e.jsx(gs,{relative:!0,cells:vs(h,n),zoneLabel:`Times in ${r}`,summary:`From the quietest hour of the week to the busiest. Times in ${r}.`,ariaLabel:`Average players on FiveM by weekday and hour over the last 14 days, times in ${r}`})]}):e.jsx("p",{style:{...j,margin:0},children:"Not enough readings for a weekly pattern yet."})]})]})}})]})}function Tr(){const[s,n]=v.useState(24),r=F(()=>Cr({hours:s}),[s]),c=Ve.find(i=>i.value===s)?.label||`${s} hours`;return e.jsxs(C,{style:Q,"data-fivestatus-activity":"",children:[e.jsx(S,{action:e.jsx(I,{size:"sm",ariaLabel:"Activity range",value:s,onChange:n,options:Ve}),children:"Resources added and removed across FiveM"}),e.jsxs("p",{style:W,children:["Every install and removal FiveStatus saw on any public server in the last ",c,"."]}),e.jsx(Y,{id:"activity",query:r,fallback:"Could not load FiveM-wide changes from FiveStatus. Try again in a minute.",children:(i,d)=>{const h=$t(i.summary),a=(Array.isArray(i.perHour)?i.perHour:[]).filter(Boolean).map((y,b)=>({key:`${y.hour}-${b}`,label:He(y.hour),value:D(y.changes)??0,installs:D(y.installs),removals:D(y.removals)})),u=a.length>0&&a.every(y=>y.installs!==null&&y.removals!==null),x=Math.max(1,...a.map(y=>
1Math.max(y.installs??0,y.removals??0))),m=D(i.perHourHours),l=m!==null&&m<s?m:null,o=d("summary")||!i.summary&&U(i);return e.jsxs(e.Fragment,{children:[o?e.jsx(k,{off:o}):e.jsxs(ae,{min:140,children:[e.jsx(E,{label:"Installs",value:g(h.installs)}),e.jsx(E,{label:"Removals",value:g(h.removals)}),e.jsx(E,{label:"Servers that changed",value:g(h.serversChanged)}),e.jsx(E,{label:"Resources moved",value:g(h.resourcesMoved)})]}),d("perHour")?e.jsx(k,{off:d("perHour")}):a.length>0&&e.jsxs("div",{style:{marginTop:t.sp(4)},children:[e.jsxs("h4",{style:ue,children:[u?"Installs and removals per hour":"Changes per hour",l?`, last ${Math.round(l/24)} days`:""]}),u?e.jsxs(e.Fragment,{children:[e.jsx(J,{height:48,max:x,label:`Installs per hour across FiveM, last ${c}`,series:a.map(y=>({key:y.key,label:`${y.label}, installs`,value:y.installs})),format:y=>`${g(y)} installs`}),e.jsx("div",{style:{height:1,background:t.border}}),e.jsx(J,{down:!0,height:48,max:x,color:t.sub,label:`Removals per hour across FiveM, last ${c}`,series:a.map(y=>({key:y.key,label:`${y.label}, removals`,value:y.removals})),format:y=>`${g(y)} removals`})]}):e.jsx(J,{height:64,label:`Resource changes per hour across FiveM, last ${c}`,series:a,format:y=>`${g(y)} changes`}),e.jsxs("div",{"aria-hidden":"true",style:{display:"flex",justifyContent:"space-between",gap:t.sp(2),fontSize:11,color:t.subtle,marginTop:t.sp(1)},children:[e.jsx("span",{children:a[0].label}),e.jsx("span",{children:a[a.length-1].label})]}),e.jsxs("p",{style:{...j,margin:`${t.sp(2)}px 0 0`},children:[u?"Installs above the line, removals below it, one bar an hour.":"Each bar is one hour's installs and removals together.",l?` FiveStatus keeps ${Math.round(l/24)} days of hourly counts, so the bars stop there while the totals cover ${c}.`:"",h.allTime!==null?` FiveStatus has recorded ${g(h.allTime)} changes${h.recordingSince?` since ${_(h.recordingSince)}`:""}.`:""]})]})]})}})]})}function Dr({rows:s}){return e.jsx("div",{"aria-hidden":"true",style:{display:"grid",gridTemplateColumns:`repeat(${s.length}, minmax(0, 1fr))`,gap:2,marginTop:t.sp(1),fontSize:10.5,color:t.sub,textAlign:"center",lineHeight:1.25},children:s.map(n=>{const[r,c]=n.label.split("-");return e.jsx("span",{style:{minWidth:0},children:c?e.jsxs(e.Fragment,{children:[r,"-",e.jsx("wbr",{}),c]}):r},n.key)})})}function Wr(){const s=F(()=>$s({days:30}),[]);return e.jsxs(C,{style:Q,"data-fivestatus-distribution":"",children:[e.jsx(S,{children:"Players per server"}),e.jsx("p",{style:W,children:"How many servers online had each number of players when CDECAD last counted them. Dashed outlines are the same count 30 days earlier."}),e.jsx(Y,{id:"distribution",query:s,fallback:"Could not load the players-per-server count. Try again in a minute.",children:(n,r)=>{const c=At(n),i=Ft(n.buckets,c?.buckets),d=i.reduce((a,u)=>a+u.servers,0),h=i.find(a=>a.key==="0"),p=r("buckets")||!i.length&&U(n);return p?e.jsx(k,{off:p}):i.length?e.jsxs(e.Fragment,{children:[e.jsx(J,{height:120,label:`Servers online by players on them, ${n.date?V(n.date):"latest count"}`,series:i.map(a=>({key:a.key,label:`${a.label} players`,value:a.servers,outline:c?a.previous:null,title:`${a.label} players: ${g(a.servers)} servers${a.previous!==null?`, ${g(a.previous)} 30 days earlier`:""}`})),format:a=>`${g(a)} servers`}),e.jsx(Dr,{rows:i}),e.jsxs("div",{style:{...j,display:"flex",flexWrap:"wrap",gap:`${t.sp(1)}px ${t.sp(4)}px`,marginTop:t.sp(3)},children:[e.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:t.sp(1.5)},children:[e.jsx("span",{"aria-hidden":"true",style:{width:14,height:10,borderRadius:2,background:t.accent,opacity:.85}}),n.date?V(n.date):"Latest count"]}),c&&e.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:t.sp(1.5)},children:[e.jsx("span",{"aria-hidden":"true",style:{width:14,height:10,borderRadius:2,border:`1.5px dashed ${t.text}`,boxSizing:"border-box",opacity:.75}}),c.date?V(c.date):"30 days earlier"]})]}),h&&d>0&&e.jsxs("p",{style:{...j,margin:`${t.sp(2)}px 0 0`},children:[Math.round(h.servers/d*100),"% of the ",g(d)," servers online had nobody on."]}),!c&&e.jsx(Oe,{title:"Nothing to compare with yet",text:"The count from 30 days earlier shows here as outlines once CDECAD has counted for 30 days."}),e.jsx("div",{className:"adm-sr",children:e.jsxs("table",{children:[e.jsx("caption",{children:"Servers online by players on them"}),e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{scope:"col",children:"Players"}),e.jsx("th",{scope:"col",children:"Servers"}),e.jsx("th",{scope:"col",children:"30 days earlier"})]})}),e.jsx("tbody",{children:i.map(a=>e.jsxs("tr",{children:[e.jsx("td",{children:a.label}),e.jsx("td",{children:g(a.servers)}),e.jsx("td",{children:a.previous===null?"Not counted":g(a.previous)})]},a.key))})]})})]}):e.jsx("p",{style:{...j,margin:0},children:"CDECAD has not counted servers by players yet. The first count shows here the day after the recorder starts."})}})]})}function Er({access:s}){const n=s?.canSeeRevenue!==!1,r=F(()=>Sr({horizon:90}),[],{enabled:n});if(!n)return null;const c=r.error?.response?.status;if(c===401||c===403)return null;const i=r.data;if(!i||i.configured===!1||i.revenue===null||!Array.isArray(i.monthly)&&!i.forecast)return null;const d=String(i.currency||"").toUpperCase(),h=Tt(i.monthly,i.forecast,"revenue"),p=hs(i.forecast),a=(Array.isArray(i.others)?i.others:Array.isArray(i.otherCurrencies)?i.otherCurrencies:[]).map(x=>
1String(x?.currency||x||"").toUpperCase()).filter(Boolean),u=[...h].reverse().find(x=>!x.projected&&x.value!==null);return e.jsxs(C,{style:Q,"data-fivestatus-revenue":"",children:[e.jsx(S,{children:"Subscription revenue a month"}),e.jsxs("p",{style:W,children:["From CDECAD's own billing, not FiveStatus. Each month's total",d?` in ${d}`:"",", with the next 3 months drawn dashed when there is enough history."]}),u&&e.jsxs("p",{style:{...j,margin:`0 0 ${t.sp(3)}px`},children:[e.jsx("span",{style:{color:t.text,fontWeight:650},children:xe(u.value,d)})," in ",u.label,"."]}),h.length?e.jsxs(e.Fragment,{children:[e.jsx(le,{gaps:!0,points:h,height:140,unit:d||"revenue",ariaLabel:`Subscription revenue a month${d?` in ${d}`:""}, with a forecast`}),e.jsx(pe,{points:h})]}):e.jsx("p",{style:{...j,margin:0},children:"No paid months recorded yet."}),p==="insufficient"&&e.jsx(Oe,{text:Dt(i.forecast)}),p==="ready"&&e.jsxs(e.Fragment,{children:[e.jsx(us,{bandLabel:"Likely range, 8 in 10"}),e.jsx("p",{"data-fivestatus-revenue-mape":"",style:{...j,margin:`${t.sp(2)}px 0 0`},children:Re(i.forecast.mape)!==null?e.jsxs(e.Fragment,{children:[e.jsxs("span",{style:{color:t.text,fontWeight:600},children:["Off by ",Re(i.forecast.mape),"% on average"]})," on months held out of the fit."]}):null})]}),typeof i.method=="string"&&i.method.trim()&&e.jsx("p",{"data-fivestatus-revenue-method":"",style:{...j,margin:`${t.sp(2)}px 0 0`},children:i.method.trim()}),a.length>0&&e.jsxs("p",{style:{...j,margin:`${t.sp(2)}px 0 0`},children:["Also billed in ",a.join(", "),". Those are not added in, since the currencies differ."]}),e.jsx(Fs,{caption:"Subscription revenue a month",points:h,unit:d||"Revenue",first:"Month"})]})}function Rr(){const s=F(()=>vr(),[]);return e.jsxs(C,{style:Q,"data-fivestatus-related":"",children:[e.jsx(S,{children:"What CDECAD communities also run"}),e.jsx(Y,{id:"related",query:s,fallback:"Could not load related resources from FiveStatus. Try again in a minute.",children:(n,r)=>{const c=gt(n.resources),i=r("resources")||!Array.isArray(n.resources)&&U(n);return e.jsxs(e.Fragment,{children:[e.jsxs("p",{style:W,children:["Resources found beside CDECAD's core resources",D(n.sampleServers)!==null?` on ${te(n.sampleServers,"server")}`:"",".",n.method?e.jsxs(e.Fragment,{children:[" FiveStatus describes the sample as: ",String(n.method).replace(/\.$/,""),"."]}):null]}),i?e.jsx(k,{off:i}):e.jsx(Ie,{ariaLabel:"Resources on the same servers as CDECAD",empty:"No other resources in the sample yet.",labelWidth:130,rows:c.map(d=>({key:d.name,label:d.name,value:d.share??0,hint:[vt[d.kind]?.label,d.isLibrary?"library":""].filter(Boolean).join(", ").toLowerCase()||void 0})),format:d=>`${Re(d)}%`})]})}})]})}function Mr(){const[s,n]=v.useState(30),r=F(()=>fr({days:s}),[s]);return e.jsxs(C,{style:Q,"data-fivestatus-newcomers":"",children:[e.jsx(S,{action:e.jsx(I,{size:"sm",ariaLabel:"New resources range",value:s,onChange:n,options:jt}),children:"New resources"}),e.jsxs("p",{style:W,children:["Resources FiveStatus first saw in the last ",s," days, possible CADs and MDTs first."]}),e.jsx(Y,{id:"newcomers",query:r,fallback:"Could not load new resources from FiveStatus. Try again in a minute.",children:(c,i)=>{const d=ft(c.rows),h=i("rows")||!Array.isArray(c.rows)&&U(c);if(h)return e.jsx(k,{off:h});const p=typeof c.note=="string"&&c.note.trim()?c.note.trim():"First seen means it crossed FiveStatus' tracking floor, not the day it was released.";return e.jsxs(e.Fragment,{children:[e.jsxs("p",{"data-fivestatus-newcomers-note":"",style:{...j,margin:`-${t.sp(1)}px 0 ${t.sp(3)}px`},children:["FiveStatus: ",p]}),e.jsx(B,{ariaLabel:"New resources",rows:d,stackBelow:760,empty:e.jsx(P,{title:"Nothing new in this range",body:`FiveStatus saw no new resource in the last ${s} days.`}),columns:[{key:"name",label:"Resource",primary:!0,wrap:!0,width:"38%",render:a=>e.jsxs("span",{style:{minWidth:0,display:"block"},children:[e.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:t.sp(2),flexWrap:"wrap",minWidth:0},children:[a.webUrl?e.jsx("a",{href:a.webUrl,target:"_blank",rel:"noopener noreferrer",style:{...re,overflowWrap:"anywhere"},children:a.name}):e.jsx("span",{style:{fontWeight:600,overflowWrap:"anywhere"},children:a.name}),a.looksLikeCad&&e.jsx("span",{"data-fivestatus-cadlike":"",children:e.jsx(z,{tone:"accent",children:"Could be a CAD"})})]}),a.looksLikeCad&&e.jsxs("span",{style:{...j,display:"block"},children:[bt(a.why),"."]})]})},{key:"servers",label:"Servers",render:a=>g(a.servers)},{key:"playersReached",label:"Players reached",render:a=>g(a.playersReached)},{key:"firstSeenAt",label:"First seen",muted:!0,render:a=>a.firstSeenAt?ne(a.firstSeenAt):"-"}]})]})}})]})}function Nr({onServer:s}){const[n,r]=v.useState(30),[c,i]=v.useState(!1),d=F(()=>jr({days:n}),[n]);return e.jsxs(C,{style:Q,"data-fivestatus-flows":"",children:[e.jsx(S,{action:e.jsx(I,{size:"sm",ariaLabel:"Competitor moves range",value:n,onChange:r,options:wt}),children:"Competitor installs and removals"}),e.jsx("p",{style:W,children:"Servers adding and removing each watched CAD or MDT a day. Bars above the line are servers that added it, bars below are servers that removed it."}),e.jsx(Y,{id:"flows",query:d,fallback:"Could not load competitor installs and removals. Try again in a minute.",children:(h,p)=>{const a=kt(h.daily),u=c?a:a.slice(0,6),x=Ct(h.flows),m=p("daily")||!h.daily&&U(h);return e.jsxs(e.Fragment,{children:[m?e.jsx(k,{off:m}):a.length?e.jsxs(e.Fragment,{children:[e.jsx("div",{style:ie(240),"data-fivestatus-flow-daily":"",children:u.map(l=>{const o=Math.max(1,...l.rows.map(y=>
1Math.max(y.installs,y.removals)));return e.jsxs("div",{style:{minWidth:0,padding:t.sp(3),borderRadius:t.r.control,border:`1px solid ${t.hair}`},children:[e.jsxs("div",{style:{display:"flex",justifyContent:"space-between",gap:t.sp(2),alignItems:"baseline",marginBottom:t.sp(2)},children:[e.jsx("span",{style:{fontSize:13.5,fontWeight:650,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",minWidth:0},children:l.name}),e.jsxs("span",{style:{...j,flex:"none"},children:[ys(l.net)," net"]})]}),e.jsx(J,{height:34,max:o,label:`${l.name}: servers that added it each day, ${g(l.installs)} in all`,series:l.rows.map(y=>({key:y.date,label:`${V(y.date)}, added`,value:y.installs})),format:y=>te(y,"server")}),e.jsx("div",{style:{height:1,background:t.border}}),e.jsx(J,{down:!0,height:34,max:o,color:t.sub,label:`${l.name}: servers that removed it each day, ${g(l.removals)} in all`,series:l.rows.map(y=>({key:y.date,label:`${V(y.date)}, removed`,value:y.removals})),format:y=>te(y,"server")}),e.jsxs("div",{style:{...j,display:"flex",justifyContent:"space-between",gap:t.sp(2),marginTop:t.sp(1)},children:[e.jsxs("span",{children:[g(l.installs)," added"]}),e.jsxs("span",{children:[g(l.removals)," removed"]})]})]},l.name)})}),a.length>6&&e.jsx("div",{style:{marginTop:t.sp(2)},children:e.jsx(O,{size:"sm",kind:"quiet",onClick:()=>i(!c),children:c?"Show the busiest 6":`Show all ${a.length}`})})]}):e.jsx("p",{style:{...j,margin:0},children:"No installs or removals of a watched resource in this range."}),e.jsxs("div",{style:{marginTop:t.sp(5)},children:[e.jsx("h4",{style:ue,children:"Servers that swapped one for another"}),e.jsx("p",{style:{...j,margin:`0 0 ${t.sp(2)}px`},children:"A server that removed one watched resource and added another within 7 days, from the changes CDECAD keeps."}),p("flows")?e.jsx(k,{off:p("flows")}):e.jsx(B,{ariaLabel:"Servers that swapped one watched resource for another",rows:x,stackBelow:760,empty:e.jsx(P,{title:"No swaps in this range",body:`No server swapped one watched CAD or MDT for another in the last ${n} days.`}),columns:[{key:"sentence",label:"Move",primary:!0,wrap:!0,width:"36%",render:l=>e.jsx("span",{"data-fivestatus-flow":"",style:{fontWeight:600,overflowWrap:"anywhere"},children:l.sentence})},{key:"players",label:"Players on them",render:l=>g(l.players)},{key:"examples",label:"For example",wrap:!0,render:l=>l.examples.length?e.jsx("span",{style:{display:"flex",flexDirection:"column",gap:2,minWidth:0},children:l.examples.slice(0,3).map(o=>e.jsxs("span",{style:{minWidth:0},children:[e.jsx(me,{joinCode:o.joinCode,name:o.name,onServer:s}),o.at?e.jsxs("span",{style:j,children:[" ",ne(o.at)]}):null]},`${o.joinCode}-${o.at}`))}):"-"}]})]})]})}})]})}function Lr({rows:s,onServer:n}){const r=Rt(s.map(d=>d.relative)),c=22,i=r.lanes*c+8;return e.jsxs("div",{"data-fivestatus-strip":"",children:[e.jsxs("div",{style:{position:"relative",height:i,margin:`${t.sp(2)}px 0 0`},children:[e.jsx("div",{"aria-hidden":"true",style:{position:"absolute",top:0,bottom:0,left:"50%",width:1,background:t.border}}),s.map((d,h)=>{const p=r.dots[h];if(!p)return null;const a=`${d.name||d.joinCode}: ${q(d.relative)} against FiveM. ${js(d.confidence)}`;return e.jsx("button",{type:"button",className:"adm-btn","aria-label":a,title:a,"data-fivestatus-dot":d.enough?"enough":d.confidence||"other",onClick:()=>n({joinCode:d.joinCode,name:d.name}),style:{position:"absolute",left:`${p.x}%`,top:4+p.lane*c,transform:"translateX(-50%)",width:22,height:22,padding:0,border:"none",background:"transparent",cursor:"pointer",display:"inline-flex",alignItems:"center",justifyContent:"center"},children:e.jsx("span",{"aria-hidden":"true",style:{width:12,height:12,borderRadius:6,boxSizing:"border-box",background:d.enough?t.accent:"transparent",border:d.enough?`1.5px solid ${t.card}`:`1.5px solid ${t.sub}`}})},d._id)})]}),e.jsxs("div",{"aria-hidden":"true",style:{display:"flex",justifyContent:"space-between",fontSize:11,color:t.subtle,marginTop:t.sp(1)},children:[e.jsx("span",{children:q(-r.span)}),e.jsx("span",{children:"Same as FiveM"}),e.jsx("span",{children:q(r.span)})]}),e.jsxs("div",{style:{...j,display:"flex",flexWrap:"wrap",gap:`${t.sp(1)}px ${t.sp(4)}px`,marginTop:t.sp(2)},children:[e.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:t.sp(1.5)},children:[e.jsx("span",{"aria-hidden":"true",style:{width:10,height:10,borderRadius:5,background:t.accent}}),"Enough days to compare"]}),e.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:t.sp(1.5)},children:[e.jsx("span",{"aria-hidden":"true",style:{width:10,height:10,borderRadius:5,border:`1.5px solid ${t.sub}`,boxSizing:"border-box"}}),"Too soon or too noisy, left out of the median"]})]})]})}const Pr={enough:"Enough days",too_soon:"Too soon",too_noisy:"Too noisy"};function zr({resources:s,onServer:n}){const[r,c]=v.useState("cdecad"),[i,d]=v.useState("installed"),[h,p]=v.useState(!1),a=F(()=>$r({resource:r,action:i,days:180}),[r,i]),u=v.useMemo(()=>
1[...new Set(["cdecad",...(Array.isArray(s)?s:[]).map(l=>String(l||"").toLowerCase()).filter(Boolean)])],[s]),x=i==="removed"?"removes":"adds";return e.jsxs(C,{style:Q,"data-fivestatus-impact":"",children:[e.jsxs(S,{children:["What happens after a server ",x," a resource"]}),e.jsx("p",{style:W,children:"Each server's players in the 14 days after the change against the 14 days before, on the same weekdays, minus what FiveM as a whole did over those days."}),e.jsxs(ee,{children:[e.jsx(Z,{"aria-label":"Resource",value:r,onChange:m=>c(m.target.value),style:{maxWidth:220},children:u.map(m=>e.jsx("option",{value:m,children:m},m))}),e.jsx(I,{size:"sm",ariaLabel:"Added or removed",value:i,onChange:d,options:ut})]}),e.jsx(Y,{id:"impact",query:a,fallback:"Could not load before and after numbers. Try again in a minute.",children:(m,l)=>{const o=pt(m.servers),y=mt(m.summary),b=l("servers")||!Array.isArray(m.servers)&&U(m),R=D(m.leftOut??m.omitted),w=D(m.unread);if(b)return e.jsx(k,{off:b});if(!o.length)return e.jsx(P,{title:"No servers to compare",body:`CDECAD has not recorded a server that ${i==="removed"?"removed":"added"} ${r} in the last 180 days.`});const f=h?o:o.slice(0,8);return e.jsxs(e.Fragment,{children:[m.watched===!1&&e.jsxs("p",{style:{...j,margin:`0 0 ${t.sp(3)}px`},children:["CDECAD keeps changes for ",r," for 3 days only, since it is not ours or a competitor, so every server here is too soon to tell."]}),e.jsxs(ae,{min:150,children:[e.jsx(E,{label:"Typical change against FiveM",value:y.median===null?"-":q(y.median),hint:yt(y)||void 0}),e.jsx(E,{label:"Servers after the change",value:`${g(y.improved)} up, ${g(y.declined)} down`,hint:`Against FiveM, of ${te(y.enough,"server")} with enough days`})]}),Ue(y,i,r)&&e.jsxs("p",{"data-fivestatus-median":"",style:{...j,color:t.text,margin:`${t.sp(3)}px 0 0`},children:[Ue(y,i,r),"."]}),e.jsx(Lr,{rows:o,onServer:n}),e.jsxs("p",{"data-fivestatus-impact-note":"",style:{...j,margin:`${t.sp(3)}px 0 ${t.sp(3)}px`},children:[String(m.note||"").trim()||xt,R?` ${te(R,"more server was","more servers were")} left out to stay inside the FiveStatus budget.`:"",w?` ${te(w,"server","servers")} could not be read just now and ${w===1?"is":"are"} not counted.`:""]}),e.jsx(B,{ariaLabel:`Servers that ${i==="removed"?"removed":"added"} ${r}`,rows:f,stackBelow:760,columns:[{key:"name",label:"Server",primary:!0,wrap:!0,width:"40%",render:M=>e.jsx(me,{joinCode:M.joinCode,name:M.name,onServer:n})},{key:"at",label:i==="removed"?"Removed":"Added",muted:!0,render:M=>_(M.at)},{key:"relative",label:"Against FiveM",render:M=>q(M.relative)},{key:"confidence",label:"Compared",muted:!0,render:M=>Pr[M.confidence]||"Not enough days"}]}),o.length>8&&e.jsx("div",{style:{marginTop:t.sp(2)},children:e.jsx(O,{size:"sm",kind:"quiet",onClick:()=>p(!h),children:h?"Show 8":`Show all ${o.length}`})})]})}})]})}function Ir({atRisk:s}){if(!s)return null;const n=(Array.isArray(s.others)?s.others:[]).filter(r=>r&&r.currency);return e.jsxs("div",{"data-fivestatus-revenue-risk":"",style:{marginBottom:t.sp(4)},children:[e.jsxs(ae,{min:160,children:[e.jsx(E,{label:"Revenue at risk, high",value:`${xe(s.high,s.currency)}`,hint:"A month, from customers scored high risk"}),e.jsx(E,{label:"Revenue to watch",value:`${xe(s.watch,s.currency)}`,hint:"A month, from customers scored watch"})]}),n.length>0&&e.jsxs("p",{style:{...j,margin:`${t.sp(2)}px 0 0`},children:["In other currencies, not added in: ",n.map(r=>`${xe(r.high,r.currency)} high and ${xe(r.watch,r.currency)} watch`).join("; "),"."]})]})}function Br({onServer:s,regions:n,frameworks:r}){const[c,i]=v.useState(""),[d,h]=v.useState(""),[p,a]=v.useState(""),[u,x]=v.useState(""),[m,l]=v.useState(1),[o,y]=v.useState([]),b=f=>M=>{f(M.target.value),l(1)},R=F(()=>gr({resource:c,region:d,framework:p,minPlayers:u,page:m}),[c,d,p,u,m]),w=R.data?.resources;return v.useEffect(()=>{Array.isArray(w)&&w.length&&y(w.map(f=>f.name).filter(Boolean))},[w]),e.jsxs("div",{"data-fivestatus-switch":"",children:[e.jsx("p",{style:{...W,margin:`0 0 ${t.sp(3)}px`,maxWidth:760},children:"Every server FiveStatus lists running a competing CAD or MDT, read once a day. Customers stay in the list and are marked, so you can see who runs both."}),e.jsxs("div",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fit, minmax(min(150px, 100%), 1fr))",gap:t.sp(2),marginBottom:t.sp(3),maxWidth:840},children:[e.jsxs(Z,{"aria-label":"Competitor",value:c,onChange:b(i),children:[e.jsx("option",{value:"",children:"Every competitor"}),o.map(f=>e.jsx("option",{value:f,children:f},f))]}),e.jsxs(Z,{"aria-label":"Region",value:d,onChange:b(h),children:[e.jsx("option",{value:"",children:"Every region"}),n.map(f=>e.jsx("option",{value:f.value,children:f.label},f.value))]}),e.jsxs(Z,{"aria-label":"Framework",value:p,onChange:b(a),children:[e.jsx("option",{value:"",children:"Every framework"}),r.map(f=>e.jsx("option",{value:f.value,children:f.label},f.value))]}),e.jsx(Z,{"aria-label":"Players",value:u,onChange:b(x),children:ct.map(f=>e.jsx("option",{value:f.value,children:f.label},f.value))})]}),e.jsx(Y,{id:"switch",query:R,fallback:"Could not load servers running a competitor. Try again in a minute.",height:240,children:(f,M)=>{const ye=ht(f.rows),We=M("rows")||!Array.isArray(f.rows)&&U(f),Ws=M("resources"),_e=Array.isArray(f.resources)?f.resources.filter($=>$&&$.name):[];return e.jsxs(e.Fragment,{children:[!We&&!Ws&&_e.length>0&&e.jsx("div",{"data-fivestatus-switch-resources":"",style:{...ie(170),marginBottom:t.sp(4)},children:_e.map($=>e.jsxs("div",{style:{minWidth:0,padding:t.sp(3),borderRadius:t.r.control,border:`1px solid ${t.border}`,background:t.card},children:[e.jsx("div",{style:{fontSize:13.5,fontWeight:650,color:t.text,overflowWrap:"anywhere"},children:$.name}),$.tracked===!1?e.jsx("div",{style:j,children:"FiveStatus does not track it, so no servers are listed."}):D($.servers)===null?e.jsx("div",{style:j,children:"Not read just now. It is read again within the day."}):e.jsxs(e.Fragment,{children:[e.jsx("div",{style:{fontSize:18,fontWeight:700,color:t.text,fontVariantNumeric:"tabular-nums"},children:te(D($.servers),"server")}),e.jsxs("div",{style:j,children:[D($.players)!==null?`${g($.players)} players on them`:"Players not read",$.fetchedAt?`, read ${ne($.fetchedAt)}`:""]}),$.complete===!1&&e.jsx("div",{"data-fivestatus-switch-partial":"",style:j,children:"Only its busiest 100 so far. The recorder reads the full list once a day."})]})]},$.name))}),We?e.jsx(k,{off:We}):e.jsxs(C,{children:[f.totals&&e.jsxs("p",{"data-fivestatus-switch-totals":"",style:{...j,margin:`0 0 ${t.sp(3)}px`},children:[te(D(f.totals.servers)??0,"server")," match, with ",g(f.totals.players)," players on them now."]}),e.jsx(B,{ariaLabel:"Servers running a competitor",rows:ye,stackBelow:1e3,empty:e.jsx(P,{title:"No servers for this filter",body:"Try every competitor, every region or any number of players."}),columns:[{key:"name",label:"Server",primary:!0,wrap:!0,width:"30%",render:$=>{const H=Ae($.webUrl),de=Ae($.connectUrl);return e.jsxs("span",{style:{minWidth:0,display:"block"},children:[e.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:t.sp(2),flexWrap:"wrap",minWidth:0},children:[e.jsx(me,{joinCode:$.joinCode,name:$.name,onServer:s}),$.customer&&e.jsx("span",{"data-fivestatus-customer":"",children:e.jsx(z,{tone:"accent",children:"Customer"})})]}),e.jsx("span",{style:{...j,display:"block",overflowWrap:"anywhere"}
1,children:[$.region?.name,$.framework?.label].filter(Boolean).join(" · ")||"Region and framework not known"}),(H||de)&&e.jsxs("span",{style:{display:"inline-flex",gap:t.sp(3),flexWrap:"wrap",fontSize:12.5,marginTop:2},children:[H&&e.jsx("a",{href:H,target:"_blank",rel:"noopener noreferrer",style:re,children:"FiveStatus page"}),de&&e.jsx("a",{href:de,target:"_blank",rel:"noopener noreferrer",style:re,children:"Connect"})]})]})}},{key:"runs",label:"Runs",wrap:!0,render:$=>$.runs.length?e.jsx("span",{style:{display:"inline-flex",flexWrap:"wrap",gap:t.sp(1)},children:$.runs.map(H=>e.jsx(z,{dot:!1,children:H},H))}):"-"},{key:"players",label:"Players",wrap:!0,render:$=>e.jsxs("span",{style:{whiteSpace:"nowrap"},children:[g($.players)," now, peak ",g($.peak24h)]})},{key:"population",label:"Population",wrap:!0,width:"22%",render:$=>{const H=ps($);return H?e.jsxs("span",{style:{minWidth:0},children:[H.label&&e.jsx(z,{dot:!1,children:H.label}),H.note&&e.jsx("span",{style:{...j,display:"block",marginTop:2},children:H.note})]}):e.jsx("span",{style:{color:t.sub},children:"No label yet"})}},{key:"score",label:"Score",wrap:!0,width:"20%",render:$=>{const H=ms($.reasons);return e.jsxs("span",{style:{minWidth:0},children:[e.jsx("span",{style:{display:"block",fontWeight:650},children:g($.score)}),H.slice(0,2).map(de=>e.jsx("span",{style:{...j,display:"block"},children:de.text},de.key))]})}}]}),e.jsx(rs,{page:f.page||m,pages:f.pages,onPage:l,noun:"server"})]})]})}}),R.data&&e.jsx(Be,{data:R.data,section:"leads"})]})}function Or({lines:s}){return e.jsx("ul",{"data-fivestatus-compare-legend":"",style:{listStyle:"none",margin:`${t.sp(3)}px 0 0`,padding:0,display:"grid",gridTemplateColumns:"repeat(auto-fit, minmax(min(170px, 100%), 1fr))",gap:`${t.sp(1.5)}px ${t.sp(4)}px`},children:s.map(n=>e.jsxs("li",{style:{display:"flex",alignItems:"center",gap:t.sp(2),fontSize:13,minWidth:0},children:[e.jsx(Et,{dash:n.dash,tone:n.tone}),e.jsxs("span",{style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",minWidth:0},children:[n.name,n.short!==n.name?e.jsxs("span",{style:{color:t.subtle},children:[" (",n.short,")"]}):null]}),e.jsx("span",{style:{marginLeft:"auto",color:t.sub,fontVariantNumeric:"tabular-nums",flex:"none"},children:g(n.latest)})]},n.key))})}function Hr({regions:s,frameworks:n}){const[r,c]=v.useState("region"),[i,d]=v.useState(90),h=r==="region"?s:n,[p,a]=v.useState(""),u=h.some(o=>o.value===p)?p:h[0]?.value||"",x=F(()=>br({kind:r,segment:u,days:i}),[r,u,i],{enabled:!!u}),m=F(()=>wr({kind:r,days:i}),[r,i]),l=r==="region"?"region":"framework";return e.jsxs(e.Fragment,{children:[e.jsxs(C,{style:Q,"data-fivestatus-segment":"",children:[e.jsxs(S,{children:["One ",l," over time"]}),e.jsx("p",{style:W,children:"Average players a day, with the next 30 days forecast the same way as FiveM as a whole."}),e.jsxs(ee,{children:[e.jsx(I,{size:"sm",ariaLabel:"Regions or frameworks",value:r,onChange:o=>{c(o),a("")},options:it}),e.jsx(Z,{"aria-label":r==="region"?"Region to chart":"Framework to chart",value:u,onChange:o=>a(o.target.value),style:{maxWidth:220},children:h.map(o=>e.jsx("option",{value:o.value,children:o.label},o.value))}),e.jsx(I,{size:"sm",ariaLabel:"Trend range",value:i,onChange:d,options:lt})]}),!u&&e.jsxs("p",{style:{...j,margin:0},children:["FiveStatus has not listed any ",r==="region"?"regions":"frameworks"," yet, so there is nothing to chart."]}),u&&e.jsx(Y,{id:"segment",query:x,fallback:"Could not load this segment's history. Try again in a minute.",height:200,children:(o,y)=>{const b=o.label||h.find(f=>f.value===u)?.label||u,R=ze((Array.isArray(o.hourly)?o.hourly:[]).map(f=>({at:f.hour,players:f.players})),He),w=y("daily")||!o.daily&&U(o);return e.jsxs(e.Fragment,{children:[w?e.jsx(k,{off:w}):e.jsx(De,{daily:o.daily,forecast:o.forecast,valueKey:"playersAvg",unit:"players",what:b,ariaLabel:`Average players a day in ${b}, with a 30-day forecast`}),e.jsxs("div",{style:{marginTop:t.sp(5)},children:[e.jsxs("h4",{style:ue,children:[b,", every hour of the last 14 days"]}),y("hourly")?e.jsx(k,{off:y("hourly")}):R.length?e.jsxs(e.Fragment,{children:[e.jsx(le,{points:R,height:100,unit:"players",ariaLabel:`Players in ${b} every hour over the last 14 days`}),e.jsx(pe,{points:R})]}):e.jsx("p",{style:{...j,margin:0},children:"No hours recorded in the last 14 days."})]})]})}})]}),e.jsxs(C,{style:Q,"data-fivestatus-compare":"",children:[e.jsxs(S,{children:["The top 8 ",r==="region"?"regions":"frameworks"," compared"]}),e.jsx("p",{style:W,children:"Average players a day on one scale. Eac
1h line has its own dash pattern and is named at its right end and in the key below."}),e.jsx(Y,{id:"compare",query:m,fallback:"Could not load the comparison. Try again in a minute.",height:200,children:(o,y)=>{const{dates:b,lines:R}=ot(o.series),w=y("series")||!Array.isArray(o.series)&&U(o);if(w)return e.jsx(k,{off:w});if(!R.length)return e.jsx("p",{style:{...j,margin:0},children:"Nothing recorded for this range yet."});const f=[{key:b[0],label:V(b[0])},{key:b[b.length-1],label:V(b[b.length-1])}];return e.jsxs(e.Fragment,{children:[e.jsx(dt,{dates:b,lines:R,height:200,unit:"players",labelOf:M=>V(M),ariaLabel:`Average players a day, top ${R.length} ${r==="region"?"regions":"frameworks"}, over ${i} days`}),e.jsx(pe,{points:f}),e.jsx(Or,{lines:R}),e.jsx("div",{className:"adm-sr",children:e.jsxs("table",{children:[e.jsxs("caption",{children:["Latest average players a day, top ",R.length]}),e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{scope:"col",children:r==="region"?"Region":"Framework"}),e.jsx("th",{scope:"col",children:"Players"})]})}),e.jsx("tbody",{children:R.map(M=>e.jsxs("tr",{children:[e.jsx("td",{children:M.name}),e.jsx("td",{children:g(M.latest)})]},M.key))})]})})]})}})]})]})}function _r({storage:s,off:n}){const r=Wt(s);return!r&&n?e.jsxs("div",{"data-fivestatus-storage":"",style:{marginTop:t.sp(5)},children:[e.jsx("h4",{style:ue,children:"What CDECAD stores"}),e.jsx(k,{off:n})]}):r?e.jsxs("div",{"data-fivestatus-storage":"",style:{marginTop:t.sp(5)},children:[e.jsx("h4",{style:ue,children:"What CDECAD stores"}),e.jsxs("p",{style:{...j,margin:`0 0 ${t.sp(2)}px`},children:[e.jsxs("span",{style:{color:t.text,fontWeight:650},children:[he(r.total)," of the ",he(r.budget)," budget"]}),r.percent!==null?`, ${Math.round(r.percent)}%.`:".",r.over?" That is over the budget.":"",r.planned!==null?` The budget table plans for ${he(r.planned)} once every collection is full.`:""]}),r.percent!==null&&e.jsx("div",{role:"img","aria-label":`${he(r.total)} of ${he(r.budget)} used`,style:{height:8,borderRadius:4,background:t.press,overflow:"hidden",marginBottom:t.sp(3)},children:e.jsx("div",{style:{width:`${r.percent}%`,height:"100%",background:r.over?t.danger:t.accent,borderRadius:4}})}),e.jsx(B,{ariaLabel:"FiveStatus collections and their size",rows:r.rows,stackBelow:760,empty:e.jsx(P,{title:"No collections reported"}),columns:[{key:"name",label:"Collection",primary:!0,wrap:!0,render:c=>e.jsx("span",{style:{fontWeight:600,overflowWrap:"anywhere"},children:c.name})},{key:"rows",label:"Rows",render:c=>g(c.rows)},{key:"mb",label:"Size",render:c=>`${he(c.mb)}${c.measured===!1?", estimated":""}`},{key:"retention",label:"Kept",wrap:!0,muted:!0,render:c=>c.retention||"-"}]})]}):null}const Ur={added:"Added a resource",removed:"Removed a resource",both:"Added and removed"};function qr(){return e.jsx("div",{style:{...j,display:"flex",flexWrap:"wrap",gap:`${t.sp(1)}px ${t.sp(4)}px`,marginTop:t.sp(1)},children:Object.entries(Ur).map(([s,n])=>e.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:t.sp(1.5)},children:[e.jsx(ws,{shape:s,size:12}),n]},s))})}function es({title:s,side:n}){return e.jsxs("div",{style:{minWidth:0,padding:t.sp(3),borderRadius:t.r.control,background:t.press},children:[e.jsxs("div",{style:{...j,marginBottom:2},children:[s,n.days!==null?`, ${n.days} ${n.days===1?"day":"days"}`:""]}),e.jsx("div",{style:{fontSize:18,fontWeight:700,color:t.text,fontVariantNumeric:"tabular-nums"},children:g(n.avg===null?null:Math.round(n.avg))}),e.jsxs("div",{style:j,children:["players on average",n.peak!==null?`, peak ${g(n.peak)}`:""]})]})}function Gr({change:s,entry:n}){const r=zt(n);return e.jsxs("div",{"data-fivestatus-impact-card":"",style:{border:`1px solid ${t.border}`,borderRadius:t.r.card,padding:t.sp(4),display:"flex",flexDirection:"column",gap:t.sp(3)},children:[e.jsxs("div",{children:[e.jsx("div",{style:{fontSize:14,fontWeight:650,color:t.text},children:s.what}),e.jsx("div",{style:j,children:_(s.at,{time:!0})})]}),r?e.jsxs(e.Fragment,{children:[e.jsxs("div",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fit, minmax(min(150px, 100%), 1fr))",gap:t.sp(2)},children:[e.jsx(es,{title:"Before",side:r.before}),e.jsx(es,{title:"After",side:r.after})]}),e.jsx(Ne,{items:[["This server",r.change===null?null:`${q(r.change)} players`],["FiveM, same days",r.fivem===null?"CDECAD has not stored FiveM for these days":`${q(r.fivem)} players`],["Difference",r.relative===null?null:e.jsxs("span",{style:{fontWeight:650},children:[q(r.relative)," against FiveM"]},"d")],["How sure",`${js(r.confidence)}${r.spread!==null?` Before it, players swung ${Te(r.spread)} from week to week.`:""}`]]}),e.jsx("p",{"data-fivestatus-impact-note":"",style:{...j,margin:0},children:r.note})]}):e.jsx("p",{style:{...j,margin:0},children:"CDECAD has no before and after for this change yet. It is worked out once there are recorded days on both sides of it."})]})}function Vr({joinCode:s}){const n=F(()=>$s({joinCode:s}),[s]),r=Lt(n.data?.position,n.data?.buckets);return!r||!r.text?null:e.jsxs("p",{"data-fivestatus-position":"",style:{margin:0,fontSize:14,color:t.text},children:[e.jsx("span",{style:{fontWeight:650},children:r.text}),r.bucket?e.jsxs("span",{style:{color:t.sub},children:[", in the ",r.bucket," players group",n.data?.date?` on ${V(n.data.date)}`:"","."]}):"."]})}const Kr=(s,n)=>{const r=Math.round((Date.parse(`${n}T00:00:00Z`)-Date.parse(`${s}T00:00:00Z`))/864e5)+1;return(ve.find(c=>c.value>=r)||ve[ve.length-1]).value};function Yr({d:s,title:n}){const[r,c]=v.useState(90),[i,d]=v.useState(null),h=v.useMemo(()=>Pe(s.daily,s.forecast,"average"),[s.daily,s.forecast]),p=v.useMemo(()=>{const l=h.filter(o=>!o.projected);return l.length?l[l.length-1].key:""},[h]),a=v.useMemo(()=>Ke(s.changes,h),[s.changes,h]),u=v.useMemo(()=>l=>Ke(s.changes,l),[s.changes]),x=a.find(l=>l.key===i)||null,m=l=>{const o=a.find(y=>y.key===l);o&&p&&!cs(h,r).some(y=>y.key===o.day)&&c(Kr(o.day,p)),d(l)};return e.jsxs("div",{"data-fivestatus-server-players":"",children:[e.jsx(S,{action:e.jsx(I,{size:"sm",ariaLabel:"Players range",value:r,onChange:c,options:ve}),children:"Average players a day"}),e.jsx(De,{daily:s.daily,forecast:s.forecast,valueKey:"average",unit:"players",
1what:"this server",height:150,days:r,markers:u,selectedMarker:i,onMarker:d,ariaLabel:`Average players a day on ${n}, last ${ve.find(l=>l.value===r)?.label}, with a 30-day forecast`}),a.length>0&&e.jsxs("div",{style:{marginTop:t.sp(3)},children:[e.jsx(qr,{}),e.jsx("p",{style:{...j,margin:`${t.sp(2)}px 0 ${t.sp(2)}px`},children:"Each mark under the chart is a resource change. Pick one, there or in the list below, to see the players before and after it."}),x&&e.jsx("div",{style:{margin:`${t.sp(3)}px 0`},children:e.jsx(Gr,{change:x,entry:Pt(s.impact,x.at)})}),e.jsx("div",{role:"list","aria-label":"Resource changes on this server",style:{display:"flex",flexDirection:"column",gap:t.sp(1)},children:[...a].reverse().map(l=>e.jsx("div",{role:"listitem",children:e.jsxs("button",{type:"button",className:"adm-btn","aria-pressed":l.key===i,"data-fivestatus-change":l.shape,onClick:()=>m(l.key===i?null:l.key),style:{display:"flex",alignItems:"center",gap:t.sp(2),width:"100%",textAlign:"left",padding:`${t.sp(1.5)}px ${t.sp(2)}px`,borderRadius:t.r.control,border:`1px solid ${l.key===i?t.text:t.hair}`,background:l.key===i?t.press:"transparent",color:t.text,font:"inherit",fontSize:13,cursor:"pointer"},children:[e.jsx(ws,{shape:l.shape,size:12}),e.jsx("span",{style:{minWidth:0,overflowWrap:"anywhere"},children:l.what}),e.jsx("span",{style:{marginLeft:"auto",color:t.sub,flex:"none"},children:V(l.day)})]})},l.key))})]})]})}function Qr({target:s,access:n,onClose:r}){const c=F(()=>xr(s.joinCode),[s.joinCode]),i=c.data,d=Mt(i?.server),h=Nt(i?.standing),p=d.name||s.name||`cfx.re/join/${s.joinCode}`;return e.jsx(ns,{title:p,onClose:r,width:760,children:e.jsx(oe,{id:"server",query:c,fallback:"Could not load this server from FiveStatus. Try again in a minute.",children:(a,u)=>{const x=ze((Array.isArray(a.hourly)?a.hourly:[]).filter(Boolean).map(l=>({at:l.hour,average:l.average??l.players})),l=>_(l,{time:!0})),m=bs(a.changes).length;return e.jsxs("div",{"data-fivestatus-server":"",style:{display:"flex",flexDirection:"column",gap:t.sp(5)},children:[u("server")&&e.jsx(k,{off:u("server")}),u("standing")&&e.jsx(k,{off:u("standing")}),e.jsx(Vr,{joinCode:d.joinCode||s.joinCode}),e.jsx(Ne,{items:[a.customer?["Customer",e.jsx(be,{row:a.customer,access:n},"c")]:null,["Players now",d.players!==null?`${g(d.players)}${d.maxPlayers!==null?` of ${g(d.maxPlayers)}`:""}`:null],["Rank",h.rank!==null?`${g(h.rank)}${h.outOf!==null?` of ${g(h.outOf)}`:""}`:"Not ranked while empty"],["Rank change",h.change7d!==null||h.change30d!==null?`${Me(h.change7d).replace(/^./,l=>l.toUpperCase())} in 7 days, ${Me(h.change30d)} in 30`:null],["Listed",h.listedPercent!==null?`${Te(h.listedPercent)} of hours`:null],["Join code",e.jsx(ts,{children:d.joinCode||s.joinCode},"j")]]}),(d.webUrl||d.connectUrl)&&e.jsxs("div",{style:{display:"flex",gap:t.sp(4),flexWrap:"wrap",fontSize:13.5},children:[d.webUrl&&e.jsx("a",{href:d.webUrl,target:"_blank",rel:"noopener noreferrer",style:re,children:"FiveStatus page"}),d.connectUrl&&e.jsx("a",{href:d.connectUrl,target:"_blank",rel:"noopener noreferrer",style:re,children:"Connect"})]}),u("daily")?e.jsxs("div",{children:[e.jsx(S,{children:"Average players a day"}),e.jsx(k,{off:u("daily")})]}):e.jsx(Yr,{d:a,title:p}),u("changes")&&e.jsx(k,{off:u("changes")}),!u("changes")&&!m&&e.jsx("p",{style:{...j,margin:0},children:"No resource changes recorded on this server."}),e.jsxs("div",{children:[e.jsx(S,{children:"Players every hour, last 14 days"}),u("hourly")?e.jsx(k,{off:u("hourly")}):x.length?e.jsxs(e.Fragment,{children:[e.jsx(le,{points:x,height:100,unit:"players",ariaLabel:`Players every hour on ${p} over the last 14 days`}),e.jsx(pe,{points:x})]}):e.jsx("p",{style:{...j,margin:0},children:"No hours recorded."})]})]})}})})}function Zr({access:s}){const[n,r]=v.useState(30),c=F(()=>hr({horizon:n}),[n]);return e.jsxs(e.Fragment,{children:[e.jsx(oe,{id:"ecosystem",query:c,fallback:"Could not load FiveM's numbers from FiveStatus. Try again in a minute.",after:e.jsxs(e.Fragment,{children:[e.jsx(Fr,{}),e.jsx(Tr,{}),e.jsx(Wr,{})]}),children:(i,d)=>{const h=i.now||{},p=sr(i.busyTimes);return e.jsxs(e.Fragment,{children:[d("now")?e.jsx(k,{off:d("now")}):e.jsxs(ae,{min:160,children:[e.jsx(E,{label:"Playing FiveM now",value:g(h.playersOnline),hint:D(h.change24h?.players)!==null?`${q(h.change24h.players)} on 24 hours ago`:void 0}),e.jsx(E,{label:"Servers online",value:g(h.serversOnline),hint:[D(h.serversPopulated)!==null?`${g(h.serversPopulated)} with players on`:"",D(h.change24h?.servers)!==null?`${q(h.change24h.servers)}
1 on 24 hours ago`:""].filter(Boolean).join(", ")||void 0}),e.jsx(E,{label:"Slots filled",value:Te(h.fillRatePercent),hint:"Players online against every slot servers advertise"})]}),e.jsxs(C,{children:[e.jsx(S,{action:e.jsx(I,{size:"sm",ariaLabel:"Forecast length",value:n,onChange:r,options:tr}),children:"Average players a day"}),e.jsxs("p",{style:W,children:["Each day's average across every public FiveM server, with the next ",n," days forecast from the weekly pattern and the trend."]}),d("daily")?e.jsx(k,{off:d("daily")}):e.jsx(De,{daily:i.daily,forecast:i.forecast,valueKey:"average",unit:"players",what:"FiveM",ariaLabel:`Average players on FiveM a day, with a ${n}-day forecast`})]}),e.jsxs(C,{style:{marginTop:t.sp(4)},children:[e.jsx(S,{children:"When each region is busiest"}),e.jsx("p",{style:W,children:"Average players by hour over the last 14 days, in each region's own local time."}),d("busyTimes")?e.jsx(k,{off:d("busyTimes")}):p.length?e.jsx("div",{style:ie(240),"data-fivestatus-busy":"",children:p.map(a=>e.jsxs("div",{style:{minWidth:0,padding:t.sp(3),borderRadius:t.r.control,border:`1px solid ${t.hair}`},children:[e.jsx("div",{style:{fontSize:14,fontWeight:650,color:t.text,overflowWrap:"anywhere"},children:a.name}),e.jsxs("div",{style:{...j,marginBottom:t.sp(2)},children:["Busiest ",ke(a.peak),", quietest ",ke(a.quiet),a.offset?` (${a.offset})`:""]}),e.jsx(J,{height:48,label:`${a.name}: average players by local hour, busiest at ${ke(a.peak)}`,series:a.hours.map((u,x)=>({key:x,label:ke(x),value:u})),format:u=>`${g(Math.round(u))} players`}),e.jsxs("div",{"aria-hidden":"true",style:{display:"flex",justifyContent:"space-between",fontSize:11,color:t.subtle,marginTop:t.sp(1)},children:[e.jsx("span",{children:"00:00"}),e.jsx("span",{children:"12:00"}),e.jsx("span",{children:"23:00"})]}),Je(a.swing)&&e.jsxs("div",{style:{...j,marginTop:t.sp(1.5)},children:[Je(a.swing),"."]})]},a.key))}):e.jsx("p",{style:{...j,margin:0},children:"FiveStatus has no hourly pattern for any region yet."})]})]})}}),e.jsx(Er,{access:s})]})}function Jr({data:s,canManage:n,onSaved:r}){const[c,i]=v.useState((s.competitors||[]).join(`
2`)),[d,h]=v.useState(!1),[p,a]=v.useState(null),u=(s.competitors||[]).join(`
3`);v.useEffect(()=>{i(u)},[u]);const x=async l=>{h(!0),a(null);try{const o=await ls("/admin/cde-metrics/settings",{competitors:l});je.success("Competing resources saved"),r(o.data?.competitors||l)}catch(o){a(o)}finally{h(!1)}},m=s.competitors||[];return e.jsxs(C,{style:{marginTop:t.sp(4)},"data-fivestatus-competitors":"",children:[e.jsx(S,{children:"Competing CADs and MDTs"}),e.jsx("p",{style:W,children:"The resources Market, Churn, Leads and Changes count as competitors. Recording starts on a new name at the recorder's next pass."}),n?e.jsxs(e.Fragment,{children:[e.jsx(Se,{label:"Competing resources",hint:"One per line, as the resource folder is named, like sonorancad. Up to 30.",children:e.jsx(as,{rows:5,value:c,onChange:l=>i(l.target.value),placeholder:"sonorancad"})}),e.jsxs("div",{style:{display:"flex",justifyContent:"flex-end",gap:t.sp(2),flexWrap:"wrap",marginTop:t.sp(2)},children:[(s.competitorsDefault||[]).length>0&&e.jsx(O,{kind:"quiet",disabled:d,onClick:()=>i(s.competitorsDefault.join(`
4`)),children:"Use the default list"}),e.jsx(O,{disabled:d,onClick:()=>x(c.split(/[\n,]+/).map(l=>l.trim()).filter(Boolean)),children:d?"Saving…":"Save competing resources"})]}),e.jsx(G,{error:p})]}):e.jsxs(e.Fragment,{children:[e.jsx("div",{style:{display:"flex",flexWrap:"wrap",gap:t.sp(1.5)},children:m.map(l=>e.jsx(z,{dot:!1,children:l},l))}),e.jsx("p",{style:{...j,margin:`${t.sp(2)}px 0 0`},children:"A support lead or super admin changes this list."})]})]})}function Xr({access:s,onServer:n}){const[r,c]=v.useState(365),i=F(()=>ur({days:r}),[r]),d=p=>{i.setData(a=>a&&{...a,competitors:p}),i.reload()},h=[...(i.data?.resources||[]).filter(p=>p&&p.name&&p.kind!=="addon").map(p=>p.name),...i.data?.competitors||[]];return e.jsxs("div",{children:[e.jsx(ee,{children:e.jsx(I,{size:"sm",ariaLabel:"Market range",value:r,onChange:c,options:Qt})}),e.jsx(oe,{id:"market",query:i,fallback:"Could not load resource adoption from FiveStatus. Try again in a minute.",after:e.jsxs(e.Fragment,{children:[e.jsx(zr,{resources:h,onServer:n}),e.jsx(Rr,{}),e.jsx(Mr,{}),e.jsx(Nr,{onServer:n}),Array.isArray(i.data?.competitors)&&e.jsx(Jr,{data:i.data,canManage:!!s?.canManage,onSaved:d})]}),children:(p,a)=>{const u=Zt(p.resources),x=Jt(p.resources),m=Qe(p.movers?.gaining),l=Qe(p.movers?.losing);return e.jsxs(e.Fragment,{children:[a("resources")&&e.jsx(k,{off:a("resources")}),!a("resources")&&x&&e.jsxs(C,{children:[e.jsxs(S,{children:[x.name," on public servers"]}
4),e.jsxs("p",{style:W,children:["Servers running ",x.name," each day. ",Ee(x)?`${Ee(x)}.`:""]}),e.jsx(De,{daily:x.daily,forecast:x.forecast,valueKey:"servers",unit:"servers",what:x.name,ariaLabel:`Servers running ${x.name} a day, with a forecast`})]}),!a("resources")&&e.jsxs(C,{style:{marginTop:t.sp(4)},children:[e.jsx(S,{children:"Share and momentum"}),e.jsx("p",{style:W,children:"Our resources beside the competing CADs and MDTs, by servers running each today."}),e.jsx(B,{ariaLabel:"Resources, share and momentum",rows:u,stackBelow:900,empty:e.jsx(P,{title:"No resources recorded",body:"CDECAD has not stored any resource adoption from FiveStatus yet."}),columns:[{key:"name",label:"Resource",primary:!0,wrap:!0,render:o=>e.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:t.sp(2),flexWrap:"wrap",minWidth:0},children:[e.jsx("span",{style:{fontWeight:600,overflowWrap:"anywhere"},children:o.name}),e.jsx(z,{tone:Ze(o.kind).tone,dot:!1,children:Ze(o.kind).label})]})},{key:"servers",label:"Servers",wrap:!0,render:o=>o.tracked===!1?e.jsx("span",{style:{color:t.sub},title:"FiveStatus only tracks resources running on more than a handful of servers.",children:"Not tracked"}):g(o.servers)},{key:"playersReached",label:"Players reached",render:o=>g(o.playersReached)},{key:"share",label:"Share",wrap:!0,muted:!0,render:o=>Xt(o)},{key:"momentum",label:"Momentum",wrap:!0,render:o=>Ee(o)||"-"},{key:"churn",label:"Last 30 days",wrap:!0,muted:!0,render:o=>er(o)||"-"}]})]}),!a("resources")&&u.length>0&&e.jsxs(C,{style:{marginTop:t.sp(4)},children:[e.jsx(S,{children:"Servers over time"}),e.jsx("p",{style:W,children:"One chart each, on its own scale, so a small resource's trend stays visible beside a large one."}),e.jsx("div",{style:ie(260),"data-fivestatus-multiples":"",children:u.map(o=>{const y=Pe(o.daily,null,"servers");return e.jsxs("div",{style:{minWidth:0},children:[e.jsxs("div",{style:{display:"flex",justifyContent:"space-between",gap:t.sp(2),alignItems:"baseline",marginBottom:t.sp(1)},children:[e.jsx("span",{style:{fontSize:13.5,fontWeight:650,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",minWidth:0},children:o.name}),e.jsx("span",{style:{...j,flex:"none"},children:o.tracked===!1?"Not tracked":`${g(o.servers)} now`})]}),y.length?e.jsx(le,{gaps:!0,points:y,height:64,unit:"servers",ariaLabel:`Servers running ${o.name} a day`}):e.jsx("p",{style:{...j,margin:0},children:"No days recorded yet."})]},o.name)})})]}),e.jsxs(C,{style:{marginTop:t.sp(4)},children:[e.jsx(S,{children:"Biggest movers"}),e.jsx("p",{style:W,children:"Net servers gained or lost over the range, for the watched resources and FiveStatus' top 10."}),a("movers")?e.jsx(k,{off:a("movers")}):e.jsx("div",{style:ie(260),"data-fivestatus-movers":"",children:[["Gaining",m],["Losing",l]].map(([o,y])=>e.jsxs("div",{style:{minWidth:0},children:[e.jsx("div",{style:{fontSize:13,fontWeight:650,color:t.sub,marginBottom:t.sp(2)},children:o}),e.jsx(Ie,{ariaLabel:`${o} servers`,empty:"None in this range.",rows:y.map(b=>({key:b.key,label:b.name,value:Math.abs(b.net??0),hint:b.detail})),format:b=>`${o==="Losing"?"-":"+"}${g(b)}`,labelWidth:120})]},o))})]})]})}})]})}function Ts({installed:s=[],removed:n=[]}){return!s.length&&!n.length?e.jsx("span",{style:{color:t.sub},children:"No change recorded"}):e.jsxs("span",{style:{display:"inline-flex",flexWrap:"wrap",gap:t.sp(1.5),minWidth:0},children:[s.map(r=>
4e.jsxs(z,{tone:"good",title:`Added ${r}`,children:["Added ",r]},`i-${r}`)),n.map(r=>e.jsxs(z,{tone:"warn",title:`Removed ${r}`,children:["Removed ",r]},`r-${r}`))]})}function Ds({reasons:s}){const n=ms(s);return n.length?e.jsx("ul",{"data-fivestatus-reasons":"",style:{margin:0,paddingLeft:t.sp(4),display:"flex",flexDirection:"column",gap:t.sp(1),fontSize:13,lineHeight:1.45,color:t.text},children:n.map(r=>e.jsx("li",{style:{overflowWrap:"anywhere"},children:r.text},r.key))}):e.jsx("span",{style:{color:t.sub},children:"Nothing stands out"})}function en({access:s,onServer:n}){const r=F(()=>pr(),[]);return e.jsx(oe,{id:"churn",query:r,fallback:"Could not load churn risk. Try again in a minute.",children:(c,i)=>{const d=Kt(c.servers).map((a,u)=>({...a,_id:`${a.communityId||"c"}-${a.joinCode||u}`}));if(i("servers"))return e.jsx(k,{off:i("servers")});const h=Yt(c),p=[{key:"communityName",label:"Community",primary:!0,wrap:!0,width:h.visible?"20%":"22%",render:a=>e.jsxs("span",{style:{minWidth:0},children:[e.jsx(be,{row:a,access:s}),e.jsxs("span",{style:{...j,display:"block",overflowWrap:"anywhere"},children:[e.jsx(me,{joinCode:a.joinCode,name:a.name||"Unnamed server",onServer:n,style:{fontWeight:500}})," · cfx.re/join/",a.joinCode]})]})},{key:"risk",label:"Risk",render:a=>e.jsxs("span",{"data-fivestatus-risk":a.risk?.level||"",style:{display:"inline-flex",alignItems:"center",gap:t.sp(2)},children:[e.jsx(z,{tone:Xe(a.risk?.level).tone,children:Xe(a.risk?.level).label}),e.jsxs("span",{style:j,children:[g(a.risk?.score)," of 100"]})]})},h.visible?{key:"revenue",label:"Revenue",wrap:!0,render:a=>e.jsx("span",{"data-fivestatus-revenue-cell":"",children:ar(a.revenue)})}:null,{key:"players",label:"Players",wrap:!0,width:"20%",render:a=>e.jsxs("span",{style:{minWidth:0},children:[e.jsx("span",{style:{display:"block"},children:ir(a.peak7d,a.peakPrior)}),e.jsxs("span",{style:{...j,display:"block"},children:[lr(a.rank,a.rankChange30d)," in 30 days",D(a.listedPercent)!==null?` · listed ${Te(a.listedPercent)} of hours`:"",D(a.recordedDays)!==null?` · ${g(a.recordedDays)} ${D(a.recordedDays)===1?"day":"days"} recorded`:""]})]})},{key:"why",label:"Why",wrap:!0,width:"32%",render:a=>e.jsx(Ds,{reasons:a.risk?.reasons})},{key:"lastChange",label:"Last change",wrap:!0,render:a=>a.lastChange?e.jsxs("span",{style:{minWidth:0},children:[e.jsx(Ts,{installed:a.lastChange.installed,removed:a.lastChange.removed}),e.jsx("span",{style:{...j,display:"block",marginTop:2},children:ne(a.lastChange.detectedAt)})]}):e.jsx("span",{style:{color:t.sub},children:"None recorded"})}].filter(Boolean);return e.jsxs(e.Fragment,{children:[i("revenue")&&e.jsx(k,{off:i("revenue")}),h.visible&&e.jsx(Ir,{atRisk:h.atRisk}),e.jsxs(C,{children:[e.jsxs(S,{children:["Customers by churn risk (",d.length,")"]}),e.jsx("p",{style:W,children:"Every linked customer server FiveStatus can see, highest risk first. Each reason says what moved and by how much; the score adds them up. Pick a server to see its players with its resource changes."}),e.jsx(B,{ariaLabel:"Customers by churn risk",rows:d,stackBelow:1e3,empty:e.jsx(P,{title:"No customer servers to score",body:"Link a community's public server on the Communities view; it is scored after the next recording."}),columns:p})]})]})}})}function sn({onServer:s}){const[n,r]=ks(),c=Gt(n.get("leads")),i=F(()=>Ss({days:30}),[]),d=Fe(i.data?.regions,"code","name"),h=Fe(i.data?.frameworks,"slug","label"),p=a=>{const u=new URLSearchParams(n);a==="switch"?u.set("leads","switch"):u.delete("leads"),r(u)};return e.jsxs("div",{children:[e.jsx("div",{style:{marginBottom:t.sp(3)},children:e.jsx(I,{size:"sm",ariaLabel:"Which leads",value:c,onChange:p,options:Vt})}),c==="switch"?e.jsx(Br,{onServer:s,regions:d,frameworks:h}):e.jsx(tn,{onServer:s,regions:d,frameworks:h})]})}function tn({onServer:s,regions:n,frameworks:r}){const[c,i]=v.useState(""),[d,h]=v.useState(""),[p,a]=v.useState(1);v.useEffect(()=>{a(1)},[c,d]);const u=F(()=>mr({region:c,framework:d,page:p}),[c,d,p]);return e.jsxs("div",{children:[e.jsx("p",{style:{...W,margin:`0 0 ${t.sp(3)}px`,maxWidth:760},children:"Servers that are not customers, scored by what makes one likely to switch: a rising rank, a growing region, a framework CDECAD supp
4orts, and a CAD recently removed. FiveStatus' own label describes how each server's player count behaves."}),e.jsxs(ee,{children:[e.jsxs(Z,{"aria-label":"Region",value:c,onChange:x=>i(x.target.value),style:{maxWidth:220},children:[e.jsx("option",{value:"",children:"Every region"}),n.map(x=>e.jsx("option",{value:x.value,children:x.label},x.value))]}),e.jsxs(Z,{"aria-label":"Framework",value:d,onChange:x=>h(x.target.value),style:{maxWidth:220},children:[e.jsx("option",{value:"",children:"Every framework"}),r.map(x=>e.jsx("option",{value:x.value,children:x.label},x.value))]})]}),e.jsx(oe,{id:"leads",query:u,fallback:"Could not load leads from FiveStatus. Try again in a minute.",children:(x,m)=>{const l=(x.leads||[]).map((o,y)=>({...o,_id:o.joinCode||`l${y}`}));return m("leads")?e.jsx(k,{off:m("leads")}):e.jsxs(C,{children:[m("regionGrowth")&&e.jsx(k,{off:m("regionGrowth")}),e.jsx(B,{ariaLabel:"Leads from FiveStatus",rows:l,stackBelow:1e3,empty:e.jsx(P,{title:"No leads for this filter",body:"Try every region or every framework."}),columns:[{key:"name",label:"Server",primary:!0,wrap:!0,width:"22%",render:o=>{const y=Ae(o.webUrl),b=Ae(o.connectUrl);return e.jsxs("span",{style:{minWidth:0},children:[e.jsx("span",{style:{display:"block"},children:e.jsx(me,{joinCode:o.joinCode,name:o.name,onServer:s})}),e.jsx("span",{style:{...j,display:"block",overflowWrap:"anywhere"},children:[o.region?.name,o.framework?.label].filter(Boolean).join(" · ")||"Region and framework not known"}),(y||b)&&e.jsxs("span",{style:{display:"inline-flex",gap:t.sp(3),flexWrap:"wrap",fontSize:12.5,marginTop:2},children:[y&&e.jsx("a",{href:y,target:"_blank",rel:"noopener noreferrer",style:re,children:"FiveStatus page"}),b&&e.jsx("a",{href:b,target:"_blank",rel:"noopener noreferrer",style:re,children:"Connect"})]})]})}},{key:"score",label:"Score",wrap:!0,width:"28%",render:o=>e.jsxs("span",{style:{minWidth:0},children:[e.jsx("span",{style:{display:"block",fontWeight:650},children:g(o.score)}),e.jsx(Ds,{reasons:o.reasons})]})},{key:"players",label:"Players",wrap:!0,width:"15%",render:o=>e.jsxs("span",{style:{minWidth:0},children:[e.jsxs("span",{style:{display:"block",whiteSpace:"nowrap"},children:[g(o.players)," now, peak ",g(o.peak24h)]}),e.jsx("span",{style:j,children:D(o.rankChange7d)?`${Me(o.rankChange7d).replace(/^./,y=>y.toUpperCase())} in 7 days`:"Same rank as 7 days ago"})]})},{key:"population",label:"Population",wrap:!0,width:"21%",render:o=>{const y=ps(o);return y?e.jsxs("span",{"data-fivestatus-population":o.population?.verdict||"",style:{minWidth:0},children:[y.label&&e.jsx(z,{dot:!1,children:y.label}),y.note&&e.jsx("span",{style:{...j,display:"block",marginTop:2},children:y.note})]}):e.jsx("span",{style:{color:t.sub},children:"No label yet"})}},{key:"runsCad",label:"CAD",wrap:!0,render:o=>nr(o.runsCad,o.resourcesKnown)}]}),e.jsx(rs,{page:x.page||p,pages:x.pages,onPage:a,noun:"lead"})]})}})]})}function rn({access:s,onServer:n}){const[r,c]=v.useState("ours"),[i,d]=v.useState(30),h=F(()=>yr({scope:r,days:i}),[r,i]),p=Ye.find(a=>a.value===r)?.label.toLowerCase();return e.jsxs("div",{children:[e.jsxs(ee,{children:[e.jsx(I,{size:"sm",ariaLabel:"Whose changes",value:r,onChange:c,options:Ye}),e.jsx(I,{size:"sm",ariaLabel:"Changes range",value:i,onChange:d,options:qt})]}),e.jsx(oe,{id:"changes",query:h,fallback:"Could not load resource changes. Try again in a minute.",children:(a,u)=>{const x=bs(a.events);if(u("events"))return e.jsx(k,{off:u("events")});const m=a.recordedSince&&Date.parse(a.recordedSince)>Date.now()-i*864e5?a.recordedSince:null;return e.jsxs(C,{children:[e.jsxs(S,{children:["Installs and removals (",x.length,")"]}),e.jsxs("p",{style:W,children:[r==="customers"?"Every resource change FiveStatus saw on a customer server":`Servers that added or removed ${r==="ours"?"one of our resources":"a competing CAD or MDT"}`,", newest first. CDECAD keeps FiveStatus' feed, so the history runs past FiveStatus' own 30 days.",m?` CDECAD started keeping it on ${_(m)}, so nothing before that is here.`:""]}),e.jsx(B,{ariaLabel:`Resource changes, ${p}`,rows:x,stackBelow:860,empty:e.jsx(P,{title:"No changes in this range",body:`Nothing was added or removed for ${p} in the last ${i} days.`}),columns:[{key:"serverName",label:"Server",primary:!0,wrap:!0,width:"34%",render:l=>e.jsxs("span",{style:{minWidth:0},children:[e.jsx("span",{style:{display:"block"},children:e.jsx(me,{joinCode:l.joinCode,name:l.serverName,onServer:n})}),e.jsxs("span",{style:{...j,display:"block",overflowWrap:"anywhere"},children:[_(l.detectedAt,{time:!0}
4),l.region?` · ${typeof l.region=="object"?l.region.name||l.region.code:l.region}`:""]}),l.customer&&e.jsxs("span",{style:{fontSize:12.5},children:["Customer: ",e.jsx(be,{row:l.customer,access:s})]})]})},{key:"change",label:"Change",wrap:!0,render:l=>e.jsx(Ts,{installed:l.installed,removed:l.removed})},{key:"players",label:"Players then",render:l=>g(l.players)}]})]})}})]})}function nn(){const[s,n]=v.useState(30),r=F(()=>Ss({days:s}),[s]),c=Fe((r.data?.regions||[]).filter(d=>d&&d.code&&d.code!=="unset"),"code","name"),i=Fe(r.data?.frameworks,"slug","label");return e.jsxs("div",{children:[e.jsx(ee,{children:e.jsx(I,{size:"sm",ariaLabel:"Regions range",value:s,onChange:n,options:Ot})}),e.jsx(oe,{id:"regions",query:r,fallback:"Could not load regions and frameworks. Try again in a minute.",after:e.jsx(Hr,{regions:c,frameworks:i}),children:(d,h)=>{const p=(d.regions||[]).map((l,o)=>({...l,_id:l.code||`r${o}`})),a=(d.frameworks||[]).filter(Boolean).slice().sort((l,o)=>(D(o.servers)??0)-(D(l.servers)??0)),u=Ht(d.migrations?.flows),x=_t(d.migrations?.net),m=Ut(d.regionFrameworks);return e.jsxs(e.Fragment,{children:[e.jsxs(C,{children:[e.jsx(S,{children:"Growth by region"}),e.jsxs("p",{style:W,children:["Players and servers now, and the change against ",s," days ago."]}),h("regions")?e.jsx(k,{off:h("regions")}):e.jsx(B,{ariaLabel:"Regions",rows:p,stackBelow:700,empty:e.jsx(P,{title:"No regions recorded",body:"CDECAD has not stored region numbers from FiveStatus yet."}),columns:[{key:"name",label:"Region",primary:!0,wrap:!0,render:l=>e.jsx("span",{style:{fontWeight:600},children:l.name||l.code})},{key:"players",label:"Players",render:l=>`${g(l.players)} (${q(l.playersChangePercent)})`},{key:"servers",label:"Servers",render:l=>`${g(l.servers)} (${q(l.serversChangePercent)})`}]})]}),e.jsxs(C,{style:{marginTop:t.sp(4)},children:[e.jsx(S,{children:"Frameworks"}),e.jsx("p",{style:W,children:"FiveStatus works out each server's framework from its resource list, not from anything the server declares."}),h("frameworks")?e.jsx(k,{off:h("frameworks")}):e.jsx(Ie,{ariaLabel:"Servers by framework",empty:"No frameworks recorded.",rows:a.map(l=>({key:l.slug||l.label,label:l.label||l.slug,value:D(l.servers)??0,hint:D(l.players)!==null?`${g(l.players)} players`:void 0})),format:l=>`${g(l)} servers`,labelWidth:110})]}),e.jsxs(C,{style:{marginTop:t.sp(4)},children:[e.jsx(S,{children:"Framework moves"}),e.jsxs("p",{style:W,children:["Servers that switched framework in the last ",s," days, and where each framework ended up."]}),h("migrations")?e.jsx(k,{off:h("migrations")}):e.jsxs("div",{style:ie(320),children:[e.jsx(B,{ariaLabel:"Framework moves",rows:u,stackBelow:700,empty:e.jsx(P,{title:"No moves recorded",body:`No server switched framework in the last ${s} days.`}),columns:[{key:"move",label:"Move",primary:!0,wrap:!0,render:l=>e.jsxs("span",{style:{fontWeight:600},children:[l.from," to ",l.to]})},{key:"servers",label:"Servers",render:l=>g(l.servers)},{key:"players",label:"Players",muted:!0,render:l=>g(l.players)}]}),e.jsx(B,{ariaLabel:"Net framework moves",rows:x,stackBelow:700,empty:e.jsx(P,{title:"No net change"}),columns:[{key:"name",label:"Framework",primary:!0,render:l=>e.jsx("span",{style:{fontWeight:600},children:l.name})},{key:"arrived",label:"Arrived",render:l=>g(l.arrived)},{key:"left",label:"Left",render:l=>g(l.left)},{key:"net",label:"Net",render:l=>ys(l.net)}]})]})]}),h("regionFrameworks")?e.jsx(k,{off:h("regionFrameworks")}):m.length>0&&e.jsxs(C,{style:{marginTop:t.sp(4)},children:[e.jsx(S,{children:"Frameworks in each region"}),e.jsx("div",{style:ie(220),"data-fivestatus-region-frameworks":"",children:m.map(l=>e.jsxs("div",{style:{minWidth:0},children:[e.jsx("div",{style:{fontSize:13.5,fontWeight:650,marginBottom:t.sp(1)},children:l.name}),e.jsx("div",{style:j,children:l.frameworks.slice(0,4).map(o=>`${o.label} ${g(o.servers)}`).join(" · ")})]},l._id))})]})]})}})]})}function an({status:s}){const n=s.key||{},r=s.limits||{},c=s.budget||{},i=s.recorder?.backfill||{},d=$e(s,"meta"),h=Array.isArray(s.missingScopes)?s.missingScopes:[];return e.jsxs(C,{style:{marginTop:t.sp(6)},"data-fivestatus-connection":"",children:[e.jsx(S,{children:"FiveStatus connection"}),s.stopped&&e.jsx(k,{off:s.stopped}),d&&e.jsx(k,{off:d}),e.jsx(Ne,{items:[["Key",[n.tier?`${n.tier.charAt(0).toUpperCase()}${n.tier.slice(1)} tier`:null,n.expiresAt?`expires ${_(n.expiresAt)}`:null,n.sourceRestricted?"limited to set addresses":null].filter(
4Boolean).join(", ")],["FiveStatus allows",D(r.perDay)!==null?`${g(r.perDay)} requests a day, ${g(r.perMinute)} a minute${D(r.remainingToday)!==null?`, ${g(r.remainingToday)} left today`:""}`:null],["CDECAD uses",D(c.perDay)!==null?`${g(c.usedToday??0)} of its ${g(c.perDay)} today, ${g(c.usedThisMinute??0)} of ${g(c.perMinute)} this minute`:null],["Scopes",(s.scopes||[]).length?e.jsx("span",{style:{display:"inline-flex",gap:t.sp(1.5),flexWrap:"wrap"},children:s.scopes.map(p=>e.jsx(z,{dot:!1,children:p},p))},"s"):null],h.length?["Missing scopes",`${h.join(", ")}. Those sections stay empty until FiveStatus adds them to the key.`]:null,["Last recording",s.recorder?.lastRunAt?ne(s.recorder.lastRunAt):"Not yet"],...["ecosystem","resources","servers","segments"].map(p=>[`History, ${p}`,rr(i[p])])]}),e.jsx(_r,{storage:s.storage,off:$e(s,"storage")}),e.jsx(Be,{data:s,section:"status"})]})}const ln={ecosystem:Zr,market:Xr,churn:en,leads:sn,changes:rn,regions:nn};function on({access:s}){const[n,r]=ks(),c=It(n.get("section")),i=F(()=>cr(),[]),[d,h]=v.useState(null);if(i.error)return e.jsx(G,{error:i.error,onRetry:i.reload,fallback:"Could not reach the FiveStatus part of the backend. Try again in a minute."});if(!i.data)return e.jsx(X,{height:160});if(i.data.configured===!1)return e.jsx(As,{});const p=ln[c],a=Le(i.data);return e.jsxs("div",{"data-fivestatus":"",children:[e.jsx("p",{style:{...W,margin:`0 0 ${t.sp(3)}px`,maxWidth:760},children:"Public FiveM numbers from FiveStatus. CDECAD stores a copy every day, so the history here runs longer than FiveStatus keeps its own."}),a&&e.jsx(k,{off:a}),e.jsx("div",{style:{marginBottom:t.sp(4)},children:e.jsx(I,{wrap:!0,size:"sm",ariaLabel:"FiveStatus sections",value:c,onChange:u=>r(u==="ecosystem"?{}:{section:u}),options:Bt.map(u=>({value:u.id,label:u.label}))})}),e.jsx(p,{access:s,onServer:h}),e.jsx(an,{status:i.data}),d&&e.jsx(Qr,{target:d,access:s,onClose:()=>h(null)})]})}const A=s=>s==null?"-":Number(s).toLocaleString("en-US"),dn=[["","Every language"],["en","English"],["de","German"],["fr","French"],["nl","Dutch"],["es","Spanish"],["pt","Portuguese"],["pl","Polish"],["it","Italian"],["sv","Swedish"],["da","Danish"],["tr","Turkish"]],fe={margin:`-${t.sp(1)}px 0 ${t.sp(3)}px`,color:t.sub,fontSize:14,lineHeight:1.5},K={fontSize:12.5,color:t.sub};function we({fetchedAt:s,stale:n,ours:r}){return e.jsxs("p",{"data-cde-source":"",style:{margin:`${t.sp(3)}px 0 0`,fontSize:12.5,color:t.sub,lineHeight:1.5},children:["Public server numbers from fivestats.io",s?`, read ${ne(s)}`:"",".",r?" Reporting numbers from CDECAD's own server telemetry.":""," ","For CDECAD staff only: fivestats' terms do not allow passing their data to communities without their permission.",n?" fivestats did not answer, so this is the last copy.":""]})}function cn({initial:s,onSaved:n}){const[r,c]=v.useState((s||[]).join(`
5`)),[i,d]=v.useState(!1),[h,p]=v.useState(null);v.useEffect(()=>{c((s||[]).join(`
6`))},[s]);const a=async()=>{d(!0),p(null);try{const u=r.split(/[\n,]+/).map(m=>m.trim()).filter(Boolean),x=await ls("/admin/cde-metrics/settings",{watchResources:u});je.success("Watched resources saved"),n(x.data?.watchResources||u)}catch(u){p(u)}finally{d(!1)}};return e.jsxs("div",{children:[e.jsx(Se,{label:"Resources to watch",hint:"One per line, as the folder is named on a server, like SonoranCAD. Up to 30.",children:e.jsx(as,{rows:4,value:r,onChange:u=>c(u.target.value),placeholder:"SonoranCAD"})}),e.jsx("div",{style:{display:"flex",justifyContent:"flex-end",marginTop:t.sp(2)},children:e.jsx(O,{onClick:a,disabled:i,children:i?"Saving…":"Save watched resources"})}),e.jsx(G,{error:h})]})}function hn({access:s}){const{data:n,setData:r,error:c,loading:i,reload:d}=F(()=>T("/admin/cde-metrics/overview").then(m=>m.data),[]),h=n?.adoption||[],p=h.find(m=>m.name==="CDECAD"),a=n?.cad,u=a?.summary||{},x=a?.daily||[];return e.jsxs("div",{children:[e.jsx(G,{error:c,onRetry:d,fallback:"Could not load CDE Metrics. Try again in a minute."}),i&&!n&&e.jsx(X,{height:160}),n&&e.jsxs(e.Fragment,{children:[e.jsx(S,{children:"Public servers against what reports to us"}),e.jsxs(ae,{min:160,children:[e.jsx(E,{label:"Public servers running CDECAD",value:A(p?.servers),hint:"Seen by fivestats right now"}),e.jsx(E,{label:"Servers reporting to CDECAD",value:A(u.reporting),hint:`${A(u.servers)} heard from in ${a?.days||7} days`}),e.jsx(E,{label:"Communities reporting",value:A(a?.communities)}),e.jsx(E,{label:"Public servers linked",value:A(n.linked?.servers),hint:`${A(n.linked?.communities)} communities`})]}),e.jsxs("div",{style:{marginTop:t.sp(5)},children:[e.jsx(S,{children:"This week, from our telemetry"}),e.jsxs(ae,{min:160,children:[e.jsx(E,{label:"Player hours",value:A(u.playerHours)}),e.jsx(E,{label:"Average players online",value:A(u.avgConcurrent)}),e.jsx(E,{label:"Peak on one server",value:A(u.peakPlayers)}),e.jsx(E,{label:"Servers on an old version",value:A(a?.outdated),hint:a?.latestVersion?`Latest is ${a.latestVersion}`:void 0,tone:a?.outdated?"warn":void 0})]}),x.length>0&&e.jsxs(C,{style:{marginTop:t.sp(3)},children:[e.jsxs("div",{style:{...K,marginBottom:t.sp(2)},children:["Player hours a day, ",_(x[0].date)," to ",_(x[x.length-1].date)]}),e.jsx(J,{height:96,label:`Player hours a day over ${x.length} days`,series:x.map(m=>({key:m.date,label:m.date,value:m.playerHours}))})]})]}),e.jsxs(C,{style:{marginTop:t.sp(5)},children:[e.jsx(S,{children:"CDE resources on public servers"}),e.jsx("p",{style:fe,children:"Every server fivestats sees running one of our resources, by folder name. Generic names we also ship, like cad-911, are left out because other authors use them too."}),e.jsx(B,{ariaLabel:"CDE resources on public servers",rows:h.map(m=>({...m,_id:m.name})),stackBelow:720,empty:e.jsx(P,{title:"No CDE resources seen",body:"fivestats has not seen any of our resources running on a server."}),columns:[{key:"name",label:"Resource",primary:!0,render:m=>e.jsx("span",{style:{fontWeight:600},children:m.name})},{key:"ours",label:"Kind",render:m=>e.jsx(z,{tone:m.ours==="core"?"accent":"neutral",dot:!1,children:m.ours==="core"?"CAD":"Add-on"})},{key:"servers",label:"Servers",render:m=>A(m.servers)},{key:"share",label:"Share",muted:!0,render:m=>m.share===null?"-":`${m.share}%`},{key:"rank",label:"Rank",muted:!0,render:m=>A(m.rank)},{key:"growth",label:"Growth",muted:!0,render:m=>m.growth===null?"-":`${m.growth>0?"+":""}${m.growth}`}]})]}),e.jsxs(C,{style:{marginTop:t.sp(4)}
6,children:[e.jsx(S,{children:"Watched resources"}),e.jsx("p",{style:fe,children:"Other resources to count beside ours, such as another CAD. Leads mark the servers that run them."}),(n.watched||[]).length>0?e.jsx("div",{style:{display:"flex",flexWrap:"wrap",gap:t.sp(2),marginBottom:t.sp(3)},"data-cde-watched":"",children:n.watched.map(m=>e.jsxs(z,{dot:!1,tone:m.missing?"neutral":"accent",children:[m.name," ",m.missing?"(not seen)":`${A(m.servers)} servers`]},m.name))}):!s?.canManage&&e.jsx("p",{style:{...K,margin:0},children:"Nothing is watched yet."}),s?.canManage?e.jsx(cn,{initial:n.watchResources,onSaved:m=>{r(l=>({...l,watchResources:m})),d()}}):e.jsx("p",{style:{...K,margin:`${t.sp(2)}px 0 0`},children:"A support lead or super admin changes this list."})]}),e.jsx(we,{fetchedAt:n.fetchedAt,stale:n.stale,ours:!0})]})]})}function un({server:s,onClose:n}){const[r,c]=v.useState(168),{data:i,error:d,loading:h,reload:p}=F(()=>T(`/admin/cde-metrics/servers/${s.endpoint}/history`,{hours:r}).then(x=>x.data),[s.endpoint,r]),a=i?.points||[],u=a.reduce((x,m)=>Math.max(x,m.clients||0),0);return e.jsxs(ns,{title:`${s.server?.name||s.endpoint}: players`,onClose:n,width:720,children:[e.jsx(I,{size:"sm",ariaLabel:"Window",value:r,onChange:c,options:[{value:24,label:"24 hours"},{value:168,label:"7 days"},{value:720,label:"30 days"}]}),e.jsx(G,{error:d,onRetry:p}),h&&!i&&e.jsx(X,{height:120}),i&&(a.length?e.jsxs("div",{"data-cde-history":"",style:{marginTop:t.sp(3)},children:[e.jsxs("div",{style:{fontSize:13,color:t.sub,marginBottom:t.sp(2)},children:["Peak ",A(u)," players · ",a.length," readings · ",_(a[0].at,{time:!0})," to ",_(a[a.length-1].at,{time:!0})]}),e.jsx(J,{height:140,label:`Players over ${r} hours, peak ${u}`,series:a.map(x=>({key:x.at,label:_(x.at,{time:!0}),value:x.clients}))})]}):e.jsx(P,{title:"No history yet",body:"fivestats has no readings for this server in this window."})),i&&e.jsx(we,{fetchedAt:i.fetchedAt,stale:i.stale})]})}function pn({onLinked:s}){const[n,r]=v.useState(""),[c,i]=v.useState([]),[d,h]=v.useState(null),[p,a]=v.useState(""),[u,x]=v.useState(!1),[m,l]=v.useState(null);v.useEffect(()=>{if(d||n.trim().length<2){i([]);return}const y=setTimeout(()=>{T("/admin/communities",{search:n.trim(),limit:6}).then(b=>i(b.data?.communities||[])).catch(()=>i([]))},250);return()=>clearTimeout(y)},[n,d]);const o=async()=>{if(!d){l(new Error("Pick the community first."));return}x(!0),l(null);try{const y=await os("/admin/cde-metrics/links",{communityId:d._id,input:p});je.success(`${d.name} linked to ${y.data?.link?.endpoint}`),a(""),h(null),r(""),s()}catch(y){l(y)}finally{x(!1)}};return e.jsxs(C,{style:{marginBottom:t.sp(4)},"data-cde-link-form":"",children:[e.jsx(S,{children:"Link a public server"}),e.jsx("p",{style:fe,children:"A community whose home page lists a cfx.re/join link is linked already. For any other, paste its join link or code. fivestats keys servers by join code, not by address."}),e.jsxs("div",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fit, minmax(min(100%, 240px), 1fr))",gap:t.sp(3)},children:[e.jsx(Se,{label:"Community",children:d?e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:t.sp(2),minHeight:40},children:[e.jsx("span",{style:{fontWeight:600,overflowWrap:"anywhere"},children:d.name}),e.jsx(O,{size:"sm",kind:"quiet",onClick:()=>h(null),children:"Change"})]}):e.jsxs("div",{style:{position:"relative"},children:[e.jsx(is,{value:n,onChange:r,placeholder:"Search communities",label:"Search communities"}),c.length>0&&e.jsx("div",{role:"listbox","aria-label":"Communities",style:{position:"absolute",zIndex:5,left:0,right:0,top:"calc(100% + 4px)",background:t.card,border:`1px solid ${t.border}`,borderRadius:11,boxShadow:t.shadowLg,overflow:"hidden"},children:c.map(y=>e.jsx("button",{type:"button",role:"option","aria-selected":"false",className:"adm-btn",onClick:()=>{h(y),i([])},style:{display:"block",width:"100%",textAlign:"left",padding:`${t.sp(2.5)}px ${t.sp(3)}px`,border:"none",background:"transparent",color:t.text,font:"inherit",cursor:"pointer"},children:y.name},y._id))})]})}),e.jsx(Se,{label:"Join link or code",children:e.jsx(Xs,{value:p,onChange:y=>a(y.target.value),placeholder:"cfx.re/join/abc123"})})]}),e.jsx("div",{style:{display:"flex",justifyContent:"flex-end",marginTop:t.sp(3)},children:e.jsx(O,{onClick:o,disabled:u||!p.trim(),children:u?"Checking with fivestats…":"Link server"})}),e.jsx(G,{error:m})]})}function mn({row:s,access:n,onHistory:r,onUnlink:c}){return s.public.length?e.jsx("span",{style:{display:"flex",flexDirection:"column",gap:t.sp(2),minWidth:0},children:s.public.map(i=>e.jsxs("span",{"data-cde-public":i.endpoint,style:{minWidth:0},children:[e.jsxs("span",{style:{display:"block",overflowWrap:"anywhere"},children:[i.server?`${A(i.server.clients)} / ${A(i.server.maxClients)} players`:i.notFound?"Not on fivestats":i.pending?"Waiting its turn":i.error||"Not read",i.server&&i.resourcesKnown&&!i.runsCde?" · CDECAD not seen":""]}),e.jsxs("span",{style:{...K,display:"block",overflowWrap:"anywhere"},children:[i.server?.name?`${i.server.name} · `:"","cfx.re/join/",i.endpoint," · ",i.source==="connect_url"?"from their home page":"linked by staff"]}),e.jsxs("span",{style:{display:"inline-flex",gap:t.sp(2),flexWrap:"wrap",marginTop:t.sp(1)},children:[i.server&&e.jsx(O,{size:"sm",onClick:()=>r(i),children:"History"}),n?.canManage&&e.jsx(O,{size:"sm",kind:"quiet",onClick:()=>c(s,i),children:"Unlink"})]})]},i.endpoint))}):e.jsx("span",{style:{color:t.sub},children:"None linked"})}function yn({cad:s,latestVersion:n}){return s?e.jsxs("span",{style:{minWidth:0},children:[e.jsxs("span",{style:{display:"block"},children:[A(s.playerHours)," player hours · peak ",A(s.peakPlayers)]}),e.jsx("span",{style:{...K,display:"block",overflowWrap:"anywhere"},children:[`${s.servers}
6 ${s.servers===1?"server":"servers"}`,Gs(s.change),s.versions?.length?`v${s.versions.join(", v")}${s.outdated&&n?` (latest ${n})`:""}`:"",s.lastSeen?`last heard ${ne(s.lastSeen)}`:""].filter(Boolean).join(" · ")})]}):e.jsx("span",{style:{color:t.sub},children:"Nothing this week or last"})}function xn({access:s}){const{data:n,setData:r,error:c,loading:i,reload:d}=F(()=>T("/admin/cde-metrics/communities").then(w=>w.data),[]),[h,p]=v.useState("attention"),[a,u]=v.useState(""),[x,m]=v.useState(null),l=v.useMemo(()=>n?.rows||[],[n]),o=v.useMemo(()=>Ps(l),[l]),y=l.filter(w=>w.flags?.length).length,b=zs(l,h,a).map(w=>({...w,_id:w.communityId})),R=async(w,f)=>{if(await Qs({title:"Unlink server",message:`Stop counting ${f.server?.name||f.endpoint} as ${w.communityName}'s server?${f.source==="connect_url"?" Their home page still lists it; it stays unlinked here anyway.":""}`,confirmLabel:"Unlink"}))try{await os("/admin/cde-metrics/links/unlink",{communityId:w.communityId,endpoint:f.endpoint}),r(ye=>qs(ye,w.communityId,f.endpoint)),je.success("Unl
6inked"),d()}catch(ye){je.error(et(ye))}};return e.jsxs("div",{children:[s?.canManage&&e.jsx(pn,{onLinked:d}),e.jsx(G,{error:c,onRetry:d,fallback:"Could not load the communities. Try again in a minute."}),i&&!n&&e.jsx(X,{height:160}),n?.pending>0&&e.jsxs(ss,{tone:"warn",action:e.jsx(O,{size:"sm",onClick:d,children:"Load the rest"}),children:[n.pending," more public servers are waiting their turn, to stay inside fivestats' request limit."]}),n&&e.jsxs(C,{children:[e.jsxs(S,{children:["Each community, both sides (",l.length,")"]}),e.jsxs("p",{style:fe,children:["What fivestats shows on a community's public server beside what its CDECAD resource reported to us over the last ",n.cadDays||7," days. Rows where the two disagree come first."]}),Object.keys(o).length>0&&e.jsx("div",{"data-cde-flag-legend":"",style:{display:"flex",flexWrap:"wrap",gap:t.sp(2),marginBottom:t.sp(3)},children:Object.entries(o).map(([w,f])=>e.jsxs(z,{tone:ce(w).tone,title:ce(w).body,children:[ce(w).label,": ",f]},w))}),e.jsxs(ee,{children:[e.jsx(I,{size:"sm",ariaLabel:"Show",value:h,onChange:p,options:Is.map(w=>({value:w.value,label:w.value==="attention"?`${w.label} (${y})`:w.label}))}),e.jsx(is,{value:a,onChange:u,placeholder:"Community, server or join code",label:"Search communities",style:{maxWidth:320}})]}),e.jsx(B,{ariaLabel:"Communities, public and reported",rows:b,stackBelow:980,empty:e.jsx(P,{title:h==="attention"&&!a?"Nothing needs a look":"No communities match",body:h==="attention"&&!a?"Every community's public server and CDECAD reports agree.":"Try All, or a different search."}),columns:[{key:"communityName",label:"Community",primary:!0,wrap:!0,width:"20%",render:w=>e.jsx(be,{row:w,access:s})},{key:"public",label:"Public server",wrap:!0,width:"30%",render:w=>e.jsx(mn,{row:w,access:s,onHistory:m,onUnlink:R})},{key:"cad",label:"Reported to CDECAD",wrap:!0,width:"24%",render:w=>e.jsx(yn,{cad:w.cad,latestVersion:n.latestVersion})},{key:"flags",label:"Disagrees",wrap:!0,width:"26%",render:w=>w.flags?.length?e.jsx("span",{style:{display:"flex",flexDirection:"column",gap:t.sp(1.5),minWidth:0},children:w.flags.map(f=>e.jsxs("span",{"data-cde-flag":f,style:{minWidth:0},children:[e.jsx(z,{tone:ce(f).tone,children:ce(f).label}),e.jsx("span",{style:{...K,display:"block",marginTop:2,lineHeight:1.45},children:ce(f).body})]},f))}):e.jsx(z,{tone:"good",children:"Agree"})}]})]}),n&&e.jsx(we,{fetchedAt:n.fetchedAt,stale:n.stale,ours:!0}),x&&e.jsx(un,{server:x,onClose:()=>m(null)})]})}function gn({access:s}){const[n,r]=v.useState(""),[c,i]=v.useState(1),[d,h]=v.useState(!1);v.useEffect(()=>{i(1)},[n]);const{data:p,error:a,loading:u,reload:x}=F(()=>T("/admin/cde-metrics/leads",{locale:n||void 0,page:c}).then(o=>o.data),[n,c]),m=(p?.rows||[]).filter(o=>!d||!o.runsCde&&!o.community).map(o=>({...o,_id:o.endpoint})),l=Math.min(p?.totalPages||1,20);return e.jsxs("div",{children:[e.jsx("p",{style:{margin:`0 0 ${t.sp(3)}px`,color:t.sub,fontSize:14,lineHeight:1.5,maxWidth:760},children:"Roleplay GTA servers by players right now, 25 a page, with what each runs of ours and of the watched list. Each page costs fivestats 26 requests the first time, then is kept for six hours."}),e.jsxs(ee,{children:[e.jsx(Z,{"aria-label":"Language",value:n,onChange:o=>r(o.target.value),style:{maxWidth:220},children:dn.map(([o,y])=>e.jsx("option",{value:o,children:y},o))}),e.jsx(Js,{checked:d,onChange:h,label:"Hide servers already on CDECAD"})]}),e.jsx(G,{error:a,onRetry:x,fallback:"Could not load leads. Try again in a minute."}),u&&!p&&e.jsx(X,{height:200}),p&&e.jsxs(C,{children:[e.jsx(B,{ariaLabel:"Leads",rows:m,stackBelow:860,empty:e.jsx(P,{title:"Nothing on this page",body:d?"Every server here already runs CDECAD.":"fivestats returned no servers for this filter."}),columns:[{key:"name",label:"Server",primary:!0,wrap:!0,render:o=>e.jsxs("span",{style:{minWidth:0},children:[e.jsx("span",{style:{display:"block",fontWeight:600,overflowWrap:"anywhere"},children:o.name}),e.jsxs("span",{style:K,children:["cfx.re/join/",o.endpoint]})]})},{key:"clients",label:"Players",render:o=>`${A(o.clients)} / ${A(o.maxClients)}`},{key:"rank",label:"Rank",muted:!0,render:o=>A(o.rank)},{key:"locale",label:"Language",muted:!0,render:o=>o.locale||"-"},{key:"runs",label:"Runs",wrap:!0,render:o=>e.jsxs("span",{style:{display:"inline-flex",gap:t.sp(1.5),flexWrap:"wrap"},children:[o.runsCde?e.jsx(z,{tone:"good",children:"CDECAD"}):null,(o.watched||[]).map(y=>e.jsx(z,{tone:"warn",dot:!1,children:y},y)),!o.runsCde&&!(o.watched||[]).length&&e.jsx("span",{style:{color:t.sub},children:o.resourcesKnown?"Neither":"Not read"})]})}
6,{key:"community",label:"Customer",render:o=>o.community?e.jsx(be,{row:{communityId:o.community._id,communityName:o.community.name},access:s}):e.jsx("span",{style:{color:t.sub},children:"No"})}]}),e.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",gap:t.sp(3),paddingTop:t.sp(3),flexWrap:"wrap"},children:[e.jsxs("span",{style:{fontSize:13,color:t.sub},children:["Page ",c,p.totalPages?` of ${A(l)}`:""]}),e.jsxs("span",{style:{display:"inline-flex",gap:t.sp(2)},children:[e.jsx(O,{size:"sm",onClick:()=>i(o=>Math.max(1,o-1)),disabled:c<=1,children:"Previous"}),e.jsx(O,{size:"sm",onClick:()=>i(o=>o+1),disabled:c>=l,children:"Next"})]})]})]}),p&&e.jsx(we,{fetchedAt:p.fetchedAt,stale:p.stale})]})}const Ce=s=>_(s,{time:!0});function vn(){const[s,n]=v.useState("7d"),{data:r,error:c,loading:i,reload:d}=F(()=>T("/admin/cde-metrics/platform",{range:s}).then(b=>b.data),[s]),h=v.useMemo(()=>xs(),[]),p=fs(h),a=Bs(s),u=r?.summary||{},x=r?.now?.gta5Players??u.latest?.players??null,m=r?.now?.gta5Servers??u.latest?.servers??null,l=v.useMemo(()=>Os(r?.points,Ce),[r]),o=l[0],y=l[l.length-1];return e.jsxs("div",{"data-cde-fivem":"",children:[e.jsxs("p",{style:fe,children:["Everyone playing on public FiveM servers, as fivestats.io counts them. CDECAD keeps fivestats' total every ",r?.sampleMinutes||15," minutes, so this is a trend and not just today's number."]}),e.jsx(ee,{style:{marginBottom:t.sp(3)},children:e.jsx(I,{ariaLabel:"Time range",value:s,onChange:n,options:Hs.map(b=>({value:b.value,label:b.label}))})}),e.jsx(G,{error:c,onRetry:d,fallback:"Could not load FiveM's player numbers. Try again in a minute."}),i&&!r&&e.jsx(X,{height:160}),r&&e.jsxs(e.Fragment,{children:[e.jsxs(ae,{min:160,children:[e.jsx(E,{label:"Playing FiveM now",value:A(x),hint:m!==null?`${A(m)} servers online`:void 0}),e.jsx(E,{label:`Average, ${a.label}`,value:A(u.average),hint:u.average===null?"No readings in this range yet":_s(u.change,s)}),e.jsx(E,{label:"Peak",value:A(u.peak?.players),hint:u.peak?Ce(u.peak.at):void 0}),e.jsx(E,{label:"Low",value:A(u.low?.players),hint:u.low?Ce(u.low.at):void 0})]}),r.now?.totalPlayers!==null&&r.now?.totalPlayers!==void 0&&e.jsxs("p",{style:{...K,margin:`${t.sp(2)}px 0 0`},children:["Every Cfx.re game together, FiveM and RedM: ",A(r.now.totalPlayers)," players on ",A(r.now.totalServers)," servers."]}),e.jsxs(C,{style:{marginTop:t.sp(4)},children:[e.jsxs(S,{children:["Players on FiveM, ",a.window]}),l.length?e.jsxs("div",{"data-cde-fivem-line":"",children:[e.jsx(le,{gaps:!0,ariaLabel:`Players on FiveM over ${a.window}`,points:l}),e.jsxs("div",{"aria-hidden":"true",style:{display:"flex",justifyContent:"space-between",gap:t.sp(2),marginTop:t.sp(1.5),fontSize:11.5,color:t.subtle,paddingLeft:40},children:[e.jsx("span",{children:o?.label}),e.jsx("span",{children:y?.label})]}),e.jsxs("p",{style:{...K,margin:`${t.sp(2)}px 0 0`},children:[r.bucketMinutes===15?"Each point is one reading.":`Each point is the average of the readings in ${r.bucketMinutes===60?"an hour":`${r.bucketMinutes/60} hours`}.`," ","A break in the line is a reading CDECAD missed, not a drop in players.",r.recordingSince&&new Date(r.recordingSince).getTime()>Date.now()-r.hours*36e5?` Readings began ${Ce(r.recordingSince)}.`:""]}),e.jsx("div",{className:"adm-sr",children:e.jsxs("table",{children:[e.jsxs("caption",{children:["Players on FiveM over ",a.window]}),e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{scope:"col",children:"Time"}),e.jsx("th",{scope:"col",children:"Players"})]})}),e.jsx("tbody",{children:l.map(b=>e.jsxs("tr",{children:[e.jsx("td",{children:b.label}),e.jsx("td",{children:b.value===null?"No reading":A(b.value)})]},b.key))})]})})]}):e.jsx(P,{title:"No readings yet",body:`CDECAD takes its first reading of FiveM's total within ${r.sampleMinutes||15} minutes of the backend starting with the fivestats key set, then one every ${r.sampleMinutes||15} minutes. The number right now is above.`})]}),e.jsxs(C,{style:{marginTop:t.sp(4)},children:[e.jsx(S,{children:"When FiveM is busiest"}),Array.isArray(r.heatmap)&&r.heatmap.length===168?e.jsx(gs,{cells:vs(r.heatmap,h),ariaLabel:`Average players on FiveM by day of week and hour, over ${a.window}`,zoneLabel:`Times in ${p}`}):e.jsx("p",{style:{...K,margin:0},"data-cde-fivem-grid-note":"",children:Us(r)})]}),e.jsx(we,{fetchedAt:r.fetchedAt,stale:r.stale})]})]})}const jn={overview:hn,fivem:vn,communities:xn,leads:gn,fivestatus:on};function fn({view:s}){const n=Cs(),{data:r,error:c,reload:i}=F(()=>T("/admin/cde-metrics/access").then(h=>h.data),[]);if(c){const h=Ys({error:c});return h.status==="policy"?e.jsx(ge,{title:"The admin access policy stopped this sign-in",action:e.jsx(O,{kind:"primary",onClick:i,children:"Check again"}),children:h.message||"CDE Metrics answers to the same access policy as the admin console, and this sign-in does not meet it."}):h.status==="denied"?e.jsx(ge,{title:"CDE Metrics is for CDECAD's support team",action:e.jsx(O,{onClick:()=>n("/"),children:"Back to CDECAD"}),children:"It reads public server numbers from fivestats.io, whose terms keep that data with CDECAD staff. Your account has no support role, so this page is closed to it. If you work on C
6DECAD support, ask a super admin to add you on the Staff page. Your own community's server numbers are on its Server analytics page."}):e.jsx(ge,{title:"Your access could not be checked",action:e.jsx(O,{kind:"primary",onClick:i,children:"Try again"}),children:h.message||"The server did not answer. Nothing is wrong with your role; try again in a moment."})}if(!r)return e.jsx(X,{height:160});if(!r.configured&&s!=="fivestatus")return e.jsx(ge,{title:"CDE Metrics is not set up",children:"Add the fivestats API key to the backend .env as FIVESTATS and restart the backend. The key stays on the server; this page never sees it."});const d=jn[s];return e.jsx(d,{access:r})}function Bn(){const{view:s}=dr(),n=Es(s),r=Cs(),{logout:c}=Vs(),[i,d]=Rs(),h=i!=="light";v.useEffect(()=>{document.title="CDE Metrics · CDECAD"},[]);const p=async()=>{try{await c?.()}finally{r("/")}};return e.jsxs("div",{className:"adm-root","data-cde-metrics":"",style:{...Ks(h),minHeight:"100vh",background:t.bg,color:t.text,fontFamily:t.font,colorScheme:t.colorScheme},children:[e.jsx("style",{children:Zs}),e.jsx(Ms,{themeMode:i,setThemeMode:d,onLogout:p}),e.jsxs("main",{id:"metrics-main",tabIndex:-1,style:{maxWidth:1180,margin:"0 auto",padding:`${t.sp(6)}px ${t.sp(4)}px ${t.sp(12)}px`,outline:"none"},children:[e.jsxs("header",{style:{marginBottom:t.sp(5)},children:[e.jsx("div",{style:{fontSize:12,fontWeight:650,letterSpacing:"0.08em",textTransform:"uppercase",color:t.accent},children:"CDECAD staff"}),e.jsx("h1",{style:{margin:`${t.sp(1)}px 0 0`,fontSize:"clamp(26px, 6vw, 34px)",fontWeight:750,letterSpacing:"-0.03em",lineHeight:1.1},children:"CDE Metrics"}),e.jsx("p",{style:{margin:`${t.sp(2)}px 0 ${t.sp(4)}px`,color:t.sub,fontSize:15,lineHeight:1.5,maxWidth:680},children:"Public FiveM server numbers from fivestats.io and FiveStatus beside what each community's CDECAD resource reports to us, in one place."}),e.jsx("nav",{"aria-label":"CDE Metrics",children:e.jsx(I,{wrap:!0,ariaLabel:"CDE Metrics views",value:n,onChange:a=>r(Ls(a)),options:Ns.map(a=>({value:a.id,label:a.label}))})})]}),e.jsx(fn,{view:n})]})]})}export{Bn as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.