agentlytics 0.2.12 → 0.2.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,10 +3,24 @@ const path = require('path');
3
3
  const os = require('os');
4
4
  const fs = require('fs');
5
5
 
6
- // Windsurf variants: Windsurf, Windsurf Next
6
+ // Devin variants. Keep legacy Windsurf identifiers only for detection/config compatibility.
7
7
  const VARIANTS = [
8
- { id: 'windsurf', matchKey: 'ide', matchVal: 'windsurf', https: false, appName: 'Windsurf', needsMetadata: true },
9
- { id: 'windsurf-next', matchKey: 'ide', matchVal: 'windsurf-next', https: false, appName: 'Windsurf - Next', needsMetadata: true },
8
+ {
9
+ id: 'devin',
10
+ matchKey: 'ide',
11
+ matchVals: ['windsurf', 'devin', 'devin-desktop'],
12
+ https: false,
13
+ appNames: ['Devin Desktop', 'Devin', 'Windsurf'],
14
+ needsMetadata: true,
15
+ },
16
+ {
17
+ id: 'devin-next',
18
+ matchKey: 'ide',
19
+ matchVals: ['windsurf-next', 'devin-next', 'devin-desktop-next'],
20
+ https: false,
21
+ appNames: ['Devin Desktop - Next', 'Devin - Next', 'Windsurf - Next'],
22
+ needsMetadata: true,
23
+ },
10
24
  ];
11
25
 
12
26
  // ============================================================
@@ -85,7 +99,7 @@ function getListeningPorts(pid) {
85
99
  }
86
100
 
87
101
  // ============================================================
88
- // Find running Windsurf language server (port + CSRF token)
102
+ // Find running Devin language server (port + CSRF token)
89
103
  // ============================================================
90
104
 
91
105
  let _lsCache = null;
