Spaces:
Running
Running
Apply Tailwind v4 shorthand fixes; narrow eslint disables to real FPs
Browse filesAuto-fixes from eslint-plugin-better-tailwindcss (enforce-canonical-classes
re-enabled — these are real Tailwind v4 shorthands, not stylistic preferences):
- h-full w-full → size-full
- h-5 w-5 → size-5
- px-2 py-2 → p-2
- text-{sm,xs} leading-relaxed → text-{sm,xs}/relaxed
- -translate-x-1/2 -translate-y-1/2 → -translate-1/2
- data-[disabled]:foo → data-disabled:foo
- break-words → wrap-break-word
Only no-unknown-classes stays disabled — it can't see classes defined in
Svelte <style> blocks (.vs-beam, .vp-freeze, ...).
- eslint.config.js +3 -5
- src/lib/components/grid-tile.svelte +4 -4
- src/lib/components/map-preview.svelte +3 -3
- src/lib/components/perspective-grid.svelte +2 -2
- src/lib/components/player-grid.svelte +1 -1
- src/lib/components/round-list.svelte +1 -3
- src/lib/components/timeline-bar.svelte +1 -1
- src/lib/components/video-player/playbar.svelte +1 -1
- src/lib/components/video-player/video-player.svelte +3 -3
- src/lib/components/video-stage.svelte +3 -3
- src/routes/+page.svelte +8 -8
eslint.config.js
CHANGED
|
@@ -12,11 +12,9 @@ const tailwindRules = {
|
|
| 12 |
...eslintPluginBetterTailwindcss.configs.recommended.rules,
|
| 13 |
// Prettier handles physical line wrapping
|
| 14 |
'better-tailwindcss/enforce-consistent-line-wrapping': 'off',
|
| 15 |
-
//
|
| 16 |
-
//
|
| 17 |
-
'better-tailwindcss/no-unknown-classes': 'off'
|
| 18 |
-
// `h-full w-full` ≠ `size-full` semantically when a parent is asymmetric
|
| 19 |
-
'better-tailwindcss/enforce-canonical-classes': 'off'
|
| 20 |
};
|
| 21 |
|
| 22 |
export default [
|
|
|
|
| 12 |
...eslintPluginBetterTailwindcss.configs.recommended.rules,
|
| 13 |
// Prettier handles physical line wrapping
|
| 14 |
'better-tailwindcss/enforce-consistent-line-wrapping': 'off',
|
| 15 |
+
// False-positives on classes defined inside Svelte <style> blocks
|
| 16 |
+
// (`vs-beam`, `vp-freeze`, ...) that the plugin can't see
|
| 17 |
+
'better-tailwindcss/no-unknown-classes': 'off'
|
|
|
|
|
|
|
| 18 |
};
|
| 19 |
|
| 20 |
export default [
|
src/lib/components/grid-tile.svelte
CHANGED
|
@@ -168,12 +168,12 @@
|
|
| 168 |
ontimeupdate={onTimeUpdate}
|
| 169 |
onended={onEnded}
|
| 170 |
onprogress={onProgress}
|
| 171 |
-
class="
|
| 172 |
></video>
|
| 173 |
|
| 174 |
<!-- top-left: player number, colored per slot -->
|
| 175 |
<div
|
| 176 |
-
class="absolute top-1.5 left-1.5 flex
|
| 177 |
style="background-color: {color};"
|
| 178 |
>
|
| 179 |
{player}
|
|
@@ -181,7 +181,7 @@
|
|
| 181 |
|
| 182 |
{#if isLeader}
|
| 183 |
<div
|
| 184 |
-
class="absolute top-1.5 right-1.5 grid
|
| 185 |
aria-label="Audio source"
|
| 186 |
title="Audio source"
|
| 187 |
>
|
|
@@ -191,7 +191,7 @@
|
|
| 191 |
|
| 192 |
{#if !available}
|
| 193 |
<div
|
| 194 |
-
class="absolute right-1.5 bottom-1.5 grid
|
| 195 |
aria-label="Player is dead"
|
| 196 |
title="Player is dead"
|
| 197 |
>
|
|
|
|
| 168 |
ontimeupdate={onTimeUpdate}
|
| 169 |
onended={onEnded}
|
| 170 |
onprogress={onProgress}
|
| 171 |
+
class="size-full object-cover"
|
| 172 |
></video>
|
| 173 |
|
| 174 |
<!-- top-left: player number, colored per slot -->
|
| 175 |
<div
|
| 176 |
+
class="absolute top-1.5 left-1.5 flex size-6 items-center justify-center rounded-sm font-mono text-[11px] font-bold text-white/95 shadow-sm ring-1 ring-black/20"
|
| 177 |
style="background-color: {color};"
|
| 178 |
>
|
| 179 |
{player}
|
|
|
|
| 181 |
|
| 182 |
{#if isLeader}
|
| 183 |
<div
|
| 184 |
+
class="absolute top-1.5 right-1.5 grid size-5 place-items-center rounded-sm bg-emerald-500/85 text-white shadow-sm ring-1 ring-black/20"
|
| 185 |
aria-label="Audio source"
|
| 186 |
title="Audio source"
|
| 187 |
>
|
|
|
|
| 191 |
|
| 192 |
{#if !available}
|
| 193 |
<div
|
| 194 |
+
class="absolute right-1.5 bottom-1.5 grid size-5 place-items-center rounded-sm bg-rose-500/85 text-white shadow-sm ring-1 ring-black/20"
|
| 195 |
aria-label="Player is dead"
|
| 196 |
title="Player is dead"
|
| 197 |
>
|
src/lib/components/map-preview.svelte
CHANGED
|
@@ -92,17 +92,17 @@
|
|
| 92 |
style={size === undefined ? undefined : `width: ${size}px; height: ${size}px;`}
|
| 93 |
>
|
| 94 |
{#if !map}
|
| 95 |
-
<Skeleton class="
|
| 96 |
{:else}
|
| 97 |
<img
|
| 98 |
src={radarUrl(mapName, displayedFloor)}
|
| 99 |
alt="{mapName} radar"
|
| 100 |
-
class="absolute inset-0
|
| 101 |
draggable="false"
|
| 102 |
/>
|
| 103 |
<svg
|
| 104 |
viewBox="0 0 {RADAR_PX} {RADAR_PX}"
|
| 105 |
-
class="absolute inset-0
|
| 106 |
aria-label="Player positions on {mapName}"
|
| 107 |
>
|
| 108 |
{#each players as p (p.steamid)}
|
|
|
|
| 92 |
style={size === undefined ? undefined : `width: ${size}px; height: ${size}px;`}
|
| 93 |
>
|
| 94 |
{#if !map}
|
| 95 |
+
<Skeleton class="size-full rounded-md" />
|
| 96 |
{:else}
|
| 97 |
<img
|
| 98 |
src={radarUrl(mapName, displayedFloor)}
|
| 99 |
alt="{mapName} radar"
|
| 100 |
+
class="absolute inset-0 size-full rounded-md opacity-70 select-none"
|
| 101 |
draggable="false"
|
| 102 |
/>
|
| 103 |
<svg
|
| 104 |
viewBox="0 0 {RADAR_PX} {RADAR_PX}"
|
| 105 |
+
class="absolute inset-0 size-full"
|
| 106 |
aria-label="Player positions on {mapName}"
|
| 107 |
>
|
| 108 |
{#each players as p (p.steamid)}
|
src/lib/components/perspective-grid.svelte
CHANGED
|
@@ -137,7 +137,7 @@
|
|
| 137 |
/>
|
| 138 |
<div class="flex items-center gap-1.5 px-0.5 text-xs">
|
| 139 |
<span
|
| 140 |
-
class="inline-block
|
| 141 |
style={`background: ${playerColor(player.player)};`}
|
| 142 |
></span>
|
| 143 |
<span class="truncate font-medium">Player {player.player}</span>
|
|
@@ -176,7 +176,7 @@
|
|
| 176 |
/>
|
| 177 |
<div class="flex items-center gap-1.5 px-0.5 text-xs">
|
| 178 |
<span
|
| 179 |
-
class="inline-block
|
| 180 |
style={`background: ${playerColor(player.player)};`}
|
| 181 |
></span>
|
| 182 |
<span class="truncate font-medium">Player {player.player}</span>
|
|
|
|
| 137 |
/>
|
| 138 |
<div class="flex items-center gap-1.5 px-0.5 text-xs">
|
| 139 |
<span
|
| 140 |
+
class="inline-block size-2 shrink-0 rounded-full"
|
| 141 |
style={`background: ${playerColor(player.player)};`}
|
| 142 |
></span>
|
| 143 |
<span class="truncate font-medium">Player {player.player}</span>
|
|
|
|
| 176 |
/>
|
| 177 |
<div class="flex items-center gap-1.5 px-0.5 text-xs">
|
| 178 |
<span
|
| 179 |
+
class="inline-block size-2 shrink-0 rounded-full"
|
| 180 |
style={`background: ${playerColor(player.player)};`}
|
| 181 |
></span>
|
| 182 |
<span class="truncate font-medium">Player {player.player}</span>
|
src/lib/components/player-grid.svelte
CHANGED
|
@@ -87,7 +87,7 @@
|
|
| 87 |
)}
|
| 88 |
>
|
| 89 |
<span
|
| 90 |
-
class="flex
|
| 91 |
style="background-color: {playerColor(p.player)};"
|
| 92 |
>
|
| 93 |
{p.player}
|
|
|
|
| 87 |
)}
|
| 88 |
>
|
| 89 |
<span
|
| 90 |
+
class="flex size-7 shrink-0 items-center justify-center rounded-sm font-mono text-xs font-bold text-white/95 shadow-sm ring-1 ring-black/20"
|
| 91 |
style="background-color: {playerColor(p.player)};"
|
| 92 |
>
|
| 93 |
{p.player}
|
src/lib/components/round-list.svelte
CHANGED
|
@@ -28,9 +28,7 @@
|
|
| 28 |
</script>
|
| 29 |
|
| 30 |
<div class="flex h-full min-h-0 flex-col">
|
| 31 |
-
<div
|
| 32 |
-
class="border-b px-2 py-2 text-[10px] font-semibold tracking-wide text-muted-foreground uppercase"
|
| 33 |
-
>
|
| 34 |
Rounds <span class="ml-1 text-muted-foreground/50">({rounds.length})</span>
|
| 35 |
</div>
|
| 36 |
<ScrollArea class="min-h-0 flex-1">
|
|
|
|
| 28 |
</script>
|
| 29 |
|
| 30 |
<div class="flex h-full min-h-0 flex-col">
|
| 31 |
+
<div class="border-b p-2 text-[10px] font-semibold tracking-wide text-muted-foreground uppercase">
|
|
|
|
|
|
|
| 32 |
Rounds <span class="ml-1 text-muted-foreground/50">({rounds.length})</span>
|
| 33 |
</div>
|
| 34 |
<ScrollArea class="min-h-0 flex-1">
|
src/lib/components/timeline-bar.svelte
CHANGED
|
@@ -43,7 +43,7 @@
|
|
| 43 |
aria-disabled={disabled}
|
| 44 |
class={cn(
|
| 45 |
'flex items-center gap-3 rounded-lg border bg-card px-3 py-2 shadow-sm',
|
| 46 |
-
'data-
|
| 47 |
)}
|
| 48 |
>
|
| 49 |
<Button
|
|
|
|
| 43 |
aria-disabled={disabled}
|
| 44 |
class={cn(
|
| 45 |
'flex items-center gap-3 rounded-lg border bg-card px-3 py-2 shadow-sm',
|
| 46 |
+
'data-disabled:pointer-events-none data-disabled:opacity-60'
|
| 47 |
)}
|
| 48 |
>
|
| 49 |
<Button
|
src/lib/components/video-player/playbar.svelte
CHANGED
|
@@ -128,7 +128,7 @@
|
|
| 128 |
<div
|
| 129 |
data-dragging={isDragging}
|
| 130 |
class={cn(
|
| 131 |
-
'absolute top-1/2 size-3 -translate-
|
| 132 |
'group-hover/playbar:opacity-100 data-[dragging=true]:opacity-100'
|
| 133 |
)}
|
| 134 |
style:left="{visiblePct}%"
|
|
|
|
| 128 |
<div
|
| 129 |
data-dragging={isDragging}
|
| 130 |
class={cn(
|
| 131 |
+
'absolute top-1/2 size-3 -translate-1/2 rounded-full bg-primary opacity-0 transition-opacity',
|
| 132 |
'group-hover/playbar:opacity-100 data-[dragging=true]:opacity-100'
|
| 133 |
)}
|
| 134 |
style:left="{visiblePct}%"
|
src/lib/components/video-player/video-player.svelte
CHANGED
|
@@ -289,7 +289,7 @@
|
|
| 289 |
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
|
| 290 |
<div
|
| 291 |
bind:this={containerEl}
|
| 292 |
-
class="relative
|
| 293 |
role="region"
|
| 294 |
aria-label="Video player"
|
| 295 |
tabindex="0"
|
|
@@ -309,7 +309,7 @@
|
|
| 309 |
disableremoteplayback
|
| 310 |
controlslist="nodownload nofullscreen noplaybackrate noremoteplayback"
|
| 311 |
oncontextmenu={(e) => e.preventDefault()}
|
| 312 |
-
class="
|
| 313 |
onloadedmetadata={onLoadedMetadata}
|
| 314 |
onloadeddata={onLoadedData}
|
| 315 |
onplay={onPlay}
|
|
@@ -323,7 +323,7 @@
|
|
| 323 |
bind:this={canvasEl}
|
| 324 |
data-wipe={dissolveFreeze || undefined}
|
| 325 |
class={cn(
|
| 326 |
-
'vp-freeze pointer-events-none absolute inset-0 z-10
|
| 327 |
!showFreezeFrame && 'hidden'
|
| 328 |
)}
|
| 329 |
aria-hidden="true"
|
|
|
|
| 289 |
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
|
| 290 |
<div
|
| 291 |
bind:this={containerEl}
|
| 292 |
+
class="relative size-full overflow-hidden bg-black"
|
| 293 |
role="region"
|
| 294 |
aria-label="Video player"
|
| 295 |
tabindex="0"
|
|
|
|
| 309 |
disableremoteplayback
|
| 310 |
controlslist="nodownload nofullscreen noplaybackrate noremoteplayback"
|
| 311 |
oncontextmenu={(e) => e.preventDefault()}
|
| 312 |
+
class="size-full object-cover"
|
| 313 |
onloadedmetadata={onLoadedMetadata}
|
| 314 |
onloadeddata={onLoadedData}
|
| 315 |
onplay={onPlay}
|
|
|
|
| 323 |
bind:this={canvasEl}
|
| 324 |
data-wipe={dissolveFreeze || undefined}
|
| 325 |
class={cn(
|
| 326 |
+
'vp-freeze pointer-events-none absolute inset-0 z-10 size-full object-contain',
|
| 327 |
!showFreezeFrame && 'hidden'
|
| 328 |
)}
|
| 329 |
aria-hidden="true"
|
src/lib/components/video-stage.svelte
CHANGED
|
@@ -82,7 +82,7 @@
|
|
| 82 |
<div class="overflow-hidden rounded-lg border bg-card shadow-sm">
|
| 83 |
<AspectRatio ratio={16 / 9} class="bg-black">
|
| 84 |
{#if loading}
|
| 85 |
-
<Skeleton class="
|
| 86 |
<div class="absolute inset-0 flex items-center justify-center text-muted-foreground">
|
| 87 |
<div class="text-center">
|
| 88 |
<SpinnerIcon size={32} weight="duotone" class="mx-auto mb-2 animate-spin opacity-70" />
|
|
@@ -96,7 +96,7 @@
|
|
| 96 |
<div class="max-w-sm px-6 text-center">
|
| 97 |
<WarningCircleIcon size={32} weight="duotone" class="mx-auto mb-2 text-destructive" />
|
| 98 |
<p class="text-sm font-medium text-foreground">Couldn't load clip</p>
|
| 99 |
-
<p class="mt-1 text-xs break-
|
| 100 |
</div>
|
| 101 |
</div>
|
| 102 |
{:else if !chunks.length}
|
|
@@ -160,7 +160,7 @@
|
|
| 160 |
style="box-shadow: 0 0 24px {switchPing.color}55;"
|
| 161 |
>
|
| 162 |
<span
|
| 163 |
-
class="inline-flex
|
| 164 |
style="background-color: {switchPing.color};"
|
| 165 |
>
|
| 166 |
{switchPing.player}
|
|
|
|
| 82 |
<div class="overflow-hidden rounded-lg border bg-card shadow-sm">
|
| 83 |
<AspectRatio ratio={16 / 9} class="bg-black">
|
| 84 |
{#if loading}
|
| 85 |
+
<Skeleton class="size-full rounded-none" />
|
| 86 |
<div class="absolute inset-0 flex items-center justify-center text-muted-foreground">
|
| 87 |
<div class="text-center">
|
| 88 |
<SpinnerIcon size={32} weight="duotone" class="mx-auto mb-2 animate-spin opacity-70" />
|
|
|
|
| 96 |
<div class="max-w-sm px-6 text-center">
|
| 97 |
<WarningCircleIcon size={32} weight="duotone" class="mx-auto mb-2 text-destructive" />
|
| 98 |
<p class="text-sm font-medium text-foreground">Couldn't load clip</p>
|
| 99 |
+
<p class="mt-1 text-xs wrap-break-word text-muted-foreground">{error}</p>
|
| 100 |
</div>
|
| 101 |
</div>
|
| 102 |
{:else if !chunks.length}
|
|
|
|
| 160 |
style="box-shadow: 0 0 24px {switchPing.color}55;"
|
| 161 |
>
|
| 162 |
<span
|
| 163 |
+
class="inline-flex size-5 items-center justify-center rounded-sm font-mono text-[11px] font-bold text-white"
|
| 164 |
style="background-color: {switchPing.color};"
|
| 165 |
>
|
| 166 |
{switchPing.player}
|
src/routes/+page.svelte
CHANGED
|
@@ -151,7 +151,7 @@
|
|
| 151 |
</Button>
|
| 152 |
</div>
|
| 153 |
|
| 154 |
-
<p class="mt-8 text-sm
|
| 155 |
A rendered dataset of professional Counter Strike 2 matches: every round captured from all ten
|
| 156 |
player POVs, frame-aligned, with spatialized audio, mouse/keyboard inputs, and per-tick world
|
| 157 |
state. Built from HLTV demos, served as parquet shards, and browsable here without downloading
|
|
@@ -166,7 +166,7 @@
|
|
| 166 |
>
|
| 167 |
Motivation
|
| 168 |
</h2>
|
| 169 |
-
<p class="mx-auto mt-3 max-w-2xl text-center text-sm
|
| 170 |
Pro CS2 demos are a goldmine of expert sequential decision-making — long horizons, partial
|
| 171 |
observability, dense visual signal, and 5v5 multi-agent dynamics. This dataset turns them into
|
| 172 |
trainable rendered video.
|
|
@@ -178,7 +178,7 @@
|
|
| 178 |
<div class="font-heading text-sm font-semibold tracking-tight">
|
| 179 |
{m.title}
|
| 180 |
</div>
|
| 181 |
-
<p class="mt-1 text-xs
|
| 182 |
{m.body}
|
| 183 |
</p>
|
| 184 |
</div>
|
|
@@ -199,7 +199,7 @@
|
|
| 199 |
Video
|
| 200 |
</div>
|
| 201 |
<div class="mt-1 font-heading text-sm font-semibold">1280×720 · 32 fps</div>
|
| 202 |
-
<p class="mt-1 text-xs
|
| 203 |
Near-lossless H.264, one stream per player POV. 10 streams per round, all tick-aligned.
|
| 204 |
</p>
|
| 205 |
</div>
|
|
@@ -208,7 +208,7 @@
|
|
| 208 |
Inputs
|
| 209 |
</div>
|
| 210 |
<div class="mt-1 font-heading text-sm font-semibold">Keyboard + mouse</div>
|
| 211 |
-
<p class="mt-1 text-xs
|
| 212 |
Per-tick keystrokes, mouse delta, fire/jump/use, weapon switches — the actions a policy
|
| 213 |
has to predict.
|
| 214 |
</p>
|
|
@@ -218,7 +218,7 @@
|
|
| 218 |
World state
|
| 219 |
</div>
|
| 220 |
<div class="mt-1 font-heading text-sm font-semibold">Per-tick game state</div>
|
| 221 |
-
<p class="mt-1 text-xs
|
| 222 |
Positions, velocities, camera intrinsics, health, armor, ammo, weapons — for all 10
|
| 223 |
players, every tick.
|
| 224 |
</p>
|
|
@@ -228,7 +228,7 @@
|
|
| 228 |
G-buffers <span class="text-amber-600 dark:text-amber-400">· soon</span>
|
| 229 |
</div>
|
| 230 |
<div class="mt-1 font-heading text-sm font-semibold">Luminance · depth · vertex IDs</div>
|
| 231 |
-
<p class="mt-1 text-xs
|
| 232 |
Per-pixel auxiliary channels for self-supervised pretraining and dense prediction heads.
|
| 233 |
</p>
|
| 234 |
</div>
|
|
@@ -338,7 +338,7 @@
|
|
| 338 |
BibTeX
|
| 339 |
</h2>
|
| 340 |
<pre
|
| 341 |
-
class="mt-3 overflow-x-auto rounded-md border bg-card p-4 text-left font-mono text-xs
|
| 342 |
author = {Julien Blanchon},
|
| 343 |
title = {Counter Strike 2 Dataset},
|
| 344 |
year = {2026},
|
|
|
|
| 151 |
</Button>
|
| 152 |
</div>
|
| 153 |
|
| 154 |
+
<p class="mt-8 text-sm/relaxed text-pretty text-muted-foreground md:text-base">
|
| 155 |
A rendered dataset of professional Counter Strike 2 matches: every round captured from all ten
|
| 156 |
player POVs, frame-aligned, with spatialized audio, mouse/keyboard inputs, and per-tick world
|
| 157 |
state. Built from HLTV demos, served as parquet shards, and browsable here without downloading
|
|
|
|
| 166 |
>
|
| 167 |
Motivation
|
| 168 |
</h2>
|
| 169 |
+
<p class="mx-auto mt-3 max-w-2xl text-center text-sm/relaxed text-muted-foreground">
|
| 170 |
Pro CS2 demos are a goldmine of expert sequential decision-making — long horizons, partial
|
| 171 |
observability, dense visual signal, and 5v5 multi-agent dynamics. This dataset turns them into
|
| 172 |
trainable rendered video.
|
|
|
|
| 178 |
<div class="font-heading text-sm font-semibold tracking-tight">
|
| 179 |
{m.title}
|
| 180 |
</div>
|
| 181 |
+
<p class="mt-1 text-xs/relaxed text-muted-foreground">
|
| 182 |
{m.body}
|
| 183 |
</p>
|
| 184 |
</div>
|
|
|
|
| 199 |
Video
|
| 200 |
</div>
|
| 201 |
<div class="mt-1 font-heading text-sm font-semibold">1280×720 · 32 fps</div>
|
| 202 |
+
<p class="mt-1 text-xs/relaxed text-muted-foreground">
|
| 203 |
Near-lossless H.264, one stream per player POV. 10 streams per round, all tick-aligned.
|
| 204 |
</p>
|
| 205 |
</div>
|
|
|
|
| 208 |
Inputs
|
| 209 |
</div>
|
| 210 |
<div class="mt-1 font-heading text-sm font-semibold">Keyboard + mouse</div>
|
| 211 |
+
<p class="mt-1 text-xs/relaxed text-muted-foreground">
|
| 212 |
Per-tick keystrokes, mouse delta, fire/jump/use, weapon switches — the actions a policy
|
| 213 |
has to predict.
|
| 214 |
</p>
|
|
|
|
| 218 |
World state
|
| 219 |
</div>
|
| 220 |
<div class="mt-1 font-heading text-sm font-semibold">Per-tick game state</div>
|
| 221 |
+
<p class="mt-1 text-xs/relaxed text-muted-foreground">
|
| 222 |
Positions, velocities, camera intrinsics, health, armor, ammo, weapons — for all 10
|
| 223 |
players, every tick.
|
| 224 |
</p>
|
|
|
|
| 228 |
G-buffers <span class="text-amber-600 dark:text-amber-400">· soon</span>
|
| 229 |
</div>
|
| 230 |
<div class="mt-1 font-heading text-sm font-semibold">Luminance · depth · vertex IDs</div>
|
| 231 |
+
<p class="mt-1 text-xs/relaxed text-muted-foreground">
|
| 232 |
Per-pixel auxiliary channels for self-supervised pretraining and dense prediction heads.
|
| 233 |
</p>
|
| 234 |
</div>
|
|
|
|
| 338 |
BibTeX
|
| 339 |
</h2>
|
| 340 |
<pre
|
| 341 |
+
class="mt-3 overflow-x-auto rounded-md border bg-card p-4 text-left font-mono text-xs/relaxed text-foreground/90">{`@misc{blanchon2026cs2dataset,
|
| 342 |
author = {Julien Blanchon},
|
| 343 |
title = {Counter Strike 2 Dataset},
|
| 344 |
year = {2026},
|