PageSourceSearch

https://www.hamienet.com/assets/BIDashboard-BMEu96EU.js

js hamienet.com collected 2026-10-02 05:01:30 UTC 39,899 bytes, 394 lines download raw bytes

1import { r as reactExports, j as jsxRuntimeExports } from "./vendor-react-Bay9Y7Lb.js";
2import { a as api } from "./index-w5lXls15.js";
3import { cg as Activity, cM as RefreshCw, bA as Eye, dP as Users, bV as Play, d1 as Download, bC as Gamepad2, bl as UserPlus, e4 as Bot, bs as Zap, fs as ResponsiveContainer, ft as AreaChart, fu as XAxis, fv as YAxis, fw as CartesianGrid, fx as Tooltip, fy as Area, fz as PieChart, fA as Pie, fB as Cell, fC as Legend, fD as LineChart, fE as Line, fF as BarChart, fG as Bar, cu as TrendingUp, fH as TrendingDown } from "./vendor-D0P4XgNj.js";
4import "./vendor-i18n-BC7ZMXWQ.js";
5const COLORS = ["#3b82f6", "#10b981", "#8b5cf6", "#f59e0b", "#ef4444", "#06b6d4", "#ec4899", "#84cc16"];
6const countryFlag = (code) => code ? String.fromCodePoint(...[...code.toUpperCase()].map((c) => c.charCodeAt(0) + 127397)) : "🌍";
7const formatNum = (num) => num.toLocaleString();
8const Skeleton = ({ className = "" }) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `animate-pulse bg-zinc-800 rounded ${className}` });
9const MetricCard = ({ title, metric, icon: Icon, color, format = formatNum, suffix = "" }) => {
10  const isPositive = (metric == null ? void 0 : metric.change) >= 0;
11  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-zinc-900 border border-zinc-800 p-4 rounded-xl flex flex-col justify-between", children: [
12    /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-start mb-2", children: [
13      /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-400 text-sm font-medium", children: title }),
14      /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `p-2 rounded-lg`, style: { backgroundColor: `${color}20`, color }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Icon, { size: 18 }) })
15    ] }),
16    /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
17      /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-2xl font-bold text-zinc-100 mb-1", children: metric ? `${format(metric.value)}${suffix}` : /* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-8 w-24" }) }),
18      metric ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center text-xs", children: [
19        isPositive ? /* @__PURE__ */ jsxRuntimeExports.jsx(TrendingUp, { size: 14, className: "text-emerald-500 mr-1" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(TrendingDown, { size: 14, className: "text-red-500 mr-1" }),
20        /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: isPositive ? "text-emerald-500" : "text-red-500", children: [
21          Math.abs(metric.change),
22          "%"
23        ] }),
24        /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-500 ml-2", children: "vs previous" })
25      ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-32" })
26    ] })
27  ] });
28};
29function BIDashboard() {
30  const [tab, setTab] = reactExports.useState("Overview");
31  const [range, setRange] = reactExports.useState("30d");
32  const [autoRefresh, setAutoRefresh] = reactExports.useState(true);
33  const [refreshTrigger, setRefreshTrigger] = reactExports.useState(0);
34  const [loading, setLoading] = reactExports.useState(true);
35  const [error, setError] = reactExports.useState(null);
36  const [overview, setOverview] = reactExports.useState(null);
37  const [traffic, setTraffic] = reactExports.useState(null);
38  const [content, setContent] = reactExports.useState(null);
39  const [games, setGames] = reactExports.useState(null);
40  const [users, setUsers] = reactExports.useState(null);
41  const [bots, setBots] = reactExports.useState(null);
42  const TABS = ["Overview", "Traffic", "Content", "Games", "Users", "Bots"];
43  const ranges = [
44    { label: "Today", value: "1d" },
45    { label: "Last 24h", value: "24h" },
46    { label: "7 Days", value: "7d" },
47    { label: "30 Days", value: "30d" },
48    { label: "Quarter", value: "90d" },
49    { label: "Year", value: "1y" },
50    { label: "All Time", value: "all" }
51  ];
52  const fetchData = reactExports.useCallback(async () => {
53    setLoading(true);
54    setError(null);
55    try {
56      if (tab === "Overview") {
57        const [ov, tr] = await Promise.all([
58          api.getAnalyticsOverview(range),
59          api.getAnalyticsTraffic(range)
60        ]);
61        setOverview(ov);
62        setTraffic(tr);
63      } else if (tab === "Traffic") setTraffic(await api.getAnalyticsTraffic(range));
64      else if (tab === "Content") setContent(await api.getAnalyticsContent(range));
65      else if (tab === "Games") setGames(await api.getAnalyticsGames(range));
66      else if (tab === "Users") setUsers(await api.getAnalyticsUsers(range));
67      else if (tab === "Bots") setBots(await api.getAnalyticsBots(range));
68    } catch (e) {
69      setError(e.message || "Failed to fetch analytics");
70    } finally {
71      setLoading(false);
72    }
73  }, [tab, range, refreshTrigger]);
74  reactExports.useEffect(() => {
75    fetchData();
76  }, [fetchData]);
77  reactExports.useEffect(() => {
78    if (!autoRefresh) return;
79    const interval = setInterval(() => setRefreshTrigger((prev) => prev + 1), 6e4);
80    return () => clearInterval(interval);
81  }, [autoRefresh]);
82  const renderOverview = () => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [
83    /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4", children: [
84      /* @__PURE__ */ jsxRuntimeExports.jsx(MetricCard, { title: "Page Views", metric: overview == null ? void 0 : overview.pageViews, icon: Eye, color: "#3b82f6" }),
85      /* @__PURE__ */ jsxRuntimeExports.jsx(MetricCard, { title: "Unique Visitors", metric: overview == null ? void 0 : overview.uniqueVisitors, icon: Users, color: "#10b981" }),
86      /* @__PURE__ */ jsxRuntimeExports.jsx(MetricCard, { title: "Track Plays", metric: overview == null ? void 0 : overview.trackPlays, icon: Play, color: "#8b5cf6" }),
87      /* @__PURE__ */ jsxRuntimeExports.jsx(MetricCard, { title: "Downloads", metric: overview == null ? void 0 : overview.downloads, icon: Download, color: "#f59e0b" }),
88      /* @__PURE__ */ jsxRuntimeExports.jsx(MetricCard, { title: "Games Played", metric: overview == null ? void 0 : overview.gamePlays, icon: Gamepad2, color: "#ec4899" }),
89      /* @__PURE__ */ jsxRuntimeExports.jsx(MetricCard, { title: "New Users", metric: overview == null ? void 0 : overview.newUsers, icon: UserPlus, color: "#06b6d4" }),
90      /* @__PURE__ */ jsxRuntimeExports.jsx(MetricCard, { title: "Bot Visits", metric: overview == null ? void 0 : overview.botVisits, icon: Bot, color: "#f59e0b" }),
91      /* @__PURE__ */ jsxRuntimeExports.jsx(MetricCard, { title: "Avg Response Time", metric: overview == null ? void 0 : overview.avgResponseTime, icon: Zap, color: "#10b981", suffix: "ms" })
92    ] }),
93    /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-zinc-900 border border-zinc-800 p-6 rounded-xl h-96", children: [
94      /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-zinc-100 font-semibold mb-4", children: "Page Views Overview" }),
95      loading && !traffic ? /* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "w-full h-full" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(AreaChart, { data: (traffic == null ? void 0 : traffic.timeSeries) || [], margin: { top: 10, right: 30, left: 0, bottom: 0 }, children: [
96        /* @__PURE__ */ jsxRuntimeExports.jsx("defs", { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("linearGradient", { id: "colorPv", x1: "0", y1: "0", x2: "0", y2: "1", children: [
97          /* @__PURE__ */ jsxRuntimeExports.jsx("stop", { offset: "5%", stopColor: "#3b82f6", stopOpacity: 0.8 }),
98          /* @__PURE__ */ jsxRuntimeExports.jsx("stop", { offset: "95%", stopColor: "#3b82f6", stopOpacity: 0 })
99        ] }) }),
100        /* @__PURE__ */ jsxRuntimeExports.jsx(XAxis, { dataKey: "date", stroke: "#52525b", tick: { fill: "#a1a1aa" } }),
101        /* @__PURE__ */ jsxRuntimeExports.jsx(YAxis, { stroke: "#52525b", tick: { fill: "#a1a1aa" } }),
102        /* @__PURE__ */ jsxRuntimeExports.jsx(CartesianGrid, { strokeDasharray: "3 3", stroke: "#27272a" }),
103        /* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip, { contentStyle: { backgroundColor: "#18181b", borderColor: "#27272a", color: "#f4f4f5" } }),
104        /* @__PURE__ */ jsxRuntimeExports.jsx(Area, { type: "monotone", dataKey: "views", stroke: "#3b82f6", fillOpacity: 1, fill: "url(#colorPv)" })
105      ] }) })
106    ] }),
107    /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-3 gap-6", children: [
108      /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-zinc-900 border border-zinc-800 p-4 rounded-xl", children: [
109        /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-zinc-100 font-semibold mb-4", children: "Top 10 Pages" }),
110        /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3", children: (traffic == null ? void 0 : traffic.topPages.slice(0, 10).map((page, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between text-sm", children: [
111          /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-400 truncate pr-4", children: page.route }),
112          /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-100 font-medium", children: formatNum(page.views) })
113        ] }, i))) || /* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-48" }) })
114      ] }),
115      /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-zinc-900 border border-zinc-800 p-4 rounded-xl", children: [
116        /* @__P
116URE__ */ jsxRuntimeExports.jsx("h3", { className: "text-zinc-100 font-semibold mb-4", children: "Top 10 Countries" }),
117        /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3", children: (traffic == null ? void 0 : traffic.topCountries.slice(0, 10).map((c, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between text-sm", children: [
118          /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-zinc-400", children: [
119            /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "mr-2", children: countryFlag(c.country) }),
120            c.country
121          ] }),
122          /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-100 font-medium", children: formatNum(c.views) })
123        ] }, i))) || /* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-48" }) })
124      ] }),
125      /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-zinc-900 border border-zinc-800 p-4 rounded-xl flex flex-col", children: [
126        /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-zinc-100 font-semibold mb-4", children: "Device Breakdown" }),
127        /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 min-h-[200px]", children: traffic ? /* @__PURE__ */ jsxRuntimeExports.jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(PieChart, { children: [
128          /* @__PURE__ */ jsxRuntimeExports.jsx(Pie, { data: traffic.devices, cx: "50%", cy: "50%", innerRadius: 60, outerRadius: 80, paddingAngle: 5, dataKey: "count", nameKey: "type", children: traffic.devices.map((entry, index) => /* @__PURE__ */ jsxRuntimeExports.jsx(Cell, { fill: COLORS[index % COLORS.length] }, `cell-${index}`)) }),
129          /* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip, { contentStyle: { backgroundColor: "#18181b", borderColor: "#27272a", color: "#f4f4f5" } }),
130          /* @__PURE__ */ jsxRuntimeExports.jsx(Legend, { verticalAlign: "bottom", height: 36 })
131        ] }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-full" }) })
132      ] })
133    ] })
134  ] });
135  const renderTraffic = () => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [
136    /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-zinc-900 border border-zinc-800 p-6 rounded-xl h-96", children: [
137      /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-zinc-100 font-semibold mb-4", children: "Traffic & Visitors" }),
138      traffic ? /* @__PURE__ */ jsxRuntimeExports.jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(LineChart, { data: traffic.timeSeries, margin: { top: 5, right: 30, left: 20, bottom: 5 }, children: [
139        /* @__PURE__ */ jsxRuntimeExports.jsx(CartesianGrid, { strokeDasharray: "3 3", stroke: "#27272a" }),
140        /* @__PURE__ */ jsxRuntimeExports.jsx(XAxis, { dataKey: "date", stroke: "#52525b", tick: { fill: "#a1a1aa" } }),
141        /* @__PURE__ */ jsxRuntimeExports.jsx(YAxis, { stroke: "#52525b", tick: { fill: "#a1a1aa" } }),
142        /* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip, { contentStyle: { backgroundColor: "#18181b", borderColor: "#27272a", color: "#f4f4f5" } }),
143        /* @__PURE__ */ jsxRuntimeExports.jsx(Legend, {}),
144        /* @__PURE__ */ jsxRuntimeExports.jsx(Line, { type: "monotone", dataKey: "views", name: "Page Views", stroke: "#3b82f6", strokeWidth: 2, dot: false }),
145        /* @__PURE__ */ jsxRuntimeExports.jsx(Line, { type: "monotone", dataKey: "uniqueVisitors", name: "Unique Visitors", stroke: "#10b981", strokeWidth: 2, dot: false }),
146        /* @__PURE__ */ jsxRuntimeExports.jsx(Line, { type: "monotone", dataKey: "botVisits", name: "Bot Visits", stroke: "#f59e0b", strokeWidth: 2, dot: false })
147      ] }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-full" })
148    ] }),
149    /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-6", children: [
150      /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-zinc-900 border border-zinc-800 p-6 rounded-xl h-80", children: [
151        /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-zinc-100 font-semibold mb-4", children: "Top Countries" }),
152        traffic ? /* @__PURE__ */ jsxRuntimeExports.jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(BarChart, { data: traffic.topCountries.slice(0, 10), layout: "vertical", margin: { top: 5, right: 30, left: 40, bottom: 5 }, children: [
153          /* @__PURE__ */ jsxRuntimeExports.jsx(CartesianGrid, { strokeDasharray: "3 3", stroke: "#27272a", horizontal: false }),
154          /* @__PURE__ */ jsxRuntimeExports.jsx(XAxis, { type: "number", stroke: "#52525b", tick: { fill: "#a1a1aa" } }),
155          /* @__PURE__ */ jsxRuntimeExports.jsx(YAxis, { dataKey: "country", type: "category", stroke: "#52525b", tick: { fill: "#a1a1aa" } }),
156          /* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip, { contentStyle: { backgroundColor: "#18181b", borderColor: "#27272a", color: "#f4f4f5" }, cursor: { fill: "#27272a" } }),
157          /* @__PURE__ */ jsxRuntimeExports.jsx(Bar, { dataKey: "views", fill: "#3b82f6", radius: [0, 4, 4, 0] })
158        ] }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-full" })
159      ] }),
160      /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-zinc-900 border border-zinc-800 p-6 rounded-xl h-80", children: [
161        /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-zinc-100 font-semibold mb-4", children: "Browsers" }),
162        traffic ? /* @__PURE__ */ jsxRuntimeExports.jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(BarChart, { data: traffic.browsers.slice(0, 10), layout: "vertical", margin: { top: 5, right: 30, left: 40, bottom: 5 }, children: [
163          /* @__PURE__ */ jsxRuntimeExports.jsx(CartesianGrid, { strokeDasharray: "3 3", stroke: "#27272a", horizontal: false }),
164          /* @__PURE__ */ jsxRuntimeExports.jsx(XAxis, { type: "number", stroke: "#52525b", tick: { fill: "#a1a1aa" } }),
165          /* @__PURE__ */ jsxRuntimeExports.jsx(YAxis, { dataKey: "name", type: "category", stroke: "#52525b", tick: { fill: "#a1a1aa" } }),
166          /* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip, { contentStyle: { backgroundColor: "#18181b", borderColor: "#27272a", color: "#f4f4f5" }, cursor: { fill: "#27272a" } }),
167          /* @__PURE__ */ jsxRuntimeExports.jsx(Bar, { dataKey: "count", fill: "#8b5cf6", radius: [0, 4, 4, 0] })
168        ] }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-full" })
169      ] })
170    ] }),
171    /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-zinc-900 border border-zinc-800 p-6 rounded-xl", children: [
172      /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-zinc-100 font-semibold mb-4", children: "Top Referrers" }),
173      /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4", children: (traffic == null ? void 0 : traffic.referrers.slice(0, 15).map((ref, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center p-3 bg-zinc-800/50 rounded-lg", children: [
174        /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-300 text-sm truncate pr-4", title: ref.domain, children: ref.domain || "Direct" }),
175        /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-100 font-medium text-sm bg-zinc-800 px-2 py-1 rounded", children: formatNum(ref.count) })
176      ] }, i))) || /* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-32" }) })
177    ] })
178  ] });
179  const renderContent = () => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [
180    /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-zinc-900 border border-zinc-800 p-6 rounded-xl h-96", children: [
181      /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-zinc-100 font-semibold mb-4", children: "Content Engagement Over Time" }),
182      content ? /* @__PURE__ */ jsxRuntimeExports.jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(AreaChart, { data: content.timeSeries, margin: { top: 10, right: 30, left: 0, bottom: 0 }, children: [
183        /* @__PURE__ */ jsxRuntimeExports.jsx(XAxis, { dataKey: "date", stroke: "#52525b", tick: { fill: "#a1a1aa" } }),
184        /* @__PURE__ */ jsxRuntimeExports.jsx(YAxis, { stroke: "#52525b", tick: { fill: "#a1a1aa" } }),
185        /* @__PURE__ */ jsxRuntimeExports.jsx(CartesianGrid, { strokeDasharray: "3 3", stroke: "#27272a" }),
186        /* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip, { contentStyle: { backgroundColor: "#18181b", borderColor: "#27272a", color: "#f4f4f5" } }),
187        /* @__PURE__ */ jsxRuntimeExports.jsx(Legend, {}),
188        /* @__PURE__ */ jsxRuntimeExports.jsx(Area, { type: "monotone", dataKey: "views", stackId: "1", stroke: "#3b82f6", fill: "#3b82f6", fillOpacity: 0.6 }),
189        /* @__PURE__ */ jsxRuntimeExports.jsx(Area, { type: "monotone", dataKey: "plays", stackId: "1", stroke: "#8b5cf6", fill: "#8b5cf6", fillOpacity: 0.6 }),
190        /* @__PURE__ */ jsxRuntimeExports.jsx(Area, { type: "monotone", dataKey: "downloads", stackId: "1", stroke: "#10b981", fill: "#10b981", fillOpacity: 0.6 })
191      ] }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-full" })
192    ] }),
193    /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-3 gap-6", children: [
194      /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-zinc-900 border border-zinc-800 p-4 rounded-xl", children: [
195        /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-zinc-100 font-semibold mb-4", children: "Top Viewed" }),
196        /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3", children: (content == null ? void 0 : content.topViewed.slice(0, 10).map((t, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center text-sm", children: [
197          /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-400 truncate pr-2 flex-1", title: t.title, children: t.title }),
198          /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-100 font-medium", children: formatNum(t.views) })
199        ] }, i))) || /* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-48" }) })
200      ] }),
201      /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-zinc-900 border border-zinc-800 p-4 rounded-xl", children: [
202        /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-zinc-100 font-semibold mb-4", children: "Top Played" }),
203        /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3", children: (content == null ? void 0 : content.topPlayed.slice(0, 10).map((t, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center text-sm", children: [
204          /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-400 truncate pr-2 flex-1", title: t.title, children: t.title }),
205          /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-100 font-medium", children: formatNum(t.plays) })
206        ] }, i))) || /* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-48" }) })
207      ] }),
208      /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-zinc-900 border border-zinc-800 p-4 rounded-xl", children: [
209        /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-zinc-100 font-semibold mb-4", children: "Top Downloaded" }),
210        /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3", children: (content == null ? void 0 : content.topDownloaded.slice(0, 10).map((t, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center text-sm", children: [
211          /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-400 truncate pr-2 flex-1", title: t.title, children: t.title }),
212          /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-100 font-medium", children: formatNum(t.downloads) })
213        ] }, i))) || /* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-48" }) })
214      ] })
215    ] }),
216    /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-zinc-900 border border-zinc-800 p-6 rounded-xl", children: [
217      /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-zinc-100 font-semibold mb-4", children: "Download Breakdown" }),
218      content ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-full h-8 flex rounded overflow-hidden", children: [
219        /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { width: `${content.downloadBreakdown.midi / (content.downloadBreakdown.midi + content.downloadBreakdown.audio + content.downloadBreakdown.clean) * 100}%` }, className: "bg-blue-500 h-full flex items-center justify-center text-xs font-bold", title: "MIDI", children: "MIDI" }),
220        /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { width: `${content.downloadBreakdown.audio / (content.downloadBreakdown.midi + content.downloadBreakdown.audio + content.downloadBreakdown.clean) * 100}%` }, className: "bg-emerald-500 h-full flex items-center justify-center text-xs font-bold", title: "Audio", children: "Audio" }),
221        /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { width: `${content.downloadBreakdown.clean / (content.downloadBreakdown.midi + content.downloadBreakdown.audio + content.downloadBreakdown.clean) * 100}%` }, className: "bg-purple-500 h-full flex items-center justify-center text-xs font-bold", title: "Clean", children: "Clean" })
222      ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-8" })
223    ] })
224  ] });
225  const renderGames = () => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [
226    /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-4", children: [
227      /* @__PURE__ */ jsxRuntimeExports.jsx(MetricCard, { title: "Unique Players", metric: { value: (games == null ? void 0 : games.uniquePlayers) || 0, change: 0, previousValue: 0 }, icon: Users, color: "#10b981" }),
228      /* @__PURE__ */ jsxRuntimeExports.jsx(MetricCard, { title: "Average Accuracy", metric: { value: (games == null ? void 0 : games.avgAccuracy) || 0, change: 0, previousValue: 0 }, icon: Zap, color: "#8b5cf6", suffix: "%" }),
229      /* @__PURE__ */ jsxRuntimeExports.jsx(MetricCard, { title: "Average Score", metric: { value: (games == null ? void 0 : games.avgScore) || 0, change: 0, previousValue: 0 }, icon: TrendingUp, color: "#f59e0b" })
230    ] }),
231    /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-zinc-900 border border-zinc-800 p-6 rounded-xl h-96", children: [
232      /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-zinc-100 font-semibold mb-4", children: "Games Played by Mode" }),
233      games ? /* @__PURE__ */ jsxRuntimeExports.jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(LineChart, { data: games.timeSeries, margin: { top: 5, right: 30, left: 20, bottom: 5 }, children: [
234        /* @__PURE__ */ jsxRuntimeExports.jsx(CartesianGrid, { strokeDasharray: "3 3", stroke: "#27272a" }),
235        /* @__PURE__ */ jsxRuntimeExports.jsx(XAxis, { dataKey: "date", stroke: "#52525b", tick: { fill: "#a1a1aa" } }),
236        /* @__PURE__ */ jsxRuntimeExports.jsx(YAxis, { stroke: "#52525b", tick: { fill: "#a1a1aa" } }),
237        /* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip, { contentStyle: { backgroundColor: "#18181b", borderColor: "#27272a", color: "#f4f4f5" } }),
238        /* @__PURE__ */ jsxRuntimeExports.jsx(Legend, {}),
239        /* @__PURE__ */ jsxRuntimeExports.jsx(Line, { type: "monotone", dataKey: "pianoRoll", name: "Piano Roll", stroke: "#3b82f6", strokeWidth: 2, dot: false }),
240        /* @__PURE__ */ jsxRuntimeExports.jsx(Line, { type: "monotone", dataKey: "karaoke", name: "Karaoke", stroke: "#ec4899", strokeWidth: 2, dot: false }),
241        /* @__PURE__ */ jsxRuntimeExports.jsx(Line, { type: "monotone", dataKey: "taiko", name: "Taiko", stroke: "#f59e0b", strokeWidth: 2, dot: false })
242      ] }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-full" })
243    ] }),
244    /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-6", children: [
245      /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-zinc-900 border border-zinc-800 p-6 rounded-xl h-80", children: [
246        /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-zinc-100 font-semibold mb-4", children: "Score Distribution" }),
247        games ? /* @__PURE__ */ jsxRuntimeExports.jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(BarChart, { data: games.scoreDistribution, margin: { top: 5, right: 30, left: 0, bottom: 5 }, children: [
248          /* @__PURE__ */ jsxRuntimeExports.jsx(CartesianGrid, { strokeDasharray: "3 3", stroke: "#27272a", vertical: false }),
249          /* @__PURE__ */ jsxRuntimeExports.jsx(XAxis, { dataKey: "range", stroke: "#52525b", tick: { fill: "#a1a1aa" } }),
250          /* @__PURE__ */ jsxRuntimeExports.jsx(YAxis, { stroke: "#52525b", tick: { fill: "#a1a1aa" } }),
251          /* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip, { contentStyle: { backgroundColor: "#18181b", borderColor: "#27272a", color: "#f4f4f5" }, cursor: { fill: "#27272a" } }),
252          /* @__PURE__ */ jsxRuntimeExports.jsx(Bar, { dataKey: "count", fill: "#8b5cf6", radius: [4, 4, 0, 0] })
253        ] }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-full" })
254      ] }),
255      /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-zinc-900 border border-zinc-800 p-4 rounded-xl overflow-auto h-80", children: [
256        /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-zinc-100 font-semibold mb-4", children: "Top Played Tracks" }),
257        /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3", children: (games == null ? void 0 : games.topTracks.slice(0, 10).map((t, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center text-sm p-2 hover:bg-zinc-800/50 rounded", children: [
258          /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-400 truncate pr-2 flex-1", children: t.title }),
259          /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-zinc-100 font-medium bg-zinc-800 px-2 py-1 rounded", children: [
260            formatNum(t.plays),
261            " plays"
262          ] })
263        ] }, i))) || /* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-48" }) })
264      ] })
265    ] })
266  ] });
267  const renderUsers = () => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [
268    /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-4 gap-4", children: [
269      /* @__PURE__ */ jsxRuntimeExports.jsx(MetricCard, { title: "Total Users", metric: { value: (users == null ? void 0 : users.totalUsers) || 0, change: 0, previousValue: 0 }, icon: Users, color: "#3b82f6" }),
270      /* @__PURE__ */ jsxRuntimeExports.jsx(MetricCard, { title: "DAU (Daily Active)", metric: { value: (users == null ? void 0 : users.dau) || 0, change: 0, previousValue: 0 }, icon: Activity, color: "#10b981" }),
271      /* @__PURE__ */ jsxRuntimeExports.jsx(MetricCard, { title: "WAU (Weekly Active)", metric: { value: (users == null ? void 0 : users.wau) || 0, change: 0, previousValue: 0 }, icon: Activity, color: "#8b5cf6" }),
272      /* @__PURE__ */ jsxRuntimeExports.jsx(MetricCard, { title: "MAU (Monthly Active)", metric: { value: (users == null ? void 0 : users.mau) || 0, change: 0, previousValue: 0 }, icon: Activity, color: "#f59e0b" })
273    ] }),
274    /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-3 gap-6", children: [
275      /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lg:col-span-2 bg-zinc-900 border border-zinc-800 p-6 rounded-xl h-80", children: [
276        /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-zinc-100 font-semibold mb-4", children: "New Registrations" }),
277        users ? /* @__PURE__ */ jsxRuntimeExports.jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(BarChart, { data: users.timeSeries, margin: { top: 5, right: 30, left: 0, bottom: 5 }, children: [
278          /* @__PURE__ */ jsxRuntimeExports.jsx(CartesianGrid, { strokeDasharray: "3 3", stroke: "#27272a", vertical: false }),
279          /* @__PURE__ */ jsxRuntimeExports.jsx(XAxis, { dataKey: "date", stroke: "#52525b", tick: { fill: "#a1a1aa" } }),
280          /* @__PURE__ */ jsxRuntimeExports.jsx(YAxis, { stroke: "#52525b", tick: { fill: "#a1a1aa" } }),
281          /* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip, { contentStyle: { backgroundColor: "#18181b", borderColor: "#27272a", color: "#f4f4f5" }, cursor: { fill: "#27272a" } }),
282          /* @__PURE__ */ jsxRuntimeExports.jsx(Bar, { dataKey: "newUsers", fill: "#06b6d4", radius: [4, 4, 0, 0] })
283        ] }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-full" })
284      ] }),
285      /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-zinc-900 border border-zinc-800 p-6 rounded-xl flex flex-col", children: [
286        /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-zinc-100 font-semibold mb-4", children: "Subscriptions" }),
287        /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 min-h-[200px]", children: users ? /* @__PURE__ */ jsxRuntimeExports.jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(PieChart, { children: [
288          /* @__PURE__ */ jsxRuntimeExports.jsxs(Pie, { data: [
289            { name: "Free", value: users.subscriptionBreakdown.free },
290            { name: "Gold", value: users.subscriptionBreakdown.gold },
291            { name: "Premium", value: users.subscriptionBreakdown.premium }
292          ], cx: "50%", cy: "50%", innerRadius: 50, outerRadius: 80, paddingAngle: 2, dataKey: "value", nameKey: "name", children: [
293            /* @__PURE__ */ jsxRuntimeExports.jsx(Cell, { fill: "#9ca3af" }),
294            /* @__PURE__ */ jsxRuntimeExports.jsx(Cell, { fill: "#f59e0b" }),
295            /* @__PURE__ */ jsxRuntimeExports.jsx(Cell, { fill: "#3b82f6" })
296          ] }),
297          /* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip, { contentStyle: { backgroundColor: "#18181b", borderColor: "#27272a", color: "#f4f4f5" } }),
298          /* @__PURE__ */ jsxRuntimeExports.jsx(Legend, { verticalAlign: "bottom", height: 36 })
299        ] }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-full" }) })
300      ] })
301    ] })
302  ] });
303  const renderBots = () => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [
304    /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-zinc-900 border border-zinc-800 p-6 rounded-xl h-96", children: [
305      /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-zinc-100 font-semibold mb-4", children: "Bot Visits Over Time" }),
306      bots ? /* @__PURE__ */ jsxRuntimeExports.jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(AreaChart, { data: bots.timeSeries, margin: { top: 10, right: 30, left: 0, bottom: 0 }, children: [
307        /* @__PURE__ */ jsxRuntimeExports.jsx(XAxis, { dataKey: "date", stroke: "#52525b", tick: { fill: "#a1a1aa" } }),
308        /* @__PURE__ */ jsxRuntimeExports.jsx(YAxis, { stroke: "#52525b", tick: { fill: "#a1a1aa" } }),
309        /* @__PURE__ */ jsxRuntimeExports.jsx(CartesianGrid, { strokeDasharray: "3 3", stroke: "#27272a" }),
310        /* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip, { contentStyle: { backgroundColor: "#18181b", borderColor: "#27272a", color: "#f4f4f5" } }),
311        /* @__PURE__ */ jsxRuntimeExports.jsx(Legend, {}),
312        Object.keys(bots.timeSeries[0] || {}).filter((k) => k !== "date").map((key, i) => /* @__PURE__ */ jsxRuntimeExports.jsx(Area, { type: "monotone", dataKey: key, stackId: "1", stroke: COLORS[i % COLORS.length], fill: COLORS[i % COLORS.length], fillOpacity: 0.6 }, key))
313      ] }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-full" })
314    ] }),
315    /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-6", children: [
316      /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-zinc-900 border border-zinc-800 p-4 rounded-xl", children: [
317        /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-zinc-100 font-semibold mb-4", children: "Top Bots" }),
318        /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3", children: (bots == null ? void 0 : bots.topBots.slice(0, 10).map((b, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center text-sm p-2 hover:bg-zinc-800/50 rounded", children: [
319          /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-400 font-mono", children: b.name }),
320          /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-100 font-medium bg-zinc-800 px-2 py-1 rounded", children: formatNum(b.visits) })
321        ] }, i))) || /* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-48" }) })
322      ] }),
323      /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-zinc-900 border border-zinc-800 p-4 rounded-xl", children: [
324        /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-zinc-100 font-semibold mb-4", children: "Most Crawled Pages" }),
325        /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3", children: (bots == null ? void 0 : bots.topCrawledPages.slice(0, 10).map((p, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center text-sm p-2 hover:bg-zinc-800/50 rounded", children: [
326          /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-400 truncate pr-2 flex-1", children: p.route }),
327          /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-100 font-medium bg-zinc-800 px-2 py-1 rounded", children: formatNum(p.visits) })
328        ] }, i))) || /* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-48" }) })
329      ] })
330    ] })
331  ] });
332  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-6 bg-zinc-950 min-h-screen text-zinc-100 font-sans", children: [
333    /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col md:flex-row justify-between items-start md:items-center mb-8 gap-4", children: [
334      /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
335        /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-2 bg-blue-500/20 text-blue-400 rounded-lg", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Activity, { size: 24 }) }),
336        /* @__PURE__ */ jsxRuntimeExports.jsx("h1", { className: "text-2xl font-bold", children: "Analytics" })
337      ] }),
338      /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-4 bg-zinc-900 p-2 rounded-xl border border-zinc-800", children: [
339        /* @__PURE__ */ jsxRuntimeExports.jsx(
340          "select",
341          {
342            className: "bg-zinc-800 border-none text-sm rounded-lg px-3 py-2 text-zinc-200 outline-none focus:ring-2 focus:ring-blue-500",
343            value: range,
344            onChange: (e) => setRange(e.target.value),
345            children: ranges.map((r) => /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: r.value, children: r.label }, r.value))
346          }
347        ),
348        /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "flex items-center gap-2 text-sm text-zinc-400 cursor-pointer", children: [
349          /* @__PURE__ */ jsxRuntimeExports.jsx(
350            "input",
351            {
352              type: "checkbox",
353              checked: autoRefresh,
354              onChange: (e) => setAutoRefresh(e.target.checked),
355              className: "rounded bg-zinc-800 border-zinc-700 text-blue-500 focus:ring-blue-500 focus:ring-offset-zinc-900"
356            }
357          ),
358          "Auto-refresh"
359        ] }),
360        /* @__PURE__ */ jsxRuntimeExports.jsx(
361          "button",
362          {
363            onClick: () => setRefreshTrigger((prev) => prev + 1),
364            disabled: loading,
365            className: "p-2 text-zinc-400 hover:text-zinc-100 hover:bg-zinc-800 rounded-lg transition-colors disabled:opacity-50",
366            title: "Refresh now",
367            children: /* @__PURE__ */ jsxRuntimeExports.jsx(RefreshCw, { size: 18, className: loading ? "animate-spin" : "" })
368          }
369        )
370      ] })
371    ] }),
372    error && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-6 p-4 bg-red-500/20 border border-red-500/50 rounded-xl text-red-200", children: error }),
373    /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex border-b border-zinc-800 mb-6 overflow-x-auto no-scrollbar", children: TABS.map((t) => /* @__PURE__ */ jsxRuntimeExports.jsx(
374      "button",
375      {
376        onClick: () => setTab(t),
377        className: `px-6 py-3 font-medium text-sm whitespace-nowrap border-b-2 transition-colors ${tab === t ? "border-blue-500 text-blue-400" : "border-transparent text-zinc-400 hover:text-zinc-200 hover:bg-zinc-900/50"}`,
378        children: t
379      },
380      t
381    )) }),
382    /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "transition-opacity duration-300", children: [
383      tab === "Overview" && renderOverview(),
384      tab === "Traffic" && renderTraffic(),
385      tab === "Content" && renderContent(),
386      tab === "Games" && renderGames(),
387      tab === "Users" && renderUsers(),
388      tab === "Bots" && renderBots()
389    ] })
390  ] });
391}
392export {
393  BIDashboard as default
394};

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.