@@ -101,13 +115,13 @@ function findLanguageServers() {
101
115
  ? 'language_server_macos'
102
116
  : 'language_server_linux';
103
117
 
104
- // On macOS/Linux, also check env vars for WINDSURF_CSRF_TOKEN (newer Windsurf Next passes CSRF via env, not CLI arg)
118
+ // On macOS/Linux, also check env vars for CSRF tokens (some variants pass CSRF via env, not CLI arg)
105
119
  const envCsrfByPid = {};
106
120
  if (!IS_WINDOWS) {
107
121
  try {
108
122
  const psEnv = execSync('ps eww -A', { encoding: 'utf-8', maxBuffer: 2 * 1024 * 1024, stdio: ['pipe', 'pipe', 'pipe'] });
109
123
  for (const envLine of psEnv.split('\n')) {
110
- const envCsrf = envLine.match(/WINDSURF_CSRF_TOKEN=(\S+)/);
124
+ const envCsrf = envLine.match(/(?:WINDSURF|DEVIN)_CSRF_TOKEN=(\S+)/);
111
125
  if (envCsrf) {
112
126
  const envPid = envLine.match(/^\s*(\d+)/);
113
127
  if (envPid) envCsrfByPid[envPid[1]] = envCsrf[1];
@@ -162,10 +176,11 @@ function findLanguageServers() {
162
176
  function getLsForVariant(variant) {
163
177
  const servers = findLanguageServers();
164
178
  let matches;
179
+ const matchVals = variant.matchVals || [variant.matchVal];
165
180
  if (variant.matchKey === 'appDataDir') {
166
- matches = servers.filter(s => s.appDataDir?.includes(variant.matchVal));
181
+ matches = servers.filter(s => matchVals.some(matchVal => s.appDataDir?.includes(matchVal)));
167
182
  } else {
168
- matches = servers.filter(s => s.ide === variant.matchVal);
183
+ matches = servers.filter(s => matchVals.includes(s.ide));
169
184
  }
170
185
  return matches.length > 0 ? matches[0] : null;
171
186
  }
@@ -197,8 +212,9 @@ function callRpc(port, csrf, method, body, extCsrf = null) {
197
212
  // Adapter interface
198
213
  // ============================================================
199
214
 
200
- const name = 'windsurf';
201
- const sources = ['windsurf', 'windsurf-next'];
215
+ const name = 'devin';
216
+ const sources = ['devin', 'devin-next'];
217
+ const legacySources = ['windsurf', 'windsurf-next'];
202
218
 
203
219
  function getChats() {
204
220
  const chats = [];
@@ -449,29 +465,39 @@ function getMessages(chat) {
449
465
  // Usage / quota data from language server RPC
450
466
  // ============================================================
451
467
 
452
- function getWindsurfApiKey(appName) {
453
- if (!appName) return null;
468
+ function getDevinApiKey(appNames) {
469
+ if (!appNames) return null;
470
+ const names = Array.isArray(appNames) ? appNames : [appNames];
471
+ const keys = ['windsurfAuthStatus', 'devinAuthStatus'];
454
472
  try {
455
473
  const HOME = os.homedir();
456
- let dbPath;
457
- switch (process.platform) {
458
- case 'darwin':
459
- dbPath = path.join(HOME, 'Library', 'Application Support', appName, 'User', 'globalStorage', 'state.vscdb');
460
- break;
461
- case 'win32':
462
- dbPath = path.join(HOME, 'AppData', 'Roaming', appName, 'User', 'globalStorage', 'state.vscdb');
463
- break;
464
- default:
465
- dbPath = path.join(HOME, '.config', appName, 'User', 'globalStorage', 'state.vscdb');
474
+ for (const appName of names) {
475
+ let dbPath;
476
+ switch (process.platform) {
477
+ case 'darwin':
478
+ dbPath = path.join(HOME, 'Library', 'Application Support', appName, 'User', 'globalStorage', 'state.vscdb');
479
+ break;
480
+ case 'win32':
481
+ dbPath = path.join(HOME, 'AppData', 'Roaming', appName, 'User', 'globalStorage', 'state.vscdb');
482
+ break;
483
+ default:
484
+ dbPath = path.join(HOME, '.config', appName, 'User', 'globalStorage', 'state.vscdb');
485
+ }
486
+ if (!fs.existsSync(dbPath)) continue;
487
+ const Database = require('better-sqlite3');
488
+ const db = new Database(dbPath, { readonly: true });
489
+ try {
490
+ for (const key of keys) {
491
+ const row = db.prepare('SELECT value FROM ItemTable WHERE key = ?').get(key);
492
+ if (!row) continue;
493
+ const parsed = JSON.parse(row.value);
494
+ if (parsed.apiKey) return parsed.apiKey;
495
+ }
496
+ } finally {
497
+ db.close();
498
+ }
466
499
  }
467
- if (!fs.existsSync(dbPath)) return null;
468
- const Database = require('better-sqlite3');
469
- const db = new Database(dbPath, { readonly: true });
470
- const row = db.prepare("SELECT value FROM ItemTable WHERE key = 'windsurfAuthStatus'").get();
471
- db.close();
472
- if (!row) return null;
473
- const parsed = JSON.parse(row.value);
474
- return parsed.apiKey || null;
500
+ return null;
475
501
  } catch { return null; }
476
502
  }
477
503
 
@@ -485,7 +511,7 @@ function getUsage() {
485
511
  const ls = getLsForVariant(variant);
486
512
  if (!ls) continue;
487
513
 
488
- const apiKey = getWindsurfApiKey(variant.appName);
514
+ const apiKey = getDevinApiKey(variant.appNames);
489
515
  if (!apiKey) continue;
490
516
  const body = {
491
517
  metadata: {
@@ -579,13 +605,13 @@ function getUsage() {
579
605
 
580
606
  function resetCache() { _lsCache = null; }
581
607
 
582
- const labels = { 'windsurf': 'Windsurf', 'windsurf-next': 'Windsurf Next' };
608
+ const labels = { 'devin': 'Devin', 'devin-next': 'Devin Next' };
583
609
 
584
610
  function getArtifacts(folder) {
585
611
  const { scanArtifacts } = require('./base');
586
612
  return scanArtifacts(folder, {
587
- editor: 'windsurf',
588
- label: 'Windsurf',
613
+ editor: 'devin',
614
+ label: 'Devin',
589
615
  files: ['.windsurfrules'],
590
616
  dirs: ['.windsurf/workflows', '.windsurf/rules', '.windsurf/plans', '.windsurf/skills'],
591
617
  });
@@ -595,8 +621,9 @@ function getMCPServers() {
595
621
  const { parseMcpConfigFile } = require('./base');
596
622
  const results = [];
597
623
  const configs = [
598
- { file: path.join(os.homedir(), '.codeium', 'windsurf', 'mcp_config.json'), editor: 'windsurf', label: 'Windsurf' },
599
- { file: path.join(os.homedir(), '.codeium', 'windsurf-next', 'mcp_config.json'), editor: 'windsurf-next', label: 'Windsurf Next' },
624
+ { file: path.join(os.homedir(), '.windsurf', 'mcp_config.json'), editor: 'devin', label: 'Devin' },
625
+ { file: path.join(os.homedir(), '.codeium', 'windsurf', 'mcp_config.json'), editor: 'devin', label: 'Devin' },
626
+ { file: path.join(os.homedir(), '.codeium', 'windsurf-next', 'mcp_config.json'), editor: 'devin-next', label: 'Devin Next' },
600
627
  ];
601
628
  for (const c of configs) {
602
629
  results.push(...parseMcpConfigFile(c.file, { editor: c.editor, label: c.label, scope: 'global' }));
@@ -604,4 +631,4 @@ function getMCPServers() {
604
631
  return results;
605
632
  }
606
633
 
607
- module.exports = { name, sources, labels, getChats, getMessages, resetCache, getUsage, getArtifacts, getMCPServers };
634
+ module.exports = { name, sources, legacySources, labels, getChats, getMessages, resetCache, getUsage, getArtifacts, getMCPServers };
package/index.js CHANGED
@@ -247,11 +247,21 @@ if (noCache) {
247
247
  }
248
248
  }
249
249
 
250
- // ── Warn about installed-but-not-running Windsurf variants (macOS only) ─
250
+ // ── Warn about installed-but-not-running Devin variants (macOS only) ─
251
251
  if (process.platform === 'darwin') {
252
- const WINDSURF_VARIANTS = [
253
- { name: 'Windsurf', app: '/Applications/Windsurf.app', dataDir: path.join(HOME, '.codeium', 'windsurf'), ide: 'windsurf' },
254
- { name: 'Windsurf Next', app: '/Applications/Windsurf Next.app', dataDir: path.join(HOME, '.codeium', 'windsurf-next'), ide: 'windsurf-next' },
252
+ const DEVIN_DESKTOP_VARIANTS = [
253
+ {
254
+ name: 'Devin',
255
+ apps: ['/Applications/Devin Desktop.app', '/Applications/Devin.app', '/Applications/Windsurf.app'],
256
+ dataDirs: [path.join(HOME, '.windsurf'), path.join(HOME, '.codeium', 'windsurf')],
257
+ ides: ['devin-desktop', 'devin', 'windsurf'],
258
+ },
259
+ {
260
+ name: 'Devin Next',
261
+ apps: ['/Applications/Devin Desktop Next.app', '/Applications/Devin Next.app', '/Applications/Windsurf Next.app'],
262
+ dataDirs: [path.join(HOME, '.codeium', 'windsurf-next')],
263
+ ides: ['devin-desktop-next', 'devin-next', 'windsurf-next'],
264
+ },
255
265
  { name: 'Antigravity', app: '/Applications/Antigravity.app', dataDir: path.join(HOME, '.codeium', 'antigravity'), ide: 'antigravity' },
256
266
  ];
257
267
 
@@ -269,9 +279,12 @@ const WINDSURF_VARIANTS = [
269
279
  }
270
280
  } catch {}
271
281
 
272
- const installedNotRunning = WINDSURF_VARIANTS.filter(v => {
273
- const installed = fs.existsSync(v.app) || fs.existsSync(v.dataDir);
274
- const running = runningIdes.some(r => r === v.ide || r.includes(v.ide));
282
+ const installedNotRunning = DEVIN_DESKTOP_VARIANTS.filter(v => {
283
+ const apps = v.apps || [v.app];
284
+ const dataDirs = v.dataDirs || [v.dataDir];
285
+ const ides = v.ides || [v.ide];
286
+ const installed = apps.some(app => fs.existsSync(app)) || dataDirs.some(dataDir => fs.existsSync(dataDir));
287
+ const running = runningIdes.some(r => ides.some(ide => r === ide || r.includes(ide)));
275
288
  return installed && !running;
276
289
  });
277
290
 
@@ -304,11 +317,18 @@ allChats.sort((a, b) => (b.lastUpdatedAt || b.createdAt || 0) - (a.lastUpdatedAt
304
317
  const bySource = {};
305
318
  for (const chat of allChats) bySource[chat.source] = (bySource[chat.source] || 0) + 1;
306
319
 
307
- const displayList = Object.entries(editorLabels)
308
- .map(([src, label]) => [src, label, bySource[src] || 0])
309
- .sort((a, b) => b[2] - a[2]);
320
+ const displayByLabel = new Map();
321
+ for (const [src, label] of Object.entries(editorLabels)) {
322
+ const existing = displayByLabel.get(label) || { label, count: 0 };
323
+ existing.count += bySource[src] || 0;
324
+ displayByLabel.set(label, existing);
325
+ }
326
+
327
+ const displayList = Array.from(displayByLabel.values())
328
+ .map(({ label, count }) => [label, count])
329
+ .sort((a, b) => b[1] - a[1]);
310
330
 
311
- for (const [src, label, count] of displayList) {
331
+ for (const [label, count] of displayList) {
312
332
  if (count > 0) {
313
333
  console.log(` ${chalk.green('✓')} ${chalk.bold(label.padEnd(18))} ${chalk.dim(`${count} session${count === 1 ? '' : 's'}`)}`);
314
334
  } else {
@@ -344,7 +364,7 @@ const BOT_STYLES = [
344
364
  console.log(chalk.dim(' • Copilot – ~/.config/github-copilot/apps.json'));
345
365
  console.log(chalk.dim(' • VS Code – ~/.config/github-copilot/apps.json'));
346
366
  console.log(chalk.dim(' • Codex – local auth.json (JWT decode only)'));
347
- console.log(chalk.dim(' • Windsurf – local SQLite (state.vscdb)'));
367
+ console.log(chalk.dim(' • Devin – local SQLite (state.vscdb)'));
348
368
  console.log('');
349
369
  console.log(chalk.dim(' These tokens are used to query each editor\'s own API for'));
350
370
  console.log(chalk.dim(' your plan name and usage limits.'));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "agentlytics",
3
- "version": "0.2.12",
4
- "description": "Comprehensive analytics dashboard for AI coding agents — Cursor, Windsurf, Claude Code, VS Code Copilot, Zed, Antigravity, OpenCode, Command Code",
3
+ "version": "0.2.13",
4
+ "description": "Comprehensive analytics dashboard for AI coding agents — Cursor, Devin, Claude Code, VS Code Copilot, Zed, Antigravity, OpenCode, Command Code",
5
5
  "main": "index.js",
6
6
  "bin": {
7
7
  "agentlytics": "./index.js"
@@ -23,9 +23,8 @@
23
23
  "ui/package-lock.json",
24
24
  "ui/vite.config.js",
25
25
  "ui/eslint.config.js",
26
- "README.md",
27
- "mod.ts",
28
- "deno.json"
26
+ "public/",
27
+ "README.md"
29
28
  ],
30
29
  "scripts": {
31
30
  "start": "node index.js",
@@ -34,7 +33,8 @@
34
33
  },
35
34
  "keywords": [
36
35
  "cursor",
37
- "windsurf",
36
+ "devin",
37
+ "devin-desktop",
38
38
  "claude",
39
39
  "vscode",
40
40
  "copilot",
@@ -0,0 +1,2 @@
1
+ /*! tailwindcss v4.2.1 | MIT License | https://tailwindcss.com */
2
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-orange-400:oklch(75% .183 55.934);--color-amber-400:oklch(82.8% .189 84.429);--color-yellow-400:oklch(85.2% .199 91.936);--color-yellow-500:oklch(79.5% .184 86.047);--spacing:.25rem;--container-xs:20rem;--container-sm:24rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--font-weight-black:900;--tracking-tight:-.025em;--tracking-wider:.05em;--leading-relaxed:1.625;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--animate-spin:spin 1s linear infinite;--blur-xl:24px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-accent:#6366f1}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.collapse{visibility:collapse}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing) * 0)}.start{inset-inline-start:var(--spacing)}.end{inset-inline-end:var(--spacing)}.top-0{top:calc(var(--spacing) * 0)}.top-1\/2{top:50%}.top-6{top:calc(var(--spacing) * 6)}.top-\[42px\]{top:42px}.top-full{top:100%}.right-0{right:calc(var(--spacing) * 0)}.bottom-0{bottom:calc(var(--spacing) * 0)}.left-0{left:calc(var(--spacing) * 0)}.left-2{left:calc(var(--spacing) * 2)}.left-2\.5{left:calc(var(--spacing) * 2.5)}.z-40{z-index:40}.z-50{z-index:50}.z-\[60\]{z-index:60}.z-\[70\]{z-index:70}.z-\[100\]{z-index:100}.mx-4{margin-inline:calc(var(--spacing) * 4)}.mx-auto{margin-inline:auto}.my-1{margin-block:calc(var(--spacing) * 1)}.-mt-1\.5{margin-top:calc(var(--spacing) * -1.5)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-8{margin-top:calc(var(--spacing) * 8)}.mt-px{margin-top:1px}.mr-0\.5{margin-right:calc(var(--spacing) * .5)}.mr-1{margin-right:calc(var(--spacing) * 1)}.mr-1\.5{margin-right:calc(var(--spacing) * 1.5)}.mb-0\.5{margin-bottom:calc(var(--spacing) * .5)}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-5{margin-bottom:calc(var(--spacing) * 5)}.ml-0\.5{margin-left:calc(var(--spacing) * .5)}.ml-1{margin-left:calc(var(--spacing) * 1)}.ml-1\.5{margin-left:calc(var(--spacing) * 1.5)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-auto{margin-left:auto}.line-clamp-1{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.h-1{height:calc(var(--spacing) * 1)}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-2{height:calc(var(--spacing) * 2)}.h-3{height:calc(var(--spacing) * 3)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-11{height:calc(var(--spacing) * 11)}.h-\[9px\]{height:9px}.h-full{height:100%}.max-h-\[160px\]{max-height:160px}.max-h-\[180px\]{max-height:180px}.max-h-\[300px\]{max-height:300px}.max-h-\[400px\]{max-height:400px}.max-h-\[500px\]{max-height:500px}.min-h-screen{min-height:100vh}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-2{width:calc(var(--spacing) * 2)}.w-3{width:calc(var(--spacing) * 3)}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-7{width:calc(var(--spacing) * 7)}.w-8{width:calc(var(--spacing) * 8)}.w-9{width:calc(var(--spacing) * 9)}.w-10{width:calc(var(--spacing) * 10)}.w-11{width:calc(var(--spacing) * 11)}.w-12{width:calc(var(--spacing) * 12)}.w-16{width:calc(var(--spacing) * 16)}.w-20{width:calc(var(--spacing) * 20)}.w-28{width:calc(var(--spacing) * 28)}.w-32{width:calc(var(--spacing) * 32)}.w-64{width:calc(var(--spacing) * 64)}.w-\[9px\]{width:9px}.w-\[24px\]{width:24px}.w-\[80px\]{width:80px}.w-\[180px\]{width:180px}.w-\[200px\]{width:200px}.w-\[250px\]{width:250px}.w-\[300px\]{width:300px}.w-\[340px\]{width:340px}.w-\[420px\]{width:420px}.w-\[440px\]{width:440px}.w-full{width:100%}.max-w-\[90vw\]{max-width:90vw}.max-w-\[120px\]{max-width:120px}.max-w-\[140px\]{max-width:140px}.max-w-\[150px\]{max-width:150px}.max-w-\[160px\]{max-width:160px}.max-w-\[200px\]{max-width:200px}.max-w-\[220px\]{max-width:220px}.max-w-\[280px\]{max-width:280px}.max-w-\[300px\]{max-width:300px}.max-w-\[1400px\]{max-width:1400px}.max-w-sm{max-width:var(--container-sm)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:calc(var(--spacing) * 0)}.min-w-\[160px\]{min-width:160px}.min-w-\[180px\]{min-width:180px}.flex-1{flex:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-spin{animation:var(--animate-spin)}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.resize-y{resize:vertical}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-\[1fr_100px_100px\]{grid-template-columns:1fr 100px 100px}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}:where(.space-y-0\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * .5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * .5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1.5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}.gap-x-3{column-gap:calc(var(--spacing) * 3)}.gap-x-4{column-gap:calc(var(--spacing) * 4)}.gap-y-0\.5{row-gap:calc(var(--spacing) * .5)}.gap-y-1{row-gap:calc(var(--spacing) * 1)}.self-start{align-self:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-r{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.bg-\[var\(--c-bg3\)\]{background-color:var(--c-bg3)}.bg-\[var\(--c-card\)\]{background-color:var(--c-card)}.bg-accent\/30{background-color:#6366f14d}@supports (color:color-mix(in lab, red, red)){.bg-accent\/30{background-color:color-mix(in oklab, var(--color-accent) 30%, transparent)}}.bg-transparent{background-color:#0000}.p-0{padding:calc(var(--spacing) * 0)}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-1{padding:calc(var(--spacing) * 1)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-2{padding:calc(var(--spacing) * 2)}.p-2\.5{padding:calc(var(--spacing) * 2.5)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.p-8{padding:calc(var(--spacing) * 8)}.px-0{padding-inline:calc(var(--spacing) * 0)}.px-0\.5{padding-inline:calc(var(--spacing) * .5)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.py-0{padding-block:calc(var(--spacing) * 0)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-8{padding-block:calc(var(--spacing) * 8)}.py-12{padding-block:calc(var(--spacing) * 12)}.py-16{padding-block:calc(var(--spacing) * 16)}.py-20{padding-block:calc(var(--spacing) * 20)}.py-px{padding-block:1px}.pt-0{padding-top:calc(var(--spacing) * 0)}.pt-1{padding-top:calc(var(--spacing) * 1)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pr-3{padding-right:calc(var(--spacing) * 3)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pl-1{padding-left:calc(var(--spacing) * 1)}.pl-3{padding-left:calc(var(--spacing) * 3)}.pl-6{padding-left:calc(var(--spacing) * 6)}.pl-7{padding-left:calc(var(--spacing) * 7)}.pl-12{padding-left:calc(var(--spacing) * 12)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[7px\]{font-size:7px}.text-\[8px\]{font-size:8px}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-\[13px\]{font-size:13px}.text-\[14px\]{font-size:14px}.text-\[18px\]{font-size:18px}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-black{--tw-font-weight:var(--font-weight-black);font-weight:var(--font-weight-black)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-\[var\(--c-text2\)\]{color:var(--c-text2)}.text-\[var\(--c-white\)\]{color:var(--c-white)}.text-amber-400{color:var(--color-amber-400)}.text-orange-400{color:var(--color-orange-400)}.text-yellow-400{color:var(--color-yellow-400)}.text-yellow-500\/60{color:#edb20099}@supports (color:color-mix(in lab, red, red)){.text-yellow-500\/60{color:color-mix(in oklab, var(--color-yellow-500) 60%, transparent)}}.capitalize{text-transform:capitalize}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.line-through{text-decoration-line:line-through}.underline{text-decoration-line:underline}.accent-\[var\(--c-accent\)\]{accent-color:var(--c-accent)}.opacity-30{opacity:.3}.opacity-40{opacity:.4}.opacity-60{opacity:.6}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.backdrop-blur-xl{--tw-backdrop-blur:blur(var(--blur-xl));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-500{--tw-duration:.5s;transition-duration:.5s}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}@media (hover:hover){.hover\:bg-\[var\(--c-bg\)\]:hover{background-color:var(--c-bg)}.hover\:bg-\[var\(--c-bg2\)\]:hover{background-color:var(--c-bg2)}.hover\:bg-\[var\(--c-bg3\)\]:hover{background-color:var(--c-bg3)}.hover\:bg-\[var\(--c-card\)\]:hover{background-color:var(--c-card)}.hover\:text-\[var\(--c-text\)\]:hover{color:var(--c-text)}.hover\:text-\[var\(--c-white\)\]:hover{color:var(--c-white)}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-70:hover{opacity:.7}.hover\:opacity-80:hover{opacity:.8}.hover\:opacity-90:hover{opacity:.9}}@media (width>=48rem){.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (width>=64rem){.lg\:col-span-2{grid-column:span 2/span 2}.lg\:flex{display:flex}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}@media (width>=80rem){.xl\:flex{display:flex}.xl\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.xl\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}.\[\&\>svg\]\:block>svg{display:block}.\[\&\>svg\]\:h-auto>svg{height:auto}.\[\&\>svg\]\:w-full>svg{width:100%}}:root{--c-bg:#0e0e0e;--c-bg2:#161616;--c-bg3:#1e1e1e;--c-bg4:#272727;--c-text:#a0a0a0;--c-text2:#666;--c-text3:#444;--c-white:#e0e0e0;--c-border:#ffffff0f;--c-card:#ffffff06;--c-card-hover:#6366f140;--c-header:#0e0e0ed9;--c-code-bg:#ffffff0d;--c-pre-bg:#0006;--c-md-strong:#d0d0d0}.light{--c-bg:#f5f5f5;--c-bg2:#ebebeb;--c-bg3:#e0e0e0;--c-bg4:#d6d6d6;--c-text:#444;--c-text2:#888;--c-text3:#bbb;--c-white:#111;--c-border:#00000014;--c-card:#00000006;--c-card-hover:#6366f133;--c-header:#f5f5f5e6;--c-code-bg:#0000000d;--c-pre-bg:#0000000a;--c-md-strong:#111}body{background:var(--c-bg);color:var(--c-text);min-height:100vh;margin:0;font-family:JetBrains Mono,SF Mono,Fira Code,monospace;font-size:13px;line-height:1.5}.card{background:var(--c-card);border:1px solid var(--c-border);border-radius:0;transition:border-color .15s}*{border-radius:0!important}.card:hover{border-color:var(--c-card-hover)}.scrollbar-thin{scrollbar-width:thin;scrollbar-color:transparent transparent}.scrollbar-thin:hover{scrollbar-color:var(--c-border) transparent}.scrollbar-thin::-webkit-scrollbar{width:3px}.scrollbar-thin::-webkit-scrollbar-track{background:0 0}.scrollbar-thin::-webkit-scrollbar-thumb{background:0 0}.scrollbar-thin:hover::-webkit-scrollbar-thumb{background:var(--c-border)}.fade-in{animation:.2s ease-out fadeIn}@keyframes fadeIn{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.sidebar-slide-in{animation:.2s ease-out slideInRight}@keyframes slideInRight{0%{transform:translate(100%)}to{transform:translate(0)}}.pulse-dot{animation:1.5s ease-in-out infinite pulseDot}@keyframes pulseDot{0%,to{opacity:1;box-shadow:0 0 #22c55e80}50%{opacity:.6;box-shadow:0 0 0 4px #22c55e00}}.md-body h1,.md-body h2,.md-body h3{color:var(--c-white);margin:8px 0 4px;font-weight:600}.md-body h1{font-size:1.15em}.md-body h2{font-size:1.05em}.md-body h3{font-size:1em}.md-body p{margin:4px 0;line-height:1.6}.md-body ul,.md-body ol{margin:3px 0;padding-left:1.3em}.md-body li{margin:1px 0}.md-body code{background:var(--c-code-bg);border-radius:3px;padding:1px 4px;font-size:.9em}.md-body pre{background:var(--c-pre-bg);border:1px solid var(--c-border);border-radius:6px;margin:6px 0;padding:10px;overflow-x:auto}.md-body pre code{background:0 0;padding:0}.md-body strong{color:var(--c-md-strong)}.md-body a{color:#818cf8;text-decoration:underline}.md-body blockquote{color:var(--c-text2);border-left:2px solid #6366f14d;margin:6px 0;padding-left:10px}.md-body table{border-collapse:collapse;margin:6px 0}.md-body th,.md-body td{border:1px solid var(--c-border);padding:4px 8px;font-size:.9em}.md-body th{background:var(--c-code-bg)}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@keyframes spin{to{transform:rotate(360deg)}}