agentdog 1.2.0 → 1.3.0
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.
- package/README.md +5 -4
- package/dist/ai-gateway/auth.d.ts.map +1 -1
- package/dist/ai-gateway/auth.js +7 -1
- package/dist/ai-gateway/auth.js.map +1 -1
- package/dist/ai-gateway/auth.test.js +11 -4
- package/dist/ai-gateway/auth.test.js.map +1 -1
- package/dist/ai-gateway/call-log.d.ts +18 -0
- package/dist/ai-gateway/call-log.d.ts.map +1 -0
- package/dist/ai-gateway/call-log.js +136 -0
- package/dist/ai-gateway/call-log.js.map +1 -0
- package/dist/ai-gateway/call-log.test.d.ts +2 -0
- package/dist/ai-gateway/call-log.test.d.ts.map +1 -0
- package/dist/ai-gateway/call-log.test.js +136 -0
- package/dist/ai-gateway/call-log.test.js.map +1 -0
- package/dist/ai-gateway/count-tokens.d.ts.map +1 -1
- package/dist/ai-gateway/count-tokens.js +11 -1
- package/dist/ai-gateway/count-tokens.js.map +1 -1
- package/dist/ai-gateway/dialects.d.ts +1 -0
- package/dist/ai-gateway/dialects.d.ts.map +1 -1
- package/dist/ai-gateway/dialects.js +7 -0
- package/dist/ai-gateway/dialects.js.map +1 -1
- package/dist/ai-gateway/gateway-server.d.ts +2 -3
- package/dist/ai-gateway/gateway-server.d.ts.map +1 -1
- package/dist/ai-gateway/gateway-server.js +183 -67
- package/dist/ai-gateway/gateway-server.js.map +1 -1
- package/dist/ai-gateway/integration.test.js +237 -3
- package/dist/ai-gateway/integration.test.js.map +1 -1
- package/dist/ai-gateway/ir/anthropic-out.d.ts +15 -0
- package/dist/ai-gateway/ir/anthropic-out.d.ts.map +1 -0
- package/dist/ai-gateway/ir/anthropic-out.js +173 -0
- package/dist/ai-gateway/ir/anthropic-out.js.map +1 -0
- package/dist/ai-gateway/ir/anthropic-out.test.d.ts +2 -0
- package/dist/ai-gateway/ir/anthropic-out.test.d.ts.map +1 -0
- package/dist/ai-gateway/ir/anthropic-out.test.js +173 -0
- package/dist/ai-gateway/ir/anthropic-out.test.js.map +1 -0
- package/dist/ai-gateway/ir/openai-in.d.ts +3 -0
- package/dist/ai-gateway/ir/openai-in.d.ts.map +1 -0
- package/dist/ai-gateway/ir/openai-in.js +133 -0
- package/dist/ai-gateway/ir/openai-in.js.map +1 -0
- package/dist/ai-gateway/ir/openai-in.test.d.ts +2 -0
- package/dist/ai-gateway/ir/openai-in.test.d.ts.map +1 -0
- package/dist/ai-gateway/ir/openai-in.test.js +108 -0
- package/dist/ai-gateway/ir/openai-in.test.js.map +1 -0
- package/dist/ai-gateway/ir/openai-sse.d.ts +22 -0
- package/dist/ai-gateway/ir/openai-sse.d.ts.map +1 -0
- package/dist/ai-gateway/ir/openai-sse.js +166 -0
- package/dist/ai-gateway/ir/openai-sse.js.map +1 -0
- package/dist/ai-gateway/ir/openai-sse.test.d.ts +2 -0
- package/dist/ai-gateway/ir/openai-sse.test.d.ts.map +1 -0
- package/dist/ai-gateway/ir/openai-sse.test.js +119 -0
- package/dist/ai-gateway/ir/openai-sse.test.js.map +1 -0
- package/dist/ai-gateway/ir-channel.d.ts +14 -1
- package/dist/ai-gateway/ir-channel.d.ts.map +1 -1
- package/dist/ai-gateway/ir-channel.js +52 -11
- package/dist/ai-gateway/ir-channel.js.map +1 -1
- package/dist/ai-gateway/model-router.d.ts.map +1 -1
- package/dist/ai-gateway/model-router.js +3 -0
- package/dist/ai-gateway/model-router.js.map +1 -1
- package/dist/ai-gateway/model-router.test.js +10 -0
- package/dist/ai-gateway/model-router.test.js.map +1 -1
- package/dist/ai-gateway/models-list.d.ts +9 -0
- package/dist/ai-gateway/models-list.d.ts.map +1 -0
- package/dist/ai-gateway/models-list.js +42 -0
- package/dist/ai-gateway/models-list.js.map +1 -0
- package/dist/ai-gateway/models-list.test.d.ts +2 -0
- package/dist/ai-gateway/models-list.test.d.ts.map +1 -0
- package/dist/ai-gateway/models-list.test.js +47 -0
- package/dist/ai-gateway/models-list.test.js.map +1 -0
- package/dist/ai-gateway/openai-errors.d.ts +7 -0
- package/dist/ai-gateway/openai-errors.d.ts.map +1 -0
- package/dist/ai-gateway/openai-errors.js +23 -0
- package/dist/ai-gateway/openai-errors.js.map +1 -0
- package/dist/ai-gateway/openai-errors.test.d.ts +2 -0
- package/dist/ai-gateway/openai-errors.test.d.ts.map +1 -0
- package/dist/ai-gateway/openai-errors.test.js +38 -0
- package/dist/ai-gateway/openai-errors.test.js.map +1 -0
- package/dist/ai-gateway/passthrough.d.ts +1 -0
- package/dist/ai-gateway/passthrough.d.ts.map +1 -1
- package/dist/ai-gateway/passthrough.js +104 -0
- package/dist/ai-gateway/passthrough.js.map +1 -1
- package/dist/ai-gateway/passthrough.test.js +66 -1
- package/dist/ai-gateway/passthrough.test.js.map +1 -1
- package/dist/daemon/agentdog-daemon.d.ts +1 -1
- package/dist/daemon/agentdog-daemon.d.ts.map +1 -1
- package/dist/daemon/agentdog-daemon.js +27 -1
- package/dist/daemon/agentdog-daemon.js.map +1 -1
- package/dist/daemon/daemon-web-server.ai.test.js +30 -3
- package/dist/daemon/daemon-web-server.ai.test.js.map +1 -1
- package/dist/daemon/daemon-web-server.d.ts +2 -0
- package/dist/daemon/daemon-web-server.d.ts.map +1 -1
- package/dist/daemon/daemon-web-server.js +83 -11
- package/dist/daemon/daemon-web-server.js.map +1 -1
- package/dist/logging/jsonl-store.d.ts +23 -0
- package/dist/logging/jsonl-store.d.ts.map +1 -0
- package/dist/logging/jsonl-store.js +107 -0
- package/dist/logging/jsonl-store.js.map +1 -0
- package/dist/logging/jsonl-store.test.d.ts +2 -0
- package/dist/logging/jsonl-store.test.d.ts.map +1 -0
- package/dist/logging/jsonl-store.test.js +89 -0
- package/dist/logging/jsonl-store.test.js.map +1 -0
- package/dist/logging/server-log-manager.d.ts +3 -0
- package/dist/logging/server-log-manager.d.ts.map +1 -1
- package/dist/logging/server-log-manager.js +20 -0
- package/dist/logging/server-log-manager.js.map +1 -1
- package/dist/types/index.d.ts +20 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +3 -2
- package/web/dist/assets/index-CHSrrPtl.css +1 -0
- package/web/dist/assets/index-gdp_c7vR.js +106 -0
- package/web/dist/assets/index-gdp_c7vR.js.map +1 -0
- package/web/dist/index.html +2 -2
- package/web/dist/assets/index-BdEVyQ8g.js +0 -118
- package/web/dist/assets/index-BdEVyQ8g.js.map +0 -1
- package/web/dist/assets/index-Bsl7BWhF.css +0 -1
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
export interface JsonlStoreOptions {
|
|
3
|
+
filePath: string;
|
|
4
|
+
maxEntries: number;
|
|
5
|
+
rotateBytes?: number;
|
|
6
|
+
}
|
|
7
|
+
export declare function resolveLogDir(): string;
|
|
8
|
+
export declare class JsonlStore extends EventEmitter {
|
|
9
|
+
private readonly opts;
|
|
10
|
+
private entries;
|
|
11
|
+
private bytesSinceRotate;
|
|
12
|
+
private initialized;
|
|
13
|
+
private initPromise?;
|
|
14
|
+
private writeQueue;
|
|
15
|
+
constructor(options: JsonlStoreOptions);
|
|
16
|
+
private ensureInit;
|
|
17
|
+
private init;
|
|
18
|
+
append(line: unknown): void;
|
|
19
|
+
private write;
|
|
20
|
+
ready(): Promise<unknown[]>;
|
|
21
|
+
recent(limit?: number): unknown[];
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=jsonl-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonl-store.d.ts","sourceRoot":"","sources":["../../src/logging/jsonl-store.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAKtC,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAID,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,qBAAa,UAAW,SAAQ,YAAY;IAC1C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA8B;IACnD,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,WAAW,CAAC,CAAgB;IAEpC,OAAO,CAAC,UAAU,CAAoC;gBAE1C,OAAO,EAAE,iBAAiB;IAMtC,OAAO,CAAC,UAAU;YAYJ,IAAI;IA6BlB,MAAM,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;YAYb,KAAK;IAkBb,KAAK,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAMjC,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,EAAE;CAMlC"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// 共享 JSONL 追加存储:内存环形缓冲 + 文件追加 + 超限轮转 + 启动读尾部。
|
|
2
|
+
// MCP 日志(mcp.jsonl)与 AI 调用流水(ai-calls.jsonl)两处同构持久化的通用件。
|
|
3
|
+
// 日志目录可被 AGENTDOG_LOG_DIR 覆盖(测试隔离用)。
|
|
4
|
+
import { EventEmitter } from 'events';
|
|
5
|
+
import { appendFile, mkdir, readFile, rename, rm, stat } from 'fs/promises';
|
|
6
|
+
import { dirname, join } from 'path';
|
|
7
|
+
import { homedir } from 'os';
|
|
8
|
+
const DEFAULT_ROTATE_BYTES = 5 * 1024 * 1024;
|
|
9
|
+
export function resolveLogDir() {
|
|
10
|
+
return process.env.AGENTDOG_LOG_DIR || join(homedir(), '.agentdog', 'logs');
|
|
11
|
+
}
|
|
12
|
+
export class JsonlStore extends EventEmitter {
|
|
13
|
+
opts;
|
|
14
|
+
entries = [];
|
|
15
|
+
bytesSinceRotate = 0;
|
|
16
|
+
initialized = false;
|
|
17
|
+
initPromise;
|
|
18
|
+
// 写盘串行队列:appendFile 并发执行完成顺序不定,会导致 JSONL 行乱序
|
|
19
|
+
writeQueue = Promise.resolve();
|
|
20
|
+
constructor(options) {
|
|
21
|
+
super();
|
|
22
|
+
this.opts = { rotateBytes: DEFAULT_ROTATE_BYTES, ...options };
|
|
23
|
+
}
|
|
24
|
+
// 构造后惰性初始化(首次 append/recent 时触发),避免模块加载即做文件 IO
|
|
25
|
+
ensureInit() {
|
|
26
|
+
if (this.initialized) {
|
|
27
|
+
return Promise.resolve();
|
|
28
|
+
}
|
|
29
|
+
if (!this.initPromise) {
|
|
30
|
+
this.initPromise = this.init().then(() => {
|
|
31
|
+
this.initialized = true;
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return this.initPromise;
|
|
35
|
+
}
|
|
36
|
+
async init() {
|
|
37
|
+
try {
|
|
38
|
+
await mkdir(dirname(this.opts.filePath), { recursive: true });
|
|
39
|
+
const [buffer, stats] = await Promise.all([
|
|
40
|
+
readFile(this.opts.filePath).catch(() => null),
|
|
41
|
+
stat(this.opts.filePath).catch(() => null),
|
|
42
|
+
]);
|
|
43
|
+
if (stats) {
|
|
44
|
+
this.bytesSinceRotate = stats.size;
|
|
45
|
+
}
|
|
46
|
+
if (buffer) {
|
|
47
|
+
const tail = [];
|
|
48
|
+
for (const line of buffer.toString('utf8').split('\n')) {
|
|
49
|
+
if (!line.trim())
|
|
50
|
+
continue;
|
|
51
|
+
try {
|
|
52
|
+
tail.push(JSON.parse(line));
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
// 半行/损坏行跳过(如进程写入中途被杀)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// init 期间可能已有新行 append 进来(内存先行、落盘在 init 后),合并保留
|
|
59
|
+
this.entries = [...tail, ...this.entries].slice(-this.opts.maxEntries);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
// 读历史失败不阻断服务:缓冲从空开始,新日志照常追加
|
|
64
|
+
console.error(`[JSONL-STORE] Failed to load ${this.opts.filePath}:`, error.message);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
append(line) {
|
|
68
|
+
this.entries.push(line);
|
|
69
|
+
if (this.entries.length > this.opts.maxEntries) {
|
|
70
|
+
this.entries.splice(0, this.entries.length - this.opts.maxEntries);
|
|
71
|
+
}
|
|
72
|
+
this.emit('append', line);
|
|
73
|
+
const text = JSON.stringify(line) + '\n';
|
|
74
|
+
this.bytesSinceRotate += Buffer.byteLength(text, 'utf8');
|
|
75
|
+
this.writeQueue = this.writeQueue.then(() => this.write(text));
|
|
76
|
+
}
|
|
77
|
+
async write(text) {
|
|
78
|
+
try {
|
|
79
|
+
await this.ensureInit();
|
|
80
|
+
if (this.bytesSinceRotate >= this.opts.rotateBytes) {
|
|
81
|
+
// 轮转:先删旧 .1 再改名(Windows rename 不覆盖已存在文件)
|
|
82
|
+
const rotated = this.opts.filePath + '.1';
|
|
83
|
+
await rm(rotated, { force: true });
|
|
84
|
+
await rename(this.opts.filePath, rotated);
|
|
85
|
+
this.bytesSinceRotate = Buffer.byteLength(text, 'utf8');
|
|
86
|
+
}
|
|
87
|
+
await appendFile(this.opts.filePath, text, 'utf8');
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
// 落盘失败不抛出:日志持久化失败不能拖垮转发请求,仅上报
|
|
91
|
+
console.error(`[JSONL-STORE] Failed to append ${this.opts.filePath}:`, error.message);
|
|
92
|
+
this.emit('write-error', error);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
async ready() {
|
|
96
|
+
await this.ensureInit();
|
|
97
|
+
await this.writeQueue; // 等待积压写盘完成,调用方可确定性读取
|
|
98
|
+
return this.entries;
|
|
99
|
+
}
|
|
100
|
+
recent(limit) {
|
|
101
|
+
if (limit && limit > 0) {
|
|
102
|
+
return this.entries.slice(-limit);
|
|
103
|
+
}
|
|
104
|
+
return [...this.entries];
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=jsonl-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonl-store.js","sourceRoot":"","sources":["../../src/logging/jsonl-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonl-store.test.d.ts","sourceRoot":"","sources":["../../src/logging/jsonl-store.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { mkdtemp, rm, readFile, writeFile, access } from 'fs/promises';
|
|
3
|
+
import { tmpdir } from 'os';
|
|
4
|
+
import { join } from 'path';
|
|
5
|
+
import { JsonlStore } from './jsonl-store.js';
|
|
6
|
+
// 测试隔离:每个用例独立临时目录,不触碰 ~/.agentdog/logs
|
|
7
|
+
let dir;
|
|
8
|
+
beforeEach(async () => {
|
|
9
|
+
dir = await mkdtemp(join(tmpdir(), 'agentdog-jsonl-'));
|
|
10
|
+
});
|
|
11
|
+
afterEach(async () => {
|
|
12
|
+
await rm(dir, { recursive: true, force: true });
|
|
13
|
+
});
|
|
14
|
+
describe('JsonlStore', () => {
|
|
15
|
+
it('append 写入内存缓冲并落盘为 JSON 行', async () => {
|
|
16
|
+
const store = new JsonlStore({ filePath: join(dir, 'a.jsonl'), maxEntries: 10 });
|
|
17
|
+
store.append({ id: 1, msg: 'hello' });
|
|
18
|
+
await store.ready();
|
|
19
|
+
expect(store.recent()).toEqual([{ id: 1, msg: 'hello' }]);
|
|
20
|
+
const text = await readFile(join(dir, 'a.jsonl'), 'utf8');
|
|
21
|
+
expect(text).toBe('{"id":1,"msg":"hello"}\n');
|
|
22
|
+
});
|
|
23
|
+
it('append 触发 append 事件(daemon-web-server 据此 socket 推送)', async () => {
|
|
24
|
+
const store = new JsonlStore({ filePath: join(dir, 'a.jsonl'), maxEntries: 10 });
|
|
25
|
+
const seen = [];
|
|
26
|
+
store.on('append', (line) => seen.push(line));
|
|
27
|
+
store.append({ n: 1 });
|
|
28
|
+
store.append({ n: 2 });
|
|
29
|
+
await store.ready(); // ready 等待写盘队列排空
|
|
30
|
+
expect(seen).toEqual([{ n: 1 }, { n: 2 }]);
|
|
31
|
+
});
|
|
32
|
+
it('超过 maxEntries 时内存环形截断,保留最新', async () => {
|
|
33
|
+
const store = new JsonlStore({ filePath: join(dir, 'a.jsonl'), maxEntries: 3 });
|
|
34
|
+
for (let i = 1; i <= 5; i++) {
|
|
35
|
+
store.append({ n: i });
|
|
36
|
+
}
|
|
37
|
+
await store.ready();
|
|
38
|
+
expect(store.recent().map((l) => l.n)).toEqual([3, 4, 5]);
|
|
39
|
+
});
|
|
40
|
+
it('并发 append 落盘行序保持(写盘串行队列)', async () => {
|
|
41
|
+
const store = new JsonlStore({ filePath: join(dir, 'a.jsonl'), maxEntries: 100 });
|
|
42
|
+
for (let i = 1; i <= 20; i++) {
|
|
43
|
+
store.append({ n: i });
|
|
44
|
+
}
|
|
45
|
+
await store.ready();
|
|
46
|
+
const text = await readFile(join(dir, 'a.jsonl'), 'utf8');
|
|
47
|
+
const ns = text.trim().split('\n').map((l) => JSON.parse(l).n);
|
|
48
|
+
expect(ns).toEqual(Array.from({ length: 20 }, (_, i) => i + 1));
|
|
49
|
+
});
|
|
50
|
+
it('同一文件重新实例化时加载尾部历史(daemon 重启恢复)', async () => {
|
|
51
|
+
const first = new JsonlStore({ filePath: join(dir, 'a.jsonl'), maxEntries: 10 });
|
|
52
|
+
for (let i = 1; i <= 4; i++) {
|
|
53
|
+
first.append({ n: i });
|
|
54
|
+
}
|
|
55
|
+
await first.ready();
|
|
56
|
+
const second = new JsonlStore({ filePath: join(dir, 'a.jsonl'), maxEntries: 3 });
|
|
57
|
+
await second.ready();
|
|
58
|
+
expect(second.recent().map((l) => l.n)).toEqual([2, 3, 4]);
|
|
59
|
+
});
|
|
60
|
+
it('启动前已存在的文件计入轮转字节阈值,超限轮转为 .1', async () => {
|
|
61
|
+
const path = join(dir, 'rot.jsonl');
|
|
62
|
+
await writeFile(path, 'x'.repeat(600), 'utf8'); // 预置 600 字节
|
|
63
|
+
const store = new JsonlStore({ filePath: path, maxEntries: 10, rotateBytes: 1024 });
|
|
64
|
+
await store.ready();
|
|
65
|
+
store.append({ big: 'y'.repeat(500) }); // 600 + 500 ≥ 1024 → 触发轮转
|
|
66
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
67
|
+
await access(path); // 轮转后新文件已重建
|
|
68
|
+
const rotated = await readFile(path + '.1', 'utf8');
|
|
69
|
+
expect(rotated).toBe('x'.repeat(600)); // 旧内容完整进入 .1
|
|
70
|
+
const fresh = await readFile(path, 'utf8');
|
|
71
|
+
expect(fresh).toContain('"big"'); // 新行写入新文件
|
|
72
|
+
});
|
|
73
|
+
it('文件不存在时首次 append 自动创建目录与文件', async () => {
|
|
74
|
+
const path = join(dir, 'nested', 'deep', 'a.jsonl');
|
|
75
|
+
const store = new JsonlStore({ filePath: path, maxEntries: 5 });
|
|
76
|
+
store.append({ ok: true });
|
|
77
|
+
await store.ready();
|
|
78
|
+
const text = await readFile(path, 'utf8');
|
|
79
|
+
expect(text).toBe('{"ok":true}\n');
|
|
80
|
+
});
|
|
81
|
+
it('加载时跳过损坏行(半行 JSON)', async () => {
|
|
82
|
+
const path = join(dir, 'a.jsonl');
|
|
83
|
+
await writeFile(path, '{"n":1}\n{"n":2}\n{"broken": ', 'utf8');
|
|
84
|
+
const store = new JsonlStore({ filePath: path, maxEntries: 10 });
|
|
85
|
+
await store.ready();
|
|
86
|
+
expect(store.recent().map((l) => l.n)).toEqual([1, 2]);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
//# sourceMappingURL=jsonl-store.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonl-store.test.js","sourceRoot":"","sources":["../../src/logging/jsonl-store.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { EventEmitter } from 'events';
|
|
2
|
+
import { JsonlStore } from './jsonl-store.js';
|
|
2
3
|
export interface LogEntry {
|
|
3
4
|
timestamp: string;
|
|
4
5
|
level: 'info' | 'warn' | 'error' | 'debug';
|
|
@@ -15,6 +16,8 @@ export interface ServerLogStats {
|
|
|
15
16
|
connectionAttempts: number;
|
|
16
17
|
lastError?: string;
|
|
17
18
|
}
|
|
19
|
+
export declare function getMcpLogStore(): JsonlStore;
|
|
20
|
+
export declare function resetMcpLogStoreForTests(): void;
|
|
18
21
|
export declare class ServerLogManager extends EventEmitter {
|
|
19
22
|
private logs;
|
|
20
23
|
private maxLogsPerServer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-log-manager.d.ts","sourceRoot":"","sources":["../../src/logging/server-log-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACxC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,gBAAiB,SAAQ,YAAY;IAChD,OAAO,CAAC,IAAI,CAAiC;IAC7C,OAAO,CAAC,gBAAgB,CAAQ;IAChC,OAAO,CAAC,QAAQ,CAAqC;gBAEzC,gBAAgB,SAAO;IAKnC;;OAEG;IACH,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAE,QAAQ,CAAC,QAAQ,CAAY,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"server-log-manager.d.ts","sourceRoot":"","sources":["../../src/logging/server-log-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,EAAE,UAAU,EAAiB,MAAM,kBAAkB,CAAC;AAE7D,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACxC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAMD,wBAAgB,cAAc,IAAI,UAAU,CAQ3C;AAGD,wBAAgB,wBAAwB,IAAI,IAAI,CAE/C;AAED,qBAAa,gBAAiB,SAAQ,YAAY;IAChD,OAAO,CAAC,IAAI,CAAiC;IAC7C,OAAO,CAAC,gBAAgB,CAAQ;IAChC,OAAO,CAAC,QAAQ,CAAqC;gBAEzC,gBAAgB,SAAO;IAKnC;;OAEG;IACH,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAE,QAAQ,CAAC,QAAQ,CAAY,GAAG,IAAI;IAsClH;;OAEG;IACH,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,EAAE;IAQvD;;OAEG;IACH,gBAAgB,CAAC,KAAK,SAAK,GAAG,QAAQ,EAAE;IAaxC;;OAEG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAIxD;;OAEG;IACH,WAAW,IAAI,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC;IAI1C;;OAEG;IACH,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAMnC;;OAEG;IACH,YAAY,IAAI,IAAI;IAMpB;;OAEG;IACH,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IAoBtF;;OAEG;IACH,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,IAAI;IASpF;;OAEG;IACH,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QACtD,KAAK,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC1B,MAAM,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,GAAG,QAAQ,EAAE;IAmBd;;OAEG;IACH,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,GAAG,MAAe,GAAG,MAAM;IAgBxE,OAAO,CAAC,WAAW;IAiBnB,OAAO,CAAC,gBAAgB;CAazB;AAGD,eAAO,MAAM,gBAAgB,kBAAyB,CAAC"}
|
|
@@ -1,4 +1,22 @@
|
|
|
1
1
|
import { EventEmitter } from 'events';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { JsonlStore, resolveLogDir } from './jsonl-store.js';
|
|
4
|
+
// MCP 日志时间线:子服务器输出与连接事件的统一落盘(kind 标记行类型)。
|
|
5
|
+
// 惰性单例同 call-log:首次使用才解析 AGENTDOG_LOG_DIR(测试隔离用)。
|
|
6
|
+
let mcpStore;
|
|
7
|
+
export function getMcpLogStore() {
|
|
8
|
+
if (!mcpStore) {
|
|
9
|
+
mcpStore = new JsonlStore({
|
|
10
|
+
filePath: join(resolveLogDir(), 'mcp.jsonl'),
|
|
11
|
+
maxEntries: 500,
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
return mcpStore;
|
|
15
|
+
}
|
|
16
|
+
// 仅供测试:重置惰性单例
|
|
17
|
+
export function resetMcpLogStoreForTests() {
|
|
18
|
+
mcpStore = undefined;
|
|
19
|
+
}
|
|
2
20
|
export class ServerLogManager extends EventEmitter {
|
|
3
21
|
logs = new Map();
|
|
4
22
|
maxLogsPerServer = 1000;
|
|
@@ -31,6 +49,8 @@ export class ServerLogManager extends EventEmitter {
|
|
|
31
49
|
}
|
|
32
50
|
// Update statistics
|
|
33
51
|
this.updateStats(serverName, logEntry);
|
|
52
|
+
// 统一时间线落盘(MCP 日志页重启后恢复历史的数据源)
|
|
53
|
+
getMcpLogStore().append({ kind: 'server-log', ...logEntry });
|
|
34
54
|
// Emit log event
|
|
35
55
|
this.emit('log-added', { serverName, logEntry });
|
|
36
56
|
// If it's an error, emit error event
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-log-manager.js","sourceRoot":"","sources":["../../src/logging/server-log-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"server-log-manager.js","sourceRoot":"","sources":["../../src/logging/server-log-manager.ts"],"names":[],"mappings":"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"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -58,6 +58,8 @@ export interface AIProviderConfig {
|
|
|
58
58
|
apiKey: string;
|
|
59
59
|
enabled: boolean;
|
|
60
60
|
models?: string[];
|
|
61
|
+
disabledModels?: string[];
|
|
62
|
+
autoFetchModels?: boolean;
|
|
61
63
|
headers?: Record<string, string>;
|
|
62
64
|
}
|
|
63
65
|
export interface AIGatewayConfig {
|
|
@@ -66,6 +68,24 @@ export interface AIGatewayConfig {
|
|
|
66
68
|
host: string;
|
|
67
69
|
apiKey: string;
|
|
68
70
|
}
|
|
71
|
+
export interface AiCallLog {
|
|
72
|
+
id: string;
|
|
73
|
+
timestamp: string;
|
|
74
|
+
ingress: 'anthropic' | 'openai';
|
|
75
|
+
path: string;
|
|
76
|
+
model: string;
|
|
77
|
+
providerName: string;
|
|
78
|
+
upstreamModel: string;
|
|
79
|
+
status: number;
|
|
80
|
+
durationMs: number;
|
|
81
|
+
usage?: {
|
|
82
|
+
inputTokens?: number;
|
|
83
|
+
outputTokens?: number;
|
|
84
|
+
};
|
|
85
|
+
error?: string;
|
|
86
|
+
requestExcerpt?: string;
|
|
87
|
+
responseExcerpt?: string;
|
|
88
|
+
}
|
|
69
89
|
export interface MCPTool {
|
|
70
90
|
name: string;
|
|
71
91
|
description: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentdog",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "AgentDog - MCP 服务器统一管理网关(SIE 运维团队维护版)",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
"build": "tsc && cd web && tsc && vite build",
|
|
9
9
|
"start": "node dist/index.js",
|
|
10
10
|
"dev": "tsx src/index.ts",
|
|
11
|
-
"test": "vitest",
|
|
11
|
+
"test": "vitest run",
|
|
12
|
+
"test:watch": "vitest",
|
|
12
13
|
"test:integration": "vitest run --config vitest.integration.config.ts",
|
|
13
14
|
"web": "node dist/index.js --web-port 38881",
|
|
14
15
|
"prepublishOnly": "npm run build"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}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;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}:where(:root),:root:has(input.theme-controller[value=light]:checked),[data-theme=light]{color-scheme:light;--color-base-100: oklch(100% 0 0);--color-base-200: oklch(98% 0 0);--color-base-300: oklch(95% 0 0);--color-base-content: oklch(21% .006 285.885);--color-primary: oklch(45% .24 277.023);--color-primary-content: oklch(93% .034 272.788);--color-secondary: oklch(65% .241 354.308);--color-secondary-content: oklch(94% .028 342.258);--color-accent: oklch(77% .152 181.912);--color-accent-content: oklch(38% .063 188.416);--color-neutral: oklch(14% .005 285.823);--color-neutral-content: oklch(92% .004 286.32);--color-info: oklch(74% .16 232.661);--color-info-content: oklch(29% .066 243.157);--color-success: oklch(76% .177 163.223);--color-success-content: oklch(37% .077 168.94);--color-warning: oklch(82% .189 84.429);--color-warning-content: oklch(41% .112 45.904);--color-error: oklch(71% .194 13.428);--color-error-content: oklch(27% .105 12.094);--radius-selector: .5rem;--radius-field: .25rem;--radius-box: .5rem;--size-selector: .25rem;--size-field: .25rem;--border: 1px;--depth: 1;--noise: 0}@media (prefers-color-scheme: dark){:root{color-scheme:dark;--color-base-100: oklch(25.33% .016 252.42);--color-base-200: oklch(23.26% .014 253.1);--color-base-300: oklch(21.15% .012 254.09);--color-base-content: oklch(97.807% .029 256.847);--color-primary: oklch(58% .233 277.117);--color-primary-content: oklch(96% .018 272.314);--color-secondary: oklch(65% .241 354.308);--color-secondary-content: oklch(94% .028 342.258);--color-accent: oklch(77% .152 181.912);--color-accent-content: oklch(38% .063 188.416);--color-neutral: oklch(14% .005 285.823);--color-neutral-content: oklch(92% .004 286.32);--color-info: oklch(74% .16 232.661);--color-info-content: oklch(29% .066 243.157);--color-success: oklch(76% .177 163.223);--color-success-content: oklch(37% .077 168.94);--color-warning: oklch(82% .189 84.429);--color-warning-content: oklch(41% .112 45.904);--color-error: oklch(71% .194 13.428);--color-error-content: oklch(27% .105 12.094);--radius-selector: .5rem;--radius-field: .25rem;--radius-box: .5rem;--size-selector: .25rem;--size-field: .25rem;--border: 1px;--depth: 1;--noise: 0}}:root:has(input.theme-controller[value=light]:checked),[data-theme=light]{color-scheme:light;--color-base-100: oklch(100% 0 0);--color-base-200: oklch(98% 0 0);--color-base-300: oklch(95% 0 0);--color-base-content: oklch(21% .006 285.885);--color-primary: oklch(45% .24 277.023);--color-primary-content: oklch(93% .034 272.788);--color-secondary: oklch(65% .241 354.308);--color-secondary-content: oklch(94% .028 342.258);--color-accent: oklch(77% .152 181.912);--color-accent-content: oklch(38% .063 188.416);--color-neutral: oklch(14% .005 285.823);--color-neutral-content: oklch(92% .004 286.32);--color-info: oklch(74% .16 232.661);--color-info-content: oklch(29% .066 243.157);--color-success: oklch(76% .177 163.223);--color-success-content: oklch(37% .077 168.94);--color-warning: oklch(82% .189 84.429);--color-warning-content: oklch(41% .112 45.904);--color-error: oklch(71% .194 13.428);--color-error-content: oklch(27% .105 12.094);--radius-selector: .5rem;--radius-field: .25rem;--radius-box: .5rem;--size-selector: .25rem;--size-field: .25rem;--border: 1px;--depth: 1;--noise: 0}:root:has(input.theme-controller[value=dark]:checked),[data-theme=dark]{color-scheme:dark;--color-base-100: oklch(25.33% .016 252.42);--color-base-200: oklch(23.26% .014 253.1);--color-base-300: oklch(21.15% .012 254.09);--color-base-content: oklch(97.807% .029 256.847);--color-primary: oklch(58% .233 277.117);--color-primary-content: oklch(96% .018 272.314);--color-secondary: oklch(65% .241 354.308);--color-secondary-content: oklch(94% .028 342.258);--color-accent: oklch(77% .152 181.912);--color-accent-content: oklch(38% .063 188.416);--color-neutral: oklch(14% .005 285.823);--color-neutral-content: oklch(92% .004 286.32);--color-info: oklch(74% .16 232.661);--color-info-content: oklch(29% .066 243.157);--color-success: oklch(76% .177 163.223);--color-success-content: oklch(37% .077 168.94);--color-warning: oklch(82% .189 84.429);--color-warning-content: oklch(41% .112 45.904);--color-error: oklch(71% .194 13.428);--color-error-content: oklch(27% .105 12.094);--radius-selector: .5rem;--radius-field: .25rem;--radius-box: .5rem;--size-selector: .25rem;--size-field: .25rem;--border: 1px;--depth: 1;--noise: 0}:root,[data-theme]{background-color:var(--root-bg, var(--color-base-100));color:var(--color-base-content)}:root{--fx-noise: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='a'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.34' numOctaves='4' stitchTiles='stitch'%3E%3C/feTurbulence%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23a)' opacity='0.2'%3E%3C/rect%3E%3C/svg%3E")}@property --radialprogress{syntax: "<percentage>"; inherits: true; initial-value: 0%;}:where(:root:has(.modal-open,.modal[open],.modal:target,.modal-toggle:checked,.drawer:not(.drawer-open)>.drawer-toggle:checked)){scrollbar-gutter:stable;background-image:linear-gradient(var(--color-base-100),var(--color-base-100));--root-bg: color-mix(in srgb, var(--color-base-100), oklch(0% 0 0) 40%)}:where(.modal[open],.modal-open,.modal-toggle:checked+.modal):not(.modal-start,.modal-end){scrollbar-gutter:stable}:root{scrollbar-color:color-mix(in oklch,currentColor 35%,#0000) #0000}:root:has(.modal-open,.modal[open],.modal:target,.modal-toggle:checked,.drawer:not([class*=drawer-open])>.drawer-toggle:checked){overflow:hidden}.textarea{border:var(--border) solid #0000;min-height:5rem;flex-shrink:1;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:var(--radius-field);background-color:var(--color-base-100);padding-block:.5rem;vertical-align:middle;width:clamp(3rem,20rem,100%);padding-inline-start:.75rem;padding-inline-end:.75rem;font-size:.875rem;touch-action:manipulation;border-color:var(--input-color);box-shadow:0 1px color-mix(in oklab,var(--input-color) calc(var(--depth) * 10%),#0000) inset,0 -1px oklch(100% 0 0 / calc(var(--depth) * .1)) inset;--input-color: color-mix(in oklab, var(--color-base-content) 20%, #0000)}.textarea textarea{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent;border:none}.textarea textarea:focus,.textarea textarea:focus-within{--tw-outline-style: none;outline-style:none}@media (forced-colors: active){.textarea textarea:focus,.textarea textarea:focus-within{outline:2px solid transparent;outline-offset:2px}}.textarea:focus,.textarea:focus-within{--input-color: var(--color-base-content);box-shadow:0 1px color-mix(in oklab,var(--input-color) calc(var(--depth) * 10%),#0000);outline:2px solid var(--input-color);outline-offset:2px;isolation:isolate}.textarea:has(>textarea[disabled]),.textarea:is(:disabled,[disabled]){cursor:not-allowed;border-color:var(--color-base-200);background-color:var(--color-base-200);color:color-mix(in oklab,var(--color-base-content) 40%,transparent)}.textarea:has(>textarea[disabled])::-moz-placeholder,.textarea:is(:disabled,[disabled])::-moz-placeholder{color:color-mix(in oklab,var(--color-base-content) 20%,transparent)}.textarea:has(>textarea[disabled])::placeholder,.textarea:is(:disabled,[disabled])::placeholder{color:color-mix(in oklab,var(--color-base-content) 20%,transparent)}.textarea:has(>textarea[disabled]),.textarea:is(:disabled,[disabled]){box-shadow:none}.textarea:has(>textarea[disabled])>textarea[disabled]{cursor:not-allowed}.textarea-error,.textarea-error:focus,.textarea-error:focus-within{--input-color: var(--color-error)}.textarea-sm{font-size:.75rem}@keyframes progress{50%{background-position-x:-115%}}.select{border:var(--border) solid #0000;position:relative;display:inline-flex;flex-shrink:1;-webkit-appearance:none;-moz-appearance:none;appearance:none;align-items:center;gap:.375rem;background-color:var(--color-base-100);padding-inline-start:1rem;padding-inline-end:1.75rem;vertical-align:middle;width:clamp(3rem,20rem,100%);height:var(--size);font-size:.875rem;touch-action:manipulation;border-start-start-radius:var(--join-ss, var(--radius-field));border-start-end-radius:var(--join-se, var(--radius-field));border-end-start-radius:var(--join-es, var(--radius-field));border-end-end-radius:var(--join-ee, var(--radius-field));background-image:linear-gradient(45deg,#0000 50%,currentColor 50%),linear-gradient(135deg,currentColor 50%,#0000 50%);background-position:calc(100% - 20px) calc(1px + 50%),calc(100% - 16.1px) calc(1px + 50%);background-size:4px 4px,4px 4px;background-repeat:no-repeat;text-overflow:ellipsis;box-shadow:0 1px color-mix(in oklab,var(--input-color) calc(var(--depth) * 10%),#0000) inset,0 -1px oklch(100% 0 0 / calc(var(--depth) * .1)) inset;border-color:var(--input-color);--input-color: color-mix(in oklab, var(--color-base-content) 20%, #0000);--size: calc(var(--size-field, .25rem) * 10)}[dir=rtl] .select{background-position:calc(0% + 12px) calc(1px + 50%),calc(0% + 16px) calc(1px + 50%)}.select select{margin-inline-start:-1rem;margin-inline-end:-1.75rem;width:calc(100% + 2.75rem);-webkit-appearance:none;-moz-appearance:none;appearance:none;padding-inline-start:1rem;padding-inline-end:1.75rem;height:calc(100% - 2px);background:inherit;border-radius:inherit;border-style:none}.select select:focus,.select select:focus-within{--tw-outline-style: none;outline-style:none}@media (forced-colors: active){.select select:focus,.select select:focus-within{outline:2px solid transparent;outline-offset:2px}}.select select:not(:last-child){margin-inline-end:-1.375rem;background-image:none}.select:focus,.select:focus-within{--input-color: var(--color-base-content);box-shadow:0 1px color-mix(in oklab,var(--input-color) calc(var(--depth) * 10%),#0000);outline:2px solid var(--input-color);outline-offset:2px;isolation:isolate;z-index:1}.select:has(>select[disabled]),.select:is(:disabled,[disabled]){cursor:not-allowed;border-color:var(--color-base-200);background-color:var(--color-base-200);color:color-mix(in oklab,var(--color-base-content) 40%,transparent)}.select:has(>select[disabled])::-moz-placeholder,.select:is(:disabled,[disabled])::-moz-placeholder{color:color-mix(in oklab,var(--color-base-content) 20%,transparent)}.select:has(>select[disabled])::placeholder,.select:is(:disabled,[disabled])::placeholder{color:color-mix(in oklab,var(--color-base-content) 20%,transparent)}.select:has(>select[disabled])>select[disabled]{cursor:not-allowed}.select-sm{--size: calc(var(--size-field, .25rem) * 8);font-size:.75rem}.alert{display:grid;align-items:center;gap:1rem;border-radius:var(--radius-box);padding-inline:1rem;padding-block:.75rem;color:var(--color-base-content);background-color:var(--alert-color, var(--color-base-200));justify-content:start;justify-items:start;grid-auto-flow:column;grid-template-columns:auto;text-align:start;border:var(--border) solid var(--color-base-200);font-size:.875rem;line-height:1.25rem;background-size:auto,calc(var(--noise) * 100%);background-image:none,var(--fx-noise);box-shadow:0 3px 0 -2px oklch(100% 0 0 / calc(var(--depth) * .08)) inset,0 1px color-mix(in oklab,color-mix(in oklab,#000 20%,var(--alert-color, var(--color-base-200))) calc(var(--depth) * 20%),#0000),0 4px 3px -2px oklch(0% 0 0 / calc(var(--depth) * .08))}.alert:has(:nth-child(2)){grid-template-columns:auto minmax(auto,1fr)}.alert.alert-outline{background-color:transparent;color:var(--alert-color);box-shadow:none;background-image:none}.alert.alert-dash{background-color:transparent;color:var(--alert-color);border-style:dashed;box-shadow:none;background-image:none}.alert.alert-soft{color:var(--alert-color, var(--color-base-content));background:color-mix(in oklab,var(--alert-color, var(--color-base-content)) 8%,var(--color-base-100));border-color:color-mix(in oklab,var(--alert-color, var(--color-base-content)) 10%,var(--color-base-100));box-shadow:none;background-image:none}.alert-info{border-color:var(--color-info);color:var(--color-info-content);--alert-color: var(--color-info)}.alert-error{border-color:var(--color-error);color:var(--color-error-content);--alert-color: var(--color-error)}@keyframes radio{0%{padding:5px}50%{padding:3px}}.menu :where(li) .badge{justify-self:flex-end}@keyframes toast{0%{scale:.9;opacity:0}to{scale:1;opacity:1}}.status{display:inline-block;aspect-ratio:1 / 1;width:.5rem;height:.5rem;border-radius:var(--radius-selector);background-color:color-mix(in oklab,var(--color-base-content) 20%,transparent);background-position:center;background-repeat:no-repeat;vertical-align:middle;color:color-mix(in srgb,#000 30%,transparent)}@supports (color: color-mix(in lab,red,red)){.status{color:color-mix(in oklab,var(--color-black) 30%,transparent)}}.status{background-image:radial-gradient(circle at 35% 30%,oklch(1 0 0 / calc(var(--depth) * .5)),#0000);box-shadow:0 2px 3px -1px color-mix(in oklab,currentColor calc(var(--depth) * 100%),#0000)}.card{position:relative;display:flex;flex-direction:column;border-radius:var(--radius-box);outline-width:2px;transition:outline .2s ease-in-out;outline:0 solid #0000;outline-offset:2px}.card:focus{--tw-outline-style: none;outline-style:none}@media (forced-colors: active){.card:focus{outline:2px solid transparent;outline-offset:2px}}.card:focus-visible{outline-color:currentColor}.card :where(figure:first-child){overflow:hidden;border-start-start-radius:inherit;border-start-end-radius:inherit;border-end-start-radius:unset;border-end-end-radius:unset}.card :where(figure:last-child){overflow:hidden;border-start-start-radius:unset;border-start-end-radius:unset;border-end-start-radius:inherit;border-end-end-radius:inherit}.card:where(.card-border){border:var(--border) solid var(--color-base-200)}.card:where(.card-dash){border:var(--border) dashed var(--color-base-200)}.card.image-full{display:grid}.card.image-full>*{grid-column-start:1;grid-row-start:1}.card.image-full>.card-body{position:relative;color:var(--color-neutral-content)}.card.image-full :where(figure){overflow:hidden;border-radius:inherit}.card.image-full>figure img{height:100%;-o-object-fit:cover;object-fit:cover;filter:brightness(28%)}.card figure{display:flex;align-items:center;justify-content:center}.card:has(>input:is(input[type=checkbox],input[type=radio])){cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none}.card:has(>:checked){outline:2px solid currentColor}.card-title{display:flex;align-items:center;gap:.5rem;font-size:var(--cardtitle-fs, 1.125rem);font-weight:600}.card-body{display:flex;flex:auto;flex-direction:column;gap:.5rem;padding:var(--card-p, 1.5rem);font-size:var(--card-fs, .875rem)}.card-body :where(p){flex-grow:1}.card-xs .card-body{--card-p: .5rem;--card-fs: .6875rem}.card-xs .card-title{--cardtitle-fs: .875rem}.card-sm .card-body{--card-p: 1rem;--card-fs: .75rem}.card-sm .card-title{--cardtitle-fs: 1rem}.card-md .card-body{--card-p: 1.5rem;--card-fs: .875rem}.card-md .card-title{--cardtitle-fs: 1.125rem}.card-lg .card-body{--card-p: 2rem;--card-fs: 1rem}.card-lg .card-title{--cardtitle-fs: 1.25rem}.card-xl .card-body{--card-p: 2.5rem;--card-fs: 1.125rem}.card-xl .card-title{--cardtitle-fs: 1.375rem}.link{cursor:pointer;text-decoration-line:underline}.link:focus{--tw-outline-style: none;outline-style:none}@media (forced-colors: active){.link:focus{outline:2px solid transparent;outline-offset:2px}}.link:focus-visible{outline:2px solid currentColor;outline-offset:2px}.badge{display:inline-flex;align-items:center;justify-content:center;gap:.5rem;border-radius:var(--radius-selector);vertical-align:middle;color:var(--badge-fg);border:var(--border) solid var(--badge-color, var(--color-base-200));font-size:.875rem;width:-moz-fit-content;width:fit-content;padding-inline:calc(.25rem * 3 - var(--border));background-size:auto,calc(var(--noise) * 100%);background-image:none,var(--fx-noise);background-color:var(--badge-bg);--badge-bg: var(--badge-color, var(--color-base-100));--badge-fg: var(--color-base-content);--size: calc(var(--size-selector, .25rem) * 6);height:var(--size)}.badge-outline{color:var(--badge-color);--badge-bg: #0000;background-image:none;border-color:currentColor}.badge-secondary{--badge-color: var(--color-secondary);--badge-fg: var(--color-secondary-content)}.badge-neutral{--badge-color: var(--color-neutral);--badge-fg: var(--color-neutral-content)}.badge-info{--badge-color: var(--color-info);--badge-fg: var(--color-info-content)}.badge-success{--badge-color: var(--color-success);--badge-fg: var(--color-success-content)}.badge-warning{--badge-color: var(--color-warning);--badge-fg: var(--color-warning-content)}.badge-ghost{border-color:var(--color-base-200);background-color:var(--color-base-200);color:var(--color-base-content);background-image:none}.badge-xs{--size: calc(var(--size-selector, .25rem) * 4);font-size:.625rem;padding-inline:calc(.25rem * 2 - var(--border))}.badge-sm{--size: calc(var(--size-selector, .25rem) * 5);font-size:.75rem;padding-inline:calc(.25rem * 2.5 - var(--border))}@keyframes dropdown{0%{opacity:0}}:where(.btn){width:unset}.btn{display:inline-flex;flex-shrink:0;cursor:pointer;flex-wrap:nowrap;align-items:center;justify-content:center;gap:.375rem;text-align:center;vertical-align:middle;outline-offset:2px;webkit-user-select:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;padding-inline:var(--btn-p);color:var(--btn-fg);--tw-prose-links: var(--btn-fg);height:var(--size);font-size:var(--fontsize, .875rem);font-weight:600;outline-color:var(--btn-color, var(--color-base-content));transition-property:color,background-color,border-color,box-shadow;transition-timing-function:cubic-bezier(0,0,.2,1);transition-duration:.2s;border-start-start-radius:var(--join-ss, var(--radius-field));border-start-end-radius:var(--join-se, var(--radius-field));border-end-start-radius:var(--join-es, var(--radius-field));border-end-end-radius:var(--join-ee, var(--radius-field));background-color:var(--btn-bg);background-size:auto,calc(var(--noise) * 100%);background-image:none,var(--btn-noise);border-width:var(--border);border-style:solid;border-color:var(--btn-border);text-shadow:0 .5px oklch(100% 0 0 / calc(var(--depth) * .15));touch-action:manipulation;box-shadow:0 .5px 0 .5px oklch(100% 0 0 / calc(var(--depth) * 6%)) inset,var(--btn-shadow);--size: calc(var(--size-field, .25rem) * 10);--btn-bg: var(--btn-color, var(--color-base-200));--btn-fg: var(--color-base-content);--btn-p: 1rem;--btn-border: color-mix(in oklab, var(--btn-bg), #000 calc(var(--depth) * 5%));--btn-shadow: 0 3px 2px -2px color-mix(in oklab, var(--btn-bg) calc(var(--depth) * 30%), #0000), 0 4px 3px -2px color-mix(in oklab, var(--btn-bg) calc(var(--depth) * 30%), #0000);--btn-noise: var(--fx-noise)}.prose .btn{text-decoration-line:none}@media (hover: hover){.btn:hover{--btn-bg: color-mix(in oklab, var(--btn-color, var(--color-base-200)), #000 7%)}}.btn:focus-visible{outline-width:2px;outline-style:solid;isolation:isolate}.btn:active:not(.btn-active){translate:0 .5px;--btn-bg: color-mix(in oklab, var(--btn-color, var(--color-base-200)), #000 5%);--btn-border: color-mix(in oklab, var(--btn-color, var(--color-base-200)), #000 7%);--btn-shadow: 0 0 0 0 oklch(0% 0 0/0), 0 0 0 0 oklch(0% 0 0/0)}.btn:is(:disabled,[disabled],.btn-disabled):not(.btn-link,.btn-ghost){background-color:color-mix(in oklab,var(--color-base-content) 10%,transparent);box-shadow:none}.btn:is(:disabled,[disabled],.btn-disabled){pointer-events:none;--btn-border: #0000;--btn-noise: none;--btn-fg: color-mix(in oklch, var(--color-base-content) 20%, #0000)}@media (hover: hover){.btn:is(:disabled,[disabled],.btn-disabled):hover{pointer-events:none;background-color:color-mix(in oklab,var(--color-neutral) 20%,transparent);--btn-border: #0000;--btn-fg: color-mix(in oklch, var(--color-base-content) 20%, #0000)}}.btn:is(input[type=checkbox],input[type=radio]){-webkit-appearance:none;-moz-appearance:none;appearance:none}.btn:is(input[type=checkbox],input[type=radio]):after{content:attr(aria-label)}.btn:where(input:checked:not(.filter .btn)){--btn-color: var(--color-primary);--btn-fg: var(--color-primary-content);isolation:isolate}.btn-primary{--btn-color: var(--color-primary);--btn-fg: var(--color-primary-content)}.btn-error{--btn-color: var(--color-error);--btn-fg: var(--color-error-content)}.btn-ghost:not(.btn-active,:hover,:active:focus,:focus-visible){--btn-shadow: "";--btn-bg: #0000;--btn-border: #0000;--btn-noise: none}.btn-ghost:not(.btn-active,:hover,:active:focus,:focus-visible):not(:disabled,[disabled],.btn-disabled){outline-color:currentColor;--btn-fg: currentColor}@media (hover: none){.btn-ghost:hover:not(.btn-active,:active,:focus-visible,:disabled,[disabled],.btn-disabled){--btn-shadow: "";--btn-bg: #0000;--btn-border: #0000;--btn-noise: none;--btn-fg: currentColor}}.btn-link{text-decoration-line:underline;outline-color:currentColor;--btn-border: #0000;--btn-bg: #0000;--btn-fg: var(--color-primary);--btn-noise: none;--btn-shadow: ""}.btn-link:is(.btn-active,:hover,:active:focus,:focus-visible){text-decoration-line:underline;--btn-border: #0000;--btn-bg: #0000}@media (hover: none){.btn-link:hover:not(.btn-active,:active,:focus-visible,:disabled,[disabled],.btn-disabled){text-decoration-line:none}}.btn-outline:not(.btn-active,:hover,:active:focus,:focus-visible,:disabled,[disabled],.btn-disabled,:checked){--btn-shadow: "";--btn-bg: #0000;--btn-fg: var(--btn-color);--btn-border: var(--btn-color);--btn-noise: none}@media (hover: none){.btn-outline:hover:not(.btn-active,:active,:focus-visible,:disabled,[disabled],.btn-disabled,:checked){--btn-shadow: "";--btn-bg: #0000;--btn-fg: var(--btn-color);--btn-border: var(--btn-color);--btn-noise: none}}.btn-xs{--fontsize: .6875rem;--btn-p: .5rem;--size: calc(var(--size-field, .25rem) * 6)}.btn-sm{--fontsize: .75rem;--btn-p: .75rem;--size: calc(var(--size-field, .25rem) * 8)}.btn-square{padding-inline:0rem;width:var(--size);height:var(--size)}.btn-circle{border-radius:calc(infinity * 1px);padding-inline:0rem;width:var(--size);height:var(--size)}.label{display:inline-flex;align-items:center;gap:.375rem;white-space:nowrap;color:color-mix(in oklab,currentColor 60%,transparent)}.label:has(input){cursor:pointer}.label:is(.input>*,.select>*){display:flex;height:calc(100% - .5rem);align-items:center;padding-inline:.75rem;white-space:nowrap;font-size:inherit}.label:is(.input>*,.select>*):first-child{margin-inline-start:-.75rem;margin-inline-end:.75rem;border-inline-end:var(--border) solid color-mix(in oklab,currentColor 10%,#0000)}.label:is(.input>*,.select>*):last-child{margin-inline-start:.75rem;margin-inline-end:-.75rem;border-inline-start:var(--border) solid color-mix(in oklab,currentColor 10%,#0000)}.floating-label:has(.input-sm,.select-sm,.textarea-sm) span{font-size:.75rem;top:calc(var(--size-field, .25rem) * 8 / 2)}@keyframes rating{0%,40%{scale:1.1;filter:brightness(1.05) contrast(1.05)}}.filter{display:flex;flex-wrap:wrap}.filter input[type=radio]{width:auto}.filter input{overflow:hidden;opacity:100%;scale:1;transition:margin .1s,opacity .3s,padding .3s,border-width .1s}.filter input:not(:last-child){margin-inline-end:.25rem}.filter input.filter-reset{aspect-ratio:1 / 1}.filter input.filter-reset:after{content:"×"}.filter:not(:has(input:checked:not(.filter-reset))) .filter-reset,.filter:not(:has(input:checked:not(.filter-reset))) input[type=reset]{scale:0;border-width:0;margin-inline:0rem;width:0rem;padding-inline:0rem;opacity:0%}.filter:has(input:checked:not(.filter-reset)) input:not(:checked,.filter-reset,input[type=reset]){scale:0;border-width:0;margin-inline:0rem;width:0rem;padding-inline:0rem;opacity:0%}.toggle{border:var(--border) solid currentColor;color:var(--input-color);position:relative;display:inline-grid;flex-shrink:0;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;place-content:center;vertical-align:middle;webkit-user-select:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;grid-template-columns:0fr 1fr 1fr;--radius-selector-max: calc( var(--radius-selector) + var(--radius-selector) + var(--radius-selector) );border-radius:calc(var(--radius-selector) + min(var(--toggle-p),var(--radius-selector-max)) + min(var(--border),var(--radius-selector-max)));padding:var(--toggle-p);box-shadow:0 1px color-mix(in oklab,currentColor calc(var(--depth) * 10%),#0000) inset;transition:color .3s,grid-template-columns .2s;--input-color: color-mix(in oklab, var(--color-base-content) 50%, #0000);--toggle-p: calc(var(--size) * .125);--size: calc(var(--size-selector, .25rem) * 6);width:calc((var(--size) * 2) - (var(--border) + var(--toggle-p)) * 2);height:var(--size)}.toggle>*{z-index:1;grid-column:span 1 / span 1;grid-column-start:2;grid-row-start:1;height:100%;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent;padding:.125rem;transition:opacity .2s,rotate .4s;border:none}.toggle>*:focus{--tw-outline-style: none;outline-style:none}@media (forced-colors: active){.toggle>*:focus{outline:2px solid transparent;outline-offset:2px}}.toggle>*:nth-child(2){color:var(--color-base-100);rotate:0deg}.toggle>*:nth-child(3){color:var(--color-base-100);opacity:0%;rotate:-15deg}.toggle:has(:checked)>:nth-child(2){opacity:0%;rotate:15deg}.toggle:has(:checked)>:nth-child(3){opacity:100%;rotate:0deg}.toggle:before{position:relative;inset-inline-start:0rem;grid-column-start:2;grid-row-start:1;aspect-ratio:1 / 1;height:100%;border-radius:var(--radius-selector);background-color:currentColor;translate:0;--tw-content: "";content:var(--tw-content);transition:background-color .1s,translate .2s,inset-inline-start .2s;box-shadow:0 -1px oklch(0% 0 0 / calc(var(--depth) * .1)) inset,0 8px 0 -4px oklch(100% 0 0 / calc(var(--depth) * .1)) inset,0 1px color-mix(in oklab,currentColor calc(var(--depth) * 10%),#0000);background-size:auto,calc(var(--noise) * 100%);background-image:none,var(--fx-noise)}@media (forced-colors: active){.toggle:before{outline-style:var(--tw-outline-style);outline-width:1px;outline-offset:-1px}}@media print{.toggle:before{outline:.25rem solid;outline-offset:-1rem}}.toggle:focus-visible,.toggle:has(:focus-visible){outline:2px solid currentColor;outline-offset:2px}.toggle:checked,.toggle[aria-checked=true],.toggle:has(>input:checked){grid-template-columns:1fr 1fr 0fr;background-color:var(--color-base-100);--input-color: var(--color-base-content)}.toggle:checked:before,.toggle[aria-checked=true]:before,.toggle:has(>input:checked):before{background-color:currentColor}@starting-style{.toggle:checked:before,.toggle[aria-checked=true]:before,.toggle:has(>input:checked):before{opacity:0}}.toggle:indeterminate{grid-template-columns:.5fr 1fr .5fr}.toggle:disabled{cursor:not-allowed;opacity:30%}.toggle:disabled:before{background-color:transparent;border:var(--border) solid currentColor}.toggle-primary:checked,.toggle-primary[aria-checked=true]{--input-color: var(--color-primary)}.toggle-xs:is([type=checkbox]),.toggle-xs:has([type=checkbox]){--size: calc(var(--size-selector, .25rem) * 4)}.toggle-sm:is([type=checkbox]),.toggle-sm:has([type=checkbox]){--size: calc(var(--size-selector, .25rem) * 5)}.stats{position:relative;display:inline-grid;grid-auto-flow:column;overflow-x:auto;border-radius:var(--radius-box)}.stat{display:inline-grid;width:100%;-moz-column-gap:1rem;column-gap:1rem;padding-inline:1.5rem;padding-block:1rem;grid-template-columns:repeat(1,1fr)}.stat:not(:last-child){border-inline-end:var(--border) dashed color-mix(in oklab,currentColor 10%,#0000);border-block-end:none}.stat-title{grid-column-start:1;white-space:nowrap;color:color-mix(in oklab,var(--color-base-content) 60%,transparent);font-size:.75rem}.stat-value{grid-column-start:1;white-space:nowrap;font-size:2rem;font-weight:800}.stat-desc{grid-column-start:1;white-space:nowrap;color:color-mix(in oklab,var(--color-base-content) 60%,transparent);font-size:.75rem}.stats-horizontal .stat:not(:last-child){border-inline-end:var(--border) dashed color-mix(in oklab,currentColor 10%,#0000);border-block-end:none}.stats-vertical .stat:not(:last-child){border-inline-end:none;border-block-end:var(--border) dashed color-mix(in oklab,currentColor 10%,#0000)}@keyframes skeleton{0%{background-position:150%}to{background-position:-50%}}.loading{pointer-events:none;display:inline-block;aspect-ratio:1 / 1;background-color:currentColor;vertical-align:middle;width:calc(var(--size-selector, .25rem) * 6);-webkit-mask-size:100%;mask-size:100%;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:center;mask-position:center;-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='black' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg transform-origin='center'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='2s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dasharray' values='0,150;42,150;42,150' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dashoffset' values='0;-16;-59' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/g%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='black' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg transform-origin='center'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='2s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dasharray' values='0,150;42,150;42,150' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dashoffset' values='0;-16;-59' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/g%3E%3C/svg%3E")}.loading-spinner{-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='black' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg transform-origin='center'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='2s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dasharray' values='0,150;42,150;42,150' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dashoffset' values='0;-16;-59' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/g%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='black' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg transform-origin='center'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='2s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dasharray' values='0,150;42,150;42,150' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dashoffset' values='0;-16;-59' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/g%3E%3C/svg%3E")}.loading-dots{-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='4' cy='12' r='3'%3E%3Canimate attributeName='cy' values='12;6;12;12' keyTimes='0;0.286;0.571;1' dur='1.05s' repeatCount='indefinite' keySplines='.33,0,.66,.33;.33,.66,.66,1'/%3E%3C/circle%3E%3Ccircle cx='12' cy='12' r='3'%3E%3Canimate attributeName='cy' values='12;6;12;12' keyTimes='0;0.286;0.571;1' dur='1.05s' repeatCount='indefinite' keySplines='.33,0,.66,.33;.33,.66,.66,1' begin='0.1s'/%3E%3C/circle%3E%3Ccircle cx='20' cy='12' r='3'%3E%3Canimate attributeName='cy' values='12;6;12;12' keyTimes='0;0.286;0.571;1' dur='1.05s' repeatCount='indefinite' keySplines='.33,0,.66,.33;.33,.66,.66,1' begin='0.2s'/%3E%3C/circle%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='4' cy='12' r='3'%3E%3Canimate attributeName='cy' values='12;6;12;12' keyTimes='0;0.286;0.571;1' dur='1.05s' repeatCount='indefinite' keySplines='.33,0,.66,.33;.33,.66,.66,1'/%3E%3C/circle%3E%3Ccircle cx='12' cy='12' r='3'%3E%3Canimate attributeName='cy' values='12;6;12;12' keyTimes='0;0.286;0.571;1' dur='1.05s' repeatCount='indefinite' keySplines='.33,0,.66,.33;.33,.66,.66,1' begin='0.1s'/%3E%3C/circle%3E%3Ccircle cx='20' cy='12' r='3'%3E%3Canimate attributeName='cy' values='12;6;12;12' keyTimes='0;0.286;0.571;1' dur='1.05s' repeatCount='indefinite' keySplines='.33,0,.66,.33;.33,.66,.66,1' begin='0.2s'/%3E%3C/circle%3E%3C/svg%3E")}.loading-xs{width:calc(var(--size-selector, .25rem) * 4)}.loading-sm{width:calc(var(--size-selector, .25rem) * 5)}.loading-md{width:calc(var(--size-selector, .25rem) * 6)}.loading-lg{width:calc(var(--size-selector, .25rem) * 7)}.checkbox{border:var(--border) solid var(--input-color, color-mix(in oklab, var(--color-base-content) 20%, #0000));position:relative;display:inline-block;flex-shrink:0;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:var(--radius-selector);padding:.25rem;vertical-align:middle;color:var(--color-base-content);box-shadow:0 1px oklch(0% 0 0 / calc(var(--depth) * .1)) inset,0 0 #0000 inset,0 0 #0000;transition:background-color .2s,box-shadow .2s;--size: calc(var(--size-selector, .25rem) * 6);width:var(--size);height:var(--size);background-size:auto,calc(var(--noise) * 100%);background-image:none,var(--fx-noise)}.checkbox:before{--tw-content: "";content:var(--tw-content);display:block;width:100%;height:100%;rotate:45deg;background-color:currentColor;opacity:0%;transition:clip-path .3s,opacity .1s,rotate .3s,translate .3s;transition-delay:.1s;clip-path:polygon(20% 100%,20% 80%,50% 80%,50% 80%,70% 80%,70% 100%);box-shadow:0 3px oklch(100% 0 0 / calc(var(--depth) * .1)) inset;font-size:1rem;line-height:.75}.checkbox:focus-visible{outline:2px solid var(--input-color, currentColor);outline-offset:2px}.checkbox:checked,.checkbox[aria-checked=true]{background-color:var(--input-color, color-mix(in oklab, var(--color-base-content) 20%, #0000));box-shadow:0 0 #0000 inset,0 8px 0 -4px oklch(100% 0 0 / calc(var(--depth) * .1)) inset,0 1px oklch(0% 0 0 / calc(var(--depth) * .1))}.checkbox:checked:before,.checkbox[aria-checked=true]:before{clip-path:polygon(20% 100%,20% 80%,50% 80%,50% 0%,70% 0%,70% 100%);opacity:100%}@media (forced-colors: active){.checkbox:checked:before,.checkbox[aria-checked=true]:before{rotate:0deg;background-color:transparent;--tw-content: "✔︎";clip-path:none}}@media print{.checkbox:checked:before,.checkbox[aria-checked=true]:before{rotate:0deg;background-color:transparent;--tw-content: "✔︎";clip-path:none}}.checkbox:indeterminate{background-color:var(--input-color, color-mix(in oklab, var(--color-base-content) 20%, #0000))}.checkbox:indeterminate:before{rotate:0deg;opacity:100%;translate:0 -35%;clip-path:polygon(20% 100%,20% 80%,50% 80%,50% 80%,80% 80%,80% 100%)}.checkbox:disabled{cursor:not-allowed;opacity:20%}.checkbox-sm{padding:.1875rem;--size: calc(var(--size-selector, .25rem) * 5)}.tabs{display:flex;flex-wrap:wrap;--tabs-height: auto;--tabs-direction: row;--tab-height: calc(var(--size-field, .25rem) * 10);height:var(--tabs-height);flex-direction:var(--tabs-direction)}.tab{position:relative;display:inline-flex;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;flex-wrap:wrap;align-items:center;justify-content:center;text-align:center;webkit-user-select:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}@media (hover: hover){.tab:hover{color:var(--color-base-content)}}.tab{--tab-p: 1rem;--tab-bg: var(--color-base-100);--tab-border-color: var(--color-base-300);--tab-radius-ss: 0;--tab-radius-se: 0;--tab-radius-es: 0;--tab-radius-ee: 0;--tab-order: 0;--tab-radius-min: calc(.75rem - var(--border));border-color:#0000;order:var(--tab-order);height:var(--tab-height);font-size:.875rem;padding-inline-start:var(--tab-p);padding-inline-end:var(--tab-p)}.tab:is(input[type=radio]){min-width:-moz-fit-content;min-width:fit-content}.tab:is(input[type=radio]):after{content:attr(aria-label)}.tab:is(label){position:relative}.tab:is(label) input{position:absolute;top:0rem;right:0rem;bottom:0rem;left:0rem;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;opacity:0%}.tab:checked+.tab-content,.tab:is(label:has(:checked))+.tab-content,.tab:is(.tab-active,[aria-selected=true])+.tab-content{display:block;height:calc(100% - var(--tab-height) + var(--border))}.tab:not(:checked,label:has(:checked),:hover,.tab-active,[aria-selected=true]){color:color-mix(in oklab,var(--color-base-content) 50%,transparent)}.tab:not(input):empty{flex-grow:1;cursor:default}.tab:focus{--tw-outline-style: none;outline-style:none}@media (forced-colors: active){.tab:focus{outline:2px solid transparent;outline-offset:2px}}.tab:focus-visible,.tab:is(label:has(:checked:focus-visible)){outline:2px solid currentColor;outline-offset:-5px}.tab[disabled]{pointer-events:none;opacity:40%}.tabs-border .tab{--tab-border-color: #0000 #0000 var(--tab-border-color) #0000;position:relative;border-radius:var(--radius-field)}.tabs-border .tab:before{--tw-content: "";content:var(--tw-content);background-color:var(--tab-border-color);transition:background-color .2s ease;width:80%;height:3px;border-radius:var(--radius-field);bottom:0;left:10%;position:absolute}.tabs-border .tab:is(.tab-active,[aria-selected=true]):not(.tab-disabled,[disabled]):before,.tabs-border .tab:is(input:checked):before,.tabs-border .tab:is(label:has(:checked)):before{--tab-border-color: currentColor;border-top:3px solid}.tabs-lift>.tab{--tab-border: 0 0 var(--border) 0;--tab-radius-ss: min(var(--radius-field), var(--tab-radius-min));--tab-radius-se: min(var(--radius-field), var(--tab-radius-min));--tab-radius-es: 0;--tab-radius-ee: 0;--tab-paddings: var(--border) var(--tab-p) 0 var(--tab-p);--tab-border-colors: #0000 #0000 var(--tab-border-color) #0000;--tab-corner-width: calc(100% + min(var(--radius-field), var(--tab-radius-min))*2) ;--tab-corner-height: min(var(--radius-field), var(--tab-radius-min));--tab-corner-position: top left, top right;border-width:var(--tab-border);border-start-start-radius:var(--tab-radius-ss);border-start-end-radius:var(--tab-radius-se);border-end-start-radius:var(--tab-radius-es);border-end-end-radius:var(--tab-radius-ee);padding:var(--tab-paddings);border-color:var(--tab-border-colors)}.tabs-lift>.tab:is(.tab-active,[aria-selected=true]):not(.tab-disabled,[disabled]),.tabs-lift>.tab:is(input:checked,label:has(:checked)){--tab-border: var(--border) var(--border) 0 var(--border);--tab-border-colors: var(--tab-border-color) var(--tab-border-color) #0000 var(--tab-border-color);--tab-paddings: 0 calc(var(--tab-p) - var(--border)) var(--border) calc(var(--tab-p) - var(--border));--tab-inset: auto auto 0 auto;--tab-grad: calc(69% - var(--border));--radius-start: radial-gradient( circle at top left, #0000 var(--tab-grad), var(--tab-border-color) calc(var(--tab-grad) + .25px), var(--tab-border-color) calc(var(--tab-grad) + var(--border)), var(--tab-bg) calc(var(--tab-grad) + var(--border) + .25px) );--radius-end: radial-gradient( circle at top right, #0000 var(--tab-grad), var(--tab-border-color) calc(var(--tab-grad) + .25px), var(--tab-border-color) calc(var(--tab-grad) + var(--border)), var(--tab-bg) calc(var(--tab-grad) + var(--border) + .25px) );background-color:var(--tab-bg)}.tabs-lift>.tab:is(.tab-active,[aria-selected=true]):not(.tab-disabled,[disabled]):before,.tabs-lift>.tab:is(input:checked,label:has(:checked)):before{z-index:1;content:"";display:block;position:absolute;width:var(--tab-corner-width);height:var(--tab-corner-height);background-position:var(--tab-corner-position);background-image:var(--radius-start),var(--radius-end);background-size:min(var(--radius-field),var(--tab-radius-min)) min(var(--radius-field),var(--tab-radius-min));background-repeat:no-repeat;inset:var(--tab-inset)}.tabs-lift>.tab:is(.tab-active,[aria-selected=true]):not(.tab-disabled,[disabled]):first-child:before,.tabs-lift>.tab:is(input:checked,label:has(:checked)):first-child:before{--radius-start: none}[dir=rtl] .tabs-lift>.tab:is(.tab-active,[aria-selected=true]):not(.tab-disabled,[disabled]):first-child:before,[dir=rtl] .tabs-lift>.tab:is(input:checked,label:has(:checked)):first-child:before{transform:rotateY(180deg)}.tabs-lift>.tab:is(.tab-active,[aria-selected=true]):not(.tab-disabled,[disabled]):last-child:before,.tabs-lift>.tab:is(input:checked,label:has(:checked)):last-child:before{--radius-end: none}[dir=rtl] .tabs-lift>.tab:is(.tab-active,[aria-selected=true]):not(.tab-disabled,[disabled]):last-child:before,[dir=rtl] .tabs-lift>.tab:is(input:checked,label:has(:checked)):last-child:before{transform:rotateY(180deg)}.tabs-lift:has(.tab-content)>.tab:first-child:not(.tab-active,[aria-selected=true]){--tab-border-colors: var(--tab-border-color) var(--tab-border-color) #0000 var(--tab-border-color)}.tabs-lift :checked+.tab-content:nth-child(1),.tabs-lift :checked+.tab-content:nth-child(n+3),.tabs-lift label:has(:checked)+.tab-content:nth-child(1),.tabs-lift label:has(:checked)+.tab-content:nth-child(n+3),.tabs-lift :is(.tab-active,[aria-selected=true])+.tab-content:nth-child(1),.tabs-lift :is(.tab-active,[aria-selected=true])+.tab-content:nth-child(n+3){--tabcontent-radius-ss: var(--radius-box)}.tabs-top .tab{--tab-order: 0;--tab-border: 0 0 var(--border) 0;--tab-radius-ss: min(var(--radius-field), var(--tab-radius-min));--tab-radius-se: min(var(--radius-field), var(--tab-radius-min));--tab-radius-es: 0;--tab-radius-ee: 0;--tab-paddings: var(--border) var(--tab-p) 0 var(--tab-p);--tab-border-colors: #0000 #0000 var(--tab-border-color) #0000;--tab-corner-width: calc(100% + min(var(--radius-field), var(--tab-radius-min))*2) ;--tab-corner-height: min(var(--radius-field), var(--tab-radius-min));--tab-corner-position: top left, top right}.tabs-top .tab:is(.tab-active,[aria-selected=true]):not(.tab-disabled,[disabled]),.tabs-top .tab:is(input:checked),.tabs-top .tab:is(label:has(:checked)){--tab-border: var(--border) var(--border) 0 var(--border);--tab-border-colors: var(--tab-border-color) var(--tab-border-color) #0000 var(--tab-border-color);--tab-paddings: 0 calc(var(--tab-p) - var(--border)) var(--border) calc(var(--tab-p) - var(--border));--tab-inset: auto auto 0 auto;--radius-start: radial-gradient( circle at top left, #0000 var(--tab-grad), var(--tab-border-color) calc(var(--tab-grad) + .25px), var(--tab-border-color) calc(var(--tab-grad) + var(--border)), var(--tab-bg) calc(var(--tab-grad) + var(--border) + .25px) );--radius-end: radial-gradient( circle at top right, #0000 var(--tab-grad), var(--tab-border-color) calc(var(--tab-grad) + .25px), var(--tab-border-color) calc(var(--tab-grad) + var(--border)), var(--tab-bg) calc(var(--tab-grad) + var(--border) + .25px) )}.tabs-top:has(.tab-content)>.tab:first-child:not(.tab-active,[aria-selected=true]){--tab-border-colors: var(--tab-border-color) var(--tab-border-color) #0000 var(--tab-border-color)}.tabs-top :checked+.tab-content:nth-child(1),.tabs-top :checked+.tab-content:nth-child(n+3),.tabs-top label:has(:checked)+.tab-content:nth-child(1),.tabs-top label:has(:checked)+.tab-content:nth-child(n+3),.tabs-top :is(.tab-active,[aria-selected=true])+.tab-content:nth-child(1),.tabs-top :is(.tab-active,[aria-selected=true])+.tab-content:nth-child(n+3){--tabcontent-radius-ss: var(--radius-box)}.tabs-bottom .tab{--tab-order: 1;--tab-border: var(--border) 0 0 0;--tab-radius-ss: 0;--tab-radius-se: 0;--tab-radius-es: min(var(--radius-field), var(--tab-radius-min));--tab-radius-ee: min(var(--radius-field), var(--tab-radius-min));--tab-border-colors: var(--tab-border-color) #0000 #0000 #0000;--tab-paddings: 0 var(--tab-p) var(--border) var(--tab-p);--tab-corner-width: calc(100% + min(var(--radius-field), var(--tab-radius-min))*2) ;--tab-corner-height: min(var(--radius-field), var(--tab-radius-min));--tab-corner-position: top left, top right}.tabs-bottom .tab:is(.tab-active,[aria-selected=true]):not(.tab-disabled,[disabled]),.tabs-bottom .tab:is(input:checked),.tabs-bottom .tab:is(label:has(:checked)){--tab-border: 0 var(--border) var(--border) var(--border);--tab-border-colors: #0000 var(--tab-border-color) var(--tab-border-color) var(--tab-border-color);--tab-paddings: var(--border) calc(var(--tab-p) - var(--border)) 0 calc(var(--tab-p) - var(--border));--tab-inset: 0 auto auto auto;--radius-start: radial-gradient( circle at bottom left, #0000 var(--tab-grad), var(--tab-border-color) calc(var(--tab-grad) + .25px), var(--tab-border-color) calc(var(--tab-grad) + var(--border)), var(--tab-bg) calc(var(--tab-grad) + var(--border) + .25px) );--radius-end: radial-gradient( circle at bottom right, #0000 var(--tab-grad), var(--tab-border-color) calc(var(--tab-grad) + .25px), var(--tab-border-color) calc(var(--tab-grad) + var(--border)), var(--tab-bg) calc(var(--tab-grad) + var(--border) + .25px) )}.tabs-bottom:has(.tab-content)>.tab:first-child:not(.tab-active,[aria-selected=true]){--tab-border-colors: #0000 var(--tab-border-color) var(--tab-border-color) var(--tab-border-color)}.tabs-bottom>:checked+.tab-content:not(:nth-child(2)),.tabs-bottom>:is(label:has(:checked))+.tab-content:not(:nth-child(2)),.tabs-bottom>:is(.tab-active,[aria-selected=true])+.tab-content:not(:nth-child(2)){--tabcontent-radius-es: var(--radius-box)}.tabs-box .tab{border-radius:var(--radius-field);border-style:none}.tabs-box .tab:focus-visible,.tabs-box .tab:is(label:has(:checked:focus-visible)){outline-offset:2px}.tabs-box>:is(.tab-active,[aria-selected=true]):not(.tab-disabled,[disabled]),.tabs-box>:is(input:checked),.tabs-box>:is(label:has(:checked)){background-color:var(--tab-bg, var(--color-base-100));box-shadow:0 1px oklch(100% 0 0 / calc(var(--depth) * .1)) inset,0 1px 1px -1px color-mix(in oklab,var(--color-neutral) calc(var(--depth) * 50%),#0000),0 1px 6px -4px color-mix(in oklab,var(--color-neutral) calc(var(--depth) * 100%),#0000)}@media (forced-colors: active){.tabs-box>:is(.tab-active,[aria-selected=true]):not(.tab-disabled,[disabled]),.tabs-box>:is(input:checked),.tabs-box>:is(label:has(:checked)){border:1px solid}}.tabs-xs :where(.tab){font-size:.75rem;--tab-p: .375rem;--tab-radius-min: calc(.5rem - var(--border))}.tabs-sm :where(.tab){font-size:.875rem;--tab-p: .5rem;--tab-radius-min: calc(.5rem - var(--border))}.tabs-md :where(.tab){font-size:.875rem;--tab-p: .75rem;--tab-radius-min: calc(.75rem - var(--border))}.tabs-lg :where(.tab){font-size:1.125rem;--tab-p: 1rem;--tab-radius-min: calc(1.5rem - var(--border))}.tabs-xl :where(.tab){font-size:1.125rem;--tab-p: 1.25rem;--tab-radius-min: calc(2rem - var(--border))}.input{cursor:text;border:var(--border) solid #0000;position:relative;display:inline-flex;flex-shrink:1;-webkit-appearance:none;-moz-appearance:none;appearance:none;align-items:center;gap:.5rem;background-color:var(--color-base-100);padding-inline:.75rem;vertical-align:middle;white-space:nowrap;width:clamp(3rem,20rem,100%);height:var(--size);font-size:.875rem;touch-action:manipulation;border-start-start-radius:var(--join-ss, var(--radius-field));border-start-end-radius:var(--join-se, var(--radius-field));border-end-start-radius:var(--join-es, var(--radius-field));border-end-end-radius:var(--join-ee, var(--radius-field));border-color:var(--input-color);box-shadow:0 1px color-mix(in oklab,var(--input-color) calc(var(--depth) * 10%),#0000) inset,0 -1px oklch(100% 0 0 / calc(var(--depth) * .1)) inset;--size: calc(var(--size-field, .25rem) * 10);--input-color: color-mix(in oklab, var(--color-base-content) 20%, #0000)}.input:where(input){display:inline-flex}.input :where(input){display:inline-flex;height:100%;width:100%;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent;border:none}.input :where(input):focus,.input :where(input):focus-within{--tw-outline-style: none;outline-style:none}@media (forced-colors: active){.input :where(input):focus,.input :where(input):focus-within{outline:2px solid transparent;outline-offset:2px}}.input :where(input[type=url]),.input :where(input[type=email]){direction:ltr}.input :where(input[type=date]){display:inline-block}.input:focus,.input:focus-within{--input-color: var(--color-base-content);box-shadow:0 1px color-mix(in oklab,var(--input-color) calc(var(--depth) * 10%),#0000);outline:2px solid var(--input-color);outline-offset:2px;isolation:isolate;z-index:1}.input:has(>input[disabled]),.input:is(:disabled,[disabled]){cursor:not-allowed;border-color:var(--color-base-200);background-color:var(--color-base-200);color:color-mix(in oklab,var(--color-base-content) 40%,transparent)}.input:has(>input[disabled])::-moz-placeholder,.input:is(:disabled,[disabled])::-moz-placeholder{color:color-mix(in oklab,var(--color-base-content) 20%,transparent)}.input:has(>input[disabled])::placeholder,.input:is(:disabled,[disabled])::placeholder{color:color-mix(in oklab,var(--color-base-content) 20%,transparent)}.input:has(>input[disabled]),.input:is(:disabled,[disabled]){box-shadow:none}.input:has(>input[disabled])>input[disabled]{cursor:not-allowed}.input::-webkit-date-and-time-value{text-align:inherit}.input[type=number]::-webkit-inner-spin-button{margin-block:-.75rem;margin-inline-end:-.75rem}.input::-webkit-calendar-picker-indicator{position:absolute;inset-inline-end:.75em}.input-success,.input-success:focus,.input-success:focus-within{--input-color: var(--color-success)}.input-error,.input-error:focus,.input-error:focus-within{--input-color: var(--color-error)}.input-sm{--size: calc(var(--size-field, .25rem) * 8);font-size:.75rem}.input-sm[type=number]::-webkit-inner-spin-button{margin-block:-.5rem;margin-inline-end:-.75rem}.list{display:flex;flex-direction:column;font-size:.875rem}.list :where(.list-row){--list-grid-cols: minmax(0, auto) 1fr;position:relative;display:grid;grid-auto-flow:column;gap:1rem;border-radius:var(--radius-box);padding:1rem;word-break:break-word;grid-template-columns:var(--list-grid-cols)}.list :where(.list-row):has(.list-col-grow:nth-child(1)){--list-grid-cols: 1fr}.list :where(.list-row):has(.list-col-grow:nth-child(2)){--list-grid-cols: minmax(0, auto) 1fr}.list :where(.list-row):has(.list-col-grow:nth-child(3)){--list-grid-cols: minmax(0, auto) minmax(0, auto) 1fr}.list :where(.list-row):has(.list-col-grow:nth-child(4)){--list-grid-cols: minmax(0, auto) minmax(0, auto) minmax(0, auto) 1fr}.list :where(.list-row):has(.list-col-grow:nth-child(5)){--list-grid-cols: minmax(0, auto) minmax(0, auto) minmax(0, auto) minmax(0, auto) 1fr}.list :where(.list-row):has(.list-col-grow:nth-child(6)){--list-grid-cols: minmax(0, auto) minmax(0, auto) minmax(0, auto) minmax(0, auto) minmax(0, auto) 1fr}.list :where(.list-row) :not(.list-col-wrap){grid-row-start:1}.list>:not(:last-child).list-row:after,.list>:not(:last-child) .list-row:after{content:"";border-bottom:var(--border) solid;inset-inline:var(--radius-box);position:absolute;bottom:0rem;border-color:color-mix(in oklab,var(--color-base-content) 5%,transparent)}.mockup-code{position:relative;overflow:hidden;overflow-x:auto;border-radius:var(--radius-box);background-color:var(--color-neutral);padding-block:1.25rem;color:var(--color-neutral-content);font-size:.875rem;direction:ltr}.mockup-code:before{content:"";margin-bottom:1rem;display:block;height:.75rem;width:.75rem;border-radius:calc(infinity * 1px);opacity:30%;box-shadow:1.4em 0,2.8em 0,4.2em 0}.mockup-code pre{padding-right:1.25rem}.mockup-code pre:before{content:"";margin-right:2ch}.mockup-code pre[data-prefix]:before{content:attr(data-prefix);display:inline-block;width:2rem;text-align:right;opacity:50%}.mockup-browser .mockup-browser-toolbar .input{margin-inline:auto;display:flex;height:100%;align-items:center;gap:.5rem;overflow:hidden;background-color:var(--color-base-200);text-overflow:ellipsis;white-space:nowrap;font-size:.75rem;direction:ltr}.mockup-browser .mockup-browser-toolbar .input:before{content:"";width:1rem;height:1rem;opacity:50%;background-color:currentColor;-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M9.965 11.026a5 5 0 1 1 1.06-1.06l2.755 2.754a.75.75 0 1 1-1.06 1.06l-2.755-2.754ZM10.5 7a3.5 3.5 0 1 1-7 0 3.5 3.5 0 0 1 7 0Z' clip-rule='evenodd' /%3E%3C/svg%3E") no-repeat center;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M9.965 11.026a5 5 0 1 1 1.06-1.06l2.755 2.754a.75.75 0 1 1-1.06 1.06l-2.755-2.754ZM10.5 7a3.5 3.5 0 1 1-7 0 3.5 3.5 0 0 1 7 0Z' clip-rule='evenodd' /%3E%3C/svg%3E") no-repeat center;-webkit-mask-size:contain;mask-size:contain}.modal{pointer-events:none;visibility:hidden;position:fixed;top:0rem;right:0rem;bottom:0rem;left:0rem;margin:0rem;display:grid;height:100%;max-height:none;width:100%;max-width:none;align-items:center;justify-items:center;background-color:transparent;padding:0rem;color:inherit;overflow-x:hidden;transition:translate .3s ease-out,visibility .3s allow-discrete,background-color .3s ease-out,opacity .1s ease-out;overflow-y:hidden;overscroll-behavior:contain;z-index:999}.modal::backdrop{display:none}.modal.modal-open,.modal[open],.modal:target{pointer-events:auto;visibility:visible;opacity:100%;background-color:#0006}.modal.modal-open .modal-box,.modal[open] .modal-box,.modal:target .modal-box{translate:0 0;scale:1;opacity:1}@starting-style{.modal.modal-open,.modal[open],.modal:target{visibility:hidden;opacity:0%}}.modal-action{margin-top:1.5rem;display:flex;justify-content:flex-end;gap:.5rem}.modal-toggle:checked+.modal{pointer-events:auto;visibility:visible;opacity:100%;background-color:#0006}.modal-toggle:checked+.modal .modal-box{translate:0 0;scale:1;opacity:1}@starting-style{.modal-toggle:checked+.modal{visibility:hidden;opacity:0%}}.modal-backdrop{grid-column-start:1;grid-row-start:1;display:grid;align-self:stretch;justify-self:stretch;color:transparent;z-index:-1}.modal-backdrop button{cursor:pointer}.modal-box{grid-column-start:1;grid-row-start:1;max-height:100vh;width:calc(11/12 * 100%);max-width:32rem;background-color:var(--color-base-100);padding:1.5rem;transition:translate .3s ease-out,scale .3s ease-out,opacity .2s ease-out .05s,box-shadow .3s ease-out;border-top-left-radius:var(--modal-tl, var(--radius-box));border-top-right-radius:var(--modal-tr, var(--radius-box));border-bottom-left-radius:var(--modal-bl, var(--radius-box));border-bottom-right-radius:var(--modal-br, var(--radius-box));scale:95%;opacity:0;box-shadow:#00000040 0 25px 50px -12px;overflow-y:auto;overscroll-behavior:contain}.modal-top :where(.modal-box){height:auto;width:100%;max-width:none;max-height:calc(100vh - 5em);translate:0 -100%;scale:1;--modal-tl: 0;--modal-tr: 0;--modal-bl: var(--radius-box);--modal-br: var(--radius-box)}.modal-middle :where(.modal-box){height:auto;width:calc(11/12 * 100%);max-width:32rem;max-height:calc(100vh - 5em);translate:0 2%;scale:98%;--modal-tl: var(--radius-box);--modal-tr: var(--radius-box);--modal-bl: var(--radius-box);--modal-br: var(--radius-box)}.modal-bottom :where(.modal-box){height:auto;width:100%;max-width:none;max-height:calc(100vh - 5em);translate:0 100%;scale:1;--modal-tl: var(--radius-box);--modal-tr: var(--radius-box);--modal-bl: 0;--modal-br: 0}.modal-start :where(.modal-box){height:100vh;max-height:none;width:auto;max-width:none;translate:-100% 0;scale:1;--modal-tl: 0;--modal-tr: var(--radius-box);--modal-bl: 0;--modal-br: var(--radius-box)}.modal-end :where(.modal-box){height:100vh;max-height:none;width:auto;max-width:none;translate:100% 0;scale:1;--modal-tl: var(--radius-box);--modal-tr: 0;--modal-bl: var(--radius-box);--modal-br: 0}.scrollbar-thin::-webkit-scrollbar{width:6px}.scrollbar-thin::-webkit-scrollbar-track{background-color:var(--color-base-200)}.scrollbar-thin::-webkit-scrollbar-thumb{border-radius:.25rem;background-color:var(--color-base-300)}.scrollbar-thin::-webkit-scrollbar-thumb:hover{background:color-mix(in srgb,var(--color-base-content) 40%,transparent)}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.bottom-0{bottom:0}.bottom-3{bottom:.75rem}.bottom-4{bottom:1rem}.left-1\/2{left:50%}.right-0{right:0}.right-3{right:.75rem}.top-0{top:0}.top-2\.5{top:.625rem}.top-\[4\.5rem\]{top:4.5rem}.z-10{z-index:10}.z-30{z-index:30}.z-50{z-index:50}.col-span-2{grid-column:span 2 / span 2}.mx-auto{margin-left:auto;margin-right:auto}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-auto{margin-left:auto}.mr-1{margin-right:.25rem}.mr-2{margin-right:.5rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-1\.5{margin-top:.375rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-8{margin-top:2rem}.flex{display:flex}.grid{display:grid}.hidden{display:none}.h-1\.5{height:.375rem}.h-10{height:2.5rem}.h-11{height:2.75rem}.h-12{height:3rem}.h-16{height:4rem}.h-2{height:.5rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-64{height:16rem}.h-9{height:2.25rem}.h-\[18px\]{height:18px}.h-\[calc\(100vh-7\.5rem\)\]{height:calc(100vh - 7.5rem)}.h-full{height:100%}.max-h-56{max-height:14rem}.max-h-\[30rem\]{max-height:30rem}.max-h-\[80vh\]{max-height:80vh}.max-h-\[90vh\]{max-height:90vh}.max-h-\[calc\(100vh-16rem\)\]{max-height:calc(100vh - 16rem)}.min-h-0{min-height:0px}.min-h-\[120px\]{min-height:120px}.min-h-\[400px\]{min-height:400px}.min-h-\[480px\]{min-height:480px}.min-h-screen{min-height:100vh}.w-1{width:.25rem}.w-1\.5{width:.375rem}.w-10{width:2.5rem}.w-11{width:2.75rem}.w-12{width:3rem}.w-16{width:4rem}.w-2{width:.5rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-32{width:8rem}.w-4{width:1rem}.w-40{width:10rem}.w-44{width:11rem}.w-48{width:12rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-72{width:18rem}.w-80{width:20rem}.w-9{width:2.25rem}.w-\[18px\]{width:18px}.w-\[240px\]{width:240px}.w-fit{width:-moz-fit-content;width:fit-content}.w-full{width:100%}.min-w-0{min-width:0px}.max-w-4xl{max-width:56rem}.max-w-\[340px\]{max-width:340px}.max-w-\[60\%\]{max-width:60%}.max-w-\[94vw\]{max-width:94vw}.max-w-lg{max-width:32rem}.max-w-md{max-width:28rem}.max-w-xs{max-width:20rem}.flex-1{flex:1 1 0%}.flex-shrink-0,.shrink-0{flex-shrink:0}.-translate-x-1\/2{--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-rotate-90{--tw-rotate: -90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.list-inside{list-style-position:inside}.list-disc{list-style-type:disc}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.items-baseline{align-items:baseline}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0{gap:0px}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-2\.5{gap:.625rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-x-4{-moz-column-gap:1rem;column-gap:1rem}.gap-y-2{row-gap:.5rem}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.5rem * var(--tw-space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--tw-space-x-reverse)))}.space-x-3>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.75rem * var(--tw-space-x-reverse));margin-left:calc(.75rem * calc(1 - var(--tw-space-x-reverse)))}.space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(1rem * var(--tw-space-x-reverse));margin-left:calc(1rem * calc(1 - var(--tw-space-x-reverse)))}.space-x-6>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(1.5rem * var(--tw-space-x-reverse));margin-left:calc(1.5rem * calc(1 - var(--tw-space-x-reverse)))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.25rem * var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.divide-base-300>:not([hidden])~:not([hidden]){border-color:var(--color-base-300)}.self-stretch{align-self:stretch}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:1rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-base-300{border-color:var(--color-base-300)}.border-primary{border-color:var(--color-primary)}.border-transparent{border-color:transparent}.bg-base-100{background-color:var(--color-base-100)}.bg-base-200{background-color:var(--color-base-200)}.bg-black{--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1))}.bg-gray-400{--tw-bg-opacity: 1;background-color:rgb(156 163 175 / var(--tw-bg-opacity, 1))}.bg-green-500{--tw-bg-opacity: 1;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))}.bg-primary{background-color:var(--color-primary)}.bg-success{background-color:var(--color-success)}.bg-warning{background-color:var(--color-warning)}.bg-yellow-500{--tw-bg-opacity: 1;background-color:rgb(234 179 8 / var(--tw-bg-opacity, 1))}.bg-opacity-50{--tw-bg-opacity: .5}.bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}.from-primary{--tw-gradient-from: var(--color-primary) var(--tw-gradient-from-position);--tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.to-accent{--tw-gradient-to: var(--color-accent) var(--tw-gradient-to-position)}.stroke-current{stroke:currentColor}.p-0{padding:0}.p-1\.5{padding:.375rem}.p-12{padding:3rem}.p-2{padding:.5rem}.p-2\.5{padding:.625rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0{padding-top:0;padding-bottom:0}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-0\.5{padding-bottom:.125rem}.pb-2\.5{padding-bottom:.625rem}.pb-24{padding-bottom:6rem}.pb-8{padding-bottom:2rem}.pl-3{padding-left:.75rem}.pl-3\.5{padding-left:.875rem}.pl-9{padding-left:2.25rem}.pl-\[4\.5rem\]{padding-left:4.5rem}.pr-3{padding-right:.75rem}.pr-4{padding-right:1rem}.pt-2\.5{padding-top:.625rem}.pt-4{padding-top:1rem}.text-left{text-align:left}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-\[13px\]{font-size:13px}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.lowercase{text-transform:lowercase}.leading-relaxed{line-height:1.625}.leading-tight{line-height:1.25}.text-accent{color:var(--color-accent)}.text-base-content{color:var(--color-base-content)}.text-error{color:var(--color-error)}.text-info{color:var(--color-info)}.text-primary{color:var(--color-primary)}.text-primary-content{color:var(--color-primary-content)}.text-secondary{color:var(--color-secondary)}.text-success{color:var(--color-success)}.text-warning{color:var(--color-warning)}.line-through{text-decoration-line:line-through}.opacity-40{opacity:.4}.opacity-80{opacity:.8}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.ring-1{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-inset{--tw-ring-inset: inset}.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)}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.glass{border:none;-webkit-backdrop-filter:blur(var(--glass-blur, 40px));backdrop-filter:blur(var(--glass-blur, 40px));background-color:#0000;background-image:linear-gradient(135deg,oklch(100% 0 0 / var(--glass-opacity, 30%)),#0000),linear-gradient(var(--glass-reflect-degree, 100deg),oklch(100% 0 0 / var(--glass-reflect-opacity, 5%)) 25%,oklch(0% 0 0 / 0%) 25%);box-shadow:0 0 0 1px oklch(100% 0 0 / var(--glass-border-opacity, 20%)) inset,0 0 0 2px #0000000d;text-shadow:0 1px oklch(0% 0 0 / var(--glass-text-shadow-opacity, 5%))}.join{display:inline-flex;align-items:stretch;--join-ss: 0;--join-se: 0;--join-es: 0;--join-ee: 0}.join :where(.join-item){border-start-start-radius:var(--join-ss, 0);border-start-end-radius:var(--join-se, 0);border-end-start-radius:var(--join-es, 0);border-end-end-radius:var(--join-ee, 0)}.join :where(.join-item) *{--join-ss: var(--radius-field);--join-se: var(--radius-field);--join-es: var(--radius-field);--join-ee: var(--radius-field)}.join>.join-item:where(:first-child){--join-ss: var(--radius-field);--join-se: 0;--join-es: var(--radius-field);--join-ee: 0}.join :first-child:not(:last-child) :where(.join-item){--join-ss: var(--radius-field);--join-se: 0;--join-es: var(--radius-field);--join-ee: 0}.join>.join-item:where(:last-child){--join-ss: 0;--join-se: var(--radius-field);--join-es: 0;--join-ee: var(--radius-field)}.join :last-child:not(:first-child) :where(.join-item){--join-ss: 0;--join-se: var(--radius-field);--join-es: 0;--join-ee: var(--radius-field)}.join>.join-item:where(:only-child){--join-ss: var(--radius-field);--join-se: var(--radius-field);--join-es: var(--radius-field);--join-ee: var(--radius-field)}.join :only-child :where(.join-item){--join-ss: var(--radius-field);--join-se: var(--radius-field);--join-es: var(--radius-field);--join-ee: var(--radius-field)}.join-item:where(*:not(:first-child,:disabled,[disabled],.btn-disabled)){margin-inline-start:calc(var(--border, 1px) * -1);margin-block-start:0}.join-item:where(*:is(:disabled,[disabled],.btn-disabled)){border-width:var(--border, 1px) 0 var(--border, 1px) var(--border, 1px)}.join-vertical>.join-item:first-child{--join-ss: var(--radius-field);--join-se: var(--radius-field);--join-es: 0;--join-ee: 0}.join-vertical :first-child:not(:last-child) .join-item{--join-ss: var(--radius-field);--join-se: var(--radius-field);--join-es: 0;--join-ee: 0}.join-vertical>.join-item:last-child{--join-ss: 0;--join-se: 0;--join-es: var(--radius-field);--join-ee: var(--radius-field)}.join-vertical :last-child:not(:first-child) .join-item{--join-ss: 0;--join-se: 0;--join-es: var(--radius-field);--join-ee: var(--radius-field)}.join-vertical>.join-item:only-child{--join-ss: var(--radius-field);--join-se: var(--radius-field);--join-es: var(--radius-field);--join-ee: var(--radius-field)}.join-vertical :only-child .join-item{--join-ss: var(--radius-field);--join-se: var(--radius-field);--join-es: var(--radius-field);--join-ee: var(--radius-field)}.join-vertical .join-item:where(*:not(:first-child)){margin-inline-start:0;margin-block-start:calc(var(--border, 1px) * -1)}.join-horizontal>.join-item:first-child{--join-ss: var(--radius-field);--join-se: 0;--join-es: var(--radius-field);--join-ee: 0}.join-horizontal :first-child:not(:last-child) .join-item{--join-ss: var(--radius-field);--join-se: 0;--join-es: var(--radius-field);--join-ee: 0}.join-horizontal>.join-item:last-child{--join-ss: 0;--join-se: var(--radius-field);--join-es: 0;--join-ee: var(--radius-field)}.join-horizontal :last-child:not(:first-child) .join-item{--join-ss: 0;--join-se: var(--radius-field);--join-es: 0;--join-ee: var(--radius-field)}.join-horizontal>.join-item:only-child{--join-ss: var(--radius-field);--join-se: var(--radius-field);--join-es: var(--radius-field);--join-ee: var(--radius-field)}.join-horizontal :only-child .join-item{--join-ss: var(--radius-field);--join-se: var(--radius-field);--join-es: var(--radius-field);--join-ee: var(--radius-field)}.join-horizontal .join-item:where(*:not(:first-child)){margin-inline-start:calc(var(--border, 1px) * -1);margin-block-start:0}.rounded-box{border-radius:var(--radius-box)}.rounded-field{border-radius:var(--radius-field)}:root,[data-theme=dark]{--color-base-100: #1e293b;--color-base-200: #0f172a;--color-base-300: #334155;--color-base-content: #f1f5f9;--color-primary: #10b981;--color-primary-content: #052e16;--color-secondary: #94a3b8;--color-secondary-content: #0f172a;--color-accent: #34d399;--color-accent-content: #052e16;--color-neutral: #1e293b;--color-neutral-content: #f1f5f9;--color-info: #3b82f6;--color-info-content: #ffffff;--color-success: #10b981;--color-success-content: #052e16;--color-warning: #f59e0b;--color-warning-content: #451a03;--color-error: #ef4444;--color-error-content: #ffffff;--radius-box: 1rem;--radius-field: .6rem;--radius-selector: .6rem;--glass-bg: rgba(30, 41, 59, .85);--glass-border: rgba(51, 65, 85, .9)}[data-theme=light]{--color-base-100: #ffffff;--color-base-200: #f1f5f9;--color-base-300: #e2e8f0;--color-base-content: #0f172a;--color-primary: #047857;--color-primary-content: #ffffff;--color-secondary: #475569;--color-secondary-content: #ffffff;--color-accent: #059669;--color-accent-content: #ffffff;--color-neutral: #0f172a;--color-neutral-content: #f1f5f9;--color-info: #3b82f6;--color-info-content: #ffffff;--color-success: #047857;--color-success-content: #ffffff;--color-warning: #f59e0b;--color-warning-content: #ffffff;--color-error: #ef4444;--color-error-content: #ffffff;--radius-box: 1rem;--radius-field: .6rem;--radius-selector: .6rem;--glass-bg: rgba(255, 255, 255, .8);--glass-border: rgba(226, 232, 240, .9)}body{transition:background-color .2s,color .2s}.glass{background:var(--glass-bg);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px)}.page-fade{animation:ad-fade-in .3s cubic-bezier(.4,0,.2,1)}@keyframes ad-fade-in{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}.log-terminal{background:var(--color-base-200);border:1px solid var(--color-base-300);border-radius:var(--radius-field);padding:.75rem 1rem;font-family:Consolas,Courier New,monospace;font-size:.76rem;line-height:1.7}.log-terminal .log-time{color:var(--color-base-content);opacity:.45}.log-terminal .log-info{color:var(--color-info)}.log-terminal .log-ok{color:var(--color-success)}.log-terminal .log-err{color:var(--color-error)}.log-terminal .log-warn{color:var(--color-warning)}.last\:border-0:last-child{border-width:0px}.hover\:border-primary:hover{border-color:var(--color-primary)}.hover\:bg-base-100:hover{background-color:var(--color-base-100)}.hover\:bg-base-200:hover{background-color:var(--color-base-200)}.hover\:text-base-content:hover{color:var(--color-base-content)}.hover\:text-error:hover{color:var(--color-error)}@media (min-width: 640px){.sm\:block{display:block}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}}@media (min-width: 768px){.md\:col-span-1{grid-column:span 1 / span 1}.md\:col-span-2{grid-column:span 2 / span 2}.md\:flex{display:flex}.md\:hidden{display:none}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:pb-6{padding-bottom:1.5rem}}@media (min-width: 1024px){.lg\:gap-6{gap:1.5rem}.lg\:p-6{padding:1.5rem}.lg\:px-6{padding-left:1.5rem;padding-right:1.5rem}.lg\:px-8{padding-left:2rem;padding-right:2rem}}@media (min-width: 1280px){.xl\:flex{display:flex}.xl\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.xl\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}
|