+8
.env.example
+8
.env.example
-76
Caddyfile
-76
Caddyfile
···
1
-
{
2
-
storage file_system /data/
3
-
debug
4
-
pki {
5
-
ca hayden {
6
-
name "Hayden"
7
-
}
8
-
}
9
-
}
10
-
11
-
api.dev.hayden.moe {
12
-
tls {
13
-
issuer internal {
14
-
ca hayden
15
-
}
16
-
}
17
-
18
-
reverse_proxy http://host.docker.internal:8080
19
-
}
20
-
21
-
cookware.dev.hayden.moe {
22
-
tls {
23
-
issuer internal {
24
-
ca hayden
25
-
}
26
-
}
27
-
28
-
reverse_proxy http://host.docker.internal:5173
29
-
30
-
handle_path /xrpc/* {
31
-
rewrite * /xrpc{uri}
32
-
reverse_proxy http://host.docker.internal:8080
33
-
}
34
-
handle_path /api/* {
35
-
rewrite * /api{uri}
36
-
reverse_proxy http://host.docker.internal:8080
37
-
}
38
-
}
39
-
40
-
http://*.trycloudflare.com {
41
-
reverse_proxy http://host.docker.internal:5173
42
-
43
-
handle_path /xrpc/* {
44
-
rewrite * /xrpc{uri}
45
-
reverse_proxy http://host.docker.internal:8080
46
-
}
47
-
handle_path /oauth/* {
48
-
rewrite * /oauth{uri}
49
-
reverse_proxy http://host.docker.internal:8080
50
-
}
51
-
handle_path /api/* {
52
-
rewrite * /api{uri}
53
-
reverse_proxy http://host.docker.internal:8080
54
-
}
55
-
}
56
-
57
-
acme.dev.hayden.moe {
58
-
tls {
59
-
issuer internal {
60
-
ca hayden
61
-
}
62
-
}
63
-
acme_server {
64
-
ca hayden
65
-
}
66
-
}
67
-
68
-
turso.dev.hayden.moe {
69
-
tls {
70
-
issuer internal {
71
-
ca hayden
72
-
}
73
-
}
74
-
75
-
reverse_proxy http://libsql:8080
76
-
}
+36
-7
README.md
+36
-7
README.md
···
10
10
11
11
## Requirements
12
12
13
-
- Node.js 22.x LTS
14
-
- [pnpm](https://pnpm.io)
15
-
- A [Turso](https://turso.tech) database
16
-
- Maybe Docker?
13
+
- [Bun](https://bun.sh) 1.3.3+
14
+
- Docker & Docker Compose (for local dev)
17
15
18
16
## Services
19
17
20
-
- [`api`](./apps/api): Runs the API server and hosts the SPA in production
21
-
- [`ingester`](./apps/ingester): Ingests ATProto records from a Jetstream source independently of the API process.
22
-
- [`web`](./apps/web): React SPA, hosted by the API in production.
18
+
- [`api`](./apps/api): Bun server running the XRPC API
19
+
- [`ingester`](./apps/ingester): Ingests ATProto records from Jetstream
20
+
- [`web`](./apps/web): React SPA frontend
21
+
- `libsql`: LibSQL database server
22
+
23
+
## Development
24
+
25
+
1. Copy `.env.example` to `.env`:
26
+
```bash
27
+
cp .env.example .env
28
+
```
29
+
30
+
2. Start LibSQL:
31
+
```bash
32
+
docker compose up -d libsql
33
+
```
34
+
35
+
3. Run migrations:
36
+
```bash
37
+
bun run db:generate # generate migration files
38
+
bun run db:migrate # apply to database
39
+
```
40
+
41
+
4. Start services:
42
+
```bash
43
+
bun run dev # starts all services in dev mode
44
+
```
45
+
46
+
## Production
47
+
48
+
Build and run with Docker:
49
+
```bash
50
+
docker compose up -d
51
+
```
-3
apps/api/Dockerfile
-3
apps/api/Dockerfile
+18
-47
apps/api/package.json
+18
-47
apps/api/package.json
···
1
1
{
2
-
"name": "@cookware/api",
3
2
"type": "module",
3
+
"name": "@cookware/api",
4
4
"private": true,
5
-
"main": "dist/index.js",
6
-
"publishConfig": {
7
-
"access": "public"
8
-
},
9
5
"scripts": {
10
-
"dev": "NODE_OPTIONS=--use-openssl-ca tsx watch --clear-screen=false src/index.ts | pino-pretty",
11
-
"build": "tsup",
12
-
"start": "NODE_OPTIONS=--use-openssl-ca node dist/index.cjs",
6
+
"build": "bun --bun run check-types && bun --bun run compile",
7
+
"dev": "bun run --hot src/index.ts | pino-pretty",
8
+
"check-types": "tsc --noEmit",
9
+
"compile": "bun build src/index.ts --compile --minify --sourcemap --outfile=dist/api --target=bun",
13
10
"clean": "rimraf dist"
14
11
},
15
12
"dependencies": {
16
-
"@atcute/client": "^2.0.6",
17
-
"@atproto/api": "^0.13.19",
18
-
"@atproto/common": "^0.4.5",
19
-
"@atproto/crypto": "^0.4.2",
20
-
"@atproto/jwk-jose": "^0.1.2",
21
-
"@atproto/oauth-client-node": "^0.2.3",
13
+
"@atcute/atproto": "^3.1.9",
14
+
"@atcute/client": "catalog:",
15
+
"@atcute/identity": "^1.1.3",
16
+
"@atcute/identity-resolver": "^1.1.4",
17
+
"@atcute/lexicons": "catalog:",
18
+
"@atcute/xrpc-server": "^0.1.3",
22
19
"@cookware/database": "workspace:*",
23
20
"@cookware/lexicons": "workspace:*",
24
-
"@hono/node-server": "^1.13.7",
25
21
"@libsql/client": "^0.14.0",
26
-
"@sentry/node": "^8.42.0",
27
-
"@skyware/jetstream": "^0.2.1",
28
-
"bufferutil": "^4.0.8",
29
-
"drizzle-orm": "^0.37.0",
30
-
"hono": "^4.6.12",
31
-
"hono-sessions": "^0.7.0",
32
-
"jose": "^5.9.6",
33
-
"pino": "^9.5.0",
34
-
"uint8arrays": "^5.1.0",
35
-
"ws": "^8.18.0",
36
-
"zod": "^3.23.8"
22
+
"drizzle-orm": "catalog:",
23
+
"hono": "^4.10.7",
24
+
"pino": "^9.5.0"
37
25
},
38
26
"devDependencies": {
39
-
"@atcute/bluesky": "^1.0.9",
27
+
"@atcute/bluesky": "^3.2.10",
40
28
"@cookware/tsconfig": "workspace:*",
41
-
"@swc/core": "^1.9.3",
42
-
"@types/node": "^22.10.1",
43
-
"@types/ws": "^8.5.13",
29
+
"@types/bun": "catalog:",
44
30
"drizzle-kit": "^0.29.0",
45
-
"pino-pretty": "^13.0.0",
46
-
"rimraf": "^6.0.1",
47
-
"ts-node": "^10.9.2",
48
-
"tsup": "^8.3.5",
49
-
"tsx": "^4.19.2",
50
-
"typescript": "^5.7.2"
51
-
},
52
-
"tsup": {
53
-
"entry": [
54
-
"src",
55
-
"!src/**/__tests__/**",
56
-
"!src/**/*.test.*"
57
-
],
58
-
"splitting": false,
59
-
"sourcemap": true,
60
-
"clean": true,
61
-
"format": "esm"
31
+
"pino-pretty": "^13.1.2",
32
+
"rimraf": "^6.0.1"
62
33
}
63
34
}
-25
apps/api/scripts/generate-jwk.ts
-25
apps/api/scripts/generate-jwk.ts
···
1
-
import { generateKeyPair } from "jose";
2
-
3
-
async function serializeKeyToJwk() {
4
-
// Generate an RSA key pair
5
-
const { publicKey, privateKey } = await generateKeyPair("ES256");
6
-
7
-
// Export keys as JWK
8
-
const publicJwk = await import("jose").then((lib) =>
9
-
lib.exportJWK(publicKey)
10
-
);
11
-
const privateJwk = await import("jose").then((lib) =>
12
-
lib.exportJWK(privateKey)
13
-
);
14
-
15
-
// Convert to JSON strings
16
-
const publicJwkString = JSON.stringify(publicJwk);
17
-
const privateJwkString = JSON.stringify(privateJwk);
18
-
19
-
// save 3 of these to PRIVATE_KEY_X env vars
20
-
console.log(privateJwkString);
21
-
22
-
return { publicJwkString, privateJwkString };
23
-
}
24
-
25
-
serializeKeyToJwk();
-34
apps/api/src/config/env.ts
-34
apps/api/src/config/env.ts
···
1
-
import { z } from "zod";
2
-
3
-
const envSchema = z.object({
4
-
PORT: z.coerce.number().lte(65535).default(8080),
5
-
HOST: z.string().ip().default('0.0.0.0'),
6
-
7
-
PUBLIC_DIR: z.string().default('../web/dist'),
8
-
9
-
CORS_ORIGINS: z
10
-
.string()
11
-
.transform((arg) => arg.split(','))
12
-
.default('http://127.0.0.1:5173,https://cookware.dev.hayden.moe'),
13
-
14
-
PLC_DIRECTORY_URL: z.string().url().default('https://plc.directory'),
15
-
16
-
JWKS_PRIVATE_KEY: z.string().default('{"kty":"EC","x":"pew2xWIyBQ4XSY4gcCuTJBI-oC5rQqQlcDxIN8nN834","y":"aiJFNEFWyKKWGiFKPRvLAU4wdhsfgysfTfTuzTC4LNQ","crv":"P-256","d":"QS-q9RzH1u2Oj8gDiUzLk1qpGxZjKSf-3Z1oKCRL_jQ"}'),
17
-
18
-
SESSION_KEY: z.string().default('bJVS+Dx03A3QWWfW3A5Om5DGx1GKptx+1IGAXzOTpw8='),
19
-
SESSION_TTL: z.number().default(((60 * 60) * 24) * 5), // expire in 5 days
20
-
21
-
SENTRY_DSN: z.string().or(z.undefined()),
22
-
23
-
ENV: z
24
-
.union([
25
-
z.literal('development'),
26
-
z.literal('production'),
27
-
])
28
-
.default('development'),
29
-
});
30
-
31
-
const env = envSchema.parse(process.env);
32
-
33
-
export default env;
34
-
export type Env = z.infer<typeof envSchema>;
+7
-2
apps/api/src/env.d.ts
+7
-2
apps/api/src/env.d.ts
+45
-84
apps/api/src/index.ts
+45
-84
apps/api/src/index.ts
···
1
-
import { serve } from "@hono/node-server";
2
-
import { Hono } from "hono";
3
-
import { rootLogger } from "./logger.js";
4
-
import env from "./config/env.js";
5
-
import { xrpcApp } from "./xrpc/index.js";
6
-
import { cors } from "hono/cors";
7
-
import { ZodError } from "zod";
8
-
import * as Sentry from "@sentry/node"
9
-
import { recipeApp } from "./recipes/index.js";
10
-
import { XRPCError } from "./util/xrpc.js";
11
-
import { getFilePathWithoutDefaultDocument } from "hono/utils/filepath";
12
-
import { readFileSync } from "fs";
1
+
import { XRPCError, XRPCRouter } from '@atcute/xrpc-server';
2
+
import { cors } from '@atcute/xrpc-server/middlewares/cors';
3
+
import { registerGetRecipes } from './xrpc/blue.recipes.feed.getRecipes.js';
4
+
import { registerGetRecipe } from './xrpc/blue.recipes.feed.getRecipe.js';
5
+
import { logMiddleware } from './logger.js';
6
+
import pino from 'pino';
7
+
import { RedisClient } from 'bun';
8
+
import { registerGetProfile } from './xrpc/blue.recipes.actor.getProfile.js';
9
+
import { Hono } from 'hono';
10
+
import { mountXrpcRouter } from './util/hono.js';
13
11
14
-
if (env.SENTRY_DSN) {
15
-
Sentry.init({
16
-
dsn: env.SENTRY_DSN,
17
-
});
18
-
}
12
+
const logger = pino();
13
+
const redis = new RedisClient(Bun.env.REDIS_URL ?? "redis://127.0.0.1:6379/0");
19
14
20
-
const app = new Hono();
21
-
22
-
app.use(cors({
23
-
origin: (origin, _ctx) => {
24
-
if (env.ENV == 'development') {
25
-
return origin;
15
+
const xrpcRouter = new XRPCRouter({
16
+
handleException: (err, _req) => {
17
+
if (err instanceof XRPCError) {
18
+
return err.toResponse();
19
+
} else if (err instanceof Response) {
20
+
return err;
21
+
} else {
22
+
logger.error({ err }, 'Exception thrown during request');
23
+
return Response.json(
24
+
{ error: 'InternalServerError', message: 'an exception happened whilst processing this request' },
25
+
{ status: 500 },
26
+
)
26
27
}
27
-
return env.CORS_ORIGINS.includes(origin)
28
-
? origin
29
-
: 'https://recipes.blue';
30
28
},
31
-
allowHeaders: ['Content-Type', 'Accept'],
32
-
allowMethods: ['POST', 'GET', 'OPTIONS'],
33
-
exposeHeaders: ['Content-Length'],
34
-
maxAge: 600,
35
-
credentials: true,
36
-
}));
37
-
38
-
app.route('/xrpc', xrpcApp);
39
-
app.route('/api/recipes', recipeApp);
40
-
41
-
app.use(async (ctx, next) => {
42
-
try {
43
-
await next();
44
-
} catch (e) {
45
-
if (e instanceof ZodError) {
46
-
ctx.status(400);
47
-
return ctx.json({
48
-
error: 'invalid_data',
49
-
message: e.message,
50
-
});
51
-
} else if (e instanceof XRPCError) {
52
-
return e.hono(ctx);
53
-
}
54
-
55
-
ctx.status(500);
56
-
return ctx.json({
57
-
error: 'internal_server_error',
58
-
message: 'The server could not process the request.',
59
-
});
60
-
}
29
+
middlewares: [
30
+
logMiddleware(logger),
31
+
cors({
32
+
allowedHeaders: ['Content-Type', 'Accept'],
33
+
exposedHeaders: ['Content-Length'],
34
+
}),
35
+
],
61
36
});
62
37
63
-
app.use('/*', async (ctx, next) => {
64
-
if (ctx.req.path == '/client-metadata.json') {
65
-
let path = getFilePathWithoutDefaultDocument({
66
-
filename: 'client-metadata.json',
67
-
root: env.PUBLIC_DIR,
68
-
});
69
-
70
-
const metadata = JSON.parse(readFileSync(`./${path}`).toString());
71
-
return ctx.json(metadata);
72
-
}
38
+
// actor
39
+
registerGetProfile(xrpcRouter, logger, redis);
73
40
74
-
if (ctx.finalized) return next();
75
-
let path = getFilePathWithoutDefaultDocument({
76
-
filename: 'index.html',
77
-
root: env.PUBLIC_DIR,
78
-
})
41
+
// feed
42
+
registerGetRecipes(xrpcRouter, logger, redis);
43
+
registerGetRecipe(xrpcRouter, logger, redis);
79
44
80
-
if (path) {
81
-
path = `./${path}`;
82
-
} else {
83
-
return next();
84
-
}
45
+
const app = new Hono();
85
46
86
-
const index = readFileSync(path).toString();
87
-
return ctx.html(index);
88
-
});
47
+
// mount xrpc router at /xrpc
48
+
const xrpcApp = new Hono();
49
+
mountXrpcRouter(xrpcApp, xrpcRouter);
50
+
app.route('/xrpc', xrpcApp);
89
51
90
-
serve({
52
+
const server = Bun.serve({
53
+
port: process.env.PORT || 4000,
91
54
fetch: app.fetch,
92
-
hostname: env.HOST,
93
-
port: env.PORT,
94
-
}).on('listening', () => {
95
-
rootLogger.info({ port: 8080, host: '0.0.0.0' }, 'Server booted.');
96
55
});
56
+
57
+
logger.info({ url: server.url.toString() }, `Recipes.blue API started up`);
+28
-4
apps/api/src/logger.ts
+28
-4
apps/api/src/logger.ts
···
1
-
import { pino } from "pino";
1
+
import type { FetchMiddleware } from "@atcute/xrpc-server";
2
+
import type { Logger } from "pino";
2
3
3
-
export const rootLogger = pino({ name: 'recipes' });
4
-
export const apiLogger = pino({ name: 'recipes.api' });
5
-
export const authLogger = pino({ name: 'recipes.auth' });
4
+
export const logMiddleware = (logger: Logger): FetchMiddleware => {
5
+
return async (req, next) => {
6
+
const startTime = new Date();
7
+
logger.setBindings({
8
+
request: {
9
+
method: req.method,
10
+
path: new URL(req.url).pathname,
11
+
id: crypto.randomUUID(),
12
+
}
13
+
});
14
+
15
+
logger.info('Request received');
16
+
17
+
const response = await next(req);
18
+
const endTime = new Date();
19
+
20
+
logger.info({
21
+
response: {
22
+
status: response.status,
23
+
durationMs: endTime.getTime() - startTime.getTime(),
24
+
},
25
+
}, 'Finished processing request');
26
+
27
+
return response;
28
+
};
29
+
};
-5
apps/api/src/recipes/index.ts
-5
apps/api/src/recipes/index.ts
+59
-25
apps/api/src/util/api.ts
+59
-25
apps/api/src/util/api.ts
···
1
-
import { XRPC } from '@atcute/client';
2
-
import type { AppBskyActorProfile, BlueRecipesFeedDefs } from '@atcute/client/lexicons';
3
-
import { DID, getDidDoc } from '@cookware/lexicons';
1
+
import type {} from '@atcute/atproto';
2
+
import { CompositeDidDocumentResolver, PlcDidDocumentResolver, WebDidDocumentResolver } from '@atcute/identity-resolver';
3
+
import { CompositeHandleResolver, DohJsonHandleResolver, WellKnownHandleResolver } from '@atcute/identity-resolver';
4
+
import { type ActorIdentifier, type AtprotoDid, type Handle, isHandle } from '@atcute/lexicons/syntax';
5
+
import { isAtprotoDid } from '@atcute/identity';
6
+
import { RedisClient } from 'bun';
7
+
import type { BlueRecipesActorDefs } from '@cookware/lexicons';
8
+
import type { Blob, LegacyBlob } from '@atcute/lexicons';
9
+
import { buildCdnUrl } from './cdn.js';
4
10
5
-
export const getAuthorInfo = async (
6
-
did: DID,
7
-
rpc: XRPC,
8
-
): Promise<BlueRecipesFeedDefs.AuthorInfo> => {
9
-
const author = await getDidDoc(did);
10
-
const profile = await rpc.get('com.atproto.repo.getRecord', {
11
-
params: {
12
-
repo: did,
13
-
collection: 'app.bsky.actor.profile',
14
-
rkey: 'self',
15
-
},
16
-
});
17
-
const data = profile.data.value as AppBskyActorProfile.Record;
11
+
const handleResolver = new CompositeHandleResolver({
12
+
strategy: 'race',
13
+
methods: {
14
+
dns: new DohJsonHandleResolver({ dohUrl: 'https://mozilla.cloudflare-dns.com/dns-query' }),
15
+
http: new WellKnownHandleResolver({ fetch }),
16
+
},
17
+
});
18
18
19
-
let info: BlueRecipesFeedDefs.AuthorInfo = {
20
-
did: did,
21
-
handle: author.alsoKnownAs[0]?.substring(5) as string,
22
-
displayName: data.displayName,
23
-
};
19
+
const didResolver = new CompositeDidDocumentResolver({
20
+
methods: {
21
+
plc: new PlcDidDocumentResolver(),
22
+
web: new WebDidDocumentResolver(),
23
+
}
24
+
});
24
25
25
-
if (data.avatar)
26
-
info['avatarUrl'] = `https://cdn.bsky.app/img/avatar_thumbnail/plain/${did}/${data.avatar.ref.$link}@jpeg`;
26
+
const HANDLE_CACHE_TTL = 5 * 60; // 5 minutes
27
+
28
+
export const parseDid = async (id: ActorIdentifier): Promise<AtprotoDid> => {
29
+
if (isAtprotoDid(id)) return id;
30
+
if (isHandle(id)) {
31
+
return await handleResolver.resolve(id);
32
+
}
33
+
throw Error("Invalid DID or Handle!");
34
+
}
27
35
28
-
return info;
29
-
};
36
+
export const getHandle = async (did: AtprotoDid, redis: RedisClient): Promise<Handle> => {
37
+
let handle = await redis.get(`handle:${did}`) as Handle | null;
38
+
if (!handle) {
39
+
const didDoc = await didResolver.resolve(did);
40
+
if (didDoc.alsoKnownAs == null || didDoc.alsoKnownAs.length < 1) {
41
+
throw new Error(`User ${did} had no resolvable DID document.`);
42
+
}
43
+
handle = didDoc.alsoKnownAs[0]!.substring(5) as Handle;
44
+
redis.setex(`handle:${did}`, HANDLE_CACHE_TTL, handle);
45
+
}
46
+
47
+
return handle;
48
+
}
49
+
50
+
export const buildProfileViewBasic = async (author: {
51
+
did: AtprotoDid;
52
+
displayName: string;
53
+
pronouns: string | null;
54
+
avatarRef: Blob | LegacyBlob | null;
55
+
createdAt: Date;
56
+
}, redis: RedisClient): Promise<BlueRecipesActorDefs.ProfileViewBasic> => ({
57
+
did: author.did,
58
+
handle: await getHandle(author.did, redis),
59
+
displayName: author.displayName,
60
+
pronouns: author.pronouns ?? undefined,
61
+
avatar: author.avatarRef ? buildCdnUrl('avatar', author.did, author.avatarRef) : undefined,
62
+
createdAt: author.createdAt.toISOString(),
63
+
});
+21
apps/api/src/util/cdn.ts
+21
apps/api/src/util/cdn.ts
···
1
+
import { type Blob, type LegacyBlob } from "@atcute/lexicons";
2
+
import { isBlob, isLegacyBlob } from "@atcute/lexicons/interfaces";
3
+
4
+
const CDN_ROOT = "https://cdn.bsky.app/img/";
5
+
6
+
export const buildCdnUrl = (
7
+
type: 'feed_thumbnail' | 'post_image' | 'avatar',
8
+
did: string,
9
+
blob: Blob | LegacyBlob,
10
+
): string => {
11
+
let ref: string;
12
+
if (isLegacyBlob(blob)) {
13
+
ref = blob.cid;
14
+
} else if (isBlob(blob)) {
15
+
ref = blob.ref.$link;
16
+
} else {
17
+
throw new Error("Invalid blob type");
18
+
}
19
+
20
+
return `${CDN_ROOT}${type}/plain/${did}/${ref}`;
21
+
}
+40
apps/api/src/util/hono.ts
+40
apps/api/src/util/hono.ts
···
1
+
import { XRPCRouter } from '@atcute/xrpc-server';
2
+
import type { Context, Hono } from 'hono';
3
+
4
+
export type ApiContext = {};
5
+
6
+
/**
7
+
* mounts an @atcute/xrpc-server router into hono as a nested route
8
+
*
9
+
* basically just bridges the two request handlers since both are
10
+
* web standard Request/Response. you can optionally pass hono context
11
+
* properties to xrpc handlers via the request object
12
+
*/
13
+
export const mountXrpcRouter = (
14
+
app: Hono,
15
+
router: XRPCRouter,
16
+
injectContext?: (c: Context) => ApiContext,
17
+
) => {
18
+
app.all('*', async (c) => {
19
+
let request = c.req.raw;
20
+
21
+
// if context injector provided, attach properties to request
22
+
if (injectContext) {
23
+
const contextData = injectContext(c);
24
+
request = Object.assign(request, contextData);
25
+
}
26
+
27
+
const response = await router.fetch(request);
28
+
return response;
29
+
});
30
+
};
31
+
32
+
/**
33
+
* helper to extract injected context from xrpc request
34
+
* use this in your xrpc handlers to access hono context data
35
+
*/
36
+
export const getInjectedContext = (
37
+
request: Request
38
+
): ApiContext => {
39
+
return request as any as ApiContext;
40
+
};
-229
apps/api/src/util/jwt.ts
-229
apps/api/src/util/jwt.ts
···
1
-
import * as common from "@atproto/common";
2
-
import { MINUTE } from "@atproto/common";
3
-
import * as crypto from "@atproto/crypto";
4
-
import * as ui8 from "uint8arrays";
5
-
import { XRPCError } from "./xrpc.js";
6
-
import { z } from "zod";
7
-
8
-
export const jwt = z.custom<`${string}.${string}.${string}`>((input) => {
9
-
if (typeof input !== "string") return;
10
-
if (input.split(".").length !== 3) return false;
11
-
return true;
12
-
});
13
-
14
-
type ServiceJwtParams = {
15
-
iss: string;
16
-
aud: string;
17
-
iat?: number;
18
-
exp?: number;
19
-
lxm: string | null;
20
-
keypair: crypto.Keypair;
21
-
};
22
-
23
-
type ServiceJwtHeaders = {
24
-
alg: string;
25
-
} & Record<string, unknown>;
26
-
27
-
type ServiceJwtPayload = {
28
-
iss: string;
29
-
aud: string;
30
-
exp: number;
31
-
lxm?: string;
32
-
jti?: string;
33
-
};
34
-
35
-
export const createServiceJwt = async (
36
-
params: ServiceJwtParams,
37
-
): Promise<string> => {
38
-
const { iss, aud, keypair } = params;
39
-
const iat = params.iat ?? Math.floor(Date.now() / 1e3);
40
-
const exp = params.exp ?? iat + MINUTE / 1e3;
41
-
const lxm = params.lxm ?? undefined;
42
-
const jti = crypto.randomStr(16, "hex");
43
-
const header = {
44
-
typ: "JWT",
45
-
alg: keypair.jwtAlg,
46
-
};
47
-
const payload = common.noUndefinedVals({
48
-
iat,
49
-
iss,
50
-
aud,
51
-
exp,
52
-
lxm,
53
-
jti,
54
-
});
55
-
const toSignStr = `${jsonToB64Url(header)}.${jsonToB64Url(payload)}`;
56
-
const toSign = ui8.fromString(toSignStr, "utf8");
57
-
const sig = await keypair.sign(toSign);
58
-
return `${toSignStr}.${ui8.toString(sig, "base64url")}`;
59
-
};
60
-
61
-
export const createServiceAuthHeaders = async (params: ServiceJwtParams) => {
62
-
const jwt = await createServiceJwt(params);
63
-
return {
64
-
headers: { authorization: `Bearer ${jwt}` },
65
-
};
66
-
};
67
-
68
-
const jsonToB64Url = (json: Record<string, unknown>): string => {
69
-
return common.utf8ToB64Url(JSON.stringify(json));
70
-
};
71
-
72
-
export type VerifySignatureWithKeyFn = (
73
-
key: string,
74
-
msgBytes: Uint8Array,
75
-
sigBytes: Uint8Array,
76
-
alg: string,
77
-
) => Promise<boolean>;
78
-
79
-
export const verifyJwt = async (
80
-
jwtStr: string,
81
-
ownDid: string | null, // null indicates to skip the audience check
82
-
lxm: string | null, // null indicates to skip the lxm check
83
-
getSigningKey: (iss: string, forceRefresh: boolean) => Promise<string>,
84
-
verifySignatureWithKey: VerifySignatureWithKeyFn = cryptoVerifySignatureWithKey,
85
-
): Promise<ServiceJwtPayload> => {
86
-
const jwtParsed = jwt.safeParse(jwtStr);
87
-
if (!jwtParsed.success) {
88
-
throw new XRPCError("poorly formatted jwt", "BadJwt", 401);
89
-
}
90
-
const parts = jwtParsed.data.split(".");
91
-
92
-
const header = parseHeader(parts[0]!);
93
-
94
-
// The spec does not describe what to do with the "typ" claim. We can,
95
-
// however, forbid some values that are not compatible with our use case.
96
-
if (
97
-
// service tokens are not OAuth 2.0 access tokens
98
-
// https://datatracker.ietf.org/doc/html/rfc9068
99
-
header["typ"] === "at+jwt" ||
100
-
// "refresh+jwt" is a non-standard type used by the @atproto packages
101
-
header["typ"] === "refresh+jwt" ||
102
-
// "DPoP" proofs are not meant to be used as service tokens
103
-
// https://datatracker.ietf.org/doc/html/rfc9449
104
-
header["typ"] === "dpop+jwt"
105
-
) {
106
-
throw new XRPCError(
107
-
`Invalid jwt type "${header["typ"]}"`,
108
-
"BadJwtType",
109
-
401,
110
-
);
111
-
}
112
-
113
-
const payload = parsePayload(parts[1]!);
114
-
const sig = parts[2]!;
115
-
116
-
if (Date.now() / 1000 > payload.exp) {
117
-
throw new XRPCError("jwt expired", "JwtExpired", 401);
118
-
}
119
-
if (ownDid !== null && payload.aud !== ownDid) {
120
-
throw new XRPCError(
121
-
"jwt audience does not match service did",
122
-
"BadJwtAudience",
123
-
401,
124
-
);
125
-
}
126
-
if (lxm !== null && payload.lxm !== lxm) {
127
-
throw new XRPCError(
128
-
payload.lxm !== undefined
129
-
? `bad jwt lexicon method ("lxm"). must match: ${lxm}`
130
-
: `missing jwt lexicon method ("lxm"). must match: ${lxm}`,
131
-
"BadJwtLexiconMethod",
132
-
401,
133
-
);
134
-
}
135
-
136
-
const msgBytes = ui8.fromString(parts.slice(0, 2).join("."), "utf8");
137
-
const sigBytes = ui8.fromString(sig, "base64url");
138
-
139
-
const signingKey = await getSigningKey(payload.iss, false);
140
-
const { alg } = header;
141
-
142
-
let validSig: boolean;
143
-
try {
144
-
validSig = await verifySignatureWithKey(
145
-
signingKey,
146
-
msgBytes,
147
-
sigBytes,
148
-
alg,
149
-
);
150
-
} catch (err) {
151
-
throw new XRPCError(
152
-
"could not verify jwt signature",
153
-
"BadJwtSignature",
154
-
401,
155
-
);
156
-
}
157
-
158
-
if (!validSig) {
159
-
// get fresh signing key in case it failed due to a recent rotation
160
-
const freshSigningKey = await getSigningKey(payload.iss, true);
161
-
try {
162
-
validSig =
163
-
freshSigningKey !== signingKey
164
-
? await verifySignatureWithKey(
165
-
freshSigningKey,
166
-
msgBytes,
167
-
sigBytes,
168
-
alg,
169
-
)
170
-
: false;
171
-
} catch (err) {
172
-
throw new XRPCError(
173
-
"could not verify jwt signature",
174
-
"BadJwtSignature",
175
-
401,
176
-
);
177
-
}
178
-
}
179
-
180
-
if (!validSig) {
181
-
throw new XRPCError(
182
-
"jwt signature does not match jwt issuer",
183
-
"BadJwtSignature",
184
-
401,
185
-
);
186
-
}
187
-
188
-
return payload;
189
-
};
190
-
191
-
export const cryptoVerifySignatureWithKey: VerifySignatureWithKeyFn = async (
192
-
key: string,
193
-
msgBytes: Uint8Array,
194
-
sigBytes: Uint8Array,
195
-
alg: string,
196
-
) => {
197
-
return crypto.verifySignature(key, msgBytes, sigBytes, {
198
-
jwtAlg: alg,
199
-
allowMalleableSig: true,
200
-
});
201
-
};
202
-
203
-
const parseB64UrlToJson = (b64: string) => {
204
-
return JSON.parse(common.b64UrlToUtf8(b64));
205
-
};
206
-
207
-
const parseHeader = (b64: string): ServiceJwtHeaders => {
208
-
const header = parseB64UrlToJson(b64);
209
-
if (!header || typeof header !== "object" || typeof header.alg !== "string") {
210
-
throw new XRPCError("poorly formatted jwt", "BadJwt", 401);
211
-
}
212
-
return header;
213
-
};
214
-
215
-
const parsePayload = (b64: string): ServiceJwtPayload => {
216
-
const payload = parseB64UrlToJson(b64);
217
-
if (
218
-
!payload ||
219
-
typeof payload !== "object" ||
220
-
typeof payload.iss !== "string" ||
221
-
typeof payload.aud !== "string" ||
222
-
typeof payload.exp !== "number" ||
223
-
(payload.lxm && typeof payload.lxm !== "string") ||
224
-
(payload.nonce && typeof payload.nonce !== "string")
225
-
) {
226
-
throw new XRPCError("poorly formatted jwt", "BadJwt", 401);
227
-
}
228
-
return payload;
229
-
};
-20
apps/api/src/util/xrpc.ts
-20
apps/api/src/util/xrpc.ts
···
1
-
import { Context } from "hono";
2
-
import { StatusCode } from "hono/utils/http-status";
3
-
4
-
export class XRPCError extends Error {
5
-
constructor(
6
-
message: string,
7
-
public error: string,
8
-
public code: StatusCode,
9
-
) {
10
-
super(message);
11
-
}
12
-
13
-
hono(ctx: Context) {
14
-
ctx.status(this.code);
15
-
return ctx.json({
16
-
error: this.error,
17
-
message: this.message,
18
-
});
19
-
}
20
-
}
+44
apps/api/src/xrpc/blue.recipes.actor.getProfile.ts
+44
apps/api/src/xrpc/blue.recipes.actor.getProfile.ts
···
1
+
import { json, XRPCRouter, XRPCError } from '@atcute/xrpc-server';
2
+
import { BlueRecipesActorGetProfile } from '@cookware/lexicons';
3
+
import { db, eq } from '@cookware/database';
4
+
import { getHandle, parseDid } from '../util/api.js';
5
+
import { type Logger } from 'pino';
6
+
import { profilesTable, recipeTable } from '@cookware/database/schema';
7
+
import { RedisClient } from 'bun';
8
+
import { buildCdnUrl } from '../util/cdn.js';
9
+
10
+
export const registerGetProfile = (router: XRPCRouter, _logger: Logger, redis: RedisClient) => {
11
+
router.addQuery(BlueRecipesActorGetProfile.mainSchema, {
12
+
async handler({ params: { actor } }) {
13
+
const where = eq(profilesTable.did, await parseDid(actor));
14
+
const profile = await db.query.profilesTable.findFirst({
15
+
where,
16
+
orderBy: profilesTable.createdAt,
17
+
extras: {
18
+
recipesCount: db.$count(recipeTable, where).as('recipesCount'),
19
+
}
20
+
});
21
+
22
+
if (!profile) {
23
+
throw new XRPCError({
24
+
status: 404,
25
+
error: 'ProfileNotFound',
26
+
description: `Profile for actor ${actor} not found.`,
27
+
});
28
+
}
29
+
30
+
return json({
31
+
did: profile.did,
32
+
handle: await getHandle(profile.did, redis),
33
+
displayName: profile.displayName ?? undefined,
34
+
description: profile.description ?? undefined,
35
+
pronouns: profile.pronouns ?? undefined,
36
+
website: profile.website ?? undefined,
37
+
avatar: profile.avatarRef ? buildCdnUrl('avatar', profile.did, profile.avatarRef) : undefined,
38
+
banner: profile.bannerRef ? buildCdnUrl('feed_thumbnail', profile.did, profile.bannerRef) : undefined,
39
+
recipesCount: profile.recipesCount,
40
+
createdAt: profile.createdAt.toISOString(),
41
+
});
42
+
},
43
+
});
44
+
};
+78
apps/api/src/xrpc/blue.recipes.feed.getRecipe.ts
+78
apps/api/src/xrpc/blue.recipes.feed.getRecipe.ts
···
1
+
import { json, XRPCRouter, XRPCError } from '@atcute/xrpc-server';
2
+
import { BlueRecipesFeedGetRecipe, BlueRecipesFeedRecipe } from '@cookware/lexicons';
3
+
import { db, and, or, eq } from '@cookware/database';
4
+
import { buildProfileViewBasic, parseDid } from '../util/api.js';
5
+
import { type Logger } from 'pino';
6
+
import { parseResourceUri, type ResourceUri } from '@atcute/lexicons';
7
+
import { recipeTable } from '@cookware/database/schema';
8
+
import { isLegacyBlob } from '@atcute/lexicons/interfaces';
9
+
import { RedisClient } from 'bun';
10
+
import { buildCdnUrl } from '../util/cdn.js';
11
+
12
+
const invalidUriError = (uri: string) => new XRPCError({
13
+
status: 400,
14
+
error: 'InvalidURI',
15
+
description: `The provided URI is invalid: ${uri}`,
16
+
});
17
+
18
+
export const registerGetRecipe = (router: XRPCRouter, _logger: Logger, redis: RedisClient) => {
19
+
router.addQuery(BlueRecipesFeedGetRecipe.mainSchema, {
20
+
async handler({ params: { uris } }) {
21
+
const whereClauses = [];
22
+
23
+
for (const uri of uris) {
24
+
const parsed = parseResourceUri(uri);
25
+
if (!parsed.ok) throw invalidUriError(uri);
26
+
27
+
const { repo, collection, rkey } = parsed.value;
28
+
if (!repo) throw invalidUriError(uri);
29
+
if (collection !== BlueRecipesFeedRecipe.mainSchema.object.shape.$type.expected) throw invalidUriError(uri);
30
+
if (!rkey) throw invalidUriError(uri);
31
+
32
+
const did = await parseDid(repo);
33
+
34
+
whereClauses.push(and(eq(recipeTable.did, did), eq(recipeTable.rkey, rkey)));
35
+
}
36
+
37
+
const recipes = await db.query.recipeTable.findMany({
38
+
orderBy: recipeTable.createdAt,
39
+
where: or(...whereClauses),
40
+
with: {
41
+
author: {
42
+
columns: {
43
+
did: true,
44
+
displayName: true,
45
+
pronouns: true,
46
+
avatarRef: true,
47
+
createdAt: true,
48
+
},
49
+
},
50
+
},
51
+
});
52
+
53
+
return json({
54
+
recipes: await Promise.all(
55
+
recipes.map(async ({ author, ...recipe }) => ({
56
+
uri: recipe.uri as ResourceUri,
57
+
author: await buildProfileViewBasic(author, redis),
58
+
cid: recipe.cid,
59
+
rkey: recipe.rkey,
60
+
imageUrl: recipe.imageRef ? buildCdnUrl('post_image', recipe.did, recipe.imageRef) : undefined,
61
+
indexedAt: recipe.ingestedAt.toISOString(),
62
+
record: {
63
+
$type: BlueRecipesFeedRecipe.mainSchema.object.shape.$type.expected,
64
+
title: recipe.title,
65
+
description: recipe.description ?? undefined,
66
+
time: recipe.time ?? undefined,
67
+
serves: recipe.serves ?? undefined,
68
+
ingredients: recipe.ingredients as BlueRecipesFeedRecipe.Ingredient[],
69
+
steps: recipe.steps as BlueRecipesFeedRecipe.Step[],
70
+
image: isLegacyBlob(recipe.imageRef) ? undefined : recipe.imageRef ?? undefined,
71
+
createdAt: recipe.createdAt.toISOString(),
72
+
},
73
+
})),
74
+
),
75
+
});
76
+
},
77
+
});
78
+
};
+79
apps/api/src/xrpc/blue.recipes.feed.getRecipes.ts
+79
apps/api/src/xrpc/blue.recipes.feed.getRecipes.ts
···
1
+
import { db, and, eq } from '@cookware/database';
2
+
import { recipeTable } from '@cookware/database/schema';
3
+
import { BlueRecipesFeedGetRecipes, BlueRecipesFeedRecipe } from '@cookware/lexicons';
4
+
import { json, XRPCRouter } from '@atcute/xrpc-server';
5
+
import { getHandle, parseDid } from '../util/api.js';
6
+
import { type ResourceUri } from '@atcute/lexicons/syntax';
7
+
import { type Logger } from 'pino';
8
+
import { isLegacyBlob } from '@atcute/lexicons/interfaces';
9
+
import { RedisClient } from 'bun';
10
+
import { buildCdnUrl } from '../util/cdn.js';
11
+
12
+
export const registerGetRecipes = (router: XRPCRouter, _logger: Logger, redis: RedisClient) => {
13
+
router.addQuery(BlueRecipesFeedGetRecipes.mainSchema, {
14
+
async handler({ params: { author, limit, cursor } }) {
15
+
const whereClauses = [];
16
+
if (author) {
17
+
const did = await parseDid(author);
18
+
whereClauses.push(eq(recipeTable.did, did));
19
+
}
20
+
21
+
if (cursor) {
22
+
const { c } = JSON.parse(atob(cursor)) as { c: string };
23
+
whereClauses.push(eq(recipeTable.createdAt, new Date(c)));
24
+
}
25
+
26
+
const recipes = await db.query.recipeTable.findMany({
27
+
orderBy: recipeTable.createdAt,
28
+
limit: limit,
29
+
where: whereClauses ? and(...whereClauses) : undefined,
30
+
with: {
31
+
author: {
32
+
columns: {
33
+
did: true,
34
+
displayName: true,
35
+
pronouns: true,
36
+
avatarRef: true,
37
+
createdAt: true,
38
+
},
39
+
},
40
+
},
41
+
});
42
+
43
+
let nextCursor = '';
44
+
if (recipes.length == limit) {
45
+
const { createdAt } = recipes[limit - 1]!;
46
+
nextCursor = atob(JSON.stringify({ c: createdAt }));
47
+
}
48
+
49
+
return json({
50
+
nextCursor,
51
+
recipes: await Promise.all(recipes.map(async (recipe) => ({
52
+
author: {
53
+
did: recipe.author.did,
54
+
handle: await getHandle(recipe.author.did, redis),
55
+
displayName: recipe.author.displayName,
56
+
avatar: recipe.author.avatarRef ? buildCdnUrl('avatar', recipe.author.did, recipe.author.avatarRef) : undefined,
57
+
pronouns: recipe.author.pronouns ?? undefined,
58
+
createdAt: recipe.author.createdAt.toISOString(),
59
+
},
60
+
cid: recipe.cid,
61
+
rkey: recipe.rkey,
62
+
indexedAt: recipe.ingestedAt.toISOString(),
63
+
record: {
64
+
$type: BlueRecipesFeedRecipe.mainSchema.object.shape.$type.expected,
65
+
title: recipe.title,
66
+
description: recipe.description ?? undefined,
67
+
time: recipe.time ?? undefined,
68
+
serves: recipe.serves ?? undefined,
69
+
ingredients: recipe.ingredients as BlueRecipesFeedRecipe.Ingredient[],
70
+
steps: recipe.steps as BlueRecipesFeedRecipe.Step[],
71
+
image: isLegacyBlob(recipe.imageRef) ? undefined : recipe.imageRef ?? undefined,
72
+
createdAt: recipe.createdAt.toISOString(),
73
+
},
74
+
uri: recipe.uri as ResourceUri,
75
+
}))),
76
+
});
77
+
}
78
+
});
79
+
};
-125
apps/api/src/xrpc/index.ts
-125
apps/api/src/xrpc/index.ts
···
1
-
import { Hono } from 'hono';
2
-
import { db, recipeTable } from '@cookware/database';
3
-
import { and, desc, eq, sql } from 'drizzle-orm';
4
-
import { DID, getDidFromHandleOrDid } from '@cookware/lexicons';
5
-
import { simpleFetchHandler, XRPC } from '@atcute/client';
6
-
import { BlueRecipesFeedDefs, BlueRecipesFeedGetRecipes } from '@atcute/client/lexicons';
7
-
import { getAuthorInfo } from '../util/api.js';
8
-
9
-
export const xrpcApp = new Hono();
10
-
11
-
xrpcApp.get('/blue.recipes.feed.getRecipes', async ctx => {
12
-
const { did: didQuery } = ctx.req.query();
13
-
14
-
let did: DID | null = null;
15
-
if (didQuery)
16
-
did = await getDidFromHandleOrDid(didQuery);
17
-
18
-
const recipes = await db
19
-
.select({
20
-
rkey: recipeTable.rkey,
21
-
title: recipeTable.title,
22
-
description: recipeTable.description,
23
-
time: recipeTable.time,
24
-
serves: recipeTable.serves,
25
-
ingredientsCount: sql`json_array_length(${recipeTable.ingredients})`,
26
-
stepsCount: sql`json_array_length(${recipeTable.steps})`,
27
-
createdAt: recipeTable.createdAt,
28
-
authorDid: recipeTable.authorDid,
29
-
imageRef: recipeTable.imageRef,
30
-
uri: sql`concat(${recipeTable.authorDid}, "/", ${recipeTable.rkey})`.as('uri'),
31
-
})
32
-
.from(recipeTable)
33
-
.where(did ? eq(recipeTable.authorDid, did) : undefined)
34
-
.orderBy(desc(recipeTable.createdAt));
35
-
36
-
const rpc = new XRPC({
37
-
handler: simpleFetchHandler({
38
-
service: 'https://public.api.bsky.app',
39
-
}),
40
-
});
41
-
42
-
let authorInfo: BlueRecipesFeedDefs.AuthorInfo | null = null;
43
-
if (did) {
44
-
authorInfo = await getAuthorInfo(did, rpc);
45
-
};
46
-
47
-
const results = [];
48
-
const eachRecipe = async (r: typeof recipes[0]) => ({
49
-
author: authorInfo || await getAuthorInfo(r.authorDid, rpc),
50
-
rkey: r.rkey,
51
-
title: r.title,
52
-
time: r.time,
53
-
serves: r.serves ?? 1,
54
-
description: r.description || undefined,
55
-
ingredients: r.ingredientsCount as number,
56
-
steps: r.stepsCount as number,
57
-
imageUrl: r.imageRef
58
-
? `https://cdn.bsky.app/img/feed_thumbnail/plain/${r.authorDid}/${r.imageRef}@jpeg`
59
-
: undefined,
60
-
});
61
-
62
-
for (const result of recipes) {
63
-
results.push(await eachRecipe(result));
64
-
}
65
-
66
-
let result: BlueRecipesFeedGetRecipes.Output = {
67
-
author: authorInfo || undefined,
68
-
recipes: results,
69
-
};
70
-
71
-
return ctx.json(result);
72
-
});
73
-
74
-
xrpcApp.get('/blue.recipes.feed.getRecipe', async ctx => {
75
-
const { did, rkey } = ctx.req.query();
76
-
if (!did) throw new Error('Invalid DID');
77
-
if (!rkey) throw new Error('Invalid rkey');
78
-
79
-
let parsedDid = await getDidFromHandleOrDid(did);
80
-
if (!parsedDid) {
81
-
ctx.status(404);
82
-
return ctx.json({
83
-
error: 'invalid_did',
84
-
message: 'No such author was found by that identifier.',
85
-
});
86
-
}
87
-
88
-
const recipe = await db.query.recipeTable.findFirst({
89
-
where: and(
90
-
eq(recipeTable.authorDid, parsedDid),
91
-
eq(recipeTable.rkey, rkey),
92
-
),
93
-
});
94
-
95
-
if (!recipe) {
96
-
ctx.status(404);
97
-
return ctx.json({
98
-
error: 'not_found',
99
-
message: 'No such recipe was found in the index.',
100
-
});
101
-
}
102
-
103
-
const rpc = new XRPC({
104
-
handler: simpleFetchHandler({
105
-
service: 'https://public.api.bsky.app',
106
-
}),
107
-
});
108
-
109
-
const authorInfo = await getAuthorInfo(recipe.authorDid, rpc);
110
-
111
-
return ctx.json({
112
-
recipe: {
113
-
author: authorInfo,
114
-
title: recipe.title,
115
-
time: recipe.time,
116
-
serves: recipe.serves,
117
-
description: recipe.description,
118
-
ingredients: recipe.ingredients,
119
-
steps: recipe.steps,
120
-
imageUrl: recipe.imageRef
121
-
? `https://cdn.bsky.app/img/feed_thumbnail/plain/${recipe.authorDid}/${recipe.imageRef}@jpeg`
122
-
: null,
123
-
},
124
-
});
125
-
});
+41
apps/app/.gitignore
+41
apps/app/.gitignore
···
1
+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2
+
3
+
# dependencies
4
+
/node_modules
5
+
/.pnp
6
+
.pnp.*
7
+
.yarn/*
8
+
!.yarn/patches
9
+
!.yarn/plugins
10
+
!.yarn/releases
11
+
!.yarn/versions
12
+
13
+
# testing
14
+
/coverage
15
+
16
+
# next.js
17
+
/.next/
18
+
/out/
19
+
20
+
# production
21
+
/build
22
+
23
+
# misc
24
+
.DS_Store
25
+
*.pem
26
+
27
+
# debug
28
+
npm-debug.log*
29
+
yarn-debug.log*
30
+
yarn-error.log*
31
+
.pnpm-debug.log*
32
+
33
+
# env files (can opt-in for committing if needed)
34
+
.env*
35
+
36
+
# vercel
37
+
.vercel
38
+
39
+
# typescript
40
+
*.tsbuildinfo
41
+
next-env.d.ts
+36
apps/app/README.md
+36
apps/app/README.md
···
1
+
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
2
+
3
+
## Getting Started
4
+
5
+
First, run the development server:
6
+
7
+
```bash
8
+
npm run dev
9
+
# or
10
+
yarn dev
11
+
# or
12
+
pnpm dev
13
+
# or
14
+
bun dev
15
+
```
16
+
17
+
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
18
+
19
+
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
20
+
21
+
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
22
+
23
+
## Learn More
24
+
25
+
To learn more about Next.js, take a look at the following resources:
26
+
27
+
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
28
+
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
29
+
30
+
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
31
+
32
+
## Deploy on Vercel
33
+
34
+
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
35
+
36
+
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
+63
apps/app/app/(app)/home/home.tsx
+63
apps/app/app/(app)/home/home.tsx
···
1
+
'use client';
2
+
3
+
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
4
+
import { Input } from "@/components/ui/input";
5
+
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
6
+
import { ClockIcon } from "lucide-react";
7
+
import { Separator } from "@/components/ui/separator";
8
+
import { useGetRecipesQuery } from "@/lib/queries/recipes";
9
+
import { RecipeCard } from "@/components/views/recipe-card";
10
+
11
+
export const Home = () => {
12
+
const { data } = useGetRecipesQuery();
13
+
14
+
return (
15
+
<div className="p-4 flex flex-col gap-8">
16
+
<div className="flex flex-col gap-4 max-w-3xl items-center mx-auto py-16">
17
+
<h1 className="font-bold text-3xl">Welcome to Cookware!</h1>
18
+
<span className="text-xl">A little corner of the internet for you to share your recipes with the world.</span>
19
+
<Input placeholder="Search recipes..." className="w-full max-w-md" />
20
+
</div>
21
+
22
+
<Separator />
23
+
24
+
<h1 className="font-bold text-2xl text-center">Recently-added recipes</h1>
25
+
26
+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
27
+
28
+
{data && data.recipes.map(v => <RecipeCard key={v.cid} recipe={v} />)}
29
+
30
+
{[1, 2, 3, 4, 5, 6, 7, 8, 9].map(v => (
31
+
<Card key={v}>
32
+
<CardHeader>
33
+
<CardTitle>Featured Recipe {v}</CardTitle>
34
+
<CardDescription>A recipe to make some of the best food you've ever had!</CardDescription>
35
+
</CardHeader>
36
+
37
+
<CardContent>
38
+
<img className="rounded-md ratio-[4/3] object-cover" src="https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:26tsx5juuss4yealylyfbj4h/bafkreia4wvg2y4rr6liuffdt4ckcskf4bvdmzbfdsv3ul6t442fu4jxy6m@jpeg" />
39
+
</CardContent>
40
+
41
+
<CardFooter>
42
+
<div className="flex flex-col gap-2">
43
+
<div className="flex items-center gap-2 text-sm">
44
+
<Avatar className="!size-8">
45
+
<AvatarImage></AvatarImage>
46
+
<AvatarFallback>HM</AvatarFallback>
47
+
</Avatar>
48
+
<span>@hayden.moe</span>
49
+
</div>
50
+
51
+
<div className="flex items-center gap-2 text-sm">
52
+
<ClockIcon className="!size-4" />
53
+
<span>15 mins</span>
54
+
</div>
55
+
</div>
56
+
</CardFooter>
57
+
</Card>
58
+
))}
59
+
60
+
</div>
61
+
</div>
62
+
);
63
+
}
+18
apps/app/app/(app)/home/page.tsx
+18
apps/app/app/(app)/home/page.tsx
···
1
+
import { getRecipesOptions } from "@/lib/queries/recipes";
2
+
import { dehydrate, HydrationBoundary, QueryClient } from "@tanstack/react-query";
3
+
import { Home } from "./home";
4
+
import { Client, simpleFetchHandler } from "@atcute/client";
5
+
import { COOKWARE_API_URL } from "@/lib/consts";
6
+
7
+
export default async function HomeRoute() {
8
+
const queryClient = new QueryClient();
9
+
await queryClient.prefetchQuery(getRecipesOptions(new Client({
10
+
handler: simpleFetchHandler({ service: COOKWARE_API_URL }),
11
+
})));
12
+
13
+
return (
14
+
<HydrationBoundary state={dehydrate(queryClient)}>
15
+
<Home />
16
+
</HydrationBoundary>
17
+
);
18
+
};
+21
apps/app/app/(app)/layout.tsx
+21
apps/app/app/(app)/layout.tsx
···
1
+
import { AppSidebar } from "@/components/app-sidebar";
2
+
import { SidebarInset, SidebarProvider } from "@/components/ui/sidebar";
3
+
import { PropsWithChildren } from "react";
4
+
5
+
export default ({ children }: PropsWithChildren) => {
6
+
return (
7
+
<SidebarProvider
8
+
style={
9
+
{
10
+
"--sidebar-width": "calc(var(--spacing) * 72)",
11
+
"--header-height": "calc(var(--spacing) * 12)",
12
+
} as React.CSSProperties
13
+
}
14
+
>
15
+
<AppSidebar variant="inset" />
16
+
<SidebarInset>
17
+
{children}
18
+
</SidebarInset>
19
+
</SidebarProvider>
20
+
);
21
+
}
+5
apps/app/app/auth/layout.tsx
+5
apps/app/app/auth/layout.tsx
+97
apps/app/app/auth/login/page.tsx
+97
apps/app/app/auth/login/page.tsx
···
1
+
"use client";
2
+
3
+
import { Button } from "@/components/ui/button";
4
+
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
5
+
import { Field, FieldDescription, FieldError, FieldGroup, FieldLabel } from "@/components/ui/field";
6
+
import { InputGroup, InputGroupAddon, InputGroupInput } from "@/components/ui/input-group";
7
+
import { Separator } from "@/components/ui/separator";
8
+
import { createAuthorizationUrl, OAuthResponseError } from "@atcute/oauth-browser-client";
9
+
import { IconAt } from "@tabler/icons-react";
10
+
import Link from "next/link";
11
+
import { FormEvent, useState } from "react";
12
+
import { isActorIdentifier } from "@atcute/lexicons/syntax";
13
+
14
+
export default () => {
15
+
const [handle, setHandle] = useState('');
16
+
const [error, setError] = useState<string | null>(null);
17
+
18
+
const submit = async (e: FormEvent) => {
19
+
e.preventDefault();
20
+
21
+
if (!isActorIdentifier(handle)) {
22
+
setError('Invalid handle or DID.');
23
+
return;
24
+
}
25
+
26
+
try {
27
+
const authUrl = await createAuthorizationUrl({
28
+
target: { type: 'account', identifier: handle },
29
+
scope: 'atproto transition:generic',
30
+
});
31
+
32
+
setTimeout(() => {
33
+
window.location.assign(authUrl);
34
+
}, 200);
35
+
} catch (e) {
36
+
if (e instanceof OAuthResponseError) {
37
+
setError(e.message);
38
+
return;
39
+
}
40
+
console.error(e);
41
+
setError('Something went wrong, try again later.');
42
+
}
43
+
};
44
+
45
+
return (
46
+
<div className="min-h-screen min-w-screen flex flex-col p-4 items-center justify-center">
47
+
<Card className="max-w-sm w-full">
48
+
<CardHeader>
49
+
<CardTitle>Sign in to Cookware</CardTitle>
50
+
<CardDescription>Enter your ATProto/Bluesky handle to log in or sign up.</CardDescription>
51
+
</CardHeader>
52
+
53
+
<CardContent>
54
+
<form onSubmit={submit}>
55
+
<FieldGroup>
56
+
<Field>
57
+
<FieldLabel htmlFor="login_handle">Handle</FieldLabel>
58
+
<InputGroup>
59
+
<InputGroupInput
60
+
name="handle"
61
+
id="login_handle"
62
+
placeholder="john.doe"
63
+
autoFocus
64
+
aria-invalid={false}
65
+
tabIndex={1}
66
+
value={handle}
67
+
onChange={(e) => {
68
+
e.preventDefault();
69
+
setHandle(e.currentTarget.value);
70
+
}}
71
+
/>
72
+
<InputGroupAddon><IconAt /></InputGroupAddon>
73
+
</InputGroup>
74
+
<FieldDescription>This is the username you use to log in to sites like Bluesky and Leaflet.</FieldDescription>
75
+
{error && <FieldError>{error}</FieldError>}
76
+
</Field>
77
+
<Field>
78
+
<Button
79
+
type="submit"
80
+
tabIndex={2}
81
+
>
82
+
Sign in
83
+
</Button>
84
+
</Field>
85
+
</FieldGroup>
86
+
<Separator className="my-4" />
87
+
<FieldDescription>
88
+
<span>
89
+
Don't have an account? <Link className="text-bluesky underline" href="https://bsky.app">Sign up on Bluesky!</Link>
90
+
</span>
91
+
</FieldDescription>
92
+
</form>
93
+
</CardContent>
94
+
</Card>
95
+
</div>
96
+
);
97
+
};
+132
apps/app/app/auth/signup/page.tsx
+132
apps/app/app/auth/signup/page.tsx
···
1
+
"use client";
2
+
3
+
import { Button } from "@/components/ui/button";
4
+
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
5
+
import { Field, FieldDescription, FieldError, FieldGroup, FieldLabel } from "@/components/ui/field";
6
+
import { FormEvent, useState } from "react";
7
+
import { useAuth } from "@/lib/state/auth";
8
+
import { redirect } from "next/navigation";
9
+
import { Input } from "@/components/ui/input";
10
+
import { Textarea } from "@/components/ui/textarea";
11
+
import { BlueRecipesActorProfile } from "@cookware/lexicons";
12
+
import { parse } from "@atcute/lexicons/validations";
13
+
14
+
export default () => {
15
+
const auth = useAuth();
16
+
const [displayName, setHandle] = useState('');
17
+
const [bio, setBio] = useState('');
18
+
const [pronouns, setPronouns] = useState('');
19
+
const [error, setError] = useState<string | null>(null);
20
+
21
+
if (!auth.loggedIn) throw redirect('/auth/login');
22
+
if (auth.profile.exists) throw redirect('/home');
23
+
24
+
const submit = async (e: FormEvent) => {
25
+
e.preventDefault();
26
+
27
+
const res = await auth.pdsClient.post('com.atproto.repo.putRecord', {
28
+
input: {
29
+
rkey: 'self',
30
+
repo: auth.actorDid,
31
+
collection: BlueRecipesActorProfile.mainSchema.object.shape.$type.expected,
32
+
record: parse(BlueRecipesActorProfile.mainSchema, {
33
+
$type: BlueRecipesActorProfile.mainSchema.object.shape.$type.expected,
34
+
displayName: displayName,
35
+
description: bio,
36
+
pronouns: pronouns,
37
+
}),
38
+
}
39
+
});
40
+
41
+
if (!res.ok) {
42
+
setError(res.data.error);
43
+
return;
44
+
}
45
+
46
+
throw redirect('/home');
47
+
};
48
+
49
+
return (
50
+
<div className="min-h-screen min-w-screen flex flex-col p-4 items-center justify-center">
51
+
<Card className="max-w-sm w-full">
52
+
<CardHeader>
53
+
<CardTitle>Finish setting up your profile</CardTitle>
54
+
<CardDescription>You've logged in, but now tell us about yourself before you start sharing foodie tidbits with the world.</CardDescription>
55
+
</CardHeader>
56
+
57
+
<CardContent>
58
+
<form onSubmit={submit}>
59
+
<FieldGroup>
60
+
<Field>
61
+
<FieldLabel htmlFor="signup_displayname">Display name</FieldLabel>
62
+
<Input
63
+
name="displayName"
64
+
id="signup_displayname"
65
+
placeholder="Cookery Master"
66
+
autoFocus
67
+
aria-invalid={false}
68
+
tabIndex={1}
69
+
value={displayName}
70
+
onChange={(e) => {
71
+
e.preventDefault();
72
+
setHandle(e.currentTarget.value);
73
+
}}
74
+
/>
75
+
<FieldDescription>What should we call you?</FieldDescription>
76
+
{error && <FieldError>{error}</FieldError>}
77
+
</Field>
78
+
79
+
<Field>
80
+
<FieldLabel htmlFor="signup_bio">
81
+
Your bio
82
+
<span className="text-muted-foreground">(optional)</span>
83
+
</FieldLabel>
84
+
<Textarea
85
+
name="bio"
86
+
id="signup_bio"
87
+
placeholder="I'm a chef from the UK, and I love..."
88
+
aria-invalid={false}
89
+
tabIndex={2}
90
+
value={bio}
91
+
onChange={(e) => {
92
+
e.preventDefault();
93
+
setBio(e.currentTarget.value);
94
+
}}
95
+
/>
96
+
{error && <FieldError>{error}</FieldError>}
97
+
</Field>
98
+
99
+
<Field>
100
+
<FieldLabel htmlFor="signup_pronouns">
101
+
Your pronouns
102
+
<span className="text-muted-foreground">(optional)</span>
103
+
</FieldLabel>
104
+
<Input
105
+
name="pronouns"
106
+
id="signup_pronouns"
107
+
aria-invalid={false}
108
+
tabIndex={3}
109
+
value={pronouns}
110
+
onChange={(e) => {
111
+
e.preventDefault();
112
+
setPronouns(e.currentTarget.value);
113
+
}}
114
+
/>
115
+
{error && <FieldError>{error}</FieldError>}
116
+
</Field>
117
+
118
+
<Field>
119
+
<Button
120
+
type="submit"
121
+
tabIndex={2}
122
+
>
123
+
Continue
124
+
</Button>
125
+
</Field>
126
+
</FieldGroup>
127
+
</form>
128
+
</CardContent>
129
+
</Card>
130
+
</div>
131
+
);
132
+
};
apps/app/app/favicon.ico
apps/app/app/favicon.ico
This is a binary file and will not be displayed.
+126
apps/app/app/globals.css
+126
apps/app/app/globals.css
···
1
+
@import "tailwindcss";
2
+
@import "tw-animate-css";
3
+
4
+
@custom-variant dark (&:is(.dark *));
5
+
6
+
@theme inline {
7
+
--color-background: var(--background);
8
+
--color-foreground: var(--foreground);
9
+
--font-sans: var(--font-geist-sans);
10
+
--font-mono: var(--font-geist-mono);
11
+
--color-sidebar-ring: var(--sidebar-ring);
12
+
--color-sidebar-border: var(--sidebar-border);
13
+
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
14
+
--color-sidebar-accent: var(--sidebar-accent);
15
+
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
16
+
--color-sidebar-primary: var(--sidebar-primary);
17
+
--color-sidebar-foreground: var(--sidebar-foreground);
18
+
--color-sidebar: var(--sidebar);
19
+
--color-chart-5: var(--chart-5);
20
+
--color-chart-4: var(--chart-4);
21
+
--color-chart-3: var(--chart-3);
22
+
--color-chart-2: var(--chart-2);
23
+
--color-chart-1: var(--chart-1);
24
+
--color-ring: var(--ring);
25
+
--color-input: var(--input);
26
+
--color-border: var(--border);
27
+
--color-destructive: var(--destructive);
28
+
--color-accent-foreground: var(--accent-foreground);
29
+
--color-accent: var(--accent);
30
+
--color-muted-foreground: var(--muted-foreground);
31
+
--color-muted: var(--muted);
32
+
--color-secondary-foreground: var(--secondary-foreground);
33
+
--color-secondary: var(--secondary);
34
+
--color-primary-foreground: var(--primary-foreground);
35
+
--color-primary: var(--primary);
36
+
--color-popover-foreground: var(--popover-foreground);
37
+
--color-popover: var(--popover);
38
+
--color-card-foreground: var(--card-foreground);
39
+
--color-card: var(--card);
40
+
--color-bluesky: var(--bluesky);
41
+
--color-bluesky-foreground: var(--bluesky-foreground);
42
+
--radius-sm: calc(var(--radius) - 4px);
43
+
--radius-md: calc(var(--radius) - 2px);
44
+
--radius-lg: var(--radius);
45
+
--radius-xl: calc(var(--radius) + 4px);
46
+
}
47
+
48
+
:root {
49
+
--radius: 0.625rem;
50
+
--background: oklch(1 0 0);
51
+
--foreground: oklch(0.141 0.005 285.823);
52
+
--card: oklch(1 0 0);
53
+
--card-foreground: oklch(0.141 0.005 285.823);
54
+
--popover: oklch(1 0 0);
55
+
--popover-foreground: oklch(0.141 0.005 285.823);
56
+
--primary: oklch(0.21 0.006 285.885);
57
+
--primary-foreground: oklch(0.985 0 0);
58
+
--secondary: oklch(0.967 0.001 286.375);
59
+
--secondary-foreground: oklch(0.21 0.006 285.885);
60
+
--muted: oklch(0.967 0.001 286.375);
61
+
--muted-foreground: oklch(0.552 0.016 285.938);
62
+
--accent: oklch(0.967 0.001 286.375);
63
+
--accent-foreground: oklch(0.21 0.006 285.885);
64
+
--destructive: oklch(0.577 0.245 27.325);
65
+
--border: oklch(0.92 0.004 286.32);
66
+
--input: oklch(0.92 0.004 286.32);
67
+
--ring: oklch(0.705 0.015 286.067);
68
+
--bluesky: oklch(0.6462 0.1927 254.47);
69
+
--bluesky-foreground: oklch(1 0 0);
70
+
--chart-1: oklch(0.646 0.222 41.116);
71
+
--chart-2: oklch(0.6 0.118 184.704);
72
+
--chart-3: oklch(0.398 0.07 227.392);
73
+
--chart-4: oklch(0.828 0.189 84.429);
74
+
--chart-5: oklch(0.769 0.188 70.08);
75
+
--sidebar: oklch(0.985 0 0);
76
+
--sidebar-foreground: oklch(0.141 0.005 285.823);
77
+
--sidebar-primary: oklch(0.21 0.006 285.885);
78
+
--sidebar-primary-foreground: oklch(0.985 0 0);
79
+
--sidebar-accent: oklch(0.967 0.001 286.375);
80
+
--sidebar-accent-foreground: oklch(0.21 0.006 285.885);
81
+
--sidebar-border: oklch(0.92 0.004 286.32);
82
+
--sidebar-ring: oklch(0.705 0.015 286.067);
83
+
}
84
+
85
+
.dark {
86
+
--background: oklch(0.141 0.005 285.823);
87
+
--foreground: oklch(0.985 0 0);
88
+
--card: oklch(0.21 0.006 285.885);
89
+
--card-foreground: oklch(0.985 0 0);
90
+
--popover: oklch(0.21 0.006 285.885);
91
+
--popover-foreground: oklch(0.985 0 0);
92
+
--primary: oklch(0.92 0.004 286.32);
93
+
--primary-foreground: oklch(0.21 0.006 285.885);
94
+
--secondary: oklch(0.274 0.006 286.033);
95
+
--secondary-foreground: oklch(0.985 0 0);
96
+
--muted: oklch(0.274 0.006 286.033);
97
+
--muted-foreground: oklch(0.705 0.015 286.067);
98
+
--accent: oklch(0.274 0.006 286.033);
99
+
--accent-foreground: oklch(0.985 0 0);
100
+
--destructive: oklch(0.704 0.191 22.216);
101
+
--border: oklch(1 0 0 / 10%);
102
+
--input: oklch(1 0 0 / 15%);
103
+
--ring: oklch(0.552 0.016 285.938);
104
+
--chart-1: oklch(0.488 0.243 264.376);
105
+
--chart-2: oklch(0.696 0.17 162.48);
106
+
--chart-3: oklch(0.769 0.188 70.08);
107
+
--chart-4: oklch(0.627 0.265 303.9);
108
+
--chart-5: oklch(0.645 0.246 16.439);
109
+
--sidebar: oklch(0.21 0.006 285.885);
110
+
--sidebar-foreground: oklch(0.985 0 0);
111
+
--sidebar-primary: oklch(0.488 0.243 264.376);
112
+
--sidebar-primary-foreground: oklch(0.985 0 0);
113
+
--sidebar-accent: oklch(0.274 0.006 286.033);
114
+
--sidebar-accent-foreground: oklch(0.985 0 0);
115
+
--sidebar-border: oklch(1 0 0 / 10%);
116
+
--sidebar-ring: oklch(0.552 0.016 285.938);
117
+
}
118
+
119
+
@layer base {
120
+
* {
121
+
@apply border-border outline-ring/50;
122
+
}
123
+
body {
124
+
@apply bg-background text-foreground;
125
+
}
126
+
}
+37
apps/app/app/layout.tsx
+37
apps/app/app/layout.tsx
···
1
+
import type { Metadata } from "next";
2
+
import { Noto_Sans } from "next/font/google";
3
+
import Providers from './providers'
4
+
import "./globals.css";
5
+
6
+
const notoSans = Noto_Sans({
7
+
variable: "--font-noto-sans",
8
+
display: "swap",
9
+
subsets: ["latin"],
10
+
});
11
+
12
+
export const metadata: Metadata = {
13
+
title: "Cookware",
14
+
description: "tiny social platform for cooking and recipe sharing",
15
+
metadataBase: new URL("https://cookware.social"),
16
+
appleWebApp: {
17
+
title: "Cookware",
18
+
statusBarStyle: "black-translucent",
19
+
capable: true,
20
+
},
21
+
};
22
+
23
+
export default function RootLayout({
24
+
children,
25
+
}: Readonly<{
26
+
children: React.ReactNode;
27
+
}>) {
28
+
return (
29
+
<html lang="en" className={`${notoSans.variable}`}>
30
+
<body className="antialiased bg-sidebar text-foreground">
31
+
<Providers>
32
+
{children}
33
+
</Providers>
34
+
</body>
35
+
</html>
36
+
);
37
+
}
+20
apps/app/app/manifest.json
+20
apps/app/app/manifest.json
···
1
+
{
2
+
"name": "Cookware",
3
+
"id": "cookware",
4
+
"description": "An app to manage and share your recipes with the world.",
5
+
"short_name": "Cookware",
6
+
"start_url": "/home",
7
+
"shortcuts": [
8
+
{
9
+
"name": "New Recipe",
10
+
"url": "/recipes/new"
11
+
},
12
+
{
13
+
"name": "New Cookbook",
14
+
"url": "/books/new"
15
+
}
16
+
],
17
+
"theme_color": "#FFFFFF",
18
+
"background_color": "#FFFFFF",
19
+
"display": "standalone"
20
+
}
+9
apps/app/app/not-found.tsx
+9
apps/app/app/not-found.tsx
+43
apps/app/app/providers.tsx
+43
apps/app/app/providers.tsx
···
1
+
'use client';
2
+
3
+
import { isServer, QueryClient, QueryClientProvider } from "@tanstack/react-query";
4
+
import { PropsWithChildren } from "react";
5
+
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
6
+
import { ClientProvider } from "@/lib/state/query-provider";
7
+
import { AuthProvider } from "@/lib/state/auth";
8
+
9
+
const makeQueryClient = () => {
10
+
return new QueryClient({
11
+
defaultOptions: {
12
+
queries: {
13
+
staleTime: 60 * 1000, // 1 minute
14
+
},
15
+
}
16
+
});
17
+
};
18
+
19
+
let browserQueryClient: QueryClient | undefined = undefined;
20
+
21
+
const getQueryClient = () => {
22
+
if (isServer) {
23
+
return makeQueryClient();
24
+
} else {
25
+
if (!browserQueryClient) browserQueryClient = makeQueryClient();
26
+
return browserQueryClient;
27
+
}
28
+
};
29
+
30
+
export default ({ children }: PropsWithChildren) => {
31
+
const queryClient = getQueryClient();
32
+
33
+
return (
34
+
<ClientProvider>
35
+
<AuthProvider>
36
+
<QueryClientProvider client={queryClient}>
37
+
{children}
38
+
<ReactQueryDevtools />
39
+
</QueryClientProvider>
40
+
</AuthProvider>
41
+
</ClientProvider>
42
+
);
43
+
}
+8
apps/app/app/route.tsx
+8
apps/app/app/route.tsx
+53
apps/app/components/ui/avatar.tsx
+53
apps/app/components/ui/avatar.tsx
···
1
+
"use client"
2
+
3
+
import * as React from "react"
4
+
import * as AvatarPrimitive from "@radix-ui/react-avatar"
5
+
6
+
import { cn } from "@/lib/utils"
7
+
8
+
function Avatar({
9
+
className,
10
+
...props
11
+
}: React.ComponentProps<typeof AvatarPrimitive.Root>) {
12
+
return (
13
+
<AvatarPrimitive.Root
14
+
data-slot="avatar"
15
+
className={cn(
16
+
"relative flex size-8 shrink-0 overflow-hidden rounded-full",
17
+
className
18
+
)}
19
+
{...props}
20
+
/>
21
+
)
22
+
}
23
+
24
+
function AvatarImage({
25
+
className,
26
+
...props
27
+
}: React.ComponentProps<typeof AvatarPrimitive.Image>) {
28
+
return (
29
+
<AvatarPrimitive.Image
30
+
data-slot="avatar-image"
31
+
className={cn("aspect-square size-full", className)}
32
+
{...props}
33
+
/>
34
+
)
35
+
}
36
+
37
+
function AvatarFallback({
38
+
className,
39
+
...props
40
+
}: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {
41
+
return (
42
+
<AvatarPrimitive.Fallback
43
+
data-slot="avatar-fallback"
44
+
className={cn(
45
+
"bg-muted flex size-full items-center justify-center rounded-full",
46
+
className
47
+
)}
48
+
{...props}
49
+
/>
50
+
)
51
+
}
52
+
53
+
export { Avatar, AvatarImage, AvatarFallback }
+92
apps/app/components/ui/card.tsx
+92
apps/app/components/ui/card.tsx
···
1
+
import * as React from "react"
2
+
3
+
import { cn } from "@/lib/utils"
4
+
5
+
function Card({ className, ...props }: React.ComponentProps<"div">) {
6
+
return (
7
+
<div
8
+
data-slot="card"
9
+
className={cn(
10
+
"bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm",
11
+
className
12
+
)}
13
+
{...props}
14
+
/>
15
+
)
16
+
}
17
+
18
+
function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
19
+
return (
20
+
<div
21
+
data-slot="card-header"
22
+
className={cn(
23
+
"@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6",
24
+
className
25
+
)}
26
+
{...props}
27
+
/>
28
+
)
29
+
}
30
+
31
+
function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
32
+
return (
33
+
<div
34
+
data-slot="card-title"
35
+
className={cn("leading-none font-semibold", className)}
36
+
{...props}
37
+
/>
38
+
)
39
+
}
40
+
41
+
function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
42
+
return (
43
+
<div
44
+
data-slot="card-description"
45
+
className={cn("text-muted-foreground text-sm", className)}
46
+
{...props}
47
+
/>
48
+
)
49
+
}
50
+
51
+
function CardAction({ className, ...props }: React.ComponentProps<"div">) {
52
+
return (
53
+
<div
54
+
data-slot="card-action"
55
+
className={cn(
56
+
"col-start-2 row-span-2 row-start-1 self-start justify-self-end",
57
+
className
58
+
)}
59
+
{...props}
60
+
/>
61
+
)
62
+
}
63
+
64
+
function CardContent({ className, ...props }: React.ComponentProps<"div">) {
65
+
return (
66
+
<div
67
+
data-slot="card-content"
68
+
className={cn("px-6", className)}
69
+
{...props}
70
+
/>
71
+
)
72
+
}
73
+
74
+
function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
75
+
return (
76
+
<div
77
+
data-slot="card-footer"
78
+
className={cn("flex items-center px-6 [.border-t]:pt-6", className)}
79
+
{...props}
80
+
/>
81
+
)
82
+
}
83
+
84
+
export {
85
+
Card,
86
+
CardHeader,
87
+
CardFooter,
88
+
CardTitle,
89
+
CardAction,
90
+
CardDescription,
91
+
CardContent,
92
+
}
+248
apps/app/components/ui/field.tsx
+248
apps/app/components/ui/field.tsx
···
1
+
"use client"
2
+
3
+
import { useMemo } from "react"
4
+
import { cva, type VariantProps } from "class-variance-authority"
5
+
6
+
import { cn } from "@/lib/utils"
7
+
import { Label } from "@/components/ui/label"
8
+
import { Separator } from "@/components/ui/separator"
9
+
10
+
function FieldSet({ className, ...props }: React.ComponentProps<"fieldset">) {
11
+
return (
12
+
<fieldset
13
+
data-slot="field-set"
14
+
className={cn(
15
+
"flex flex-col gap-6",
16
+
"has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3",
17
+
className
18
+
)}
19
+
{...props}
20
+
/>
21
+
)
22
+
}
23
+
24
+
function FieldLegend({
25
+
className,
26
+
variant = "legend",
27
+
...props
28
+
}: React.ComponentProps<"legend"> & { variant?: "legend" | "label" }) {
29
+
return (
30
+
<legend
31
+
data-slot="field-legend"
32
+
data-variant={variant}
33
+
className={cn(
34
+
"mb-3 font-medium",
35
+
"data-[variant=legend]:text-base",
36
+
"data-[variant=label]:text-sm",
37
+
className
38
+
)}
39
+
{...props}
40
+
/>
41
+
)
42
+
}
43
+
44
+
function FieldGroup({ className, ...props }: React.ComponentProps<"div">) {
45
+
return (
46
+
<div
47
+
data-slot="field-group"
48
+
className={cn(
49
+
"group/field-group @container/field-group flex w-full flex-col gap-7 data-[slot=checkbox-group]:gap-3 [&>[data-slot=field-group]]:gap-4",
50
+
className
51
+
)}
52
+
{...props}
53
+
/>
54
+
)
55
+
}
56
+
57
+
const fieldVariants = cva(
58
+
"group/field flex w-full gap-3 data-[invalid=true]:text-destructive",
59
+
{
60
+
variants: {
61
+
orientation: {
62
+
vertical: ["flex-col [&>*]:w-full [&>.sr-only]:w-auto"],
63
+
horizontal: [
64
+
"flex-row items-center",
65
+
"[&>[data-slot=field-label]]:flex-auto",
66
+
"has-[>[data-slot=field-content]]:items-start has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px",
67
+
],
68
+
responsive: [
69
+
"flex-col [&>*]:w-full [&>.sr-only]:w-auto @md/field-group:flex-row @md/field-group:items-center @md/field-group:[&>*]:w-auto",
70
+
"@md/field-group:[&>[data-slot=field-label]]:flex-auto",
71
+
"@md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px",
72
+
],
73
+
},
74
+
},
75
+
defaultVariants: {
76
+
orientation: "vertical",
77
+
},
78
+
}
79
+
)
80
+
81
+
function Field({
82
+
className,
83
+
orientation = "vertical",
84
+
...props
85
+
}: React.ComponentProps<"div"> & VariantProps<typeof fieldVariants>) {
86
+
return (
87
+
<div
88
+
role="group"
89
+
data-slot="field"
90
+
data-orientation={orientation}
91
+
className={cn(fieldVariants({ orientation }), className)}
92
+
{...props}
93
+
/>
94
+
)
95
+
}
96
+
97
+
function FieldContent({ className, ...props }: React.ComponentProps<"div">) {
98
+
return (
99
+
<div
100
+
data-slot="field-content"
101
+
className={cn(
102
+
"group/field-content flex flex-1 flex-col gap-1.5 leading-snug",
103
+
className
104
+
)}
105
+
{...props}
106
+
/>
107
+
)
108
+
}
109
+
110
+
function FieldLabel({
111
+
className,
112
+
...props
113
+
}: React.ComponentProps<typeof Label>) {
114
+
return (
115
+
<Label
116
+
data-slot="field-label"
117
+
className={cn(
118
+
"group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50",
119
+
"has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col has-[>[data-slot=field]]:rounded-md has-[>[data-slot=field]]:border [&>*]:data-[slot=field]:p-4",
120
+
"has-data-[state=checked]:bg-primary/5 has-data-[state=checked]:border-primary dark:has-data-[state=checked]:bg-primary/10",
121
+
className
122
+
)}
123
+
{...props}
124
+
/>
125
+
)
126
+
}
127
+
128
+
function FieldTitle({ className, ...props }: React.ComponentProps<"div">) {
129
+
return (
130
+
<div
131
+
data-slot="field-label"
132
+
className={cn(
133
+
"flex w-fit items-center gap-2 text-sm leading-snug font-medium group-data-[disabled=true]/field:opacity-50",
134
+
className
135
+
)}
136
+
{...props}
137
+
/>
138
+
)
139
+
}
140
+
141
+
function FieldDescription({ className, ...props }: React.ComponentProps<"p">) {
142
+
return (
143
+
<p
144
+
data-slot="field-description"
145
+
className={cn(
146
+
"text-muted-foreground text-sm leading-normal font-normal group-has-[[data-orientation=horizontal]]/field:text-balance",
147
+
"last:mt-0 nth-last-2:-mt-1 [[data-variant=legend]+&]:-mt-1.5",
148
+
"[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4",
149
+
className
150
+
)}
151
+
{...props}
152
+
/>
153
+
)
154
+
}
155
+
156
+
function FieldSeparator({
157
+
children,
158
+
className,
159
+
...props
160
+
}: React.ComponentProps<"div"> & {
161
+
children?: React.ReactNode
162
+
}) {
163
+
return (
164
+
<div
165
+
data-slot="field-separator"
166
+
data-content={!!children}
167
+
className={cn(
168
+
"relative -my-2 h-5 text-sm group-data-[variant=outline]/field-group:-mb-2",
169
+
className
170
+
)}
171
+
{...props}
172
+
>
173
+
<Separator className="absolute inset-0 top-1/2" />
174
+
{children && (
175
+
<span
176
+
className="bg-background text-muted-foreground relative mx-auto block w-fit px-2"
177
+
data-slot="field-separator-content"
178
+
>
179
+
{children}
180
+
</span>
181
+
)}
182
+
</div>
183
+
)
184
+
}
185
+
186
+
function FieldError({
187
+
className,
188
+
children,
189
+
errors,
190
+
...props
191
+
}: React.ComponentProps<"div"> & {
192
+
errors?: Array<{ message?: string } | undefined>
193
+
}) {
194
+
const content = useMemo(() => {
195
+
if (children) {
196
+
return children
197
+
}
198
+
199
+
if (!errors?.length) {
200
+
return null
201
+
}
202
+
203
+
const uniqueErrors = [
204
+
...new Map(errors.map((error) => [error?.message, error])).values(),
205
+
]
206
+
207
+
if (uniqueErrors?.length == 1) {
208
+
return uniqueErrors[0]?.message
209
+
}
210
+
211
+
return (
212
+
<ul className="ml-4 flex list-disc flex-col gap-1">
213
+
{uniqueErrors.map(
214
+
(error, index) =>
215
+
error?.message && <li key={index}>{error.message}</li>
216
+
)}
217
+
</ul>
218
+
)
219
+
}, [children, errors])
220
+
221
+
if (!content) {
222
+
return null
223
+
}
224
+
225
+
return (
226
+
<div
227
+
role="alert"
228
+
data-slot="field-error"
229
+
className={cn("text-destructive text-sm font-normal", className)}
230
+
{...props}
231
+
>
232
+
{content}
233
+
</div>
234
+
)
235
+
}
236
+
237
+
export {
238
+
Field,
239
+
FieldLabel,
240
+
FieldDescription,
241
+
FieldError,
242
+
FieldGroup,
243
+
FieldLegend,
244
+
FieldSeparator,
245
+
FieldSet,
246
+
FieldContent,
247
+
FieldTitle,
248
+
}
+170
apps/app/components/ui/input-group.tsx
+170
apps/app/components/ui/input-group.tsx
···
1
+
"use client"
2
+
3
+
import * as React from "react"
4
+
import { cva, type VariantProps } from "class-variance-authority"
5
+
6
+
import { cn } from "@/lib/utils"
7
+
import { Button } from "@/components/ui/button"
8
+
import { Input } from "@/components/ui/input"
9
+
import { Textarea } from "@/components/ui/textarea"
10
+
11
+
function InputGroup({ className, ...props }: React.ComponentProps<"div">) {
12
+
return (
13
+
<div
14
+
data-slot="input-group"
15
+
role="group"
16
+
className={cn(
17
+
"group/input-group border-input dark:bg-input/30 relative flex w-full items-center rounded-md border shadow-xs transition-[color,box-shadow] outline-none",
18
+
"h-9 min-w-0 has-[>textarea]:h-auto",
19
+
20
+
// Variants based on alignment.
21
+
"has-[>[data-align=inline-start]]:[&>input]:pl-2",
22
+
"has-[>[data-align=inline-end]]:[&>input]:pr-2",
23
+
"has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-start]]:[&>input]:pb-3",
24
+
"has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-3",
25
+
26
+
// Focus state.
27
+
"has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot=input-group-control]:focus-visible]:ring-[3px]",
28
+
29
+
// Error state.
30
+
"has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[[data-slot][aria-invalid=true]]:border-destructive dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40",
31
+
32
+
className
33
+
)}
34
+
{...props}
35
+
/>
36
+
)
37
+
}
38
+
39
+
const inputGroupAddonVariants = cva(
40
+
"text-muted-foreground flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium select-none [&>svg:not([class*='size-'])]:size-4 [&>kbd]:rounded-[calc(var(--radius)-5px)] group-data-[disabled=true]/input-group:opacity-50",
41
+
{
42
+
variants: {
43
+
align: {
44
+
"inline-start":
45
+
"order-first pl-3 has-[>button]:ml-[-0.45rem] has-[>kbd]:ml-[-0.35rem]",
46
+
"inline-end":
47
+
"order-last pr-3 has-[>button]:mr-[-0.45rem] has-[>kbd]:mr-[-0.35rem]",
48
+
"block-start":
49
+
"order-first w-full justify-start px-3 pt-3 [.border-b]:pb-3 group-has-[>input]/input-group:pt-2.5",
50
+
"block-end":
51
+
"order-last w-full justify-start px-3 pb-3 [.border-t]:pt-3 group-has-[>input]/input-group:pb-2.5",
52
+
},
53
+
},
54
+
defaultVariants: {
55
+
align: "inline-start",
56
+
},
57
+
}
58
+
)
59
+
60
+
function InputGroupAddon({
61
+
className,
62
+
align = "inline-start",
63
+
...props
64
+
}: React.ComponentProps<"div"> & VariantProps<typeof inputGroupAddonVariants>) {
65
+
return (
66
+
<div
67
+
role="group"
68
+
data-slot="input-group-addon"
69
+
data-align={align}
70
+
className={cn(inputGroupAddonVariants({ align }), className)}
71
+
onClick={(e) => {
72
+
if ((e.target as HTMLElement).closest("button")) {
73
+
return
74
+
}
75
+
e.currentTarget.parentElement?.querySelector("input")?.focus()
76
+
}}
77
+
{...props}
78
+
/>
79
+
)
80
+
}
81
+
82
+
const inputGroupButtonVariants = cva(
83
+
"text-sm shadow-none flex gap-2 items-center",
84
+
{
85
+
variants: {
86
+
size: {
87
+
xs: "h-6 gap-1 px-2 rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-3.5 has-[>svg]:px-2",
88
+
sm: "h-8 px-2.5 gap-1.5 rounded-md has-[>svg]:px-2.5",
89
+
"icon-xs":
90
+
"size-6 rounded-[calc(var(--radius)-5px)] p-0 has-[>svg]:p-0",
91
+
"icon-sm": "size-8 p-0 has-[>svg]:p-0",
92
+
},
93
+
},
94
+
defaultVariants: {
95
+
size: "xs",
96
+
},
97
+
}
98
+
)
99
+
100
+
function InputGroupButton({
101
+
className,
102
+
type = "button",
103
+
variant = "ghost",
104
+
size = "xs",
105
+
...props
106
+
}: Omit<React.ComponentProps<typeof Button>, "size"> &
107
+
VariantProps<typeof inputGroupButtonVariants>) {
108
+
return (
109
+
<Button
110
+
type={type}
111
+
data-size={size}
112
+
variant={variant}
113
+
className={cn(inputGroupButtonVariants({ size }), className)}
114
+
{...props}
115
+
/>
116
+
)
117
+
}
118
+
119
+
function InputGroupText({ className, ...props }: React.ComponentProps<"span">) {
120
+
return (
121
+
<span
122
+
className={cn(
123
+
"text-muted-foreground flex items-center gap-2 text-sm [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4",
124
+
className
125
+
)}
126
+
{...props}
127
+
/>
128
+
)
129
+
}
130
+
131
+
function InputGroupInput({
132
+
className,
133
+
...props
134
+
}: React.ComponentProps<"input">) {
135
+
return (
136
+
<Input
137
+
data-slot="input-group-control"
138
+
className={cn(
139
+
"flex-1 rounded-none border-0 bg-transparent shadow-none focus-visible:ring-0 dark:bg-transparent",
140
+
className
141
+
)}
142
+
{...props}
143
+
/>
144
+
)
145
+
}
146
+
147
+
function InputGroupTextarea({
148
+
className,
149
+
...props
150
+
}: React.ComponentProps<"textarea">) {
151
+
return (
152
+
<Textarea
153
+
data-slot="input-group-control"
154
+
className={cn(
155
+
"flex-1 resize-none rounded-none border-0 bg-transparent py-3 shadow-none focus-visible:ring-0 dark:bg-transparent",
156
+
className
157
+
)}
158
+
{...props}
159
+
/>
160
+
)
161
+
}
162
+
163
+
export {
164
+
InputGroup,
165
+
InputGroupAddon,
166
+
InputGroupButton,
167
+
InputGroupText,
168
+
InputGroupInput,
169
+
InputGroupTextarea,
170
+
}
+21
apps/app/components/ui/input.tsx
+21
apps/app/components/ui/input.tsx
···
1
+
import * as React from "react"
2
+
3
+
import { cn } from "@/lib/utils"
4
+
5
+
function Input({ className, type, ...props }: React.ComponentProps<"input">) {
6
+
return (
7
+
<input
8
+
type={type}
9
+
data-slot="input"
10
+
className={cn(
11
+
"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
12
+
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
13
+
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
14
+
className
15
+
)}
16
+
{...props}
17
+
/>
18
+
)
19
+
}
20
+
21
+
export { Input }
+24
apps/app/components/ui/label.tsx
+24
apps/app/components/ui/label.tsx
···
1
+
"use client"
2
+
3
+
import * as React from "react"
4
+
import * as LabelPrimitive from "@radix-ui/react-label"
5
+
6
+
import { cn } from "@/lib/utils"
7
+
8
+
function Label({
9
+
className,
10
+
...props
11
+
}: React.ComponentProps<typeof LabelPrimitive.Root>) {
12
+
return (
13
+
<LabelPrimitive.Root
14
+
data-slot="label"
15
+
className={cn(
16
+
"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
17
+
className
18
+
)}
19
+
{...props}
20
+
/>
21
+
)
22
+
}
23
+
24
+
export { Label }
+28
apps/app/components/ui/separator.tsx
+28
apps/app/components/ui/separator.tsx
···
1
+
"use client"
2
+
3
+
import * as React from "react"
4
+
import * as SeparatorPrimitive from "@radix-ui/react-separator"
5
+
6
+
import { cn } from "@/lib/utils"
7
+
8
+
function Separator({
9
+
className,
10
+
orientation = "horizontal",
11
+
decorative = true,
12
+
...props
13
+
}: React.ComponentProps<typeof SeparatorPrimitive.Root>) {
14
+
return (
15
+
<SeparatorPrimitive.Root
16
+
data-slot="separator"
17
+
decorative={decorative}
18
+
orientation={orientation}
19
+
className={cn(
20
+
"bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
21
+
className
22
+
)}
23
+
{...props}
24
+
/>
25
+
)
26
+
}
27
+
28
+
export { Separator }
+139
apps/app/components/ui/sheet.tsx
+139
apps/app/components/ui/sheet.tsx
···
1
+
"use client"
2
+
3
+
import * as React from "react"
4
+
import * as SheetPrimitive from "@radix-ui/react-dialog"
5
+
import { XIcon } from "lucide-react"
6
+
7
+
import { cn } from "@/lib/utils"
8
+
9
+
function Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {
10
+
return <SheetPrimitive.Root data-slot="sheet" {...props} />
11
+
}
12
+
13
+
function SheetTrigger({
14
+
...props
15
+
}: React.ComponentProps<typeof SheetPrimitive.Trigger>) {
16
+
return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />
17
+
}
18
+
19
+
function SheetClose({
20
+
...props
21
+
}: React.ComponentProps<typeof SheetPrimitive.Close>) {
22
+
return <SheetPrimitive.Close data-slot="sheet-close" {...props} />
23
+
}
24
+
25
+
function SheetPortal({
26
+
...props
27
+
}: React.ComponentProps<typeof SheetPrimitive.Portal>) {
28
+
return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />
29
+
}
30
+
31
+
function SheetOverlay({
32
+
className,
33
+
...props
34
+
}: React.ComponentProps<typeof SheetPrimitive.Overlay>) {
35
+
return (
36
+
<SheetPrimitive.Overlay
37
+
data-slot="sheet-overlay"
38
+
className={cn(
39
+
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
40
+
className
41
+
)}
42
+
{...props}
43
+
/>
44
+
)
45
+
}
46
+
47
+
function SheetContent({
48
+
className,
49
+
children,
50
+
side = "right",
51
+
...props
52
+
}: React.ComponentProps<typeof SheetPrimitive.Content> & {
53
+
side?: "top" | "right" | "bottom" | "left"
54
+
}) {
55
+
return (
56
+
<SheetPortal>
57
+
<SheetOverlay />
58
+
<SheetPrimitive.Content
59
+
data-slot="sheet-content"
60
+
className={cn(
61
+
"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
62
+
side === "right" &&
63
+
"data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm",
64
+
side === "left" &&
65
+
"data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm",
66
+
side === "top" &&
67
+
"data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b",
68
+
side === "bottom" &&
69
+
"data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t",
70
+
className
71
+
)}
72
+
{...props}
73
+
>
74
+
{children}
75
+
<SheetPrimitive.Close className="ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none">
76
+
<XIcon className="size-4" />
77
+
<span className="sr-only">Close</span>
78
+
</SheetPrimitive.Close>
79
+
</SheetPrimitive.Content>
80
+
</SheetPortal>
81
+
)
82
+
}
83
+
84
+
function SheetHeader({ className, ...props }: React.ComponentProps<"div">) {
85
+
return (
86
+
<div
87
+
data-slot="sheet-header"
88
+
className={cn("flex flex-col gap-1.5 p-4", className)}
89
+
{...props}
90
+
/>
91
+
)
92
+
}
93
+
94
+
function SheetFooter({ className, ...props }: React.ComponentProps<"div">) {
95
+
return (
96
+
<div
97
+
data-slot="sheet-footer"
98
+
className={cn("mt-auto flex flex-col gap-2 p-4", className)}
99
+
{...props}
100
+
/>
101
+
)
102
+
}
103
+
104
+
function SheetTitle({
105
+
className,
106
+
...props
107
+
}: React.ComponentProps<typeof SheetPrimitive.Title>) {
108
+
return (
109
+
<SheetPrimitive.Title
110
+
data-slot="sheet-title"
111
+
className={cn("text-foreground font-semibold", className)}
112
+
{...props}
113
+
/>
114
+
)
115
+
}
116
+
117
+
function SheetDescription({
118
+
className,
119
+
...props
120
+
}: React.ComponentProps<typeof SheetPrimitive.Description>) {
121
+
return (
122
+
<SheetPrimitive.Description
123
+
data-slot="sheet-description"
124
+
className={cn("text-muted-foreground text-sm", className)}
125
+
{...props}
126
+
/>
127
+
)
128
+
}
129
+
130
+
export {
131
+
Sheet,
132
+
SheetTrigger,
133
+
SheetClose,
134
+
SheetContent,
135
+
SheetHeader,
136
+
SheetFooter,
137
+
SheetTitle,
138
+
SheetDescription,
139
+
}
+13
apps/app/components/ui/skeleton.tsx
+13
apps/app/components/ui/skeleton.tsx
···
1
+
import { cn } from "@/lib/utils"
2
+
3
+
function Skeleton({ className, ...props }: React.ComponentProps<"div">) {
4
+
return (
5
+
<div
6
+
data-slot="skeleton"
7
+
className={cn("bg-accent animate-pulse rounded-md", className)}
8
+
{...props}
9
+
/>
10
+
)
11
+
}
12
+
13
+
export { Skeleton }
+18
apps/app/components/ui/textarea.tsx
+18
apps/app/components/ui/textarea.tsx
···
1
+
import * as React from "react"
2
+
3
+
import { cn } from "@/lib/utils"
4
+
5
+
function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
6
+
return (
7
+
<textarea
8
+
data-slot="textarea"
9
+
className={cn(
10
+
"border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
11
+
className
12
+
)}
13
+
{...props}
14
+
/>
15
+
)
16
+
}
17
+
18
+
export { Textarea }
+61
apps/app/components/ui/tooltip.tsx
+61
apps/app/components/ui/tooltip.tsx
···
1
+
"use client"
2
+
3
+
import * as React from "react"
4
+
import * as TooltipPrimitive from "@radix-ui/react-tooltip"
5
+
6
+
import { cn } from "@/lib/utils"
7
+
8
+
function TooltipProvider({
9
+
delayDuration = 0,
10
+
...props
11
+
}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {
12
+
return (
13
+
<TooltipPrimitive.Provider
14
+
data-slot="tooltip-provider"
15
+
delayDuration={delayDuration}
16
+
{...props}
17
+
/>
18
+
)
19
+
}
20
+
21
+
function Tooltip({
22
+
...props
23
+
}: React.ComponentProps<typeof TooltipPrimitive.Root>) {
24
+
return (
25
+
<TooltipProvider>
26
+
<TooltipPrimitive.Root data-slot="tooltip" {...props} />
27
+
</TooltipProvider>
28
+
)
29
+
}
30
+
31
+
function TooltipTrigger({
32
+
...props
33
+
}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {
34
+
return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />
35
+
}
36
+
37
+
function TooltipContent({
38
+
className,
39
+
sideOffset = 0,
40
+
children,
41
+
...props
42
+
}: React.ComponentProps<typeof TooltipPrimitive.Content>) {
43
+
return (
44
+
<TooltipPrimitive.Portal>
45
+
<TooltipPrimitive.Content
46
+
data-slot="tooltip-content"
47
+
sideOffset={sideOffset}
48
+
className={cn(
49
+
"bg-foreground text-background animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance",
50
+
className
51
+
)}
52
+
{...props}
53
+
>
54
+
{children}
55
+
<TooltipPrimitive.Arrow className="bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" />
56
+
</TooltipPrimitive.Content>
57
+
</TooltipPrimitive.Portal>
58
+
)
59
+
}
60
+
61
+
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }
+45
apps/app/components/views/recipe-card.tsx
+45
apps/app/components/views/recipe-card.tsx
···
1
+
import { BlueRecipesFeedDefs } from "@cookware/lexicons";
2
+
import { ClockIcon } from "lucide-react";
3
+
import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from "../ui/card";
4
+
import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar";
5
+
import Link from "next/link";
6
+
7
+
export type RecipeCardProps = {
8
+
recipe: BlueRecipesFeedDefs.RecipeView;
9
+
}
10
+
11
+
export const RecipeCard = ({ recipe }: RecipeCardProps) => (
12
+
<Link href={`/recipes/${recipe.author.handle}/${recipe.rkey}`}>
13
+
<Card>
14
+
<CardHeader>
15
+
<CardTitle>{recipe.record.title}</CardTitle>
16
+
{recipe.record.description && <CardDescription>{recipe.record.description}</CardDescription>}
17
+
</CardHeader>
18
+
19
+
{recipe.imageUrl && (
20
+
<CardContent>
21
+
<img className="rounded-md ratio-[4/3] object-cover" src={recipe.imageUrl} />
22
+
</CardContent>
23
+
)}
24
+
25
+
<CardFooter>
26
+
<div className="flex flex-col gap-2">
27
+
<div className="flex items-center gap-2 text-sm">
28
+
<Avatar className="!size-8">
29
+
<AvatarImage>
30
+
<img src={recipe.author.avatar} />
31
+
</AvatarImage>
32
+
<AvatarFallback>{recipe.author.handle.split('.').map(v => v.startsWith('@') ? v[1] : v[0]).join('').toUpperCase()}</AvatarFallback>
33
+
</Avatar>
34
+
<span>{recipe.author.displayName ?? recipe.author.handle}</span>
35
+
</div>
36
+
37
+
<div className="flex items-center gap-2 text-sm">
38
+
<ClockIcon className="!size-4" />
39
+
<span>{recipe.record.time} mins</span>
40
+
</div>
41
+
</div>
42
+
</CardFooter>
43
+
</Card>
44
+
</Link>
45
+
);
+22
apps/app/components.json
+22
apps/app/components.json
···
1
+
{
2
+
"$schema": "https://ui.shadcn.com/schema.json",
3
+
"style": "new-york",
4
+
"rsc": true,
5
+
"tsx": true,
6
+
"tailwind": {
7
+
"config": "",
8
+
"css": "app/globals.css",
9
+
"baseColor": "zinc",
10
+
"cssVariables": true,
11
+
"prefix": ""
12
+
},
13
+
"iconLibrary": "lucide",
14
+
"aliases": {
15
+
"components": "@/components",
16
+
"utils": "@/lib/utils",
17
+
"ui": "@/components/ui",
18
+
"lib": "@/lib",
19
+
"hooks": "@/hooks"
20
+
},
21
+
"registries": {}
22
+
}
+18
apps/app/eslint.config.mjs
+18
apps/app/eslint.config.mjs
···
1
+
import { defineConfig, globalIgnores } from "eslint/config";
2
+
import nextVitals from "eslint-config-next/core-web-vitals";
3
+
import nextTs from "eslint-config-next/typescript";
4
+
5
+
const eslintConfig = defineConfig([
6
+
...nextVitals,
7
+
...nextTs,
8
+
// Override default ignores of eslint-config-next.
9
+
globalIgnores([
10
+
// Default ignores of eslint-config-next:
11
+
".next/**",
12
+
"out/**",
13
+
"build/**",
14
+
"next-env.d.ts",
15
+
]),
16
+
]);
17
+
18
+
export default eslintConfig;
+19
apps/app/hooks/use-mobile.ts
+19
apps/app/hooks/use-mobile.ts
···
1
+
import * as React from "react"
2
+
3
+
const MOBILE_BREAKPOINT = 768
4
+
5
+
export function useIsMobile() {
6
+
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)
7
+
8
+
React.useEffect(() => {
9
+
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)
10
+
const onChange = () => {
11
+
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
12
+
}
13
+
mql.addEventListener("change", onChange)
14
+
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
15
+
return () => mql.removeEventListener("change", onChange)
16
+
}, [])
17
+
18
+
return !!isMobile
19
+
}
+18
apps/app/lib/consts.ts
+18
apps/app/lib/consts.ts
···
1
+
export const IS_DEV = process.env.NODE_ENV == "development";
2
+
export const OAUTH_SCOPE = ['atproto', 'transition:generic'];
3
+
4
+
export const REDIRECT_URI = IS_DEV
5
+
? "http://127.0.0.1:3000"
6
+
: "https://cookware.social";
7
+
8
+
export const CLIENT_ID = IS_DEV
9
+
? `http://localhost?redirect_uri=${encodeURIComponent(REDIRECT_URI)}&scope=${encodeURIComponent(OAUTH_SCOPE.join(' '))}`
10
+
: "https://cookware.social/oauth-client-metadata.json";
11
+
12
+
export const COOKWARE_API_URL = IS_DEV
13
+
? "http://localhost:4000"
14
+
: "https://api.cookware.social";
15
+
16
+
export const BLUESKY_PROFILE_URL = "https://bsky.app/profile/cookware.social";
17
+
export const DISCORD_URL = "https://discord.gg/64nAv9QPJ9";
18
+
export const HANDLE_RESOLUTION_SERVICE = "https://slingshot.microcosm.blue";
+25
apps/app/lib/queries/recipes.tsx
+25
apps/app/lib/queries/recipes.tsx
···
1
+
import { Client } from '@atcute/client';
2
+
import { useQuery, queryOptions } from '@tanstack/react-query';
3
+
import { useClient } from '../state/query-provider';
4
+
5
+
export const GET_RECIPES_QK = ['recipes'];
6
+
7
+
export const getRecipesOptions = (client: Client) => queryOptions({
8
+
queryKey: GET_RECIPES_QK,
9
+
queryFn: async () => {
10
+
const res = await client.get('blue.recipes.feed.getRecipes', {
11
+
params: {},
12
+
});
13
+
14
+
if (!res.ok) throw res;
15
+
16
+
return res.data;
17
+
},
18
+
});
19
+
20
+
export const useGetRecipesQuery = () => {
21
+
const { client } = useClient();
22
+
return useQuery({
23
+
...getRecipesOptions(client)
24
+
});
25
+
};
+135
apps/app/lib/state/auth.tsx
+135
apps/app/lib/state/auth.tsx
···
1
+
"use client";
2
+
3
+
import { LocalActorResolver, XrpcHandleResolver, CompositeDidDocumentResolver, PlcDidDocumentResolver, WebDidDocumentResolver } from "@atcute/identity-resolver";
4
+
import { configureOAuth, finalizeAuthorization, getSession, OAuthUserAgent } from "@atcute/oauth-browser-client";
5
+
import { createContext, PropsWithChildren, useContext, useEffect, useLayoutEffect, useState } from "react";
6
+
import { CLIENT_ID, HANDLE_RESOLUTION_SERVICE, REDIRECT_URI } from "@/lib/consts";
7
+
import { useClient } from "./query-provider";
8
+
import { Did, isDid } from "@atcute/lexicons/syntax";
9
+
import { BlueRecipesActorDefs } from "@cookware/lexicons";
10
+
import { Client } from "@atcute/client";
11
+
12
+
type AuthContext = {
13
+
loggedIn: false;
14
+
} | {
15
+
loggedIn: true;
16
+
actorDid: Did;
17
+
pdsClient: Client;
18
+
profile: {
19
+
exists: true;
20
+
profileView: BlueRecipesActorDefs.ProfileViewDetailed;
21
+
} | {
22
+
exists: false;
23
+
}
24
+
};
25
+
26
+
const authContext = createContext<AuthContext | undefined>(undefined);
27
+
28
+
export const identityResolver = new LocalActorResolver({
29
+
handleResolver: new XrpcHandleResolver({ serviceUrl: HANDLE_RESOLUTION_SERVICE }),
30
+
didDocumentResolver: new CompositeDidDocumentResolver({
31
+
methods: {
32
+
plc: new PlcDidDocumentResolver(),
33
+
web: new WebDidDocumentResolver(),
34
+
},
35
+
}),
36
+
});
37
+
38
+
export const AuthProvider = ({ children }: PropsWithChildren) => {
39
+
const { client, setHandler } = useClient();
40
+
const [loading, setLoading] = useState<boolean>(true);
41
+
const [loggedIn, setLoggedIn] = useState<boolean>(false);
42
+
const [actorDid, setActorDid] = useState<Did>();
43
+
const [pdsClient, setPdsClient] = useState<Client>();
44
+
const [hasProfile, setHasProfile] = useState<boolean>(false);
45
+
const [profileView, setProfileView] = useState<BlueRecipesActorDefs.ProfileViewDetailed>();
46
+
47
+
useLayoutEffect(() => {
48
+
configureOAuth({
49
+
identityResolver,
50
+
metadata: {
51
+
client_id: CLIENT_ID,
52
+
redirect_uri: REDIRECT_URI,
53
+
},
54
+
});
55
+
56
+
const params = new URLSearchParams(location.hash.slice(1));
57
+
if (params.has('state') && params.has('iss') && params.has('code')) {
58
+
// Remove state & code to prevent thievery and abject tomfoolery
59
+
window.history.replaceState(null, '', location.pathname + location.search);
60
+
61
+
finalizeAuthorization(params)
62
+
.then(({ session }) => {
63
+
localStorage.setItem('lastSignedIn', session.info.sub);
64
+
const agent = new OAuthUserAgent(session);
65
+
setHandler(agent);
66
+
setActorDid(session.info.sub);
67
+
setLoggedIn(true);
68
+
setPdsClient(new Client({ handler: agent }));
69
+
});
70
+
} else {
71
+
const existing = localStorage.getItem('lastSignedIn');
72
+
if (!existing || !isDid(existing)) {
73
+
setLoading(false);
74
+
return;
75
+
};
76
+
getSession(existing, { allowStale: true })
77
+
.then(session => {
78
+
localStorage.setItem('lastSignedIn', session.info.sub);
79
+
const agent = new OAuthUserAgent(session);
80
+
setHandler(new OAuthUserAgent(session));
81
+
setActorDid(session.info.sub);
82
+
setLoggedIn(true);
83
+
setPdsClient(new Client({ handler: agent }));
84
+
setLoading(false);
85
+
});
86
+
}
87
+
}, []);
88
+
89
+
useEffect(() => {
90
+
if (loggedIn && actorDid) {
91
+
client.get('blue.recipes.actor.getProfile', {
92
+
params: { actor: actorDid },
93
+
})
94
+
.then(res => {
95
+
if (!res.ok) {
96
+
if (res.data.error === 'ProfileNotFound') {
97
+
setHasProfile(false);
98
+
return;
99
+
}
100
+
throw res.data.error;
101
+
} else {
102
+
setHasProfile(true);
103
+
setProfileView(res.data);
104
+
if (loading) setLoading(false);
105
+
}
106
+
});
107
+
}
108
+
}, [loggedIn]);
109
+
110
+
if (loading) return <>Loading...</>;
111
+
112
+
return (
113
+
<authContext.Provider value={
114
+
loggedIn
115
+
? {
116
+
loggedIn,
117
+
actorDid: actorDid!,
118
+
pdsClient: pdsClient!,
119
+
profile: hasProfile ? {
120
+
exists: hasProfile,
121
+
profileView: profileView!,
122
+
} : { exists: false },
123
+
}
124
+
: { loggedIn: false }
125
+
}>
126
+
{children}
127
+
</authContext.Provider>
128
+
);
129
+
};
130
+
131
+
export const useAuth = () => {
132
+
const ctx = useContext(authContext);
133
+
if (!ctx) throw new Error("useAuth() must be called inside <AuthProvider />");
134
+
return ctx;
135
+
}
+44
apps/app/lib/state/query-provider.tsx
+44
apps/app/lib/state/query-provider.tsx
···
1
+
"use client";
2
+
3
+
import { createContext, PropsWithChildren, useContext, useEffect, useState } from "react";
4
+
import { Client, CredentialManager, FetchHandler, FetchHandlerObject } from "@atcute/client";
5
+
import { COOKWARE_API_URL } from "../consts";
6
+
7
+
type QueryContext = {
8
+
client: Client;
9
+
handler: FetchHandler | FetchHandlerObject;
10
+
setHandler: (handler: FetchHandler | FetchHandlerObject) => void;
11
+
};
12
+
13
+
export const queryContext = createContext<QueryContext | undefined>(undefined);
14
+
15
+
export const ClientProvider = ({ children }: PropsWithChildren) => {
16
+
const [isLoaded, setIsLoaded] = useState(false);
17
+
const [handler, setHandler] = useState<QueryContext["handler"]>(
18
+
new CredentialManager({ service: COOKWARE_API_URL }),
19
+
);
20
+
const [client, setClient] = useState<QueryContext["client"]>(new Client({ handler }));
21
+
22
+
useEffect(() => {
23
+
if (!isLoaded) {
24
+
setIsLoaded(true);
25
+
return;
26
+
}
27
+
setClient(new Client({ handler }));
28
+
setIsLoaded(true);
29
+
}, [handler]);
30
+
31
+
if (!isLoaded || !client) return <>Loading...</>;
32
+
33
+
return (
34
+
<queryContext.Provider value={{ client: client!, handler, setHandler }}>
35
+
{children}
36
+
</queryContext.Provider>
37
+
);
38
+
};
39
+
40
+
export const useClient = () => {
41
+
const ctx = useContext(queryContext);
42
+
if (!ctx) throw new Error("useClient must be used within a ClientProvider");
43
+
return ctx;
44
+
}
+6
apps/app/lib/utils.ts
+6
apps/app/lib/utils.ts
+7
apps/app/next.config.ts
+7
apps/app/next.config.ts
+49
apps/app/package.json
+49
apps/app/package.json
···
1
+
{
2
+
"name": "app",
3
+
"version": "0.1.0",
4
+
"private": true,
5
+
"scripts": {
6
+
"dev": "next dev",
7
+
"build": "next build",
8
+
"start": "next start",
9
+
"lint": "eslint"
10
+
},
11
+
"dependencies": {
12
+
"@atcute/atproto": "catalog:",
13
+
"@atcute/client": "catalog:",
14
+
"@atcute/identity": "catalog:",
15
+
"@atcute/identity-resolver": "catalog:",
16
+
"@atcute/lexicons": "catalog:",
17
+
"@atproto/oauth-client-node": "^0.3.13",
18
+
"@cookware/lexicons": "workspace:*",
19
+
"@radix-ui/react-avatar": "^1.1.11",
20
+
"@radix-ui/react-dialog": "^1.1.15",
21
+
"@radix-ui/react-dropdown-menu": "^2.1.16",
22
+
"@radix-ui/react-label": "^2.1.8",
23
+
"@radix-ui/react-separator": "^1.1.8",
24
+
"@radix-ui/react-slot": "^1.2.4",
25
+
"@radix-ui/react-tooltip": "^1.2.8",
26
+
"@tabler/icons-react": "^3.35.0",
27
+
"@tanstack/react-query": "^5.90.12",
28
+
"class-variance-authority": "^0.7.1",
29
+
"clsx": "^2.1.1",
30
+
"lucide-react": "^0.556.0",
31
+
"next": "16.0.7",
32
+
"react": "19.2.0",
33
+
"react-dom": "19.2.0",
34
+
"tailwind-merge": "^3.4.0"
35
+
},
36
+
"devDependencies": {
37
+
"@tailwindcss/postcss": "^4",
38
+
"@tanstack/query-devtools": "^5.91.1",
39
+
"@tanstack/react-query-devtools": "^5.91.1",
40
+
"@types/node": "^20",
41
+
"@types/react": "^19",
42
+
"@types/react-dom": "^19",
43
+
"eslint": "^9",
44
+
"eslint-config-next": "16.0.7",
45
+
"tailwindcss": "^4",
46
+
"tw-animate-css": "^1.4.0",
47
+
"typescript": "^5"
48
+
}
49
+
}
+7
apps/app/postcss.config.mjs
+7
apps/app/postcss.config.mjs
+35
apps/app/tsconfig.json
+35
apps/app/tsconfig.json
···
1
+
{
2
+
"compilerOptions": {
3
+
"types": ["@atcute/atproto", "@cookware/lexicons"],
4
+
"target": "ES2017",
5
+
"lib": ["dom", "dom.iterable", "esnext"],
6
+
"allowJs": true,
7
+
"skipLibCheck": true,
8
+
"strict": true,
9
+
"noEmit": true,
10
+
"esModuleInterop": true,
11
+
"module": "esnext",
12
+
"moduleResolution": "bundler",
13
+
"resolveJsonModule": true,
14
+
"isolatedModules": true,
15
+
"jsx": "react-jsx",
16
+
"incremental": true,
17
+
"plugins": [
18
+
{
19
+
"name": "next"
20
+
}
21
+
],
22
+
"paths": {
23
+
"@/*": ["./*"]
24
+
}
25
+
},
26
+
"include": [
27
+
"next-env.d.ts",
28
+
"**/*.ts",
29
+
"**/*.tsx",
30
+
".next/types/**/*.ts",
31
+
".next/dev/types/**/*.ts",
32
+
"**/*.mts"
33
+
],
34
+
"exclude": ["node_modules"]
35
+
}
-3
apps/ingester/Dockerfile
-3
apps/ingester/Dockerfile
+13
-26
apps/ingester/package.json
+13
-26
apps/ingester/package.json
···
7
7
"access": "public"
8
8
},
9
9
"scripts": {
10
-
"dev": "NODE_OPTIONS=--use-openssl-ca tsx watch --clear-screen=false src/index.ts | pino-pretty",
11
-
"build": "tsup",
12
-
"start": "NODE_OPTIONS=--use-openssl-ca node dist/index.cjs",
10
+
"build": "bun --bun run check-types && bun --bun run compile",
11
+
"dev": "bun run --hot src/index.ts | pino-pretty",
12
+
"check-types": "tsc --noEmit",
13
+
"compile": "bun build src/index.ts --compile --minify --sourcemap --outfile=dist/ingester --target=bun",
13
14
"clean": "rimraf dist"
14
15
},
15
16
"dependencies": {
16
-
"@atcute/client": "^2.0.6",
17
+
"@atcute/client": "catalog:",
18
+
"@atcute/identity": "^1.1.3",
19
+
"@atcute/identity-resolver": "^1.1.4",
20
+
"@atcute/jetstream": "^1.1.2",
21
+
"@atcute/lexicons": "catalog:",
22
+
"@badrap/valita": "^0.4.6",
17
23
"@cookware/database": "workspace:^",
24
+
"@cookware/lexicons": "workspace:*",
18
25
"@sentry/node": "^8.42.0",
19
-
"@skyware/jetstream": "^0.2.1",
20
-
"bufferutil": "^4.0.8",
21
-
"drizzle-orm": "^0.37.0",
22
-
"pino": "^9.5.0",
23
-
"ws": "^8.18.0",
24
-
"zod": "^3.23.8"
26
+
"pino": "^9.5.0"
25
27
},
26
28
"devDependencies": {
27
-
"@cookware/lexicons": "workspace:*",
28
29
"@cookware/tsconfig": "workspace:*",
29
-
"@types/node": "^22.10.1",
30
+
"@types/bun": "catalog:",
30
31
"@types/ws": "^8.5.13",
31
32
"pino-pretty": "^13.0.0",
32
33
"rimraf": "^6.0.1",
33
-
"ts-node": "^10.9.2",
34
-
"tsup": "^8.3.5",
35
-
"tsx": "^4.19.2",
36
34
"typescript": "^5.7.2"
37
-
},
38
-
"tsup": {
39
-
"entry": [
40
-
"src",
41
-
"!src/**/__tests__/**",
42
-
"!src/**/*.test.*"
43
-
],
44
-
"splitting": false,
45
-
"sourcemap": true,
46
-
"clean": true,
47
-
"format": "esm"
48
35
}
49
36
}
+13
-18
apps/ingester/src/config.ts
+13
-18
apps/ingester/src/config.ts
···
1
-
import { z } from "zod";
1
+
import * as v from "@badrap/valita";
2
2
3
-
const envSchema = z.object({
4
-
TURSO_CONNECTION_URL: z.string().default('https://turso.dev.hayden.moe'),
5
-
TURSO_AUTH_TOKEN: z.string().or(z.undefined()),
3
+
const envSchema = v.object({
4
+
TURSO_CONNECTION_URL: v.string().optional(() => 'https://turso.dev.hayden.moe'),
5
+
TURSO_AUTH_TOKEN: v.string().optional(),
6
6
7
-
JETSTREAM_ENDPOINT: z
8
-
.string()
9
-
.url()
10
-
.default('wss://jetstream1.us-east.bsky.network/subscribe'),
11
-
PLC_DIRECTORY_URL: z.string().url().default('https://plc.directory'),
7
+
REDIS_URL: v.string().optional(() => 'redis://localhost:6379/0'),
12
8
13
-
SENTRY_DSN: z.string().or(z.undefined()),
9
+
JETSTREAM_ENDPOINT: v.string()
10
+
.optional(() => 'wss://jetstream1.us-east.bsky.network'),
11
+
PLC_DIRECTORY_URL: v.string().optional(() => 'https://plc.directory'),
14
12
15
-
ENV: z
16
-
.union([
17
-
z.literal('development'),
18
-
z.literal('production'),
19
-
])
20
-
.default('development'),
13
+
ENV: v
14
+
.union(v.literal('development'), v.literal('production'))
15
+
.optional(() => 'development'),
21
16
});
22
17
23
-
const env = envSchema.parse(process.env);
18
+
const env = envSchema.parse(process.env, { mode: 'strip' });
24
19
25
20
export default env;
26
-
export type Env = z.infer<typeof envSchema>;
21
+
export type Env = v.Infer<typeof envSchema>;
+52
-79
apps/ingester/src/index.ts
+52
-79
apps/ingester/src/index.ts
···
1
-
import { Jetstream } from "@skyware/jetstream";
2
-
import { WebSocket } from "ws";
3
-
import { ingestLogger } from "./logger.js";
1
+
import { JetstreamSubscription } from "@atcute/jetstream";
4
2
import env from "./config.js";
5
-
import { RecipeCollection, RecipeRecord, parseDid } from "@cookware/lexicons";
6
-
import { db, recipeTable } from "@cookware/database";
7
-
import { and, eq } from "drizzle-orm";
3
+
import { BlueRecipesActorProfile, BlueRecipesFeedRecipe } from "@cookware/lexicons";
4
+
import { isAtprotoDid } from '@atcute/identity';
5
+
import pino from "pino";
6
+
import { ingestRecipe } from "./ingesters/recipe.js";
7
+
import { ingestProfile } from "./ingesters/profile.js";
8
8
9
9
export const newIngester = () => {
10
-
const jetstream = new Jetstream({
11
-
ws: WebSocket,
12
-
endpoint: env.JETSTREAM_ENDPOINT,
13
-
wantedCollections: ['blue.recipes.*'],
14
-
cursor: 0,
10
+
const logger = pino({
11
+
name: 'recipes.ingester',
12
+
level: env.ENV === 'development' ? 'debug' : 'info',
15
13
});
16
14
17
-
jetstream.on("commit", async event => {
18
-
if (event.commit.operation == 'create' || event.commit.operation == 'update') {
19
-
const now = new Date();
20
-
const { record } = event.commit;
21
-
22
-
if (
23
-
event.commit.collection == RecipeCollection
24
-
&& record.$type == RecipeCollection
25
-
&& RecipeRecord.safeParse(record).success
26
-
) {
27
-
const res = await db
28
-
.insert(recipeTable)
29
-
.values({
30
-
rkey: event.commit.rkey,
31
-
title: record.title,
32
-
time: record.time,
33
-
serves: record.serves,
34
-
description: record.description,
35
-
ingredients: record.ingredients,
36
-
steps: record.steps,
37
-
imageRef: record.image ? record.image.ref.$link : null,
38
-
authorDid: parseDid(event.did)!,
39
-
createdAt: now,
40
-
})
41
-
.onConflictDoUpdate({
42
-
target: recipeTable.id,
43
-
set: {
44
-
title: record.title,
45
-
time: record.time,
46
-
serves: record.serves,
47
-
description: record.description,
48
-
ingredients: record.ingredients,
49
-
steps: record.steps,
50
-
imageRef: record.image ? record.image.ref.$link : null,
51
-
},
52
-
})
53
-
.execute();
54
-
55
-
ingestLogger.info({ res }, 'recipe ingested');
56
-
}
57
-
} else if (event.commit.operation == 'delete') {
58
-
const res = await db
59
-
.delete(recipeTable)
60
-
.where(
61
-
and(
62
-
eq(recipeTable.authorDid, parseDid(event.did)!),
63
-
eq(recipeTable.rkey, event.commit.rkey),
64
-
)
65
-
)
66
-
.execute();
67
-
68
-
ingestLogger.info({ res }, 'recipe deleted');
69
-
}
15
+
const subscription = new JetstreamSubscription({
16
+
url: env.JETSTREAM_ENDPOINT,
17
+
wantedCollections: [
18
+
'blue.recipes.feed.recipe',
19
+
'blue.recipes.actor.profile',
20
+
],
21
+
onConnectionOpen: () => logger.info('Connected to Jetstream'),
22
+
onConnectionError: err => {
23
+
logger.error(err, 'Failed to connect to Jetstream');
24
+
process.exit(1);
25
+
},
26
+
onConnectionClose: () => logger.info('Disconnected from Jetstream'),
70
27
});
71
28
72
-
jetstream.on('open', () => {
73
-
ingestLogger.info({
74
-
endpoint: env.JETSTREAM_ENDPOINT,
75
-
wantedCollections: ['recipes.blue.*'],
76
-
}, 'Ingester connection opened.');
77
-
});
29
+
return {
30
+
subscription,
31
+
start: async () => {
32
+
const redis = new Bun.RedisClient(env.REDIS_URL);
78
33
79
-
jetstream.on('close', () => {
80
-
ingestLogger.error('Ingester connection closed.');
81
-
});
82
-
83
-
jetstream.on('error', err => {
84
-
ingestLogger.error({ err }, 'Ingester runtime error.');
85
-
});
34
+
for await (const event of subscription) {
35
+
const authorDid = event.did;
36
+
if (!isAtprotoDid(authorDid)) {
37
+
logger.warn(`Invalid did: ${authorDid}`);
38
+
continue;
39
+
}
86
40
87
-
return jetstream;
41
+
if (event.kind === 'commit') {
42
+
const commit = event.commit;
43
+
switch (commit.collection) {
44
+
case BlueRecipesFeedRecipe.mainSchema.object.shape.$type.expected:
45
+
await ingestRecipe(authorDid, commit, logger);
46
+
break;
47
+
case BlueRecipesActorProfile.mainSchema.object.shape.$type.expected:
48
+
await ingestProfile(authorDid, commit, logger, redis);
49
+
break;
50
+
default:
51
+
logger.debug({ collection: commit.collection }, "skipping unknown collection");
52
+
break;
53
+
}
54
+
} else {
55
+
logger.trace({ kind: event.kind, authorDid }, `Skipping non-commit event for did: ${event.did}`);
56
+
continue;
57
+
}
58
+
}
59
+
},
60
+
}
88
61
};
89
62
90
-
newIngester().start();
63
+
await newIngester().start();
+84
apps/ingester/src/ingesters/profile.ts
+84
apps/ingester/src/ingesters/profile.ts
···
1
+
import { db, eq } from "@cookware/database";
2
+
import { profilesTable } from "@cookware/database/schema";
3
+
import { is } from '@atcute/lexicons';
4
+
import { BlueRecipesActorProfile } from "@cookware/lexicons";
5
+
import type { CommitOperation } from "@atcute/jetstream";
6
+
import type { Logger } from "pino";
7
+
import type { AtprotoDid } from "@atcute/lexicons/syntax";
8
+
import { RedisClient } from "bun";
9
+
import { CompositeDidDocumentResolver, PlcDidDocumentResolver, WebDidDocumentResolver } from "@atcute/identity-resolver";
10
+
import env from "../config.js";
11
+
12
+
const didResolver = new CompositeDidDocumentResolver({
13
+
methods: {
14
+
plc: new PlcDidDocumentResolver({ apiUrl: env.PLC_DIRECTORY_URL }),
15
+
web: new WebDidDocumentResolver(),
16
+
}
17
+
});
18
+
19
+
const HANDLE_CACHE_TTL = 5 * 60; // 5 minutes
20
+
21
+
export const ingestProfile = async (did: AtprotoDid, commit: CommitOperation, logger: Logger, redis: RedisClient) => {
22
+
if (commit.operation == 'create' || commit.operation == 'update') {
23
+
const { rkey, record, cid } = commit;
24
+
25
+
if (rkey != "self") {
26
+
logger.warn(`Invalid profile rkey for ${commit['operation']} ${did}: ${rkey}`);
27
+
return;
28
+
}
29
+
if (!is(BlueRecipesActorProfile.mainSchema, record)) {
30
+
logger.warn(`Invalid profile schema for ${commit['operation']} ${did}`);
31
+
return;
32
+
}
33
+
34
+
// Preemptively cache the user's handle for the API
35
+
let handle = await redis.get(`handle:${did}`);
36
+
if (!handle) {
37
+
const didDoc = await didResolver.resolve(did);
38
+
if (didDoc.alsoKnownAs == null || didDoc.alsoKnownAs.length < 1) {
39
+
logger.warn(`User ${did} had no resolvable DID document.`);
40
+
return;
41
+
}
42
+
handle = didDoc.alsoKnownAs[0]!.substring(5);
43
+
redis.setex(`handle:${did}`, HANDLE_CACHE_TTL, handle);
44
+
}
45
+
46
+
await db
47
+
.insert(profilesTable)
48
+
.values({
49
+
cid,
50
+
did,
51
+
displayName: record.displayName,
52
+
avatarRef: record.avatar,
53
+
bannerRef: record.banner,
54
+
description: record.description,
55
+
pronouns: record.pronouns,
56
+
website: record.website,
57
+
createdAt: record.createdAt ? new Date(record.createdAt) : new Date(),
58
+
ingestedAt: new Date(),
59
+
})
60
+
.onConflictDoUpdate({
61
+
target: [profilesTable.did],
62
+
set: {
63
+
cid,
64
+
displayName: record.displayName,
65
+
avatarRef: record.avatar,
66
+
bannerRef: record.banner,
67
+
description: record.description,
68
+
pronouns: record.pronouns,
69
+
website: record.website,
70
+
createdAt: record.createdAt ? new Date(record.createdAt) : new Date(),
71
+
},
72
+
});
73
+
74
+
logger.info(`Upserted profile ${did}/${rkey}`);
75
+
} else if (commit.operation == 'delete') {
76
+
const rkey = commit.rkey;
77
+
db
78
+
.delete(profilesTable)
79
+
.where(eq(profilesTable.did, did));
80
+
logger.info(`Deleted profile ${did}/${rkey}`);
81
+
} else {
82
+
logger.warn(`Unknown operation type: ${commit['operation']}`);
83
+
}
84
+
};
+57
apps/ingester/src/ingesters/recipe.ts
+57
apps/ingester/src/ingesters/recipe.ts
···
1
+
import { db, and, eq } from "@cookware/database";
2
+
import { recipeTable } from "@cookware/database/schema";
3
+
import { is } from '@atcute/lexicons';
4
+
import { BlueRecipesFeedRecipe } from "@cookware/lexicons";
5
+
import type { CommitOperation } from "@atcute/jetstream";
6
+
import type { Logger } from "pino";
7
+
import type { AtprotoDid } from "@atcute/lexicons/syntax";
8
+
9
+
export const ingestRecipe = async (did: AtprotoDid, commit: CommitOperation, logger: Logger) => {
10
+
if (commit.operation == 'create' || commit.operation == 'update') {
11
+
const { rkey, record, cid } = commit;
12
+
13
+
if (!is(BlueRecipesFeedRecipe.mainSchema, record)) {
14
+
logger.warn(`Invalid recipe schema for ${commit['operation']} ${did}/${rkey}`);
15
+
return;
16
+
}
17
+
18
+
await db
19
+
.insert(recipeTable)
20
+
.values({
21
+
cid, rkey, did,
22
+
title: record.title,
23
+
time: record.time ?? 0,
24
+
serves: record.serves ?? null,
25
+
description: record.description ?? null,
26
+
ingredients: record.ingredients,
27
+
steps: record.steps,
28
+
createdAt: record.createdAt ? new Date(record.createdAt) : new Date(),
29
+
})
30
+
.onConflictDoUpdate({
31
+
target: [recipeTable.did, recipeTable.rkey],
32
+
set: {
33
+
cid,
34
+
title: record.title,
35
+
time: record.time ?? 0,
36
+
serves: record.serves ?? null,
37
+
description: record.description ?? null,
38
+
ingredients: record.ingredients,
39
+
steps: record.steps,
40
+
createdAt: record.createdAt ? new Date(record.createdAt) : new Date(),
41
+
},
42
+
});
43
+
44
+
logger.info(`Upserted recipe ${did}/${rkey}`);
45
+
} else if (commit.operation == 'delete') {
46
+
const rkey = commit.rkey;
47
+
db
48
+
.delete(recipeTable)
49
+
.where(and(
50
+
eq(recipeTable.did, did),
51
+
eq(recipeTable.rkey, rkey),
52
+
));
53
+
logger.info(`Deleted recipe ${did}/${rkey}`);
54
+
} else {
55
+
logger.warn(`Unknown operation type: ${commit['operation']}`);
56
+
}
57
+
};
-4
apps/ingester/src/logger.ts
-4
apps/ingester/src/logger.ts
+52
-29
apps/web/README.md
+52
-29
apps/web/README.md
···
4
4
5
5
Currently, two official plugins are available:
6
6
7
-
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
8
-
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
7
+
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh
8
+
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
9
+
10
+
## React Compiler
11
+
12
+
The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).
9
13
10
14
## Expanding the ESLint configuration
11
15
12
-
If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:
16
+
If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
17
+
18
+
```js
19
+
export default defineConfig([
20
+
globalIgnores(['dist']),
21
+
{
22
+
files: ['**/*.{ts,tsx}'],
23
+
extends: [
24
+
// Other configs...
13
25
14
-
- Configure the top-level `parserOptions` property like this:
26
+
// Remove tseslint.configs.recommended and replace with this
27
+
tseslint.configs.recommendedTypeChecked,
28
+
// Alternatively, use this for stricter rules
29
+
tseslint.configs.strictTypeChecked,
30
+
// Optionally, add this for stylistic rules
31
+
tseslint.configs.stylisticTypeChecked,
15
32
16
-
```js
17
-
export default tseslint.config({
18
-
languageOptions: {
19
-
// other options...
20
-
parserOptions: {
21
-
project: ['./tsconfig.node.json', './tsconfig.app.json'],
22
-
tsconfigRootDir: import.meta.dirname,
33
+
// Other configs...
34
+
],
35
+
languageOptions: {
36
+
parserOptions: {
37
+
project: ['./tsconfig.node.json', './tsconfig.app.json'],
38
+
tsconfigRootDir: import.meta.dirname,
39
+
},
40
+
// other options...
23
41
},
24
42
},
25
-
})
43
+
])
26
44
```
27
45
28
-
- Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked`
29
-
- Optionally add `...tseslint.configs.stylisticTypeChecked`
30
-
- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config:
46
+
You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
31
47
32
48
```js
33
49
// eslint.config.js
34
-
import react from 'eslint-plugin-react'
50
+
import reactX from 'eslint-plugin-react-x'
51
+
import reactDom from 'eslint-plugin-react-dom'
35
52
36
-
export default tseslint.config({
37
-
// Set the react version
38
-
settings: { react: { version: '18.3' } },
39
-
plugins: {
40
-
// Add the react plugin
41
-
react,
42
-
},
43
-
rules: {
44
-
// other rules...
45
-
// Enable its recommended rules
46
-
...react.configs.recommended.rules,
47
-
...react.configs['jsx-runtime'].rules,
53
+
export default defineConfig([
54
+
globalIgnores(['dist']),
55
+
{
56
+
files: ['**/*.{ts,tsx}'],
57
+
extends: [
58
+
// Other configs...
59
+
// Enable lint rules for React
60
+
reactX.configs['recommended-typescript'],
61
+
// Enable lint rules for React DOM
62
+
reactDom.configs.recommended,
63
+
],
64
+
languageOptions: {
65
+
parserOptions: {
66
+
project: ['./tsconfig.node.json', './tsconfig.app.json'],
67
+
tsconfigRootDir: import.meta.dirname,
68
+
},
69
+
// other options...
70
+
},
48
71
},
49
-
})
72
+
])
50
73
```
+4
-3
apps/web/components.json
+4
-3
apps/web/components.json
···
4
4
"rsc": false,
5
5
"tsx": true,
6
6
"tailwind": {
7
-
"config": "tailwind.config.js",
7
+
"config": "",
8
8
"css": "src/index.css",
9
9
"baseColor": "zinc",
10
10
"cssVariables": true,
11
11
"prefix": ""
12
12
},
13
+
"iconLibrary": "lucide",
13
14
"aliases": {
14
15
"components": "@/components",
15
16
"utils": "@/lib/utils",
···
17
18
"lib": "@/lib",
18
19
"hooks": "@/hooks"
19
20
},
20
-
"iconLibrary": "lucide"
21
-
}
21
+
"registries": {}
22
+
}
+10
-15
apps/web/eslint.config.js
+10
-15
apps/web/eslint.config.js
···
3
3
import reactHooks from 'eslint-plugin-react-hooks'
4
4
import reactRefresh from 'eslint-plugin-react-refresh'
5
5
import tseslint from 'typescript-eslint'
6
+
import { defineConfig, globalIgnores } from 'eslint/config'
6
7
7
-
export default tseslint.config(
8
-
{ ignores: ['dist'] },
8
+
export default defineConfig([
9
+
globalIgnores(['dist']),
9
10
{
10
-
extends: [js.configs.recommended, ...tseslint.configs.recommended],
11
11
files: ['**/*.{ts,tsx}'],
12
+
extends: [
13
+
js.configs.recommended,
14
+
tseslint.configs.recommended,
15
+
reactHooks.configs.flat.recommended,
16
+
reactRefresh.configs.vite,
17
+
],
12
18
languageOptions: {
13
19
ecmaVersion: 2020,
14
20
globals: globals.browser,
15
21
},
16
-
plugins: {
17
-
'react-hooks': reactHooks,
18
-
'react-refresh': reactRefresh,
19
-
},
20
-
rules: {
21
-
...reactHooks.configs.recommended.rules,
22
-
'react-refresh/only-export-components': [
23
-
'warn',
24
-
{ allowConstantExport: true },
25
-
],
26
-
},
27
22
},
28
-
)
23
+
])
+2
-1
apps/web/index.html
+2
-1
apps/web/index.html
···
2
2
<html lang="en">
3
3
<head>
4
4
<meta charset="UTF-8" />
5
+
<link rel="icon" type="image/svg+xml" href="/icon.svg" />
5
6
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
-
<title>Recipes</title>
7
+
<title>Cookware</title>
7
8
</head>
8
9
<body>
9
10
<div id="root"></div>
+32
-52
apps/web/package.json
+32
-52
apps/web/package.json
···
1
1
{
2
-
"name": "@cookware/web",
2
+
"name": "web",
3
3
"private": true,
4
4
"version": "0.0.0",
5
5
"type": "module",
6
6
"scripts": {
7
-
"dev": "vite --host",
7
+
"dev": "vite",
8
8
"build": "tsc -b && vite build",
9
9
"lint": "eslint .",
10
10
"preview": "vite preview"
11
11
},
12
12
"dependencies": {
13
-
"@atcute/client": "^2.0.6",
14
-
"@atcute/oauth-browser-client": "^1.0.7",
15
-
"@atproto/common": "^0.4.5",
16
-
"@atproto/common-web": "^0.3.1",
17
-
"@dnd-kit/core": "^6.3.1",
18
-
"@dnd-kit/modifiers": "^9.0.0",
19
-
"@dnd-kit/sortable": "^10.0.0",
20
-
"@dnd-kit/utilities": "^3.2.2",
21
-
"@hookform/resolvers": "^3.9.1",
22
-
"@radix-ui/react-avatar": "^1.1.1",
23
-
"@radix-ui/react-collapsible": "^1.1.1",
24
-
"@radix-ui/react-dialog": "^1.1.4",
25
-
"@radix-ui/react-dropdown-menu": "^2.1.4",
26
-
"@radix-ui/react-icons": "^1.3.2",
27
-
"@radix-ui/react-label": "^2.1.0",
28
-
"@radix-ui/react-separator": "^1.1.0",
29
-
"@radix-ui/react-slot": "^1.1.0",
30
-
"@radix-ui/react-tooltip": "^1.1.4",
31
-
"@tanstack/react-query": "^5.62.2",
32
-
"@tanstack/react-query-devtools": "^5.62.2",
33
-
"@tanstack/react-router": "^1.91.2",
34
-
"axios": "^1.7.9",
13
+
"@radix-ui/react-avatar": "^1.1.11",
14
+
"@radix-ui/react-dialog": "^1.1.15",
15
+
"@radix-ui/react-dropdown-menu": "^2.1.16",
16
+
"@radix-ui/react-label": "^2.1.8",
17
+
"@radix-ui/react-separator": "^1.1.8",
18
+
"@radix-ui/react-slot": "^1.2.4",
19
+
"@radix-ui/react-tooltip": "^1.2.8",
35
20
"class-variance-authority": "^0.7.1",
36
21
"clsx": "^2.1.1",
37
-
"lucide-react": "^0.464.0",
38
-
"react-dom": "19.0.0",
39
-
"react-hook-form": "^7.54.1",
40
-
"tailwind-merge": "^2.5.5",
41
-
"tailwindcss-animate": "^1.0.7",
42
-
"zod": "^3.23.8"
22
+
"lucide-react": "^0.556.0",
23
+
"react": "^19.2.0",
24
+
"react-dom": "^19.2.0",
25
+
"tailwind-merge": "^3.4.0",
26
+
"tailwindcss": "^4.1.17"
43
27
},
44
28
"devDependencies": {
45
-
"@atcute/bluesky": "^1.0.9",
46
-
"@cookware/lexicons": "workspace:*",
47
-
"@eslint/js": "^9.15.0",
48
-
"@tanstack/eslint-plugin-query": "^5.62.1",
49
-
"@tanstack/router-devtools": "^1.85.5",
50
-
"@tanstack/router-plugin": "^1.85.3",
51
-
"@types/node": "^22.10.1",
52
-
"@types/react": "^19.0.0",
53
-
"@types/react-dom": "^19.0.0",
54
-
"@vitejs/plugin-react-swc": "^3.5.0",
55
-
"autoprefixer": "^10.4.20",
56
-
"cssnano": "^7.0.6",
57
-
"eslint": "^9.15.0",
58
-
"eslint-plugin-react-hooks": "^5.0.0",
59
-
"eslint-plugin-react-refresh": "^0.4.14",
60
-
"globals": "^15.12.0",
61
-
"postcss": "^8.4.49",
62
-
"react": "19.0.0",
63
-
"tailwindcss": "^3.4.16",
64
-
"typescript": "~5.6.2",
65
-
"typescript-eslint": "^8.15.0",
66
-
"vite": "^6.0.1"
29
+
"@cookware/tsconfig": "workspace:*",
30
+
"@eslint/js": "^9.39.1",
31
+
"@tailwindcss/vite": "^4.1.17",
32
+
"@types/bun": "^1.3.4",
33
+
"@types/react": "^19.2.5",
34
+
"@types/react-dom": "^19.2.3",
35
+
"@vitejs/plugin-react": "^5.1.1",
36
+
"eslint": "^9.39.1",
37
+
"eslint-plugin-react-hooks": "^7.0.1",
38
+
"eslint-plugin-react-refresh": "^0.4.24",
39
+
"globals": "^16.5.0",
40
+
"tw-animate-css": "^1.4.0",
41
+
"typescript": "~5.9.3",
42
+
"typescript-eslint": "^8.46.4",
43
+
"vite": "npm:rolldown-vite@7.2.5"
44
+
},
45
+
"overrides": {
46
+
"vite": "npm:rolldown-vite@7.2.5"
67
47
}
68
48
}
-7
apps/web/postcss.config.js
-7
apps/web/postcss.config.js
-13
apps/web/public/.well-known/did.json
-13
apps/web/public/.well-known/did.json
-12
apps/web/public/client-metadata.json
-12
apps/web/public/client-metadata.json
···
1
-
{
2
-
"client_id": "https://recipes.blue/client-metadata.json",
3
-
"client_name": "Recipes",
4
-
"client_uri": "https://recipes.blue",
5
-
"redirect_uris": ["https://recipes.blue/"],
6
-
"scope": "atproto transition:generic",
7
-
"grant_types": ["authorization_code", "refresh_token"],
8
-
"response_types": ["code"],
9
-
"token_endpoint_auth_method": "none",
10
-
"application_type": "web",
11
-
"dpop_bound_access_tokens": true
12
-
}
+1
apps/web/public/icon.svg
+1
apps/web/public/icon.svg
···
1
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-chef-hat"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12 3c1.918 0 3.52 1.35 3.91 3.151a4 4 0 0 1 2.09 7.723l0 7.126h-12v-7.126a4 4 0 1 1 2.092 -7.723a4 4 0 0 1 3.908 -3.151z" /><path d="M6.161 17.009l11.839 -.009" /></svg>
-37
apps/web/src/components/mode-toggle.tsx
-37
apps/web/src/components/mode-toggle.tsx
···
1
-
import { Moon, Sun } from "lucide-react"
2
-
3
-
import { Button } from "@/components/ui/button"
4
-
import {
5
-
DropdownMenu,
6
-
DropdownMenuContent,
7
-
DropdownMenuItem,
8
-
DropdownMenuTrigger,
9
-
} from "@/components/ui/dropdown-menu"
10
-
import { useTheme } from "@/components/theme-provider"
11
-
12
-
export function ModeToggle() {
13
-
const { setTheme } = useTheme()
14
-
15
-
return (
16
-
<DropdownMenu>
17
-
<DropdownMenuTrigger asChild>
18
-
<Button variant="outline" size="icon" className="size-8 aspect-square flex items-center justify-center rounded-lg">
19
-
<Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
20
-
<Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
21
-
<span className="sr-only">Toggle theme</span>
22
-
</Button>
23
-
</DropdownMenuTrigger>
24
-
<DropdownMenuContent align="end">
25
-
<DropdownMenuItem onClick={() => setTheme("light")}>
26
-
Light
27
-
</DropdownMenuItem>
28
-
<DropdownMenuItem onClick={() => setTheme("dark")}>
29
-
Dark
30
-
</DropdownMenuItem>
31
-
<DropdownMenuItem onClick={() => setTheme("system")}>
32
-
System
33
-
</DropdownMenuItem>
34
-
</DropdownMenuContent>
35
-
</DropdownMenu>
36
-
)
37
-
}
-58
apps/web/src/components/query-placeholder.tsx
-58
apps/web/src/components/query-placeholder.tsx
···
1
-
import type { UseQueryResult } from '@tanstack/react-query';
2
-
import { PropsWithChildren, ReactNode } from 'react';
3
-
import { Skeleton } from './ui/skeleton';
4
-
import { Alert, AlertDescription, AlertTitle } from './ui/alert';
5
-
import { AlertCircle } from 'lucide-react';
6
-
import { XRPCError } from '@atcute/client';
7
-
8
-
type QueryPlaceholderProps<TData, TError> = PropsWithChildren<{
9
-
query: UseQueryResult<TData, TError>;
10
-
cards?: boolean;
11
-
cardsCount?: number;
12
-
noData?: ReactNode;
13
-
}>;
14
-
15
-
const QueryPlaceholder = <TData = {}, TError = Error>(
16
-
{
17
-
query,
18
-
children,
19
-
cards = false,
20
-
cardsCount = 3,
21
-
noData = <></>,
22
-
}: QueryPlaceholderProps<TData, TError>
23
-
) => {
24
-
if (query.isPending || query.isLoading) {
25
-
if (cards) {
26
-
return [...Array(cardsCount)].map((_, i) => <Skeleton key={i} className="h-[200px] w-full rounded-lg" />);
27
-
}
28
-
29
-
return (
30
-
<p>Loading...</p>
31
-
)
32
-
} else if (query.isError) {
33
-
const { error } = query;
34
-
let errMsg = 'Unknown';
35
-
if (error instanceof XRPCError) {
36
-
errMsg = error.kind ?? `HTTP_${error.status}`;
37
-
} if (error instanceof Error) {
38
-
errMsg = `${error.message} (${error.name})`;
39
-
}
40
-
41
-
return (
42
-
<Alert variant="destructive">
43
-
<AlertCircle className="size-4" />
44
-
45
-
<AlertTitle>Error fetching data.</AlertTitle>
46
-
<AlertDescription>
47
-
The data you were trying to see failed to fetch.<br/>
48
-
<b>Error code: {errMsg}</b>
49
-
</AlertDescription>
50
-
</Alert>
51
-
)
52
-
} else if (query.data) {
53
-
return children;
54
-
}
55
-
return noData;
56
-
};
57
-
58
-
export default QueryPlaceholder;
-72
apps/web/src/components/recipe-card.tsx
-72
apps/web/src/components/recipe-card.tsx
···
1
-
import { BlueRecipesFeedGetRecipes } from "@atcute/client/lexicons";
2
-
import { Card, CardContent, CardFooter, CardHeader } from "./ui/card";
3
-
import { Avatar, AvatarFallback, AvatarImage } from "./ui/avatar";
4
-
import { Link } from "@tanstack/react-router";
5
-
import { Clock, ListOrdered, Users, Utensils } from "lucide-react";
6
-
7
-
type RecipeCardProps = {
8
-
recipe: BlueRecipesFeedGetRecipes.Result;
9
-
};
10
-
11
-
function truncateDescription(description: string, maxLength: number = 120) {
12
-
if (description.length <= maxLength) return description;
13
-
return description.slice(0, maxLength).trim() + '...';
14
-
}
15
-
16
-
export const RecipeCard = ({ recipe }: RecipeCardProps) => {
17
-
return (
18
-
<Link to="/recipes/$author/$rkey" params={{ author: recipe.author.handle, rkey: recipe.rkey }} className="w-full">
19
-
<Card className="overflow-hidden">
20
-
<CardHeader className="p-0">
21
-
{ recipe.imageUrl &&
22
-
<div className="relative h-48 w-full">
23
-
<img
24
-
src={recipe.imageUrl}
25
-
alt={recipe.title}
26
-
className="h-full w-full object-cover"
27
-
/>
28
-
</div>
29
-
}
30
-
</CardHeader>
31
-
<CardContent className="p-4">
32
-
<h3 className="text-lg font-semibold mb-2">{recipe.title}</h3>
33
-
<p className="text-sm text-muted-foreground mb-4">
34
-
{truncateDescription(recipe.description || '')}
35
-
</p>
36
-
</CardContent>
37
-
<CardFooter className="p-4 pt-0">
38
-
<div className="w-full flex items-center justify-between">
39
-
<div className="flex items-center">
40
-
<Avatar className="h-8 w-8 mr-2">
41
-
<AvatarImage src={recipe.author.avatarUrl} alt={recipe.author.displayName} />
42
-
<AvatarFallback className="rounded-lg">{recipe.author.displayName?.charAt(0)}</AvatarFallback>
43
-
</Avatar>
44
-
<span className="text-sm text-muted-foreground">{recipe.author.displayName}</span>
45
-
</div>
46
-
<div className="flex gap-6 justify-between items-center text-sm text-muted-foreground">
47
-
<div className="flex items-center">
48
-
<Utensils className="w-4 h-4 mr-1" />
49
-
<span>{recipe.ingredients}</span>
50
-
</div>
51
-
52
-
<div className="flex items-center">
53
-
<ListOrdered className="w-4 h-4 mr-1" />
54
-
<span>{recipe.steps}</span>
55
-
</div>
56
-
57
-
<div className="flex items-center">
58
-
<Users className="w-4 h-4 mr-1" />
59
-
<span>{recipe.serves}</span>
60
-
</div>
61
-
62
-
<div className="flex items-center">
63
-
<Clock className="w-4 h-4 mr-1" />
64
-
<span>{recipe.time} min</span>
65
-
</div>
66
-
</div>
67
-
</div>
68
-
</CardFooter>
69
-
</Card>
70
-
</Link>
71
-
);
72
-
};
-73
apps/web/src/components/theme-provider.tsx
-73
apps/web/src/components/theme-provider.tsx
···
1
-
import { createContext, useContext, useEffect, useState } from "react"
2
-
3
-
type Theme = "dark" | "light" | "system"
4
-
5
-
type ThemeProviderProps = {
6
-
children: React.ReactNode
7
-
defaultTheme?: Theme
8
-
storageKey?: string
9
-
}
10
-
11
-
type ThemeProviderState = {
12
-
theme: Theme
13
-
setTheme: (theme: Theme) => void
14
-
}
15
-
16
-
const initialState: ThemeProviderState = {
17
-
theme: "system",
18
-
setTheme: () => null,
19
-
}
20
-
21
-
const ThemeProviderContext = createContext<ThemeProviderState>(initialState)
22
-
23
-
export function ThemeProvider({
24
-
children,
25
-
defaultTheme = "system",
26
-
storageKey = "vite-ui-theme",
27
-
...props
28
-
}: ThemeProviderProps) {
29
-
const [theme, setTheme] = useState<Theme>(
30
-
() => (localStorage.getItem(storageKey) as Theme) || defaultTheme
31
-
)
32
-
33
-
useEffect(() => {
34
-
const root = window.document.documentElement
35
-
36
-
root.classList.remove("light", "dark")
37
-
38
-
if (theme === "system") {
39
-
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)")
40
-
.matches
41
-
? "dark"
42
-
: "light"
43
-
44
-
root.classList.add(systemTheme)
45
-
return
46
-
}
47
-
48
-
root.classList.add(theme)
49
-
}, [theme])
50
-
51
-
const value = {
52
-
theme,
53
-
setTheme: (theme: Theme) => {
54
-
localStorage.setItem(storageKey, theme)
55
-
setTheme(theme)
56
-
},
57
-
}
58
-
59
-
return (
60
-
<ThemeProviderContext.Provider {...props} value={value}>
61
-
{children}
62
-
</ThemeProviderContext.Provider>
63
-
)
64
-
}
65
-
66
-
export const useTheme = () => {
67
-
const context = useContext(ThemeProviderContext)
68
-
69
-
if (context === undefined)
70
-
throw new Error("useTheme must be used within a ThemeProvider")
71
-
72
-
return context
73
-
}
-59
apps/web/src/components/ui/alert.tsx
-59
apps/web/src/components/ui/alert.tsx
···
1
-
import * as React from "react"
2
-
import { cva, type VariantProps } from "class-variance-authority"
3
-
4
-
import { cn } from "@/lib/utils"
5
-
6
-
const alertVariants = cva(
7
-
"relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7",
8
-
{
9
-
variants: {
10
-
variant: {
11
-
default: "bg-background text-foreground",
12
-
destructive:
13
-
"border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive",
14
-
},
15
-
},
16
-
defaultVariants: {
17
-
variant: "default",
18
-
},
19
-
}
20
-
)
21
-
22
-
const Alert = React.forwardRef<
23
-
HTMLDivElement,
24
-
React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>
25
-
>(({ className, variant, ...props }, ref) => (
26
-
<div
27
-
ref={ref}
28
-
role="alert"
29
-
className={cn(alertVariants({ variant }), className)}
30
-
{...props}
31
-
/>
32
-
))
33
-
Alert.displayName = "Alert"
34
-
35
-
const AlertTitle = React.forwardRef<
36
-
HTMLParagraphElement,
37
-
React.HTMLAttributes<HTMLHeadingElement>
38
-
>(({ className, ...props }, ref) => (
39
-
<h5
40
-
ref={ref}
41
-
className={cn("mb-1 font-medium leading-none tracking-tight", className)}
42
-
{...props}
43
-
/>
44
-
))
45
-
AlertTitle.displayName = "AlertTitle"
46
-
47
-
const AlertDescription = React.forwardRef<
48
-
HTMLParagraphElement,
49
-
React.HTMLAttributes<HTMLParagraphElement>
50
-
>(({ className, ...props }, ref) => (
51
-
<div
52
-
ref={ref}
53
-
className={cn("text-sm [&_p]:leading-relaxed", className)}
54
-
{...props}
55
-
/>
56
-
))
57
-
AlertDescription.displayName = "AlertDescription"
58
-
59
-
export { Alert, AlertTitle, AlertDescription }
+42
-39
apps/web/src/components/ui/avatar.tsx
+42
-39
apps/web/src/components/ui/avatar.tsx
···
3
3
4
4
import { cn } from "@/lib/utils"
5
5
6
-
const Avatar = React.forwardRef<
7
-
React.ElementRef<typeof AvatarPrimitive.Root>,
8
-
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
9
-
>(({ className, ...props }, ref) => (
10
-
<AvatarPrimitive.Root
11
-
ref={ref}
12
-
className={cn(
13
-
"relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
14
-
className
15
-
)}
16
-
{...props}
17
-
/>
18
-
))
19
-
Avatar.displayName = AvatarPrimitive.Root.displayName
6
+
function Avatar({
7
+
className,
8
+
...props
9
+
}: React.ComponentProps<typeof AvatarPrimitive.Root>) {
10
+
return (
11
+
<AvatarPrimitive.Root
12
+
data-slot="avatar"
13
+
className={cn(
14
+
"relative flex size-8 shrink-0 overflow-hidden rounded-full",
15
+
className
16
+
)}
17
+
{...props}
18
+
/>
19
+
)
20
+
}
20
21
21
-
const AvatarImage = React.forwardRef<
22
-
React.ElementRef<typeof AvatarPrimitive.Image>,
23
-
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
24
-
>(({ className, ...props }, ref) => (
25
-
<AvatarPrimitive.Image
26
-
ref={ref}
27
-
className={cn("aspect-square h-full w-full", className)}
28
-
{...props}
29
-
/>
30
-
))
31
-
AvatarImage.displayName = AvatarPrimitive.Image.displayName
22
+
function AvatarImage({
23
+
className,
24
+
...props
25
+
}: React.ComponentProps<typeof AvatarPrimitive.Image>) {
26
+
return (
27
+
<AvatarPrimitive.Image
28
+
data-slot="avatar-image"
29
+
className={cn("aspect-square size-full", className)}
30
+
{...props}
31
+
/>
32
+
)
33
+
}
32
34
33
-
const AvatarFallback = React.forwardRef<
34
-
React.ElementRef<typeof AvatarPrimitive.Fallback>,
35
-
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
36
-
>(({ className, ...props }, ref) => (
37
-
<AvatarPrimitive.Fallback
38
-
ref={ref}
39
-
className={cn(
40
-
"flex h-full w-full items-center justify-center rounded-full bg-muted",
41
-
className
42
-
)}
43
-
{...props}
44
-
/>
45
-
))
46
-
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName
35
+
function AvatarFallback({
36
+
className,
37
+
...props
38
+
}: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {
39
+
return (
40
+
<AvatarPrimitive.Fallback
41
+
data-slot="avatar-fallback"
42
+
className={cn(
43
+
"bg-muted flex size-full items-center justify-center rounded-full",
44
+
className
45
+
)}
46
+
{...props}
47
+
/>
48
+
)
49
+
}
47
50
48
51
export { Avatar, AvatarImage, AvatarFallback }
-36
apps/web/src/components/ui/badge.tsx
-36
apps/web/src/components/ui/badge.tsx
···
1
-
import * as React from "react"
2
-
import { cva, type VariantProps } from "class-variance-authority"
3
-
4
-
import { cn } from "@/lib/utils"
5
-
6
-
const badgeVariants = cva(
7
-
"inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
8
-
{
9
-
variants: {
10
-
variant: {
11
-
default:
12
-
"border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80",
13
-
secondary:
14
-
"border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
15
-
destructive:
16
-
"border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80",
17
-
outline: "text-foreground",
18
-
},
19
-
},
20
-
defaultVariants: {
21
-
variant: "default",
22
-
},
23
-
}
24
-
)
25
-
26
-
export interface BadgeProps
27
-
extends React.HTMLAttributes<HTMLDivElement>,
28
-
VariantProps<typeof badgeVariants> {}
29
-
30
-
function Badge({ className, variant, ...props }: BadgeProps) {
31
-
return (
32
-
<div className={cn(badgeVariants({ variant }), className)} {...props} />
33
-
)
34
-
}
35
-
36
-
export { Badge, badgeVariants }
+82
-66
apps/web/src/components/ui/card.tsx
+82
-66
apps/web/src/components/ui/card.tsx
···
2
2
3
3
import { cn } from "@/lib/utils"
4
4
5
-
const Card = React.forwardRef<
6
-
HTMLDivElement,
7
-
React.HTMLAttributes<HTMLDivElement>
8
-
>(({ className, ...props }, ref) => (
9
-
<div
10
-
ref={ref}
11
-
className={cn(
12
-
"rounded-xl border bg-card text-card-foreground shadow",
13
-
className
14
-
)}
15
-
{...props}
16
-
/>
17
-
))
18
-
Card.displayName = "Card"
5
+
function Card({ className, ...props }: React.ComponentProps<"div">) {
6
+
return (
7
+
<div
8
+
data-slot="card"
9
+
className={cn(
10
+
"bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm",
11
+
className
12
+
)}
13
+
{...props}
14
+
/>
15
+
)
16
+
}
19
17
20
-
const CardHeader = React.forwardRef<
21
-
HTMLDivElement,
22
-
React.HTMLAttributes<HTMLDivElement>
23
-
>(({ className, ...props }, ref) => (
24
-
<div
25
-
ref={ref}
26
-
className={cn("flex flex-col space-y-1.5 p-6", className)}
27
-
{...props}
28
-
/>
29
-
))
30
-
CardHeader.displayName = "CardHeader"
18
+
function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
19
+
return (
20
+
<div
21
+
data-slot="card-header"
22
+
className={cn(
23
+
"@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6",
24
+
className
25
+
)}
26
+
{...props}
27
+
/>
28
+
)
29
+
}
31
30
32
-
const CardTitle = React.forwardRef<
33
-
HTMLDivElement,
34
-
React.HTMLAttributes<HTMLDivElement>
35
-
>(({ className, ...props }, ref) => (
36
-
<div
37
-
ref={ref}
38
-
className={cn("font-semibold leading-none tracking-tight", className)}
39
-
{...props}
40
-
/>
41
-
))
42
-
CardTitle.displayName = "CardTitle"
31
+
function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
32
+
return (
33
+
<div
34
+
data-slot="card-title"
35
+
className={cn("leading-none font-semibold", className)}
36
+
{...props}
37
+
/>
38
+
)
39
+
}
43
40
44
-
const CardDescription = React.forwardRef<
45
-
HTMLDivElement,
46
-
React.HTMLAttributes<HTMLDivElement>
47
-
>(({ className, ...props }, ref) => (
48
-
<div
49
-
ref={ref}
50
-
className={cn("text-sm text-muted-foreground", className)}
51
-
{...props}
52
-
/>
53
-
))
54
-
CardDescription.displayName = "CardDescription"
41
+
function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
42
+
return (
43
+
<div
44
+
data-slot="card-description"
45
+
className={cn("text-muted-foreground text-sm", className)}
46
+
{...props}
47
+
/>
48
+
)
49
+
}
55
50
56
-
const CardContent = React.forwardRef<
57
-
HTMLDivElement,
58
-
React.HTMLAttributes<HTMLDivElement>
59
-
>(({ className, ...props }, ref) => (
60
-
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
61
-
))
62
-
CardContent.displayName = "CardContent"
51
+
function CardAction({ className, ...props }: React.ComponentProps<"div">) {
52
+
return (
53
+
<div
54
+
data-slot="card-action"
55
+
className={cn(
56
+
"col-start-2 row-span-2 row-start-1 self-start justify-self-end",
57
+
className
58
+
)}
59
+
{...props}
60
+
/>
61
+
)
62
+
}
63
63
64
-
const CardFooter = React.forwardRef<
65
-
HTMLDivElement,
66
-
React.HTMLAttributes<HTMLDivElement>
67
-
>(({ className, ...props }, ref) => (
68
-
<div
69
-
ref={ref}
70
-
className={cn("flex items-center p-6 pt-0", className)}
71
-
{...props}
72
-
/>
73
-
))
74
-
CardFooter.displayName = "CardFooter"
64
+
function CardContent({ className, ...props }: React.ComponentProps<"div">) {
65
+
return (
66
+
<div
67
+
data-slot="card-content"
68
+
className={cn("px-6", className)}
69
+
{...props}
70
+
/>
71
+
)
72
+
}
73
+
74
+
function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
75
+
return (
76
+
<div
77
+
data-slot="card-footer"
78
+
className={cn("flex items-center px-6 [.border-t]:pt-6", className)}
79
+
{...props}
80
+
/>
81
+
)
82
+
}
75
83
76
-
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
84
+
export {
85
+
Card,
86
+
CardHeader,
87
+
CardFooter,
88
+
CardTitle,
89
+
CardAction,
90
+
CardDescription,
91
+
CardContent,
92
+
}
-9
apps/web/src/components/ui/collapsible.tsx
-9
apps/web/src/components/ui/collapsible.tsx
···
1
-
import * as CollapsiblePrimitive from "@radix-ui/react-collapsible"
2
-
3
-
const Collapsible = CollapsiblePrimitive.Root
4
-
5
-
const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger
6
-
7
-
const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent
8
-
9
-
export { Collapsible, CollapsibleTrigger, CollapsibleContent }
+248
apps/web/src/components/ui/field.tsx
+248
apps/web/src/components/ui/field.tsx
···
1
+
"use client"
2
+
3
+
import { useMemo } from "react"
4
+
import { cva, type VariantProps } from "class-variance-authority"
5
+
6
+
import { cn } from "@/lib/utils"
7
+
import { Label } from "@/components/ui/label"
8
+
import { Separator } from "@/components/ui/separator"
9
+
10
+
function FieldSet({ className, ...props }: React.ComponentProps<"fieldset">) {
11
+
return (
12
+
<fieldset
13
+
data-slot="field-set"
14
+
className={cn(
15
+
"flex flex-col gap-6",
16
+
"has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3",
17
+
className
18
+
)}
19
+
{...props}
20
+
/>
21
+
)
22
+
}
23
+
24
+
function FieldLegend({
25
+
className,
26
+
variant = "legend",
27
+
...props
28
+
}: React.ComponentProps<"legend"> & { variant?: "legend" | "label" }) {
29
+
return (
30
+
<legend
31
+
data-slot="field-legend"
32
+
data-variant={variant}
33
+
className={cn(
34
+
"mb-3 font-medium",
35
+
"data-[variant=legend]:text-base",
36
+
"data-[variant=label]:text-sm",
37
+
className
38
+
)}
39
+
{...props}
40
+
/>
41
+
)
42
+
}
43
+
44
+
function FieldGroup({ className, ...props }: React.ComponentProps<"div">) {
45
+
return (
46
+
<div
47
+
data-slot="field-group"
48
+
className={cn(
49
+
"group/field-group @container/field-group flex w-full flex-col gap-7 data-[slot=checkbox-group]:gap-3 [&>[data-slot=field-group]]:gap-4",
50
+
className
51
+
)}
52
+
{...props}
53
+
/>
54
+
)
55
+
}
56
+
57
+
const fieldVariants = cva(
58
+
"group/field flex w-full gap-3 data-[invalid=true]:text-destructive",
59
+
{
60
+
variants: {
61
+
orientation: {
62
+
vertical: ["flex-col [&>*]:w-full [&>.sr-only]:w-auto"],
63
+
horizontal: [
64
+
"flex-row items-center",
65
+
"[&>[data-slot=field-label]]:flex-auto",
66
+
"has-[>[data-slot=field-content]]:items-start has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px",
67
+
],
68
+
responsive: [
69
+
"flex-col [&>*]:w-full [&>.sr-only]:w-auto @md/field-group:flex-row @md/field-group:items-center @md/field-group:[&>*]:w-auto",
70
+
"@md/field-group:[&>[data-slot=field-label]]:flex-auto",
71
+
"@md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px",
72
+
],
73
+
},
74
+
},
75
+
defaultVariants: {
76
+
orientation: "vertical",
77
+
},
78
+
}
79
+
)
80
+
81
+
function Field({
82
+
className,
83
+
orientation = "vertical",
84
+
...props
85
+
}: React.ComponentProps<"div"> & VariantProps<typeof fieldVariants>) {
86
+
return (
87
+
<div
88
+
role="group"
89
+
data-slot="field"
90
+
data-orientation={orientation}
91
+
className={cn(fieldVariants({ orientation }), className)}
92
+
{...props}
93
+
/>
94
+
)
95
+
}
96
+
97
+
function FieldContent({ className, ...props }: React.ComponentProps<"div">) {
98
+
return (
99
+
<div
100
+
data-slot="field-content"
101
+
className={cn(
102
+
"group/field-content flex flex-1 flex-col gap-1.5 leading-snug",
103
+
className
104
+
)}
105
+
{...props}
106
+
/>
107
+
)
108
+
}
109
+
110
+
function FieldLabel({
111
+
className,
112
+
...props
113
+
}: React.ComponentProps<typeof Label>) {
114
+
return (
115
+
<Label
116
+
data-slot="field-label"
117
+
className={cn(
118
+
"group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50",
119
+
"has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col has-[>[data-slot=field]]:rounded-md has-[>[data-slot=field]]:border [&>*]:data-[slot=field]:p-4",
120
+
"has-data-[state=checked]:bg-primary/5 has-data-[state=checked]:border-primary dark:has-data-[state=checked]:bg-primary/10",
121
+
className
122
+
)}
123
+
{...props}
124
+
/>
125
+
)
126
+
}
127
+
128
+
function FieldTitle({ className, ...props }: React.ComponentProps<"div">) {
129
+
return (
130
+
<div
131
+
data-slot="field-label"
132
+
className={cn(
133
+
"flex w-fit items-center gap-2 text-sm leading-snug font-medium group-data-[disabled=true]/field:opacity-50",
134
+
className
135
+
)}
136
+
{...props}
137
+
/>
138
+
)
139
+
}
140
+
141
+
function FieldDescription({ className, ...props }: React.ComponentProps<"p">) {
142
+
return (
143
+
<p
144
+
data-slot="field-description"
145
+
className={cn(
146
+
"text-muted-foreground text-sm leading-normal font-normal group-has-[[data-orientation=horizontal]]/field:text-balance",
147
+
"last:mt-0 nth-last-2:-mt-1 [[data-variant=legend]+&]:-mt-1.5",
148
+
"[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4",
149
+
className
150
+
)}
151
+
{...props}
152
+
/>
153
+
)
154
+
}
155
+
156
+
function FieldSeparator({
157
+
children,
158
+
className,
159
+
...props
160
+
}: React.ComponentProps<"div"> & {
161
+
children?: React.ReactNode
162
+
}) {
163
+
return (
164
+
<div
165
+
data-slot="field-separator"
166
+
data-content={!!children}
167
+
className={cn(
168
+
"relative -my-2 h-5 text-sm group-data-[variant=outline]/field-group:-mb-2",
169
+
className
170
+
)}
171
+
{...props}
172
+
>
173
+
<Separator className="absolute inset-0 top-1/2" />
174
+
{children && (
175
+
<span
176
+
className="bg-background text-muted-foreground relative mx-auto block w-fit px-2"
177
+
data-slot="field-separator-content"
178
+
>
179
+
{children}
180
+
</span>
181
+
)}
182
+
</div>
183
+
)
184
+
}
185
+
186
+
function FieldError({
187
+
className,
188
+
children,
189
+
errors,
190
+
...props
191
+
}: React.ComponentProps<"div"> & {
192
+
errors?: Array<{ message?: string } | undefined>
193
+
}) {
194
+
const content = useMemo(() => {
195
+
if (children) {
196
+
return children
197
+
}
198
+
199
+
if (!errors?.length) {
200
+
return null
201
+
}
202
+
203
+
const uniqueErrors = [
204
+
...new Map(errors.map((error) => [error?.message, error])).values(),
205
+
]
206
+
207
+
if (uniqueErrors?.length == 1) {
208
+
return uniqueErrors[0]?.message
209
+
}
210
+
211
+
return (
212
+
<ul className="ml-4 flex list-disc flex-col gap-1">
213
+
{uniqueErrors.map(
214
+
(error, index) =>
215
+
error?.message && <li key={index}>{error.message}</li>
216
+
)}
217
+
</ul>
218
+
)
219
+
}, [children, errors])
220
+
221
+
if (!content) {
222
+
return null
223
+
}
224
+
225
+
return (
226
+
<div
227
+
role="alert"
228
+
data-slot="field-error"
229
+
className={cn("text-destructive text-sm font-normal", className)}
230
+
{...props}
231
+
>
232
+
{content}
233
+
</div>
234
+
)
235
+
}
236
+
237
+
export {
238
+
Field,
239
+
FieldLabel,
240
+
FieldDescription,
241
+
FieldError,
242
+
FieldGroup,
243
+
FieldLegend,
244
+
FieldSeparator,
245
+
FieldSet,
246
+
FieldContent,
247
+
FieldTitle,
248
+
}
-176
apps/web/src/components/ui/form.tsx
-176
apps/web/src/components/ui/form.tsx
···
1
-
import * as React from "react"
2
-
import * as LabelPrimitive from "@radix-ui/react-label"
3
-
import { Slot } from "@radix-ui/react-slot"
4
-
import {
5
-
Controller,
6
-
ControllerProps,
7
-
FieldPath,
8
-
FieldValues,
9
-
FormProvider,
10
-
useFormContext,
11
-
} from "react-hook-form"
12
-
13
-
import { cn } from "@/lib/utils"
14
-
import { Label } from "@/components/ui/label"
15
-
16
-
const Form = FormProvider
17
-
18
-
type FormFieldContextValue<
19
-
TFieldValues extends FieldValues = FieldValues,
20
-
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
21
-
> = {
22
-
name: TName
23
-
}
24
-
25
-
const FormFieldContext = React.createContext<FormFieldContextValue>(
26
-
{} as FormFieldContextValue
27
-
)
28
-
29
-
const FormField = <
30
-
TFieldValues extends FieldValues = FieldValues,
31
-
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
32
-
>({
33
-
...props
34
-
}: ControllerProps<TFieldValues, TName>) => {
35
-
return (
36
-
<FormFieldContext.Provider value={{ name: props.name }}>
37
-
<Controller {...props} />
38
-
</FormFieldContext.Provider>
39
-
)
40
-
}
41
-
42
-
const useFormField = () => {
43
-
const fieldContext = React.useContext(FormFieldContext)
44
-
const itemContext = React.useContext(FormItemContext)
45
-
const { getFieldState, formState } = useFormContext()
46
-
47
-
const fieldState = getFieldState(fieldContext.name, formState)
48
-
49
-
if (!fieldContext) {
50
-
throw new Error("useFormField should be used within <FormField>")
51
-
}
52
-
53
-
const { id } = itemContext
54
-
55
-
return {
56
-
id,
57
-
name: fieldContext.name,
58
-
formItemId: `${id}-form-item`,
59
-
formDescriptionId: `${id}-form-item-description`,
60
-
formMessageId: `${id}-form-item-message`,
61
-
...fieldState,
62
-
}
63
-
}
64
-
65
-
type FormItemContextValue = {
66
-
id: string
67
-
}
68
-
69
-
const FormItemContext = React.createContext<FormItemContextValue>(
70
-
{} as FormItemContextValue
71
-
)
72
-
73
-
const FormItem = React.forwardRef<
74
-
HTMLDivElement,
75
-
React.HTMLAttributes<HTMLDivElement>
76
-
>(({ className, ...props }, ref) => {
77
-
const id = React.useId()
78
-
79
-
return (
80
-
<FormItemContext.Provider value={{ id }}>
81
-
<div ref={ref} className={cn("space-y-2", className)} {...props} />
82
-
</FormItemContext.Provider>
83
-
)
84
-
})
85
-
FormItem.displayName = "FormItem"
86
-
87
-
const FormLabel = React.forwardRef<
88
-
React.ElementRef<typeof LabelPrimitive.Root>,
89
-
React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root>
90
-
>(({ className, ...props }, ref) => {
91
-
const { error, formItemId } = useFormField()
92
-
93
-
return (
94
-
<Label
95
-
ref={ref}
96
-
className={cn(error && "text-destructive", className)}
97
-
htmlFor={formItemId}
98
-
{...props}
99
-
/>
100
-
)
101
-
})
102
-
FormLabel.displayName = "FormLabel"
103
-
104
-
const FormControl = React.forwardRef<
105
-
React.ElementRef<typeof Slot>,
106
-
React.ComponentPropsWithoutRef<typeof Slot>
107
-
>(({ ...props }, ref) => {
108
-
const { error, formItemId, formDescriptionId, formMessageId } = useFormField()
109
-
110
-
return (
111
-
<Slot
112
-
ref={ref}
113
-
id={formItemId}
114
-
aria-describedby={
115
-
!error
116
-
? `${formDescriptionId}`
117
-
: `${formDescriptionId} ${formMessageId}`
118
-
}
119
-
aria-invalid={!!error}
120
-
{...props}
121
-
/>
122
-
)
123
-
})
124
-
FormControl.displayName = "FormControl"
125
-
126
-
const FormDescription = React.forwardRef<
127
-
HTMLParagraphElement,
128
-
React.HTMLAttributes<HTMLParagraphElement>
129
-
>(({ className, ...props }, ref) => {
130
-
const { formDescriptionId } = useFormField()
131
-
132
-
return (
133
-
<p
134
-
ref={ref}
135
-
id={formDescriptionId}
136
-
className={cn("text-[0.8rem] text-muted-foreground", className)}
137
-
{...props}
138
-
/>
139
-
)
140
-
})
141
-
FormDescription.displayName = "FormDescription"
142
-
143
-
const FormMessage = React.forwardRef<
144
-
HTMLParagraphElement,
145
-
React.HTMLAttributes<HTMLParagraphElement>
146
-
>(({ className, children, ...props }, ref) => {
147
-
const { error, formMessageId } = useFormField()
148
-
const body = error ? String(error?.message) : children
149
-
150
-
if (!body) {
151
-
return null
152
-
}
153
-
154
-
return (
155
-
<p
156
-
ref={ref}
157
-
id={formMessageId}
158
-
className={cn("text-[0.8rem] font-medium text-destructive", className)}
159
-
{...props}
160
-
>
161
-
{body}
162
-
</p>
163
-
)
164
-
})
165
-
FormMessage.displayName = "FormMessage"
166
-
167
-
export {
168
-
useFormField,
169
-
Form,
170
-
FormItem,
171
-
FormLabel,
172
-
FormControl,
173
-
FormDescription,
174
-
FormMessage,
175
-
FormField,
176
-
}
+168
apps/web/src/components/ui/input-group.tsx
+168
apps/web/src/components/ui/input-group.tsx
···
1
+
import * as React from "react"
2
+
import { cva, type VariantProps } from "class-variance-authority"
3
+
4
+
import { cn } from "@/lib/utils"
5
+
import { Button } from "@/components/ui/button"
6
+
import { Input } from "@/components/ui/input"
7
+
import { Textarea } from "@/components/ui/textarea"
8
+
9
+
function InputGroup({ className, ...props }: React.ComponentProps<"div">) {
10
+
return (
11
+
<div
12
+
data-slot="input-group"
13
+
role="group"
14
+
className={cn(
15
+
"group/input-group border-input dark:bg-input/30 relative flex w-full items-center rounded-md border shadow-xs transition-[color,box-shadow] outline-none",
16
+
"h-9 min-w-0 has-[>textarea]:h-auto",
17
+
18
+
// Variants based on alignment.
19
+
"has-[>[data-align=inline-start]]:[&>input]:pl-2",
20
+
"has-[>[data-align=inline-end]]:[&>input]:pr-2",
21
+
"has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-start]]:[&>input]:pb-3",
22
+
"has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-3",
23
+
24
+
// Focus state.
25
+
"has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot=input-group-control]:focus-visible]:ring-[3px]",
26
+
27
+
// Error state.
28
+
"has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[[data-slot][aria-invalid=true]]:border-destructive dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40",
29
+
30
+
className
31
+
)}
32
+
{...props}
33
+
/>
34
+
)
35
+
}
36
+
37
+
const inputGroupAddonVariants = cva(
38
+
"text-muted-foreground flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium select-none [&>svg:not([class*='size-'])]:size-4 [&>kbd]:rounded-[calc(var(--radius)-5px)] group-data-[disabled=true]/input-group:opacity-50",
39
+
{
40
+
variants: {
41
+
align: {
42
+
"inline-start":
43
+
"order-first pl-3 has-[>button]:ml-[-0.45rem] has-[>kbd]:ml-[-0.35rem]",
44
+
"inline-end":
45
+
"order-last pr-3 has-[>button]:mr-[-0.45rem] has-[>kbd]:mr-[-0.35rem]",
46
+
"block-start":
47
+
"order-first w-full justify-start px-3 pt-3 [.border-b]:pb-3 group-has-[>input]/input-group:pt-2.5",
48
+
"block-end":
49
+
"order-last w-full justify-start px-3 pb-3 [.border-t]:pt-3 group-has-[>input]/input-group:pb-2.5",
50
+
},
51
+
},
52
+
defaultVariants: {
53
+
align: "inline-start",
54
+
},
55
+
}
56
+
)
57
+
58
+
function InputGroupAddon({
59
+
className,
60
+
align = "inline-start",
61
+
...props
62
+
}: React.ComponentProps<"div"> & VariantProps<typeof inputGroupAddonVariants>) {
63
+
return (
64
+
<div
65
+
role="group"
66
+
data-slot="input-group-addon"
67
+
data-align={align}
68
+
className={cn(inputGroupAddonVariants({ align }), className)}
69
+
onClick={(e) => {
70
+
if ((e.target as HTMLElement).closest("button")) {
71
+
return
72
+
}
73
+
e.currentTarget.parentElement?.querySelector("input")?.focus()
74
+
}}
75
+
{...props}
76
+
/>
77
+
)
78
+
}
79
+
80
+
const inputGroupButtonVariants = cva(
81
+
"text-sm shadow-none flex gap-2 items-center",
82
+
{
83
+
variants: {
84
+
size: {
85
+
xs: "h-6 gap-1 px-2 rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-3.5 has-[>svg]:px-2",
86
+
sm: "h-8 px-2.5 gap-1.5 rounded-md has-[>svg]:px-2.5",
87
+
"icon-xs":
88
+
"size-6 rounded-[calc(var(--radius)-5px)] p-0 has-[>svg]:p-0",
89
+
"icon-sm": "size-8 p-0 has-[>svg]:p-0",
90
+
},
91
+
},
92
+
defaultVariants: {
93
+
size: "xs",
94
+
},
95
+
}
96
+
)
97
+
98
+
function InputGroupButton({
99
+
className,
100
+
type = "button",
101
+
variant = "ghost",
102
+
size = "xs",
103
+
...props
104
+
}: Omit<React.ComponentProps<typeof Button>, "size"> &
105
+
VariantProps<typeof inputGroupButtonVariants>) {
106
+
return (
107
+
<Button
108
+
type={type}
109
+
data-size={size}
110
+
variant={variant}
111
+
className={cn(inputGroupButtonVariants({ size }), className)}
112
+
{...props}
113
+
/>
114
+
)
115
+
}
116
+
117
+
function InputGroupText({ className, ...props }: React.ComponentProps<"span">) {
118
+
return (
119
+
<span
120
+
className={cn(
121
+
"text-muted-foreground flex items-center gap-2 text-sm [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4",
122
+
className
123
+
)}
124
+
{...props}
125
+
/>
126
+
)
127
+
}
128
+
129
+
function InputGroupInput({
130
+
className,
131
+
...props
132
+
}: React.ComponentProps<"input">) {
133
+
return (
134
+
<Input
135
+
data-slot="input-group-control"
136
+
className={cn(
137
+
"flex-1 rounded-none border-0 bg-transparent shadow-none focus-visible:ring-0 dark:bg-transparent",
138
+
className
139
+
)}
140
+
{...props}
141
+
/>
142
+
)
143
+
}
144
+
145
+
function InputGroupTextarea({
146
+
className,
147
+
...props
148
+
}: React.ComponentProps<"textarea">) {
149
+
return (
150
+
<Textarea
151
+
data-slot="input-group-control"
152
+
className={cn(
153
+
"flex-1 resize-none rounded-none border-0 bg-transparent py-3 shadow-none focus-visible:ring-0 dark:bg-transparent",
154
+
className
155
+
)}
156
+
{...props}
157
+
/>
158
+
)
159
+
}
160
+
161
+
export {
162
+
InputGroup,
163
+
InputGroupAddon,
164
+
InputGroupButton,
165
+
InputGroupText,
166
+
InputGroupInput,
167
+
InputGroupTextarea,
168
+
}
+15
-16
apps/web/src/components/ui/input.tsx
+15
-16
apps/web/src/components/ui/input.tsx
···
2
2
3
3
import { cn } from "@/lib/utils"
4
4
5
-
const Input = React.forwardRef<HTMLInputElement, React.ComponentProps<"input">>(
6
-
({ className, type, ...props }, ref) => {
7
-
return (
8
-
<input
9
-
type={type}
10
-
className={cn(
11
-
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
12
-
className
13
-
)}
14
-
ref={ref}
15
-
{...props}
16
-
/>
17
-
)
18
-
}
19
-
)
20
-
Input.displayName = "Input"
5
+
function Input({ className, type, ...props }: React.ComponentProps<"input">) {
6
+
return (
7
+
<input
8
+
type={type}
9
+
data-slot="input"
10
+
className={cn(
11
+
"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
12
+
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
13
+
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
14
+
className
15
+
)}
16
+
{...props}
17
+
/>
18
+
)
19
+
}
21
20
22
21
export { Input }
+15
-17
apps/web/src/components/ui/label.tsx
+15
-17
apps/web/src/components/ui/label.tsx
···
1
1
import * as React from "react"
2
2
import * as LabelPrimitive from "@radix-ui/react-label"
3
-
import { cva, type VariantProps } from "class-variance-authority"
4
3
5
4
import { cn } from "@/lib/utils"
6
5
7
-
const labelVariants = cva(
8
-
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
9
-
)
10
-
11
-
const Label = React.forwardRef<
12
-
React.ElementRef<typeof LabelPrimitive.Root>,
13
-
React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> &
14
-
VariantProps<typeof labelVariants>
15
-
>(({ className, ...props }, ref) => (
16
-
<LabelPrimitive.Root
17
-
ref={ref}
18
-
className={cn(labelVariants(), className)}
19
-
{...props}
20
-
/>
21
-
))
22
-
Label.displayName = LabelPrimitive.Root.displayName
6
+
function Label({
7
+
className,
8
+
...props
9
+
}: React.ComponentProps<typeof LabelPrimitive.Root>) {
10
+
return (
11
+
<LabelPrimitive.Root
12
+
data-slot="label"
13
+
className={cn(
14
+
"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
15
+
className
16
+
)}
17
+
{...props}
18
+
/>
19
+
)
20
+
}
23
21
24
22
export { Label }
+12
-13
apps/web/src/components/ui/separator.tsx
+12
-13
apps/web/src/components/ui/separator.tsx
···
1
+
"use client"
2
+
1
3
import * as React from "react"
2
4
import * as SeparatorPrimitive from "@radix-ui/react-separator"
3
5
4
6
import { cn } from "@/lib/utils"
5
7
6
-
const Separator = React.forwardRef<
7
-
React.ElementRef<typeof SeparatorPrimitive.Root>,
8
-
React.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root>
9
-
>(
10
-
(
11
-
{ className, orientation = "horizontal", decorative = true, ...props },
12
-
ref
13
-
) => (
8
+
function Separator({
9
+
className,
10
+
orientation = "horizontal",
11
+
decorative = true,
12
+
...props
13
+
}: React.ComponentProps<typeof SeparatorPrimitive.Root>) {
14
+
return (
14
15
<SeparatorPrimitive.Root
15
-
ref={ref}
16
+
data-slot="separator"
16
17
decorative={decorative}
17
18
orientation={orientation}
18
19
className={cn(
19
-
"shrink-0 bg-border",
20
-
orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
20
+
"bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
21
21
className
22
22
)}
23
23
{...props}
24
24
/>
25
25
)
26
-
)
27
-
Separator.displayName = SeparatorPrimitive.Root.displayName
26
+
}
28
27
29
28
export { Separator }
+107
-110
apps/web/src/components/ui/sheet.tsx
+107
-110
apps/web/src/components/ui/sheet.tsx
···
1
-
"use client"
2
-
3
1
import * as React from "react"
4
2
import * as SheetPrimitive from "@radix-ui/react-dialog"
5
-
import { cva, type VariantProps } from "class-variance-authority"
6
-
import { X } from "lucide-react"
3
+
import { XIcon } from "lucide-react"
7
4
8
5
import { cn } from "@/lib/utils"
9
6
10
-
const Sheet = SheetPrimitive.Root
7
+
function Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {
8
+
return <SheetPrimitive.Root data-slot="sheet" {...props} />
9
+
}
11
10
12
-
const SheetTrigger = SheetPrimitive.Trigger
11
+
function SheetTrigger({
12
+
...props
13
+
}: React.ComponentProps<typeof SheetPrimitive.Trigger>) {
14
+
return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />
15
+
}
13
16
14
-
const SheetClose = SheetPrimitive.Close
17
+
function SheetClose({
18
+
...props
19
+
}: React.ComponentProps<typeof SheetPrimitive.Close>) {
20
+
return <SheetPrimitive.Close data-slot="sheet-close" {...props} />
21
+
}
15
22
16
-
const SheetPortal = SheetPrimitive.Portal
23
+
function SheetPortal({
24
+
...props
25
+
}: React.ComponentProps<typeof SheetPrimitive.Portal>) {
26
+
return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />
27
+
}
17
28
18
-
const SheetOverlay = React.forwardRef<
19
-
React.ElementRef<typeof SheetPrimitive.Overlay>,
20
-
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>
21
-
>(({ className, ...props }, ref) => (
22
-
<SheetPrimitive.Overlay
23
-
className={cn(
24
-
"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
25
-
className
26
-
)}
27
-
{...props}
28
-
ref={ref}
29
-
/>
30
-
))
31
-
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName
29
+
function SheetOverlay({
30
+
className,
31
+
...props
32
+
}: React.ComponentProps<typeof SheetPrimitive.Overlay>) {
33
+
return (
34
+
<SheetPrimitive.Overlay
35
+
data-slot="sheet-overlay"
36
+
className={cn(
37
+
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
38
+
className
39
+
)}
40
+
{...props}
41
+
/>
42
+
)
43
+
}
32
44
33
-
const sheetVariants = cva(
34
-
"fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500 data-[state=open]:animate-in data-[state=closed]:animate-out",
35
-
{
36
-
variants: {
37
-
side: {
38
-
top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
39
-
bottom:
40
-
"inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
41
-
left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
42
-
right:
43
-
"inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
44
-
},
45
-
},
46
-
defaultVariants: {
47
-
side: "right",
48
-
},
49
-
}
50
-
)
45
+
function SheetContent({
46
+
className,
47
+
children,
48
+
side = "right",
49
+
...props
50
+
}: React.ComponentProps<typeof SheetPrimitive.Content> & {
51
+
side?: "top" | "right" | "bottom" | "left"
52
+
}) {
53
+
return (
54
+
<SheetPortal>
55
+
<SheetOverlay />
56
+
<SheetPrimitive.Content
57
+
data-slot="sheet-content"
58
+
className={cn(
59
+
"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
60
+
side === "right" &&
61
+
"data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm",
62
+
side === "left" &&
63
+
"data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm",
64
+
side === "top" &&
65
+
"data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b",
66
+
side === "bottom" &&
67
+
"data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t",
68
+
className
69
+
)}
70
+
{...props}
71
+
>
72
+
{children}
73
+
<SheetPrimitive.Close className="ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none">
74
+
<XIcon className="size-4" />
75
+
<span className="sr-only">Close</span>
76
+
</SheetPrimitive.Close>
77
+
</SheetPrimitive.Content>
78
+
</SheetPortal>
79
+
)
80
+
}
51
81
52
-
interface SheetContentProps
53
-
extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,
54
-
VariantProps<typeof sheetVariants> {}
82
+
function SheetHeader({ className, ...props }: React.ComponentProps<"div">) {
83
+
return (
84
+
<div
85
+
data-slot="sheet-header"
86
+
className={cn("flex flex-col gap-1.5 p-4", className)}
87
+
{...props}
88
+
/>
89
+
)
90
+
}
55
91
56
-
const SheetContent = React.forwardRef<
57
-
React.ElementRef<typeof SheetPrimitive.Content>,
58
-
SheetContentProps
59
-
>(({ side = "right", className, children, ...props }, ref) => (
60
-
<SheetPortal>
61
-
<SheetOverlay />
62
-
<SheetPrimitive.Content
63
-
ref={ref}
64
-
className={cn(sheetVariants({ side }), className)}
92
+
function SheetFooter({ className, ...props }: React.ComponentProps<"div">) {
93
+
return (
94
+
<div
95
+
data-slot="sheet-footer"
96
+
className={cn("mt-auto flex flex-col gap-2 p-4", className)}
65
97
{...props}
66
-
>
67
-
<SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary">
68
-
<X className="h-4 w-4" />
69
-
<span className="sr-only">Close</span>
70
-
</SheetPrimitive.Close>
71
-
{children}
72
-
</SheetPrimitive.Content>
73
-
</SheetPortal>
74
-
))
75
-
SheetContent.displayName = SheetPrimitive.Content.displayName
98
+
/>
99
+
)
100
+
}
76
101
77
-
const SheetHeader = ({
102
+
function SheetTitle({
78
103
className,
79
104
...props
80
-
}: React.HTMLAttributes<HTMLDivElement>) => (
81
-
<div
82
-
className={cn(
83
-
"flex flex-col space-y-2 text-center sm:text-left",
84
-
className
85
-
)}
86
-
{...props}
87
-
/>
88
-
)
89
-
SheetHeader.displayName = "SheetHeader"
105
+
}: React.ComponentProps<typeof SheetPrimitive.Title>) {
106
+
return (
107
+
<SheetPrimitive.Title
108
+
data-slot="sheet-title"
109
+
className={cn("text-foreground font-semibold", className)}
110
+
{...props}
111
+
/>
112
+
)
113
+
}
90
114
91
-
const SheetFooter = ({
115
+
function SheetDescription({
92
116
className,
93
117
...props
94
-
}: React.HTMLAttributes<HTMLDivElement>) => (
95
-
<div
96
-
className={cn(
97
-
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
98
-
className
99
-
)}
100
-
{...props}
101
-
/>
102
-
)
103
-
SheetFooter.displayName = "SheetFooter"
104
-
105
-
const SheetTitle = React.forwardRef<
106
-
React.ElementRef<typeof SheetPrimitive.Title>,
107
-
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>
108
-
>(({ className, ...props }, ref) => (
109
-
<SheetPrimitive.Title
110
-
ref={ref}
111
-
className={cn("text-lg font-semibold text-foreground", className)}
112
-
{...props}
113
-
/>
114
-
))
115
-
SheetTitle.displayName = SheetPrimitive.Title.displayName
116
-
117
-
const SheetDescription = React.forwardRef<
118
-
React.ElementRef<typeof SheetPrimitive.Description>,
119
-
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>
120
-
>(({ className, ...props }, ref) => (
121
-
<SheetPrimitive.Description
122
-
ref={ref}
123
-
className={cn("text-sm text-muted-foreground", className)}
124
-
{...props}
125
-
/>
126
-
))
127
-
SheetDescription.displayName = SheetPrimitive.Description.displayName
118
+
}: React.ComponentProps<typeof SheetPrimitive.Description>) {
119
+
return (
120
+
<SheetPrimitive.Description
121
+
data-slot="sheet-description"
122
+
className={cn("text-muted-foreground text-sm", className)}
123
+
{...props}
124
+
/>
125
+
)
126
+
}
128
127
129
128
export {
130
129
Sheet,
131
-
SheetPortal,
132
-
SheetOverlay,
133
130
SheetTrigger,
134
131
SheetClose,
135
132
SheetContent,
+3
-5
apps/web/src/components/ui/skeleton.tsx
+3
-5
apps/web/src/components/ui/skeleton.tsx
···
1
1
import { cn } from "@/lib/utils"
2
2
3
-
function Skeleton({
4
-
className,
5
-
...props
6
-
}: React.HTMLAttributes<HTMLDivElement>) {
3
+
function Skeleton({ className, ...props }: React.ComponentProps<"div">) {
7
4
return (
8
5
<div
9
-
className={cn("animate-pulse rounded-md bg-primary/10", className)}
6
+
data-slot="skeleton"
7
+
className={cn("bg-accent animate-pulse rounded-md", className)}
10
8
{...props}
11
9
/>
12
10
)
-336
apps/web/src/components/ui/sortable.tsx
-336
apps/web/src/components/ui/sortable.tsx
···
1
-
"use client"
2
-
3
-
import * as React from "react"
4
-
import type {
5
-
DndContextProps,
6
-
DraggableSyntheticListeners,
7
-
DropAnimation,
8
-
UniqueIdentifier,
9
-
} from "@dnd-kit/core"
10
-
import {
11
-
closestCenter,
12
-
defaultDropAnimationSideEffects,
13
-
DndContext,
14
-
DragOverlay,
15
-
KeyboardSensor,
16
-
MouseSensor,
17
-
TouchSensor,
18
-
useSensor,
19
-
useSensors,
20
-
} from "@dnd-kit/core"
21
-
import {
22
-
restrictToHorizontalAxis,
23
-
restrictToParentElement,
24
-
restrictToVerticalAxis,
25
-
} from "@dnd-kit/modifiers"
26
-
import {
27
-
arrayMove,
28
-
horizontalListSortingStrategy,
29
-
SortableContext,
30
-
useSortable,
31
-
verticalListSortingStrategy,
32
-
type SortableContextProps,
33
-
} from "@dnd-kit/sortable"
34
-
import { CSS } from "@dnd-kit/utilities"
35
-
import { Slot, type SlotProps } from "@radix-ui/react-slot"
36
-
37
-
import { composeRefs } from "@/lib/compose-refs"
38
-
import { cn } from "@/lib/utils"
39
-
import { Button, type ButtonProps } from "@/components/ui/button"
40
-
41
-
const orientationConfig = {
42
-
vertical: {
43
-
modifiers: [restrictToVerticalAxis, restrictToParentElement],
44
-
strategy: verticalListSortingStrategy,
45
-
},
46
-
horizontal: {
47
-
modifiers: [restrictToHorizontalAxis, restrictToParentElement],
48
-
strategy: horizontalListSortingStrategy,
49
-
},
50
-
mixed: {
51
-
modifiers: [restrictToParentElement],
52
-
strategy: undefined,
53
-
},
54
-
}
55
-
56
-
interface SortableProps<TData extends { id: UniqueIdentifier }>
57
-
extends DndContextProps {
58
-
/**
59
-
* An array of data items that the sortable component will render.
60
-
* @example
61
-
* value={[
62
-
* { id: 1, name: 'Item 1' },
63
-
* { id: 2, name: 'Item 2' },
64
-
* ]}
65
-
*/
66
-
value: TData[]
67
-
68
-
/**
69
-
* An optional callback function that is called when the order of the data items changes.
70
-
* It receives the new array of items as its argument.
71
-
* @example
72
-
* onValueChange={(items) => console.log(items)}
73
-
*/
74
-
onValueChange?: (items: TData[]) => void
75
-
76
-
/**
77
-
* An optional callback function that is called when an item is moved.
78
-
* It receives an event object with `activeIndex` and `overIndex` properties, representing the original and new positions of the moved item.
79
-
* This will override the default behavior of updating the order of the data items.
80
-
* @type (event: { activeIndex: number; overIndex: number }) => void
81
-
* @example
82
-
* onMove={(event) => console.log(`Item moved from index ${event.activeIndex} to index ${event.overIndex}`)}
83
-
*/
84
-
onMove?: (event: { activeIndex: number; overIndex: number }) => void
85
-
86
-
/**
87
-
* A collision detection strategy that will be used to determine the closest sortable item.
88
-
* @default closestCenter
89
-
* @type DndContextProps["collisionDetection"]
90
-
*/
91
-
collisionDetection?: DndContextProps["collisionDetection"]
92
-
93
-
/**
94
-
* An array of modifiers that will be used to modify the behavior of the sortable component.
95
-
* @default
96
-
* [restrictToVerticalAxis, restrictToParentElement]
97
-
* @type Modifier[]
98
-
*/
99
-
modifiers?: DndContextProps["modifiers"]
100
-
101
-
/**
102
-
* A sorting strategy that will be used to determine the new order of the data items.
103
-
* @default verticalListSortingStrategy
104
-
* @type SortableContextProps["strategy"]
105
-
*/
106
-
strategy?: SortableContextProps["strategy"]
107
-
108
-
/**
109
-
* Specifies the axis for the drag-and-drop operation. It can be "vertical", "horizontal", or "both".
110
-
* @default "vertical"
111
-
* @type "vertical" | "horizontal" | "mixed"
112
-
*/
113
-
orientation?: "vertical" | "horizontal" | "mixed"
114
-
115
-
/**
116
-
* An optional React node that is rendered on top of the sortable component.
117
-
* It can be used to display additional information or controls.
118
-
* @default null
119
-
* @type React.ReactNode | null
120
-
* @example
121
-
* overlay={<Skeleton className="w-full h-8" />}
122
-
*/
123
-
overlay?: React.ReactNode | null
124
-
}
125
-
126
-
function Sortable<TData extends { id: UniqueIdentifier }>({
127
-
value,
128
-
onValueChange,
129
-
collisionDetection = closestCenter,
130
-
modifiers,
131
-
strategy,
132
-
onMove,
133
-
orientation = "vertical",
134
-
overlay,
135
-
children,
136
-
...props
137
-
}: SortableProps<TData>) {
138
-
const [activeId, setActiveId] = React.useState<UniqueIdentifier | null>(null)
139
-
const sensors = useSensors(
140
-
useSensor(MouseSensor),
141
-
useSensor(TouchSensor),
142
-
useSensor(KeyboardSensor)
143
-
)
144
-
145
-
const config = orientationConfig[orientation]
146
-
147
-
return (
148
-
<DndContext
149
-
modifiers={modifiers ?? config.modifiers}
150
-
sensors={sensors}
151
-
onDragStart={({ active }) => setActiveId(active.id)}
152
-
onDragEnd={({ active, over }) => {
153
-
if (over && active.id !== over?.id) {
154
-
const activeIndex = value.findIndex((item) => item.id === active.id)
155
-
const overIndex = value.findIndex((item) => item.id === over.id)
156
-
157
-
if (onMove) {
158
-
onMove({ activeIndex, overIndex })
159
-
} else {
160
-
onValueChange?.(arrayMove(value, activeIndex, overIndex))
161
-
}
162
-
}
163
-
setActiveId(null)
164
-
}}
165
-
onDragCancel={() => setActiveId(null)}
166
-
collisionDetection={collisionDetection}
167
-
{...props}
168
-
>
169
-
<SortableContext items={value} strategy={strategy ?? config.strategy}>
170
-
{children}
171
-
</SortableContext>
172
-
{overlay ? (
173
-
<SortableOverlay activeId={activeId}>{overlay}</SortableOverlay>
174
-
) : null}
175
-
</DndContext>
176
-
)
177
-
}
178
-
179
-
const dropAnimationOpts: DropAnimation = {
180
-
sideEffects: defaultDropAnimationSideEffects({
181
-
styles: {
182
-
active: {
183
-
opacity: "0.4",
184
-
},
185
-
},
186
-
}),
187
-
}
188
-
189
-
interface SortableOverlayProps
190
-
extends React.ComponentPropsWithRef<typeof DragOverlay> {
191
-
activeId?: UniqueIdentifier | null
192
-
}
193
-
194
-
const SortableOverlay = React.forwardRef<HTMLDivElement, SortableOverlayProps>(
195
-
(
196
-
{ activeId, dropAnimation = dropAnimationOpts, children, ...props },
197
-
ref
198
-
) => {
199
-
return (
200
-
<DragOverlay dropAnimation={dropAnimation} {...props}>
201
-
{activeId ? (
202
-
<SortableItem
203
-
ref={ref}
204
-
value={activeId}
205
-
className="cursor-grabbing"
206
-
asChild
207
-
>
208
-
{children}
209
-
</SortableItem>
210
-
) : null}
211
-
</DragOverlay>
212
-
)
213
-
}
214
-
)
215
-
SortableOverlay.displayName = "SortableOverlay"
216
-
217
-
interface SortableItemContextProps {
218
-
attributes: React.HTMLAttributes<HTMLElement>
219
-
listeners: DraggableSyntheticListeners | undefined
220
-
isDragging?: boolean
221
-
}
222
-
223
-
const SortableItemContext = React.createContext<SortableItemContextProps>({
224
-
attributes: {},
225
-
listeners: undefined,
226
-
isDragging: false,
227
-
})
228
-
229
-
function useSortableItem() {
230
-
const context = React.useContext(SortableItemContext)
231
-
232
-
if (!context) {
233
-
throw new Error("useSortableItem must be used within a SortableItem")
234
-
}
235
-
236
-
return context
237
-
}
238
-
239
-
interface SortableItemProps extends SlotProps {
240
-
/**
241
-
* The unique identifier of the item.
242
-
* @example "item-1"
243
-
* @type UniqueIdentifier
244
-
*/
245
-
value: UniqueIdentifier
246
-
247
-
/**
248
-
* Specifies whether the item should act as a trigger for the drag-and-drop action.
249
-
* @default false
250
-
* @type boolean | undefined
251
-
*/
252
-
asTrigger?: boolean
253
-
254
-
/**
255
-
* Merges the item's props into its immediate child.
256
-
* @default false
257
-
* @type boolean | undefined
258
-
*/
259
-
asChild?: boolean
260
-
}
261
-
262
-
const SortableItem = React.forwardRef<HTMLDivElement, SortableItemProps>(
263
-
({ value, asTrigger, asChild, className, ...props }, ref) => {
264
-
const {
265
-
attributes,
266
-
listeners,
267
-
setNodeRef,
268
-
transform,
269
-
transition,
270
-
isDragging,
271
-
} = useSortable({ id: value })
272
-
273
-
const context = React.useMemo<SortableItemContextProps>(
274
-
() => ({
275
-
attributes,
276
-
listeners,
277
-
isDragging,
278
-
}),
279
-
[attributes, listeners, isDragging]
280
-
)
281
-
const style: React.CSSProperties = {
282
-
opacity: isDragging ? 0.5 : 1,
283
-
transform: CSS.Translate.toString(transform),
284
-
transition,
285
-
}
286
-
287
-
const Comp = asChild ? Slot : "div"
288
-
289
-
return (
290
-
<SortableItemContext.Provider value={context}>
291
-
<Comp
292
-
data-state={isDragging ? "dragging" : undefined}
293
-
className={cn(
294
-
"data-[state=dragging]:cursor-grabbing",
295
-
{ "cursor-grab": !isDragging && asTrigger },
296
-
className
297
-
)}
298
-
ref={composeRefs(ref, setNodeRef as React.Ref<HTMLDivElement>)}
299
-
style={style}
300
-
{...(asTrigger ? attributes : {})}
301
-
{...(asTrigger ? listeners : {})}
302
-
{...props}
303
-
/>
304
-
</SortableItemContext.Provider>
305
-
)
306
-
}
307
-
)
308
-
SortableItem.displayName = "SortableItem"
309
-
310
-
interface SortableDragHandleProps extends ButtonProps {
311
-
withHandle?: boolean
312
-
}
313
-
314
-
const SortableDragHandle = React.forwardRef<
315
-
HTMLButtonElement,
316
-
SortableDragHandleProps
317
-
>(({ className, ...props }, ref) => {
318
-
const { attributes, listeners, isDragging } = useSortableItem()
319
-
320
-
return (
321
-
<Button
322
-
ref={composeRefs(ref)}
323
-
data-state={isDragging ? "dragging" : undefined}
324
-
className={cn(
325
-
"cursor-grab data-[state=dragging]:cursor-grabbing",
326
-
className
327
-
)}
328
-
{...attributes}
329
-
{...listeners}
330
-
{...props}
331
-
/>
332
-
)
333
-
})
334
-
SortableDragHandle.displayName = "SortableDragHandle"
335
-
336
-
export { Sortable, SortableDragHandle, SortableItem, SortableOverlay }
+4
-8
apps/web/src/components/ui/textarea.tsx
+4
-8
apps/web/src/components/ui/textarea.tsx
···
2
2
3
3
import { cn } from "@/lib/utils"
4
4
5
-
const Textarea = React.forwardRef<
6
-
HTMLTextAreaElement,
7
-
React.ComponentProps<"textarea">
8
-
>(({ className, ...props }, ref) => {
5
+
function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
9
6
return (
10
7
<textarea
8
+
data-slot="textarea"
11
9
className={cn(
12
-
"flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
10
+
"border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
13
11
className
14
12
)}
15
-
ref={ref}
16
13
{...props}
17
14
/>
18
15
)
19
-
})
20
-
Textarea.displayName = "Textarea"
16
+
}
21
17
22
18
export { Textarea }
+51
-20
apps/web/src/components/ui/tooltip.tsx
+51
-20
apps/web/src/components/ui/tooltip.tsx
···
1
+
"use client"
2
+
1
3
import * as React from "react"
2
4
import * as TooltipPrimitive from "@radix-ui/react-tooltip"
3
5
4
6
import { cn } from "@/lib/utils"
5
7
6
-
const TooltipProvider = TooltipPrimitive.Provider
8
+
function TooltipProvider({
9
+
delayDuration = 0,
10
+
...props
11
+
}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {
12
+
return (
13
+
<TooltipPrimitive.Provider
14
+
data-slot="tooltip-provider"
15
+
delayDuration={delayDuration}
16
+
{...props}
17
+
/>
18
+
)
19
+
}
7
20
8
-
const Tooltip = TooltipPrimitive.Root
21
+
function Tooltip({
22
+
...props
23
+
}: React.ComponentProps<typeof TooltipPrimitive.Root>) {
24
+
return (
25
+
<TooltipProvider>
26
+
<TooltipPrimitive.Root data-slot="tooltip" {...props} />
27
+
</TooltipProvider>
28
+
)
29
+
}
9
30
10
-
const TooltipTrigger = TooltipPrimitive.Trigger
31
+
function TooltipTrigger({
32
+
...props
33
+
}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {
34
+
return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />
35
+
}
11
36
12
-
const TooltipContent = React.forwardRef<
13
-
React.ElementRef<typeof TooltipPrimitive.Content>,
14
-
React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
15
-
>(({ className, sideOffset = 4, ...props }, ref) => (
16
-
<TooltipPrimitive.Portal>
17
-
<TooltipPrimitive.Content
18
-
ref={ref}
19
-
sideOffset={sideOffset}
20
-
className={cn(
21
-
"z-50 overflow-hidden rounded-md bg-primary px-3 py-1.5 text-xs text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
22
-
className
23
-
)}
24
-
{...props}
25
-
/>
26
-
</TooltipPrimitive.Portal>
27
-
))
28
-
TooltipContent.displayName = TooltipPrimitive.Content.displayName
37
+
function TooltipContent({
38
+
className,
39
+
sideOffset = 0,
40
+
children,
41
+
...props
42
+
}: React.ComponentProps<typeof TooltipPrimitive.Content>) {
43
+
return (
44
+
<TooltipPrimitive.Portal>
45
+
<TooltipPrimitive.Content
46
+
data-slot="tooltip-content"
47
+
sideOffset={sideOffset}
48
+
className={cn(
49
+
"bg-foreground text-background animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance",
50
+
className
51
+
)}
52
+
{...props}
53
+
>
54
+
{children}
55
+
<TooltipPrimitive.Arrow className="bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" />
56
+
</TooltipPrimitive.Content>
57
+
</TooltipPrimitive.Portal>
58
+
)
59
+
}
29
60
30
61
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }
-9
apps/web/src/forms/recipe.ts
-9
apps/web/src/forms/recipe.ts
+19
apps/web/src/hooks/use-mobile.ts
+19
apps/web/src/hooks/use-mobile.ts
···
1
+
import * as React from "react"
2
+
3
+
const MOBILE_BREAKPOINT = 768
4
+
5
+
export function useIsMobile() {
6
+
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)
7
+
8
+
React.useEffect(() => {
9
+
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)
10
+
const onChange = () => {
11
+
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
12
+
}
13
+
mql.addEventListener("change", onChange)
14
+
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
15
+
return () => mql.removeEventListener("change", onChange)
16
+
}, [])
17
+
18
+
return !!isMobile
19
+
}
-19
apps/web/src/hooks/use-mobile.tsx
-19
apps/web/src/hooks/use-mobile.tsx
···
1
-
import * as React from "react"
2
-
3
-
const MOBILE_BREAKPOINT = 768
4
-
5
-
export function useIsMobile() {
6
-
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)
7
-
8
-
React.useEffect(() => {
9
-
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)
10
-
const onChange = () => {
11
-
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
12
-
}
13
-
mql.addEventListener("change", onChange)
14
-
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
15
-
return () => mql.removeEventListener("change", onChange)
16
-
}, [])
17
-
18
-
return !!isMobile
19
-
}
-20
apps/web/src/hooks/use-xrpc.tsx
-20
apps/web/src/hooks/use-xrpc.tsx
···
1
-
import { SERVER_URL } from "@/lib/utils";
2
-
import { useAuth } from "@/state/auth";
3
-
import { CredentialManager, XRPC } from "@atcute/client"
4
-
5
-
export function useXrpc() {
6
-
const { agent } = useAuth();
7
-
8
-
if (agent) {
9
-
return new XRPC({
10
-
handler: agent,
11
-
proxy: {
12
-
type: 'api',
13
-
service: `did:web:${SERVER_URL}`,
14
-
},
15
-
});
16
-
}
17
-
18
-
const creds = new CredentialManager({ service: `https://${SERVER_URL}` });
19
-
return new XRPC({ handler: creds });
20
-
}
+110
-74
apps/web/src/index.css
+110
-74
apps/web/src/index.css
···
1
-
@tailwind base;
2
-
@tailwind components;
3
-
@tailwind utilities;
1
+
@import "tailwindcss";
2
+
@import "tw-animate-css";
4
3
5
-
@layer base {
6
-
:root {
7
-
--background: 0 0% 96.1%;
8
-
--foreground: 0 0% 3.9%;
9
-
--card: 0 0% 100%;
10
-
--card-foreground: 0 0% 3.9%;
11
-
--popover: 0 0% 100%;
12
-
--popover-foreground: 0 0% 3.9%;
13
-
--primary: 221.2 83.2% 53.3%;
14
-
--primary-foreground: 210 40% 98%;
15
-
--secondary: 210 40% 96.1%;
16
-
--secondary-foreground: 222.2 47.4% 11.2%;
17
-
--muted: 0 0% 96.1%;
18
-
--muted-foreground: 0 0% 45.1%;
19
-
--accent: 210 40% 96.1%;
20
-
--accent-foreground: 222.2 47.4% 11.2%;
21
-
--destructive: 0 84.2% 60.2%;
22
-
--destructive-foreground: 0 0% 98%;
23
-
--border: 214.3 31.8% 91.4%;
24
-
--input: 214.3 31.8% 91.4%;
25
-
--ring: 221.2 83.2% 53.3%;
26
-
--radius: 0.5rem;
27
-
--chart-1: 12 76% 61%;
28
-
--chart-2: 173 58% 39%;
29
-
--chart-3: 197 37% 24%;
30
-
--chart-4: 43 74% 66%;
31
-
--chart-5: 27 87% 67%;
32
-
--sidebar-background: 0 0% 98%;
33
-
--sidebar-foreground: 240 5.3% 26.1%;
34
-
--sidebar-primary: 221.2 83.2% 53.3%;
35
-
--sidebar-primary-foreground: 0 0% 98%;
36
-
--sidebar-accent: 210 40% 96.1%;
37
-
--sidebar-accent-foreground: 240 5.9% 10%;
38
-
--sidebar-border: 220 13% 91%;
39
-
--sidebar-ring: 221.2 83.2% 53.3%;
40
-
}
41
-
.dark {
42
-
--background: 0 0% 3.9%;
43
-
--foreground: 0 0% 98%;
44
-
--card: 0 0% 3.9%;
45
-
--card-foreground: 0 0% 98%;
46
-
--popover: 0 0% 3.9%;
47
-
--popover-foreground: 0 0% 98%;
48
-
--primary: 217.2 91.2% 59.8%;
49
-
--primary-foreground: 222.2 47.4% 11.2%;
50
-
--secondary: 217.2 32.6% 17.5%;
51
-
--secondary-foreground: 210 40% 98%;
52
-
--muted: 217.2 32.6% 17.5%;
53
-
--muted-foreground: 215 20.2% 65.1%;
54
-
--accent: 217.2 32.6% 17.5%;
55
-
--accent-foreground: 210 40% 98%;
56
-
--destructive: 0 62.8% 30.6%;
57
-
--destructive-foreground: 210 40% 98%;
58
-
--border: 217.2 32.6% 17.5%;
59
-
--input: 217.2 32.6% 17.5%;
60
-
--ring: 224.3 76.3% 48%;
61
-
--chart-1: 220 70% 50%;
62
-
--chart-2: 160 60% 45%;
63
-
--chart-3: 30 80% 55%;
64
-
--chart-4: 280 65% 60%;
65
-
--chart-5: 340 75% 55%;
66
-
--sidebar-background: 240 5.9% 10%;
67
-
--sidebar-foreground: 240 4.8% 95.9%;
68
-
--sidebar-primary: 217.2 91.2% 59.8%;
69
-
--sidebar-primary-foreground: 0 0% 100%;
70
-
--sidebar-accent: 217.2 32.6% 17.5%;
71
-
--sidebar-accent-foreground: 240 4.8% 95.9%;
72
-
--sidebar-border: 240 3.7% 15.9%;
73
-
--sidebar-ring: 217.2 91.2% 59.8%;
74
-
}
4
+
@custom-variant dark (&:is(.dark *));
5
+
6
+
@theme inline {
7
+
--radius-sm: calc(var(--radius) - 4px);
8
+
--radius-md: calc(var(--radius) - 2px);
9
+
--radius-lg: var(--radius);
10
+
--radius-xl: calc(var(--radius) + 4px);
11
+
--color-background: var(--background);
12
+
--color-foreground: var(--foreground);
13
+
--color-card: var(--card);
14
+
--color-card-foreground: var(--card-foreground);
15
+
--color-popover: var(--popover);
16
+
--color-popover-foreground: var(--popover-foreground);
17
+
--color-primary: var(--primary);
18
+
--color-primary-foreground: var(--primary-foreground);
19
+
--color-secondary: var(--secondary);
20
+
--color-secondary-foreground: var(--secondary-foreground);
21
+
--color-muted: var(--muted);
22
+
--color-muted-foreground: var(--muted-foreground);
23
+
--color-accent: var(--accent);
24
+
--color-accent-foreground: var(--accent-foreground);
25
+
--color-destructive: var(--destructive);
26
+
--color-border: var(--border);
27
+
--color-input: var(--input);
28
+
--color-ring: var(--ring);
29
+
--color-chart-1: var(--chart-1);
30
+
--color-chart-2: var(--chart-2);
31
+
--color-chart-3: var(--chart-3);
32
+
--color-chart-4: var(--chart-4);
33
+
--color-chart-5: var(--chart-5);
34
+
--color-sidebar: var(--sidebar);
35
+
--color-sidebar-foreground: var(--sidebar-foreground);
36
+
--color-sidebar-primary: var(--sidebar-primary);
37
+
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
38
+
--color-sidebar-accent: var(--sidebar-accent);
39
+
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
40
+
--color-sidebar-border: var(--sidebar-border);
41
+
--color-sidebar-ring: var(--sidebar-ring);
42
+
}
43
+
44
+
:root {
45
+
--radius: 0.625rem;
46
+
--background: oklch(1 0 0);
47
+
--foreground: oklch(0.141 0.005 285.823);
48
+
--card: oklch(1 0 0);
49
+
--card-foreground: oklch(0.141 0.005 285.823);
50
+
--popover: oklch(1 0 0);
51
+
--popover-foreground: oklch(0.141 0.005 285.823);
52
+
--primary: oklch(0.21 0.006 285.885);
53
+
--primary-foreground: oklch(0.985 0 0);
54
+
--secondary: oklch(0.967 0.001 286.375);
55
+
--secondary-foreground: oklch(0.21 0.006 285.885);
56
+
--muted: oklch(0.967 0.001 286.375);
57
+
--muted-foreground: oklch(0.552 0.016 285.938);
58
+
--accent: oklch(0.967 0.001 286.375);
59
+
--accent-foreground: oklch(0.21 0.006 285.885);
60
+
--destructive: oklch(0.577 0.245 27.325);
61
+
--border: oklch(0.92 0.004 286.32);
62
+
--input: oklch(0.92 0.004 286.32);
63
+
--ring: oklch(0.705 0.015 286.067);
64
+
--chart-1: oklch(0.646 0.222 41.116);
65
+
--chart-2: oklch(0.6 0.118 184.704);
66
+
--chart-3: oklch(0.398 0.07 227.392);
67
+
--chart-4: oklch(0.828 0.189 84.429);
68
+
--chart-5: oklch(0.769 0.188 70.08);
69
+
--sidebar: oklch(0.985 0 0);
70
+
--sidebar-foreground: oklch(0.141 0.005 285.823);
71
+
--sidebar-primary: oklch(0.21 0.006 285.885);
72
+
--sidebar-primary-foreground: oklch(0.985 0 0);
73
+
--sidebar-accent: oklch(0.967 0.001 286.375);
74
+
--sidebar-accent-foreground: oklch(0.21 0.006 285.885);
75
+
--sidebar-border: oklch(0.92 0.004 286.32);
76
+
--sidebar-ring: oklch(0.705 0.015 286.067);
77
+
}
78
+
79
+
.dark {
80
+
--background: oklch(0.141 0.005 285.823);
81
+
--foreground: oklch(0.985 0 0);
82
+
--card: oklch(0.21 0.006 285.885);
83
+
--card-foreground: oklch(0.985 0 0);
84
+
--popover: oklch(0.21 0.006 285.885);
85
+
--popover-foreground: oklch(0.985 0 0);
86
+
--primary: oklch(0.92 0.004 286.32);
87
+
--primary-foreground: oklch(0.21 0.006 285.885);
88
+
--secondary: oklch(0.274 0.006 286.033);
89
+
--secondary-foreground: oklch(0.985 0 0);
90
+
--muted: oklch(0.274 0.006 286.033);
91
+
--muted-foreground: oklch(0.705 0.015 286.067);
92
+
--accent: oklch(0.274 0.006 286.033);
93
+
--accent-foreground: oklch(0.985 0 0);
94
+
--destructive: oklch(0.704 0.191 22.216);
95
+
--border: oklch(1 0 0 / 10%);
96
+
--input: oklch(1 0 0 / 15%);
97
+
--ring: oklch(0.552 0.016 285.938);
98
+
--chart-1: oklch(0.488 0.243 264.376);
99
+
--chart-2: oklch(0.696 0.17 162.48);
100
+
--chart-3: oklch(0.769 0.188 70.08);
101
+
--chart-4: oklch(0.627 0.265 303.9);
102
+
--chart-5: oklch(0.645 0.246 16.439);
103
+
--sidebar: oklch(0.21 0.006 285.885);
104
+
--sidebar-foreground: oklch(0.985 0 0);
105
+
--sidebar-primary: oklch(0.488 0.243 264.376);
106
+
--sidebar-primary-foreground: oklch(0.985 0 0);
107
+
--sidebar-accent: oklch(0.274 0.006 286.033);
108
+
--sidebar-accent-foreground: oklch(0.985 0 0);
109
+
--sidebar-border: oklch(1 0 0 / 10%);
110
+
--sidebar-ring: oklch(0.552 0.016 285.938);
75
111
}
76
112
77
113
@layer base {
78
114
* {
79
-
@apply border-border;
115
+
@apply border-border outline-ring/50;
80
116
}
81
117
body {
82
118
@apply bg-background text-foreground;
-36
apps/web/src/lib/compose-refs.ts
-36
apps/web/src/lib/compose-refs.ts
···
1
-
// @see https://github.com/radix-ui/primitives/blob/main/packages/react/compose-refs/src/composeRefs.tsx
2
-
3
-
import * as React from "react"
4
-
5
-
type PossibleRef<T> = React.Ref<T> | undefined
6
-
7
-
/**
8
-
* Set a given ref to a given value
9
-
* This utility takes care of different types of refs: callback refs and RefObject(s)
10
-
*/
11
-
function setRef<T>(ref: PossibleRef<T>, value: T) {
12
-
if (typeof ref === "function") {
13
-
ref(value)
14
-
} else if (ref !== null && ref !== undefined) {
15
-
;(ref as React.MutableRefObject<T>).current = value
16
-
}
17
-
}
18
-
19
-
/**
20
-
* A utility to compose multiple refs together
21
-
* Accepts callback refs and RefObject(s)
22
-
*/
23
-
function composeRefs<T>(...refs: PossibleRef<T>[]) {
24
-
return (node: T) => refs.forEach((ref) => setRef(ref, node))
25
-
}
26
-
27
-
/**
28
-
* A custom hook that composes multiple refs
29
-
* Accepts callback refs and RefObject(s)
30
-
*/
31
-
function useComposedRefs<T>(...refs: PossibleRef<T>[]) {
32
-
// eslint-disable-next-line react-hooks/exhaustive-deps
33
-
return React.useCallback(composeRefs(...refs), refs)
34
-
}
35
-
36
-
export { composeRefs, useComposedRefs }
+1
apps/web/src/lib/consts.ts
+1
apps/web/src/lib/consts.ts
···
1
+
export const IS_DEV = import.meta.env.DEV;
-139
apps/web/src/lib/did.ts
-139
apps/web/src/lib/did.ts
···
1
-
import { z } from "zod";
2
-
3
-
type Brand<K, T> = K & { __brand: T };
4
-
export type DID = Brand<string, "DID">;
5
-
6
-
export function isDid(s: string): s is DID {
7
-
return s.startsWith("did:");
8
-
}
9
-
10
-
export function parseDid(s: string): DID | null {
11
-
if (!isDid(s)) {
12
-
return null;
13
-
}
14
-
return s;
15
-
}
16
-
17
-
export const getDidDoc = async (did: DID) => {
18
-
let url = `https://plc.directory/${did}`;
19
-
if (did.startsWith('did:web')) {
20
-
url = `https://${did.split(':')[2]}/.well-known/did.json`;
21
-
}
22
-
23
-
const response = await fetch(url);
24
-
25
-
return PlcDocument.parse(await response.json());
26
-
};
27
-
28
-
export const getPdsUrl = async (did: DID) => {
29
-
const plc = await getDidDoc(did);
30
-
31
-
return (
32
-
plc.service.find((s) => s.type === "AtprotoPersonalDataServer")
33
-
?.serviceEndpoint ?? null
34
-
);
35
-
};
36
-
37
-
const PlcDocument = z.object({
38
-
id: z.string(),
39
-
alsoKnownAs: z.array(z.string()),
40
-
service: z.array(
41
-
z.object({
42
-
id: z.string(),
43
-
type: z.string(),
44
-
serviceEndpoint: z.string(),
45
-
}),
46
-
),
47
-
});
48
-
49
-
const DnsQueryResponse = z.object({
50
-
Answer: z.array(
51
-
z.object({
52
-
name: z.string(),
53
-
type: z.number(),
54
-
TTL: z.number(),
55
-
data: z.string(),
56
-
}),
57
-
),
58
-
});
59
-
60
-
async function getAtprotoDidFromDns(handle: string) {
61
-
const url = new URL("https://cloudflare-dns.com/dns-query");
62
-
url.searchParams.set("type", "TXT");
63
-
url.searchParams.set("name", `_atproto.${handle}`);
64
-
65
-
const response = await fetch(url, {
66
-
headers: {
67
-
Accept: "application/dns-json",
68
-
},
69
-
});
70
-
71
-
const { Answer } = DnsQueryResponse.parse(await response.json());
72
-
// Answer[0].data is "\"did=...\"" (with quotes)
73
-
const val = Answer[0]?.data
74
-
? JSON.parse(Answer[0]?.data).split("did=")[1]
75
-
: null;
76
-
77
-
return val ? parseDid(val) : null;
78
-
}
79
-
80
-
const getAtprotoFromHttps = async (handle: string) => {
81
-
let res;
82
-
const timeoutSignal = AbortSignal.timeout(1500);
83
-
try {
84
-
res = await fetch(`https://${handle}/.well-known/atproto-did`, {
85
-
signal: timeoutSignal,
86
-
});
87
-
} catch (_e) {
88
-
// We're caching failures here, we should at some point invalidate the cache by listening to handle changes on the network
89
-
return null;
90
-
}
91
-
92
-
if (!res.ok) {
93
-
return null;
94
-
}
95
-
return parseDid((await res.text()).trim());
96
-
};
97
-
98
-
export const getVerifiedDid = async (handle: string) => {
99
-
const [dnsDid, httpDid] = await Promise.all([
100
-
getAtprotoDidFromDns(handle).catch((_) => {
101
-
return null;
102
-
}),
103
-
getAtprotoFromHttps(handle).catch(() => {
104
-
return null;
105
-
}),
106
-
]);
107
-
108
-
if (dnsDid && httpDid && dnsDid !== httpDid) {
109
-
return null;
110
-
}
111
-
112
-
const did = dnsDid ?? (httpDid ? parseDid(httpDid) : null);
113
-
if (!did) {
114
-
return null;
115
-
}
116
-
117
-
const plcDoc = await getDidDoc(did);
118
-
const plcHandle = plcDoc.alsoKnownAs
119
-
.find((handle) => handle.startsWith("at://"))
120
-
?.replace("at://", "");
121
-
122
-
if (!plcHandle) return null;
123
-
124
-
return plcHandle.toLowerCase() === handle.toLowerCase() ? did : null;
125
-
};
126
-
127
-
export const getDidFromHandleOrDid = async (handleOrDid: string) => {
128
-
const decodedHandleOrDid = decodeURIComponent(handleOrDid);
129
-
if (isDid(decodedHandleOrDid)) {
130
-
return decodedHandleOrDid;
131
-
}
132
-
133
-
return getVerifiedDid(decodedHandleOrDid);
134
-
};
135
-
136
-
export const getHandleFromHandleOrDid = async (did: string) => {
137
-
const didDoc = await getDidDoc(did as DID);
138
-
return didDoc.alsoKnownAs[0]?.substring(5);
139
-
}
-11
apps/web/src/lib/react-query.ts
-11
apps/web/src/lib/react-query.ts
-4
apps/web/src/lib/utils.ts
-4
apps/web/src/lib/utils.ts
+14
-54
apps/web/src/main.tsx
+14
-54
apps/web/src/main.tsx
···
1
-
import { StrictMode } from 'react'
2
-
import { createRoot } from 'react-dom/client'
3
-
import { routeTree } from './routeTree.gen';
1
+
import { StrictMode } from 'react';
2
+
import { createRoot } from 'react-dom/client';
4
3
import { createRouter, RouterProvider } from '@tanstack/react-router';
5
-
import { QueryClientProvider, QueryClient } from '@tanstack/react-query'
6
-
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
7
-
import { configureOAuth } from '@atcute/oauth-browser-client';
8
-
import './index.css'
9
-
import { AuthProvider, useAuth } from './state/auth';
10
-
import { ThemeProvider } from './components/theme-provider';
11
-
12
-
const router = createRouter({
13
-
routeTree,
14
-
context: {
15
-
auth: undefined!,
16
-
},
17
-
});
4
+
import { routeTree } from './routeTree.gen';
18
5
19
-
declare module '@tanstack/react-router' {
20
-
interface Register {
21
-
router: typeof router
22
-
}
23
-
}
24
-
25
-
configureOAuth({
26
-
metadata: {
27
-
client_id: import.meta.env.VITE_OAUTH_CLIENT_ID,
28
-
redirect_uri: import.meta.env.VITE_OAUTH_REDIRECT_URL,
29
-
},
30
-
});
31
-
32
-
const queryClient = new QueryClient({
33
-
defaultOptions: {
34
-
queries: {
35
-
refetchOnWindowFocus: false,
36
-
structuralSharing: false,
37
-
retry: false,
38
-
}
39
-
}
40
-
});
6
+
import './index.css';
41
7
42
-
const InnerApp = () => {
43
-
const auth = useAuth();
44
-
return <RouterProvider router={router} context={{ auth }} />
45
-
};
8
+
const router = createRouter({ routeTree });
46
9
47
-
createRoot(document.getElementById('root')!).render(
48
-
<StrictMode>
49
-
<ThemeProvider defaultTheme="dark" storageKey="recipes-theme">
50
-
<AuthProvider>
51
-
<QueryClientProvider client={queryClient}>
52
-
<InnerApp />
53
-
<ReactQueryDevtools initialIsOpen={false} />
54
-
</QueryClientProvider>
55
-
</AuthProvider>
56
-
</ThemeProvider>
57
-
</StrictMode>,
58
-
)
10
+
const rootElement = document.getElementById('root')!;
11
+
if (!rootElement.innerHTML) {
12
+
const root = createRoot(rootElement);
13
+
root.render(
14
+
<StrictMode>
15
+
<RouterProvider router={router} />
16
+
</StrictMode>,
17
+
);
18
+
}
-91
apps/web/src/queries/recipe.ts
-91
apps/web/src/queries/recipe.ts
···
1
-
import { useXrpc } from "@/hooks/use-xrpc";
2
-
import { useAuth } from "@/state/auth";
3
-
import { XRPC, XRPCError } from "@atcute/client";
4
-
import { RecipeCollection } from "@cookware/lexicons";
5
-
import { queryOptions, useMutation, useQuery } from "@tanstack/react-query";
6
-
import { notFound } from "@tanstack/react-router";
7
-
import { UseFormReturn } from "react-hook-form";
8
-
import { TID } from '@atproto/common-web';
9
-
import { recipeSchema } from "@/forms/recipe";
10
-
import { z } from "zod";
11
-
12
-
const RQKEY_ROOT = 'posts';
13
-
export const RQKEY = (cursor: string, did: string, rkey: string) => [RQKEY_ROOT, cursor, did, rkey];
14
-
15
-
export const useRecipesQuery = (cursor: string, did?: string) => {
16
-
const rpc = useXrpc();
17
-
return useQuery({
18
-
queryKey: RQKEY(cursor, did ?? '', ''),
19
-
queryFn: async () => {
20
-
const res = await rpc.get('blue.recipes.feed.getRecipes', {
21
-
params: { cursor, did },
22
-
});
23
-
return res.data;
24
-
},
25
-
});
26
-
};
27
-
28
-
export const recipeQueryOptions = (rpc: XRPC, did: string, rkey: string) => {
29
-
return queryOptions({
30
-
queryKey: RQKEY('', did, rkey),
31
-
queryFn: async () => {
32
-
try {
33
-
const res = await rpc.get('blue.recipes.feed.getRecipe', {
34
-
params: { did, rkey },
35
-
});
36
-
return res.data;
37
-
} catch (err) {
38
-
if (err instanceof XRPCError && err.kind && err.kind == 'not_found') {
39
-
throw notFound({ routeId: '/_' });
40
-
}
41
-
throw err;
42
-
}
43
-
},
44
-
});
45
-
};
46
-
47
-
export const useRecipeQuery = (did: string, rkey: string) => {
48
-
const rpc = useXrpc();
49
-
return useQuery(recipeQueryOptions(rpc, did, rkey));
50
-
};
51
-
52
-
export const useNewRecipeMutation = (form: UseFormReturn<z.infer<typeof recipeSchema>>) => {
53
-
const { agent } = useAuth();
54
-
const rpc = useXrpc();
55
-
return useMutation({
56
-
mutationKey: ['recipes.new'],
57
-
mutationFn: async ({ recipe: { image, ...recipe } }: { recipe: z.infer<typeof recipeSchema> }) => {
58
-
let recipeImg = null;
59
-
if (image) {
60
-
const imageFile = image.item(0) as File;
61
-
const res = await rpc.call('com.atproto.repo.uploadBlob', {
62
-
data: imageFile,
63
-
});
64
-
recipeImg = res.data.blob
65
-
}
66
-
67
-
const rkey = TID.nextStr();
68
-
const res = await rpc.call(`com.atproto.repo.createRecord`, {
69
-
data: {
70
-
repo: agent?.session.info.sub as `did:${string}`,
71
-
record: {
72
-
...recipe,
73
-
image: recipeImg,
74
-
},
75
-
collection: RecipeCollection,
76
-
rkey: rkey,
77
-
},
78
-
});
79
-
return {
80
-
rkey: rkey,
81
-
resp: res.data
82
-
};
83
-
},
84
-
onError: (error) => {
85
-
form.setError('title', error);
86
-
},
87
-
onSuccess: ({ rkey }) => {
88
-
window.location.assign(`/recipes/${agent?.sub}/${rkey}`);
89
-
},
90
-
});
91
-
};
-26
apps/web/src/queries/self.ts
-26
apps/web/src/queries/self.ts
···
1
-
import { useXrpc } from "@/hooks/use-xrpc";
2
-
import { useAuth } from "@/state/auth";
3
-
import { AppBskyActorProfile } from "@atcute/client/lexicons";
4
-
import { At } from "@atcute/client/lexicons";
5
-
import { useQuery } from "@tanstack/react-query";
6
-
7
-
export const useUserQuery = () => {
8
-
const { isLoggedIn, agent } = useAuth();
9
-
const rpc = useXrpc();
10
-
11
-
return useQuery({
12
-
queryKey: ['self'],
13
-
queryFn: async () => {
14
-
const res = await rpc.get('com.atproto.repo.getRecord', {
15
-
params: {
16
-
repo: agent?.sub as At.DID,
17
-
collection: 'app.bsky.actor.profile',
18
-
rkey: 'self',
19
-
},
20
-
});
21
-
22
-
return res.data.value as AppBskyActorProfile.Record;
23
-
},
24
-
enabled: isLoggedIn,
25
-
});
26
-
}
+8
-164
apps/web/src/routeTree.gen.ts
+8
-164
apps/web/src/routeTree.gen.ts
···
8
8
// You should NOT make any changes in this file as it will be overwritten.
9
9
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
10
10
11
-
import { createFileRoute } from '@tanstack/react-router'
12
-
13
11
import { Route as rootRouteImport } from './routes/__root'
14
-
import { Route as RouteImport } from './routes/_'
15
-
import { Route as authLoginRouteImport } from './routes/_.(auth)/login'
16
-
import { Route as appRecipesNewRouteImport } from './routes/_.(app)/recipes/new'
17
12
18
-
const appIndexLazyRouteImport = createFileRoute('/_/(app)/')()
19
-
const appRecipesAuthorIndexLazyRouteImport = createFileRoute(
20
-
'/_/(app)/recipes/$author/',
21
-
)()
22
-
const appRecipesAuthorRkeyIndexLazyRouteImport = createFileRoute(
23
-
'/_/(app)/recipes/$author/$rkey/',
24
-
)()
25
-
26
-
const Route = RouteImport.update({
27
-
id: '/_',
28
-
getParentRoute: () => rootRouteImport,
29
-
} as any)
30
-
const appIndexLazyRoute = appIndexLazyRouteImport
31
-
.update({
32
-
id: '/(app)/',
33
-
path: '/',
34
-
getParentRoute: () => Route,
35
-
} as any)
36
-
.lazy(() => import('./routes/_.(app)/index.lazy').then((d) => d.Route))
37
-
const authLoginRoute = authLoginRouteImport.update({
38
-
id: '/(auth)/login',
39
-
path: '/login',
40
-
getParentRoute: () => Route,
41
-
} as any)
42
-
const appRecipesNewRoute = appRecipesNewRouteImport.update({
43
-
id: '/(app)/recipes/new',
44
-
path: '/recipes/new',
45
-
getParentRoute: () => Route,
46
-
} as any)
47
-
const appRecipesAuthorIndexLazyRoute = appRecipesAuthorIndexLazyRouteImport
48
-
.update({
49
-
id: '/(app)/recipes/$author/',
50
-
path: '/recipes/$author/',
51
-
getParentRoute: () => Route,
52
-
} as any)
53
-
.lazy(() =>
54
-
import('./routes/_.(app)/recipes/$author/index.lazy').then((d) => d.Route),
55
-
)
56
-
const appRecipesAuthorRkeyIndexLazyRoute =
57
-
appRecipesAuthorRkeyIndexLazyRouteImport
58
-
.update({
59
-
id: '/(app)/recipes/$author/$rkey/',
60
-
path: '/recipes/$author/$rkey/',
61
-
getParentRoute: () => Route,
62
-
} as any)
63
-
.lazy(() =>
64
-
import('./routes/_.(app)/recipes/$author/$rkey/index.lazy').then(
65
-
(d) => d.Route,
66
-
),
67
-
)
68
-
69
-
export interface FileRoutesByFullPath {
70
-
'/login': typeof authLoginRoute
71
-
'/': typeof appIndexLazyRoute
72
-
'/recipes/new': typeof appRecipesNewRoute
73
-
'/recipes/$author': typeof appRecipesAuthorIndexLazyRoute
74
-
'/recipes/$author/$rkey': typeof appRecipesAuthorRkeyIndexLazyRoute
75
-
}
76
-
export interface FileRoutesByTo {
77
-
'/login': typeof authLoginRoute
78
-
'/': typeof appIndexLazyRoute
79
-
'/recipes/new': typeof appRecipesNewRoute
80
-
'/recipes/$author': typeof appRecipesAuthorIndexLazyRoute
81
-
'/recipes/$author/$rkey': typeof appRecipesAuthorRkeyIndexLazyRoute
82
-
}
13
+
export interface FileRoutesByFullPath {}
14
+
export interface FileRoutesByTo {}
83
15
export interface FileRoutesById {
84
16
__root__: typeof rootRouteImport
85
-
'/_': typeof RouteWithChildren
86
-
'/_/(auth)/login': typeof authLoginRoute
87
-
'/_/(app)/': typeof appIndexLazyRoute
88
-
'/_/(app)/recipes/new': typeof appRecipesNewRoute
89
-
'/_/(app)/recipes/$author/': typeof appRecipesAuthorIndexLazyRoute
90
-
'/_/(app)/recipes/$author/$rkey/': typeof appRecipesAuthorRkeyIndexLazyRoute
91
17
}
92
18
export interface FileRouteTypes {
93
19
fileRoutesByFullPath: FileRoutesByFullPath
94
-
fullPaths:
95
-
| '/login'
96
-
| '/'
97
-
| '/recipes/new'
98
-
| '/recipes/$author'
99
-
| '/recipes/$author/$rkey'
20
+
fullPaths: never
100
21
fileRoutesByTo: FileRoutesByTo
101
-
to:
102
-
| '/login'
103
-
| '/'
104
-
| '/recipes/new'
105
-
| '/recipes/$author'
106
-
| '/recipes/$author/$rkey'
107
-
id:
108
-
| '__root__'
109
-
| '/_'
110
-
| '/_/(auth)/login'
111
-
| '/_/(app)/'
112
-
| '/_/(app)/recipes/new'
113
-
| '/_/(app)/recipes/$author/'
114
-
| '/_/(app)/recipes/$author/$rkey/'
22
+
to: never
23
+
id: '__root__'
115
24
fileRoutesById: FileRoutesById
116
25
}
117
-
export interface RootRouteChildren {
118
-
Route: typeof RouteWithChildren
119
-
}
26
+
export interface RootRouteChildren {}
120
27
121
28
declare module '@tanstack/react-router' {
122
-
interface FileRoutesByPath {
123
-
'/_': {
124
-
id: '/_'
125
-
path: ''
126
-
fullPath: ''
127
-
preLoaderRoute: typeof RouteImport
128
-
parentRoute: typeof rootRouteImport
129
-
}
130
-
'/_/(app)/': {
131
-
id: '/_/(app)/'
132
-
path: '/'
133
-
fullPath: '/'
134
-
preLoaderRoute: typeof appIndexLazyRouteImport
135
-
parentRoute: typeof Route
136
-
}
137
-
'/_/(auth)/login': {
138
-
id: '/_/(auth)/login'
139
-
path: '/login'
140
-
fullPath: '/login'
141
-
preLoaderRoute: typeof authLoginRouteImport
142
-
parentRoute: typeof Route
143
-
}
144
-
'/_/(app)/recipes/new': {
145
-
id: '/_/(app)/recipes/new'
146
-
path: '/recipes/new'
147
-
fullPath: '/recipes/new'
148
-
preLoaderRoute: typeof appRecipesNewRouteImport
149
-
parentRoute: typeof Route
150
-
}
151
-
'/_/(app)/recipes/$author/': {
152
-
id: '/_/(app)/recipes/$author/'
153
-
path: '/recipes/$author'
154
-
fullPath: '/recipes/$author'
155
-
preLoaderRoute: typeof appRecipesAuthorIndexLazyRouteImport
156
-
parentRoute: typeof Route
157
-
}
158
-
'/_/(app)/recipes/$author/$rkey/': {
159
-
id: '/_/(app)/recipes/$author/$rkey/'
160
-
path: '/recipes/$author/$rkey'
161
-
fullPath: '/recipes/$author/$rkey'
162
-
preLoaderRoute: typeof appRecipesAuthorRkeyIndexLazyRouteImport
163
-
parentRoute: typeof Route
164
-
}
165
-
}
29
+
interface FileRoutesByPath {}
166
30
}
167
31
168
-
interface RouteChildren {
169
-
authLoginRoute: typeof authLoginRoute
170
-
appIndexLazyRoute: typeof appIndexLazyRoute
171
-
appRecipesNewRoute: typeof appRecipesNewRoute
172
-
appRecipesAuthorIndexLazyRoute: typeof appRecipesAuthorIndexLazyRoute
173
-
appRecipesAuthorRkeyIndexLazyRoute: typeof appRecipesAuthorRkeyIndexLazyRoute
174
-
}
175
-
176
-
const RouteChildren: RouteChildren = {
177
-
authLoginRoute: authLoginRoute,
178
-
appIndexLazyRoute: appIndexLazyRoute,
179
-
appRecipesNewRoute: appRecipesNewRoute,
180
-
appRecipesAuthorIndexLazyRoute: appRecipesAuthorIndexLazyRoute,
181
-
appRecipesAuthorRkeyIndexLazyRoute: appRecipesAuthorRkeyIndexLazyRoute,
182
-
}
183
-
184
-
const RouteWithChildren = Route._addFileChildren(RouteChildren)
185
-
186
-
const rootRouteChildren: RootRouteChildren = {
187
-
Route: RouteWithChildren,
188
-
}
32
+
const rootRouteChildren: RootRouteChildren = {}
189
33
export const routeTree = rootRouteImport
190
34
._addFileChildren(rootRouteChildren)
191
35
._addFileTypes<FileRouteTypes>()
-62
apps/web/src/routes/_.(app)/index.lazy.tsx
-62
apps/web/src/routes/_.(app)/index.lazy.tsx
···
1
-
import { createLazyFileRoute, Link } from '@tanstack/react-router'
2
-
import {
3
-
Breadcrumb,
4
-
BreadcrumbItem,
5
-
BreadcrumbLink,
6
-
BreadcrumbList,
7
-
BreadcrumbPage,
8
-
BreadcrumbSeparator,
9
-
} from '@/components/ui/breadcrumb'
10
-
import { Separator } from '@/components/ui/separator'
11
-
import { SidebarTrigger } from '@/components/ui/sidebar'
12
-
import QueryPlaceholder from '@/components/query-placeholder'
13
-
import { useRecipesQuery } from '@/queries/recipe'
14
-
import { RecipeCard } from '@/components/recipe-card';
15
-
16
-
export const Route = createLazyFileRoute('/_/(app)/')({
17
-
component: RouteComponent,
18
-
})
19
-
20
-
function RouteComponent() {
21
-
const query = useRecipesQuery('')
22
-
23
-
return (
24
-
<>
25
-
<header className="flex h-16 shrink-0 items-center gap-2 transition-[width,height] ease-linear group-has-[[data-collapsible=icon]]/sidebar-wrapper:h-12">
26
-
<div className="flex items-center gap-2 px-4">
27
-
<SidebarTrigger className="-ml-1" />
28
-
<Separator orientation="vertical" className="mr-2 h-4" />
29
-
<Breadcrumb>
30
-
<BreadcrumbList>
31
-
<BreadcrumbItem className="hidden md:block">
32
-
<BreadcrumbLink asChild>
33
-
<Link href="/">Community</Link>
34
-
</BreadcrumbLink>
35
-
</BreadcrumbItem>
36
-
<BreadcrumbSeparator className="hidden md:block" />
37
-
<BreadcrumbItem>
38
-
<BreadcrumbPage>Browse Recipes</BreadcrumbPage>
39
-
</BreadcrumbItem>
40
-
</BreadcrumbList>
41
-
</Breadcrumb>
42
-
</div>
43
-
</header>
44
-
<div className="flex flex-col gap-4 p-4 pt-6 items-center">
45
-
<h1 className="text-4xl font-black">Community Recipes!</h1>
46
-
<p className="text-lg">See what the community's been cooking.</p>
47
-
</div>
48
-
<div className="flex-1 flex flex-col items-center p-4">
49
-
<div className="flex flex-col gap-4 max-w-2xl w-full items-center">
50
-
<QueryPlaceholder query={query} cards cardsCount={12}>
51
-
{query.data?.recipes.map((recipe, idx) => (
52
-
<RecipeCard
53
-
recipe={recipe}
54
-
key={idx}
55
-
/>
56
-
))}
57
-
</QueryPlaceholder>
58
-
</div>
59
-
</div>
60
-
</>
61
-
)
62
-
}
-372
apps/web/src/routes/_.(app)/recipes/new.tsx
-372
apps/web/src/routes/_.(app)/recipes/new.tsx
···
1
-
import { createFileRoute, Link, redirect } from "@tanstack/react-router";
2
-
import {
3
-
Breadcrumb,
4
-
BreadcrumbItem,
5
-
BreadcrumbLink,
6
-
BreadcrumbList,
7
-
BreadcrumbPage,
8
-
BreadcrumbSeparator,
9
-
} from "@/components/ui/breadcrumb";
10
-
import { Separator } from "@/components/ui/separator";
11
-
import { SidebarTrigger } from "@/components/ui/sidebar";
12
-
import { useFieldArray, useForm } from "react-hook-form";
13
-
import { z } from "zod";
14
-
import { zodResolver } from "@hookform/resolvers/zod";
15
-
import {
16
-
Form,
17
-
FormControl,
18
-
FormDescription,
19
-
FormField,
20
-
FormItem,
21
-
FormLabel,
22
-
FormMessage,
23
-
} from "@/components/ui/form";
24
-
import { Button } from "@/components/ui/button";
25
-
import { Input } from "@/components/ui/input";
26
-
import { Textarea } from "@/components/ui/textarea";
27
-
import {
28
-
Card,
29
-
CardContent,
30
-
CardDescription,
31
-
CardHeader,
32
-
CardTitle,
33
-
} from "@/components/ui/card";
34
-
import {
35
-
Sortable,
36
-
SortableDragHandle,
37
-
SortableItem,
38
-
} from "@/components/ui/sortable";
39
-
import { DragHandleDots2Icon } from "@radix-ui/react-icons";
40
-
import { Label } from "@/components/ui/label";
41
-
import { TrashIcon } from "lucide-react";
42
-
import { useNewRecipeMutation } from "@/queries/recipe";
43
-
import { recipeSchema } from "@/forms/recipe";
44
-
45
-
export const Route = createFileRoute("/_/(app)/recipes/new")({
46
-
beforeLoad: async ({ context }) => {
47
-
if (!context.auth.isLoggedIn) {
48
-
throw redirect({
49
-
to: '/login',
50
-
});
51
-
}
52
-
},
53
-
component: RouteComponent,
54
-
});
55
-
56
-
function RouteComponent() {
57
-
const form = useForm<z.infer<typeof recipeSchema>>({
58
-
resolver: zodResolver(recipeSchema),
59
-
defaultValues: {
60
-
title: "",
61
-
time: 0,
62
-
image: null,
63
-
description: "",
64
-
ingredients: [{ name: "" }],
65
-
steps: [{ text: "" }],
66
-
},
67
-
});
68
-
69
-
const { mutate, isPending } = useNewRecipeMutation(form);
70
-
71
-
const onSubmit = (values: z.infer<typeof recipeSchema>) => {
72
-
mutate({ recipe: values });
73
-
};
74
-
75
-
const imageRef = form.register("image");
76
-
77
-
const ingredients = useFieldArray({
78
-
control: form.control,
79
-
name: "ingredients",
80
-
});
81
-
82
-
const steps = useFieldArray({
83
-
control: form.control,
84
-
name: "steps",
85
-
});
86
-
87
-
return (
88
-
<>
89
-
<Breadcrumbs />
90
-
<div className="flex-1 flex-col p-4 pt-0 max-w-xl w-full mx-auto">
91
-
<Card>
92
-
<CardHeader>
93
-
<CardTitle>New recipe</CardTitle>
94
-
<CardDescription>Share your recipe with the world!</CardDescription>
95
-
</CardHeader>
96
-
<CardContent>
97
-
<Form {...form}>
98
-
<form
99
-
onSubmit={form.handleSubmit(onSubmit)}
100
-
className="space-y-8"
101
-
>
102
-
<FormField
103
-
name="title"
104
-
control={form.control}
105
-
render={({ field }) => (
106
-
<FormItem>
107
-
<FormLabel>Title</FormLabel>
108
-
<FormControl>
109
-
<Input placeholder="My awesome recipe!" {...field} />
110
-
</FormControl>
111
-
<FormDescription>
112
-
This is your recipe's name.
113
-
</FormDescription>
114
-
<FormMessage />
115
-
</FormItem>
116
-
)}
117
-
/>
118
-
119
-
<FormField
120
-
name="description"
121
-
control={form.control}
122
-
render={({ field: { value, ...field } }) => (
123
-
<FormItem>
124
-
<FormLabel>Description</FormLabel>
125
-
<FormControl>
126
-
<Textarea
127
-
className="resize-none"
128
-
value={value || ""}
129
-
{...field}
130
-
/>
131
-
</FormControl>
132
-
<FormDescription>Describe your recipe, maybe tell the world how tasty it is? (Optional)</FormDescription>
133
-
<FormMessage />
134
-
</FormItem>
135
-
)}
136
-
/>
137
-
138
-
<FormField
139
-
name="image"
140
-
control={form.control}
141
-
render={(_props) => (
142
-
<FormItem>
143
-
<FormLabel>Image</FormLabel>
144
-
<FormControl>
145
-
<Input
146
-
type="file"
147
-
className="resize-none"
148
-
{...imageRef}
149
-
/>
150
-
</FormControl>
151
-
<FormMessage />
152
-
</FormItem>
153
-
)}
154
-
/>
155
-
156
-
<FormField
157
-
name="time"
158
-
control={form.control}
159
-
render={({ field: { value, ...field } }) => (
160
-
<FormItem>
161
-
<FormLabel>Time</FormLabel>
162
-
<FormControl>
163
-
<Input
164
-
type="number"
165
-
className="resize-none"
166
-
value={value || ""}
167
-
{...field}
168
-
/>
169
-
</FormControl>
170
-
<FormDescription>How long (in minutes) does your recipe take to complete?</FormDescription>
171
-
<FormMessage />
172
-
</FormItem>
173
-
)}
174
-
/>
175
-
176
-
<div className="grid gap-2">
177
-
<Label>Ingredients</Label>
178
-
<Sortable
179
-
value={ingredients.fields}
180
-
onMove={({ activeIndex, overIndex }) =>
181
-
ingredients.move(activeIndex, overIndex)}
182
-
>
183
-
<div className="flex w-full flex-col gap-2">
184
-
{ingredients.fields.map((field, index) => (
185
-
<SortableItem key={field.id} value={field.id} asChild>
186
-
<div className="grid grid-cols-[2rem_0.3fr_1fr_2rem] items-center gap-2">
187
-
<SortableDragHandle
188
-
type="button"
189
-
variant="outline"
190
-
size="icon"
191
-
className="size-8 shrink-0"
192
-
>
193
-
<DragHandleDots2Icon
194
-
className="size-4"
195
-
aria-hidden="true"
196
-
/>
197
-
</SortableDragHandle>
198
-
199
-
<FormField
200
-
control={form.control}
201
-
name={`ingredients.${index}.amount`}
202
-
render={({ field: { value, ...field } }) => (
203
-
<FormItem>
204
-
<FormControl>
205
-
<Input
206
-
placeholder="Amount"
207
-
value={value || ""}
208
-
className="h-8"
209
-
{...field}
210
-
/>
211
-
</FormControl>
212
-
<FormMessage />
213
-
</FormItem>
214
-
)}
215
-
/>
216
-
217
-
<FormField
218
-
control={form.control}
219
-
name={`ingredients.${index}.name`}
220
-
render={({ field }) => (
221
-
<FormItem>
222
-
<FormControl>
223
-
<Input
224
-
placeholder="Ingredient"
225
-
className="h-8"
226
-
{...field}
227
-
/>
228
-
</FormControl>
229
-
<FormMessage />
230
-
</FormItem>
231
-
)}
232
-
/>
233
-
234
-
<Button
235
-
type="button"
236
-
variant="destructive"
237
-
className="size-8"
238
-
onClick={(e) => {
239
-
e.preventDefault();
240
-
ingredients.remove(index);
241
-
}}
242
-
>
243
-
<TrashIcon />
244
-
</Button>
245
-
</div>
246
-
</SortableItem>
247
-
))}
248
-
</div>
249
-
</Sortable>
250
-
<Button
251
-
type="button"
252
-
variant="secondary"
253
-
onClick={(e) => {
254
-
e.preventDefault();
255
-
ingredients.append({
256
-
name: "",
257
-
amount: "",
258
-
});
259
-
}}
260
-
>
261
-
Add
262
-
</Button>
263
-
</div>
264
-
265
-
<div className="grid gap-2">
266
-
<Label>Steps</Label>
267
-
<Sortable
268
-
value={steps.fields}
269
-
onMove={({ activeIndex, overIndex }) =>
270
-
steps.move(activeIndex, overIndex)}
271
-
>
272
-
<div className="flex w-full flex-col gap-2">
273
-
{steps.fields.map((field, index) => (
274
-
<SortableItem key={field.id} value={field.id} asChild>
275
-
<div className="grid grid-cols-[2rem_auto_2rem] items-center gap-2">
276
-
<SortableDragHandle
277
-
type="button"
278
-
variant="outline"
279
-
size="icon"
280
-
className="size-8 shrink-0"
281
-
>
282
-
<DragHandleDots2Icon
283
-
className="size-4"
284
-
aria-hidden="true"
285
-
/>
286
-
</SortableDragHandle>
287
-
<FormField
288
-
control={form.control}
289
-
name={`steps.${index}.text`}
290
-
render={({ field }) => (
291
-
<FormItem>
292
-
<FormControl>
293
-
<Input className="h-8" {...field} />
294
-
</FormControl>
295
-
<FormMessage />
296
-
</FormItem>
297
-
)}
298
-
/>
299
-
300
-
<Button
301
-
type="button"
302
-
variant="destructive"
303
-
className="size-8"
304
-
onClick={(e) => {
305
-
e.preventDefault();
306
-
steps.remove(index);
307
-
}}
308
-
>
309
-
<TrashIcon />
310
-
</Button>
311
-
</div>
312
-
</SortableItem>
313
-
))}
314
-
</div>
315
-
</Sortable>
316
-
<Button
317
-
type="button"
318
-
variant="secondary"
319
-
onClick={(e) => {
320
-
e.preventDefault();
321
-
steps.append({ text: "" });
322
-
}}
323
-
>
324
-
Add
325
-
</Button>
326
-
</div>
327
-
328
-
<div className="grid justify-end">
329
-
<Button
330
-
type="submit"
331
-
className="ml-auto"
332
-
disabled={isPending}
333
-
>
334
-
Submit
335
-
</Button>
336
-
</div>
337
-
</form>
338
-
</Form>
339
-
</CardContent>
340
-
</Card>
341
-
</div>
342
-
</>
343
-
);
344
-
}
345
-
346
-
const Breadcrumbs = () => (
347
-
<header className="flex h-16 shrink-0 items-center gap-2 transition-[width,height] ease-linear group-has-[[data-collapsible=icon]]/sidebar-wrapper:h-12">
348
-
<div className="flex items-center gap-2 px-4">
349
-
<SidebarTrigger className="-ml-1" />
350
-
<Separator orientation="vertical" className="mr-2 h-4" />
351
-
<Breadcrumb>
352
-
<BreadcrumbList>
353
-
<BreadcrumbItem className="hidden md:block">
354
-
<BreadcrumbLink asChild>
355
-
<Link href="/">Home</Link>
356
-
</BreadcrumbLink>
357
-
</BreadcrumbItem>
358
-
<BreadcrumbSeparator className="hidden md:block" />
359
-
<BreadcrumbItem className="hidden md:block">
360
-
<BreadcrumbLink asChild>
361
-
<Link href="/recipes">Recipes</Link>
362
-
</BreadcrumbLink>
363
-
</BreadcrumbItem>
364
-
<BreadcrumbSeparator className="hidden md:block" />
365
-
<BreadcrumbItem>
366
-
<BreadcrumbPage>New</BreadcrumbPage>
367
-
</BreadcrumbItem>
368
-
</BreadcrumbList>
369
-
</Breadcrumb>
370
-
</div>
371
-
</header>
372
-
);
-126
apps/web/src/routes/_.(auth)/login.tsx
-126
apps/web/src/routes/_.(auth)/login.tsx
···
1
-
import {
2
-
Breadcrumb,
3
-
BreadcrumbItem,
4
-
BreadcrumbList,
5
-
BreadcrumbPage,
6
-
} from '@/components/ui/breadcrumb'
7
-
import { Button } from '@/components/ui/button'
8
-
import {
9
-
Card,
10
-
CardContent,
11
-
CardDescription,
12
-
CardFooter,
13
-
CardHeader,
14
-
CardTitle,
15
-
} from '@/components/ui/card'
16
-
import { Input } from '@/components/ui/input'
17
-
import { Label } from '@/components/ui/label'
18
-
import { Separator } from '@/components/ui/separator'
19
-
import { SidebarTrigger } from '@/components/ui/sidebar'
20
-
import { sleep } from '@/lib/utils'
21
-
import {
22
-
createAuthorizationUrl,
23
-
resolveFromIdentity,
24
-
} from '@atcute/oauth-browser-client'
25
-
import { useMutation } from '@tanstack/react-query'
26
-
import { createFileRoute } from '@tanstack/react-router'
27
-
import { useState } from 'react'
28
-
29
-
export const Route = createFileRoute('/_/(auth)/login')({
30
-
component: RouteComponent,
31
-
})
32
-
33
-
function RouteComponent() {
34
-
const [handle, setHandle] = useState('')
35
-
36
-
const { mutate, isPending, error } = useMutation({
37
-
mutationKey: ['login'],
38
-
mutationFn: async () => {
39
-
const { identity, metadata } = await resolveFromIdentity(handle)
40
-
41
-
const authUrl = await createAuthorizationUrl({
42
-
metadata: metadata,
43
-
identity: identity,
44
-
scope: 'atproto transition:generic',
45
-
})
46
-
47
-
await sleep(200)
48
-
49
-
return authUrl
50
-
},
51
-
onSuccess: async (authUrl: URL) => {
52
-
window.location.assign(authUrl)
53
-
54
-
await new Promise((_resolve, reject) => {
55
-
const listener = () => {
56
-
reject(new Error(`user aborted the login request`))
57
-
}
58
-
59
-
window.addEventListener('pageshow', listener, { once: true })
60
-
})
61
-
},
62
-
})
63
-
64
-
return (
65
-
<>
66
-
<header className="flex h-16 shrink-0 items-center gap-2 transition-[width,height] ease-linear group-has-[[data-collapsible=icon]]/sidebar-wrapper:h-12">
67
-
<div className="flex items-center gap-2 px-4">
68
-
<SidebarTrigger className="-ml-1" />
69
-
<Separator orientation="vertical" className="mr-2 h-4" />
70
-
<Breadcrumb>
71
-
<BreadcrumbList>
72
-
<BreadcrumbItem>
73
-
<BreadcrumbPage>Log in</BreadcrumbPage>
74
-
</BreadcrumbItem>
75
-
</BreadcrumbList>
76
-
</Breadcrumb>
77
-
</div>
78
-
</header>
79
-
<div className="flex flex-1 flex-col items-center justify-center gap-4 p-4 pt-0">
80
-
<Card className="max-w-sm w-full">
81
-
<CardHeader>
82
-
<CardTitle>Log in</CardTitle>
83
-
<CardDescription>
84
-
Enter your handle below to sign in to your account.
85
-
</CardDescription>
86
-
</CardHeader>
87
-
<CardContent>
88
-
<div className="flex flex-col gap-2">
89
-
<Label htmlFor="handle">Handle</Label>
90
-
<Input
91
-
className={`${error ? 'border-destructive text-destructive' : ''}`}
92
-
type="text"
93
-
id="handle"
94
-
name="handle"
95
-
placeholder="johndoe.bsky.social"
96
-
required
97
-
value={handle}
98
-
onChange={(e) => setHandle(e.currentTarget.value)}
99
-
/>
100
-
{error && (
101
-
<p className="text-sm font-medium text-destructive">
102
-
{error.message}
103
-
</p>
104
-
)}
105
-
</div>
106
-
</CardContent>
107
-
<CardFooter className="grid gap-2">
108
-
<Button onClick={() => mutate()} disabled={isPending}>
109
-
Log in
110
-
</Button>
111
-
<p className="text-sm text-muted-foreground text-center">
112
-
Don't have an account?{' '}
113
-
<a
114
-
className="font-bold text-primary"
115
-
href="https://bsky.app/"
116
-
target="_blank"
117
-
>
118
-
Sign up on Bluesky!
119
-
</a>
120
-
</p>
121
-
</CardFooter>
122
-
</Card>
123
-
</div>
124
-
</>
125
-
)
126
-
}
-70
apps/web/src/routes/_.tsx
-70
apps/web/src/routes/_.tsx
···
1
-
import { Link, createFileRoute, Outlet } from '@tanstack/react-router'
2
-
import { Button } from '@/components/ui/button'
3
-
import { Card, CardContent, CardFooter, CardHeader, CardTitle } from '@/components/ui/card'
4
-
import { SidebarTrigger } from '@/components/ui/sidebar'
5
-
6
-
export const Route = createFileRoute('/_')({
7
-
component: RouteComponent,
8
-
errorComponent: ({ error }) => {
9
-
return (
10
-
<>
11
-
<header className="flex h-16 shrink-0 items-center gap-2 transition-[width,height] ease-linear group-has-[[data-collapsible=icon]]/sidebar-wrapper:h-12">
12
-
<div className="flex items-center gap-2 px-4">
13
-
<SidebarTrigger className="-ml-1" />
14
-
</div>
15
-
</header>
16
-
<div className="flex flex-1 flex-col gap-4 p-4 pt-0">
17
-
<Card className="m-auto max-w-sm">
18
-
<CardHeader>
19
-
<CardTitle>Error!</CardTitle>
20
-
</CardHeader>
21
-
<CardContent>
22
-
{error.message}
23
-
</CardContent>
24
-
<CardFooter>
25
-
<Button asChild>
26
-
<Link to="/">Go home</Link>
27
-
</Button>
28
-
</CardFooter>
29
-
</Card>
30
-
</div>
31
-
</>
32
-
);
33
-
},
34
-
35
-
notFoundComponent: () => {
36
-
return (
37
-
<>
38
-
<header className="flex h-16 shrink-0 items-center gap-2 transition-[width,height] ease-linear group-has-[[data-collapsible=icon]]/sidebar-wrapper:h-12">
39
-
<div className="flex items-center gap-2 px-4">
40
-
<SidebarTrigger className="-ml-1" />
41
-
</div>
42
-
</header>
43
-
<div className="flex flex-1 flex-col gap-4 p-4 pt-0">
44
-
<Card className="m-auto max-w-sm">
45
-
<CardHeader>
46
-
<CardTitle>Not found</CardTitle>
47
-
</CardHeader>
48
-
<CardContent>
49
-
{"The page you tried to view doesn't exist."}
50
-
</CardContent>
51
-
<CardFooter>
52
-
<Button asChild>
53
-
<Link to="/">Go home</Link>
54
-
</Button>
55
-
</CardFooter>
56
-
</Card>
57
-
</div>
58
-
</>
59
-
);
60
-
},
61
-
62
-
})
63
-
64
-
function RouteComponent() {
65
-
return (
66
-
<>
67
-
<Outlet />
68
-
</>
69
-
)
70
-
}
+8
-19
apps/web/src/routes/__root.tsx
+8
-19
apps/web/src/routes/__root.tsx
···
1
-
import { AppSidebar } from '@/components/app-sidebar'
2
-
import {
3
-
SidebarInset,
4
-
SidebarProvider,
5
-
} from '@/components/ui/sidebar'
6
-
import { AuthContextType } from '@/state/auth';
7
-
import { Outlet, createRootRouteWithContext } from '@tanstack/react-router'
1
+
import * as React from 'react'
2
+
import { Outlet, createRootRoute } from '@tanstack/react-router'
8
3
9
-
type RootContext = {
10
-
auth: AuthContextType;
11
-
};
12
-
13
-
export const Route = createRootRouteWithContext<RootContext>()({
4
+
export const Route = createRootRoute({
14
5
component: RootComponent,
15
-
});
6
+
})
16
7
17
8
function RootComponent() {
18
9
return (
19
-
<SidebarProvider>
20
-
<AppSidebar />
21
-
<SidebarInset>
22
-
<Outlet />
23
-
</SidebarInset>
24
-
</SidebarProvider>
10
+
<React.Fragment>
11
+
<div>Hello "__root"!</div>
12
+
<Outlet />
13
+
</React.Fragment>
25
14
)
26
15
}
-45
apps/web/src/screens/Recipes/RecipeCard.tsx
-45
apps/web/src/screens/Recipes/RecipeCard.tsx
···
1
-
import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar";
2
-
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
3
-
import { BlueRecipesFeedGetRecipes } from "@atcute/client/lexicons";
4
-
import { Link } from "@tanstack/react-router";
5
-
import { Clock, CookingPot, ListIcon } from "lucide-react";
6
-
7
-
type RecipeCardProps = {
8
-
recipe: BlueRecipesFeedGetRecipes.Result;
9
-
};
10
-
11
-
export const RecipeCard = ({ recipe }: RecipeCardProps) => {
12
-
return (
13
-
<Link to="/recipes/$author/$rkey" params={{ author: recipe.author.handle, rkey: recipe.rkey }} className="w-full">
14
-
<Card className="w-full">
15
-
<CardHeader>
16
-
<CardDescription className="flex items-center space-x-2">
17
-
<Avatar className="h-6 w-6 rounded-lg">
18
-
<AvatarImage src={recipe.author.avatarUrl} alt={recipe.author.displayName} />
19
-
<AvatarFallback className="rounded-lg">{recipe.author.displayName}</AvatarFallback>
20
-
</Avatar>
21
-
22
-
<span>{recipe.author.displayName}</span>
23
-
</CardDescription>
24
-
<CardTitle>{recipe.title}</CardTitle>
25
-
</CardHeader>
26
-
<CardContent>
27
-
<p>{recipe.description}</p>
28
-
</CardContent>
29
-
<CardFooter className="flex gap-6 text-sm text-muted-foreground">
30
-
<span className="flex items-center gap-2">
31
-
<ListIcon className="size-4" /> <span>{recipe.steps}</span>
32
-
</span>
33
-
34
-
<span className="flex items-center gap-2">
35
-
<CookingPot className="size-4" /> <span>{recipe.ingredients}</span>
36
-
</span>
37
-
38
-
<span className="flex items-center gap-2">
39
-
<Clock className="size-4" /> <span>{recipe.time} mins</span>
40
-
</span>
41
-
</CardFooter>
42
-
</Card>
43
-
</Link>
44
-
);
45
-
};
-78
apps/web/src/state/auth.tsx
-78
apps/web/src/state/auth.tsx
···
1
-
import { At } from "@atcute/client/lexicons";
2
-
import { finalizeAuthorization, getSession, OAuthUserAgent } from "@atcute/oauth-browser-client";
3
-
import { createContext, PropsWithChildren, useContext, useEffect, useState } from "react";
4
-
5
-
export type AuthContextType = {
6
-
isLoggedIn: boolean;
7
-
agent?: OAuthUserAgent;
8
-
logOut: () => Promise<void>;
9
-
};
10
-
11
-
const AuthContext = createContext<AuthContextType>({
12
-
isLoggedIn: false,
13
-
logOut: async () => {},
14
-
});
15
-
16
-
export const AuthProvider = ({ children }: PropsWithChildren) => {
17
-
const [isReady, setIsReady] = useState(false);
18
-
const [isLoggedIn, setIsLoggedIn] = useState(false);
19
-
const [agent, setAgent] = useState<OAuthUserAgent | undefined>(undefined);
20
-
21
-
useEffect(() => {
22
-
const init = async () => {
23
-
const params = new URLSearchParams(location.hash.slice(1));
24
-
25
-
if (params.has("state") && (params.has("code") || params.has("error"))) {
26
-
history.replaceState(null, "", location.pathname + location.search);
27
-
28
-
const session = await finalizeAuthorization(params);
29
-
const did = session.info.sub;
30
-
31
-
localStorage.setItem("lastSignedIn", did);
32
-
return session;
33
-
34
-
} else {
35
-
const lastSignedIn = localStorage.getItem("lastSignedIn");
36
-
37
-
if (lastSignedIn) {
38
-
try {
39
-
return await getSession(lastSignedIn as At.DID);
40
-
} catch (err) {
41
-
localStorage.removeItem("lastSignedIn");
42
-
throw err;
43
-
}
44
-
}
45
-
}
46
-
};
47
-
48
-
init()
49
-
.then(session => {
50
-
if (session) {
51
-
setAgent(new OAuthUserAgent(session));
52
-
setIsLoggedIn(true);
53
-
}
54
-
55
-
setIsReady(true)
56
-
})
57
-
.catch(() => {});
58
-
}, []);
59
-
60
-
if (!isReady) return null;
61
-
62
-
return (
63
-
<AuthContext.Provider value={{
64
-
isLoggedIn,
65
-
agent,
66
-
logOut: async () => {
67
-
setIsLoggedIn(false);
68
-
await agent?.signOut();
69
-
},
70
-
}}>
71
-
{children}
72
-
</AuthContext.Provider>
73
-
);
74
-
};
75
-
76
-
export const useAuth = () => {
77
-
return useContext(AuthContext);
78
-
};
apps/web/src/state/client.tsx
apps/web/src/state/client.tsx
This is a binary file and will not be displayed.
+4
-9
apps/web/src/vite-env.d.ts
+4
-9
apps/web/src/vite-env.d.ts
···
1
-
/// <reference types="vite/client" />
2
-
/// <reference types="@cookware/lexicons" />
3
-
/// <reference types="@atcute/bluesky/lexicons" />
1
+
interface ViteTypeOptions {}
4
2
5
3
interface ImportMetaEnv {
6
-
readonly VITE_API_SERVICE: string;
7
-
readonly VITE_DEV_SERVER_PORT?: string;
8
-
readonly VITE_CLIENT_URI: string;
9
-
readonly VITE_OAUTH_CLIENT_ID: string;
10
-
readonly VITE_OAUTH_REDIRECT_URL: string;
11
-
readonly VITE_OAUTH_SCOPE: string;
4
+
readonly VITE_API_URL: string;
5
+
readonly VITE_CLIENT_ID: string;
6
+
readonly VITE_REDIRECT_URI: string;
12
7
}
13
8
14
9
interface ImportMeta {
-69
apps/web/tailwind.config.js
-69
apps/web/tailwind.config.js
···
1
-
import animate from 'tailwindcss-animate';
2
-
/** @type {import('tailwindcss').Config} */
3
-
export default {
4
-
darkMode: ["class"],
5
-
content: ["./index.html", "./src/**/*.{ts,tsx,js,jsx}"],
6
-
theme: {
7
-
extend: {
8
-
borderRadius: {
9
-
lg: 'var(--radius)',
10
-
md: 'calc(var(--radius) - 2px)',
11
-
sm: 'calc(var(--radius) - 4px)'
12
-
},
13
-
colors: {
14
-
background: 'hsl(var(--background))',
15
-
foreground: 'hsl(var(--foreground))',
16
-
card: {
17
-
DEFAULT: 'hsl(var(--card))',
18
-
foreground: 'hsl(var(--card-foreground))'
19
-
},
20
-
popover: {
21
-
DEFAULT: 'hsl(var(--popover))',
22
-
foreground: 'hsl(var(--popover-foreground))'
23
-
},
24
-
primary: {
25
-
DEFAULT: 'hsl(var(--primary))',
26
-
foreground: 'hsl(var(--primary-foreground))'
27
-
},
28
-
secondary: {
29
-
DEFAULT: 'hsl(var(--secondary))',
30
-
foreground: 'hsl(var(--secondary-foreground))'
31
-
},
32
-
muted: {
33
-
DEFAULT: 'hsl(var(--muted))',
34
-
foreground: 'hsl(var(--muted-foreground))'
35
-
},
36
-
accent: {
37
-
DEFAULT: 'hsl(var(--accent))',
38
-
foreground: 'hsl(var(--accent-foreground))'
39
-
},
40
-
destructive: {
41
-
DEFAULT: 'hsl(var(--destructive))',
42
-
foreground: 'hsl(var(--destructive-foreground))'
43
-
},
44
-
border: 'hsl(var(--border))',
45
-
input: 'hsl(var(--input))',
46
-
ring: 'hsl(var(--ring))',
47
-
chart: {
48
-
'1': 'hsl(var(--chart-1))',
49
-
'2': 'hsl(var(--chart-2))',
50
-
'3': 'hsl(var(--chart-3))',
51
-
'4': 'hsl(var(--chart-4))',
52
-
'5': 'hsl(var(--chart-5))'
53
-
},
54
-
sidebar: {
55
-
DEFAULT: 'hsl(var(--sidebar-background))',
56
-
foreground: 'hsl(var(--sidebar-foreground))',
57
-
primary: 'hsl(var(--sidebar-primary))',
58
-
'primary-foreground': 'hsl(var(--sidebar-primary-foreground))',
59
-
accent: 'hsl(var(--sidebar-accent))',
60
-
'accent-foreground': 'hsl(var(--sidebar-accent-foreground))',
61
-
border: 'hsl(var(--sidebar-border))',
62
-
ring: 'hsl(var(--sidebar-ring))'
63
-
}
64
-
}
65
-
}
66
-
},
67
-
plugins: [animate],
68
-
}
69
-
+4
-25
apps/web/tsconfig.app.json
+4
-25
apps/web/tsconfig.app.json
···
1
1
{
2
+
"extends": "@cookware/tsconfig/react.json",
2
3
"compilerOptions": {
3
-
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
4
-
"target": "ES2020",
5
-
"useDefineForClassFields": true,
6
-
"lib": ["ES2020", "DOM", "DOM.Iterable"],
7
-
"module": "ESNext",
8
-
"skipLibCheck": true,
4
+
"types": ["bun", "vite/client"],
9
5
10
-
/* Bundler mode */
11
-
"moduleResolution": "bundler",
12
-
"allowImportingTsExtensions": true,
13
-
"isolatedModules": true,
14
-
"moduleDetection": "force",
15
-
"noEmit": true,
16
-
"jsx": "react-jsx",
17
-
18
-
/* Linting */
19
-
"strict": true,
20
-
"noUnusedLocals": true,
21
-
"noUnusedParameters": true,
22
-
"noFallthroughCasesInSwitch": true,
23
-
"noUncheckedSideEffectImports": true,
24
-
25
-
/* Import aliases */
6
+
/* Path aliasing */
26
7
"baseUrl": ".",
27
8
"paths": {
28
-
"@/*": [
29
-
"./src/*"
30
-
]
9
+
"@/*": ["./src/*"]
31
10
}
32
11
},
33
12
"include": ["src"]
+1
apps/web/tsconfig.json
+1
apps/web/tsconfig.json
+1
-21
apps/web/tsconfig.node.json
+1
-21
apps/web/tsconfig.node.json
···
1
1
{
2
-
"compilerOptions": {
3
-
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
4
-
"target": "ES2022",
5
-
"lib": ["ES2023"],
6
-
"module": "ESNext",
7
-
"skipLibCheck": true,
8
-
9
-
/* Bundler mode */
10
-
"moduleResolution": "bundler",
11
-
"allowImportingTsExtensions": true,
12
-
"isolatedModules": true,
13
-
"moduleDetection": "force",
14
-
"noEmit": true,
15
-
16
-
/* Linting */
17
-
"strict": true,
18
-
"noUnusedLocals": true,
19
-
"noUnusedParameters": true,
20
-
"noFallthroughCasesInSwitch": true,
21
-
"noUncheckedSideEffectImports": true
22
-
},
2
+
"extends": "@cookware/tsconfig/base.json",
23
3
"include": ["vite.config.ts"]
24
4
}
+13
-47
apps/web/vite.config.ts
+13
-47
apps/web/vite.config.ts
···
1
-
import { defineConfig } from 'vite'
2
-
import react from '@vitejs/plugin-react-swc'
3
-
import { TanStackRouterVite } from '@tanstack/router-plugin/vite'
4
-
import path from 'path'
5
-
import metadata from "./public/client-metadata.json";
1
+
import { defineConfig } from 'vite';
2
+
import react from '@vitejs/plugin-react';
3
+
import tailwindcss from '@tailwindcss/vite';
4
+
import { tanstackRouter } from '@tanstack/router-plugin/vite';
5
+
import path from 'node:path';
6
6
7
-
const SERVER_HOST = "127.0.0.1";
8
-
const SERVER_PORT = 5173;
9
-
10
-
// https://vite.dev/config/
11
7
export default defineConfig({
12
8
plugins: [
13
-
TanStackRouterVite(),
14
-
react(),
15
-
16
-
{
17
-
name: "oauth",
18
-
config(_conf, { command }) {
19
-
if (command === "build") {
20
-
process.env.VITE_OAUTH_CLIENT_ID = metadata.client_id;
21
-
process.env.VITE_OAUTH_REDIRECT_URL = metadata.redirect_uris[0];
22
-
} else {
23
-
const redirectUri = ((): string => {
24
-
const url = new URL(metadata.redirect_uris[0]);
25
-
return `http://${SERVER_HOST}:${SERVER_PORT}${url.pathname}`;
26
-
})();
27
-
28
-
const clientId =
29
-
`http://localhost` +
30
-
`?redirect_uri=${encodeURIComponent(redirectUri)}` +
31
-
`&scope=${encodeURIComponent(metadata.scope)}`;
32
-
33
-
process.env.VITE_DEV_SERVER_PORT = "" + SERVER_PORT;
34
-
process.env.VITE_OAUTH_CLIENT_ID = clientId;
35
-
process.env.VITE_OAUTH_REDIRECT_URL = redirectUri;
36
-
}
37
-
38
-
process.env.VITE_CLIENT_URI = metadata.client_uri;
39
-
process.env.VITE_OAUTH_SCOPE = metadata.scope;
40
-
},
41
-
},
9
+
tanstackRouter({
10
+
target: 'react',
11
+
autoCodeSplitting: true,
12
+
}),
13
+
tailwindcss(),
14
+
react()
42
15
],
43
-
server: {
44
-
allowedHosts: ["flat-hundreds-negotiations-locale.trycloudflare.com"],
45
-
host: SERVER_HOST,
46
-
port: SERVER_PORT,
47
-
},
48
-
build: {
49
-
target: "esnext",
50
-
},
16
+
51
17
resolve: {
52
18
alias: {
53
-
'@': path.resolve(__dirname, './src'),
19
+
"@": path.resolve(__dirname, "./src"),
54
20
}
55
21
}
56
22
})
+918
-804
bun.lock
+918
-804
bun.lock
···
3
3
"configVersion": 1,
4
4
"workspaces": {
5
5
"": {
6
+
"name": "@cookware/monorepo",
7
+
"dependencies": {
8
+
"@atcute/oauth-browser-client": "^2.0.2",
9
+
"@tanstack/react-router": "^1.140.0",
10
+
},
6
11
"devDependencies": {
12
+
"@tanstack/react-router-devtools": "^1.140.0",
13
+
"@tanstack/router-plugin": "^1.140.0",
7
14
"turbo": "^2.3.3",
15
+
"typescript": "^5.9.3",
8
16
},
9
17
},
10
18
"apps/api": {
11
19
"name": "@cookware/api",
12
20
"dependencies": {
13
-
"@atcute/client": "^2.0.6",
14
-
"@atproto/api": "^0.13.19",
15
-
"@atproto/common": "^0.4.5",
16
-
"@atproto/crypto": "^0.4.2",
17
-
"@atproto/jwk-jose": "^0.1.2",
18
-
"@atproto/oauth-client-node": "^0.2.3",
21
+
"@atcute/atproto": "^3.1.9",
22
+
"@atcute/client": "catalog:",
23
+
"@atcute/identity": "^1.1.3",
24
+
"@atcute/identity-resolver": "^1.1.4",
25
+
"@atcute/lexicons": "catalog:",
26
+
"@atcute/xrpc-server": "^0.1.3",
19
27
"@cookware/database": "workspace:*",
20
28
"@cookware/lexicons": "workspace:*",
21
-
"@hono/node-server": "^1.13.7",
22
29
"@libsql/client": "^0.14.0",
23
-
"@sentry/node": "^8.42.0",
24
-
"@skyware/jetstream": "^0.2.1",
25
-
"bufferutil": "^4.0.8",
26
-
"drizzle-orm": "^0.37.0",
27
-
"hono": "^4.6.12",
28
-
"hono-sessions": "^0.7.0",
29
-
"jose": "^5.9.6",
30
+
"drizzle-orm": "catalog:",
31
+
"hono": "^4.10.7",
30
32
"pino": "^9.5.0",
31
-
"uint8arrays": "^5.1.0",
32
-
"ws": "^8.18.0",
33
-
"zod": "^3.23.8",
34
33
},
35
34
"devDependencies": {
36
-
"@atcute/bluesky": "^1.0.9",
35
+
"@atcute/bluesky": "^3.2.10",
37
36
"@cookware/tsconfig": "workspace:*",
38
-
"@swc/core": "^1.9.3",
39
-
"@types/node": "^22.10.1",
40
-
"@types/ws": "^8.5.13",
37
+
"@types/bun": "catalog:",
41
38
"drizzle-kit": "^0.29.0",
42
-
"pino-pretty": "^13.0.0",
39
+
"pino-pretty": "^13.1.2",
43
40
"rimraf": "^6.0.1",
44
-
"ts-node": "^10.9.2",
45
-
"tsup": "^8.3.5",
46
-
"tsx": "^4.19.2",
47
-
"typescript": "^5.7.2",
41
+
},
42
+
},
43
+
"apps/app": {
44
+
"name": "app",
45
+
"version": "0.1.0",
46
+
"dependencies": {
47
+
"@atcute/atproto": "catalog:",
48
+
"@atcute/client": "catalog:",
49
+
"@atcute/identity": "catalog:",
50
+
"@atcute/identity-resolver": "catalog:",
51
+
"@atcute/lexicons": "catalog:",
52
+
"@atproto/oauth-client-node": "^0.3.13",
53
+
"@cookware/lexicons": "workspace:*",
54
+
"@radix-ui/react-avatar": "^1.1.11",
55
+
"@radix-ui/react-dialog": "^1.1.15",
56
+
"@radix-ui/react-dropdown-menu": "^2.1.16",
57
+
"@radix-ui/react-label": "^2.1.8",
58
+
"@radix-ui/react-separator": "^1.1.8",
59
+
"@radix-ui/react-slot": "^1.2.4",
60
+
"@radix-ui/react-tooltip": "^1.2.8",
61
+
"@tabler/icons-react": "^3.35.0",
62
+
"@tanstack/react-query": "^5.90.12",
63
+
"class-variance-authority": "^0.7.1",
64
+
"clsx": "^2.1.1",
65
+
"lucide-react": "^0.556.0",
66
+
"next": "16.0.7",
67
+
"react": "19.2.0",
68
+
"react-dom": "19.2.0",
69
+
"tailwind-merge": "^3.4.0",
70
+
},
71
+
"devDependencies": {
72
+
"@tailwindcss/postcss": "^4",
73
+
"@tanstack/query-devtools": "^5.91.1",
74
+
"@tanstack/react-query-devtools": "^5.91.1",
75
+
"@types/node": "^20",
76
+
"@types/react": "^19",
77
+
"@types/react-dom": "^19",
78
+
"eslint": "^9",
79
+
"eslint-config-next": "16.0.7",
80
+
"tailwindcss": "^4",
81
+
"tw-animate-css": "^1.4.0",
82
+
"typescript": "^5",
48
83
},
49
84
},
50
85
"apps/ingester": {
51
86
"name": "@cookware/ingester",
52
87
"dependencies": {
53
-
"@atcute/client": "^2.0.6",
88
+
"@atcute/client": "catalog:",
89
+
"@atcute/identity": "^1.1.3",
90
+
"@atcute/identity-resolver": "^1.1.4",
91
+
"@atcute/jetstream": "^1.1.2",
92
+
"@atcute/lexicons": "catalog:",
93
+
"@badrap/valita": "^0.4.6",
54
94
"@cookware/database": "workspace:^",
95
+
"@cookware/lexicons": "workspace:*",
55
96
"@sentry/node": "^8.42.0",
56
-
"@skyware/jetstream": "^0.2.1",
57
-
"bufferutil": "^4.0.8",
58
-
"drizzle-orm": "^0.37.0",
59
97
"pino": "^9.5.0",
60
-
"ws": "^8.18.0",
61
-
"zod": "^3.23.8",
62
98
},
63
99
"devDependencies": {
64
-
"@cookware/lexicons": "workspace:*",
65
100
"@cookware/tsconfig": "workspace:*",
66
-
"@types/node": "^22.10.1",
101
+
"@types/bun": "catalog:",
67
102
"@types/ws": "^8.5.13",
68
103
"pino-pretty": "^13.0.0",
69
104
"rimraf": "^6.0.1",
70
-
"ts-node": "^10.9.2",
71
-
"tsup": "^8.3.5",
72
-
"tsx": "^4.19.2",
73
105
"typescript": "^5.7.2",
74
106
},
75
107
},
76
108
"apps/web": {
77
-
"name": "@cookware/web",
109
+
"name": "web",
78
110
"version": "0.0.0",
79
111
"dependencies": {
80
-
"@atcute/client": "^2.0.6",
81
-
"@atcute/oauth-browser-client": "^1.0.7",
82
-
"@atproto/common": "^0.4.5",
83
-
"@atproto/common-web": "^0.3.1",
84
-
"@dnd-kit/core": "^6.3.1",
85
-
"@dnd-kit/modifiers": "^9.0.0",
86
-
"@dnd-kit/sortable": "^10.0.0",
87
-
"@dnd-kit/utilities": "^3.2.2",
88
-
"@hookform/resolvers": "^3.9.1",
89
-
"@radix-ui/react-avatar": "^1.1.1",
90
-
"@radix-ui/react-collapsible": "^1.1.1",
91
-
"@radix-ui/react-dialog": "^1.1.4",
92
-
"@radix-ui/react-dropdown-menu": "^2.1.4",
93
-
"@radix-ui/react-icons": "^1.3.2",
94
-
"@radix-ui/react-label": "^2.1.0",
95
-
"@radix-ui/react-separator": "^1.1.0",
96
-
"@radix-ui/react-slot": "^1.1.0",
97
-
"@radix-ui/react-tooltip": "^1.1.4",
98
-
"@tanstack/react-query": "^5.62.2",
99
-
"@tanstack/react-query-devtools": "^5.62.2",
100
-
"@tanstack/react-router": "^1.91.2",
101
-
"axios": "^1.7.9",
112
+
"@radix-ui/react-avatar": "^1.1.11",
113
+
"@radix-ui/react-dialog": "^1.1.15",
114
+
"@radix-ui/react-dropdown-menu": "^2.1.16",
115
+
"@radix-ui/react-label": "^2.1.8",
116
+
"@radix-ui/react-separator": "^1.1.8",
117
+
"@radix-ui/react-slot": "^1.2.4",
118
+
"@radix-ui/react-tooltip": "^1.2.8",
102
119
"class-variance-authority": "^0.7.1",
103
120
"clsx": "^2.1.1",
104
-
"lucide-react": "^0.464.0",
105
-
"react-dom": "19.0.0",
106
-
"react-hook-form": "^7.54.1",
107
-
"tailwind-merge": "^2.5.5",
108
-
"tailwindcss-animate": "^1.0.7",
109
-
"zod": "^3.23.8",
121
+
"lucide-react": "^0.556.0",
122
+
"react": "^19.2.0",
123
+
"react-dom": "^19.2.0",
124
+
"tailwind-merge": "^3.4.0",
125
+
"tailwindcss": "^4.1.17",
110
126
},
111
127
"devDependencies": {
112
-
"@atcute/bluesky": "^1.0.9",
113
-
"@cookware/lexicons": "workspace:*",
114
-
"@eslint/js": "^9.15.0",
115
-
"@tanstack/eslint-plugin-query": "^5.62.1",
116
-
"@tanstack/router-devtools": "^1.85.5",
117
-
"@tanstack/router-plugin": "^1.85.3",
118
-
"@types/node": "^22.10.1",
119
-
"@types/react": "^19.0.0",
120
-
"@types/react-dom": "^19.0.0",
121
-
"@vitejs/plugin-react-swc": "^3.5.0",
122
-
"autoprefixer": "^10.4.20",
123
-
"cssnano": "^7.0.6",
124
-
"eslint": "^9.15.0",
125
-
"eslint-plugin-react-hooks": "^5.0.0",
126
-
"eslint-plugin-react-refresh": "^0.4.14",
127
-
"globals": "^15.12.0",
128
-
"postcss": "^8.4.49",
129
-
"react": "19.0.0",
130
-
"tailwindcss": "^3.4.16",
131
-
"typescript": "~5.6.2",
132
-
"typescript-eslint": "^8.15.0",
133
-
"vite": "^6.0.1",
128
+
"@cookware/tsconfig": "workspace:*",
129
+
"@eslint/js": "^9.39.1",
130
+
"@tailwindcss/vite": "^4.1.17",
131
+
"@types/bun": "^1.3.4",
132
+
"@types/react": "^19.2.5",
133
+
"@types/react-dom": "^19.2.3",
134
+
"@vitejs/plugin-react": "^5.1.1",
135
+
"eslint": "^9.39.1",
136
+
"eslint-plugin-react-hooks": "^7.0.1",
137
+
"eslint-plugin-react-refresh": "^0.4.24",
138
+
"globals": "^16.5.0",
139
+
"tw-animate-css": "^1.4.0",
140
+
"typescript": "~5.9.3",
141
+
"typescript-eslint": "^8.46.4",
142
+
"vite": "npm:rolldown-vite@7.2.5",
134
143
},
135
144
},
136
145
"libs/database": {
137
146
"name": "@cookware/database",
138
147
"version": "0.0.0",
139
148
"dependencies": {
140
-
"@libsql/client": "^0.14.0",
141
-
"drizzle-orm": "^0.37.0",
149
+
"@libsql/client": "^0.15.15",
150
+
"drizzle-orm": "catalog:",
151
+
"pg": "^8.16.3",
142
152
"zod": "^3.23.8",
143
153
},
144
154
"devDependencies": {
155
+
"@atcute/lexicons": "catalog:",
145
156
"@atproto/oauth-client-node": "^0.2.3",
146
-
"@cookware/lexicons": "workspace:^",
157
+
"@cookware/lexicons": "workspace:*",
147
158
"@cookware/tsconfig": "workspace:*",
159
+
"@types/bun": "catalog:",
148
160
"@types/node": "^22.10.1",
161
+
"@types/pg": "^8.15.6",
149
162
"drizzle-kit": "^0.29.0",
150
163
"typescript": "^5.2.2",
151
164
},
···
153
166
"libs/lexicons": {
154
167
"name": "@cookware/lexicons",
155
168
"version": "0.0.0",
169
+
"dependencies": {
170
+
"@atcute/atproto": "catalog:",
171
+
"@atcute/bluesky": "catalog:",
172
+
"@atcute/client": "catalog:",
173
+
"@atcute/lexicons": "catalog:",
174
+
},
156
175
"devDependencies": {
157
-
"@atcute/client": "^2.0.6",
158
-
"@atcute/lex-cli": "^1.0.3",
176
+
"@atcute/lex-cli": "^2.3.3",
159
177
"@cookware/tsconfig": "workspace:*",
160
-
"typescript": "^5.7.2",
161
-
"zod": "^3.23.8",
162
-
},
163
-
"peerDependencies": {
164
-
"@atcute/client": "^2.0.6",
165
-
"zod": "^3.23.8",
178
+
"@typelex/emitter": "^0.4.0",
179
+
"@types/bun": "catalog:",
180
+
"@typespec/compiler": "^1.6.0",
166
181
},
167
182
},
168
183
"libs/tsconfig": {
169
184
"name": "@cookware/tsconfig",
170
185
"version": "0.0.0",
186
+
"dependencies": {
187
+
"@types/bun": "^1.3.3",
188
+
},
171
189
},
172
190
},
191
+
"catalog": {
192
+
"@atcute/atproto": "^3.1.9",
193
+
"@atcute/bluesky": "^3.2.11",
194
+
"@atcute/client": "^4.0.5",
195
+
"@atcute/identity": "^1.1.3",
196
+
"@atcute/identity-resolver": "^1.1.4",
197
+
"@atcute/lexicons": "^1.2.5",
198
+
"@types/bun": "^1.3.3",
199
+
"drizzle-orm": "^0.44.7",
200
+
},
173
201
"packages": {
174
202
"@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="],
175
203
176
204
"@atcute/atproto": ["@atcute/atproto@3.1.9", "", { "dependencies": { "@atcute/lexicons": "^1.2.2" } }, "sha512-DyWwHCTdR4hY2BPNbLXgVmm7lI+fceOwWbE4LXbGvbvVtSn+ejSVFaAv01Ra3kWDha0whsOmbJL8JP0QPpf1+w=="],
177
205
178
-
"@atcute/bluesky": ["@atcute/bluesky@1.0.15", "", { "peerDependencies": { "@atcute/client": "^1.0.0 || ^2.0.0" } }, "sha512-+EFiybmKQ97aBAgtaD+cKRJER5AMn3cZMkEwEg/pDdWyzxYJ9m1UgemmLdTgI8VrxPufKqdXS2nl7uO7TY6BPA=="],
206
+
"@atcute/bluesky": ["@atcute/bluesky@3.2.11", "", { "dependencies": { "@atcute/atproto": "^3.1.9", "@atcute/lexicons": "^1.2.5" } }, "sha512-AboS6y4t+zaxIq7E4noue10csSpIuk/Uwo30/l6GgGBDPXrd7STw8Yb5nGZQP+TdG/uC8/c2mm7UnY65SDOh6A=="],
207
+
208
+
"@atcute/cbor": ["@atcute/cbor@2.2.8", "", { "dependencies": { "@atcute/cid": "^2.2.6", "@atcute/multibase": "^1.1.6", "@atcute/uint8array": "^1.0.5" } }, "sha512-UzOAN9BuN6JCXgn0ryV8qZuRJUDrNqrbLd6EFM8jc6RYssjRyGRxNy6RZ1NU/07Hd8Tq/0pz8+nQiMu5Zai5uw=="],
209
+
210
+
"@atcute/cid": ["@atcute/cid@2.2.6", "", { "dependencies": { "@atcute/multibase": "^1.1.6", "@atcute/uint8array": "^1.0.5" } }, "sha512-bTAHHbJ24p+E//V4KCS4xdmd39o211jJswvqQOevj7vk+5IYcgDLx1ryZWZ1sEPOo9x875li/kj5gpKL14RDwQ=="],
211
+
212
+
"@atcute/client": ["@atcute/client@4.1.0", "", { "dependencies": { "@atcute/identity": "^1.1.3", "@atcute/lexicons": "^1.2.5" } }, "sha512-AYhSu3RSDA2VDkVGOmad320NRbUUUf5pCFWJcOzlk25YC/4kyzmMFfpzhf1jjjEcY+anNBXGGhav/kKB1evggQ=="],
179
213
180
-
"@atcute/client": ["@atcute/client@2.0.9", "", {}, "sha512-QNDm9gMP6x9LY77ArwY+urQOBtQW74/onEAz42c40JxRm6Rl9K9cU4ROvNKJ+5cpVmEm1sthEWVRmDr5CSZENA=="],
214
+
"@atcute/crypto": ["@atcute/crypto@2.2.6", "", { "dependencies": { "@atcute/multibase": "^1.1.6", "@atcute/uint8array": "^1.0.5", "@noble/secp256k1": "^3.0.0" } }, "sha512-vkuexF+kmrKE1/Uqzub99Qi4QpnxA2jbu60E6PTgL4XypELQ6rb59MB/J1VbY2gs0kd3ET7+L3+NWpKD5nXyfA=="],
181
215
182
-
"@atcute/identity": ["@atcute/identity@1.1.2", "", { "dependencies": { "@atcute/lexicons": "^1.2.3", "@badrap/valita": "^0.4.6" } }, "sha512-vn0RN7SUF6N0sEPG9yyT6a0MzpfVS8BhsiLtB8OeS4qp2rLMQW33pelCpNitP1N+fq03MFlDGzs5p7K4qMs4cA=="],
216
+
"@atcute/identity": ["@atcute/identity@1.1.3", "", { "dependencies": { "@atcute/lexicons": "^1.2.4", "@badrap/valita": "^0.4.6" } }, "sha512-oIqPoI8TwWeQxvcLmFEZLdN2XdWcaLVtlm8pNk0E72As9HNzzD9pwKPrLr3rmTLRIoULPPFmq9iFNsTeCIU9ng=="],
183
217
184
-
"@atcute/lex-cli": ["@atcute/lex-cli@1.1.2", "", { "dependencies": { "@badrap/valita": "^0.4.2", "@externdefs/collider": "^0.1.0", "picocolors": "^1.1.1", "prettier": "^3.4.2" }, "bin": { "lex-cli": "cli.mjs" } }, "sha512-DUSA+hnZTgyo231lukuvopRy4p+ZHjV2ZKxgVSjNDNQieoECwP3gONTqOQKnsqA4C37hr34g8Fd2dUw7v00xqA=="],
218
+
"@atcute/identity-resolver": ["@atcute/identity-resolver@1.1.4", "", { "dependencies": { "@atcute/lexicons": "^1.2.2", "@atcute/util-fetch": "^1.0.3", "@badrap/valita": "^0.4.6" }, "peerDependencies": { "@atcute/identity": "^1.0.0" } }, "sha512-/SVh8vf2cXFJenmBnGeYF2aY3WGQm3cJeew5NWTlkqoy3LvJ5wkvKq9PWu4Tv653VF40rPOp6LOdVr9Fa+q5rA=="],
185
219
186
-
"@atcute/lexicons": ["@atcute/lexicons@1.2.3", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "esm-env": "^1.2.2" } }, "sha512-ZNfNWS4jaR8VgWSSBaWRSSmwFeP134BmvpTt9JmM2x5vRoXeIFthxU9USY8ZV4vm0GPoxEMgkDin8HIlnFTg2w=="],
220
+
"@atcute/jetstream": ["@atcute/jetstream@1.1.2", "", { "dependencies": { "@atcute/lexicons": "^1.2.2", "@badrap/valita": "^0.4.6", "@mary-ext/event-iterator": "^1.0.0", "@mary-ext/simple-event-emitter": "^1.0.0", "partysocket": "^1.1.5", "type-fest": "^4.41.0", "yocto-queue": "^1.2.1" } }, "sha512-u6p/h2xppp7LE6W/9xErAJ6frfN60s8adZuCKtfAaaBBiiYbb1CfpzN8Uc+2qtJZNorqGvuuDb5572Jmh7yHBQ=="],
221
+
222
+
"@atcute/lex-cli": ["@atcute/lex-cli@2.3.3", "", { "dependencies": { "@atcute/lexicon-doc": "^2.0.0", "@badrap/valita": "^0.4.6", "@optique/core": "^0.6.2", "@optique/run": "^0.6.2", "picocolors": "^1.1.1", "prettier": "^3.6.2" }, "bin": { "lex-cli": "cli.mjs" } }, "sha512-L+fxfJWVBFiuS53yK2aDg7F3R0Ak7UOj9BOM2khofR6yBSKHrkCuk3b6GrkbcMKo+9O0ynaLsuXxUNlHvw/m3w=="],
223
+
224
+
"@atcute/lexicon-doc": ["@atcute/lexicon-doc@2.0.4", "", { "dependencies": { "@atcute/identity": "^1.1.3", "@atcute/lexicons": "^1.2.5", "@badrap/valita": "^0.4.6" } }, "sha512-YfwlYFoYiBvRIYG0I1zsINCTFugFtS8l67uT3nQ04zdKVflzdg8uUj8cNZYRNY1V7okoOPdikhR4kPFhYGyemw=="],
225
+
226
+
"@atcute/lexicons": ["@atcute/lexicons@1.2.5", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "esm-env": "^1.2.2" } }, "sha512-9yO9WdgxW8jZ7SbzUycH710z+JmsQ9W9n5S6i6eghYju32kkluFmgBeS47r8e8p2+Dv4DemS7o/3SUGsX9FR5Q=="],
187
227
188
228
"@atcute/multibase": ["@atcute/multibase@1.1.6", "", { "dependencies": { "@atcute/uint8array": "^1.0.5" } }, "sha512-HBxuCgYLKPPxETV0Rot4VP9e24vKl8JdzGCZOVsDaOXJgbRZoRIF67Lp0H/OgnJeH/Xpva8Z5ReoTNJE5dn3kg=="],
189
229
190
-
"@atcute/oauth-browser-client": ["@atcute/oauth-browser-client@1.0.27", "", { "dependencies": { "@atcute/client": "^4.0.4", "@atcute/identity": "^1.1.1", "@atcute/lexicons": "^1.2.2", "@atcute/multibase": "^1.1.6", "@atcute/uint8array": "^1.0.5", "nanoid": "^5.1.5" } }, "sha512-Ng1tCOTMLgFHHoIHXTtCZR1/ND62an1qxPX2kBoUzkxxd7iCP7IBYYqOiKyJYT5n1R4zS+s29hFS4t9mxXa5kQ=="],
230
+
"@atcute/oauth-browser-client": ["@atcute/oauth-browser-client@2.0.2", "", { "dependencies": { "@atcute/client": "^4.1.0", "@atcute/identity-resolver": "^1.2.0", "@atcute/lexicons": "^1.2.5", "@atcute/multibase": "^1.1.6", "@atcute/uint8array": "^1.0.6", "nanoid": "^5.1.6" } }, "sha512-F76NZwiRbqZl+5X3Uiw3VPSPvdvRugeW9BZppZWqKawkMTYZQB3iyQKBD6ZI0kOdfLNKBamrd3hmeJs+V1xpww=="],
231
+
232
+
"@atcute/uint8array": ["@atcute/uint8array@1.0.6", "", {}, "sha512-ucfRBQc7BFT8n9eCyGOzDHEMKF/nZwhS2pPao4Xtab1ML3HdFYcX2DM1tadCzas85QTGxHe5urnUAAcNKGRi9A=="],
191
233
192
-
"@atcute/uint8array": ["@atcute/uint8array@1.0.5", "", {}, "sha512-XLWWxoR2HNl2qU+FCr0rp1APwJXci7HnzbOQLxK55OaMNBXZ19+xNC5ii4QCsThsDxa4JS/JTzuiQLziITWf2Q=="],
234
+
"@atcute/util-fetch": ["@atcute/util-fetch@1.0.3", "", { "dependencies": { "@badrap/valita": "^0.4.6" } }, "sha512-f8zzTb/xlKIwv2OQ31DhShPUNCmIIleX6p7qIXwWwEUjX6x8skUtpdISSjnImq01LXpltGV5y8yhV4/Mlb7CRQ=="],
235
+
236
+
"@atcute/xrpc-server": ["@atcute/xrpc-server@0.1.3", "", { "dependencies": { "@atcute/cbor": "^2.2.7", "@atcute/crypto": "^2.2.5", "@atcute/identity": "^1.1.1", "@atcute/identity-resolver": "^1.1.4", "@atcute/lexicons": "^1.2.2", "@atcute/multibase": "^1.1.6", "@atcute/uint8array": "^1.0.5", "@badrap/valita": "^0.4.6", "nanoid": "^5.1.5" } }, "sha512-AMig6MuAL5VfXRZVsQqQXKCXnZgpjTc6UM6RggvyE1qVT8y9tZPFXdP5tt/p6Jf+h4cAw+XMu2uyrGpUmnTSyQ=="],
193
237
194
238
"@atproto-labs/did-resolver": ["@atproto-labs/did-resolver@0.1.13", "", { "dependencies": { "@atproto-labs/fetch": "0.2.3", "@atproto-labs/pipe": "0.1.1", "@atproto-labs/simple-store": "0.2.0", "@atproto-labs/simple-store-memory": "0.1.3", "@atproto/did": "0.1.5", "zod": "^3.23.8" } }, "sha512-DG3YNaCKc6PAIv1Gsz3E1Kufw2t14OBxe4LdKK7KKLCNoex51hm+A5yMevShe3BSll+QosqWYIEgkPSc5xBoGQ=="],
195
239
···
209
253
210
254
"@atproto-labs/simple-store-memory": ["@atproto-labs/simple-store-memory@0.1.3", "", { "dependencies": { "@atproto-labs/simple-store": "0.2.0", "lru-cache": "^10.2.0" } }, "sha512-jkitT9+AtU+0b28DoN92iURLaCt/q/q4yX8q6V+9LSwYlUTqKoj/5NFKvF7x6EBuG+gpUdlcycbH7e60gjOhRQ=="],
211
255
212
-
"@atproto/api": ["@atproto/api@0.13.35", "", { "dependencies": { "@atproto/common-web": "^0.4.0", "@atproto/lexicon": "^0.4.6", "@atproto/syntax": "^0.3.2", "@atproto/xrpc": "^0.6.8", "await-lock": "^2.2.2", "multiformats": "^9.9.0", "tlds": "^1.234.0", "zod": "^3.23.8" } }, "sha512-vsEfBj0C333TLjDppvTdTE0IdKlXuljKSveAeI4PPx/l6eUKNnDTsYxvILtXUVzwUlTDmSRqy5O4Ryh78n1b7g=="],
213
-
214
-
"@atproto/common": ["@atproto/common@0.4.12", "", { "dependencies": { "@atproto/common-web": "^0.4.3", "@ipld/dag-cbor": "^7.0.3", "cbor-x": "^1.5.1", "iso-datestring-validator": "^2.2.2", "multiformats": "^9.9.0", "pino": "^8.21.0" } }, "sha512-NC+TULLQiqs6MvNymhQS5WDms3SlbIKGLf4n33tpftRJcalh507rI+snbcUb7TLIkKw7VO17qMqxEXtIdd5auQ=="],
215
-
216
-
"@atproto/common-web": ["@atproto/common-web@0.3.2", "", { "dependencies": { "graphemer": "^1.4.0", "multiformats": "^9.9.0", "uint8arrays": "3.0.0", "zod": "^3.23.8" } }, "sha512-Vx0JtL1/CssJbFAb0UOdvTrkbUautsDfHNOXNTcX2vyPIxH9xOameSqLLunM1hZnOQbJwyjmQCt6TV+bhnanDg=="],
217
-
218
-
"@atproto/crypto": ["@atproto/crypto@0.4.4", "", { "dependencies": { "@noble/curves": "^1.7.0", "@noble/hashes": "^1.6.1", "uint8arrays": "3.0.0" } }, "sha512-Yq9+crJ7WQl7sxStVpHgie5Z51R05etaK9DLWYG/7bR5T4bhdcIgF6IfklLShtZwLYdVVj+K15s0BqW9a8PSDA=="],
256
+
"@atproto/common-web": ["@atproto/common-web@0.4.3", "", { "dependencies": { "graphemer": "^1.4.0", "multiformats": "^9.9.0", "uint8arrays": "3.0.0", "zod": "^3.23.8" } }, "sha512-nRDINmSe4VycJzPo6fP/hEltBcULFxt9Kw7fQk6405FyAWZiTluYHlXOnU7GkQfeUK44OENG1qFTBcmCJ7e8pg=="],
219
257
220
258
"@atproto/did": ["@atproto/did@0.1.5", "", { "dependencies": { "zod": "^3.23.8" } }, "sha512-8+1D08QdGE5TF0bB0vV8HLVrVZJeLNITpRTUVEoABNMRaUS7CoYSVb0+JNQDeJIVmqMjOL8dOjvCUDkp3gEaGQ=="],
221
259
222
-
"@atproto/jwk": ["@atproto/jwk@0.6.0", "", { "dependencies": { "multiformats": "^9.9.0", "zod": "^3.23.8" } }, "sha512-bDoJPvt7TrQVi/rBfBrSSpGykhtIriKxeYCYQTiPRKFfyRhbgpElF0wPXADjIswnbzZdOwbY63az4E/CFVT3Tw=="],
260
+
"@atproto/jwk": ["@atproto/jwk@0.3.0", "", { "dependencies": { "multiformats": "^9.9.0", "zod": "^3.23.8" } }, "sha512-MIAXyNMGu1tCNHjqW/8jqfE/wgWCIoK2cJ0mR6UxwhNPvkbe35TcpRYJdtQu/E6MUd7TziyDBa/GO4dKAiePhQ=="],
223
261
224
-
"@atproto/jwk-jose": ["@atproto/jwk-jose@0.1.11", "", { "dependencies": { "@atproto/jwk": "0.6.0", "jose": "^5.2.0" } }, "sha512-i4Fnr2sTBYmMmHXl7NJh8GrCH+tDQEVWrcDMDnV5DjJfkgT17wIqvojIw9SNbSL4Uf0OtfEv6AgG0A+mgh8b5Q=="],
262
+
"@atproto/jwk-jose": ["@atproto/jwk-jose@0.1.8", "", { "dependencies": { "@atproto/jwk": "0.3.0", "jose": "^5.2.0" } }, "sha512-aoU2Q0GpIl388KhCcv9YvAxNscALUv3xzLq5gjVPdJ+zmqw94nGZNcjiNvpnbfS+VQM9e2DrrTuwmDXnxfrrSA=="],
225
263
226
264
"@atproto/jwk-webcrypto": ["@atproto/jwk-webcrypto@0.1.8", "", { "dependencies": { "@atproto/jwk": "0.3.0", "@atproto/jwk-jose": "0.1.8", "zod": "^3.23.8" } }, "sha512-oOW/G40f6M0NbTOo8uZgiSsFtcvlfNFldyxm+V+fVo5yKe6cvgvPNqckpqMsoBe6JYfImdc/zdVak9fCSSh41A=="],
227
265
266
+
"@atproto/lex-data": ["@atproto/lex-data@0.0.3", "", { "dependencies": { "@atproto/syntax": "0.4.2", "multiformats": "^9.9.0", "tslib": "^2.8.1", "uint8arrays": "3.0.0", "unicode-segmenter": "^0.14.0" } }, "sha512-ivo1IpY/EX+RIpxPgCf4cPhQo5bfu4nrpa1vJCt8hCm9SfoonJkDFGa0n4SMw4JnXZoUcGcrJ46L+D8bH6GI2g=="],
267
+
268
+
"@atproto/lex-json": ["@atproto/lex-json@0.0.3", "", { "dependencies": { "@atproto/lex-data": "0.0.3", "tslib": "^2.8.1" } }, "sha512-ZVcY7XlRfdPYvQQ2WroKUepee0+NCovrSXgXURM3Xv+n5jflJCoczguROeRr8sN0xvT0ZbzMrDNHCUYKNnxcjw=="],
269
+
228
270
"@atproto/lexicon": ["@atproto/lexicon@0.4.14", "", { "dependencies": { "@atproto/common-web": "^0.4.2", "@atproto/syntax": "^0.4.0", "iso-datestring-validator": "^2.2.2", "multiformats": "^9.9.0", "zod": "^3.23.8" } }, "sha512-jiKpmH1QER3Gvc7JVY5brwrfo+etFoe57tKPQX/SmPwjvUsFnJAow5xLIryuBaJgFAhnTZViXKs41t//pahGHQ=="],
229
271
230
272
"@atproto/oauth-client": ["@atproto/oauth-client@0.4.0", "", { "dependencies": { "@atproto-labs/did-resolver": "0.1.13", "@atproto-labs/fetch": "0.2.3", "@atproto-labs/handle-resolver": "0.1.8", "@atproto-labs/identity-resolver": "0.1.18", "@atproto-labs/simple-store": "0.2.0", "@atproto-labs/simple-store-memory": "0.1.3", "@atproto/did": "0.1.5", "@atproto/jwk": "0.3.0", "@atproto/oauth-types": "0.3.0", "@atproto/xrpc": "0.7.0", "multiformats": "^9.9.0", "zod": "^3.23.8" } }, "sha512-uWVnlhennWkgvzqP0l53sFaw6DM6B4zmq0fv1xs05vt56Sjly8YirAj0GVDXlb37/BQRJQ1WOBzJVYDI3bH9uw=="],
···
233
275
234
276
"@atproto/oauth-types": ["@atproto/oauth-types@0.3.0", "", { "dependencies": { "@atproto/jwk": "0.3.0", "zod": "^3.23.8" } }, "sha512-ptfsJARKODXfuOoDQag4a6PpEkDEj4Urz3jOmnQZy2YspPc/TNm1o0HglU0YehELv1vfhh9gEz40BJztPPhiLA=="],
235
277
236
-
"@atproto/syntax": ["@atproto/syntax@0.3.4", "", {}, "sha512-8CNmi5DipOLaVeSMPggMe7FCksVag0aO6XZy9WflbduTKM4dFZVCs4686UeMLfGRXX+X966XgwECHoLYrovMMg=="],
278
+
"@atproto/syntax": ["@atproto/syntax@0.4.0", "", {}, "sha512-b9y5ceHS8YKOfP3mdKmwAx5yVj9294UN7FG2XzP6V5aKUdFazEYRnR9m5n5ZQFKa3GNvz7de9guZCJ/sUTcOAA=="],
237
279
238
-
"@atproto/xrpc": ["@atproto/xrpc@0.6.12", "", { "dependencies": { "@atproto/lexicon": "^0.4.10", "zod": "^3.23.8" } }, "sha512-Ut3iISNLujlmY9Gu8sNU+SPDJDvqlVzWddU8qUr0Yae5oD4SguaUFjjhireMGhQ3M5E0KljQgDbTmnBo1kIZ3w=="],
280
+
"@atproto/xrpc": ["@atproto/xrpc@0.7.0", "", { "dependencies": { "@atproto/lexicon": "^0.4.11", "zod": "^3.23.8" } }, "sha512-SfhP9dGx2qclaScFDb58Jnrmim5nk4geZXCqg6sB0I/KZhZEkr9iIx1hLCp+sxkIfEsmEJjeWO4B0rjUIJW5cw=="],
239
281
240
282
"@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
241
283
···
283
325
284
326
"@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw=="],
285
327
328
+
"@babel/plugin-transform-react-jsx-self": ["@babel/plugin-transform-react-jsx-self@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw=="],
329
+
330
+
"@babel/plugin-transform-react-jsx-source": ["@babel/plugin-transform-react-jsx-source@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw=="],
331
+
286
332
"@babel/plugin-transform-typescript": ["@babel/plugin-transform-typescript@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-create-class-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA=="],
287
333
288
334
"@babel/preset-typescript": ["@babel/preset-typescript@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.27.1", "@babel/plugin-transform-typescript": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g=="],
···
295
341
296
342
"@badrap/valita": ["@badrap/valita@0.4.6", "", {}, "sha512-4kdqcjyxo/8RQ8ayjms47HCWZIF5981oE5nIenbfThKDxWXtEHKipAOWlflpPJzZx9y/JWYQkp18Awr7VuepFg=="],
297
343
298
-
"@cbor-extract/cbor-extract-darwin-arm64": ["@cbor-extract/cbor-extract-darwin-arm64@2.2.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-P7swiOAdF7aSi0H+tHtHtr6zrpF3aAq/W9FXx5HektRvLTM2O89xCyXF3pk7pLc7QpaY7AoaE8UowVf9QBdh3w=="],
299
-
300
-
"@cbor-extract/cbor-extract-darwin-x64": ["@cbor-extract/cbor-extract-darwin-x64@2.2.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-1liF6fgowph0JxBbYnAS7ZlqNYLf000Qnj4KjqPNW4GViKrEql2MgZnAsExhY9LSy8dnvA4C0qHEBgPrll0z0w=="],
301
-
302
-
"@cbor-extract/cbor-extract-linux-arm": ["@cbor-extract/cbor-extract-linux-arm@2.2.0", "", { "os": "linux", "cpu": "arm" }, "sha512-QeBcBXk964zOytiedMPQNZr7sg0TNavZeuUCD6ON4vEOU/25+pLhNN6EDIKJ9VLTKaZ7K7EaAriyYQ1NQ05s/Q=="],
303
-
304
-
"@cbor-extract/cbor-extract-linux-arm64": ["@cbor-extract/cbor-extract-linux-arm64@2.2.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-rQvhNmDuhjTVXSPFLolmQ47/ydGOFXtbR7+wgkSY0bdOxCFept1hvg59uiLPT2fVDuJFuEy16EImo5tE2x3RsQ=="],
305
-
306
-
"@cbor-extract/cbor-extract-linux-x64": ["@cbor-extract/cbor-extract-linux-x64@2.2.0", "", { "os": "linux", "cpu": "x64" }, "sha512-cWLAWtT3kNLHSvP4RKDzSTX9o0wvQEEAj4SKvhWuOVZxiDAeQazr9A+PSiRILK1VYMLeDml89ohxCnUNQNQNCw=="],
307
-
308
-
"@cbor-extract/cbor-extract-win32-x64": ["@cbor-extract/cbor-extract-win32-x64@2.2.0", "", { "os": "win32", "cpu": "x64" }, "sha512-l2M+Z8DO2vbvADOBNLbbh9y5ST1RY5sqkWOg/58GkUPBYou/cuNZ68SGQ644f1CvZ8kcOxyZtw06+dxWHIoN/w=="],
309
-
310
344
"@cookware/api": ["@cookware/api@workspace:apps/api"],
311
345
312
346
"@cookware/database": ["@cookware/database@workspace:libs/database"],
···
317
351
318
352
"@cookware/tsconfig": ["@cookware/tsconfig@workspace:libs/tsconfig"],
319
353
320
-
"@cookware/web": ["@cookware/web@workspace:apps/web"],
321
-
322
-
"@cspotcode/source-map-support": ["@cspotcode/source-map-support@0.8.1", "", { "dependencies": { "@jridgewell/trace-mapping": "0.3.9" } }, "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw=="],
323
-
324
-
"@dnd-kit/accessibility": ["@dnd-kit/accessibility@3.1.1", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "react": ">=16.8.0" } }, "sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw=="],
354
+
"@drizzle-team/brocli": ["@drizzle-team/brocli@0.10.2", "", {}, "sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w=="],
325
355
326
-
"@dnd-kit/core": ["@dnd-kit/core@6.3.1", "", { "dependencies": { "@dnd-kit/accessibility": "^3.1.1", "@dnd-kit/utilities": "^3.2.2", "tslib": "^2.0.0" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ=="],
356
+
"@emnapi/core": ["@emnapi/core@1.7.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" } }, "sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg=="],
327
357
328
-
"@dnd-kit/modifiers": ["@dnd-kit/modifiers@9.0.0", "", { "dependencies": { "@dnd-kit/utilities": "^3.2.2", "tslib": "^2.0.0" }, "peerDependencies": { "@dnd-kit/core": "^6.3.0", "react": ">=16.8.0" } }, "sha512-ybiLc66qRGuZoC20wdSSG6pDXFikui/dCNGthxv4Ndy8ylErY0N3KVxY2bgo7AWwIbxDmXDg3ylAFmnrjcbVvw=="],
358
+
"@emnapi/runtime": ["@emnapi/runtime@1.7.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA=="],
329
359
330
-
"@dnd-kit/sortable": ["@dnd-kit/sortable@10.0.0", "", { "dependencies": { "@dnd-kit/utilities": "^3.2.2", "tslib": "^2.0.0" }, "peerDependencies": { "@dnd-kit/core": "^6.3.0", "react": ">=16.8.0" } }, "sha512-+xqhmIIzvAYMGfBYYnbKuNicfSsk4RksY2XdmJhT+HAC01nix6fHCztU68jooFiMUB01Ky3F0FyOvhG/BZrWkg=="],
331
-
332
-
"@dnd-kit/utilities": ["@dnd-kit/utilities@3.2.2", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "react": ">=16.8.0" } }, "sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg=="],
333
-
334
-
"@drizzle-team/brocli": ["@drizzle-team/brocli@0.10.2", "", {}, "sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w=="],
360
+
"@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="],
335
361
336
362
"@esbuild-kit/core-utils": ["@esbuild-kit/core-utils@3.3.2", "", { "dependencies": { "esbuild": "~0.18.20", "source-map-support": "^0.5.21" } }, "sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ=="],
337
363
···
371
397
372
398
"@esbuild/linux-x64": ["@esbuild/linux-x64@0.19.12", "", { "os": "linux", "cpu": "x64" }, "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg=="],
373
399
374
-
"@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.27.0", "", { "os": "none", "cpu": "arm64" }, "sha512-6m0sfQfxfQfy1qRuecMkJlf1cIzTOgyaeXaiVaaki8/v+WB+U4hc6ik15ZW6TAllRlg/WuQXxWj1jx6C+dfy3w=="],
400
+
"@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.27.1", "", { "os": "none", "cpu": "arm64" }, "sha512-wzC24DxAvk8Em01YmVXyjl96Mr+ecTPyOuADAvjGg+fyBpGmxmcr2E5ttf7Im8D0sXZihpxzO1isus8MdjMCXQ=="],
375
401
376
402
"@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.19.12", "", { "os": "none", "cpu": "x64" }, "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA=="],
377
403
378
-
"@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.27.0", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-fWgqR8uNbCQ/GGv0yhzttj6sU/9Z5/Sv/VGU3F5OuXK6J6SlriONKrQ7tNlwBrJZXRYk5jUhuWvF7GYzGguBZQ=="],
404
+
"@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.27.1", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-5Z+DzLCrq5wmU7RDaMDe2DVXMRm2tTDvX2KU14JJVBN2CT/qov7XVix85QoJqHltpvAOZUAc3ndU56HSMWrv8g=="],
379
405
380
406
"@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.19.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw=="],
381
407
382
-
"@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.27.0", "", { "os": "none", "cpu": "arm64" }, "sha512-nyvsBccxNAsNYz2jVFYwEGuRRomqZ149A39SHWk4hV0jWxKM0hjBPm3AmdxcbHiFLbBSwG6SbpIcUbXjgyECfA=="],
408
+
"@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.27.1", "", { "os": "none", "cpu": "arm64" }, "sha512-ajbHrGM/XiK+sXM0JzEbJAen+0E+JMQZ2l4RR4VFwvV9JEERx+oxtgkpoKv1SevhjavK2z2ReHk32pjzktWbGg=="],
383
409
384
410
"@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.19.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA=="],
385
411
···
407
433
408
434
"@eslint/plugin-kit": ["@eslint/plugin-kit@0.4.1", "", { "dependencies": { "@eslint/core": "^0.17.0", "levn": "^0.4.1" } }, "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA=="],
409
435
410
-
"@externdefs/collider": ["@externdefs/collider@0.1.0", "", { "peerDependencies": { "@badrap/valita": "^0.3.9" } }, "sha512-vmFJEKHhftREiuhhK3WIMKk6bGfm7kM9c5HeVElFCbtqajXqCfwY/GR3f1G0qYWCvbtcoBhIZ2O8ia3A2/pjkw=="],
411
-
412
436
"@floating-ui/core": ["@floating-ui/core@1.7.3", "", { "dependencies": { "@floating-ui/utils": "^0.2.10" } }, "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w=="],
413
437
414
438
"@floating-ui/dom": ["@floating-ui/dom@1.7.4", "", { "dependencies": { "@floating-ui/core": "^1.7.3", "@floating-ui/utils": "^0.2.10" } }, "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA=="],
···
417
441
418
442
"@floating-ui/utils": ["@floating-ui/utils@0.2.10", "", {}, "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ=="],
419
443
420
-
"@hono/node-server": ["@hono/node-server@1.19.6", "", { "peerDependencies": { "hono": "^4" } }, "sha512-Shz/KjlIeAhfiuE93NDKVdZ7HdBVLQAfdbaXEaoAVO3ic9ibRSLGIQGkcBbFyuLr+7/1D5ZCINM8B+6IvXeMtw=="],
421
-
422
-
"@hookform/resolvers": ["@hookform/resolvers@3.10.0", "", { "peerDependencies": { "react-hook-form": "^7.0.0" } }, "sha512-79Dv+3mDF7i+2ajj7SkypSKHhl1cbln1OGavqrsF7p6mbUv11xpqpacPsGDCTRvCSjEEIez2ef1NveSVL3b0Ag=="],
423
-
424
444
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
425
445
426
446
"@humanfs/node": ["@humanfs/node@0.16.7", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.4.0" } }, "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ=="],
···
429
449
430
450
"@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.3", "", {}, "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ=="],
431
451
432
-
"@ipld/dag-cbor": ["@ipld/dag-cbor@7.0.3", "", { "dependencies": { "cborg": "^1.6.0", "multiformats": "^9.5.4" } }, "sha512-1VVh2huHsuohdXC1bGJNE8WR72slZ9XE2T3wbBBq31dm7ZBatmKLLxrB+XAqafxfRFjv08RZmj/W/ZqaM13AuA=="],
452
+
"@img/colour": ["@img/colour@1.0.0", "", {}, "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw=="],
453
+
454
+
"@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w=="],
455
+
456
+
"@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.2.4" }, "os": "darwin", "cpu": "x64" }, "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw=="],
457
+
458
+
"@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.2.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g=="],
459
+
460
+
"@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.2.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg=="],
461
+
462
+
"@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.2.4", "", { "os": "linux", "cpu": "arm" }, "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A=="],
463
+
464
+
"@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw=="],
465
+
466
+
"@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.2.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA=="],
467
+
468
+
"@img/sharp-libvips-linux-riscv64": ["@img/sharp-libvips-linux-riscv64@1.2.4", "", { "os": "linux", "cpu": "none" }, "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA=="],
469
+
470
+
"@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.2.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ=="],
471
+
472
+
"@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw=="],
473
+
474
+
"@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw=="],
475
+
476
+
"@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg=="],
477
+
478
+
"@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.2.4" }, "os": "linux", "cpu": "arm" }, "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw=="],
479
+
480
+
"@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg=="],
481
+
482
+
"@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.2.4" }, "os": "linux", "cpu": "ppc64" }, "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA=="],
483
+
484
+
"@img/sharp-linux-riscv64": ["@img/sharp-linux-riscv64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-riscv64": "1.2.4" }, "os": "linux", "cpu": "none" }, "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw=="],
485
+
486
+
"@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.2.4" }, "os": "linux", "cpu": "s390x" }, "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg=="],
487
+
488
+
"@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ=="],
489
+
490
+
"@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg=="],
491
+
492
+
"@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q=="],
493
+
494
+
"@img/sharp-wasm32": ["@img/sharp-wasm32@0.34.5", "", { "dependencies": { "@emnapi/runtime": "^1.7.0" }, "cpu": "none" }, "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw=="],
495
+
496
+
"@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.34.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g=="],
497
+
498
+
"@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.34.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg=="],
499
+
500
+
"@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.5", "", { "os": "win32", "cpu": "x64" }, "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw=="],
501
+
502
+
"@inquirer/ansi": ["@inquirer/ansi@1.0.2", "", {}, "sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ=="],
503
+
504
+
"@inquirer/checkbox": ["@inquirer/checkbox@4.3.2", "", { "dependencies": { "@inquirer/ansi": "^1.0.2", "@inquirer/core": "^10.3.2", "@inquirer/figures": "^1.0.15", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA=="],
505
+
506
+
"@inquirer/confirm": ["@inquirer/confirm@5.1.21", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ=="],
507
+
508
+
"@inquirer/core": ["@inquirer/core@10.3.2", "", { "dependencies": { "@inquirer/ansi": "^1.0.2", "@inquirer/figures": "^1.0.15", "@inquirer/type": "^3.0.10", "cli-width": "^4.1.0", "mute-stream": "^2.0.0", "signal-exit": "^4.1.0", "wrap-ansi": "^6.2.0", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A=="],
509
+
510
+
"@inquirer/editor": ["@inquirer/editor@4.2.23", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/external-editor": "^1.0.3", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ=="],
511
+
512
+
"@inquirer/expand": ["@inquirer/expand@4.0.23", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew=="],
513
+
514
+
"@inquirer/external-editor": ["@inquirer/external-editor@1.0.3", "", { "dependencies": { "chardet": "^2.1.1", "iconv-lite": "^0.7.0" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA=="],
515
+
516
+
"@inquirer/figures": ["@inquirer/figures@1.0.15", "", {}, "sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g=="],
517
+
518
+
"@inquirer/input": ["@inquirer/input@4.3.1", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g=="],
519
+
520
+
"@inquirer/number": ["@inquirer/number@3.0.23", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg=="],
521
+
522
+
"@inquirer/password": ["@inquirer/password@4.0.23", "", { "dependencies": { "@inquirer/ansi": "^1.0.2", "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA=="],
523
+
524
+
"@inquirer/prompts": ["@inquirer/prompts@7.10.1", "", { "dependencies": { "@inquirer/checkbox": "^4.3.2", "@inquirer/confirm": "^5.1.21", "@inquirer/editor": "^4.2.23", "@inquirer/expand": "^4.0.23", "@inquirer/input": "^4.3.1", "@inquirer/number": "^3.0.23", "@inquirer/password": "^4.0.23", "@inquirer/rawlist": "^4.1.11", "@inquirer/search": "^3.2.2", "@inquirer/select": "^4.4.2" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg=="],
525
+
526
+
"@inquirer/rawlist": ["@inquirer/rawlist@4.1.11", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw=="],
527
+
528
+
"@inquirer/search": ["@inquirer/search@3.2.2", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/figures": "^1.0.15", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA=="],
529
+
530
+
"@inquirer/select": ["@inquirer/select@4.4.2", "", { "dependencies": { "@inquirer/ansi": "^1.0.2", "@inquirer/core": "^10.3.2", "@inquirer/figures": "^1.0.15", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w=="],
531
+
532
+
"@inquirer/type": ["@inquirer/type@3.0.10", "", { "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA=="],
433
533
434
534
"@isaacs/balanced-match": ["@isaacs/balanced-match@4.0.1", "", {}, "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ=="],
435
535
436
536
"@isaacs/brace-expansion": ["@isaacs/brace-expansion@5.0.0", "", { "dependencies": { "@isaacs/balanced-match": "^4.0.1" } }, "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA=="],
537
+
538
+
"@isaacs/fs-minipass": ["@isaacs/fs-minipass@4.0.1", "", { "dependencies": { "minipass": "^7.0.4" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="],
437
539
438
540
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="],
439
541
···
443
545
444
546
"@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
445
547
446
-
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.9", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" } }, "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ=="],
548
+
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
447
549
448
550
"@libsql/client": ["@libsql/client@0.14.0", "", { "dependencies": { "@libsql/core": "^0.14.0", "@libsql/hrana-client": "^0.7.0", "js-base64": "^3.7.5", "libsql": "^0.4.4", "promise-limit": "^2.7.0" } }, "sha512-/9HEKfn6fwXB5aTEEoMeFh4CtG0ZzbncBb1e++OCdVpgKZ/xyMsIVYXm0w7Pv4RUel803vE6LwniB3PqD72R0Q=="],
449
551
···
459
561
460
562
"@libsql/isomorphic-ws": ["@libsql/isomorphic-ws@0.1.5", "", { "dependencies": { "@types/ws": "^8.5.4", "ws": "^8.13.0" } }, "sha512-DtLWIH29onUYR00i0GlQ3UdcTRC6EP4u9w/h9LxpUZJWRMARk6dQwZ6Jkd+QdwVpuAOrdxt18v0K2uIYR3fwFg=="],
461
563
564
+
"@libsql/linux-arm-gnueabihf": ["@libsql/linux-arm-gnueabihf@0.5.22", "", { "os": "linux", "cpu": "arm" }, "sha512-3Uo3SoDPJe/zBnyZKosziRGtszXaEtv57raWrZIahtQDsjxBVjuzYQinCm9LRCJCUT5t2r5Z5nLDPJi2CwZVoA=="],
565
+
566
+
"@libsql/linux-arm-musleabihf": ["@libsql/linux-arm-musleabihf@0.5.22", "", { "os": "linux", "cpu": "arm" }, "sha512-LCsXh07jvSojTNJptT9CowOzwITznD+YFGGW+1XxUr7fS+7/ydUrpDfsMX7UqTqjm7xG17eq86VkWJgHJfvpNg=="],
567
+
462
568
"@libsql/linux-arm64-gnu": ["@libsql/linux-arm64-gnu@0.4.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-WlX2VYB5diM4kFfNaYcyhw5y+UJAI3xcMkEUJZPtRDEIu85SsSFrQ+gvoKfcVh76B//ztSeEX2wl9yrjF7BBCA=="],
463
569
464
570
"@libsql/linux-arm64-musl": ["@libsql/linux-arm64-musl@0.4.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-6kK9xAArVRlTCpWeqnNMCoXW1pe7WITI378n4NpvU5EJ0Ok3aNTIC2nRPRjhro90QcnmLL1jPcrVwO4WD1U0xw=="],
···
469
575
470
576
"@libsql/win32-x64-msvc": ["@libsql/win32-x64-msvc@0.4.7", "", { "os": "win32", "cpu": "x64" }, "sha512-7pJzOWzPm6oJUxml+PCDRzYQ4A1hTMHAciTAHfFK4fkbDZX33nWPVG7Y3vqdKtslcwAzwmrNDc6sXy2nwWnbiw=="],
471
577
578
+
"@mary-ext/event-iterator": ["@mary-ext/event-iterator@1.0.0", "", { "dependencies": { "yocto-queue": "^1.2.1" } }, "sha512-l6gCPsWJ8aRCe/s7/oCmero70kDHgIK5m4uJvYgwEYTqVxoBOIXbKr5tnkLqUHEg6mNduB4IWvms3h70Hp9ADQ=="],
579
+
580
+
"@mary-ext/simple-event-emitter": ["@mary-ext/simple-event-emitter@1.0.0", "", {}, "sha512-meA/zJZKIN1RVBNEYIbjufkUrW7/tRjHH60FjolpG1ixJKo76TB208qefQLNdOVDA7uIG0CGEDuhmMirtHKLAg=="],
581
+
582
+
"@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.0", "", { "dependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" } }, "sha512-Fq6DJW+Bb5jaWE69/qOE0D1TUN9+6uWhCeZpdnSBk14pjLcCWR7Q8n49PTSPHazM37JqrsdpEthXy2xn6jWWiA=="],
583
+
472
584
"@neon-rs/load": ["@neon-rs/load@0.0.4", "", {}, "sha512-kTPhdZyTQxB+2wpiRcFWrDcejc4JI6tkPuS7UZCG4l6Zvc5kU/gGQ/ozvHTh1XR5tS+UlfAfGuPajjzQjCiHCw=="],
473
585
474
-
"@noble/curves": ["@noble/curves@1.9.7", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw=="],
586
+
"@next/env": ["@next/env@16.0.7", "", {}, "sha512-gpaNgUh5nftFKRkRQGnVi5dpcYSKGcZZkQffZ172OrG/XkrnS7UBTQ648YY+8ME92cC4IojpI2LqTC8sTDhAaw=="],
587
+
588
+
"@next/eslint-plugin-next": ["@next/eslint-plugin-next@16.0.7", "", { "dependencies": { "fast-glob": "3.3.1" } }, "sha512-hFrTNZcMEG+k7qxVxZJq3F32Kms130FAhG8lvw2zkKBgAcNOJIxlljNiCjGygvBshvaGBdf88q2CqWtnqezDHA=="],
589
+
590
+
"@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@16.0.7", "", { "os": "darwin", "cpu": "arm64" }, "sha512-LlDtCYOEj/rfSnEn/Idi+j1QKHxY9BJFmxx7108A6D8K0SB+bNgfYQATPk/4LqOl4C0Wo3LACg2ie6s7xqMpJg=="],
591
+
592
+
"@next/swc-darwin-x64": ["@next/swc-darwin-x64@16.0.7", "", { "os": "darwin", "cpu": "x64" }, "sha512-rtZ7BhnVvO1ICf3QzfW9H3aPz7GhBrnSIMZyr4Qy6boXF0b5E3QLs+cvJmg3PsTCG2M1PBoC+DANUi4wCOKXpA=="],
593
+
594
+
"@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@16.0.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-mloD5WcPIeIeeZqAIP5c2kdaTa6StwP4/2EGy1mUw8HiexSHGK/jcM7lFuS3u3i2zn+xH9+wXJs6njO7VrAqww=="],
595
+
596
+
"@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@16.0.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-+ksWNrZrthisXuo9gd1XnjHRowCbMtl/YgMpbRvFeDEqEBd523YHPWpBuDjomod88U8Xliw5DHhekBC3EOOd9g=="],
597
+
598
+
"@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@16.0.7", "", { "os": "linux", "cpu": "x64" }, "sha512-4WtJU5cRDxpEE44Ana2Xro1284hnyVpBb62lIpU5k85D8xXxatT+rXxBgPkc7C1XwkZMWpK5rXLXTh9PFipWsA=="],
599
+
600
+
"@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@16.0.7", "", { "os": "linux", "cpu": "x64" }, "sha512-HYlhqIP6kBPXalW2dbMTSuB4+8fe+j9juyxwfMwCe9kQPPeiyFn7NMjNfoFOfJ2eXkeQsoUGXg+O2SE3m4Qg2w=="],
601
+
602
+
"@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@16.0.7", "", { "os": "win32", "cpu": "arm64" }, "sha512-EviG+43iOoBRZg9deGauXExjRphhuYmIOJ12b9sAPy0eQ6iwcPxfED2asb/s2/yiLYOdm37kPaiZu8uXSYPs0Q=="],
603
+
604
+
"@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@16.0.7", "", { "os": "win32", "cpu": "x64" }, "sha512-gniPjy55zp5Eg0896qSrf3yB1dw4F/3s8VK1ephdsZZ129j2n6e1WqCbE2YgcKhW9hPB9TVZENugquWJD5x0ug=="],
475
605
476
-
"@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="],
606
+
"@noble/secp256k1": ["@noble/secp256k1@3.0.0", "", {}, "sha512-NJBaR352KyIvj3t6sgT/+7xrNyF9Xk9QlLSIqUGVUYlsnDTAUqY8LOmwpcgEx4AMJXRITQ5XEVHD+mMaPfr3mg=="],
477
607
478
608
"@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
479
609
480
610
"@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="],
481
611
482
612
"@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="],
613
+
614
+
"@nolyfill/is-core-module": ["@nolyfill/is-core-module@1.0.39", "", {}, "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA=="],
483
615
484
616
"@opentelemetry/api": ["@opentelemetry/api@1.9.0", "", {}, "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg=="],
485
617
···
549
681
550
682
"@opentelemetry/sql-common": ["@opentelemetry/sql-common@0.40.1", "", { "dependencies": { "@opentelemetry/core": "^1.1.0" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0" } }, "sha512-nSDlnHSqzC3pXn/wZEZVLuAuJ1MYMXPBwtv2qAbCa3847SaHItdE7SzUq/Jtb0KZmh1zfAbNi3AAMjztTT4Ugg=="],
551
683
684
+
"@optique/core": ["@optique/core@0.6.2", "", {}, "sha512-HTxIHJ8xLOSZotiU6Zc5BCJv+SJ8DMYmuiQM+7tjF7RolJn/pdZNe7M78G3+DgXL9lIf82l8aGcilmgVYRQnGQ=="],
685
+
686
+
"@optique/run": ["@optique/run@0.6.2", "", { "dependencies": { "@optique/core": "0.6.2" } }, "sha512-ERksB5bHozwEUVlTPToIc8UjZZBOgLeBhFZYh2lgldUbNDt7LItzgcErsPq5au5i5IBmmyCti4+2A3x+MRI4Xw=="],
687
+
688
+
"@oxc-project/runtime": ["@oxc-project/runtime@0.97.0", "", {}, "sha512-yH0zw7z+jEws4dZ4IUKoix5Lh3yhqIJWF9Dc8PWvhpo7U7O+lJrv7ZZL4BeRO0la8LBQFwcCewtLBnVV7hPe/w=="],
689
+
690
+
"@oxc-project/types": ["@oxc-project/types@0.97.0", "", {}, "sha512-lxmZK4xFrdvU0yZiDwgVQTCvh2gHWBJCBk5ALsrtsBWhs0uDIi+FTOnXRQeQfs304imdvTdaakT/lqwQ8hkOXQ=="],
691
+
552
692
"@pinojs/redact": ["@pinojs/redact@0.4.0", "", {}, "sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg=="],
553
693
554
694
"@prisma/instrumentation": ["@prisma/instrumentation@5.22.0", "", { "dependencies": { "@opentelemetry/api": "^1.8", "@opentelemetry/instrumentation": "^0.49 || ^0.50 || ^0.51 || ^0.52.0 || ^0.53.0", "@opentelemetry/sdk-trace-base": "^1.22" } }, "sha512-LxccF392NN37ISGxIurUljZSh1YWnphO34V5a0+T7FVQG2u9bhAXRTJpgmQ3483woVhkraQZFF7cbRrpbw/F4Q=="],
···
558
698
"@radix-ui/react-arrow": ["@radix-ui/react-arrow@1.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w=="],
559
699
560
700
"@radix-ui/react-avatar": ["@radix-ui/react-avatar@1.1.11", "", { "dependencies": { "@radix-ui/react-context": "1.1.3", "@radix-ui/react-primitive": "2.1.4", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-is-hydrated": "0.1.0", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-0Qk603AHGV28BOBO34p7IgD5m+V5Sg/YovfayABkoDDBM5d3NCx0Mp4gGrjzLGes1jV5eNOE1r3itqOR33VC6Q=="],
561
-
562
-
"@radix-ui/react-collapsible": ["@radix-ui/react-collapsible@1.1.12", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA=="],
563
701
564
702
"@radix-ui/react-collection": ["@radix-ui/react-collection@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw=="],
565
703
···
578
716
"@radix-ui/react-focus-guards": ["@radix-ui/react-focus-guards@1.1.3", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw=="],
579
717
580
718
"@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw=="],
581
-
582
-
"@radix-ui/react-icons": ["@radix-ui/react-icons@1.3.2", "", { "peerDependencies": { "react": "^16.x || ^17.x || ^18.x || ^19.0.0 || ^19.0.0-rc" } }, "sha512-fyQIhGDhzfc9pK2kH6Pl9c4BDJGfMkPqkyIgYDthyNYoNg3wVhoJMMh19WS4Up/1KMPFVpNsT2q3WmXn2N1m6g=="],
583
719
584
720
"@radix-ui/react-id": ["@radix-ui/react-id@1.1.1", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg=="],
585
721
···
623
759
624
760
"@radix-ui/rect": ["@radix-ui/rect@1.1.1", "", {}, "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw=="],
625
761
626
-
"@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.27", "", {}, "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA=="],
762
+
"@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.0.0-beta.50", "", { "os": "android", "cpu": "arm64" }, "sha512-XlEkrOIHLyGT3avOgzfTFSjG+f+dZMw+/qd+Y3HLN86wlndrB/gSimrJCk4gOhr1XtRtEKfszpadI3Md4Z4/Ag=="],
627
763
628
-
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.53.3", "", { "os": "android", "cpu": "arm" }, "sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w=="],
764
+
"@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.0.0-beta.50", "", { "os": "darwin", "cpu": "arm64" }, "sha512-+JRqKJhoFlt5r9q+DecAGPLZ5PxeLva+wCMtAuoFMWPoZzgcYrr599KQ+Ix0jwll4B4HGP43avu9My8KtSOR+w=="],
629
765
630
-
"@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.53.3", "", { "os": "android", "cpu": "arm64" }, "sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w=="],
766
+
"@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.0.0-beta.50", "", { "os": "darwin", "cpu": "x64" }, "sha512-fFXDjXnuX7/gQZQm/1FoivVtRcyAzdjSik7Eo+9iwPQ9EgtA5/nB2+jmbzaKtMGG3q+BnZbdKHCtOacmNrkIDA=="],
631
767
632
-
"@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.53.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA=="],
768
+
"@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.0.0-beta.50", "", { "os": "freebsd", "cpu": "x64" }, "sha512-F1b6vARy49tjmT/hbloplzgJS7GIvwWZqt+tAHEstCh0JIh9sa8FAMVqEmYxDviqKBaAI8iVvUREm/Kh/PD26Q=="],
633
769
634
-
"@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.53.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ=="],
770
+
"@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.50", "", { "os": "linux", "cpu": "arm" }, "sha512-U6cR76N8T8M6lHj7EZrQ3xunLPxSvYYxA8vJsBKZiFZkT8YV4kjgCO3KwMJL0NOjQCPGKyiXO07U+KmJzdPGRw=="],
635
771
636
-
"@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.53.3", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w=="],
772
+
"@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.0.0-beta.50", "", { "os": "linux", "cpu": "arm64" }, "sha512-ONgyjofCrrE3bnh5GZb8EINSFyR/hmwTzZ7oVuyUB170lboza1VMCnb8jgE6MsyyRgHYmN8Lb59i3NKGrxrYjw=="],
637
773
638
-
"@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.53.3", "", { "os": "freebsd", "cpu": "x64" }, "sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q=="],
774
+
"@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.0.0-beta.50", "", { "os": "linux", "cpu": "arm64" }, "sha512-L0zRdH2oDPkmB+wvuTl+dJbXCsx62SkqcEqdM+79LOcB+PxbAxxjzHU14BuZIQdXcAVDzfpMfaHWzZuwhhBTcw=="],
639
775
640
-
"@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.53.3", "", { "os": "linux", "cpu": "arm" }, "sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw=="],
776
+
"@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.0.0-beta.50", "", { "os": "linux", "cpu": "x64" }, "sha512-gyoI8o/TGpQd3OzkJnh1M2kxy1Bisg8qJ5Gci0sXm9yLFzEXIFdtc4EAzepxGvrT2ri99ar5rdsmNG0zP0SbIg=="],
641
777
642
-
"@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.53.3", "", { "os": "linux", "cpu": "arm" }, "sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg=="],
778
+
"@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.0.0-beta.50", "", { "os": "linux", "cpu": "x64" }, "sha512-zti8A7M+xFDpKlghpcCAzyOi+e5nfUl3QhU023ce5NCgUxRG5zGP2GR9LTydQ1rnIPwZUVBWd4o7NjZDaQxaXA=="],
643
779
644
-
"@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.53.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w=="],
780
+
"@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.0.0-beta.50", "", { "os": "none", "cpu": "arm64" }, "sha512-eZUssog7qljrrRU9Mi0eqYEPm3Ch0UwB+qlWPMKSUXHNqhm3TvDZarJQdTevGEfu3EHAXJvBIe0YFYr0TPVaMA=="],
645
781
646
-
"@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.53.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A=="],
782
+
"@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.0.0-beta.50", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.0.7" }, "cpu": "none" }, "sha512-nmCN0nIdeUnmgeDXiQ+2HU6FT162o+rxnF7WMkBm4M5Ds8qTU7Dzv2Wrf22bo4ftnlrb2hKK6FSwAJSAe2FWLg=="],
647
783
648
-
"@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.53.3", "", { "os": "linux", "cpu": "none" }, "sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g=="],
784
+
"@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.0.0-beta.50", "", { "os": "win32", "cpu": "arm64" }, "sha512-7kcNLi7Ua59JTTLvbe1dYb028QEPaJPJQHqkmSZ5q3tJueUeb6yjRtx8mw4uIqgWZcnQHAR3PrLN4XRJxvgIkA=="],
649
785
650
-
"@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.53.3", "", { "os": "linux", "cpu": "ppc64" }, "sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw=="],
786
+
"@rolldown/binding-win32-ia32-msvc": ["@rolldown/binding-win32-ia32-msvc@1.0.0-beta.50", "", { "os": "win32", "cpu": "ia32" }, "sha512-lL70VTNvSCdSZkDPPVMwWn/M2yQiYvSoXw9hTLgdIWdUfC3g72UaruezusR6ceRuwHCY1Ayu2LtKqXkBO5LIwg=="],
651
787
652
-
"@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.53.3", "", { "os": "linux", "cpu": "none" }, "sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g=="],
788
+
"@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.0.0-beta.50", "", { "os": "win32", "cpu": "x64" }, "sha512-4qU4x5DXWB4JPjyTne/wBNPqkbQU8J45bl21geERBKtEittleonioACBL1R0PsBu0Aq21SwMK5a9zdBkWSlQtQ=="],
653
789
654
-
"@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.53.3", "", { "os": "linux", "cpu": "none" }, "sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A=="],
790
+
"@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.47", "", {}, "sha512-8QagwMH3kNCuzD8EWL8R2YPW5e4OrHNSAHRFDdmFqEwEaD/KcNKjVoumo+gP2vW5eKB2UPbM6vTYiGZX0ixLnw=="],
655
791
656
-
"@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.53.3", "", { "os": "linux", "cpu": "s390x" }, "sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg=="],
792
+
"@rtsao/scc": ["@rtsao/scc@1.1.0", "", {}, "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g=="],
657
793
658
-
"@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.53.3", "", { "os": "linux", "cpu": "x64" }, "sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w=="],
794
+
"@sentry/core": ["@sentry/core@8.55.0", "", {}, "sha512-6g7jpbefjHYs821Z+EBJ8r4Z7LT5h80YSWRJaylGS4nW5W5Z2KXzpdnyFarv37O7QjauzVC2E+PABmpkw5/JGA=="],
659
795
660
-
"@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.53.3", "", { "os": "linux", "cpu": "x64" }, "sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q=="],
796
+
"@sentry/node": ["@sentry/node@8.55.0", "", { "dependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/context-async-hooks": "^1.30.1", "@opentelemetry/core": "^1.30.1", "@opentelemetry/instrumentation": "^0.57.1", "@opentelemetry/instrumentation-amqplib": "^0.46.0", "@opentelemetry/instrumentation-connect": "0.43.0", "@opentelemetry/instrumentation-dataloader": "0.16.0", "@opentelemetry/instrumentation-express": "0.47.0", "@opentelemetry/instrumentation-fastify": "0.44.1", "@opentelemetry/instrumentation-fs": "0.19.0", "@opentelemetry/instrumentation-generic-pool": "0.43.0", "@opentelemetry/instrumentation-graphql": "0.47.0", "@opentelemetry/instrumentation-hapi": "0.45.1", "@opentelemetry/instrumentation-http": "0.57.1", "@opentelemetry/instrumentation-ioredis": "0.47.0", "@opentelemetry/instrumentation-kafkajs": "0.7.0", "@opentelemetry/instrumentation-knex": "0.44.0", "@opentelemetry/instrumentation-koa": "0.47.0", "@opentelemetry/instrumentation-lru-memoizer": "0.44.0", "@opentelemetry/instrumentation-mongodb": "0.51.0", "@opentelemetry/instrumentation-mongoose": "0.46.0", "@opentelemetry/instrumentation-mysql": "0.45.0", "@opentelemetry/instrumentation-mysql2": "0.45.0", "@opentelemetry/instrumentation-nestjs-core": "0.44.0", "@opentelemetry/instrumentation-pg": "0.50.0", "@opentelemetry/instrumentation-redis-4": "0.46.0", "@opentelemetry/instrumentation-tedious": "0.18.0", "@opentelemetry/instrumentation-undici": "0.10.0", "@opentelemetry/resources": "^1.30.1", "@opentelemetry/sdk-trace-base": "^1.30.1", "@opentelemetry/semantic-conventions": "^1.28.0", "@prisma/instrumentation": "5.22.0", "@sentry/core": "8.55.0", "@sentry/opentelemetry": "8.55.0", "import-in-the-middle": "^1.11.2" } }, "sha512-h10LJLDTRAzYgay60Oy7moMookqqSZSviCWkkmHZyaDn+4WURnPp5SKhhfrzPRQcXKrweiOwDSHBgn1tweDssg=="],
661
797
662
-
"@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.53.3", "", { "os": "none", "cpu": "arm64" }, "sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw=="],
798
+
"@sentry/opentelemetry": ["@sentry/opentelemetry@8.55.0", "", { "dependencies": { "@sentry/core": "8.55.0" }, "peerDependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/context-async-hooks": "^1.30.1", "@opentelemetry/core": "^1.30.1", "@opentelemetry/instrumentation": "^0.57.1", "@opentelemetry/sdk-trace-base": "^1.30.1", "@opentelemetry/semantic-conventions": "^1.28.0" } }, "sha512-UvatdmSr3Xf+4PLBzJNLZ2JjG1yAPWGe/VrJlJAqyTJ2gKeTzgXJJw8rp4pbvNZO8NaTGEYhhO+scLUj0UtLAQ=="],
663
799
664
-
"@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.53.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw=="],
800
+
"@sindresorhus/merge-streams": ["@sindresorhus/merge-streams@4.0.0", "", {}, "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ=="],
665
801
666
-
"@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.53.3", "", { "os": "win32", "cpu": "ia32" }, "sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA=="],
802
+
"@standard-schema/spec": ["@standard-schema/spec@1.0.0", "", {}, "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA=="],
667
803
668
-
"@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.53.3", "", { "os": "win32", "cpu": "x64" }, "sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg=="],
804
+
"@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="],
669
805
670
-
"@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.53.3", "", { "os": "win32", "cpu": "x64" }, "sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ=="],
806
+
"@tabler/icons": ["@tabler/icons@3.35.0", "", {}, "sha512-yYXe+gJ56xlZFiXwV9zVoe3FWCGuZ/D7/G4ZIlDtGxSx5CGQK110wrnT29gUj52kEZoxqF7oURTk97GQxELOFQ=="],
671
807
672
-
"@sentry/core": ["@sentry/core@8.55.0", "", {}, "sha512-6g7jpbefjHYs821Z+EBJ8r4Z7LT5h80YSWRJaylGS4nW5W5Z2KXzpdnyFarv37O7QjauzVC2E+PABmpkw5/JGA=="],
808
+
"@tabler/icons-react": ["@tabler/icons-react@3.35.0", "", { "dependencies": { "@tabler/icons": "3.35.0" }, "peerDependencies": { "react": ">= 16" } }, "sha512-XG7t2DYf3DyHT5jxFNp5xyLVbL4hMJYJhiSdHADzAjLRYfL7AnjlRfiHDHeXxkb2N103rEIvTsBRazxXtAUz2g=="],
673
809
674
-
"@sentry/node": ["@sentry/node@8.55.0", "", { "dependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/context-async-hooks": "^1.30.1", "@opentelemetry/core": "^1.30.1", "@opentelemetry/instrumentation": "^0.57.1", "@opentelemetry/instrumentation-amqplib": "^0.46.0", "@opentelemetry/instrumentation-connect": "0.43.0", "@opentelemetry/instrumentation-dataloader": "0.16.0", "@opentelemetry/instrumentation-express": "0.47.0", "@opentelemetry/instrumentation-fastify": "0.44.1", "@opentelemetry/instrumentation-fs": "0.19.0", "@opentelemetry/instrumentation-generic-pool": "0.43.0", "@opentelemetry/instrumentation-graphql": "0.47.0", "@opentelemetry/instrumentation-hapi": "0.45.1", "@opentelemetry/instrumentation-http": "0.57.1", "@opentelemetry/instrumentation-ioredis": "0.47.0", "@opentelemetry/instrumentation-kafkajs": "0.7.0", "@opentelemetry/instrumentation-knex": "0.44.0", "@opentelemetry/instrumentation-koa": "0.47.0", "@opentelemetry/instrumentation-lru-memoizer": "0.44.0", "@opentelemetry/instrumentation-mongodb": "0.51.0", "@opentelemetry/instrumentation-mongoose": "0.46.0", "@opentelemetry/instrumentation-mysql": "0.45.0", "@opentelemetry/instrumentation-mysql2": "0.45.0", "@opentelemetry/instrumentation-nestjs-core": "0.44.0", "@opentelemetry/instrumentation-pg": "0.50.0", "@opentelemetry/instrumentation-redis-4": "0.46.0", "@opentelemetry/instrumentation-tedious": "0.18.0", "@opentelemetry/instrumentation-undici": "0.10.0", "@opentelemetry/resources": "^1.30.1", "@opentelemetry/sdk-trace-base": "^1.30.1", "@opentelemetry/semantic-conventions": "^1.28.0", "@prisma/instrumentation": "5.22.0", "@sentry/core": "8.55.0", "@sentry/opentelemetry": "8.55.0", "import-in-the-middle": "^1.11.2" } }, "sha512-h10LJLDTRAzYgay60Oy7moMookqqSZSviCWkkmHZyaDn+4WURnPp5SKhhfrzPRQcXKrweiOwDSHBgn1tweDssg=="],
810
+
"@tailwindcss/node": ["@tailwindcss/node@4.1.17", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "enhanced-resolve": "^5.18.3", "jiti": "^2.6.1", "lightningcss": "1.30.2", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.1.17" } }, "sha512-csIkHIgLb3JisEFQ0vxr2Y57GUNYh447C8xzwj89U/8fdW8LhProdxvnVH6U8M2Y73QKiTIH+LWbK3V2BBZsAg=="],
675
811
676
-
"@sentry/opentelemetry": ["@sentry/opentelemetry@8.55.0", "", { "dependencies": { "@sentry/core": "8.55.0" }, "peerDependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/context-async-hooks": "^1.30.1", "@opentelemetry/core": "^1.30.1", "@opentelemetry/instrumentation": "^0.57.1", "@opentelemetry/sdk-trace-base": "^1.30.1", "@opentelemetry/semantic-conventions": "^1.28.0" } }, "sha512-UvatdmSr3Xf+4PLBzJNLZ2JjG1yAPWGe/VrJlJAqyTJ2gKeTzgXJJw8rp4pbvNZO8NaTGEYhhO+scLUj0UtLAQ=="],
812
+
"@tailwindcss/oxide": ["@tailwindcss/oxide@4.1.17", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.1.17", "@tailwindcss/oxide-darwin-arm64": "4.1.17", "@tailwindcss/oxide-darwin-x64": "4.1.17", "@tailwindcss/oxide-freebsd-x64": "4.1.17", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.17", "@tailwindcss/oxide-linux-arm64-gnu": "4.1.17", "@tailwindcss/oxide-linux-arm64-musl": "4.1.17", "@tailwindcss/oxide-linux-x64-gnu": "4.1.17", "@tailwindcss/oxide-linux-x64-musl": "4.1.17", "@tailwindcss/oxide-wasm32-wasi": "4.1.17", "@tailwindcss/oxide-win32-arm64-msvc": "4.1.17", "@tailwindcss/oxide-win32-x64-msvc": "4.1.17" } }, "sha512-F0F7d01fmkQhsTjXezGBLdrl1KresJTcI3DB8EkScCldyKp3Msz4hub4uyYaVnk88BAS1g5DQjjF6F5qczheLA=="],
677
813
678
-
"@skyware/jetstream": ["@skyware/jetstream@0.2.5", "", { "dependencies": { "@atcute/atproto": "^3.1.0", "@atcute/bluesky": "^3.1.4", "@atcute/lexicons": "^1.1.0", "partysocket": "^1.1.3", "tiny-emitter": "^2.1.0" } }, "sha512-fM/zs03DLwqRyzZZJFWN20e76KrdqIp97Tlm8Cek+vxn96+tu5d/fx79V6H85L0QN6HvGiX2l9A8hWFqHvYlOA=="],
814
+
"@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.1.17", "", { "os": "android", "cpu": "arm64" }, "sha512-BMqpkJHgOZ5z78qqiGE6ZIRExyaHyuxjgrJ6eBO5+hfrfGkuya0lYfw8fRHG77gdTjWkNWEEm+qeG2cDMxArLQ=="],
679
815
680
-
"@standard-schema/spec": ["@standard-schema/spec@1.0.0", "", {}, "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA=="],
816
+
"@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.1.17", "", { "os": "darwin", "cpu": "arm64" }, "sha512-EquyumkQweUBNk1zGEU/wfZo2qkp/nQKRZM8bUYO0J+Lums5+wl2CcG1f9BgAjn/u9pJzdYddHWBiFXJTcxmOg=="],
681
817
682
-
"@swc/core": ["@swc/core@1.15.3", "", { "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.25" }, "optionalDependencies": { "@swc/core-darwin-arm64": "1.15.3", "@swc/core-darwin-x64": "1.15.3", "@swc/core-linux-arm-gnueabihf": "1.15.3", "@swc/core-linux-arm64-gnu": "1.15.3", "@swc/core-linux-arm64-musl": "1.15.3", "@swc/core-linux-x64-gnu": "1.15.3", "@swc/core-linux-x64-musl": "1.15.3", "@swc/core-win32-arm64-msvc": "1.15.3", "@swc/core-win32-ia32-msvc": "1.15.3", "@swc/core-win32-x64-msvc": "1.15.3" }, "peerDependencies": { "@swc/helpers": ">=0.5.17" }, "optionalPeers": ["@swc/helpers"] }, "sha512-Qd8eBPkUFL4eAONgGjycZXj1jFCBW8Fd+xF0PzdTlBCWQIV1xnUT7B93wUANtW3KGjl3TRcOyxwSx/u/jyKw/Q=="],
818
+
"@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.1.17", "", { "os": "darwin", "cpu": "x64" }, "sha512-gdhEPLzke2Pog8s12oADwYu0IAw04Y2tlmgVzIN0+046ytcgx8uZmCzEg4VcQh+AHKiS7xaL8kGo/QTiNEGRog=="],
683
819
684
-
"@swc/core-darwin-arm64": ["@swc/core-darwin-arm64@1.15.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-AXfeQn0CvcQ4cndlIshETx6jrAM45oeUrK8YeEY6oUZU/qzz0Id0CyvlEywxkWVC81Ajpd8TQQ1fW5yx6zQWkQ=="],
820
+
"@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.1.17", "", { "os": "freebsd", "cpu": "x64" }, "sha512-hxGS81KskMxML9DXsaXT1H0DyA+ZBIbyG/sSAjWNe2EDl7TkPOBI42GBV3u38itzGUOmFfCzk1iAjDXds8Oh0g=="],
685
821
686
-
"@swc/core-darwin-x64": ["@swc/core-darwin-x64@1.15.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-p68OeCz1ui+MZYG4wmfJGvcsAcFYb6Sl25H9TxWl+GkBgmNimIiRdnypK9nBGlqMZAcxngNPtnG3kEMNnvoJ2A=="],
822
+
"@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.1.17", "", { "os": "linux", "cpu": "arm" }, "sha512-k7jWk5E3ldAdw0cNglhjSgv501u7yrMf8oeZ0cElhxU6Y2o7f8yqelOp3fhf7evjIS6ujTI3U8pKUXV2I4iXHQ=="],
687
823
688
-
"@swc/core-linux-arm-gnueabihf": ["@swc/core-linux-arm-gnueabihf@1.15.3", "", { "os": "linux", "cpu": "arm" }, "sha512-Nuj5iF4JteFgwrai97mUX+xUOl+rQRHqTvnvHMATL/l9xE6/TJfPBpd3hk/PVpClMXG3Uvk1MxUFOEzM1JrMYg=="],
824
+
"@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.1.17", "", { "os": "linux", "cpu": "arm64" }, "sha512-HVDOm/mxK6+TbARwdW17WrgDYEGzmoYayrCgmLEw7FxTPLcp/glBisuyWkFz/jb7ZfiAXAXUACfyItn+nTgsdQ=="],
689
825
690
-
"@swc/core-linux-arm64-gnu": ["@swc/core-linux-arm64-gnu@1.15.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-2Nc/s8jE6mW2EjXWxO/lyQuLKShcmTrym2LRf5Ayp3ICEMX6HwFqB1EzDhwoMa2DcUgmnZIalesq2lG3krrUNw=="],
826
+
"@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.1.17", "", { "os": "linux", "cpu": "arm64" }, "sha512-HvZLfGr42i5anKtIeQzxdkw/wPqIbpeZqe7vd3V9vI3RQxe3xU1fLjss0TjyhxWcBaipk7NYwSrwTwK1hJARMg=="],
691
827
692
-
"@swc/core-linux-arm64-musl": ["@swc/core-linux-arm64-musl@1.15.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-j4SJniZ/qaZ5g8op+p1G9K1z22s/EYGg1UXIb3+Cg4nsxEpF5uSIGEE4mHUfA70L0BR9wKT2QF/zv3vkhfpX4g=="],
828
+
"@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.1.17", "", { "os": "linux", "cpu": "x64" }, "sha512-M3XZuORCGB7VPOEDH+nzpJ21XPvK5PyjlkSFkFziNHGLc5d6g3di2McAAblmaSUNl8IOmzYwLx9NsE7bplNkwQ=="],
693
829
694
-
"@swc/core-linux-x64-gnu": ["@swc/core-linux-x64-gnu@1.15.3", "", { "os": "linux", "cpu": "x64" }, "sha512-aKttAZnz8YB1VJwPQZtyU8Uk0BfMP63iDMkvjhJzRZVgySmqt/apWSdnoIcZlUoGheBrcqbMC17GGUmur7OT5A=="],
830
+
"@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.1.17", "", { "os": "linux", "cpu": "x64" }, "sha512-k7f+pf9eXLEey4pBlw+8dgfJHY4PZ5qOUFDyNf7SI6lHjQ9Zt7+NcscjpwdCEbYi6FI5c2KDTDWyf2iHcCSyyQ=="],
695
831
696
-
"@swc/core-linux-x64-musl": ["@swc/core-linux-x64-musl@1.15.3", "", { "os": "linux", "cpu": "x64" }, "sha512-oe8FctPu1gnUsdtGJRO2rvOUIkkIIaHqsO9xxN0bTR7dFTlPTGi2Fhk1tnvXeyAvCPxLIcwD8phzKg6wLv9yug=="],
832
+
"@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.1.17", "", { "dependencies": { "@emnapi/core": "^1.6.0", "@emnapi/runtime": "^1.6.0", "@emnapi/wasi-threads": "^1.1.0", "@napi-rs/wasm-runtime": "^1.0.7", "@tybys/wasm-util": "^0.10.1", "tslib": "^2.4.0" }, "cpu": "none" }, "sha512-cEytGqSSoy7zK4JRWiTCx43FsKP/zGr0CsuMawhH67ONlH+T79VteQeJQRO/X7L0juEUA8ZyuYikcRBf0vsxhg=="],
697
833
698
-
"@swc/core-win32-arm64-msvc": ["@swc/core-win32-arm64-msvc@1.15.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-L9AjzP2ZQ/Xh58e0lTRMLvEDrcJpR7GwZqAtIeNLcTK7JVE+QineSyHp0kLkO1rttCHyCy0U74kDTj0dRz6raA=="],
834
+
"@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.1.17", "", { "os": "win32", "cpu": "arm64" }, "sha512-JU5AHr7gKbZlOGvMdb4722/0aYbU+tN6lv1kONx0JK2cGsh7g148zVWLM0IKR3NeKLv+L90chBVYcJ8uJWbC9A=="],
699
835
700
-
"@swc/core-win32-ia32-msvc": ["@swc/core-win32-ia32-msvc@1.15.3", "", { "os": "win32", "cpu": "ia32" }, "sha512-B8UtogMzErUPDWUoKONSVBdsgKYd58rRyv2sHJWKOIMCHfZ22FVXICR4O/VwIYtlnZ7ahERcjayBHDlBZpR0aw=="],
836
+
"@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.1.17", "", { "os": "win32", "cpu": "x64" }, "sha512-SKWM4waLuqx0IH+FMDUw6R66Hu4OuTALFgnleKbqhgGU30DY20NORZMZUKgLRjQXNN2TLzKvh48QXTig4h4bGw=="],
701
837
702
-
"@swc/core-win32-x64-msvc": ["@swc/core-win32-x64-msvc@1.15.3", "", { "os": "win32", "cpu": "x64" }, "sha512-SpZKMR9QBTecHeqpzJdYEfgw30Oo8b/Xl6rjSzBt1g0ZsXyy60KLXrp6IagQyfTYqNYE/caDvwtF2FPn7pomog=="],
838
+
"@tailwindcss/postcss": ["@tailwindcss/postcss@4.1.17", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "@tailwindcss/node": "4.1.17", "@tailwindcss/oxide": "4.1.17", "postcss": "^8.4.41", "tailwindcss": "4.1.17" } }, "sha512-+nKl9N9mN5uJ+M7dBOOCzINw94MPstNR/GtIhz1fpZysxL/4a+No64jCBD6CPN+bIHWFx3KWuu8XJRrj/572Dw=="],
703
839
704
-
"@swc/counter": ["@swc/counter@0.1.3", "", {}, "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ=="],
840
+
"@tailwindcss/vite": ["@tailwindcss/vite@4.1.17", "", { "dependencies": { "@tailwindcss/node": "4.1.17", "@tailwindcss/oxide": "4.1.17", "tailwindcss": "4.1.17" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7" } }, "sha512-4+9w8ZHOiGnpcGI6z1TVVfWaX/koK7fKeSYF3qlYg2xpBtbteP2ddBxiarL+HVgfSJGeK5RIxRQmKm4rTJJAwA=="],
705
841
706
-
"@swc/types": ["@swc/types@0.1.25", "", { "dependencies": { "@swc/counter": "^0.1.3" } }, "sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g=="],
842
+
"@tanstack/history": ["@tanstack/history@1.140.0", "", {}, "sha512-u+/dChlWlT3kYa/RmFP+E7xY5EnzvKEKcvKk+XrgWMpBWExQIh3RQX/eUqhqwCXJPNc4jfm1Coj8umnm/hDgyA=="],
707
843
708
-
"@tanstack/eslint-plugin-query": ["@tanstack/eslint-plugin-query@5.91.2", "", { "dependencies": { "@typescript-eslint/utils": "^8.44.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0" } }, "sha512-UPeWKl/Acu1IuuHJlsN+eITUHqAaa9/04geHHPedY8siVarSaWprY0SVMKrkpKfk5ehRT7+/MZ5QwWuEtkWrFw=="],
844
+
"@tanstack/query-core": ["@tanstack/query-core@5.90.12", "", {}, "sha512-T1/8t5DhV/SisWjDnaiU2drl6ySvsHj1bHBCWNXd+/T+Hh1cf6JodyEYMd5sgwm+b/mETT4EV3H+zCVczCU5hg=="],
709
845
710
-
"@tanstack/history": ["@tanstack/history@1.139.0", "", {}, "sha512-l6wcxwDBeh/7Dhles23U1O8lp9kNJmAb2yNjekR6olZwCRNAVA8TCXlVCrueELyFlYZqvQkh0ofxnzG62A1Kkg=="],
846
+
"@tanstack/query-devtools": ["@tanstack/query-devtools@5.91.1", "", {}, "sha512-l8bxjk6BMsCaVQH6NzQEE/bEgFy1hAs5qbgXl0xhzezlaQbPk6Mgz9BqEg2vTLPOHD8N4k+w/gdgCbEzecGyNg=="],
711
847
712
-
"@tanstack/query-core": ["@tanstack/query-core@5.90.10", "", {}, "sha512-EhZVFu9rl7GfRNuJLJ3Y7wtbTnENsvzp+YpcAV7kCYiXni1v8qZh++lpw4ch4rrwC0u/EZRnBHIehzCGzwXDSQ=="],
848
+
"@tanstack/react-query": ["@tanstack/react-query@5.90.12", "", { "dependencies": { "@tanstack/query-core": "5.90.12" }, "peerDependencies": { "react": "^18 || ^19" } }, "sha512-graRZspg7EoEaw0a8faiUASCyJrqjKPdqJ9EwuDRUF9mEYJ1YPczI9H+/agJ0mOJkPCJDk0lsz5QTrLZ/jQ2rg=="],
713
849
714
-
"@tanstack/query-devtools": ["@tanstack/query-devtools@5.91.0", "", {}, "sha512-uNWkqWTiIKCv8Iaahb7bftmDaZVkBetB+l+OQhQeCEZAedyqxw2eyaRUc8sAQ2LzD843tVdYL6bzOtRWJHJSbQ=="],
850
+
"@tanstack/react-query-devtools": ["@tanstack/react-query-devtools@5.91.1", "", { "dependencies": { "@tanstack/query-devtools": "5.91.1" }, "peerDependencies": { "@tanstack/react-query": "^5.90.10", "react": "^18 || ^19" } }, "sha512-tRnJYwEbH0kAOuToy8Ew7bJw1lX3AjkkgSlf/vzb+NpnqmHPdWM+lA2DSdGQSLi1SU0PDRrrCI1vnZnci96CsQ=="],
715
851
716
-
"@tanstack/react-query": ["@tanstack/react-query@5.90.10", "", { "dependencies": { "@tanstack/query-core": "5.90.10" }, "peerDependencies": { "react": "^18 || ^19" } }, "sha512-BKLss9Y8PQ9IUjPYQiv3/Zmlx92uxffUOX8ZZNoQlCIZBJPT5M+GOMQj7xislvVQ6l1BstBjcX0XB/aHfFYVNw=="],
852
+
"@tanstack/react-router": ["@tanstack/react-router@1.140.0", "", { "dependencies": { "@tanstack/history": "1.140.0", "@tanstack/react-store": "^0.8.0", "@tanstack/router-core": "1.140.0", "isbot": "^5.1.22", "tiny-invariant": "^1.3.3", "tiny-warning": "^1.0.3" }, "peerDependencies": { "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" } }, "sha512-Xe4K1bEtU5h0cAhaKYXDQA2cuITgEs1x6tOognJbcxamlAdzDAkhYBhRg8dKSVAyfGejAUNlUi4utnN0s6R+Yw=="],
717
853
718
-
"@tanstack/react-query-devtools": ["@tanstack/react-query-devtools@5.91.0", "", { "dependencies": { "@tanstack/query-devtools": "5.91.0" }, "peerDependencies": { "@tanstack/react-query": "^5.90.10", "react": "^18 || ^19" } }, "sha512-s7g8Zn8HN05HNe22n/KdNm8wXaRbkcsVkqpkdYIQuCfjVmEUoTQqtJsN2iZtgd9CU36xNS38trWIofxzyW5vbQ=="],
854
+
"@tanstack/react-router-devtools": ["@tanstack/react-router-devtools@1.140.0", "", { "dependencies": { "@tanstack/router-devtools-core": "1.140.0" }, "peerDependencies": { "@tanstack/react-router": "^1.140.0", "@tanstack/router-core": "^1.140.0", "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" }, "optionalPeers": ["@tanstack/router-core"] }, "sha512-11NFwHCG8KphG7Bif570qOxBVwNBTkIOExsf42WNv7cgRhwD6cHjUvfx20/WzkAlvFbEGlV+pp7wiJm3HR56bQ=="],
719
855
720
-
"@tanstack/react-router": ["@tanstack/react-router@1.139.1", "", { "dependencies": { "@tanstack/history": "1.139.0", "@tanstack/react-store": "^0.8.0", "@tanstack/router-core": "1.139.1", "isbot": "^5.1.22", "tiny-invariant": "^1.3.3", "tiny-warning": "^1.0.3" }, "peerDependencies": { "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" } }, "sha512-0AXxrtgc+MUiXVF6+xOZK5x/ww+XzIDF0hVeBY9oZcmV1nxJeuwFYEMswBzm6Fc6CSgtK4OIBg5+O4MdtW2lrQ=="],
856
+
"@tanstack/react-store": ["@tanstack/react-store@0.8.0", "", { "dependencies": { "@tanstack/store": "0.8.0", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-1vG9beLIuB7q69skxK9r5xiLN3ztzIPfSQSs0GfeqWGO2tGIyInZx0x1COhpx97RKaONSoAb8C3dxacWksm1ow=="],
721
857
722
-
"@tanstack/react-router-devtools": ["@tanstack/react-router-devtools@1.139.1", "", { "dependencies": { "@tanstack/router-devtools-core": "1.139.1", "vite": "^7.1.7" }, "peerDependencies": { "@tanstack/react-router": "^1.139.1", "@tanstack/router-core": "^1.139.1", "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" }, "optionalPeers": ["@tanstack/router-core"] }, "sha512-4ypEaj1Jf+dO3Iq14TjEMvs5VmwilZFMR8K32xTqtHdsfhH2VdDL3dxUY8UloWE4cD06KnLb79sD4Sf0f9HFdQ=="],
858
+
"@tanstack/router-core": ["@tanstack/router-core@1.140.0", "", { "dependencies": { "@tanstack/history": "1.140.0", "@tanstack/store": "^0.8.0", "cookie-es": "^2.0.0", "seroval": "^1.4.0", "seroval-plugins": "^1.4.0", "tiny-invariant": "^1.3.3", "tiny-warning": "^1.0.3" } }, "sha512-/Te/mlAzi5FEpZ9NF9RhVw/n+cWYLiCHpvevNKo7JPA8ZYWF58wkalPtNWSocftX4P+OIBNerFAW9UbLgSbvSw=="],
723
859
724
-
"@tanstack/react-store": ["@tanstack/react-store@0.8.0", "", { "dependencies": { "@tanstack/store": "0.8.0", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-1vG9beLIuB7q69skxK9r5xiLN3ztzIPfSQSs0GfeqWGO2tGIyInZx0x1COhpx97RKaONSoAb8C3dxacWksm1ow=="],
860
+
"@tanstack/router-devtools-core": ["@tanstack/router-devtools-core@1.140.0", "", { "dependencies": { "clsx": "^2.1.1", "goober": "^2.1.16", "tiny-invariant": "^1.3.3" }, "peerDependencies": { "@tanstack/router-core": "^1.140.0", "csstype": "^3.0.10", "solid-js": ">=1.9.5" }, "optionalPeers": ["csstype"] }, "sha512-jrfJZabe2ndKgoQWd7xLdfLFG/ew6hfPMjCmx2Ep+KBkSqfR19Pww8UtJ8Y0KcfTEFKL3YzVEsRS4EZDX3A1Qw=="],
725
861
726
-
"@tanstack/router-core": ["@tanstack/router-core@1.139.1", "", { "dependencies": { "@tanstack/history": "1.139.0", "@tanstack/store": "^0.8.0", "cookie-es": "^2.0.0", "seroval": "^1.4.0", "seroval-plugins": "^1.4.0", "tiny-invariant": "^1.3.3", "tiny-warning": "^1.0.3" } }, "sha512-nPcP7mKmX38wOlqRZLITxXSo6y71LkK31Uh4xtLnO8SVEebEsNehO9p+wDYlUKnmQqWHqC+GQX5gLULVlTYmqg=="],
862
+
"@tanstack/router-generator": ["@tanstack/router-generator@1.140.0", "", { "dependencies": { "@tanstack/router-core": "1.140.0", "@tanstack/router-utils": "1.140.0", "@tanstack/virtual-file-routes": "1.140.0", "prettier": "^3.5.0", "recast": "^0.23.11", "source-map": "^0.7.4", "tsx": "^4.19.2", "zod": "^3.24.2" } }, "sha512-YYq/DSn7EkBboCySf87RDH3mNq3AfN18v4qHmre73KOdxUJchTZ4LC1+8vbO/1K/Uus2ZFXUDy7QX5KziNx08g=="],
727
863
728
-
"@tanstack/router-devtools": ["@tanstack/router-devtools@1.139.1", "", { "dependencies": { "@tanstack/react-router-devtools": "1.139.1", "clsx": "^2.1.1", "goober": "^2.1.16", "vite": "^7.1.7" }, "peerDependencies": { "@tanstack/react-router": "^1.139.1", "csstype": "^3.0.10", "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" }, "optionalPeers": ["csstype"] }, "sha512-MjnWwiFm0H4Wtz2XQv0qAOl9OQye/bhBRxers4C8x/4oOOVbcSzQasY2a3v6Nrt6AZW2x16rgPq26YGlDgP1Jg=="],
864
+
"@tanstack/router-plugin": ["@tanstack/router-plugin@1.140.0", "", { "dependencies": { "@babel/core": "^7.27.7", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1", "@babel/template": "^7.27.2", "@babel/traverse": "^7.27.7", "@babel/types": "^7.27.7", "@tanstack/router-core": "1.140.0", "@tanstack/router-generator": "1.140.0", "@tanstack/router-utils": "1.140.0", "@tanstack/virtual-file-routes": "1.140.0", "babel-dead-code-elimination": "^1.0.10", "chokidar": "^3.6.0", "unplugin": "^2.1.2", "zod": "^3.24.2" }, "peerDependencies": { "@rsbuild/core": ">=1.0.2", "@tanstack/react-router": "^1.140.0", "vite": ">=5.0.0 || >=6.0.0 || >=7.0.0", "vite-plugin-solid": "^2.11.10", "webpack": ">=5.92.0" }, "optionalPeers": ["@rsbuild/core", "@tanstack/react-router", "vite", "vite-plugin-solid", "webpack"] }, "sha512-hUOOYTPLFS3LvGoPoQNk3BY3ZvPlVIgxnJT3JMJMdstLMT2RUYha3ddsaamZd4ONUSWmt+7N5OXmiG0v4XmzMw=="],
729
865
730
-
"@tanstack/router-devtools-core": ["@tanstack/router-devtools-core@1.139.1", "", { "dependencies": { "clsx": "^2.1.1", "goober": "^2.1.16", "tiny-invariant": "^1.3.3", "vite": "^7.1.7" }, "peerDependencies": { "@tanstack/router-core": "^1.139.1", "csstype": "^3.0.10", "solid-js": ">=1.9.5" }, "optionalPeers": ["csstype"] }, "sha512-bnsws+otH0cCcDNv1wzZXgA+NhEo4WvmGJUoDFWK7Md+/PUi66KltX9aSkJv6ZpqTj1slV1IOKx8kqLgwLIYPA=="],
866
+
"@tanstack/router-utils": ["@tanstack/router-utils@1.140.0", "", { "dependencies": { "@babel/core": "^7.27.4", "@babel/generator": "^7.27.5", "@babel/parser": "^7.27.5", "@babel/preset-typescript": "^7.27.1", "ansis": "^4.1.0", "diff": "^8.0.2", "pathe": "^2.0.3", "tinyglobby": "^0.2.15" } }, "sha512-gobraqMjkR5OO4nNbnwursGo08Idla6Yu30RspIA9IR1hv4WPJlxIyRWJcKjiQeXGyu5TuekLPUOHM46oood7w=="],
731
867
732
-
"@tanstack/router-generator": ["@tanstack/router-generator@1.139.1", "", { "dependencies": { "@tanstack/router-core": "1.139.1", "@tanstack/router-utils": "1.139.0", "@tanstack/virtual-file-routes": "1.139.0", "prettier": "^3.5.0", "recast": "^0.23.11", "source-map": "^0.7.4", "tsx": "^4.19.2", "zod": "^3.24.2" } }, "sha512-HJaJlxilmn/Y2zSLOJ9tCreNaBUJaR2aB4tAJuINcjzd1rvJeB2eKJ5C4kRWD4pcJEznVUvy1sNfeJ3QSBj5Rg=="],
868
+
"@tanstack/store": ["@tanstack/store@0.8.0", "", {}, "sha512-Om+BO0YfMZe//X2z0uLF2j+75nQga6TpTJgLJQBiq85aOyZNIhkCgleNcud2KQg4k4v9Y9l+Uhru3qWMPGTOzQ=="],
733
869
734
-
"@tanstack/router-plugin": ["@tanstack/router-plugin@1.139.1", "", { "dependencies": { "@babel/core": "^7.27.7", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1", "@babel/template": "^7.27.2", "@babel/traverse": "^7.27.7", "@babel/types": "^7.27.7", "@tanstack/router-core": "1.139.1", "@tanstack/router-generator": "1.139.1", "@tanstack/router-utils": "1.139.0", "@tanstack/virtual-file-routes": "1.139.0", "babel-dead-code-elimination": "^1.0.10", "chokidar": "^3.6.0", "unplugin": "^2.1.2", "zod": "^3.24.2" }, "peerDependencies": { "@rsbuild/core": ">=1.0.2", "@tanstack/react-router": "^1.139.1", "vite": ">=5.0.0 || >=6.0.0 || >=7.0.0", "vite-plugin-solid": "^2.11.10", "webpack": ">=5.92.0" }, "optionalPeers": ["@rsbuild/core", "@tanstack/react-router", "vite", "vite-plugin-solid", "webpack"] }, "sha512-2Sc7PqZkBLS0RC5lRnG7QldzIh6iu5PEBB/pnVWwQ5UpRietsBUGvvwPKfFtgxGs/EMLrrQNe5vMiyyfjVBbrQ=="],
870
+
"@tanstack/virtual-file-routes": ["@tanstack/virtual-file-routes@1.140.0", "", {}, "sha512-LVmd19QkxV3x40oHkuTii9ey3l5XDV+X8locO2p5zfVDUC+N58H2gA7cDUtVc9qtImncnz3WxQkO/6kM3PMx2w=="],
735
871
736
-
"@tanstack/router-utils": ["@tanstack/router-utils@1.139.0", "", { "dependencies": { "@babel/core": "^7.27.4", "@babel/generator": "^7.27.5", "@babel/parser": "^7.27.5", "@babel/preset-typescript": "^7.27.1", "ansis": "^4.1.0", "diff": "^8.0.2", "pathe": "^2.0.3", "tinyglobby": "^0.2.15" } }, "sha512-jT7D6NimWqoFSkid4vCno8gvTyfL1+NHpgm3es0B2UNhKKRV3LngOGilm1m6v8Qvk/gy6Fh/tvB+s+hBl6GhOg=="],
872
+
"@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="],
737
873
738
-
"@tanstack/store": ["@tanstack/store@0.8.0", "", {}, "sha512-Om+BO0YfMZe//X2z0uLF2j+75nQga6TpTJgLJQBiq85aOyZNIhkCgleNcud2KQg4k4v9Y9l+Uhru3qWMPGTOzQ=="],
874
+
"@typelex/emitter": ["@typelex/emitter@0.4.0", "", { "dependencies": { "@typespec/compiler": "^1.4.0" } }, "sha512-BaKny+8TA0yX5jZibkAodHHKLJ6l6xVe5ut7KeoUyTD63lSSuB9OXe8tWXrs2DbeR/hialCimHFZQ3xANleMow=="],
739
875
740
-
"@tanstack/virtual-file-routes": ["@tanstack/virtual-file-routes@1.139.0", "", {}, "sha512-9PImF1d1tovTUIpjFVa0W7Fwj/MHif7BaaczgJJfbv3sDt1Gh+oW9W9uCw9M3ndEJynnp5ZD/TTs0RGubH5ssg=="],
876
+
"@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="],
741
877
742
-
"@tsconfig/node10": ["@tsconfig/node10@1.0.12", "", {}, "sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ=="],
878
+
"@types/babel__generator": ["@types/babel__generator@7.27.0", "", { "dependencies": { "@babel/types": "^7.0.0" } }, "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg=="],
743
879
744
-
"@tsconfig/node12": ["@tsconfig/node12@1.0.11", "", {}, "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag=="],
880
+
"@types/babel__template": ["@types/babel__template@7.4.4", "", { "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" } }, "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A=="],
745
881
746
-
"@tsconfig/node14": ["@tsconfig/node14@1.0.3", "", {}, "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow=="],
882
+
"@types/babel__traverse": ["@types/babel__traverse@7.28.0", "", { "dependencies": { "@babel/types": "^7.28.2" } }, "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q=="],
747
883
748
-
"@tsconfig/node16": ["@tsconfig/node16@1.0.4", "", {}, "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA=="],
884
+
"@types/bun": ["@types/bun@1.3.3", "", { "dependencies": { "bun-types": "1.3.3" } }, "sha512-ogrKbJ2X5N0kWLLFKeytG0eHDleBYtngtlbu9cyBKFtNL3cnpDZkNdQj8flVf6WTZUX5ulI9AY1oa7ljhSrp+g=="],
749
885
750
886
"@types/connect": ["@types/connect@3.4.36", "", { "dependencies": { "@types/node": "*" } }, "sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w=="],
751
887
···
753
889
754
890
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
755
891
892
+
"@types/json5": ["@types/json5@0.0.29", "", {}, "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="],
893
+
756
894
"@types/mysql": ["@types/mysql@2.15.26", "", { "dependencies": { "@types/node": "*" } }, "sha512-DSLCOXhkvfS5WNNPbfn2KdICAmk8lLc+/PNvnPnF7gOdMZCxopXduqv0OQ13y/yA/zXTSikZZqVgybUxOEg6YQ=="],
757
895
758
896
"@types/node": ["@types/node@22.19.1", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ=="],
759
897
760
-
"@types/pg": ["@types/pg@8.6.1", "", { "dependencies": { "@types/node": "*", "pg-protocol": "*", "pg-types": "^2.2.0" } }, "sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w=="],
898
+
"@types/pg": ["@types/pg@8.15.6", "", { "dependencies": { "@types/node": "*", "pg-protocol": "*", "pg-types": "^2.2.0" } }, "sha512-NoaMtzhxOrubeL/7UZuNTrejB4MPAJ0RpxZqXQf2qXuVlTPuG6Y8p4u9dKRaue4yjmC7ZhzVO2/Yyyn25znrPQ=="],
761
899
762
900
"@types/pg-pool": ["@types/pg-pool@2.0.6", "", { "dependencies": { "@types/pg": "*" } }, "sha512-TaAUE5rq2VQYxab5Ts7WZhKNmuN78Q6PiFonTDdpbx8a1H0M1vhy3rhiMjl+e2iHmogyMw7jZF4FrE6eJUy5HQ=="],
763
901
764
-
"@types/react": ["@types/react@19.2.6", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-p/jUvulfgU7oKtj6Xpk8cA2Y1xKTtICGpJYeJXz2YVO2UcvjQgeRMLDGfDeqeRW2Ta+0QNFwcc8X3GH8SxZz6w=="],
902
+
"@types/react": ["@types/react@19.2.7", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg=="],
765
903
766
904
"@types/react-dom": ["@types/react-dom@19.2.3", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="],
767
905
···
771
909
772
910
"@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="],
773
911
774
-
"@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.47.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.47.0", "@typescript-eslint/type-utils": "8.47.0", "@typescript-eslint/utils": "8.47.0", "@typescript-eslint/visitor-keys": "8.47.0", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.47.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-fe0rz9WJQ5t2iaLfdbDc9T80GJy0AeO453q8C3YCilnGozvOyCG5t+EZtg7j7D88+c3FipfP/x+wzGnh1xp8ZA=="],
912
+
"@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.48.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.48.0", "@typescript-eslint/type-utils": "8.48.0", "@typescript-eslint/utils": "8.48.0", "@typescript-eslint/visitor-keys": "8.48.0", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.48.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-XxXP5tL1txl13YFtrECECQYeZjBZad4fyd3cFV4a19LkAY/bIp9fev3US4S5fDVV2JaYFiKAZ/GRTOLer+mbyQ=="],
913
+
914
+
"@typescript-eslint/parser": ["@typescript-eslint/parser@8.48.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.48.0", "@typescript-eslint/types": "8.48.0", "@typescript-eslint/typescript-estree": "8.48.0", "@typescript-eslint/visitor-keys": "8.48.0", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-jCzKdm/QK0Kg4V4IK/oMlRZlY+QOcdjv89U2NgKHZk1CYTj82/RVSx1mV/0gqCVMJ/DA+Zf/S4NBWNF8GQ+eqQ=="],
915
+
916
+
"@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.48.0", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.48.0", "@typescript-eslint/types": "^8.48.0", "debug": "^4.3.4" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-Ne4CTZyRh1BecBf84siv42wv5vQvVmgtk8AuiEffKTUo3DrBaGYZueJSxxBZ8fjk/N3DrgChH4TOdIOwOwiqqw=="],
917
+
918
+
"@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.48.0", "", { "dependencies": { "@typescript-eslint/types": "8.48.0", "@typescript-eslint/visitor-keys": "8.48.0" } }, "sha512-uGSSsbrtJrLduti0Q1Q9+BF1/iFKaxGoQwjWOIVNJv0o6omrdyR8ct37m4xIl5Zzpkp69Kkmvom7QFTtue89YQ=="],
919
+
920
+
"@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.48.0", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-WNebjBdFdyu10sR1M4OXTt2OkMd5KWIL+LLfeH9KhgP+jzfDV/LI3eXzwJ1s9+Yc0Kzo2fQCdY/OpdusCMmh6w=="],
921
+
922
+
"@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.48.0", "", { "dependencies": { "@typescript-eslint/types": "8.48.0", "@typescript-eslint/typescript-estree": "8.48.0", "@typescript-eslint/utils": "8.48.0", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-zbeVaVqeXhhab6QNEKfK96Xyc7UQuoFWERhEnj3mLVnUWrQnv15cJNseUni7f3g557gm0e46LZ6IJ4NJVOgOpw=="],
923
+
924
+
"@typescript-eslint/types": ["@typescript-eslint/types@8.48.0", "", {}, "sha512-cQMcGQQH7kwKoVswD1xdOytxQR60MWKM1di26xSUtxehaDs/32Zpqsu5WJlXTtTTqyAVK8R7hvsUnIXRS+bjvA=="],
925
+
926
+
"@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.48.0", "", { "dependencies": { "@typescript-eslint/project-service": "8.48.0", "@typescript-eslint/tsconfig-utils": "8.48.0", "@typescript-eslint/types": "8.48.0", "@typescript-eslint/visitor-keys": "8.48.0", "debug": "^4.3.4", "minimatch": "^9.0.4", "semver": "^7.6.0", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-ljHab1CSO4rGrQIAyizUS6UGHHCiAYhbfcIZ1zVJr5nMryxlXMVWS3duFPSKvSUbFPwkXMFk1k0EMIjub4sRRQ=="],
927
+
928
+
"@typescript-eslint/utils": ["@typescript-eslint/utils@8.48.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.48.0", "@typescript-eslint/types": "8.48.0", "@typescript-eslint/typescript-estree": "8.48.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-yTJO1XuGxCsSfIVt1+1UrLHtue8xz16V8apzPYI06W0HbEbEWHxHXgZaAgavIkoh+GeV6hKKd5jm0sS6OYxWXQ=="],
929
+
930
+
"@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.48.0", "", { "dependencies": { "@typescript-eslint/types": "8.48.0", "eslint-visitor-keys": "^4.2.1" } }, "sha512-T0XJMaRPOH3+LBbAfzR2jalckP1MSG/L9eUtY0DEzUyVaXJ/t6zN0nR7co5kz0Jko/nkSYCBRkz1djvjajVTTg=="],
931
+
932
+
"@typespec/compiler": ["@typespec/compiler@1.6.0", "", { "dependencies": { "@babel/code-frame": "~7.27.1", "@inquirer/prompts": "^7.4.0", "ajv": "~8.17.1", "change-case": "~5.4.4", "env-paths": "^3.0.0", "globby": "~15.0.0", "is-unicode-supported": "^2.1.0", "mustache": "~4.2.0", "picocolors": "~1.1.1", "prettier": "~3.6.2", "semver": "^7.7.1", "tar": "^7.5.2", "temporal-polyfill": "^0.3.0", "vscode-languageserver": "~9.0.1", "vscode-languageserver-textdocument": "~1.0.12", "yaml": "~2.8.0", "yargs": "~18.0.0" }, "bin": { "tsp": "cmd/tsp.js", "tsp-server": "cmd/tsp-server.js" } }, "sha512-yxyV+ch8tnqiuU2gClv/mQEESoFwpkjo6177UkYfV0nVA9PzTg4zVVc7+WIMZk04wiLRRT3H1uc11FB1cwLY3g=="],
933
+
934
+
"@unrs/resolver-binding-android-arm-eabi": ["@unrs/resolver-binding-android-arm-eabi@1.11.1", "", { "os": "android", "cpu": "arm" }, "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw=="],
935
+
936
+
"@unrs/resolver-binding-android-arm64": ["@unrs/resolver-binding-android-arm64@1.11.1", "", { "os": "android", "cpu": "arm64" }, "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g=="],
937
+
938
+
"@unrs/resolver-binding-darwin-arm64": ["@unrs/resolver-binding-darwin-arm64@1.11.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g=="],
939
+
940
+
"@unrs/resolver-binding-darwin-x64": ["@unrs/resolver-binding-darwin-x64@1.11.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ=="],
941
+
942
+
"@unrs/resolver-binding-freebsd-x64": ["@unrs/resolver-binding-freebsd-x64@1.11.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw=="],
943
+
944
+
"@unrs/resolver-binding-linux-arm-gnueabihf": ["@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1", "", { "os": "linux", "cpu": "arm" }, "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw=="],
945
+
946
+
"@unrs/resolver-binding-linux-arm-musleabihf": ["@unrs/resolver-binding-linux-arm-musleabihf@1.11.1", "", { "os": "linux", "cpu": "arm" }, "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw=="],
947
+
948
+
"@unrs/resolver-binding-linux-arm64-gnu": ["@unrs/resolver-binding-linux-arm64-gnu@1.11.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ=="],
949
+
950
+
"@unrs/resolver-binding-linux-arm64-musl": ["@unrs/resolver-binding-linux-arm64-musl@1.11.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w=="],
775
951
776
-
"@typescript-eslint/parser": ["@typescript-eslint/parser@8.47.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.47.0", "@typescript-eslint/types": "8.47.0", "@typescript-eslint/typescript-estree": "8.47.0", "@typescript-eslint/visitor-keys": "8.47.0", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-lJi3PfxVmo0AkEY93ecfN+r8SofEqZNGByvHAI3GBLrvt1Cw6H5k1IM02nSzu0RfUafr2EvFSw0wAsZgubNplQ=="],
952
+
"@unrs/resolver-binding-linux-ppc64-gnu": ["@unrs/resolver-binding-linux-ppc64-gnu@1.11.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA=="],
777
953
778
-
"@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.47.0", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.47.0", "@typescript-eslint/types": "^8.47.0", "debug": "^4.3.4" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-2X4BX8hUeB5JcA1TQJ7GjcgulXQ+5UkNb0DL8gHsHUHdFoiCTJoYLTpib3LtSDPZsRET5ygN4qqIWrHyYIKERA=="],
954
+
"@unrs/resolver-binding-linux-riscv64-gnu": ["@unrs/resolver-binding-linux-riscv64-gnu@1.11.1", "", { "os": "linux", "cpu": "none" }, "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ=="],
779
955
780
-
"@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.47.0", "", { "dependencies": { "@typescript-eslint/types": "8.47.0", "@typescript-eslint/visitor-keys": "8.47.0" } }, "sha512-a0TTJk4HXMkfpFkL9/WaGTNuv7JWfFTQFJd6zS9dVAjKsojmv9HT55xzbEpnZoY+VUb+YXLMp+ihMLz/UlZfDg=="],
956
+
"@unrs/resolver-binding-linux-riscv64-musl": ["@unrs/resolver-binding-linux-riscv64-musl@1.11.1", "", { "os": "linux", "cpu": "none" }, "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew=="],
781
957
782
-
"@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.47.0", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-ybUAvjy4ZCL11uryalkKxuT3w3sXJAuWhOoGS3T/Wu+iUu1tGJmk5ytSY8gbdACNARmcYEB0COksD2j6hfGK2g=="],
958
+
"@unrs/resolver-binding-linux-s390x-gnu": ["@unrs/resolver-binding-linux-s390x-gnu@1.11.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg=="],
783
959
784
-
"@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.47.0", "", { "dependencies": { "@typescript-eslint/types": "8.47.0", "@typescript-eslint/typescript-estree": "8.47.0", "@typescript-eslint/utils": "8.47.0", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-QC9RiCmZ2HmIdCEvhd1aJELBlD93ErziOXXlHEZyuBo3tBiAZieya0HLIxp+DoDWlsQqDawyKuNEhORyku+P8A=="],
960
+
"@unrs/resolver-binding-linux-x64-gnu": ["@unrs/resolver-binding-linux-x64-gnu@1.11.1", "", { "os": "linux", "cpu": "x64" }, "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w=="],
785
961
786
-
"@typescript-eslint/types": ["@typescript-eslint/types@8.47.0", "", {}, "sha512-nHAE6bMKsizhA2uuYZbEbmp5z2UpffNrPEqiKIeN7VsV6UY/roxanWfoRrf6x/k9+Obf+GQdkm0nPU+vnMXo9A=="],
962
+
"@unrs/resolver-binding-linux-x64-musl": ["@unrs/resolver-binding-linux-x64-musl@1.11.1", "", { "os": "linux", "cpu": "x64" }, "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA=="],
787
963
788
-
"@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.47.0", "", { "dependencies": { "@typescript-eslint/project-service": "8.47.0", "@typescript-eslint/tsconfig-utils": "8.47.0", "@typescript-eslint/types": "8.47.0", "@typescript-eslint/visitor-keys": "8.47.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-k6ti9UepJf5NpzCjH31hQNLHQWupTRPhZ+KFF8WtTuTpy7uHPfeg2NM7cP27aCGajoEplxJDFVCEm9TGPYyiVg=="],
964
+
"@unrs/resolver-binding-wasm32-wasi": ["@unrs/resolver-binding-wasm32-wasi@1.11.1", "", { "dependencies": { "@napi-rs/wasm-runtime": "^0.2.11" }, "cpu": "none" }, "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ=="],
789
965
790
-
"@typescript-eslint/utils": ["@typescript-eslint/utils@8.47.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.47.0", "@typescript-eslint/types": "8.47.0", "@typescript-eslint/typescript-estree": "8.47.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-g7XrNf25iL4TJOiPqatNuaChyqt49a/onq5YsJ9+hXeugK+41LVg7AxikMfM02PC6jbNtZLCJj6AUcQXJS/jGQ=="],
966
+
"@unrs/resolver-binding-win32-arm64-msvc": ["@unrs/resolver-binding-win32-arm64-msvc@1.11.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw=="],
791
967
792
-
"@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.47.0", "", { "dependencies": { "@typescript-eslint/types": "8.47.0", "eslint-visitor-keys": "^4.2.1" } }, "sha512-SIV3/6eftCy1bNzCQoPmbWsRLujS8t5iDIZ4spZOBHqrM+yfX2ogg8Tt3PDTAVKw3sSCiUgg30uOAvK2r9zGjQ=="],
968
+
"@unrs/resolver-binding-win32-ia32-msvc": ["@unrs/resolver-binding-win32-ia32-msvc@1.11.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ=="],
793
969
794
-
"@vitejs/plugin-react-swc": ["@vitejs/plugin-react-swc@3.11.0", "", { "dependencies": { "@rolldown/pluginutils": "1.0.0-beta.27", "@swc/core": "^1.12.11" }, "peerDependencies": { "vite": "^4 || ^5 || ^6 || ^7" } }, "sha512-YTJCGFdNMHCMfjODYtxRNVAYmTWQ1Lb8PulP/2/f/oEEtglw8oKxKIZmmRkyXrVrHfsKOaVkAc3NT9/dMutO5w=="],
970
+
"@unrs/resolver-binding-win32-x64-msvc": ["@unrs/resolver-binding-win32-x64-msvc@1.11.1", "", { "os": "win32", "cpu": "x64" }, "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g=="],
795
971
796
-
"abort-controller": ["abort-controller@3.0.0", "", { "dependencies": { "event-target-shim": "^5.0.0" } }, "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg=="],
972
+
"@vitejs/plugin-react": ["@vitejs/plugin-react@5.1.1", "", { "dependencies": { "@babel/core": "^7.28.5", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-beta.47", "@types/babel__core": "^7.20.5", "react-refresh": "^0.18.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-WQfkSw0QbQ5aJ2CHYw23ZGkqnRwqKHD/KYsMeTkZzPT4Jcf0DcBxBtwMJxnu6E7oxw5+JC6ZAiePgh28uJ1HBA=="],
797
973
798
974
"acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
799
975
···
801
977
802
978
"acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="],
803
979
804
-
"acorn-walk": ["acorn-walk@8.3.4", "", { "dependencies": { "acorn": "^8.11.0" } }, "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g=="],
980
+
"ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="],
805
981
806
-
"ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="],
982
+
"ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="],
807
983
808
984
"ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
809
985
810
986
"ansis": ["ansis@4.2.0", "", {}, "sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig=="],
811
-
812
-
"any-promise": ["any-promise@1.3.0", "", {}, "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="],
813
987
814
988
"anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="],
815
989
816
-
"arg": ["arg@4.1.3", "", {}, "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA=="],
990
+
"app": ["app@workspace:apps/app"],
817
991
818
992
"argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
819
993
820
994
"aria-hidden": ["aria-hidden@1.2.6", "", { "dependencies": { "tslib": "^2.0.0" } }, "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA=="],
821
995
996
+
"aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="],
997
+
998
+
"array-buffer-byte-length": ["array-buffer-byte-length@1.0.2", "", { "dependencies": { "call-bound": "^1.0.3", "is-array-buffer": "^3.0.5" } }, "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw=="],
999
+
1000
+
"array-includes": ["array-includes@3.1.9", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.4", "define-properties": "^1.2.1", "es-abstract": "^1.24.0", "es-object-atoms": "^1.1.1", "get-intrinsic": "^1.3.0", "is-string": "^1.1.1", "math-intrinsics": "^1.1.0" } }, "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ=="],
1001
+
1002
+
"array.prototype.findlast": ["array.prototype.findlast@1.2.5", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.2", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "es-shim-unscopables": "^1.0.2" } }, "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ=="],
1003
+
1004
+
"array.prototype.findlastindex": ["array.prototype.findlastindex@1.2.6", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.4", "define-properties": "^1.2.1", "es-abstract": "^1.23.9", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "es-shim-unscopables": "^1.1.0" } }, "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ=="],
1005
+
1006
+
"array.prototype.flat": ["array.prototype.flat@1.3.3", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.5", "es-shim-unscopables": "^1.0.2" } }, "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg=="],
1007
+
1008
+
"array.prototype.flatmap": ["array.prototype.flatmap@1.3.3", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.5", "es-shim-unscopables": "^1.0.2" } }, "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg=="],
1009
+
1010
+
"array.prototype.tosorted": ["array.prototype.tosorted@1.1.4", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.3", "es-errors": "^1.3.0", "es-shim-unscopables": "^1.0.2" } }, "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA=="],
1011
+
1012
+
"arraybuffer.prototype.slice": ["arraybuffer.prototype.slice@1.0.4", "", { "dependencies": { "array-buffer-byte-length": "^1.0.1", "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.5", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "is-array-buffer": "^3.0.4" } }, "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ=="],
1013
+
822
1014
"ast-types": ["ast-types@0.16.1", "", { "dependencies": { "tslib": "^2.0.1" } }, "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg=="],
823
1015
824
-
"asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="],
1016
+
"ast-types-flow": ["ast-types-flow@0.0.8", "", {}, "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ=="],
1017
+
1018
+
"async-function": ["async-function@1.0.0", "", {}, "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA=="],
825
1019
826
1020
"atomic-sleep": ["atomic-sleep@1.0.0", "", {}, "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ=="],
827
1021
828
-
"autoprefixer": ["autoprefixer@10.4.22", "", { "dependencies": { "browserslist": "^4.27.0", "caniuse-lite": "^1.0.30001754", "fraction.js": "^5.3.4", "normalize-range": "^0.1.2", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": { "autoprefixer": "bin/autoprefixer" } }, "sha512-ARe0v/t9gO28Bznv6GgqARmVqcWOV3mfgUPn9becPHMiD3o9BwlRgaeccZnwTpZ7Zwqrm+c1sUSsMxIzQzc8Xg=="],
1022
+
"available-typed-arrays": ["available-typed-arrays@1.0.7", "", { "dependencies": { "possible-typed-array-names": "^1.0.0" } }, "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ=="],
829
1023
830
-
"await-lock": ["await-lock@2.2.2", "", {}, "sha512-aDczADvlvTGajTDjcjpJMqRkOF6Qdz3YbPZm/PyW6tKPkx2hlYBzxMhEywM/tU72HrVZjgl5VCdRuMlA7pZ8Gw=="],
1024
+
"axe-core": ["axe-core@4.11.0", "", {}, "sha512-ilYanEU8vxxBexpJd8cWM4ElSQq4QctCLKih0TSfjIfCQTeyH/6zVrmIJfLPrKTKJRbiG+cfnZbQIjAlJmF1jQ=="],
831
1025
832
-
"axios": ["axios@1.13.2", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA=="],
1026
+
"axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="],
833
1027
834
1028
"babel-dead-code-elimination": ["babel-dead-code-elimination@1.0.10", "", { "dependencies": { "@babel/core": "^7.23.7", "@babel/parser": "^7.23.6", "@babel/traverse": "^7.23.7", "@babel/types": "^7.23.6" } }, "sha512-DV5bdJZTzZ0zn0DC24v3jD7Mnidh6xhKa4GfKCbq3sfW8kaWhDdZjP3i81geA8T33tdYqWKw4D3fVv0CwEgKVA=="],
835
1029
1030
+
"babel-plugin-react-compiler": ["babel-plugin-react-compiler@1.0.0", "", { "dependencies": { "@babel/types": "^7.26.0" } }, "sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw=="],
1031
+
836
1032
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
837
1033
838
-
"base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="],
839
-
840
-
"baseline-browser-mapping": ["baseline-browser-mapping@2.8.30", "", { "bin": { "baseline-browser-mapping": "dist/cli.js" } }, "sha512-aTUKW4ptQhS64+v2d6IkPzymEzzhw+G0bA1g3uBRV3+ntkH+svttKseW5IOR4Ed6NUVKqnY7qT3dKvzQ7io4AA=="],
1034
+
"baseline-browser-mapping": ["baseline-browser-mapping@2.8.31", "", { "bin": { "baseline-browser-mapping": "dist/cli.js" } }, "sha512-a28v2eWrrRWPpJSzxc+mKwm0ZtVx/G8SepdQZDArnXYU/XS+IF6mp8aB/4E+hH1tyGCoDo3KlUCdlSxGDsRkAw=="],
841
1035
842
1036
"binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="],
843
1037
844
-
"boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="],
845
-
846
1038
"brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
847
1039
848
1040
"braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
849
1041
850
1042
"browserslist": ["browserslist@4.28.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", "electron-to-chromium": "^1.5.249", "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": { "browserslist": "cli.js" } }, "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ=="],
851
1043
852
-
"buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="],
853
-
854
1044
"buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="],
855
1045
856
1046
"bufferutil": ["bufferutil@4.0.9", "", { "dependencies": { "node-gyp-build": "^4.3.0" } }, "sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw=="],
857
1047
858
-
"bundle-require": ["bundle-require@5.1.0", "", { "dependencies": { "load-tsconfig": "^0.2.3" }, "peerDependencies": { "esbuild": ">=0.18" } }, "sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA=="],
1048
+
"bun-types": ["bun-types@1.3.3", "", { "dependencies": { "@types/node": "*" } }, "sha512-z3Xwlg7j2l9JY27x5Qn3Wlyos8YAp0kKRlrePAOjgjMGS5IG6E7Jnlx736vH9UVI4wUICwwhC9anYL++XeOgTQ=="],
859
1049
860
-
"cac": ["cac@6.7.14", "", {}, "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ=="],
1050
+
"call-bind": ["call-bind@1.0.8", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", "get-intrinsic": "^1.2.4", "set-function-length": "^1.2.2" } }, "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww=="],
861
1051
862
1052
"call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
863
1053
864
-
"callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="],
865
-
866
-
"camelcase-css": ["camelcase-css@2.0.1", "", {}, "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA=="],
1054
+
"call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="],
867
1055
868
-
"caniuse-api": ["caniuse-api@3.0.0", "", { "dependencies": { "browserslist": "^4.0.0", "caniuse-lite": "^1.0.0", "lodash.memoize": "^4.1.2", "lodash.uniq": "^4.5.0" } }, "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw=="],
1056
+
"callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="],
869
1057
870
-
"caniuse-lite": ["caniuse-lite@1.0.30001756", "", {}, "sha512-4HnCNKbMLkLdhJz3TToeVWHSnfJvPaq6vu/eRP0Ahub/07n484XHhBF5AJoSGHdVrS8tKFauUQz8Bp9P7LVx7A=="],
1058
+
"caniuse-lite": ["caniuse-lite@1.0.30001757", "", {}, "sha512-r0nnL/I28Zi/yjk1el6ilj27tKcdjLsNqAOZr0yVjWPrSQyHgKI2INaEWw21bAQSv2LXRt1XuCS/GomNpWOxsQ=="],
871
1059
872
-
"cbor-extract": ["cbor-extract@2.2.0", "", { "dependencies": { "node-gyp-build-optional-packages": "5.1.1" }, "optionalDependencies": { "@cbor-extract/cbor-extract-darwin-arm64": "2.2.0", "@cbor-extract/cbor-extract-darwin-x64": "2.2.0", "@cbor-extract/cbor-extract-linux-arm": "2.2.0", "@cbor-extract/cbor-extract-linux-arm64": "2.2.0", "@cbor-extract/cbor-extract-linux-x64": "2.2.0", "@cbor-extract/cbor-extract-win32-x64": "2.2.0" }, "bin": { "download-cbor-prebuilds": "bin/download-prebuilds.js" } }, "sha512-Ig1zM66BjLfTXpNgKpvBePq271BPOvu8MR0Jl080yG7Jsl+wAZunfrwiwA+9ruzm/WEdIV5QF/bjDZTqyAIVHA=="],
1060
+
"chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
873
1061
874
-
"cbor-x": ["cbor-x@1.6.0", "", { "optionalDependencies": { "cbor-extract": "^2.2.0" } }, "sha512-0kareyRwHSkL6ws5VXHEf8uY1liitysCVJjlmhaLG+IXLqhSaOO+t63coaso7yjwEzWZzLy8fJo06gZDVQM9Qg=="],
1062
+
"change-case": ["change-case@5.4.4", "", {}, "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w=="],
875
1063
876
-
"cborg": ["cborg@1.10.2", "", { "bin": { "cborg": "cli.js" } }, "sha512-b3tFPA9pUr2zCUiCfRd2+wok2/LBSNUMKOuRRok+WlvvAgEt/PlbgPTsZUcwCOs53IJvLgTp0eotwtosE6njug=="],
1064
+
"chardet": ["chardet@2.1.1", "", {}, "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ=="],
877
1065
878
-
"chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
1066
+
"chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="],
879
1067
880
-
"chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="],
1068
+
"chownr": ["chownr@3.0.0", "", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="],
881
1069
882
1070
"cjs-module-lexer": ["cjs-module-lexer@1.4.3", "", {}, "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q=="],
883
1071
884
1072
"class-variance-authority": ["class-variance-authority@0.7.1", "", { "dependencies": { "clsx": "^2.1.1" } }, "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg=="],
885
1073
1074
+
"cli-width": ["cli-width@4.1.0", "", {}, "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ=="],
1075
+
1076
+
"client-only": ["client-only@0.0.1", "", {}, "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="],
1077
+
1078
+
"cliui": ["cliui@9.0.1", "", { "dependencies": { "string-width": "^7.2.0", "strip-ansi": "^7.1.0", "wrap-ansi": "^9.0.0" } }, "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w=="],
1079
+
886
1080
"clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="],
887
1081
888
1082
"color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
889
1083
890
1084
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
891
1085
892
-
"colord": ["colord@2.9.3", "", {}, "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw=="],
893
-
894
1086
"colorette": ["colorette@2.0.20", "", {}, "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w=="],
895
1087
896
-
"combined-stream": ["combined-stream@1.0.8", "", { "dependencies": { "delayed-stream": "~1.0.0" } }, "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="],
897
-
898
-
"commander": ["commander@4.1.1", "", {}, "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="],
899
-
900
1088
"concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
901
1089
902
-
"confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="],
903
-
904
-
"consola": ["consola@3.4.2", "", {}, "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA=="],
905
-
906
1090
"convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="],
907
1091
908
1092
"cookie-es": ["cookie-es@2.0.0", "", {}, "sha512-RAj4E421UYRgqokKUmotqAwuplYw15qtdXfY+hGzgCJ/MBjCVZcSoHK/kH9kocfjRjcDME7IiDWR/1WX1TM2Pg=="],
909
1093
910
-
"create-require": ["create-require@1.1.1", "", {}, "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ=="],
1094
+
"core-js": ["core-js@3.47.0", "", {}, "sha512-c3Q2VVkGAUyupsjRnaNX6u8Dq2vAdzm9iuPj5FW0fRxzlxgq9Q39MDq10IvmQSpLgHQNyQzQmOo6bgGHmH3NNg=="],
911
1095
912
1096
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
913
1097
914
-
"css-declaration-sorter": ["css-declaration-sorter@7.3.0", "", { "peerDependencies": { "postcss": "^8.0.9" } }, "sha512-LQF6N/3vkAMYF4xoHLJfG718HRJh34Z8BnNhd6bosOMIVjMlhuZK5++oZa3uYAgrI5+7x2o27gUqTR2U/KjUOQ=="],
1098
+
"csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="],
915
1099
916
-
"css-select": ["css-select@5.2.2", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw=="],
1100
+
"damerau-levenshtein": ["damerau-levenshtein@1.0.8", "", {}, "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA=="],
917
1101
918
-
"css-tree": ["css-tree@3.1.0", "", { "dependencies": { "mdn-data": "2.12.2", "source-map-js": "^1.0.1" } }, "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w=="],
1102
+
"data-uri-to-buffer": ["data-uri-to-buffer@4.0.1", "", {}, "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A=="],
919
1103
920
-
"css-what": ["css-what@6.2.2", "", {}, "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA=="],
1104
+
"data-view-buffer": ["data-view-buffer@1.0.2", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-data-view": "^1.0.2" } }, "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ=="],
921
1105
922
-
"cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="],
1106
+
"data-view-byte-length": ["data-view-byte-length@1.0.2", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-data-view": "^1.0.2" } }, "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ=="],
923
1107
924
-
"cssnano": ["cssnano@7.1.2", "", { "dependencies": { "cssnano-preset-default": "^7.0.10", "lilconfig": "^3.1.3" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-HYOPBsNvoiFeR1eghKD5C3ASm64v9YVyJB4Ivnl2gqKoQYvjjN/G0rztvKQq8OxocUtC6sjqY8jwYngIB4AByA=="],
925
-
926
-
"cssnano-preset-default": ["cssnano-preset-default@7.0.10", "", { "dependencies": { "browserslist": "^4.27.0", "css-declaration-sorter": "^7.2.0", "cssnano-utils": "^5.0.1", "postcss-calc": "^10.1.1", "postcss-colormin": "^7.0.5", "postcss-convert-values": "^7.0.8", "postcss-discard-comments": "^7.0.5", "postcss-discard-duplicates": "^7.0.2", "postcss-discard-empty": "^7.0.1", "postcss-discard-overridden": "^7.0.1", "postcss-merge-longhand": "^7.0.5", "postcss-merge-rules": "^7.0.7", "postcss-minify-font-values": "^7.0.1", "postcss-minify-gradients": "^7.0.1", "postcss-minify-params": "^7.0.5", "postcss-minify-selectors": "^7.0.5", "postcss-normalize-charset": "^7.0.1", "postcss-normalize-display-values": "^7.0.1", "postcss-normalize-positions": "^7.0.1", "postcss-normalize-repeat-style": "^7.0.1", "postcss-normalize-string": "^7.0.1", "postcss-normalize-timing-functions": "^7.0.1", "postcss-normalize-unicode": "^7.0.5", "postcss-normalize-url": "^7.0.1", "postcss-normalize-whitespace": "^7.0.1", "postcss-ordered-values": "^7.0.2", "postcss-reduce-initial": "^7.0.5", "postcss-reduce-transforms": "^7.0.1", "postcss-svgo": "^7.1.0", "postcss-unique-selectors": "^7.0.4" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-6ZBjW0Lf1K1Z+0OKUAUpEN62tSXmYChXWi2NAA0afxEVsj9a+MbcB1l5qel6BHJHmULai2fCGRthCeKSFbScpA=="],
927
-
928
-
"cssnano-utils": ["cssnano-utils@5.0.1", "", { "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-ZIP71eQgG9JwjVZsTPSqhc6GHgEr53uJ7tK5///VfyWj6Xp2DBmixWHqJgPno+PqATzn48pL42ww9x5SSGmhZg=="],
929
-
930
-
"csso": ["csso@5.0.5", "", { "dependencies": { "css-tree": "~2.2.0" } }, "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ=="],
931
-
932
-
"csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="],
933
-
934
-
"data-uri-to-buffer": ["data-uri-to-buffer@4.0.1", "", {}, "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A=="],
1108
+
"data-view-byte-offset": ["data-view-byte-offset@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-data-view": "^1.0.1" } }, "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ=="],
935
1109
936
1110
"dateformat": ["dateformat@4.6.3", "", {}, "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA=="],
937
1111
···
939
1113
940
1114
"deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="],
941
1115
942
-
"delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="],
1116
+
"define-data-property": ["define-data-property@1.1.4", "", { "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "gopd": "^1.0.1" } }, "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A=="],
1117
+
1118
+
"define-properties": ["define-properties@1.2.1", "", { "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } }, "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg=="],
943
1119
944
1120
"detect-libc": ["detect-libc@2.0.2", "", {}, "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw=="],
945
1121
946
1122
"detect-node-es": ["detect-node-es@1.1.0", "", {}, "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="],
947
1123
948
-
"didyoumean": ["didyoumean@1.2.2", "", {}, "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw=="],
949
-
950
-
"diff": ["diff@4.0.2", "", {}, "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A=="],
951
-
952
-
"dlv": ["dlv@1.1.3", "", {}, "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="],
953
-
954
-
"dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="],
1124
+
"diff": ["diff@8.0.2", "", {}, "sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg=="],
955
1125
956
-
"domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="],
957
-
958
-
"domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="],
959
-
960
-
"domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="],
1126
+
"doctrine": ["doctrine@2.1.0", "", { "dependencies": { "esutils": "^2.0.2" } }, "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw=="],
961
1127
962
1128
"drizzle-kit": ["drizzle-kit@0.29.1", "", { "dependencies": { "@drizzle-team/brocli": "^0.10.2", "@esbuild-kit/esm-loader": "^2.5.5", "esbuild": "^0.19.7", "esbuild-register": "^3.5.0" }, "bin": { "drizzle-kit": "bin.cjs" } }, "sha512-OvHL8RVyYiPR3LLRE3SHdcON8xGXl+qMfR9uTTnFWBPIqVk/3NWYZPb7nfpM1Bhix3H+BsxqPyyagG7YZ+Z63A=="],
963
1129
964
-
"drizzle-orm": ["drizzle-orm@0.37.0", "", { "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", "@cloudflare/workers-types": ">=4", "@electric-sql/pglite": ">=0.2.0", "@libsql/client": ">=0.10.0", "@libsql/client-wasm": ">=0.10.0", "@neondatabase/serverless": ">=0.10.0", "@op-engineering/op-sqlite": ">=2", "@opentelemetry/api": "^1.4.1", "@planetscale/database": ">=1", "@prisma/client": "*", "@tidbcloud/serverless": "*", "@types/better-sqlite3": "*", "@types/pg": "*", "@types/react": ">=18", "@types/sql.js": "*", "@vercel/postgres": ">=0.8.0", "@xata.io/client": "*", "better-sqlite3": ">=7", "bun-types": "*", "expo-sqlite": ">=14.0.0", "knex": "*", "kysely": "*", "mysql2": ">=2", "pg": ">=8", "postgres": ">=3", "react": ">=18", "sql.js": ">=1", "sqlite3": ">=5" }, "optionalPeers": ["@aws-sdk/client-rds-data", "@cloudflare/workers-types", "@electric-sql/pglite", "@libsql/client", "@libsql/client-wasm", "@neondatabase/serverless", "@op-engineering/op-sqlite", "@opentelemetry/api", "@planetscale/database", "@prisma/client", "@tidbcloud/serverless", "@types/better-sqlite3", "@types/pg", "@types/react", "@types/sql.js", "@vercel/postgres", "@xata.io/client", "better-sqlite3", "bun-types", "expo-sqlite", "knex", "kysely", "mysql2", "pg", "postgres", "react", "sql.js", "sqlite3"] }, "sha512-AsCNACQ/T2CyZUkrBRUqFT2ibHJ9ZHz3+lzYJFFn3hnj7ylIeItMz5kacRG89uSE74nXYShqehr6u+6ks4JR1A=="],
1130
+
"drizzle-orm": ["drizzle-orm@0.44.7", "", { "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", "@cloudflare/workers-types": ">=4", "@electric-sql/pglite": ">=0.2.0", "@libsql/client": ">=0.10.0", "@libsql/client-wasm": ">=0.10.0", "@neondatabase/serverless": ">=0.10.0", "@op-engineering/op-sqlite": ">=2", "@opentelemetry/api": "^1.4.1", "@planetscale/database": ">=1.13", "@prisma/client": "*", "@tidbcloud/serverless": "*", "@types/better-sqlite3": "*", "@types/pg": "*", "@types/sql.js": "*", "@upstash/redis": ">=1.34.7", "@vercel/postgres": ">=0.8.0", "@xata.io/client": "*", "better-sqlite3": ">=7", "bun-types": "*", "expo-sqlite": ">=14.0.0", "gel": ">=2", "knex": "*", "kysely": "*", "mysql2": ">=2", "pg": ">=8", "postgres": ">=3", "sql.js": ">=1", "sqlite3": ">=5" }, "optionalPeers": ["@aws-sdk/client-rds-data", "@cloudflare/workers-types", "@electric-sql/pglite", "@libsql/client", "@libsql/client-wasm", "@neondatabase/serverless", "@op-engineering/op-sqlite", "@opentelemetry/api", "@planetscale/database", "@prisma/client", "@tidbcloud/serverless", "@types/better-sqlite3", "@types/pg", "@types/sql.js", "@upstash/redis", "@vercel/postgres", "@xata.io/client", "better-sqlite3", "bun-types", "expo-sqlite", "gel", "knex", "kysely", "mysql2", "pg", "postgres", "sql.js", "sqlite3"] }, "sha512-quIpnYznjU9lHshEOAYLoZ9s3jweleHlZIAWR/jX9gAWNg/JhQ1wj0KGRf7/Zm+obRrYd9GjPVJg790QY9N5AQ=="],
965
1131
966
1132
"dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
967
1133
968
1134
"electron-to-chromium": ["electron-to-chromium@1.5.259", "", {}, "sha512-I+oLXgpEJzD6Cwuwt1gYjxsDmu/S/Kd41mmLA3O+/uH2pFRO/DvOjUyGozL8j3KeLV6WyZ7ssPwELMsXCcsJAQ=="],
969
1135
1136
+
"emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="],
1137
+
970
1138
"end-of-stream": ["end-of-stream@1.4.5", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg=="],
971
1139
972
-
"entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
1140
+
"enhanced-resolve": ["enhanced-resolve@5.18.3", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww=="],
1141
+
1142
+
"env-paths": ["env-paths@3.0.0", "", {}, "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A=="],
1143
+
1144
+
"es-abstract": ["es-abstract@1.24.0", "", { "dependencies": { "array-buffer-byte-length": "^1.0.2", "arraybuffer.prototype.slice": "^1.0.4", "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.4", "data-view-buffer": "^1.0.2", "data-view-byte-length": "^1.0.2", "data-view-byte-offset": "^1.0.1", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "es-set-tostringtag": "^2.1.0", "es-to-primitive": "^1.3.0", "function.prototype.name": "^1.1.8", "get-intrinsic": "^1.3.0", "get-proto": "^1.0.1", "get-symbol-description": "^1.1.0", "globalthis": "^1.0.4", "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", "has-proto": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "internal-slot": "^1.1.0", "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", "is-data-view": "^1.0.2", "is-negative-zero": "^2.0.3", "is-regex": "^1.2.1", "is-set": "^2.0.3", "is-shared-array-buffer": "^1.0.4", "is-string": "^1.1.1", "is-typed-array": "^1.1.15", "is-weakref": "^1.1.1", "math-intrinsics": "^1.1.0", "object-inspect": "^1.13.4", "object-keys": "^1.1.1", "object.assign": "^4.1.7", "own-keys": "^1.0.1", "regexp.prototype.flags": "^1.5.4", "safe-array-concat": "^1.1.3", "safe-push-apply": "^1.0.0", "safe-regex-test": "^1.1.0", "set-proto": "^1.0.0", "stop-iteration-iterator": "^1.1.0", "string.prototype.trim": "^1.2.10", "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", "typed-array-buffer": "^1.0.3", "typed-array-byte-length": "^1.0.3", "typed-array-byte-offset": "^1.0.4", "typed-array-length": "^1.0.7", "unbox-primitive": "^1.1.0", "which-typed-array": "^1.1.19" } }, "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg=="],
973
1145
974
1146
"es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
975
1147
976
1148
"es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
977
1149
1150
+
"es-iterator-helpers": ["es-iterator-helpers@1.2.1", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-abstract": "^1.23.6", "es-errors": "^1.3.0", "es-set-tostringtag": "^2.0.3", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.6", "globalthis": "^1.0.4", "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", "has-proto": "^1.2.0", "has-symbols": "^1.1.0", "internal-slot": "^1.1.0", "iterator.prototype": "^1.1.4", "safe-array-concat": "^1.1.3" } }, "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w=="],
1151
+
978
1152
"es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="],
979
1153
980
1154
"es-set-tostringtag": ["es-set-tostringtag@2.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="],
1155
+
1156
+
"es-shim-unscopables": ["es-shim-unscopables@1.1.0", "", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw=="],
1157
+
1158
+
"es-to-primitive": ["es-to-primitive@1.3.0", "", { "dependencies": { "is-callable": "^1.2.7", "is-date-object": "^1.0.5", "is-symbol": "^1.0.4" } }, "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g=="],
981
1159
982
1160
"esbuild": ["esbuild@0.19.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.19.12", "@esbuild/android-arm": "0.19.12", "@esbuild/android-arm64": "0.19.12", "@esbuild/android-x64": "0.19.12", "@esbuild/darwin-arm64": "0.19.12", "@esbuild/darwin-x64": "0.19.12", "@esbuild/freebsd-arm64": "0.19.12", "@esbuild/freebsd-x64": "0.19.12", "@esbuild/linux-arm": "0.19.12", "@esbuild/linux-arm64": "0.19.12", "@esbuild/linux-ia32": "0.19.12", "@esbuild/linux-loong64": "0.19.12", "@esbuild/linux-mips64el": "0.19.12", "@esbuild/linux-ppc64": "0.19.12", "@esbuild/linux-riscv64": "0.19.12", "@esbuild/linux-s390x": "0.19.12", "@esbuild/linux-x64": "0.19.12", "@esbuild/netbsd-x64": "0.19.12", "@esbuild/openbsd-x64": "0.19.12", "@esbuild/sunos-x64": "0.19.12", "@esbuild/win32-arm64": "0.19.12", "@esbuild/win32-ia32": "0.19.12", "@esbuild/win32-x64": "0.19.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg=="],
983
1161
···
989
1167
990
1168
"eslint": ["eslint@9.39.1", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.1", "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "9.39.1", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g=="],
991
1169
992
-
"eslint-plugin-react-hooks": ["eslint-plugin-react-hooks@5.2.0", "", { "peerDependencies": { "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" } }, "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg=="],
1170
+
"eslint-config-next": ["eslint-config-next@16.0.7", "", { "dependencies": { "@next/eslint-plugin-next": "16.0.7", "eslint-import-resolver-node": "^0.3.6", "eslint-import-resolver-typescript": "^3.5.2", "eslint-plugin-import": "^2.32.0", "eslint-plugin-jsx-a11y": "^6.10.0", "eslint-plugin-react": "^7.37.0", "eslint-plugin-react-hooks": "^7.0.0", "globals": "16.4.0", "typescript-eslint": "^8.46.0" }, "peerDependencies": { "eslint": ">=9.0.0", "typescript": ">=3.3.1" }, "optionalPeers": ["typescript"] }, "sha512-WubFGLFHfk2KivkdRGfx6cGSFhaQqhERRfyO8BRx+qiGPGp7WLKcPvYC4mdx1z3VhVRcrfFzczjjTrbJZOpnEQ=="],
1171
+
1172
+
"eslint-import-resolver-node": ["eslint-import-resolver-node@0.3.9", "", { "dependencies": { "debug": "^3.2.7", "is-core-module": "^2.13.0", "resolve": "^1.22.4" } }, "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g=="],
1173
+
1174
+
"eslint-import-resolver-typescript": ["eslint-import-resolver-typescript@3.10.1", "", { "dependencies": { "@nolyfill/is-core-module": "1.0.39", "debug": "^4.4.0", "get-tsconfig": "^4.10.0", "is-bun-module": "^2.0.0", "stable-hash": "^0.0.5", "tinyglobby": "^0.2.13", "unrs-resolver": "^1.6.2" }, "peerDependencies": { "eslint": "*", "eslint-plugin-import": "*", "eslint-plugin-import-x": "*" }, "optionalPeers": ["eslint-plugin-import", "eslint-plugin-import-x"] }, "sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ=="],
1175
+
1176
+
"eslint-module-utils": ["eslint-module-utils@2.12.1", "", { "dependencies": { "debug": "^3.2.7" } }, "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw=="],
1177
+
1178
+
"eslint-plugin-import": ["eslint-plugin-import@2.32.0", "", { "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", "array.prototype.findlastindex": "^1.2.6", "array.prototype.flat": "^1.3.3", "array.prototype.flatmap": "^1.3.3", "debug": "^3.2.7", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.9", "eslint-module-utils": "^2.12.1", "hasown": "^2.0.2", "is-core-module": "^2.16.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", "object.fromentries": "^2.0.8", "object.groupby": "^1.0.3", "object.values": "^1.2.1", "semver": "^6.3.1", "string.prototype.trimend": "^1.0.9", "tsconfig-paths": "^3.15.0" }, "peerDependencies": { "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" } }, "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA=="],
1179
+
1180
+
"eslint-plugin-jsx-a11y": ["eslint-plugin-jsx-a11y@6.10.2", "", { "dependencies": { "aria-query": "^5.3.2", "array-includes": "^3.1.8", "array.prototype.flatmap": "^1.3.2", "ast-types-flow": "^0.0.8", "axe-core": "^4.10.0", "axobject-query": "^4.1.0", "damerau-levenshtein": "^1.0.8", "emoji-regex": "^9.2.2", "hasown": "^2.0.2", "jsx-ast-utils": "^3.3.5", "language-tags": "^1.0.9", "minimatch": "^3.1.2", "object.fromentries": "^2.0.8", "safe-regex-test": "^1.0.3", "string.prototype.includes": "^2.0.1" }, "peerDependencies": { "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" } }, "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q=="],
1181
+
1182
+
"eslint-plugin-react": ["eslint-plugin-react@7.37.5", "", { "dependencies": { "array-includes": "^3.1.8", "array.prototype.findlast": "^1.2.5", "array.prototype.flatmap": "^1.3.3", "array.prototype.tosorted": "^1.1.4", "doctrine": "^2.1.0", "es-iterator-helpers": "^1.2.1", "estraverse": "^5.3.0", "hasown": "^2.0.2", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", "object.entries": "^1.1.9", "object.fromentries": "^2.0.8", "object.values": "^1.2.1", "prop-types": "^15.8.1", "resolve": "^2.0.0-next.5", "semver": "^6.3.1", "string.prototype.matchall": "^4.0.12", "string.prototype.repeat": "^1.0.0" }, "peerDependencies": { "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" } }, "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA=="],
1183
+
1184
+
"eslint-plugin-react-hooks": ["eslint-plugin-react-hooks@7.0.1", "", { "dependencies": { "@babel/core": "^7.24.4", "@babel/parser": "^7.24.4", "hermes-parser": "^0.25.1", "zod": "^3.25.0 || ^4.0.0", "zod-validation-error": "^3.5.0 || ^4.0.0" }, "peerDependencies": { "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" } }, "sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA=="],
993
1185
994
1186
"eslint-plugin-react-refresh": ["eslint-plugin-react-refresh@0.4.24", "", { "peerDependencies": { "eslint": ">=8.40" } }, "sha512-nLHIW7TEq3aLrEYWpVaJ1dRgFR+wLDPN8e8FpYAql/bMV2oBEfC37K0gLEGgv9fy66juNShSMV8OkTqzltcG/w=="],
995
1187
···
1013
1205
1014
1206
"event-target-polyfill": ["event-target-polyfill@0.0.4", "", {}, "sha512-Gs6RLjzlLRdT8X9ZipJdIZI/Y6/HhRLyq9RdDlCsnpxr/+Nn6bU2EFGuC94GjxqhM+Nmij2Vcq98yoHrU8uNFQ=="],
1015
1207
1016
-
"event-target-shim": ["event-target-shim@5.0.1", "", {}, "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="],
1017
-
1018
-
"events": ["events@3.3.0", "", {}, "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="],
1019
-
1020
1208
"fast-copy": ["fast-copy@3.0.2", "", {}, "sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ=="],
1021
1209
1022
1210
"fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
···
1027
1215
1028
1216
"fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="],
1029
1217
1030
-
"fast-redact": ["fast-redact@3.5.0", "", {}, "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A=="],
1218
+
"fast-safe-stringify": ["fast-safe-stringify@2.1.1", "", {}, "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA=="],
1031
1219
1032
-
"fast-safe-stringify": ["fast-safe-stringify@2.1.1", "", {}, "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA=="],
1220
+
"fast-uri": ["fast-uri@3.1.0", "", {}, "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA=="],
1033
1221
1034
1222
"fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="],
1035
1223
···
1043
1231
1044
1232
"find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="],
1045
1233
1046
-
"fix-dts-default-cjs-exports": ["fix-dts-default-cjs-exports@1.0.1", "", { "dependencies": { "magic-string": "^0.30.17", "mlly": "^1.7.4", "rollup": "^4.34.8" } }, "sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg=="],
1047
-
1048
1234
"flat-cache": ["flat-cache@4.0.1", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="],
1049
1235
1050
1236
"flatted": ["flatted@3.3.3", "", {}, "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg=="],
1051
1237
1052
-
"follow-redirects": ["follow-redirects@1.15.11", "", {}, "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ=="],
1053
-
1054
-
"form-data": ["form-data@4.0.5", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" } }, "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w=="],
1238
+
"for-each": ["for-each@0.3.5", "", { "dependencies": { "is-callable": "^1.2.7" } }, "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg=="],
1055
1239
1056
1240
"formdata-polyfill": ["formdata-polyfill@4.0.10", "", { "dependencies": { "fetch-blob": "^3.1.2" } }, "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g=="],
1057
1241
1058
1242
"forwarded-parse": ["forwarded-parse@2.1.2", "", {}, "sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw=="],
1059
1243
1060
-
"fraction.js": ["fraction.js@5.3.4", "", {}, "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ=="],
1061
-
1062
1244
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
1063
1245
1064
1246
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
1065
1247
1248
+
"function.prototype.name": ["function.prototype.name@1.1.8", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "functions-have-names": "^1.2.3", "hasown": "^2.0.2", "is-callable": "^1.2.7" } }, "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q=="],
1249
+
1250
+
"functions-have-names": ["functions-have-names@1.2.3", "", {}, "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ=="],
1251
+
1252
+
"generator-function": ["generator-function@2.0.1", "", {}, "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g=="],
1253
+
1066
1254
"gensync": ["gensync@1.0.0-beta.2", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="],
1067
1255
1256
+
"get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="],
1257
+
1258
+
"get-east-asian-width": ["get-east-asian-width@1.4.0", "", {}, "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q=="],
1259
+
1068
1260
"get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="],
1069
1261
1070
1262
"get-nonce": ["get-nonce@1.0.1", "", {}, "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q=="],
1071
1263
1072
1264
"get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="],
1073
1265
1266
+
"get-symbol-description": ["get-symbol-description@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6" } }, "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg=="],
1267
+
1074
1268
"get-tsconfig": ["get-tsconfig@4.13.0", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ=="],
1075
1269
1076
1270
"glob": ["glob@13.0.0", "", { "dependencies": { "minimatch": "^10.1.1", "minipass": "^7.1.2", "path-scurry": "^2.0.0" } }, "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA=="],
1077
1271
1078
1272
"glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
1079
1273
1080
-
"globals": ["globals@15.15.0", "", {}, "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg=="],
1274
+
"globals": ["globals@16.5.0", "", {}, "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ=="],
1275
+
1276
+
"globalthis": ["globalthis@1.0.4", "", { "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" } }, "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ=="],
1277
+
1278
+
"globby": ["globby@15.0.0", "", { "dependencies": { "@sindresorhus/merge-streams": "^4.0.0", "fast-glob": "^3.3.3", "ignore": "^7.0.5", "path-type": "^6.0.0", "slash": "^5.1.0", "unicorn-magic": "^0.3.0" } }, "sha512-oB4vkQGqlMl682wL1IlWd02tXCbquGWM4voPEI85QmNKCaw8zGTm1f1rubFgkg3Eli2PtKlFgrnmUqasbQWlkw=="],
1081
1279
1082
1280
"goober": ["goober@2.1.18", "", { "peerDependencies": { "csstype": "^3.0.10" } }, "sha512-2vFqsaDVIT9Gz7N6kAL++pLpp41l3PfDuusHcjnGLfR6+huZkl6ziX+zgVC3ZxpqWhzH6pyDdGrCeDhMIvwaxw=="],
1083
1281
1084
1282
"gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
1085
1283
1284
+
"graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
1285
+
1086
1286
"graphemer": ["graphemer@1.4.0", "", {}, "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="],
1087
1287
1288
+
"has-bigints": ["has-bigints@1.1.0", "", {}, "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg=="],
1289
+
1088
1290
"has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
1089
1291
1292
+
"has-property-descriptors": ["has-property-descriptors@1.0.2", "", { "dependencies": { "es-define-property": "^1.0.0" } }, "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg=="],
1293
+
1294
+
"has-proto": ["has-proto@1.2.0", "", { "dependencies": { "dunder-proto": "^1.0.0" } }, "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ=="],
1295
+
1090
1296
"has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="],
1091
1297
1092
1298
"has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="],
···
1095
1301
1096
1302
"help-me": ["help-me@5.0.0", "", {}, "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg=="],
1097
1303
1098
-
"hono": ["hono@4.10.6", "", {}, "sha512-BIdolzGpDO9MQ4nu3AUuDwHZZ+KViNm+EZ75Ae55eMXMqLVhDFqEMXxtUe9Qh8hjL+pIna/frs2j6Y2yD5Ua/g=="],
1304
+
"hermes-estree": ["hermes-estree@0.25.1", "", {}, "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw=="],
1099
1305
1100
-
"hono-sessions": ["hono-sessions@0.7.3", "", { "dependencies": { "hono": "^4.0.0", "iron-webcrypto": "^1.2.1" } }, "sha512-W2AD0U6KwzssxXHUfKut57YB+ivxB5o8ECOEnbCAqtdhUt4jRBkAeeucJ/KeOoUtRUK+OY/pa2Slo0V9dS5LiA=="],
1306
+
"hermes-parser": ["hermes-parser@0.25.1", "", { "dependencies": { "hermes-estree": "0.25.1" } }, "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA=="],
1101
1307
1102
-
"ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
1308
+
"hono": ["hono@4.10.7", "", {}, "sha512-icXIITfw/07Q88nLSkB9aiUrd8rYzSweK681Kjo/TSggaGbOX4RRyxxm71v+3PC8C/j+4rlxGeoTRxQDkaJkUw=="],
1309
+
1310
+
"iconv-lite": ["iconv-lite@0.7.0", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ=="],
1103
1311
1104
1312
"ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
1105
1313
···
1109
1317
1110
1318
"imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="],
1111
1319
1320
+
"internal-slot": ["internal-slot@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.2", "side-channel": "^1.1.0" } }, "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw=="],
1321
+
1112
1322
"ipaddr.js": ["ipaddr.js@2.2.0", "", {}, "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA=="],
1113
1323
1114
-
"iron-webcrypto": ["iron-webcrypto@1.2.1", "", {}, "sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg=="],
1324
+
"is-array-buffer": ["is-array-buffer@3.0.5", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "get-intrinsic": "^1.2.6" } }, "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A=="],
1325
+
1326
+
"is-async-function": ["is-async-function@2.1.1", "", { "dependencies": { "async-function": "^1.0.0", "call-bound": "^1.0.3", "get-proto": "^1.0.1", "has-tostringtag": "^1.0.2", "safe-regex-test": "^1.1.0" } }, "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ=="],
1327
+
1328
+
"is-bigint": ["is-bigint@1.1.0", "", { "dependencies": { "has-bigints": "^1.0.2" } }, "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ=="],
1115
1329
1116
1330
"is-binary-path": ["is-binary-path@2.1.0", "", { "dependencies": { "binary-extensions": "^2.0.0" } }, "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw=="],
1117
1331
1332
+
"is-boolean-object": ["is-boolean-object@1.2.2", "", { "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" } }, "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A=="],
1333
+
1334
+
"is-bun-module": ["is-bun-module@2.0.0", "", { "dependencies": { "semver": "^7.7.1" } }, "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ=="],
1335
+
1336
+
"is-callable": ["is-callable@1.2.7", "", {}, "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA=="],
1337
+
1118
1338
"is-core-module": ["is-core-module@2.16.1", "", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w=="],
1119
1339
1340
+
"is-data-view": ["is-data-view@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "get-intrinsic": "^1.2.6", "is-typed-array": "^1.1.13" } }, "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw=="],
1341
+
1342
+
"is-date-object": ["is-date-object@1.1.0", "", { "dependencies": { "call-bound": "^1.0.2", "has-tostringtag": "^1.0.2" } }, "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg=="],
1343
+
1120
1344
"is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
1121
1345
1346
+
"is-finalizationregistry": ["is-finalizationregistry@1.1.1", "", { "dependencies": { "call-bound": "^1.0.3" } }, "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg=="],
1347
+
1348
+
"is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="],
1349
+
1350
+
"is-generator-function": ["is-generator-function@1.1.2", "", { "dependencies": { "call-bound": "^1.0.4", "generator-function": "^2.0.0", "get-proto": "^1.0.1", "has-tostringtag": "^1.0.2", "safe-regex-test": "^1.1.0" } }, "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA=="],
1351
+
1122
1352
"is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
1123
1353
1354
+
"is-map": ["is-map@2.0.3", "", {}, "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw=="],
1355
+
1356
+
"is-negative-zero": ["is-negative-zero@2.0.3", "", {}, "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw=="],
1357
+
1124
1358
"is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="],
1125
1359
1360
+
"is-number-object": ["is-number-object@1.1.1", "", { "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" } }, "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw=="],
1361
+
1362
+
"is-regex": ["is-regex@1.2.1", "", { "dependencies": { "call-bound": "^1.0.2", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g=="],
1363
+
1364
+
"is-set": ["is-set@2.0.3", "", {}, "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg=="],
1365
+
1366
+
"is-shared-array-buffer": ["is-shared-array-buffer@1.0.4", "", { "dependencies": { "call-bound": "^1.0.3" } }, "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A=="],
1367
+
1368
+
"is-string": ["is-string@1.1.1", "", { "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" } }, "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA=="],
1369
+
1370
+
"is-symbol": ["is-symbol@1.1.1", "", { "dependencies": { "call-bound": "^1.0.2", "has-symbols": "^1.1.0", "safe-regex-test": "^1.1.0" } }, "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w=="],
1371
+
1372
+
"is-typed-array": ["is-typed-array@1.1.15", "", { "dependencies": { "which-typed-array": "^1.1.16" } }, "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ=="],
1373
+
1374
+
"is-unicode-supported": ["is-unicode-supported@2.1.0", "", {}, "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ=="],
1375
+
1376
+
"is-weakmap": ["is-weakmap@2.0.2", "", {}, "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w=="],
1377
+
1378
+
"is-weakref": ["is-weakref@1.1.1", "", { "dependencies": { "call-bound": "^1.0.3" } }, "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew=="],
1379
+
1380
+
"is-weakset": ["is-weakset@2.0.4", "", { "dependencies": { "call-bound": "^1.0.3", "get-intrinsic": "^1.2.6" } }, "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ=="],
1381
+
1382
+
"isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="],
1383
+
1126
1384
"isbot": ["isbot@5.1.32", "", {}, "sha512-VNfjM73zz2IBZmdShMfAUg10prm6t7HFUQmNAEOAVS4YH92ZrZcvkMcGX6cIgBJAzWDzPent/EeAtYEHNPNPBQ=="],
1127
1385
1128
1386
"isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
1129
1387
1130
1388
"iso-datestring-validator": ["iso-datestring-validator@2.2.2", "", {}, "sha512-yLEMkBbLZTlVQqOnQ4FiMujR6T4DEcCb1xizmvXS+OxuhwcbtynoosRzdMA69zZCShCNAbi+gJ71FxZBBXx1SA=="],
1389
+
1390
+
"iterator.prototype": ["iterator.prototype@1.1.5", "", { "dependencies": { "define-data-property": "^1.1.4", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.6", "get-proto": "^1.0.0", "has-symbols": "^1.1.0", "set-function-name": "^2.0.2" } }, "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g=="],
1131
1391
1132
1392
"jiti": ["jiti@1.21.7", "", { "bin": { "jiti": "bin/jiti.js" } }, "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A=="],
1133
1393
···
1145
1405
1146
1406
"json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="],
1147
1407
1148
-
"json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="],
1408
+
"json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="],
1149
1409
1150
1410
"json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="],
1151
1411
1152
1412
"json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="],
1153
1413
1414
+
"jsx-ast-utils": ["jsx-ast-utils@3.3.5", "", { "dependencies": { "array-includes": "^3.1.6", "array.prototype.flat": "^1.3.1", "object.assign": "^4.1.4", "object.values": "^1.1.6" } }, "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ=="],
1415
+
1154
1416
"keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="],
1155
1417
1418
+
"language-subtag-registry": ["language-subtag-registry@0.3.23", "", {}, "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ=="],
1419
+
1420
+
"language-tags": ["language-tags@1.0.9", "", { "dependencies": { "language-subtag-registry": "^0.3.20" } }, "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA=="],
1421
+
1156
1422
"levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="],
1157
1423
1158
1424
"libsql": ["libsql@0.4.7", "", { "dependencies": { "@neon-rs/load": "^0.0.4", "detect-libc": "2.0.2" }, "optionalDependencies": { "@libsql/darwin-arm64": "0.4.7", "@libsql/darwin-x64": "0.4.7", "@libsql/linux-arm64-gnu": "0.4.7", "@libsql/linux-arm64-musl": "0.4.7", "@libsql/linux-x64-gnu": "0.4.7", "@libsql/linux-x64-musl": "0.4.7", "@libsql/win32-x64-msvc": "0.4.7" }, "os": [ "linux", "win32", "darwin", ], "cpu": [ "x64", "arm64", ] }, "sha512-T9eIRCs6b0J1SHKYIvD8+KCJMcWZ900iZyxdnSCdqxN12Z1ijzT+jY5nrk72Jw4B0HGzms2NgpryArlJqvc3Lw=="],
1159
1425
1160
-
"lilconfig": ["lilconfig@3.1.3", "", {}, "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw=="],
1426
+
"lightningcss": ["lightningcss@1.30.2", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.30.2", "lightningcss-darwin-arm64": "1.30.2", "lightningcss-darwin-x64": "1.30.2", "lightningcss-freebsd-x64": "1.30.2", "lightningcss-linux-arm-gnueabihf": "1.30.2", "lightningcss-linux-arm64-gnu": "1.30.2", "lightningcss-linux-arm64-musl": "1.30.2", "lightningcss-linux-x64-gnu": "1.30.2", "lightningcss-linux-x64-musl": "1.30.2", "lightningcss-win32-arm64-msvc": "1.30.2", "lightningcss-win32-x64-msvc": "1.30.2" } }, "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ=="],
1161
1427
1162
-
"lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="],
1428
+
"lightningcss-android-arm64": ["lightningcss-android-arm64@1.30.2", "", { "os": "android", "cpu": "arm64" }, "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A=="],
1429
+
1430
+
"lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.30.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA=="],
1431
+
1432
+
"lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.30.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ=="],
1433
+
1434
+
"lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.30.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA=="],
1435
+
1436
+
"lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.30.2", "", { "os": "linux", "cpu": "arm" }, "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA=="],
1437
+
1438
+
"lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.30.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A=="],
1439
+
1440
+
"lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.30.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA=="],
1441
+
1442
+
"lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.30.2", "", { "os": "linux", "cpu": "x64" }, "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w=="],
1443
+
1444
+
"lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.30.2", "", { "os": "linux", "cpu": "x64" }, "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA=="],
1445
+
1446
+
"lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.30.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ=="],
1163
1447
1164
-
"load-tsconfig": ["load-tsconfig@0.2.5", "", {}, "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg=="],
1448
+
"lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.30.2", "", { "os": "win32", "cpu": "x64" }, "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw=="],
1165
1449
1166
1450
"locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
1167
1451
1168
-
"lodash.memoize": ["lodash.memoize@4.1.2", "", {}, "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag=="],
1169
-
1170
1452
"lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="],
1171
1453
1172
-
"lodash.uniq": ["lodash.uniq@4.5.0", "", {}, "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ=="],
1454
+
"loose-envify": ["loose-envify@1.4.0", "", { "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": { "loose-envify": "cli.js" } }, "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="],
1173
1455
1174
-
"lru-cache": ["lru-cache@11.2.2", "", {}, "sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg=="],
1456
+
"lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="],
1175
1457
1176
-
"lucide-react": ["lucide-react@0.464.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc" } }, "sha512-eCx1qClbnw5qRqB2Z1AFFp71wdJXEwhPp5ii8LviyvHb7o/7eMXFiTyDHh7JpjM9BO9pC6ZUp/c7mCwwxbPIcg=="],
1458
+
"lucide-react": ["lucide-react@0.556.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-iOb8dRk7kLaYBZhR2VlV1CeJGxChBgUthpSP8wom9jfj79qovgG6qcSdiy6vkoREKPnbUYzJsCn4o4PtG3Iy+A=="],
1177
1459
1178
1460
"magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
1179
1461
1180
-
"make-error": ["make-error@1.3.6", "", {}, "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw=="],
1181
-
1182
1462
"math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
1183
1463
1184
-
"mdn-data": ["mdn-data@2.12.2", "", {}, "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA=="],
1185
-
1186
1464
"merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="],
1187
1465
1188
1466
"micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
1189
1467
1190
-
"mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
1191
-
1192
-
"mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="],
1193
-
1194
1468
"minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
1195
1469
1196
1470
"minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="],
1197
1471
1198
1472
"minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
1199
1473
1200
-
"mlly": ["mlly@1.8.0", "", { "dependencies": { "acorn": "^8.15.0", "pathe": "^2.0.3", "pkg-types": "^1.3.1", "ufo": "^1.6.1" } }, "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g=="],
1474
+
"minizlib": ["minizlib@3.1.0", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw=="],
1201
1475
1202
1476
"module-details-from-path": ["module-details-from-path@1.0.4", "", {}, "sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w=="],
1203
1477
···
1205
1479
1206
1480
"multiformats": ["multiformats@9.9.0", "", {}, "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="],
1207
1481
1208
-
"mz": ["mz@2.7.0", "", { "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", "thenify-all": "^1.0.0" } }, "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q=="],
1482
+
"mustache": ["mustache@4.2.0", "", { "bin": { "mustache": "bin/mustache" } }, "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ=="],
1483
+
1484
+
"mute-stream": ["mute-stream@2.0.0", "", {}, "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA=="],
1485
+
1486
+
"nanoid": ["nanoid@5.1.6", "", { "bin": { "nanoid": "bin/nanoid.js" } }, "sha512-c7+7RQ+dMB5dPwwCp4ee1/iV/q2P6aK1mTZcfr1BTuVlyW9hJYiMPybJCcnBlQtuSmTIWNeazm/zqNoZSSElBg=="],
1209
1487
1210
-
"nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
1488
+
"napi-postinstall": ["napi-postinstall@0.3.4", "", { "bin": { "napi-postinstall": "lib/cli.js" } }, "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ=="],
1211
1489
1212
1490
"natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="],
1491
+
1492
+
"next": ["next@16.0.7", "", { "dependencies": { "@next/env": "16.0.7", "@swc/helpers": "0.5.15", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "16.0.7", "@next/swc-darwin-x64": "16.0.7", "@next/swc-linux-arm64-gnu": "16.0.7", "@next/swc-linux-arm64-musl": "16.0.7", "@next/swc-linux-x64-gnu": "16.0.7", "@next/swc-linux-x64-musl": "16.0.7", "@next/swc-win32-arm64-msvc": "16.0.7", "@next/swc-win32-x64-msvc": "16.0.7", "sharp": "^0.34.4" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-3mBRJyPxT4LOxAJI6IsXeFtKfiJUbjCLgvXO02fV8Wy/lIhPvP94Fe7dGhUgHXcQy4sSuYwQNcOLhIfOm0rL0A=="],
1213
1493
1214
1494
"node-domexception": ["node-domexception@1.0.0", "", {}, "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ=="],
1215
1495
···
1217
1497
1218
1498
"node-gyp-build": ["node-gyp-build@4.8.4", "", { "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", "node-gyp-build-test": "build-test.js" } }, "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ=="],
1219
1499
1220
-
"node-gyp-build-optional-packages": ["node-gyp-build-optional-packages@5.1.1", "", { "dependencies": { "detect-libc": "^2.0.1" }, "bin": { "node-gyp-build-optional-packages": "bin.js", "node-gyp-build-optional-packages-test": "build-test.js", "node-gyp-build-optional-packages-optional": "optional.js" } }, "sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw=="],
1221
-
1222
1500
"node-releases": ["node-releases@2.0.27", "", {}, "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA=="],
1223
1501
1224
1502
"normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="],
1225
1503
1226
-
"normalize-range": ["normalize-range@0.1.2", "", {}, "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA=="],
1504
+
"object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="],
1227
1505
1228
-
"nth-check": ["nth-check@2.1.1", "", { "dependencies": { "boolbase": "^1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="],
1506
+
"object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="],
1507
+
1508
+
"object-keys": ["object-keys@1.1.1", "", {}, "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="],
1229
1509
1230
-
"object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="],
1510
+
"object.assign": ["object.assign@4.1.7", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0", "has-symbols": "^1.1.0", "object-keys": "^1.1.1" } }, "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw=="],
1231
1511
1232
-
"object-hash": ["object-hash@3.0.0", "", {}, "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw=="],
1512
+
"object.entries": ["object.entries@1.1.9", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.4", "define-properties": "^1.2.1", "es-object-atoms": "^1.1.1" } }, "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw=="],
1513
+
1514
+
"object.fromentries": ["object.fromentries@2.0.8", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.2", "es-object-atoms": "^1.0.0" } }, "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ=="],
1515
+
1516
+
"object.groupby": ["object.groupby@1.0.3", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.2" } }, "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ=="],
1517
+
1518
+
"object.values": ["object.values@1.2.1", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" } }, "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA=="],
1233
1519
1234
1520
"on-exit-leak-free": ["on-exit-leak-free@2.1.2", "", {}, "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA=="],
1235
1521
1236
1522
"once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="],
1237
1523
1238
1524
"optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="],
1525
+
1526
+
"own-keys": ["own-keys@1.0.1", "", { "dependencies": { "get-intrinsic": "^1.2.6", "object-keys": "^1.1.1", "safe-push-apply": "^1.0.0" } }, "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg=="],
1239
1527
1240
1528
"p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="],
1241
1529
···
1255
1543
1256
1544
"path-scurry": ["path-scurry@2.0.1", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA=="],
1257
1545
1546
+
"path-type": ["path-type@6.0.0", "", {}, "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ=="],
1547
+
1258
1548
"pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="],
1259
1549
1550
+
"pg": ["pg@8.16.3", "", { "dependencies": { "pg-connection-string": "^2.9.1", "pg-pool": "^3.10.1", "pg-protocol": "^1.10.3", "pg-types": "2.2.0", "pgpass": "1.0.5" }, "optionalDependencies": { "pg-cloudflare": "^1.2.7" }, "peerDependencies": { "pg-native": ">=3.0.1" }, "optionalPeers": ["pg-native"] }, "sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw=="],
1551
+
1552
+
"pg-cloudflare": ["pg-cloudflare@1.2.7", "", {}, "sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg=="],
1553
+
1554
+
"pg-connection-string": ["pg-connection-string@2.9.1", "", {}, "sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w=="],
1555
+
1260
1556
"pg-int8": ["pg-int8@1.0.1", "", {}, "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw=="],
1557
+
1558
+
"pg-pool": ["pg-pool@3.10.1", "", { "peerDependencies": { "pg": ">=8.0" } }, "sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg=="],
1261
1559
1262
1560
"pg-protocol": ["pg-protocol@1.10.3", "", {}, "sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ=="],
1263
1561
1264
1562
"pg-types": ["pg-types@2.2.0", "", { "dependencies": { "pg-int8": "1.0.1", "postgres-array": "~2.0.0", "postgres-bytea": "~1.0.0", "postgres-date": "~1.0.4", "postgres-interval": "^1.1.0" } }, "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA=="],
1265
1563
1564
+
"pgpass": ["pgpass@1.0.5", "", { "dependencies": { "split2": "^4.1.0" } }, "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug=="],
1565
+
1266
1566
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
1267
1567
1268
1568
"picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
1269
-
1270
-
"pify": ["pify@2.3.0", "", {}, "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog=="],
1271
1569
1272
1570
"pino": ["pino@9.14.0", "", { "dependencies": { "@pinojs/redact": "^0.4.0", "atomic-sleep": "^1.0.0", "on-exit-leak-free": "^2.1.0", "pino-abstract-transport": "^2.0.0", "pino-std-serializers": "^7.0.0", "process-warning": "^5.0.0", "quick-format-unescaped": "^4.0.3", "real-require": "^0.2.0", "safe-stable-stringify": "^2.3.1", "sonic-boom": "^4.0.1", "thread-stream": "^3.0.0" }, "bin": { "pino": "bin.js" } }, "sha512-8OEwKp5juEvb/MjpIc4hjqfgCNysrS94RIOMXYvpYCdm/jglrKEiAYmiumbmGhCvs+IcInsphYDFwqrjr7398w=="],
1273
1571
···
1277
1575
1278
1576
"pino-std-serializers": ["pino-std-serializers@7.0.0", "", {}, "sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA=="],
1279
1577
1280
-
"pirates": ["pirates@4.0.7", "", {}, "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA=="],
1281
-
1282
-
"pkg-types": ["pkg-types@1.3.1", "", { "dependencies": { "confbox": "^0.1.8", "mlly": "^1.7.4", "pathe": "^2.0.1" } }, "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ=="],
1578
+
"possible-typed-array-names": ["possible-typed-array-names@1.1.0", "", {}, "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg=="],
1283
1579
1284
1580
"postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
1285
1581
1286
-
"postcss-calc": ["postcss-calc@10.1.1", "", { "dependencies": { "postcss-selector-parser": "^7.0.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.38" } }, "sha512-NYEsLHh8DgG/PRH2+G9BTuUdtf9ViS+vdoQ0YA5OQdGsfN4ztiwtDWNtBl9EKeqNMFnIu8IKZ0cLxEQ5r5KVMw=="],
1287
-
1288
-
"postcss-colormin": ["postcss-colormin@7.0.5", "", { "dependencies": { "browserslist": "^4.27.0", "caniuse-api": "^3.0.0", "colord": "^2.9.3", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-ekIBP/nwzRWhEMmIxHHbXHcMdzd1HIUzBECaj5KEdLz9DVP2HzT065sEhvOx1dkLjYW7jyD0CngThx6bpFi2fA=="],
1289
-
1290
-
"postcss-convert-values": ["postcss-convert-values@7.0.8", "", { "dependencies": { "browserslist": "^4.27.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-+XNKuPfkHTCEo499VzLMYn94TiL3r9YqRE3Ty+jP7UX4qjewUONey1t7CG21lrlTLN07GtGM8MqFVp86D4uKJg=="],
1291
-
1292
-
"postcss-discard-comments": ["postcss-discard-comments@7.0.5", "", { "dependencies": { "postcss-selector-parser": "^7.1.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-IR2Eja8WfYgN5n32vEGSctVQ1+JARfu4UH8M7bgGh1bC+xI/obsPJXaBpQF7MAByvgwZinhpHpdrmXtvVVlKcQ=="],
1293
-
1294
-
"postcss-discard-duplicates": ["postcss-discard-duplicates@7.0.2", "", { "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-eTonaQvPZ/3i1ASDHOKkYwAybiM45zFIc7KXils4mQmHLqIswXD9XNOKEVxtTFnsmwYzF66u4LMgSr0abDlh5w=="],
1295
-
1296
-
"postcss-discard-empty": ["postcss-discard-empty@7.0.1", "", { "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-cFrJKZvcg/uxB6Ijr4l6qmn3pXQBna9zyrPC+sK0zjbkDUZew+6xDltSF7OeB7rAtzaaMVYSdbod+sZOCWnMOg=="],
1297
-
1298
-
"postcss-discard-overridden": ["postcss-discard-overridden@7.0.1", "", { "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-7c3MMjjSZ/qYrx3uc1940GSOzN1Iqjtlqe8uoSg+qdVPYyRb0TILSqqmtlSFuE4mTDECwsm397Ya7iXGzfF7lg=="],
1299
-
1300
-
"postcss-import": ["postcss-import@15.1.0", "", { "dependencies": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", "resolve": "^1.1.7" }, "peerDependencies": { "postcss": "^8.0.0" } }, "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew=="],
1301
-
1302
-
"postcss-js": ["postcss-js@4.1.0", "", { "dependencies": { "camelcase-css": "^2.0.1" }, "peerDependencies": { "postcss": "^8.4.21" } }, "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw=="],
1303
-
1304
-
"postcss-load-config": ["postcss-load-config@6.0.1", "", { "dependencies": { "lilconfig": "^3.1.1" }, "peerDependencies": { "jiti": ">=1.21.0", "postcss": ">=8.0.9", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["jiti", "postcss", "tsx", "yaml"] }, "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g=="],
1305
-
1306
-
"postcss-merge-longhand": ["postcss-merge-longhand@7.0.5", "", { "dependencies": { "postcss-value-parser": "^4.2.0", "stylehacks": "^7.0.5" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-Kpu5v4Ys6QI59FxmxtNB/iHUVDn9Y9sYw66D6+SZoIk4QTz1prC4aYkhIESu+ieG1iylod1f8MILMs1Em3mmIw=="],
1307
-
1308
-
"postcss-merge-rules": ["postcss-merge-rules@7.0.7", "", { "dependencies": { "browserslist": "^4.27.0", "caniuse-api": "^3.0.0", "cssnano-utils": "^5.0.1", "postcss-selector-parser": "^7.1.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-njWJrd/Ms6XViwowaaCc+/vqhPG3SmXn725AGrnl+BgTuRPEacjiLEaGq16J6XirMJbtKkTwnt67SS+e2WGoew=="],
1309
-
1310
-
"postcss-minify-font-values": ["postcss-minify-font-values@7.0.1", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-2m1uiuJeTplll+tq4ENOQSzB8LRnSUChBv7oSyFLsJRtUgAAJGP6LLz0/8lkinTgxrmJSPOEhgY1bMXOQ4ZXhQ=="],
1311
-
1312
-
"postcss-minify-gradients": ["postcss-minify-gradients@7.0.1", "", { "dependencies": { "colord": "^2.9.3", "cssnano-utils": "^5.0.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-X9JjaysZJwlqNkJbUDgOclyG3jZEpAMOfof6PUZjPnPrePnPG62pS17CjdM32uT1Uq1jFvNSff9l7kNbmMSL2A=="],
1313
-
1314
-
"postcss-minify-params": ["postcss-minify-params@7.0.5", "", { "dependencies": { "browserslist": "^4.27.0", "cssnano-utils": "^5.0.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-FGK9ky02h6Ighn3UihsyeAH5XmLEE2MSGH5Tc4tXMFtEDx7B+zTG6hD/+/cT+fbF7PbYojsmmWjyTwFwW1JKQQ=="],
1315
-
1316
-
"postcss-minify-selectors": ["postcss-minify-selectors@7.0.5", "", { "dependencies": { "cssesc": "^3.0.0", "postcss-selector-parser": "^7.1.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-x2/IvofHcdIrAm9Q+p06ZD1h6FPcQ32WtCRVodJLDR+WMn8EVHI1kvLxZuGKz/9EY5nAmI6lIQIrpo4tBy5+ug=="],
1317
-
1318
-
"postcss-nested": ["postcss-nested@6.2.0", "", { "dependencies": { "postcss-selector-parser": "^6.1.1" }, "peerDependencies": { "postcss": "^8.2.14" } }, "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ=="],
1319
-
1320
-
"postcss-normalize-charset": ["postcss-normalize-charset@7.0.1", "", { "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-sn413ofhSQHlZFae//m9FTOfkmiZ+YQXsbosqOWRiVQncU2BA3daX3n0VF3cG6rGLSFVc5Di/yns0dFfh8NFgQ=="],
1321
-
1322
-
"postcss-normalize-display-values": ["postcss-normalize-display-values@7.0.1", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-E5nnB26XjSYz/mGITm6JgiDpAbVuAkzXwLzRZtts19jHDUBFxZ0BkXAehy0uimrOjYJbocby4FVswA/5noOxrQ=="],
1323
-
1324
-
"postcss-normalize-positions": ["postcss-normalize-positions@7.0.1", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-pB/SzrIP2l50ZIYu+yQZyMNmnAcwyYb9R1fVWPRxm4zcUFCY2ign7rcntGFuMXDdd9L2pPNUgoODDk91PzRZuQ=="],
1325
-
1326
-
"postcss-normalize-repeat-style": ["postcss-normalize-repeat-style@7.0.1", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-NsSQJ8zj8TIDiF0ig44Byo3Jk9e4gNt9x2VIlJudnQQ5DhWAHJPF4Tr1ITwyHio2BUi/I6Iv0HRO7beHYOloYQ=="],
1327
-
1328
-
"postcss-normalize-string": ["postcss-normalize-string@7.0.1", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-QByrI7hAhsoze992kpbMlJSbZ8FuCEc1OT9EFbZ6HldXNpsdpZr+YXC5di3UEv0+jeZlHbZcoCADgb7a+lPmmQ=="],
1329
-
1330
-
"postcss-normalize-timing-functions": ["postcss-normalize-timing-functions@7.0.1", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-bHifyuuSNdKKsnNJ0s8fmfLMlvsQwYVxIoUBnowIVl2ZAdrkYQNGVB4RxjfpvkMjipqvbz0u7feBZybkl/6NJg=="],
1331
-
1332
-
"postcss-normalize-unicode": ["postcss-normalize-unicode@7.0.5", "", { "dependencies": { "browserslist": "^4.27.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-X6BBwiRxVaFHrb2WyBMddIeB5HBjJcAaUHyhLrM2FsxSq5TFqcHSsK7Zu1otag+o0ZphQGJewGH1tAyrD0zX1Q=="],
1333
-
1334
-
"postcss-normalize-url": ["postcss-normalize-url@7.0.1", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-sUcD2cWtyK1AOL/82Fwy1aIVm/wwj5SdZkgZ3QiUzSzQQofrbq15jWJ3BA7Z+yVRwamCjJgZJN0I9IS7c6tgeQ=="],
1335
-
1336
-
"postcss-normalize-whitespace": ["postcss-normalize-whitespace@7.0.1", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-vsbgFHMFQrJBJKrUFJNZ2pgBeBkC2IvvoHjz1to0/0Xk7sII24T0qFOiJzG6Fu3zJoq/0yI4rKWi7WhApW+EFA=="],
1337
-
1338
-
"postcss-ordered-values": ["postcss-ordered-values@7.0.2", "", { "dependencies": { "cssnano-utils": "^5.0.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-AMJjt1ECBffF7CEON/Y0rekRLS6KsePU6PRP08UqYW4UGFRnTXNrByUzYK1h8AC7UWTZdQ9O3Oq9kFIhm0SFEw=="],
1339
-
1340
-
"postcss-reduce-initial": ["postcss-reduce-initial@7.0.5", "", { "dependencies": { "browserslist": "^4.27.0", "caniuse-api": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-RHagHLidG8hTZcnr4FpyMB2jtgd/OcyAazjMhoy5qmWJOx1uxKh4ntk0Pb46ajKM0rkf32lRH4C8c9qQiPR6IA=="],
1341
-
1342
-
"postcss-reduce-transforms": ["postcss-reduce-transforms@7.0.1", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-MhyEbfrm+Mlp/36hvZ9mT9DaO7dbncU0CvWI8V93LRkY6IYlu38OPg3FObnuKTUxJ4qA8HpurdQOo5CyqqO76g=="],
1343
-
1344
-
"postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="],
1345
-
1346
-
"postcss-svgo": ["postcss-svgo@7.1.0", "", { "dependencies": { "postcss-value-parser": "^4.2.0", "svgo": "^4.0.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-KnAlfmhtoLz6IuU3Sij2ycusNs4jPW+QoFE5kuuUOK8awR6tMxZQrs5Ey3BUz7nFCzT3eqyFgqkyrHiaU2xx3w=="],
1347
-
1348
-
"postcss-unique-selectors": ["postcss-unique-selectors@7.0.4", "", { "dependencies": { "postcss-selector-parser": "^7.1.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-pmlZjsmEAG7cHd7uK3ZiNSW6otSZ13RHuZ/4cDN/bVglS5EpF2r2oxY99SuOHa8m7AWoBCelTS3JPpzsIs8skQ=="],
1349
-
1350
-
"postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="],
1351
-
1352
1582
"postgres-array": ["postgres-array@2.0.0", "", {}, "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA=="],
1353
1583
1354
1584
"postgres-bytea": ["postgres-bytea@1.0.0", "", {}, "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w=="],
···
1361
1591
1362
1592
"prettier": ["prettier@3.6.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ=="],
1363
1593
1364
-
"process": ["process@0.11.10", "", {}, "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A=="],
1365
-
1366
1594
"process-warning": ["process-warning@5.0.0", "", {}, "sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA=="],
1367
1595
1368
1596
"promise-limit": ["promise-limit@2.7.0", "", {}, "sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw=="],
1369
1597
1370
-
"proxy-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="],
1598
+
"prop-types": ["prop-types@15.8.1", "", { "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg=="],
1371
1599
1372
1600
"pump": ["pump@3.0.3", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA=="],
1373
1601
···
1377
1605
1378
1606
"quick-format-unescaped": ["quick-format-unescaped@4.0.4", "", {}, "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg=="],
1379
1607
1380
-
"react": ["react@19.0.0", "", {}, "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ=="],
1608
+
"react": ["react@19.2.0", "", {}, "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ=="],
1609
+
1610
+
"react-dom": ["react-dom@19.2.0", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.0" } }, "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ=="],
1381
1611
1382
-
"react-dom": ["react-dom@19.0.0", "", { "dependencies": { "scheduler": "^0.25.0" }, "peerDependencies": { "react": "^19.0.0" } }, "sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ=="],
1612
+
"react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="],
1383
1613
1384
-
"react-hook-form": ["react-hook-form@7.66.1", "", { "peerDependencies": { "react": "^16.8.0 || ^17 || ^18 || ^19" } }, "sha512-2KnjpgG2Rhbi+CIiIBQQ9Df6sMGH5ExNyFl4Hw9qO7pIqMBR8Bvu9RQyjl3JM4vehzCh9soiNUM/xYMswb2EiA=="],
1614
+
"react-refresh": ["react-refresh@0.18.0", "", {}, "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw=="],
1385
1615
1386
1616
"react-remove-scroll": ["react-remove-scroll@2.7.1", "", { "dependencies": { "react-remove-scroll-bar": "^2.3.7", "react-style-singleton": "^2.2.3", "tslib": "^2.1.0", "use-callback-ref": "^1.3.3", "use-sidecar": "^1.1.3" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA=="],
1387
1617
···
1389
1619
1390
1620
"react-style-singleton": ["react-style-singleton@2.2.3", "", { "dependencies": { "get-nonce": "^1.0.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ=="],
1391
1621
1392
-
"read-cache": ["read-cache@1.0.0", "", { "dependencies": { "pify": "^2.3.0" } }, "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA=="],
1622
+
"readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="],
1393
1623
1394
-
"readable-stream": ["readable-stream@4.7.0", "", { "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", "process": "^0.11.10", "string_decoder": "^1.3.0" } }, "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg=="],
1624
+
"real-require": ["real-require@0.2.0", "", {}, "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg=="],
1625
+
1626
+
"recast": ["recast@0.23.11", "", { "dependencies": { "ast-types": "^0.16.1", "esprima": "~4.0.0", "source-map": "~0.6.1", "tiny-invariant": "^1.3.3", "tslib": "^2.0.1" } }, "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA=="],
1395
1627
1396
-
"readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="],
1628
+
"reflect.getprototypeof": ["reflect.getprototypeof@1.0.10", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.9", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.7", "get-proto": "^1.0.1", "which-builtin-type": "^1.2.1" } }, "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw=="],
1397
1629
1398
-
"real-require": ["real-require@0.2.0", "", {}, "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg=="],
1630
+
"regexp.prototype.flags": ["regexp.prototype.flags@1.5.4", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-errors": "^1.3.0", "get-proto": "^1.0.1", "gopd": "^1.2.0", "set-function-name": "^2.0.2" } }, "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA=="],
1399
1631
1400
-
"recast": ["recast@0.23.11", "", { "dependencies": { "ast-types": "^0.16.1", "esprima": "~4.0.0", "source-map": "~0.6.1", "tiny-invariant": "^1.3.3", "tslib": "^2.0.1" } }, "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA=="],
1632
+
"require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="],
1401
1633
1402
1634
"require-in-the-middle": ["require-in-the-middle@7.5.2", "", { "dependencies": { "debug": "^4.3.5", "module-details-from-path": "^1.0.3", "resolve": "^1.22.8" } }, "sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ=="],
1403
1635
1404
1636
"resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="],
1405
1637
1406
-
"resolve-from": ["resolve-from@5.0.0", "", {}, "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="],
1638
+
"resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="],
1407
1639
1408
1640
"resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="],
1409
1641
···
1411
1643
1412
1644
"rimraf": ["rimraf@6.1.2", "", { "dependencies": { "glob": "^13.0.0", "package-json-from-dist": "^1.0.1" }, "bin": { "rimraf": "dist/esm/bin.mjs" } }, "sha512-cFCkPslJv7BAXJsYlK1dZsbP8/ZNLkCAQ0bi1hf5EKX2QHegmDFEFA6QhuYJlk7UDdc+02JjO80YSOrWPpw06g=="],
1413
1645
1414
-
"rollup": ["rollup@4.53.3", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.53.3", "@rollup/rollup-android-arm64": "4.53.3", "@rollup/rollup-darwin-arm64": "4.53.3", "@rollup/rollup-darwin-x64": "4.53.3", "@rollup/rollup-freebsd-arm64": "4.53.3", "@rollup/rollup-freebsd-x64": "4.53.3", "@rollup/rollup-linux-arm-gnueabihf": "4.53.3", "@rollup/rollup-linux-arm-musleabihf": "4.53.3", "@rollup/rollup-linux-arm64-gnu": "4.53.3", "@rollup/rollup-linux-arm64-musl": "4.53.3", "@rollup/rollup-linux-loong64-gnu": "4.53.3", "@rollup/rollup-linux-ppc64-gnu": "4.53.3", "@rollup/rollup-linux-riscv64-gnu": "4.53.3", "@rollup/rollup-linux-riscv64-musl": "4.53.3", "@rollup/rollup-linux-s390x-gnu": "4.53.3", "@rollup/rollup-linux-x64-gnu": "4.53.3", "@rollup/rollup-linux-x64-musl": "4.53.3", "@rollup/rollup-openharmony-arm64": "4.53.3", "@rollup/rollup-win32-arm64-msvc": "4.53.3", "@rollup/rollup-win32-ia32-msvc": "4.53.3", "@rollup/rollup-win32-x64-gnu": "4.53.3", "@rollup/rollup-win32-x64-msvc": "4.53.3", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA=="],
1646
+
"rolldown": ["rolldown@1.0.0-beta.50", "", { "dependencies": { "@oxc-project/types": "=0.97.0", "@rolldown/pluginutils": "1.0.0-beta.50" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-beta.50", "@rolldown/binding-darwin-arm64": "1.0.0-beta.50", "@rolldown/binding-darwin-x64": "1.0.0-beta.50", "@rolldown/binding-freebsd-x64": "1.0.0-beta.50", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-beta.50", "@rolldown/binding-linux-arm64-gnu": "1.0.0-beta.50", "@rolldown/binding-linux-arm64-musl": "1.0.0-beta.50", "@rolldown/binding-linux-x64-gnu": "1.0.0-beta.50", "@rolldown/binding-linux-x64-musl": "1.0.0-beta.50", "@rolldown/binding-openharmony-arm64": "1.0.0-beta.50", "@rolldown/binding-wasm32-wasi": "1.0.0-beta.50", "@rolldown/binding-win32-arm64-msvc": "1.0.0-beta.50", "@rolldown/binding-win32-ia32-msvc": "1.0.0-beta.50", "@rolldown/binding-win32-x64-msvc": "1.0.0-beta.50" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-JFULvCNl/anKn99eKjOSEubi0lLmNqQDAjyEMME2T4CwezUDL0i6t1O9xZsu2OMehPnV2caNefWpGF+8TnzB6A=="],
1415
1647
1416
1648
"run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="],
1417
1649
1418
-
"safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
1650
+
"safe-array-concat": ["safe-array-concat@1.1.3", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", "get-intrinsic": "^1.2.6", "has-symbols": "^1.1.0", "isarray": "^2.0.5" } }, "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q=="],
1651
+
1652
+
"safe-push-apply": ["safe-push-apply@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "isarray": "^2.0.5" } }, "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA=="],
1653
+
1654
+
"safe-regex-test": ["safe-regex-test@1.1.0", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-regex": "^1.2.1" } }, "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw=="],
1419
1655
1420
1656
"safe-stable-stringify": ["safe-stable-stringify@2.5.0", "", {}, "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA=="],
1421
1657
1422
-
"sax": ["sax@1.4.3", "", {}, "sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ=="],
1658
+
"safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
1423
1659
1424
-
"scheduler": ["scheduler@0.25.0", "", {}, "sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA=="],
1660
+
"scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="],
1425
1661
1426
1662
"secure-json-parse": ["secure-json-parse@4.1.0", "", {}, "sha512-l4KnYfEyqYJxDwlNVyRfO2E4NTHfMKAWdUuA8J0yve2Dz/E/PdBepY03RvyJpssIpRFwJoCD55wA+mEDs6ByWA=="],
1427
1663
···
1431
1667
1432
1668
"seroval-plugins": ["seroval-plugins@1.4.0", "", { "peerDependencies": { "seroval": "^1.0" } }, "sha512-zir1aWzoiax6pbBVjoYVd0O1QQXgIL3eVGBMsBsNmM8Ukq90yGaWlfx0AB9dTS8GPqrOrbXn79vmItCUP9U3BQ=="],
1433
1669
1670
+
"set-function-length": ["set-function-length@1.2.2", "", { "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2" } }, "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg=="],
1671
+
1672
+
"set-function-name": ["set-function-name@2.0.2", "", { "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "functions-have-names": "^1.2.3", "has-property-descriptors": "^1.0.2" } }, "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ=="],
1673
+
1674
+
"set-proto": ["set-proto@1.0.0", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0" } }, "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw=="],
1675
+
1676
+
"sharp": ["sharp@0.34.5", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", "semver": "^7.7.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.5", "@img/sharp-darwin-x64": "0.34.5", "@img/sharp-libvips-darwin-arm64": "1.2.4", "@img/sharp-libvips-darwin-x64": "1.2.4", "@img/sharp-libvips-linux-arm": "1.2.4", "@img/sharp-libvips-linux-arm64": "1.2.4", "@img/sharp-libvips-linux-ppc64": "1.2.4", "@img/sharp-libvips-linux-riscv64": "1.2.4", "@img/sharp-libvips-linux-s390x": "1.2.4", "@img/sharp-libvips-linux-x64": "1.2.4", "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", "@img/sharp-libvips-linuxmusl-x64": "1.2.4", "@img/sharp-linux-arm": "0.34.5", "@img/sharp-linux-arm64": "0.34.5", "@img/sharp-linux-ppc64": "0.34.5", "@img/sharp-linux-riscv64": "0.34.5", "@img/sharp-linux-s390x": "0.34.5", "@img/sharp-linux-x64": "0.34.5", "@img/sharp-linuxmusl-arm64": "0.34.5", "@img/sharp-linuxmusl-x64": "0.34.5", "@img/sharp-wasm32": "0.34.5", "@img/sharp-win32-arm64": "0.34.5", "@img/sharp-win32-ia32": "0.34.5", "@img/sharp-win32-x64": "0.34.5" } }, "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg=="],
1677
+
1434
1678
"shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
1435
1679
1436
1680
"shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
1437
1681
1438
1682
"shimmer": ["shimmer@1.2.1", "", {}, "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw=="],
1439
1683
1684
+
"side-channel": ["side-channel@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="],
1685
+
1686
+
"side-channel-list": ["side-channel-list@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" } }, "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA=="],
1687
+
1688
+
"side-channel-map": ["side-channel-map@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" } }, "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA=="],
1689
+
1690
+
"side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="],
1691
+
1692
+
"signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="],
1693
+
1694
+
"slash": ["slash@5.1.0", "", {}, "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg=="],
1695
+
1440
1696
"solid-js": ["solid-js@1.9.10", "", { "dependencies": { "csstype": "^3.1.0", "seroval": "~1.3.0", "seroval-plugins": "~1.3.0" } }, "sha512-Coz956cos/EPDlhs6+jsdTxKuJDPT7B5SVIWgABwROyxjY7Xbr8wkzD68Et+NxnV7DLJ3nJdAC2r9InuV/4Jew=="],
1441
1697
1442
1698
"sonic-boom": ["sonic-boom@4.2.0", "", { "dependencies": { "atomic-sleep": "^1.0.0" } }, "sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww=="],
···
1449
1705
1450
1706
"split2": ["split2@4.2.0", "", {}, "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg=="],
1451
1707
1452
-
"string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="],
1708
+
"stable-hash": ["stable-hash@0.0.5", "", {}, "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA=="],
1453
1709
1454
-
"strip-json-comments": ["strip-json-comments@5.0.3", "", {}, "sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw=="],
1710
+
"stop-iteration-iterator": ["stop-iteration-iterator@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "internal-slot": "^1.1.0" } }, "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ=="],
1455
1711
1456
-
"stylehacks": ["stylehacks@7.0.7", "", { "dependencies": { "browserslist": "^4.27.0", "postcss-selector-parser": "^7.1.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-bJkD0JkEtbRrMFtwgpJyBbFIwfDDONQ1Ov3sDLZQP8HuJ73kBOyx66H4bOcAbVWmnfLdvQ0AJwXxOMkpujcO6g=="],
1712
+
"string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="],
1713
+
1714
+
"string.prototype.includes": ["string.prototype.includes@2.0.1", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.3" } }, "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg=="],
1715
+
1716
+
"string.prototype.matchall": ["string.prototype.matchall@4.0.12", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-abstract": "^1.23.6", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.6", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "internal-slot": "^1.1.0", "regexp.prototype.flags": "^1.5.3", "set-function-name": "^2.0.2", "side-channel": "^1.1.0" } }, "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA=="],
1717
+
1718
+
"string.prototype.repeat": ["string.prototype.repeat@1.0.0", "", { "dependencies": { "define-properties": "^1.1.3", "es-abstract": "^1.17.5" } }, "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w=="],
1719
+
1720
+
"string.prototype.trim": ["string.prototype.trim@1.2.10", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", "define-data-property": "^1.1.4", "define-properties": "^1.2.1", "es-abstract": "^1.23.5", "es-object-atoms": "^1.0.0", "has-property-descriptors": "^1.0.2" } }, "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA=="],
1721
+
1722
+
"string.prototype.trimend": ["string.prototype.trimend@1.0.9", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" } }, "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ=="],
1723
+
1724
+
"string.prototype.trimstart": ["string.prototype.trimstart@1.0.8", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" } }, "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg=="],
1725
+
1726
+
"strip-ansi": ["strip-ansi@7.1.2", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="],
1727
+
1728
+
"strip-bom": ["strip-bom@3.0.0", "", {}, "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA=="],
1729
+
1730
+
"strip-json-comments": ["strip-json-comments@5.0.3", "", {}, "sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw=="],
1457
1731
1458
-
"sucrase": ["sucrase@3.35.1", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", "lines-and-columns": "^1.1.6", "mz": "^2.7.0", "pirates": "^4.0.1", "tinyglobby": "^0.2.11", "ts-interface-checker": "^0.1.9" }, "bin": { "sucrase": "bin/sucrase", "sucrase-node": "bin/sucrase-node" } }, "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw=="],
1732
+
"styled-jsx": ["styled-jsx@5.1.6", "", { "dependencies": { "client-only": "0.0.1" }, "peerDependencies": { "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" } }, "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA=="],
1459
1733
1460
1734
"supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
1461
1735
1462
1736
"supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="],
1463
1737
1464
-
"svgo": ["svgo@4.0.0", "", { "dependencies": { "commander": "^11.1.0", "css-select": "^5.1.0", "css-tree": "^3.0.1", "css-what": "^6.1.0", "csso": "^5.0.5", "picocolors": "^1.1.1", "sax": "^1.4.1" }, "bin": "./bin/svgo.js" }, "sha512-VvrHQ+9uniE+Mvx3+C9IEe/lWasXCU0nXMY2kZeLrHNICuRiC8uMPyM14UEaMOFA5mhyQqEkB02VoQ16n3DLaw=="],
1738
+
"tailwind-merge": ["tailwind-merge@3.4.0", "", {}, "sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g=="],
1465
1739
1466
-
"tailwind-merge": ["tailwind-merge@2.6.0", "", {}, "sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA=="],
1740
+
"tailwindcss": ["tailwindcss@4.1.17", "", {}, "sha512-j9Ee2YjuQqYT9bbRTfTZht9W/ytp5H+jJpZKiYdP/bpnXARAuELt9ofP0lPnmHjbga7SNQIxdTAXCmtKVYjN+Q=="],
1467
1741
1468
-
"tailwindcss": ["tailwindcss@3.4.18", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", "chokidar": "^3.6.0", "didyoumean": "^1.2.2", "dlv": "^1.1.3", "fast-glob": "^3.3.2", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", "jiti": "^1.21.7", "lilconfig": "^3.1.3", "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "object-hash": "^3.0.0", "picocolors": "^1.1.1", "postcss": "^8.4.47", "postcss-import": "^15.1.0", "postcss-js": "^4.0.1", "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0", "postcss-nested": "^6.2.0", "postcss-selector-parser": "^6.1.2", "resolve": "^1.22.8", "sucrase": "^3.35.0" }, "bin": { "tailwind": "lib/cli.js", "tailwindcss": "lib/cli.js" } }, "sha512-6A2rnmW5xZMdw11LYjhcI5846rt9pbLSabY5XPxo+XWdxwZaFEn47Go4NzFiHu9sNNmr/kXivP1vStfvMaK1GQ=="],
1742
+
"tapable": ["tapable@2.3.0", "", {}, "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg=="],
1469
1743
1470
-
"tailwindcss-animate": ["tailwindcss-animate@1.0.7", "", { "peerDependencies": { "tailwindcss": ">=3.0.0 || insiders" } }, "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA=="],
1744
+
"tar": ["tar@7.5.2", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.1.0", "yallist": "^5.0.0" } }, "sha512-7NyxrTE4Anh8km8iEy7o0QYPs+0JKBTj5ZaqHg6B39erLg0qYXN3BijtShwbsNSvQ+LN75+KV+C4QR/f6Gwnpg=="],
1471
1745
1472
-
"thenify": ["thenify@3.3.1", "", { "dependencies": { "any-promise": "^1.0.0" } }, "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw=="],
1746
+
"temporal-polyfill": ["temporal-polyfill@0.3.0", "", { "dependencies": { "temporal-spec": "0.3.0" } }, "sha512-qNsTkX9K8hi+FHDfHmf22e/OGuXmfBm9RqNismxBrnSmZVJKegQ+HYYXT+R7Ha8F/YSm2Y34vmzD4cxMu2u95g=="],
1473
1747
1474
-
"thenify-all": ["thenify-all@1.6.0", "", { "dependencies": { "thenify": ">= 3.1.0 < 4" } }, "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA=="],
1748
+
"temporal-spec": ["temporal-spec@0.3.0", "", {}, "sha512-n+noVpIqz4hYgFSMOSiINNOUOMFtV5cZQNCmmszA6GiVFVRt3G7AqVyhXjhCSmowvQn+NsGn+jMDMKJYHd3bSQ=="],
1475
1749
1476
1750
"thread-stream": ["thread-stream@3.1.0", "", { "dependencies": { "real-require": "^0.2.0" } }, "sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A=="],
1477
-
1478
-
"tiny-emitter": ["tiny-emitter@2.1.0", "", {}, "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q=="],
1479
1751
1480
1752
"tiny-invariant": ["tiny-invariant@1.3.3", "", {}, "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="],
1481
1753
1482
1754
"tiny-warning": ["tiny-warning@1.0.3", "", {}, "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="],
1483
1755
1484
-
"tinyexec": ["tinyexec@0.3.2", "", {}, "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA=="],
1485
-
1486
1756
"tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="],
1487
-
1488
-
"tlds": ["tlds@1.261.0", "", { "bin": { "tlds": "bin.js" } }, "sha512-QXqwfEl9ddlGBaRFXIvNKK6OhipSiLXuRuLJX5DErz0o0Q0rYxulWLdFryTkV5PkdZct5iMInwYEGe/eR++1AA=="],
1489
1757
1490
1758
"to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
1491
1759
1492
-
"tree-kill": ["tree-kill@1.2.2", "", { "bin": { "tree-kill": "cli.js" } }, "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A=="],
1493
-
1494
1760
"ts-api-utils": ["ts-api-utils@2.1.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ=="],
1495
1761
1496
-
"ts-interface-checker": ["ts-interface-checker@0.1.13", "", {}, "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="],
1497
-
1498
-
"ts-node": ["ts-node@10.9.2", "", { "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", "@tsconfig/node12": "^1.0.7", "@tsconfig/node14": "^1.0.0", "@tsconfig/node16": "^1.0.2", "acorn": "^8.4.1", "acorn-walk": "^8.1.1", "arg": "^4.1.0", "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", "v8-compile-cache-lib": "^3.0.1", "yn": "3.1.1" }, "peerDependencies": { "@swc/core": ">=1.2.50", "@swc/wasm": ">=1.2.50", "@types/node": "*", "typescript": ">=2.7" }, "optionalPeers": ["@swc/core", "@swc/wasm"], "bin": { "ts-node": "dist/bin.js", "ts-script": "dist/bin-script-deprecated.js", "ts-node-cwd": "dist/bin-cwd.js", "ts-node-esm": "dist/bin-esm.js", "ts-node-script": "dist/bin-script.js", "ts-node-transpile-only": "dist/bin-transpile.js" } }, "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ=="],
1762
+
"tsconfig-paths": ["tsconfig-paths@3.15.0", "", { "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } }, "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg=="],
1499
1763
1500
1764
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
1501
1765
1502
-
"tsup": ["tsup@8.5.1", "", { "dependencies": { "bundle-require": "^5.1.0", "cac": "^6.7.14", "chokidar": "^4.0.3", "consola": "^3.4.0", "debug": "^4.4.0", "esbuild": "^0.27.0", "fix-dts-default-cjs-exports": "^1.0.0", "joycon": "^3.1.1", "picocolors": "^1.1.1", "postcss-load-config": "^6.0.1", "resolve-from": "^5.0.0", "rollup": "^4.34.8", "source-map": "^0.7.6", "sucrase": "^3.35.0", "tinyexec": "^0.3.2", "tinyglobby": "^0.2.11", "tree-kill": "^1.2.2" }, "peerDependencies": { "@microsoft/api-extractor": "^7.36.0", "@swc/core": "^1", "postcss": "^8.4.12", "typescript": ">=4.5.0" }, "optionalPeers": ["@microsoft/api-extractor", "@swc/core", "postcss", "typescript"], "bin": { "tsup": "dist/cli-default.js", "tsup-node": "dist/cli-node.js" } }, "sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing=="],
1503
-
1504
-
"tsx": ["tsx@4.20.6", "", { "dependencies": { "esbuild": "~0.25.0", "get-tsconfig": "^4.7.5" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "bin": { "tsx": "dist/cli.mjs" } }, "sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg=="],
1766
+
"tsx": ["tsx@4.21.0", "", { "dependencies": { "esbuild": "~0.27.0", "get-tsconfig": "^4.7.5" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "bin": { "tsx": "dist/cli.mjs" } }, "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw=="],
1505
1767
1506
1768
"turbo": ["turbo@2.6.1", "", { "optionalDependencies": { "turbo-darwin-64": "2.6.1", "turbo-darwin-arm64": "2.6.1", "turbo-linux-64": "2.6.1", "turbo-linux-arm64": "2.6.1", "turbo-windows-64": "2.6.1", "turbo-windows-arm64": "2.6.1" }, "bin": { "turbo": "bin/turbo" } }, "sha512-qBwXXuDT3rA53kbNafGbT5r++BrhRgx3sAo0cHoDAeG9g1ItTmUMgltz3Hy7Hazy1ODqNpR+C7QwqL6DYB52yA=="],
1507
1769
···
1517
1779
1518
1780
"turbo-windows-arm64": ["turbo-windows-arm64@2.6.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-7w+AD5vJp3R+FB0YOj1YJcNcOOvBior7bcHTodqp90S3x3bLgpr7tE6xOea1e8JkP7GK6ciKVUpQvV7psiwU5Q=="],
1519
1781
1782
+
"tw-animate-css": ["tw-animate-css@1.4.0", "", {}, "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ=="],
1783
+
1520
1784
"type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
1521
1785
1786
+
"type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="],
1787
+
1788
+
"typed-array-buffer": ["typed-array-buffer@1.0.3", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-typed-array": "^1.1.14" } }, "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw=="],
1789
+
1790
+
"typed-array-byte-length": ["typed-array-byte-length@1.0.3", "", { "dependencies": { "call-bind": "^1.0.8", "for-each": "^0.3.3", "gopd": "^1.2.0", "has-proto": "^1.2.0", "is-typed-array": "^1.1.14" } }, "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg=="],
1791
+
1792
+
"typed-array-byte-offset": ["typed-array-byte-offset@1.0.4", "", { "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "for-each": "^0.3.3", "gopd": "^1.2.0", "has-proto": "^1.2.0", "is-typed-array": "^1.1.15", "reflect.getprototypeof": "^1.0.9" } }, "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ=="],
1793
+
1794
+
"typed-array-length": ["typed-array-length@1.0.7", "", { "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", "is-typed-array": "^1.1.13", "possible-typed-array-names": "^1.0.0", "reflect.getprototypeof": "^1.0.6" } }, "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg=="],
1795
+
1522
1796
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
1523
1797
1524
-
"typescript-eslint": ["typescript-eslint@8.47.0", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.47.0", "@typescript-eslint/parser": "8.47.0", "@typescript-eslint/typescript-estree": "8.47.0", "@typescript-eslint/utils": "8.47.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-Lwe8i2XQ3WoMjua/r1PHrCTpkubPYJCAfOurtn+mtTzqB6jNd+14n9UN1bJ4s3F49x9ixAm0FLflB/JzQ57M8Q=="],
1798
+
"typescript-eslint": ["typescript-eslint@8.48.0", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.48.0", "@typescript-eslint/parser": "8.48.0", "@typescript-eslint/typescript-estree": "8.48.0", "@typescript-eslint/utils": "8.48.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-fcKOvQD9GUn3Xw63EgiDqhvWJ5jsyZUaekl3KVpGsDJnN46WJTe3jWxtQP9lMZm1LJNkFLlTaWAxK2vUQR+cqw=="],
1525
1799
1526
-
"ufo": ["ufo@1.6.1", "", {}, "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA=="],
1800
+
"uint8arrays": ["uint8arrays@3.0.0", "", { "dependencies": { "multiformats": "^9.4.2" } }, "sha512-HRCx0q6O9Bfbp+HHSfQQKD7wU70+lydKVt4EghkdOvlK/NlrF90z+eXV34mUd48rNvVJXwkrMSPpCATkct8fJA=="],
1527
1801
1528
-
"uint8arrays": ["uint8arrays@5.1.0", "", { "dependencies": { "multiformats": "^13.0.0" } }, "sha512-vA6nFepEmlSKkMBnLBaUMVvAC4G3CTmO58C12y4sq6WPDOR7mOFYOi7GlrQ4djeSbP6JG9Pv9tJDM97PedRSww=="],
1802
+
"unbox-primitive": ["unbox-primitive@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "has-bigints": "^1.0.2", "has-symbols": "^1.1.0", "which-boxed-primitive": "^1.1.1" } }, "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw=="],
1529
1803
1530
1804
"undici": ["undici@6.22.0", "", {}, "sha512-hU/10obOIu62MGYjdskASR3CUAiYaFTtC9Pa6vHyf//mAipSvSQg6od2CnJswq7fvzNS3zJhxoRkgNVaHurWKw=="],
1531
1805
1532
1806
"undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
1533
1807
1808
+
"unicode-segmenter": ["unicode-segmenter@0.14.1", "", {}, "sha512-yHedxlEpUyD+u1UE8qAuCMXVdMLn7yUdlmd8WN7FGmO1ICnpE7LJfnmuXBB+T0zkie3qHsy8fSucqceI/MylOg=="],
1809
+
1810
+
"unicorn-magic": ["unicorn-magic@0.3.0", "", {}, "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA=="],
1811
+
1534
1812
"unplugin": ["unplugin@2.3.11", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "acorn": "^8.15.0", "picomatch": "^4.0.3", "webpack-virtual-modules": "^0.6.2" } }, "sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww=="],
1813
+
1814
+
"unrs-resolver": ["unrs-resolver@1.11.1", "", { "dependencies": { "napi-postinstall": "^0.3.0" }, "optionalDependencies": { "@unrs/resolver-binding-android-arm-eabi": "1.11.1", "@unrs/resolver-binding-android-arm64": "1.11.1", "@unrs/resolver-binding-darwin-arm64": "1.11.1", "@unrs/resolver-binding-darwin-x64": "1.11.1", "@unrs/resolver-binding-freebsd-x64": "1.11.1", "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", "@unrs/resolver-binding-linux-x64-musl": "1.11.1", "@unrs/resolver-binding-wasm32-wasi": "1.11.1", "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" } }, "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg=="],
1535
1815
1536
1816
"update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
1537
1817
···
1543
1823
1544
1824
"use-sync-external-store": ["use-sync-external-store@1.6.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w=="],
1545
1825
1546
-
"util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
1826
+
"vite": ["rolldown-vite@7.2.5", "", { "dependencies": { "@oxc-project/runtime": "0.97.0", "fdir": "^6.5.0", "lightningcss": "^1.30.2", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rolldown": "1.0.0-beta.50", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "esbuild": "^0.25.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-u09tdk/huMiN8xwoiBbig197jKdCamQTtOruSalOzbqGje3jdHiV0njQlAW0YvzoahkirFePNQ4RYlfnRQpXZA=="],
1547
1827
1548
-
"v8-compile-cache-lib": ["v8-compile-cache-lib@3.0.1", "", {}, "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg=="],
1828
+
"vscode-jsonrpc": ["vscode-jsonrpc@8.2.0", "", {}, "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA=="],
1549
1829
1550
-
"vite": ["vite@6.4.1", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g=="],
1830
+
"vscode-languageserver": ["vscode-languageserver@9.0.1", "", { "dependencies": { "vscode-languageserver-protocol": "3.17.5" }, "bin": { "installServerIntoExtension": "bin/installServerIntoExtension" } }, "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g=="],
1831
+
1832
+
"vscode-languageserver-protocol": ["vscode-languageserver-protocol@3.17.5", "", { "dependencies": { "vscode-jsonrpc": "8.2.0", "vscode-languageserver-types": "3.17.5" } }, "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg=="],
1833
+
1834
+
"vscode-languageserver-textdocument": ["vscode-languageserver-textdocument@1.0.12", "", {}, "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA=="],
1835
+
1836
+
"vscode-languageserver-types": ["vscode-languageserver-types@3.17.5", "", {}, "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg=="],
1837
+
1838
+
"web": ["web@workspace:apps/web"],
1551
1839
1552
1840
"web-streams-polyfill": ["web-streams-polyfill@3.3.3", "", {}, "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw=="],
1553
1841
···
1555
1843
1556
1844
"which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
1557
1845
1558
-
"word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="],
1846
+
"which-boxed-primitive": ["which-boxed-primitive@1.1.1", "", { "dependencies": { "is-bigint": "^1.1.0", "is-boolean-object": "^1.2.1", "is-number-object": "^1.1.1", "is-string": "^1.1.1", "is-symbol": "^1.1.1" } }, "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA=="],
1559
1847
1560
-
"wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="],
1848
+
"which-builtin-type": ["which-builtin-type@1.2.1", "", { "dependencies": { "call-bound": "^1.0.2", "function.prototype.name": "^1.1.6", "has-tostringtag": "^1.0.2", "is-async-function": "^2.0.0", "is-date-object": "^1.1.0", "is-finalizationregistry": "^1.1.0", "is-generator-function": "^1.0.10", "is-regex": "^1.2.1", "is-weakref": "^1.0.2", "isarray": "^2.0.5", "which-boxed-primitive": "^1.1.0", "which-collection": "^1.0.2", "which-typed-array": "^1.1.16" } }, "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q=="],
1561
1849
1562
-
"ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="],
1850
+
"which-collection": ["which-collection@1.0.2", "", { "dependencies": { "is-map": "^2.0.3", "is-set": "^2.0.3", "is-weakmap": "^2.0.2", "is-weakset": "^2.0.3" } }, "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw=="],
1563
1851
1564
-
"xtend": ["xtend@4.0.2", "", {}, "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="],
1852
+
"which-typed-array": ["which-typed-array@1.1.19", "", { "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.4", "for-each": "^0.3.5", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" } }, "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw=="],
1565
1853
1566
-
"yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
1854
+
"word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="],
1567
1855
1568
-
"yn": ["yn@3.1.1", "", {}, "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q=="],
1856
+
"wrap-ansi": ["wrap-ansi@9.0.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww=="],
1569
1857
1570
-
"yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
1858
+
"wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="],
1571
1859
1572
-
"zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
1860
+
"ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="],
1573
1861
1574
-
"@atcute/oauth-browser-client/@atcute/client": ["@atcute/client@4.0.5", "", { "dependencies": { "@atcute/identity": "^1.1.1", "@atcute/lexicons": "^1.2.2" } }, "sha512-R8Qen8goGmEkynYGg2m6XFlVmz0GTDvQ+9w+4QqOob+XMk8/WDpF4aImev7WKEde/rV2gjcqW7zM8E6W9NShDA=="],
1862
+
"xtend": ["xtend@4.0.2", "", {}, "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="],
1575
1863
1576
-
"@atcute/oauth-browser-client/nanoid": ["nanoid@5.1.6", "", { "bin": { "nanoid": "bin/nanoid.js" } }, "sha512-c7+7RQ+dMB5dPwwCp4ee1/iV/q2P6aK1mTZcfr1BTuVlyW9hJYiMPybJCcnBlQtuSmTIWNeazm/zqNoZSSElBg=="],
1864
+
"y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="],
1577
1865
1578
-
"@atproto-labs/identity-resolver/@atproto/syntax": ["@atproto/syntax@0.4.0", "", {}, "sha512-b9y5ceHS8YKOfP3mdKmwAx5yVj9294UN7FG2XzP6V5aKUdFazEYRnR9m5n5ZQFKa3GNvz7de9guZCJ/sUTcOAA=="],
1866
+
"yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="],
1579
1867
1580
-
"@atproto-labs/simple-store-memory/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
1868
+
"yaml": ["yaml@2.8.1", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw=="],
1581
1869
1582
-
"@atproto/api/@atproto/common-web": ["@atproto/common-web@0.4.3", "", { "dependencies": { "graphemer": "^1.4.0", "multiformats": "^9.9.0", "uint8arrays": "3.0.0", "zod": "^3.23.8" } }, "sha512-nRDINmSe4VycJzPo6fP/hEltBcULFxt9Kw7fQk6405FyAWZiTluYHlXOnU7GkQfeUK44OENG1qFTBcmCJ7e8pg=="],
1870
+
"yargs": ["yargs@18.0.0", "", { "dependencies": { "cliui": "^9.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "string-width": "^7.2.0", "y18n": "^5.0.5", "yargs-parser": "^22.0.0" } }, "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg=="],
1583
1871
1584
-
"@atproto/common/@atproto/common-web": ["@atproto/common-web@0.4.3", "", { "dependencies": { "graphemer": "^1.4.0", "multiformats": "^9.9.0", "uint8arrays": "3.0.0", "zod": "^3.23.8" } }, "sha512-nRDINmSe4VycJzPo6fP/hEltBcULFxt9Kw7fQk6405FyAWZiTluYHlXOnU7GkQfeUK44OENG1qFTBcmCJ7e8pg=="],
1872
+
"yargs-parser": ["yargs-parser@22.0.0", "", {}, "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw=="],
1585
1873
1586
-
"@atproto/common/pino": ["pino@8.21.0", "", { "dependencies": { "atomic-sleep": "^1.0.0", "fast-redact": "^3.1.1", "on-exit-leak-free": "^2.1.0", "pino-abstract-transport": "^1.2.0", "pino-std-serializers": "^6.0.0", "process-warning": "^3.0.0", "quick-format-unescaped": "^4.0.3", "real-require": "^0.2.0", "safe-stable-stringify": "^2.3.1", "sonic-boom": "^3.7.0", "thread-stream": "^2.6.0" }, "bin": { "pino": "bin.js" } }, "sha512-ip4qdzjkAyDDZklUaZkcRFb2iA118H9SgRh8yzTkSQK8HilsOJF7rSY8HoW5+I0M46AZgX/pxbprf2vvzQCE0Q=="],
1874
+
"yocto-queue": ["yocto-queue@1.2.2", "", {}, "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ=="],
1587
1875
1588
-
"@atproto/common-web/uint8arrays": ["uint8arrays@3.0.0", "", { "dependencies": { "multiformats": "^9.4.2" } }, "sha512-HRCx0q6O9Bfbp+HHSfQQKD7wU70+lydKVt4EghkdOvlK/NlrF90z+eXV34mUd48rNvVJXwkrMSPpCATkct8fJA=="],
1876
+
"yoctocolors-cjs": ["yoctocolors-cjs@2.1.3", "", {}, "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw=="],
1589
1877
1590
-
"@atproto/crypto/uint8arrays": ["uint8arrays@3.0.0", "", { "dependencies": { "multiformats": "^9.4.2" } }, "sha512-HRCx0q6O9Bfbp+HHSfQQKD7wU70+lydKVt4EghkdOvlK/NlrF90z+eXV34mUd48rNvVJXwkrMSPpCATkct8fJA=="],
1878
+
"zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
1591
1879
1592
-
"@atproto/jwk-webcrypto/@atproto/jwk": ["@atproto/jwk@0.3.0", "", { "dependencies": { "multiformats": "^9.9.0", "zod": "^3.23.8" } }, "sha512-MIAXyNMGu1tCNHjqW/8jqfE/wgWCIoK2cJ0mR6UxwhNPvkbe35TcpRYJdtQu/E6MUd7TziyDBa/GO4dKAiePhQ=="],
1880
+
"zod-validation-error": ["zod-validation-error@4.0.2", "", { "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" } }, "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ=="],
1593
1881
1594
-
"@atproto/jwk-webcrypto/@atproto/jwk-jose": ["@atproto/jwk-jose@0.1.8", "", { "dependencies": { "@atproto/jwk": "0.3.0", "jose": "^5.2.0" } }, "sha512-aoU2Q0GpIl388KhCcv9YvAxNscALUv3xzLq5gjVPdJ+zmqw94nGZNcjiNvpnbfS+VQM9e2DrrTuwmDXnxfrrSA=="],
1882
+
"@atcute/cbor/@atcute/uint8array": ["@atcute/uint8array@1.0.5", "", {}, "sha512-XLWWxoR2HNl2qU+FCr0rp1APwJXci7HnzbOQLxK55OaMNBXZ19+xNC5ii4QCsThsDxa4JS/JTzuiQLziITWf2Q=="],
1595
1883
1596
-
"@atproto/lexicon/@atproto/common-web": ["@atproto/common-web@0.4.3", "", { "dependencies": { "graphemer": "^1.4.0", "multiformats": "^9.9.0", "uint8arrays": "3.0.0", "zod": "^3.23.8" } }, "sha512-nRDINmSe4VycJzPo6fP/hEltBcULFxt9Kw7fQk6405FyAWZiTluYHlXOnU7GkQfeUK44OENG1qFTBcmCJ7e8pg=="],
1884
+
"@atcute/cid/@atcute/uint8array": ["@atcute/uint8array@1.0.5", "", {}, "sha512-XLWWxoR2HNl2qU+FCr0rp1APwJXci7HnzbOQLxK55OaMNBXZ19+xNC5ii4QCsThsDxa4JS/JTzuiQLziITWf2Q=="],
1597
1885
1598
-
"@atproto/lexicon/@atproto/syntax": ["@atproto/syntax@0.4.1", "", {}, "sha512-CJdImtLAiFO+0z3BWTtxwk6aY5w4t8orHTMVJgkf++QRJWTxPbIFko/0hrkADB7n2EruDxDSeAgfUGehpH6ngw=="],
1886
+
"@atcute/crypto/@atcute/uint8array": ["@atcute/uint8array@1.0.5", "", {}, "sha512-XLWWxoR2HNl2qU+FCr0rp1APwJXci7HnzbOQLxK55OaMNBXZ19+xNC5ii4QCsThsDxa4JS/JTzuiQLziITWf2Q=="],
1599
1887
1600
-
"@atproto/oauth-client/@atproto/jwk": ["@atproto/jwk@0.3.0", "", { "dependencies": { "multiformats": "^9.9.0", "zod": "^3.23.8" } }, "sha512-MIAXyNMGu1tCNHjqW/8jqfE/wgWCIoK2cJ0mR6UxwhNPvkbe35TcpRYJdtQu/E6MUd7TziyDBa/GO4dKAiePhQ=="],
1888
+
"@atcute/multibase/@atcute/uint8array": ["@atcute/uint8array@1.0.5", "", {}, "sha512-XLWWxoR2HNl2qU+FCr0rp1APwJXci7HnzbOQLxK55OaMNBXZ19+xNC5ii4QCsThsDxa4JS/JTzuiQLziITWf2Q=="],
1601
1889
1602
-
"@atproto/oauth-client/@atproto/xrpc": ["@atproto/xrpc@0.7.0", "", { "dependencies": { "@atproto/lexicon": "^0.4.11", "zod": "^3.23.8" } }, "sha512-SfhP9dGx2qclaScFDb58Jnrmim5nk4geZXCqg6sB0I/KZhZEkr9iIx1hLCp+sxkIfEsmEJjeWO4B0rjUIJW5cw=="],
1890
+
"@atcute/oauth-browser-client/@atcute/identity-resolver": ["@atcute/identity-resolver@1.2.0", "", { "dependencies": { "@atcute/lexicons": "^1.2.5", "@atcute/util-fetch": "^1.0.4", "@badrap/valita": "^0.4.6" }, "peerDependencies": { "@atcute/identity": "^1.0.0" } }, "sha512-5UbSJfdV3JIkF8ksXz7g4nKBWasf2wROvzM66cfvTIWydWFO6/oS1KZd+zo9Eokje5Scf5+jsY9ZfgVARLepXg=="],
1603
1891
1604
-
"@atproto/oauth-client-node/@atproto/jwk": ["@atproto/jwk@0.3.0", "", { "dependencies": { "multiformats": "^9.9.0", "zod": "^3.23.8" } }, "sha512-MIAXyNMGu1tCNHjqW/8jqfE/wgWCIoK2cJ0mR6UxwhNPvkbe35TcpRYJdtQu/E6MUd7TziyDBa/GO4dKAiePhQ=="],
1892
+
"@atcute/xrpc-server/@atcute/uint8array": ["@atcute/uint8array@1.0.5", "", {}, "sha512-XLWWxoR2HNl2qU+FCr0rp1APwJXci7HnzbOQLxK55OaMNBXZ19+xNC5ii4QCsThsDxa4JS/JTzuiQLziITWf2Q=="],
1605
1893
1606
-
"@atproto/oauth-client-node/@atproto/jwk-jose": ["@atproto/jwk-jose@0.1.8", "", { "dependencies": { "@atproto/jwk": "0.3.0", "jose": "^5.2.0" } }, "sha512-aoU2Q0GpIl388KhCcv9YvAxNscALUv3xzLq5gjVPdJ+zmqw94nGZNcjiNvpnbfS+VQM9e2DrrTuwmDXnxfrrSA=="],
1894
+
"@atproto-labs/simple-store-memory/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
1607
1895
1608
-
"@atproto/oauth-types/@atproto/jwk": ["@atproto/jwk@0.3.0", "", { "dependencies": { "multiformats": "^9.9.0", "zod": "^3.23.8" } }, "sha512-MIAXyNMGu1tCNHjqW/8jqfE/wgWCIoK2cJ0mR6UxwhNPvkbe35TcpRYJdtQu/E6MUd7TziyDBa/GO4dKAiePhQ=="],
1896
+
"@atproto/lex-data/@atproto/syntax": ["@atproto/syntax@0.4.2", "", {}, "sha512-X9XSRPinBy/0VQ677j8VXlBsYSsUXaiqxWVpGGxJYsAhugdQRb0jqaVKJFtm6RskeNkV6y9xclSUi9UYG/COrA=="],
1609
1897
1610
1898
"@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
1611
1899
1612
-
"@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
1613
-
1614
-
"@babel/helper-compilation-targets/lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="],
1615
-
1616
1900
"@babel/helper-compilation-targets/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
1617
1901
1618
1902
"@babel/helper-create-class-features-plugin/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
1619
1903
1620
-
"@cookware/web/typescript": ["typescript@5.6.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw=="],
1904
+
"@cookware/database/@libsql/client": ["@libsql/client@0.15.15", "", { "dependencies": { "@libsql/core": "^0.15.14", "@libsql/hrana-client": "^0.7.0", "js-base64": "^3.7.5", "libsql": "^0.5.22", "promise-limit": "^2.7.0" } }, "sha512-twC0hQxPNHPKfeOv3sNT6u2pturQjLcI+CnpTM0SjRpocEGgfiZ7DWKXLNnsothjyJmDqEsBQJ5ztq9Wlu470w=="],
1905
+
1906
+
"@cookware/tsconfig/@types/bun": ["@types/bun@1.3.4", "", { "dependencies": { "bun-types": "1.3.4" } }, "sha512-EEPTKXHP+zKGPkhRLv+HI0UEX8/o+65hqARxLy8Ov5rIxMBPNTjeZww00CIihrIQGEQBYg+0roO5qOnS/7boGA=="],
1621
1907
1622
1908
"@esbuild-kit/core-utils/esbuild": ["esbuild@0.18.20", "", { "optionalDependencies": { "@esbuild/android-arm": "0.18.20", "@esbuild/android-arm64": "0.18.20", "@esbuild/android-x64": "0.18.20", "@esbuild/darwin-arm64": "0.18.20", "@esbuild/darwin-x64": "0.18.20", "@esbuild/freebsd-arm64": "0.18.20", "@esbuild/freebsd-x64": "0.18.20", "@esbuild/linux-arm": "0.18.20", "@esbuild/linux-arm64": "0.18.20", "@esbuild/linux-ia32": "0.18.20", "@esbuild/linux-loong64": "0.18.20", "@esbuild/linux-mips64el": "0.18.20", "@esbuild/linux-ppc64": "0.18.20", "@esbuild/linux-riscv64": "0.18.20", "@esbuild/linux-s390x": "0.18.20", "@esbuild/linux-x64": "0.18.20", "@esbuild/netbsd-x64": "0.18.20", "@esbuild/openbsd-x64": "0.18.20", "@esbuild/sunos-x64": "0.18.20", "@esbuild/win32-arm64": "0.18.20", "@esbuild/win32-ia32": "0.18.20", "@esbuild/win32-x64": "0.18.20" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA=="],
1623
1909
1624
1910
"@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
1625
1911
1912
+
"@eslint/eslintrc/ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="],
1913
+
1626
1914
"@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
1627
1915
1628
1916
"@eslint/eslintrc/strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="],
1629
1917
1630
-
"@jridgewell/gen-mapping/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
1918
+
"@inquirer/core/wrap-ansi": ["wrap-ansi@6.2.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA=="],
1631
1919
1632
-
"@jridgewell/remapping/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
1920
+
"@next/eslint-plugin-next/fast-glob": ["fast-glob@3.3.1", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.4" } }, "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg=="],
1633
1921
1634
1922
"@opentelemetry/core/@opentelemetry/semantic-conventions": ["@opentelemetry/semantic-conventions@1.28.0", "", {}, "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA=="],
1635
1923
···
1639
1927
1640
1928
"@opentelemetry/instrumentation-pg/@opentelemetry/semantic-conventions": ["@opentelemetry/semantic-conventions@1.27.0", "", {}, "sha512-sAay1RrB+ONOem0OZanAR1ZI/k7yDpnOQSQmTMuGImUQb2y8EbSaCJ94FQluM74xoU03vlb2d2U90hZluL6nQg=="],
1641
1929
1930
+
"@opentelemetry/instrumentation-pg/@types/pg": ["@types/pg@8.6.1", "", { "dependencies": { "@types/node": "*", "pg-protocol": "*", "pg-types": "^2.2.0" } }, "sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w=="],
1931
+
1642
1932
"@opentelemetry/resources/@opentelemetry/semantic-conventions": ["@opentelemetry/semantic-conventions@1.28.0", "", {}, "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA=="],
1643
1933
1644
1934
"@opentelemetry/sdk-trace-base/@opentelemetry/semantic-conventions": ["@opentelemetry/semantic-conventions@1.28.0", "", {}, "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA=="],
···
1646
1936
"@prisma/instrumentation/@opentelemetry/instrumentation": ["@opentelemetry/instrumentation@0.53.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.53.0", "@types/shimmer": "^1.2.0", "import-in-the-middle": "^1.8.1", "require-in-the-middle": "^7.1.1", "semver": "^7.5.2", "shimmer": "^1.2.1" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-DMwg0hy4wzf7K73JJtl95m/e0boSoWhH07rfvHvYzQtBD3Bmv0Wc1x733vyZBqmFm8OjJD0/pfiUg1W3JjFX0A=="],
1647
1937
1648
1938
"@radix-ui/react-arrow/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
1649
-
1650
-
"@radix-ui/react-collapsible/@radix-ui/react-context": ["@radix-ui/react-context@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA=="],
1651
-
1652
-
"@radix-ui/react-collapsible/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
1653
1939
1654
1940
"@radix-ui/react-collection/@radix-ui/react-context": ["@radix-ui/react-context@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA=="],
1655
1941
···
1695
1981
1696
1982
"@radix-ui/react-visually-hidden/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
1697
1983
1698
-
"@skyware/jetstream/@atcute/bluesky": ["@atcute/bluesky@3.2.10", "", { "dependencies": { "@atcute/atproto": "^3.1.9", "@atcute/lexicons": "^1.2.2" } }, "sha512-qwQWTzRf3umnh2u41gdU+xWYkbzGlKDupc3zeOB+YjmuP1N9wEaUhwS8H7vgrqr0xC9SGNDjeUVcjC4m5BPLBg=="],
1984
+
"@tailwindcss/node/jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="],
1699
1985
1700
-
"@tanstack/react-router-devtools/vite": ["vite@7.2.4", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w=="],
1986
+
"@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.7.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg=="],
1701
1987
1702
-
"@tanstack/router-devtools/vite": ["vite@7.2.4", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w=="],
1988
+
"@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.7.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA=="],
1703
1989
1704
-
"@tanstack/router-devtools-core/vite": ["vite@7.2.4", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w=="],
1990
+
"@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="],
1705
1991
1706
-
"@tanstack/router-plugin/chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="],
1992
+
"@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.0", "", { "dependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" }, "bundled": true }, "sha512-Fq6DJW+Bb5jaWE69/qOE0D1TUN9+6uWhCeZpdnSBk14pjLcCWR7Q8n49PTSPHazM37JqrsdpEthXy2xn6jWWiA=="],
1993
+
1994
+
"@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="],
1995
+
1996
+
"@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
1707
1997
1708
-
"@tanstack/router-utils/diff": ["diff@8.0.2", "", {}, "sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg=="],
1998
+
"@types/pg-pool/@types/pg": ["@types/pg@8.6.1", "", { "dependencies": { "@types/node": "*", "pg-protocol": "*", "pg-types": "^2.2.0" } }, "sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w=="],
1709
1999
1710
2000
"@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
1711
2001
1712
2002
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
2003
+
2004
+
"@unrs/resolver-binding-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.12", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@tybys/wasm-util": "^0.10.0" } }, "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ=="],
1713
2005
1714
2006
"anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
1715
2007
1716
-
"csso/css-tree": ["css-tree@2.2.1", "", { "dependencies": { "mdn-data": "2.0.28", "source-map-js": "^1.0.1" } }, "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA=="],
2008
+
"app/@atcute/identity-resolver": ["@atcute/identity-resolver@1.2.0", "", { "dependencies": { "@atcute/lexicons": "^1.2.5", "@atcute/util-fetch": "^1.0.4", "@badrap/valita": "^0.4.6" }, "peerDependencies": { "@atcute/identity": "^1.0.0" } }, "sha512-5UbSJfdV3JIkF8ksXz7g4nKBWasf2wROvzM66cfvTIWydWFO6/oS1KZd+zo9Eokje5Scf5+jsY9ZfgVARLepXg=="],
1717
2009
1718
-
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
2010
+
"app/@atproto/oauth-client-node": ["@atproto/oauth-client-node@0.3.13", "", { "dependencies": { "@atproto-labs/did-resolver": "0.2.4", "@atproto-labs/handle-resolver-node": "0.1.23", "@atproto-labs/simple-store": "0.3.0", "@atproto/did": "0.2.3", "@atproto/jwk": "0.6.0", "@atproto/jwk-jose": "0.1.11", "@atproto/jwk-webcrypto": "0.2.0", "@atproto/oauth-client": "0.5.11", "@atproto/oauth-types": "0.5.2" } }, "sha512-k2qT5QM6Mj5I412IZOnktShmI1A5YbwLmLM4BkeEcbcOm7kU1Cr/H/zUC/zniCIj641ZudiXU80Bsyw4A6tejA=="],
1719
2011
1720
-
"glob/minimatch": ["minimatch@10.1.1", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ=="],
2012
+
"app/@types/node": ["@types/node@20.19.25", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ=="],
1721
2013
1722
-
"import-fresh/resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="],
2014
+
"chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
1723
2015
1724
-
"micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
2016
+
"eslint/ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="],
1725
2017
1726
-
"postcss-calc/postcss-selector-parser": ["postcss-selector-parser@7.1.0", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA=="],
2018
+
"eslint-config-next/globals": ["globals@16.4.0", "", {}, "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw=="],
1727
2019
1728
-
"postcss-discard-comments/postcss-selector-parser": ["postcss-selector-parser@7.1.0", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA=="],
2020
+
"eslint-import-resolver-node/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
1729
2021
1730
-
"postcss-merge-rules/postcss-selector-parser": ["postcss-selector-parser@7.1.0", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA=="],
2022
+
"eslint-module-utils/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
1731
2023
1732
-
"postcss-minify-selectors/postcss-selector-parser": ["postcss-selector-parser@7.1.0", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA=="],
2024
+
"eslint-plugin-import/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
1733
2025
1734
-
"postcss-unique-selectors/postcss-selector-parser": ["postcss-selector-parser@7.1.0", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA=="],
2026
+
"eslint-plugin-import/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
1735
2027
1736
-
"recast/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
2028
+
"eslint-plugin-react/resolve": ["resolve@2.0.0-next.5", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA=="],
1737
2029
1738
-
"solid-js/seroval": ["seroval@1.3.2", "", {}, "sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ=="],
2030
+
"eslint-plugin-react/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
1739
2031
1740
-
"solid-js/seroval-plugins": ["seroval-plugins@1.3.3", "", { "peerDependencies": { "seroval": "^1.0" } }, "sha512-16OL3NnUBw8JG1jBLUoZJsLnQq0n5Ua6aHalhJK4fMQkz1lqR7Osz1sA30trBtd9VUDc2NgkuRCn8+/pBwqZ+w=="],
2032
+
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
1741
2033
1742
-
"source-map-support/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
2034
+
"glob/minimatch": ["minimatch@10.1.1", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ=="],
1743
2035
1744
-
"stylehacks/postcss-selector-parser": ["postcss-selector-parser@7.1.0", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA=="],
2036
+
"globby/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
1745
2037
1746
-
"svgo/commander": ["commander@11.1.0", "", {}, "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ=="],
2038
+
"lightningcss/detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
1747
2039
1748
-
"tailwindcss/arg": ["arg@5.0.2", "", {}, "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="],
2040
+
"lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
1749
2041
1750
-
"tailwindcss/chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="],
2042
+
"micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
1751
2043
1752
-
"tsup/esbuild": ["esbuild@0.27.0", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.0", "@esbuild/android-arm": "0.27.0", "@esbuild/android-arm64": "0.27.0", "@esbuild/android-x64": "0.27.0", "@esbuild/darwin-arm64": "0.27.0", "@esbuild/darwin-x64": "0.27.0", "@esbuild/freebsd-arm64": "0.27.0", "@esbuild/freebsd-x64": "0.27.0", "@esbuild/linux-arm": "0.27.0", "@esbuild/linux-arm64": "0.27.0", "@esbuild/linux-ia32": "0.27.0", "@esbuild/linux-loong64": "0.27.0", "@esbuild/linux-mips64el": "0.27.0", "@esbuild/linux-ppc64": "0.27.0", "@esbuild/linux-riscv64": "0.27.0", "@esbuild/linux-s390x": "0.27.0", "@esbuild/linux-x64": "0.27.0", "@esbuild/netbsd-arm64": "0.27.0", "@esbuild/netbsd-x64": "0.27.0", "@esbuild/openbsd-arm64": "0.27.0", "@esbuild/openbsd-x64": "0.27.0", "@esbuild/openharmony-arm64": "0.27.0", "@esbuild/sunos-x64": "0.27.0", "@esbuild/win32-arm64": "0.27.0", "@esbuild/win32-ia32": "0.27.0", "@esbuild/win32-x64": "0.27.0" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-jd0f4NHbD6cALCyGElNpGAOtWxSq46l9X/sWB0Nzd5er4Kz2YTm+Vl0qKFT9KUJvD8+fiO8AvoHhFvEatfVixA=="],
2044
+
"next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="],
1753
2045
1754
-
"tsx/esbuild": ["esbuild@0.25.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="],
2046
+
"p-limit/yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
1755
2047
1756
-
"uint8arrays/multiformats": ["multiformats@13.4.1", "", {}, "sha512-VqO6OSvLrFVAYYjgsr8tyv62/rCQhPgsZUXLTqoFLSgdkgiUYKYeArbt1uWLlEpkjxQe+P0+sHlbPEte1Bi06Q=="],
2048
+
"path-scurry/lru-cache": ["lru-cache@11.2.2", "", {}, "sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg=="],
1757
2049
1758
-
"vite/esbuild": ["esbuild@0.25.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="],
2050
+
"postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
1759
2051
1760
-
"@atproto/api/@atproto/common-web/uint8arrays": ["uint8arrays@3.0.0", "", { "dependencies": { "multiformats": "^9.4.2" } }, "sha512-HRCx0q6O9Bfbp+HHSfQQKD7wU70+lydKVt4EghkdOvlK/NlrF90z+eXV34mUd48rNvVJXwkrMSPpCATkct8fJA=="],
2052
+
"readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
2053
+
2054
+
"recast/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
1761
2055
1762
-
"@atproto/common/@atproto/common-web/uint8arrays": ["uint8arrays@3.0.0", "", { "dependencies": { "multiformats": "^9.4.2" } }, "sha512-HRCx0q6O9Bfbp+HHSfQQKD7wU70+lydKVt4EghkdOvlK/NlrF90z+eXV34mUd48rNvVJXwkrMSPpCATkct8fJA=="],
2056
+
"rolldown/@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.50", "", {}, "sha512-5e76wQiQVeL1ICOZVUg4LSOVYg9jyhGCin+icYozhsUzM+fHE7kddi1bdiE0jwVqTfkjba3jUFbEkoC9WkdvyA=="],
1763
2057
1764
-
"@atproto/common/pino/pino-abstract-transport": ["pino-abstract-transport@1.2.0", "", { "dependencies": { "readable-stream": "^4.0.0", "split2": "^4.0.0" } }, "sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q=="],
2058
+
"sharp/detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
1765
2059
1766
-
"@atproto/common/pino/pino-std-serializers": ["pino-std-serializers@6.2.2", "", {}, "sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA=="],
2060
+
"solid-js/seroval": ["seroval@1.3.2", "", {}, "sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ=="],
1767
2061
1768
-
"@atproto/common/pino/process-warning": ["process-warning@3.0.0", "", {}, "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ=="],
2062
+
"solid-js/seroval-plugins": ["seroval-plugins@1.3.3", "", { "peerDependencies": { "seroval": "^1.0" } }, "sha512-16OL3NnUBw8JG1jBLUoZJsLnQq0n5Ua6aHalhJK4fMQkz1lqR7Osz1sA30trBtd9VUDc2NgkuRCn8+/pBwqZ+w=="],
1769
2063
1770
-
"@atproto/common/pino/sonic-boom": ["sonic-boom@3.8.1", "", { "dependencies": { "atomic-sleep": "^1.0.0" } }, "sha512-y4Z8LCDBuum+PBP3lSV7RHrXscqksve/bi0as7mhwVnBW+/wUqKT/2Kb7um8yqcFy0duYbbPxzt89Zy2nOCaxg=="],
2064
+
"source-map-support/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
1771
2065
1772
-
"@atproto/common/pino/thread-stream": ["thread-stream@2.7.0", "", { "dependencies": { "real-require": "^0.2.0" } }, "sha512-qQiRWsU/wvNolI6tbbCKd9iKaTnCXsTwVxhhKM6nctPdujTyztjlbUkUTUymidWcMnZ5pWR0ej4a0tjsW021vw=="],
2066
+
"string-width/emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="],
1773
2067
1774
-
"@atproto/lexicon/@atproto/common-web/uint8arrays": ["uint8arrays@3.0.0", "", { "dependencies": { "multiformats": "^9.4.2" } }, "sha512-HRCx0q6O9Bfbp+HHSfQQKD7wU70+lydKVt4EghkdOvlK/NlrF90z+eXV34mUd48rNvVJXwkrMSPpCATkct8fJA=="],
2068
+
"tsconfig-paths/json5": ["json5@1.0.2", "", { "dependencies": { "minimist": "^1.2.0" }, "bin": { "json5": "lib/cli.js" } }, "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA=="],
2069
+
2070
+
"tsx/esbuild": ["esbuild@0.27.1", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.1", "@esbuild/android-arm": "0.27.1", "@esbuild/android-arm64": "0.27.1", "@esbuild/android-x64": "0.27.1", "@esbuild/darwin-arm64": "0.27.1", "@esbuild/darwin-x64": "0.27.1", "@esbuild/freebsd-arm64": "0.27.1", "@esbuild/freebsd-x64": "0.27.1", "@esbuild/linux-arm": "0.27.1", "@esbuild/linux-arm64": "0.27.1", "@esbuild/linux-ia32": "0.27.1", "@esbuild/linux-loong64": "0.27.1", "@esbuild/linux-mips64el": "0.27.1", "@esbuild/linux-ppc64": "0.27.1", "@esbuild/linux-riscv64": "0.27.1", "@esbuild/linux-s390x": "0.27.1", "@esbuild/linux-x64": "0.27.1", "@esbuild/netbsd-arm64": "0.27.1", "@esbuild/netbsd-x64": "0.27.1", "@esbuild/openbsd-arm64": "0.27.1", "@esbuild/openbsd-x64": "0.27.1", "@esbuild/openharmony-arm64": "0.27.1", "@esbuild/sunos-x64": "0.27.1", "@esbuild/win32-arm64": "0.27.1", "@esbuild/win32-ia32": "0.27.1", "@esbuild/win32-x64": "0.27.1" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-yY35KZckJJuVVPXpvjgxiCuVEJT67F6zDeVTv4rizyPrfGBUpZQsvmxnN+C371c2esD/hNMjj4tpBhuueLN7aA=="],
2071
+
2072
+
"web/@types/bun": ["@types/bun@1.3.4", "", { "dependencies": { "bun-types": "1.3.4" } }, "sha512-EEPTKXHP+zKGPkhRLv+HI0UEX8/o+65hqARxLy8Ov5rIxMBPNTjeZww00CIihrIQGEQBYg+0roO5qOnS/7boGA=="],
2073
+
2074
+
"wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="],
2075
+
2076
+
"@atcute/oauth-browser-client/@atcute/identity-resolver/@atcute/util-fetch": ["@atcute/util-fetch@1.0.4", "", { "dependencies": { "@badrap/valita": "^0.4.6" } }, "sha512-sIU9Qk0dE8PLEXSfhy+gIJV+HpiiknMytCI2SqLlqd0vgZUtEKI/EQfP+23LHWvP+CLCzVDOa6cpH045OlmNBg=="],
2077
+
2078
+
"@cookware/database/@libsql/client/@libsql/core": ["@libsql/core@0.15.15", "", { "dependencies": { "js-base64": "^3.7.5" } }, "sha512-C88Z6UKl+OyuKKPwz224riz02ih/zHYI3Ho/LAcVOgjsunIRZoBw7fjRfaH9oPMmSNeQfhGklSG2il1URoOIsA=="],
2079
+
2080
+
"@cookware/database/@libsql/client/libsql": ["libsql@0.5.22", "", { "dependencies": { "@neon-rs/load": "^0.0.4", "detect-libc": "2.0.2" }, "optionalDependencies": { "@libsql/darwin-arm64": "0.5.22", "@libsql/darwin-x64": "0.5.22", "@libsql/linux-arm-gnueabihf": "0.5.22", "@libsql/linux-arm-musleabihf": "0.5.22", "@libsql/linux-arm64-gnu": "0.5.22", "@libsql/linux-arm64-musl": "0.5.22", "@libsql/linux-x64-gnu": "0.5.22", "@libsql/linux-x64-musl": "0.5.22", "@libsql/win32-x64-msvc": "0.5.22" }, "os": [ "linux", "win32", "darwin", ], "cpu": [ "arm", "x64", "arm64", ] }, "sha512-NscWthMQt7fpU8lqd7LXMvT9pi+KhhmTHAJWUB/Lj6MWa0MKFv0F2V4C6WKKpjCVZl0VwcDz4nOI3CyaT1DDiA=="],
2081
+
2082
+
"@cookware/tsconfig/@types/bun/bun-types": ["bun-types@1.3.4", "", { "dependencies": { "@types/node": "*" } }, "sha512-5ua817+BZPZOlNaRgGBpZJOSAQ9RQ17pkwPD0yR7CfJg+r8DgIILByFifDTa+IPDDxzf5VNhtNlcKqFzDgJvlQ=="],
1775
2083
1776
2084
"@esbuild-kit/core-utils/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.18.20", "", { "os": "android", "cpu": "arm" }, "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw=="],
1777
2085
···
1817
2125
1818
2126
"@esbuild-kit/core-utils/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.18.20", "", { "os": "win32", "cpu": "x64" }, "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ=="],
1819
2127
2128
+
"@eslint/eslintrc/ajv/json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="],
2129
+
2130
+
"@inquirer/core/wrap-ansi/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
2131
+
2132
+
"@inquirer/core/wrap-ansi/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
2133
+
2134
+
"@next/eslint-plugin-next/fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
2135
+
1820
2136
"@opentelemetry/instrumentation-http/@opentelemetry/instrumentation/@opentelemetry/api-logs": ["@opentelemetry/api-logs@0.57.1", "", { "dependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-I4PHczeujhQAQv6ZBzqHYEUiggZL4IdSMixtVD3EYqbdrjujE7kRfI5QohjlPoJm8BvenoW5YaTMWRrbpot6tg=="],
1821
2137
1822
2138
"@prisma/instrumentation/@opentelemetry/instrumentation/@opentelemetry/api-logs": ["@opentelemetry/api-logs@0.53.0", "", { "dependencies": { "@opentelemetry/api": "^1.0.0" } }, "sha512-8HArjKx+RaAI8uEIgcORbZIPklyh1YLjPSBus8hjRmvLi6DeFzgOcdZ7KwPabKj8mXF8dX0hyfAyGfycz0DbFw=="],
1823
2139
1824
2140
"@radix-ui/react-arrow/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
1825
-
1826
-
"@radix-ui/react-collapsible/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
1827
2141
1828
2142
"@radix-ui/react-dismissable-layer/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
1829
2143
···
1839
2153
1840
2154
"@radix-ui/react-visually-hidden/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
1841
2155
1842
-
"@tanstack/react-router-devtools/vite/esbuild": ["esbuild@0.25.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="],
1843
-
1844
-
"@tanstack/router-devtools-core/vite/esbuild": ["esbuild@0.25.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="],
1845
-
1846
-
"@tanstack/router-devtools/vite/esbuild": ["esbuild@0.25.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="],
1847
-
1848
-
"@tanstack/router-plugin/chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
1849
-
1850
-
"@tanstack/router-plugin/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="],
1851
-
1852
2156
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
1853
2157
1854
-
"csso/css-tree/mdn-data": ["mdn-data@2.0.28", "", {}, "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g=="],
1855
-
1856
-
"tailwindcss/chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
1857
-
1858
-
"tailwindcss/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="],
1859
-
1860
-
"tsup/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.0", "", { "os": "aix", "cpu": "ppc64" }, "sha512-KuZrd2hRjz01y5JK9mEBSD3Vj3mbCvemhT466rSuJYeE/hjuBrHfjjcjMdTm/sz7au+++sdbJZJmuBwQLuw68A=="],
1861
-
1862
-
"tsup/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.27.0", "", { "os": "android", "cpu": "arm" }, "sha512-j67aezrPNYWJEOHUNLPj9maeJte7uSMM6gMoxfPC9hOg8N02JuQi/T7ewumf4tNvJadFkvLZMlAq73b9uwdMyQ=="],
1863
-
1864
-
"tsup/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.0", "", { "os": "android", "cpu": "arm64" }, "sha512-CC3vt4+1xZrs97/PKDkl0yN7w8edvU2vZvAFGD16n9F0Cvniy5qvzRXjfO1l94efczkkQE6g1x0i73Qf5uthOQ=="],
1865
-
1866
-
"tsup/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.27.0", "", { "os": "android", "cpu": "x64" }, "sha512-wurMkF1nmQajBO1+0CJmcN17U4BP6GqNSROP8t0X/Jiw2ltYGLHpEksp9MpoBqkrFR3kv2/te6Sha26k3+yZ9Q=="],
1867
-
1868
-
"tsup/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-uJOQKYCcHhg07DL7i8MzjvS2LaP7W7Pn/7uA0B5S1EnqAirJtbyw4yC5jQ5qcFjHK9l6o/MX9QisBg12kNkdHg=="],
1869
-
1870
-
"tsup/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-8mG6arH3yB/4ZXiEnXof5MK72dE6zM9cDvUcPtxhUZsDjESl9JipZYW60C3JGreKCEP+p8P/72r69m4AZGJd5g=="],
1871
-
1872
-
"tsup/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-9FHtyO988CwNMMOE3YIeci+UV+x5Zy8fI2qHNpsEtSF83YPBmE8UWmfYAQg6Ux7Gsmd4FejZqnEUZCMGaNQHQw=="],
1873
-
1874
-
"tsup/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-zCMeMXI4HS/tXvJz8vWGexpZj2YVtRAihHLk1imZj4efx1BQzN76YFeKqlDr3bUWI26wHwLWPd3rwh6pe4EV7g=="],
1875
-
1876
-
"tsup/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.0", "", { "os": "linux", "cpu": "arm" }, "sha512-t76XLQDpxgmq2cNXKTVEB7O7YMb42atj2Re2Haf45HkaUpjM2J0UuJZDuaGbPbamzZ7bawyGFUkodL+zcE+jvQ=="],
1877
-
1878
-
"tsup/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-AS18v0V+vZiLJyi/4LphvBE+OIX682Pu7ZYNsdUHyUKSoRwdnOsMf6FDekwoAFKej14WAkOef3zAORJgAtXnlQ=="],
1879
-
1880
-
"tsup/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.0", "", { "os": "linux", "cpu": "ia32" }, "sha512-Mz1jxqm/kfgKkc/KLHC5qIujMvnnarD9ra1cEcrs7qshTUSksPihGrWHVG5+osAIQ68577Zpww7SGapmzSt4Nw=="],
1881
-
1882
-
"tsup/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.0", "", { "os": "linux", "cpu": "none" }, "sha512-QbEREjdJeIreIAbdG2hLU1yXm1uu+LTdzoq1KCo4G4pFOLlvIspBm36QrQOar9LFduavoWX2msNFAAAY9j4BDg=="],
1883
-
1884
-
"tsup/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.0", "", { "os": "linux", "cpu": "none" }, "sha512-sJz3zRNe4tO2wxvDpH/HYJilb6+2YJxo/ZNbVdtFiKDufzWq4JmKAiHy9iGoLjAV7r/W32VgaHGkk35cUXlNOg=="],
1885
-
1886
-
"tsup/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-z9N10FBD0DCS2dmSABDBb5TLAyF1/ydVb+N4pi88T45efQ/w4ohr/F/QYCkxDPnkhkp6AIpIcQKQ8F0ANoA2JA=="],
1887
-
1888
-
"tsup/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.0", "", { "os": "linux", "cpu": "none" }, "sha512-pQdyAIZ0BWIC5GyvVFn5awDiO14TkT/19FTmFcPdDec94KJ1uZcmFs21Fo8auMXzD4Tt+diXu1LW1gHus9fhFQ=="],
1889
-
1890
-
"tsup/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-hPlRWR4eIDDEci953RI1BLZitgi5uqcsjKMxwYfmi4LcwyWo2IcRP+lThVnKjNtk90pLS8nKdroXYOqW+QQH+w=="],
1891
-
1892
-
"tsup/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.0", "", { "os": "linux", "cpu": "x64" }, "sha512-1hBWx4OUJE2cab++aVZ7pObD6s+DK4mPGpemtnAORBvb5l/g5xFGk0vc0PjSkrDs0XaXj9yyob3d14XqvnQ4gw=="],
1893
-
1894
-
"tsup/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.0", "", { "os": "none", "cpu": "x64" }, "sha512-xbbOdfn06FtcJ9d0ShxxvSn2iUsGd/lgPIO2V3VZIPDbEaIj1/3nBBe1AwuEZKXVXkMmpr6LUAgMkLD/4D2PPA=="],
1895
-
1896
-
"tsup/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.0", "", { "os": "openbsd", "cpu": "x64" }, "sha512-aCwlRdSNMNxkGGqQajMUza6uXzR/U0dIl1QmLjPtRbLOx3Gy3otfFu/VjATy4yQzo9yFDGTxYDo1FfAD9oRD2A=="],
1897
-
1898
-
"tsup/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.0", "", { "os": "sunos", "cpu": "x64" }, "sha512-Q1KY1iJafM+UX6CFEL+F4HRTgygmEW568YMqDA5UV97AuZSm21b7SXIrRJDwXWPzr8MGr75fUZPV67FdtMHlHA=="],
1899
-
1900
-
"tsup/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-W1eyGNi6d+8kOmZIwi/EDjrL9nxQIQ0MiGqe/AWc6+IaHloxHSGoeRgDRKHFISThLmsewZ5nHFvGFWdBYlgKPg=="],
1901
-
1902
-
"tsup/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-30z1aKL9h22kQhilnYkORFYt+3wp7yZsHWus+wSKAJR8JtdfI76LJ4SBdMsCopTR3z/ORqVu5L1vtnHZWVj4cQ=="],
1903
-
1904
-
"tsup/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.0", "", { "os": "win32", "cpu": "x64" }, "sha512-aIitBcjQeyOhMTImhLZmtxfdOcuNRpwlPNmlFKPcHQYPhEssw75Cl1TSXJXpMkzaua9FUetx/4OQKq7eJul5Cg=="],
1905
-
1906
-
"tsx/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="],
1907
-
1908
-
"tsx/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="],
1909
-
1910
-
"tsx/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.12", "", { "os": "android", "cpu": "arm64" }, "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg=="],
1911
-
1912
-
"tsx/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.25.12", "", { "os": "android", "cpu": "x64" }, "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg=="],
1913
-
1914
-
"tsx/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg=="],
1915
-
1916
-
"tsx/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA=="],
1917
-
1918
-
"tsx/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.12", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg=="],
1919
-
1920
-
"tsx/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ=="],
1921
-
1922
-
"tsx/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.12", "", { "os": "linux", "cpu": "arm" }, "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw=="],
1923
-
1924
-
"tsx/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ=="],
1925
-
1926
-
"tsx/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.12", "", { "os": "linux", "cpu": "ia32" }, "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA=="],
1927
-
1928
-
"tsx/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng=="],
1929
-
1930
-
"tsx/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw=="],
1931
-
1932
-
"tsx/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA=="],
1933
-
1934
-
"tsx/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w=="],
1935
-
1936
-
"tsx/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg=="],
1937
-
1938
-
"tsx/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.12", "", { "os": "linux", "cpu": "x64" }, "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw=="],
1939
-
1940
-
"tsx/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg=="],
1941
-
1942
-
"tsx/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.12", "", { "os": "none", "cpu": "x64" }, "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ=="],
1943
-
1944
-
"tsx/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.12", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A=="],
1945
-
1946
-
"tsx/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw=="],
1947
-
1948
-
"tsx/esbuild/@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg=="],
1949
-
1950
-
"tsx/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w=="],
1951
-
1952
-
"tsx/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg=="],
1953
-
1954
-
"tsx/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.12", "", { "os": "win32", "cpu": "ia32" }, "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ=="],
2158
+
"app/@atcute/identity-resolver/@atcute/util-fetch": ["@atcute/util-fetch@1.0.4", "", { "dependencies": { "@badrap/valita": "^0.4.6" } }, "sha512-sIU9Qk0dE8PLEXSfhy+gIJV+HpiiknMytCI2SqLlqd0vgZUtEKI/EQfP+23LHWvP+CLCzVDOa6cpH045OlmNBg=="],
1955
2159
1956
-
"tsx/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="],
2160
+
"app/@atproto/oauth-client-node/@atproto-labs/did-resolver": ["@atproto-labs/did-resolver@0.2.4", "", { "dependencies": { "@atproto-labs/fetch": "0.2.3", "@atproto-labs/pipe": "0.1.1", "@atproto-labs/simple-store": "0.3.0", "@atproto-labs/simple-store-memory": "0.1.4", "@atproto/did": "0.2.3", "zod": "^3.23.8" } }, "sha512-sbXxBnAJWsKv/FEGG6a/WLz7zQYUr1vA2TXvNnPwwJQJCjPwEJMOh1vM22wBr185Phy7D2GD88PcRokn7eUVyw=="],
1957
2161
1958
-
"vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="],
2162
+
"app/@atproto/oauth-client-node/@atproto-labs/handle-resolver-node": ["@atproto-labs/handle-resolver-node@0.1.23", "", { "dependencies": { "@atproto-labs/fetch-node": "0.2.0", "@atproto-labs/handle-resolver": "0.3.4", "@atproto/did": "0.2.3" } }, "sha512-tBRr2LCgzn3klk+DL0xrTFv4zg5tEszdeW6vSIFVebBYSb3MLdfhievmSqZdIQ4c9UCC4hN7YXTlZCXj8+2YmQ=="],
1959
2163
1960
-
"vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="],
2164
+
"app/@atproto/oauth-client-node/@atproto-labs/simple-store": ["@atproto-labs/simple-store@0.3.0", "", {}, "sha512-nOb6ONKBRJHRlukW1sVawUkBqReLlLx6hT35VS3imaNPwiXDxLnTK7lxw3Lrl9k5yugSBDQAkZAq3MPTEFSUBQ=="],
1961
2165
1962
-
"vite/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.12", "", { "os": "android", "cpu": "arm64" }, "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg=="],
2166
+
"app/@atproto/oauth-client-node/@atproto/did": ["@atproto/did@0.2.3", "", { "dependencies": { "zod": "^3.23.8" } }, "sha512-VI8JJkSizvM2cHYJa37WlbzeCm5tWpojyc1/Zy8q8OOjyoy6X4S4BEfoP941oJcpxpMTObamibQIXQDo7tnIjg=="],
1963
2167
1964
-
"vite/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.25.12", "", { "os": "android", "cpu": "x64" }, "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg=="],
2168
+
"app/@atproto/oauth-client-node/@atproto/jwk": ["@atproto/jwk@0.6.0", "", { "dependencies": { "multiformats": "^9.9.0", "zod": "^3.23.8" } }, "sha512-bDoJPvt7TrQVi/rBfBrSSpGykhtIriKxeYCYQTiPRKFfyRhbgpElF0wPXADjIswnbzZdOwbY63az4E/CFVT3Tw=="],
1965
2169
1966
-
"vite/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg=="],
2170
+
"app/@atproto/oauth-client-node/@atproto/jwk-jose": ["@atproto/jwk-jose@0.1.11", "", { "dependencies": { "@atproto/jwk": "0.6.0", "jose": "^5.2.0" } }, "sha512-i4Fnr2sTBYmMmHXl7NJh8GrCH+tDQEVWrcDMDnV5DjJfkgT17wIqvojIw9SNbSL4Uf0OtfEv6AgG0A+mgh8b5Q=="],
1967
2171
1968
-
"vite/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA=="],
2172
+
"app/@atproto/oauth-client-node/@atproto/jwk-webcrypto": ["@atproto/jwk-webcrypto@0.2.0", "", { "dependencies": { "@atproto/jwk": "0.6.0", "@atproto/jwk-jose": "0.1.11", "zod": "^3.23.8" } }, "sha512-UmgRrrEAkWvxwhlwe30UmDOdTEFidlIzBC7C3cCbeJMcBN1x8B3KH+crXrsTqfWQBG58mXgt8wgSK3Kxs2LhFg=="],
1969
2173
1970
-
"vite/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.12", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg=="],
2174
+
"app/@atproto/oauth-client-node/@atproto/oauth-client": ["@atproto/oauth-client@0.5.11", "", { "dependencies": { "@atproto-labs/did-resolver": "0.2.4", "@atproto-labs/fetch": "0.2.3", "@atproto-labs/handle-resolver": "0.3.4", "@atproto-labs/identity-resolver": "0.3.4", "@atproto-labs/simple-store": "0.3.0", "@atproto-labs/simple-store-memory": "0.1.4", "@atproto/did": "0.2.3", "@atproto/jwk": "0.6.0", "@atproto/oauth-types": "0.5.2", "@atproto/xrpc": "0.7.7", "core-js": "^3", "multiformats": "^9.9.0", "zod": "^3.23.8" } }, "sha512-KyxKpnF988BI3m+4NNYDgkN6a2sPORD9uaOEGP4tnJLOvhMVHyATWwq3Jx4LOYotTFDOvLdheWcI1G9DozE88w=="],
1971
2175
1972
-
"vite/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ=="],
2176
+
"app/@atproto/oauth-client-node/@atproto/oauth-types": ["@atproto/oauth-types@0.5.2", "", { "dependencies": { "@atproto/did": "0.2.3", "@atproto/jwk": "0.6.0", "zod": "^3.23.8" } }, "sha512-9DCDvtvCanTwAaU5UakYDO0hzcOITS3RutK5zfLytE5Y9unj0REmTDdN8Xd8YCfUJl7T/9pYpf04Uyq7bFTASg=="],
1973
2177
1974
-
"vite/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.12", "", { "os": "linux", "cpu": "arm" }, "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw=="],
2178
+
"eslint/ajv/json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="],
1975
2179
1976
-
"vite/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ=="],
2180
+
"next/postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
1977
2181
1978
-
"vite/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.12", "", { "os": "linux", "cpu": "ia32" }, "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA=="],
2182
+
"tsx/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.1", "", { "os": "aix", "cpu": "ppc64" }, "sha512-HHB50pdsBX6k47S4u5g/CaLjqS3qwaOVE5ILsq64jyzgMhLuCuZ8rGzM9yhsAjfjkbgUPMzZEPa7DAp7yz6vuA=="],
1979
2183
1980
-
"vite/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng=="],
2184
+
"tsx/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.27.1", "", { "os": "android", "cpu": "arm" }, "sha512-kFqa6/UcaTbGm/NncN9kzVOODjhZW8e+FRdSeypWe6j33gzclHtwlANs26JrupOntlcWmB0u8+8HZo8s7thHvg=="],
1981
2185
1982
-
"vite/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw=="],
2186
+
"tsx/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.1", "", { "os": "android", "cpu": "arm64" }, "sha512-45fuKmAJpxnQWixOGCrS+ro4Uvb4Re9+UTieUY2f8AEc+t7d4AaZ6eUJ3Hva7dtrxAAWHtlEFsXFMAgNnGU9uQ=="],
1983
2187
1984
-
"vite/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA=="],
2188
+
"tsx/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.27.1", "", { "os": "android", "cpu": "x64" }, "sha512-LBEpOz0BsgMEeHgenf5aqmn/lLNTFXVfoWMUox8CtWWYK9X4jmQzWjoGoNb8lmAYml/tQ/Ysvm8q7szu7BoxRQ=="],
1985
2189
1986
-
"vite/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w=="],
2190
+
"tsx/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-veg7fL8eMSCVKL7IW4pxb54QERtedFDfY/ASrumK/SbFsXnRazxY4YykN/THYqFnFwJ0aVjiUrVG2PwcdAEqQQ=="],
1987
2191
1988
-
"vite/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg=="],
2192
+
"tsx/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-+3ELd+nTzhfWb07Vol7EZ+5PTbJ/u74nC6iv4/lwIU99Ip5uuY6QoIf0Hn4m2HoV0qcnRivN3KSqc+FyCHjoVQ=="],
1989
2193
1990
-
"vite/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.12", "", { "os": "linux", "cpu": "x64" }, "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw=="],
2194
+
"tsx/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.1", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-/8Rfgns4XD9XOSXlzUDepG8PX+AVWHliYlUkFI3K3GB6tqbdjYqdhcb4BKRd7C0BhZSoaCxhv8kTcBrcZWP+xg=="],
1991
2195
1992
-
"vite/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg=="],
2196
+
"tsx/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-GITpD8dK9C+r+5yRT/UKVT36h/DQLOHdwGVwwoHidlnA168oD3uxA878XloXebK4Ul3gDBBIvEdL7go9gCUFzQ=="],
1993
2197
1994
-
"vite/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.12", "", { "os": "none", "cpu": "x64" }, "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ=="],
2198
+
"tsx/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.1", "", { "os": "linux", "cpu": "arm" }, "sha512-ieMID0JRZY/ZeCrsFQ3Y3NlHNCqIhTprJfDgSB3/lv5jJZ8FX3hqPyXWhe+gvS5ARMBJ242PM+VNz/ctNj//eA=="],
1995
2199
1996
-
"vite/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.12", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A=="],
2200
+
"tsx/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-W9//kCrh/6in9rWIBdKaMtuTTzNj6jSeG/haWBADqLLa9P8O5YSRDzgD5y9QBok4AYlzS6ARHifAb75V6G670Q=="],
1997
2201
1998
-
"vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw=="],
2202
+
"tsx/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.1", "", { "os": "linux", "cpu": "ia32" }, "sha512-VIUV4z8GD8rtSVMfAj1aXFahsi/+tcoXXNYmXgzISL+KB381vbSTNdeZHHHIYqFyXcoEhu9n5cT+05tRv13rlw=="],
1999
2203
2000
-
"vite/esbuild/@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg=="],
2204
+
"tsx/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.1", "", { "os": "linux", "cpu": "none" }, "sha512-l4rfiiJRN7sTNI//ff65zJ9z8U+k6zcCg0LALU5iEWzY+a1mVZ8iWC1k5EsNKThZ7XCQ6YWtsZ8EWYm7r1UEsg=="],
2001
2205
2002
-
"vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w=="],
2206
+
"tsx/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.1", "", { "os": "linux", "cpu": "none" }, "sha512-U0bEuAOLvO/DWFdygTHWY8C067FXz+UbzKgxYhXC0fDieFa0kDIra1FAhsAARRJbvEyso8aAqvPdNxzWuStBnA=="],
2003
2207
2004
-
"vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg=="],
2208
+
"tsx/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-NzdQ/Xwu6vPSf/GkdmRNsOfIeSGnh7muundsWItmBsVpMoNPVpM61qNzAVY3pZ1glzzAxLR40UyYM23eaDDbYQ=="],
2005
2209
2006
-
"vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.12", "", { "os": "win32", "cpu": "ia32" }, "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ=="],
2210
+
"tsx/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.1", "", { "os": "linux", "cpu": "none" }, "sha512-7zlw8p3IApcsN7mFw0O1Z1PyEk6PlKMu18roImfl3iQHTnr/yAfYv6s4hXPidbDoI2Q0pW+5xeoM4eTCC0UdrQ=="],
2007
2211
2008
-
"vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="],
2212
+
"tsx/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-cGj5wli+G+nkVQdZo3+7FDKC25Uh4ZVwOAK6A06Hsvgr8WqBBuOy/1s+PUEd/6Je+vjfm6stX0kmib5b/O2Ykw=="],
2009
2213
2010
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="],
2214
+
"tsx/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.1", "", { "os": "linux", "cpu": "x64" }, "sha512-z3H/HYI9MM0HTv3hQZ81f+AKb+yEoCRlUby1F80vbQ5XdzEMyY/9iNlAmhqiBKw4MJXwfgsh7ERGEOhrM1niMA=="],
2011
2215
2012
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="],
2216
+
"tsx/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.1", "", { "os": "none", "cpu": "x64" }, "sha512-1YQ8ybGi2yIXswu6eNzJsrYIGFpnlzEWRl6iR5gMgmsrR0FcNoV1m9k9sc3PuP5rUBLshOZylc9nqSgymI+TYg=="],
2013
2217
2014
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.12", "", { "os": "android", "cpu": "arm64" }, "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg=="],
2218
+
"tsx/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.1", "", { "os": "openbsd", "cpu": "x64" }, "sha512-Q73ENzIdPF5jap4wqLtsfh8YbYSZ8Q0wnxplOlZUOyZy7B4ZKW8DXGWgTCZmF8VWD7Tciwv5F4NsRf6vYlZtqg=="],
2015
2219
2016
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.25.12", "", { "os": "android", "cpu": "x64" }, "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg=="],
2220
+
"tsx/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.1", "", { "os": "sunos", "cpu": "x64" }, "sha512-IPUW+y4VIjuDVn+OMzHc5FV4GubIwPnsz6ubkvN8cuhEqH81NovB53IUlrlBkPMEPxvNnf79MGBoz8rZ2iW8HA=="],
2017
2221
2018
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg=="],
2222
+
"tsx/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-RIVRWiljWA6CdVu8zkWcRmGP7iRRIIwvhDKem8UMBjPql2TXM5PkDVvvrzMtj1V+WFPB4K7zkIGM7VzRtFkjdg=="],
2019
2223
2020
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA=="],
2224
+
"tsx/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-2BR5M8CPbptC1AK5JbJT1fWrHLvejwZidKx3UMSF0ecHMa+smhi16drIrCEggkgviBwLYd5nwrFLSl5Kho96RQ=="],
2021
2225
2022
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.12", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg=="],
2226
+
"tsx/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.1", "", { "os": "win32", "cpu": "x64" }, "sha512-d5X6RMYv6taIymSk8JBP+nxv8DQAMY6A51GPgusqLdK9wBz5wWIXy1KjTck6HnjE9hqJzJRdk+1p/t5soSbCtw=="],
2023
2227
2024
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ=="],
2228
+
"web/@types/bun/bun-types": ["bun-types@1.3.4", "", { "dependencies": { "@types/node": "*" } }, "sha512-5ua817+BZPZOlNaRgGBpZJOSAQ9RQ17pkwPD0yR7CfJg+r8DgIILByFifDTa+IPDDxzf5VNhtNlcKqFzDgJvlQ=="],
2025
2229
2026
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.12", "", { "os": "linux", "cpu": "arm" }, "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw=="],
2230
+
"@cookware/database/@libsql/client/libsql/@libsql/darwin-arm64": ["@libsql/darwin-arm64@0.5.22", "", { "os": "darwin", "cpu": "arm64" }, "sha512-4B8ZlX3nIDPndfct7GNe0nI3Yw6ibocEicWdC4fvQbSs/jdq/RC2oCsoJxJ4NzXkvktX70C1J4FcmmoBy069UA=="],
2027
2231
2028
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ=="],
2232
+
"@cookware/database/@libsql/client/libsql/@libsql/darwin-x64": ["@libsql/darwin-x64@0.5.22", "", { "os": "darwin", "cpu": "x64" }, "sha512-ny2HYWt6lFSIdNFzUFIJ04uiW6finXfMNJ7wypkAD8Pqdm6nAByO+Fdqu8t7sD0sqJGeUCiOg480icjyQ2/8VA=="],
2029
2233
2030
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.12", "", { "os": "linux", "cpu": "ia32" }, "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA=="],
2234
+
"@cookware/database/@libsql/client/libsql/@libsql/linux-arm64-gnu": ["@libsql/linux-arm64-gnu@0.5.22", "", { "os": "linux", "cpu": "arm64" }, "sha512-KSdnOMy88c9mpOFKUEzPskSaF3VLflfSUCBwas/pn1/sV3pEhtMF6H8VUCd2rsedwoukeeCSEONqX7LLnQwRMA=="],
2031
2235
2032
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng=="],
2236
+
"@cookware/database/@libsql/client/libsql/@libsql/linux-arm64-musl": ["@libsql/linux-arm64-musl@0.5.22", "", { "os": "linux", "cpu": "arm64" }, "sha512-mCHSMAsDTLK5YH//lcV3eFEgiR23Ym0U9oEvgZA0667gqRZg/2px+7LshDvErEKv2XZ8ixzw3p1IrBzLQHGSsw=="],
2033
2237
2034
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw=="],
2238
+
"@cookware/database/@libsql/client/libsql/@libsql/linux-x64-gnu": ["@libsql/linux-x64-gnu@0.5.22", "", { "os": "linux", "cpu": "x64" }, "sha512-kNBHaIkSg78Y4BqAdgjcR2mBilZXs4HYkAmi58J+4GRwDQZh5fIUWbnQvB9f95DkWUIGVeenqLRFY2pcTmlsew=="],
2035
2239
2036
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA=="],
2240
+
"@cookware/database/@libsql/client/libsql/@libsql/linux-x64-musl": ["@libsql/linux-x64-musl@0.5.22", "", { "os": "linux", "cpu": "x64" }, "sha512-UZ4Xdxm4pu3pQXjvfJiyCzZop/9j/eA2JjmhMaAhe3EVLH2g11Fy4fwyUp9sT1QJYR1kpc2JLuybPM0kuXv/Tg=="],
2037
2241
2038
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w=="],
2242
+
"@cookware/database/@libsql/client/libsql/@libsql/win32-x64-msvc": ["@libsql/win32-x64-msvc@0.5.22", "", { "os": "win32", "cpu": "x64" }, "sha512-Fj0j8RnBpo43tVZUVoNK6BV/9AtDUM5S7DF3LB4qTYg1LMSZqi3yeCneUTLJD6XomQJlZzbI4mst89yspVSAnA=="],
2039
2243
2040
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg=="],
2244
+
"@cookware/tsconfig/@types/bun/bun-types/@types/node": ["@types/node@24.10.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-WOhQTZ4G8xZ1tjJTvKOpyEVSGgOTvJAfDK3FNFgELyaTpzhdgHVHeqW8V+UJvzF5BT+/B54T/1S2K6gd9c7bbA=="],
2041
2245
2042
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.12", "", { "os": "linux", "cpu": "x64" }, "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw=="],
2246
+
"@inquirer/core/wrap-ansi/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
2043
2247
2044
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg=="],
2248
+
"@inquirer/core/wrap-ansi/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
2045
2249
2046
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.12", "", { "os": "none", "cpu": "x64" }, "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ=="],
2250
+
"app/@atproto/oauth-client-node/@atproto-labs/did-resolver/@atproto-labs/simple-store-memory": ["@atproto-labs/simple-store-memory@0.1.4", "", { "dependencies": { "@atproto-labs/simple-store": "0.3.0", "lru-cache": "^10.2.0" } }, "sha512-3mKY4dP8I7yKPFj9VKpYyCRzGJOi5CEpOLPlRhoJyLmgs3J4RzDrjn323Oakjz2Aj2JzRU/AIvWRAZVhpYNJHw=="],
2047
2251
2048
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.12", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A=="],
2252
+
"app/@atproto/oauth-client-node/@atproto-labs/handle-resolver-node/@atproto-labs/fetch-node": ["@atproto-labs/fetch-node@0.2.0", "", { "dependencies": { "@atproto-labs/fetch": "0.2.3", "@atproto-labs/pipe": "0.1.1", "ipaddr.js": "^2.1.0", "undici": "^6.14.1" } }, "sha512-Krq09nH/aeoiU2s9xdHA0FjTEFWG9B5FFenipv1iRixCcPc7V3DhTNDawxG9gI8Ny0k4dBVS9WTRN/IDzBx86Q=="],
2049
2253
2050
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw=="],
2254
+
"app/@atproto/oauth-client-node/@atproto-labs/handle-resolver-node/@atproto-labs/handle-resolver": ["@atproto-labs/handle-resolver@0.3.4", "", { "dependencies": { "@atproto-labs/simple-store": "0.3.0", "@atproto-labs/simple-store-memory": "0.1.4", "@atproto/did": "0.2.3", "zod": "^3.23.8" } }, "sha512-wsNopfzfgO3uPvfnFDgNeXgDufXxSXhjBjp2WEiSzEiLrMy0Jodnqggw4OzD9MJKf0a4Iu2/ydd537qdy91LrQ=="],
2051
2255
2052
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg=="],
2256
+
"app/@atproto/oauth-client-node/@atproto/oauth-client/@atproto-labs/handle-resolver": ["@atproto-labs/handle-resolver@0.3.4", "", { "dependencies": { "@atproto-labs/simple-store": "0.3.0", "@atproto-labs/simple-store-memory": "0.1.4", "@atproto/did": "0.2.3", "zod": "^3.23.8" } }, "sha512-wsNopfzfgO3uPvfnFDgNeXgDufXxSXhjBjp2WEiSzEiLrMy0Jodnqggw4OzD9MJKf0a4Iu2/ydd537qdy91LrQ=="],
2053
2257
2054
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w=="],
2258
+
"app/@atproto/oauth-client-node/@atproto/oauth-client/@atproto-labs/identity-resolver": ["@atproto-labs/identity-resolver@0.3.4", "", { "dependencies": { "@atproto-labs/did-resolver": "0.2.4", "@atproto-labs/handle-resolver": "0.3.4" } }, "sha512-HNUEFQIo2ws6iATxmgHd5D5rAsWYupgxZucgwolVHPiMjE1SY+EmxEsfbEN1wDEzM8/u9AKUg/jrxxPEwsgbew=="],
2055
2259
2056
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg=="],
2260
+
"app/@atproto/oauth-client-node/@atproto/oauth-client/@atproto-labs/simple-store-memory": ["@atproto-labs/simple-store-memory@0.1.4", "", { "dependencies": { "@atproto-labs/simple-store": "0.3.0", "lru-cache": "^10.2.0" } }, "sha512-3mKY4dP8I7yKPFj9VKpYyCRzGJOi5CEpOLPlRhoJyLmgs3J4RzDrjn323Oakjz2Aj2JzRU/AIvWRAZVhpYNJHw=="],
2057
2261
2058
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.12", "", { "os": "win32", "cpu": "ia32" }, "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ=="],
2262
+
"app/@atproto/oauth-client-node/@atproto/oauth-client/@atproto/xrpc": ["@atproto/xrpc@0.7.7", "", { "dependencies": { "@atproto/lexicon": "^0.6.0", "zod": "^3.23.8" } }, "sha512-K1ZyO/BU8JNtXX5dmPp7b5UrkLMMqpsIa/Lrj5D3Su+j1Xwq1m6QJ2XJ1AgjEjkI1v4Muzm7klianLE6XGxtmA=="],
2059
2263
2060
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="],
2264
+
"web/@types/bun/bun-types/@types/node": ["@types/node@24.10.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-WOhQTZ4G8xZ1tjJTvKOpyEVSGgOTvJAfDK3FNFgELyaTpzhdgHVHeqW8V+UJvzF5BT+/B54T/1S2K6gd9c7bbA=="],
2061
2265
2062
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="],
2063
-
2064
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="],
2065
-
2066
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.12", "", { "os": "android", "cpu": "arm64" }, "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg=="],
2067
-
2068
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.25.12", "", { "os": "android", "cpu": "x64" }, "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg=="],
2069
-
2070
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg=="],
2071
-
2072
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA=="],
2073
-
2074
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.12", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg=="],
2075
-
2076
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ=="],
2077
-
2078
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.12", "", { "os": "linux", "cpu": "arm" }, "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw=="],
2079
-
2080
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ=="],
2081
-
2082
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.12", "", { "os": "linux", "cpu": "ia32" }, "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA=="],
2083
-
2084
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng=="],
2085
-
2086
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw=="],
2087
-
2088
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA=="],
2266
+
"@cookware/tsconfig/@types/bun/bun-types/@types/node/undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
2089
2267
2090
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w=="],
2268
+
"app/@atproto/oauth-client-node/@atproto-labs/did-resolver/@atproto-labs/simple-store-memory/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
2091
2269
2092
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg=="],
2270
+
"app/@atproto/oauth-client-node/@atproto-labs/handle-resolver-node/@atproto-labs/handle-resolver/@atproto-labs/simple-store-memory": ["@atproto-labs/simple-store-memory@0.1.4", "", { "dependencies": { "@atproto-labs/simple-store": "0.3.0", "lru-cache": "^10.2.0" } }, "sha512-3mKY4dP8I7yKPFj9VKpYyCRzGJOi5CEpOLPlRhoJyLmgs3J4RzDrjn323Oakjz2Aj2JzRU/AIvWRAZVhpYNJHw=="],
2093
2271
2094
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.12", "", { "os": "linux", "cpu": "x64" }, "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw=="],
2272
+
"app/@atproto/oauth-client-node/@atproto/oauth-client/@atproto-labs/simple-store-memory/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
2095
2273
2096
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg=="],
2274
+
"app/@atproto/oauth-client-node/@atproto/oauth-client/@atproto/xrpc/@atproto/lexicon": ["@atproto/lexicon@0.6.0", "", { "dependencies": { "@atproto/common-web": "^0.4.7", "@atproto/syntax": "^0.4.2", "iso-datestring-validator": "^2.2.2", "multiformats": "^9.9.0", "zod": "^3.23.8" } }, "sha512-5veb8aD+J5M0qszLJ+73KSFsFrJBgAY/nM1TSAJvGY7fNc9ZAT+PSUlmIyrdye9YznAZ07yktalls/TwNV7cHQ=="],
2097
2275
2098
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.12", "", { "os": "none", "cpu": "x64" }, "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ=="],
2276
+
"web/@types/bun/bun-types/@types/node/undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
2099
2277
2100
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.12", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A=="],
2278
+
"app/@atproto/oauth-client-node/@atproto-labs/handle-resolver-node/@atproto-labs/handle-resolver/@atproto-labs/simple-store-memory/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
2101
2279
2102
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw=="],
2280
+
"app/@atproto/oauth-client-node/@atproto/oauth-client/@atproto/xrpc/@atproto/lexicon/@atproto/common-web": ["@atproto/common-web@0.4.7", "", { "dependencies": { "@atproto/lex-data": "0.0.3", "@atproto/lex-json": "0.0.3", "zod": "^3.23.8" } }, "sha512-vjw2+81KPo2/SAbbARGn64Ln+6JTI0FTI4xk8if0ebBfDxFRmHb2oSN1y77hzNq/ybGHqA2mecfhS03pxC5+lg=="],
2103
2281
2104
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg=="],
2105
-
2106
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w=="],
2107
-
2108
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg=="],
2109
-
2110
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.12", "", { "os": "win32", "cpu": "ia32" }, "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ=="],
2111
-
2112
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="],
2113
-
2114
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="],
2115
-
2116
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="],
2117
-
2118
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.12", "", { "os": "android", "cpu": "arm64" }, "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg=="],
2119
-
2120
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.25.12", "", { "os": "android", "cpu": "x64" }, "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg=="],
2121
-
2122
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg=="],
2123
-
2124
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA=="],
2125
-
2126
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.12", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg=="],
2127
-
2128
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ=="],
2129
-
2130
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.12", "", { "os": "linux", "cpu": "arm" }, "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw=="],
2131
-
2132
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ=="],
2133
-
2134
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.12", "", { "os": "linux", "cpu": "ia32" }, "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA=="],
2135
-
2136
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng=="],
2137
-
2138
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw=="],
2139
-
2140
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA=="],
2141
-
2142
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w=="],
2143
-
2144
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg=="],
2145
-
2146
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.12", "", { "os": "linux", "cpu": "x64" }, "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw=="],
2147
-
2148
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg=="],
2149
-
2150
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.12", "", { "os": "none", "cpu": "x64" }, "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ=="],
2151
-
2152
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.12", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A=="],
2153
-
2154
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw=="],
2155
-
2156
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg=="],
2157
-
2158
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w=="],
2159
-
2160
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg=="],
2161
-
2162
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.12", "", { "os": "win32", "cpu": "ia32" }, "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ=="],
2163
-
2164
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="],
2165
-
2166
-
"@tanstack/router-plugin/chokidar/readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
2167
-
2168
-
"tailwindcss/chokidar/readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
2282
+
"app/@atproto/oauth-client-node/@atproto/oauth-client/@atproto/xrpc/@atproto/lexicon/@atproto/syntax": ["@atproto/syntax@0.4.2", "", {}, "sha512-X9XSRPinBy/0VQ677j8VXlBsYSsUXaiqxWVpGGxJYsAhugdQRb0jqaVKJFtm6RskeNkV6y9xclSUi9UYG/COrA=="],
2169
2283
}
2170
2284
}
+12
-54
config/dev/caddy/Caddyfile
+12
-54
config/dev/caddy/Caddyfile
···
1
1
{
2
2
storage file_system /data/
3
3
debug
4
-
pki {
5
-
ca recipesblue {
6
-
name "Recipes.blue Local Development CA"
7
-
}
8
-
}
9
4
}
10
5
11
-
api.local.recipes.blue {
12
-
tls {
13
-
issuer internal {
14
-
ca recipesblue
15
-
}
16
-
}
17
-
18
-
reverse_proxy http://host.docker.internal:8080
6
+
(tls_config) {
7
+
tls /tls/dev.crt /tls/dev.key {
8
+
ca_root /tls/ca.crt
9
+
}
19
10
}
20
11
21
-
local.recipes.blue {
22
-
tls {
23
-
issuer internal {
24
-
ca recipesblue
25
-
}
26
-
}
27
-
28
-
reverse_proxy http://host.docker.internal:5173
29
-
30
-
handle_path /xrpc/* {
31
-
rewrite * /xrpc{uri}
32
-
reverse_proxy http://host.docker.internal:8080
33
-
}
34
-
handle_path /api/* {
35
-
rewrite * /api{uri}
36
-
reverse_proxy http://host.docker.internal:8080
37
-
}
12
+
api.local.recipes.blue {
13
+
import tls_config
14
+
reverse_proxy http://host.docker.internal:8787
38
15
}
39
16
40
-
http://*.trycloudflare.com {
17
+
local.recipes.blue {
18
+
import tls_config
41
19
reverse_proxy http://host.docker.internal:5173
42
20
43
21
handle_path /xrpc/* {
44
22
rewrite * /xrpc{uri}
45
-
reverse_proxy http://host.docker.internal:8080
46
-
}
47
-
handle_path /oauth/* {
48
-
rewrite * /oauth{uri}
49
-
reverse_proxy http://host.docker.internal:8080
23
+
reverse_proxy http://host.docker.internal:8787
50
24
}
51
25
handle_path /api/* {
52
26
rewrite * /api{uri}
53
-
reverse_proxy http://host.docker.internal:8080
27
+
reverse_proxy http://host.docker.internal:8787
54
28
}
55
29
}
56
30
57
-
acme.local.recipes.blue {
58
-
tls {
59
-
issuer internal {
60
-
ca recipesblue
61
-
}
62
-
}
63
-
acme_server {
64
-
ca recipesblue
65
-
}
66
-
}
67
-
68
31
turso.local.recipes.blue {
69
-
tls {
70
-
issuer internal {
71
-
ca recipesblue
72
-
}
73
-
}
74
-
32
+
import tls_config
75
33
reverse_proxy http://libsql:8080
76
34
}
+2
-1
config/dev/caddy/compose.yaml
+2
-1
config/dev/caddy/compose.yaml
+13
config/dev/db/compose.yaml
+13
config/dev/db/compose.yaml
-13
config/dev/libsql/compose.yaml
-13
config/dev/libsql/compose.yaml
+29
config/dev/pki/ca.crt
+29
config/dev/pki/ca.crt
···
1
+
-----BEGIN CERTIFICATE-----
2
+
MIIE/DCCA2SgAwIBAgIRALK0p95iJHmmXOWjMAS7T4swDQYJKoZIhvcNAQELBQAw
3
+
gZUxHjAcBgNVBAoTFW1rY2VydCBkZXZlbG9wbWVudCBDQTE1MDMGA1UECwwsaGF5
4
+
ZGVuQEhBWURFTi1XMTEubG9jYWxkb21haW4gKEhheWRlbiBZb3VuZykxPDA6BgNV
5
+
BAMMM21rY2VydCBoYXlkZW5ASEFZREVOLVcxMS5sb2NhbGRvbWFpbiAoSGF5ZGVu
6
+
IFlvdW5nKTAeFw0yNTExMjIyMjIyNTdaFw0zNTExMjIyMjIyNTdaMIGVMR4wHAYD
7
+
VQQKExVta2NlcnQgZGV2ZWxvcG1lbnQgQ0ExNTAzBgNVBAsMLGhheWRlbkBIQVlE
8
+
RU4tVzExLmxvY2FsZG9tYWluIChIYXlkZW4gWW91bmcpMTwwOgYDVQQDDDNta2Nl
9
+
cnQgaGF5ZGVuQEhBWURFTi1XMTEubG9jYWxkb21haW4gKEhheWRlbiBZb3VuZykw
10
+
ggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCzcORfQsG3VWrZ8GnJZZhB
11
+
FTtjV/A+LllaUlt2GIjAf9eBMIct7C4GoVfUSG8V5C3UMHMDpoZZCSJym2NyndOV
12
+
CI1O/pr8sC4klVGetny/GxO443tn6z5Xz/BHsXSrE35igIO1p8S2xYctlXYq/cdE
13
+
N5PsceQEg2p5K/EsBpcXEM1gMfUXB+v7nUhNx5AO+z+kZzSNkcmPYigwxq/pm3iM
14
+
H8vYqhmZCT9zD7+FUFsBgbEf/bLU41xium21zdqzS7aoG2rypRoDvbaWbEvqZoJO
15
+
2VBnqBwI2aaMqCJ+Lc2VwLOYHNqu6iisTMzaNLbj2dr8Uvatem3yZvB+ACPzpQ8O
16
+
zIQp5gjKZQ6nC2/1kvLIo9g5g2mCyG2hphadv/ubPmxaqe0w/PobngQFt5SbO2au
17
+
mguvKFRa4FEm/Dy215+1Hil3owQkSGEREQMLS+t8TorBw7bgXUF8iSEiZS6JYabD
18
+
yHYr8oBl/axDaAfCPkH4KGcjVf4vxOK255RbIBoCIksCAwEAAaNFMEMwDgYDVR0P
19
+
AQH/BAQDAgIEMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFKfqTnO4509h
20
+
3YIiTC2EnnZYLG1fMA0GCSqGSIb3DQEBCwUAA4IBgQBSRKsZyGQoxcONbYrTVK82
21
+
PAeOnYwlk27vPhhYbSTfgJRS5v3om9brccAVSPbZX4WXT5f/ibvLja0o7zU3RmxJ
22
+
D5M4narw76fRXNzHjHfU6PRqDqLzJhPWM/V0IuQotU6kxEoNrfg9a1buB4lqldXr
23
+
xqAarNM7kb0UXB/Wi1paKBk8o9CIvfoDP0kHoZHapBN6VWsJyPaTDfSH0roUfU+H
24
+
jsm75nTXMI6h7eI5jo7FJcut1wbBpSiHdvmr4BX2SOGPHbSYCACirGExADKa4ULz
25
+
AdhDBtBGEBtjzIKi9cLFTZY9bHFQsrwhegEDJwZs/ZH931q+f3ciE2og7qqE0drZ
26
+
zZrmjY9QdOagSNRWw1089jG02333wtdgH+eJbYqVaKxB+vpBMUP72HEDS4WOh1E6
27
+
nLNjqm6cZ4bW8I5gfsIDvcsmSGWdHaZLWvXcO20G2ySyfd/64L5+VHAs5rtbbzZr
28
+
TR3BleuWVc5lMCAQtdoMAcy7UFPdUzSxHdrATc/Y/uQ=
29
+
-----END CERTIFICATE-----
+40
config/dev/pki/ca.key
+40
config/dev/pki/ca.key
···
1
+
-----BEGIN PRIVATE KEY-----
2
+
MIIG/QIBADANBgkqhkiG9w0BAQEFAASCBucwggbjAgEAAoIBgQCzcORfQsG3VWrZ
3
+
8GnJZZhBFTtjV/A+LllaUlt2GIjAf9eBMIct7C4GoVfUSG8V5C3UMHMDpoZZCSJy
4
+
m2NyndOVCI1O/pr8sC4klVGetny/GxO443tn6z5Xz/BHsXSrE35igIO1p8S2xYct
5
+
lXYq/cdEN5PsceQEg2p5K/EsBpcXEM1gMfUXB+v7nUhNx5AO+z+kZzSNkcmPYigw
6
+
xq/pm3iMH8vYqhmZCT9zD7+FUFsBgbEf/bLU41xium21zdqzS7aoG2rypRoDvbaW
7
+
bEvqZoJO2VBnqBwI2aaMqCJ+Lc2VwLOYHNqu6iisTMzaNLbj2dr8Uvatem3yZvB+
8
+
ACPzpQ8OzIQp5gjKZQ6nC2/1kvLIo9g5g2mCyG2hphadv/ubPmxaqe0w/PobngQF
9
+
t5SbO2aumguvKFRa4FEm/Dy215+1Hil3owQkSGEREQMLS+t8TorBw7bgXUF8iSEi
10
+
ZS6JYabDyHYr8oBl/axDaAfCPkH4KGcjVf4vxOK255RbIBoCIksCAwEAAQKCAYAI
11
+
6Yd+L7udVnG7J1SpuxEH0n0jnv+Apx6q/MIsKGXKYc8bTIS6RCu5CpRpJ7vUs4OP
12
+
MWTU/pVXoLuEQ7F5xNr4YPdbwAuEl1+DU6M9JcUmXLrrCOldLPLou5wsg2TPBmXV
13
+
kJp6ED4V8dOX8P9wfTBDdBs1uCZiDwDfyc3tqNoiPCRnLbQFk9AlrBcmPc4q4FG1
14
+
4aZbja0cIPzsB0I/cQhYtU+TkEc7MZlkJpkVjvsmJQHeG+Sg7DXvdWDzkajWFOGF
15
+
RobzHS/C+9xrybTMTr/nBWFY0rzeJNkNVAK1qQMKgkK+M+WihQYlH/x9XbNDzccx
16
+
zDDU1Vn1c7WnrHiLN2m3SKgT/0NNxgZoQknOkR0kkTzAkBoco/T+/Li4M+y+jCnC
17
+
yptMScwcAJL5whkWVWrE8jtD6gjqqK+NKMkE4UI/4cRj1eB49uVuixhg5VQmEeG8
18
+
SdicfxOrnypdMthTCtxr1zoK4uRvd6XkysZUq+bneIvkykWp8IL4RA0gM4oKzFkC
19
+
gcEA0hXSYoJK2yxQBmSUB3KXbMO3Yg2WGw5m5EgXPIGMd0gwJ7ALzFsJRd7AvVO/
20
+
mlEpDkYAGWCYE94RiVN36S3XHl0jh6z2RXHZvCe5/l4Jwr0AnoL+AhPxOO6OwR5e
21
+
rnqwRYkbqI/sCsJXHKnQ5zUIgnVpgbTxdymoblM3lPcisPTxHTqCqKJ6mu97CVQk
22
+
OqmpqklDOyk/LOe/E2/wWDu1EdkD+a+BmWRadTzAv07dZ0Vq/m0gWp7iE+cG61V3
23
+
9HDnAoHBANqoiZHG4ROtXhih0qA3TXKJ99sMWflMh+vt2AD3n3S5YOBKh8EU7f9P
24
+
zE0nYpo5Qq0OkLom/Gwgp1JBiTlsDkeMSqOwwFQ9rCA8qCKMT68fcZ1LPW9loWDL
25
+
sA6Z1LpbvMs/pD1jWZV74jUt8ZmPNSsKvdmqsHXzrG4TQoEZGtopWyWdQSlGO5pY
26
+
q3qPA/EG+Asp2F3kzBFGd4Ax6xHU5mSm3OnAzqNhc26jNM8CTUG7KQad9SyrjegN
27
+
vA4jA7VC/QKBwC2cyUnUChad/13z9mPLkG7v61/hnUaQkOxdbpYXdnzrcnEbeuRK
28
+
m6/M1kIE7eO+XVCZCCp6W2ps25faRH2fE0anaDBr8ChRuLluUqaUmj/qszi3Lhkb
29
+
ZVM8EEiDpIDzaFQgmZ22acRIP4ucnxuj2w4gGeEsfQSnScdyT+4K3kBXXgY/juC4
30
+
LjB3cFotJ5SJA6pSL8Onh+zjAAxjUGaHyB9w47kRTu0T6cPshdjDcbSbUMievtiO
31
+
CH3Tuh/cNagf3wKBwQDPOXbXPyJEYcORmJti18aATJ0nbbc/evY99DUIBaWLG7zi
32
+
FABATrOXiWrXnAHoo2e7Vth2c0g6uV+Zpx6D2xJVYHHEXFiJ/cDI9HNr+onyL9ye
33
+
85WPo0Oj1qZN0CA5VYPBI9lljGh0MOoa+CXGIGCFIDL4vLlrr7m0wHAApWg7ZYJK
34
+
TZRZp4QJLQumpS9ZF/+vpMK3iYSUwrGyPpzHU3vd2/31UpMDZ/Hb4rTDkyzgpJ2m
35
+
9cBLy3I7f/i/dROoj4kCgcACSTKfxzg8sWORWu5amTGMOoTlSfJzgi0f//koqiFN
36
+
hqD77Srt23hzCqI2P7KniSwtLkyUFpW82Sq3TmkDkfiDJ4bywXjS6V9N/C3N7GGG
37
+
iDw9wVHZFLy/d0aTnnkXKre38IVC2L7bX2gDEVr3cEYuKfFHfn6S3eLxYlf/uVzW
38
+
vZYLaWra+fTpZn/TTsEu5Qf/By0jDqwmckBuaGQkpSUPVC6VCdJdkLj/P8KX/WEK
39
+
Z2CAgvzTduQVyoeY0sSM0dA=
40
+
-----END PRIVATE KEY-----
+27
config/dev/pki/dev.crt
+27
config/dev/pki/dev.crt
···
1
+
-----BEGIN CERTIFICATE-----
2
+
MIIEfjCCAuagAwIBAgIRAMooUps4l++//kLhRuQXNKIwDQYJKoZIhvcNAQELBQAw
3
+
gZUxHjAcBgNVBAoTFW1rY2VydCBkZXZlbG9wbWVudCBDQTE1MDMGA1UECwwsaGF5
4
+
ZGVuQEhBWURFTi1XMTEubG9jYWxkb21haW4gKEhheWRlbiBZb3VuZykxPDA6BgNV
5
+
BAMMM21rY2VydCBoYXlkZW5ASEFZREVOLVcxMS5sb2NhbGRvbWFpbiAoSGF5ZGVu
6
+
IFlvdW5nKTAeFw0yNTExMjIyMjIzMThaFw0yODAyMjIyMjIzMThaMGAxJzAlBgNV
7
+
BAoTHm1rY2VydCBkZXZlbG9wbWVudCBjZXJ0aWZpY2F0ZTE1MDMGA1UECwwsaGF5
8
+
ZGVuQEhBWURFTi1XMTEubG9jYWxkb21haW4gKEhheWRlbiBZb3VuZykwggEiMA0G
9
+
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDSkRNRv4sBJbigX3Xiekg2eBk5ivz5
10
+
tJ7VRPTYGCH2hqkyTvuiO44iX/CI0OKsDTxiCTzr2zaDQ6/bEAsK+NuIGUA7Lo81
11
+
MWsGphiEfyHGK5j0oI8Rg5c9Vh7InXaoAdouJ8JTZlnjLbSEv3l1fLcY+BBNBfvK
12
+
soF4KMhSyoXULsdnc5sTU1iXvhi0+330py7KYlW4KM1nb5ucQ7EYb/fWNmqmINTi
13
+
4agepceTvfV9/lkCGlwvAYUeYkiZsR2DM0j1zwiH7NVlitASjoUqP/IjzWqTd7xu
14
+
NeDTyy0srJmu/CYG8GBi/w1lNSk0WPpT6R3i76/RmRZqU4sApJVbaWkFAgMBAAGj
15
+
fTB7MA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAfBgNVHSME
16
+
GDAWgBSn6k5zuOdPYd2CIkwthJ52WCxtXzAzBgNVHREELDAqghJsb2NhbC5yZWNp
17
+
cGVzLmJsdWWCFCoubG9jYWwucmVjaXBlcy5ibHVlMA0GCSqGSIb3DQEBCwUAA4IB
18
+
gQArUayVybiyLqKslyikxMjg0W0OR6Vl3BOzcHuv0+MQYiU4RXZEy9gB158fRq/A
19
+
oYfGf0VMyP4GXCKDyJUfGiU/d1KQeu2skBK+SnZys6lV2pxtqnTxsJX18HI8bH3g
20
+
jPjP8iQTGk4izkzhP/IMtSO88gVu5YZkQuU/W3uCJEwjsQTwKCx+VbTI0+2iiVw4
21
+
6S8f5dbjRG5cWzRuNOq8YAG42/2wPEhUzxJXsFlxrRXSOP1FlGcJy0QQm6TQ85+l
22
+
D7sYHVKET2d181yWggT1KiKeGKm+pYkNgLKEHXAM0XGmlYAR01ibz2iotguYnz+z
23
+
NgD+rHerqcdIaRLDPUmNYUCbDRpKozT/X6HK9qB3OtGMLFd5nd1S6mS6NisdzZCY
24
+
s7WyCvnvMbExqpMnlX97UPcI0l0RUC/q/feQ+H2TqTD5QWszEvIO0JqEaREEgZ4p
25
+
A0ZMksO4ZDsKMX2eqDLEv+Td9nb/7Kw+ydCjAMDLV11o31WBF0ucA/dV7sdgYFCj
26
+
1NM=
27
+
-----END CERTIFICATE-----
+28
config/dev/pki/dev.key
+28
config/dev/pki/dev.key
···
1
+
-----BEGIN PRIVATE KEY-----
2
+
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDSkRNRv4sBJbig
3
+
X3Xiekg2eBk5ivz5tJ7VRPTYGCH2hqkyTvuiO44iX/CI0OKsDTxiCTzr2zaDQ6/b
4
+
EAsK+NuIGUA7Lo81MWsGphiEfyHGK5j0oI8Rg5c9Vh7InXaoAdouJ8JTZlnjLbSE
5
+
v3l1fLcY+BBNBfvKsoF4KMhSyoXULsdnc5sTU1iXvhi0+330py7KYlW4KM1nb5uc
6
+
Q7EYb/fWNmqmINTi4agepceTvfV9/lkCGlwvAYUeYkiZsR2DM0j1zwiH7NVlitAS
7
+
joUqP/IjzWqTd7xuNeDTyy0srJmu/CYG8GBi/w1lNSk0WPpT6R3i76/RmRZqU4sA
8
+
pJVbaWkFAgMBAAECggEAagiYO/BCpV9Da67mhBejyZoMycdNwMjNuwOwcCkm4SfK
9
+
iATx/i4TUwgQ7jSSEKXRpGSWgwaumsc5BQ09IldS5WQhziuR/e1WwdBeREpozYwi
10
+
x/0aTm1/eWmmsstodw4HunpXBvxhg17+qmJpXVpiMXapbr/2nYnqXIHc7qQBZGkH
11
+
MnuDi6chGw0RBZhySLCHsyth5OHP16/SiV7Am6UaQyi4oG3W/RrVIRsIjoLPj0Hw
12
+
MSPhiv/yq4TIWb4ujnGgNhIcEGJN6tYKWUEdoMjWQwvWZKw1c3G1glfUQGUeS7fH
13
+
0U4XTtPS43j7d5iQoff0gfZwV8wZvUAaRgxfgc7+eQKBgQDTeF48lHbw9lrrMu9P
14
+
YfGiS90v9U25TpOq3qYUEPdwy9ssnTXPS/iJim/IW/B10F/AneqLWPWUawjaLxVF
15
+
tAxMiruE3L4pJfYtbF7x3bWz879fMItlatWIKSwinEXu1NeQMDaTy7P5u+H37+7c
16
+
nQm8KNtIVT29XYalK9pv5Hvg7wKBgQD+6ADj4LA25h0xTcjKBERStMPRESiFE1K7
17
+
ITzp2jvOO68ZKgWSN+8bKpLKQYj40Aivi7Nu22cqlpcZ7/7uETXb6xjVrEfteg3S
18
+
u7FUU9vuwX/0RCtbj8FlV1iaJXdq2XmnQLg2RESYFKc9vHaWdRJ/VCDkDCuNWns0
19
+
IVjlY7OtSwKBgDF/fy9W4PBN+cILzhAasOB4OXG8TVEOn2nja6ROxFxWmxq6QZog
20
+
AjDPgpK3UnWBLKh9TiUH0ZPH6e6IDsad+jMAVhwnPyuKgzDmqOKcLqfMagLx7e7z
21
+
LsAMQxRm18ercjmBz4SQrbPK0n2iX5qr91dfiNRJf4YPmjCXLy35oTVpAoGBAJBT
22
+
5mUgTEXZRwAqjZysi87UYOcYMvweM8KWkDnMgf5EVuEFpP/kQbL9CP4R2y8eAzz5
23
+
+Y+0FJbNiyJ5e7tp7Tfmxjn9gQBaEkeWVFJt5OIrl3pDutTt8U+jBBzLR/Esz6++
24
+
ek7nmnsNfp/6/J42DVIg3TqiFWrEp2ud0gqXyB0/AoGBAMj1p1uknmOoEoqfdJeI
25
+
UqbWE//107MXTAhydpn/iuUKUVw9SiBpmdgA+YZ0ufuPyxy+Uoc25LrLrvA4O7aP
26
+
hy4SJZ/7jq45AK6jPqzJo9FMjB32t5QyWkHlbvbasXA+5AHlriVjC58/EW60K/e3
27
+
Pth8LTDiTKFjWFJWXYkGLtFa
28
+
-----END PRIVATE KEY-----
+12
config/dev/redis/compose.yaml
+12
config/dev/redis/compose.yaml
+2
-9
docker-compose.yaml
+2
-9
docker-compose.yaml
···
1
1
---
2
2
include:
3
-
- path: config/dev/caddy/compose.yaml
4
-
- path: config/dev/libsql/compose.yaml
3
+
- path: config/dev/db/compose.yaml
4
+
- path: config/dev/redis/compose.yaml
5
5
6
6
networks:
7
7
recipesblue:
8
-
9
-
services:
10
-
tunnel:
11
-
image: cloudflare/cloudflared
12
-
restart: unless-stopped
13
-
networks: [recipesblue]
14
-
command: tunnel --url http://caddy
-53
lexicons/app/bsky/actor/profile.json
-53
lexicons/app/bsky/actor/profile.json
···
1
-
{
2
-
"lexicon": 1,
3
-
"id": "app.bsky.actor.profile",
4
-
"defs": {
5
-
"main": {
6
-
"type": "record",
7
-
"description": "A declaration of a Bluesky account profile.",
8
-
"key": "literal:self",
9
-
"record": {
10
-
"type": "object",
11
-
"properties": {
12
-
"displayName": {
13
-
"type": "string",
14
-
"maxGraphemes": 64,
15
-
"maxLength": 640
16
-
},
17
-
"description": {
18
-
"type": "string",
19
-
"description": "Free-form profile description text.",
20
-
"maxGraphemes": 256,
21
-
"maxLength": 2560
22
-
},
23
-
"avatar": {
24
-
"type": "blob",
25
-
"description": "Small image to be displayed next to posts from account. AKA, 'profile picture'",
26
-
"accept": ["image/png", "image/jpeg"],
27
-
"maxSize": 1000000
28
-
},
29
-
"banner": {
30
-
"type": "blob",
31
-
"description": "Larger horizontal image to display behind profile view.",
32
-
"accept": ["image/png", "image/jpeg"],
33
-
"maxSize": 1000000
34
-
},
35
-
"labels": {
36
-
"type": "union",
37
-
"description": "Self-label values, specific to the Bluesky application, on the overall account.",
38
-
"refs": ["com.atproto.label.defs#selfLabels"]
39
-
},
40
-
"joinedViaStarterPack": {
41
-
"type": "ref",
42
-
"ref": "com.atproto.repo.strongRef"
43
-
},
44
-
"pinnedPost": {
45
-
"type": "ref",
46
-
"ref": "com.atproto.repo.strongRef"
47
-
},
48
-
"createdAt": { "type": "string", "format": "datetime" }
49
-
}
50
-
}
51
-
}
52
-
}
53
-
}
-43
lexicons/blue/recipes/feed/defs.json
-43
lexicons/blue/recipes/feed/defs.json
···
1
-
{
2
-
"lexicon": 1,
3
-
"id": "blue.recipes.feed.defs",
4
-
"defs": {
5
-
"ingredient": {
6
-
"type": "object",
7
-
"properties": {
8
-
"name": {
9
-
"type": "string",
10
-
"maxLength": 3000,
11
-
"maxGraphemes": 300,
12
-
"description": "The name of the ingredient."
13
-
},
14
-
"amount": {
15
-
"type": "string",
16
-
"description": "How much of the ingredient is needed."
17
-
}
18
-
}
19
-
},
20
-
"step": {
21
-
"type": "object",
22
-
"required": ["text"],
23
-
"properties": {
24
-
"text": {
25
-
"type": "string",
26
-
"maxLength": 5000,
27
-
"maxGraphemes": 300,
28
-
"description": "The instruction to provide to the user."
29
-
}
30
-
}
31
-
},
32
-
"authorInfo": {
33
-
"type": "object",
34
-
"required": ["did", "handle"],
35
-
"properties": {
36
-
"did": { "type": "string" },
37
-
"handle": { "type": "string" },
38
-
"displayName": { "type": "string" },
39
-
"avatarUrl": { "type": "string" }
40
-
}
41
-
}
42
-
}
43
-
}
-62
lexicons/blue/recipes/feed/getRecipe.json
-62
lexicons/blue/recipes/feed/getRecipe.json
···
1
-
{
2
-
"lexicon": 1,
3
-
"id": "blue.recipes.feed.getRecipe",
4
-
"defs": {
5
-
"main": {
6
-
"type": "query",
7
-
"description": "Gets a recipe from the index by author DID and rkey.",
8
-
"parameters": {
9
-
"type": "params",
10
-
"required": ["did", "rkey"],
11
-
"properties": {
12
-
"did": {
13
-
"type": "string",
14
-
"format": "at-identifier"
15
-
},
16
-
"rkey": {
17
-
"type": "string"
18
-
}
19
-
}
20
-
},
21
-
"output": {
22
-
"encoding": "application/json",
23
-
"schema": {
24
-
"type": "object",
25
-
"required": ["recipe"],
26
-
"properties": {
27
-
"recipe": {
28
-
"type": "ref",
29
-
"ref": "#result"
30
-
}
31
-
}
32
-
}
33
-
}
34
-
},
35
-
"result": {
36
-
"type": "object",
37
-
"required": ["author", "title", "ingredients", "steps"],
38
-
"properties": {
39
-
"author": { "type": "ref", "ref": "blue.recipes.feed.defs#authorInfo" },
40
-
"title": { "type": "string" },
41
-
"description": { "type": "string" },
42
-
"time": { "type": "integer" },
43
-
"serves": { "type": "integer" },
44
-
"imageUrl": { "type": "string" },
45
-
"ingredients": {
46
-
"type": "array",
47
-
"items": {
48
-
"type": "ref",
49
-
"ref": "blue.recipes.feed.defs#ingredient"
50
-
}
51
-
},
52
-
"steps": {
53
-
"type": "array",
54
-
"items": {
55
-
"type": "ref",
56
-
"ref": "blue.recipes.feed.defs#step"
57
-
}
58
-
}
59
-
}
60
-
}
61
-
}
62
-
}
-59
lexicons/blue/recipes/feed/getRecipes.json
-59
lexicons/blue/recipes/feed/getRecipes.json
···
1
-
{
2
-
"lexicon": 1,
3
-
"id": "blue.recipes.feed.getRecipes",
4
-
"defs": {
5
-
"main": {
6
-
"type": "query",
7
-
"description": "Gets recipes from the index.",
8
-
"parameters": {
9
-
"type": "params",
10
-
"required": ["cursor"],
11
-
"properties": {
12
-
"cursor": {
13
-
"type": "string"
14
-
},
15
-
"did": {
16
-
"type": "string",
17
-
"format": "at-identifier"
18
-
}
19
-
}
20
-
},
21
-
"output": {
22
-
"encoding": "application/json",
23
-
"schema": {
24
-
"type": "object",
25
-
"required": ["recipes"],
26
-
"properties": {
27
-
"author": {
28
-
"type": "ref",
29
-
"ref": "blue.recipes.feed.defs#authorInfo"
30
-
},
31
-
"recipes": {
32
-
"type": "array",
33
-
"items": {
34
-
"type": "ref",
35
-
"ref": "#result"
36
-
}
37
-
}
38
-
}
39
-
}
40
-
}
41
-
},
42
-
"result": {
43
-
"type": "object",
44
-
"required": [ "rkey", "author", "title", "time", "ingredients", "steps"],
45
-
"properties": {
46
-
"rkey": { "type": "string" },
47
-
"author": { "type": "ref", "ref": "blue.recipes.feed.defs#authorInfo" },
48
-
"type": { "type": "string" },
49
-
"imageUrl": { "type": "string" },
50
-
"title": { "type": "string" },
51
-
"time": { "type": "integer" },
52
-
"serves": { "type": "integer" },
53
-
"description": { "type": "string" },
54
-
"ingredients": { "type": "integer" },
55
-
"steps": { "type": "integer" }
56
-
}
57
-
}
58
-
}
59
-
}
-57
lexicons/blue/recipes/feed/recipes.json
-57
lexicons/blue/recipes/feed/recipes.json
···
1
-
{
2
-
"lexicon": 1,
3
-
"id": "blue.recipes.feed.recipe",
4
-
"defs": {
5
-
"main": {
6
-
"type": "record",
7
-
"description": "Record containing a Cookware recipe.",
8
-
"key": "tid",
9
-
"record": {
10
-
"type": "object",
11
-
"required": ["title", "ingredients", "steps"],
12
-
"properties": {
13
-
"title": {
14
-
"type": "string",
15
-
"maxLength": 3000,
16
-
"maxGraphemes": 300,
17
-
"description": "The title of the recipe."
18
-
},
19
-
"description": {
20
-
"type": "string",
21
-
"maxLength": 3000,
22
-
"maxGraphemes": 300,
23
-
"description": "The description of the recipe."
24
-
},
25
-
"image": {
26
-
"type": "blob",
27
-
"description": "The recipe's cover image.",
28
-
"accept": ["image/*"],
29
-
"maxSize": 1000000
30
-
},
31
-
"time": {
32
-
"type": "integer",
33
-
"description": "The amount of time (in minutes) the recipe takes to complete."
34
-
},
35
-
"serves": {
36
-
"type": "integer",
37
-
"description": "The amount of people the recipe will make servings for."
38
-
},
39
-
"ingredients": {
40
-
"type": "array",
41
-
"items": {
42
-
"type": "ref",
43
-
"ref": "blue.recipes.feed.defs#ingredient"
44
-
}
45
-
},
46
-
"steps": {
47
-
"type": "array",
48
-
"items": {
49
-
"type": "ref",
50
-
"ref": "blue.recipes.feed.defs#step"
51
-
}
52
-
}
53
-
}
54
-
}
55
-
}
56
-
}
57
-
}
-156
lexicons/com/atproto/label/defs.json
-156
lexicons/com/atproto/label/defs.json
···
1
-
{
2
-
"lexicon": 1,
3
-
"id": "com.atproto.label.defs",
4
-
"defs": {
5
-
"label": {
6
-
"type": "object",
7
-
"description": "Metadata tag on an atproto resource (eg, repo or record).",
8
-
"required": ["src", "uri", "val", "cts"],
9
-
"properties": {
10
-
"ver": {
11
-
"type": "integer",
12
-
"description": "The AT Protocol version of the label object."
13
-
},
14
-
"src": {
15
-
"type": "string",
16
-
"format": "did",
17
-
"description": "DID of the actor who created this label."
18
-
},
19
-
"uri": {
20
-
"type": "string",
21
-
"format": "uri",
22
-
"description": "AT URI of the record, repository (account), or other resource that this label applies to."
23
-
},
24
-
"cid": {
25
-
"type": "string",
26
-
"format": "cid",
27
-
"description": "Optionally, CID specifying the specific version of 'uri' resource this label applies to."
28
-
},
29
-
"val": {
30
-
"type": "string",
31
-
"maxLength": 128,
32
-
"description": "The short string name of the value or type of this label."
33
-
},
34
-
"neg": {
35
-
"type": "boolean",
36
-
"description": "If true, this is a negation label, overwriting a previous label."
37
-
},
38
-
"cts": {
39
-
"type": "string",
40
-
"format": "datetime",
41
-
"description": "Timestamp when this label was created."
42
-
},
43
-
"exp": {
44
-
"type": "string",
45
-
"format": "datetime",
46
-
"description": "Timestamp at which this label expires (no longer applies)."
47
-
},
48
-
"sig": {
49
-
"type": "bytes",
50
-
"description": "Signature of dag-cbor encoded label."
51
-
}
52
-
}
53
-
},
54
-
"selfLabels": {
55
-
"type": "object",
56
-
"description": "Metadata tags on an atproto record, published by the author within the record.",
57
-
"required": ["values"],
58
-
"properties": {
59
-
"values": {
60
-
"type": "array",
61
-
"items": { "type": "ref", "ref": "#selfLabel" },
62
-
"maxLength": 10
63
-
}
64
-
}
65
-
},
66
-
"selfLabel": {
67
-
"type": "object",
68
-
"description": "Metadata tag on an atproto record, published by the author within the record. Note that schemas should use #selfLabels, not #selfLabel.",
69
-
"required": ["val"],
70
-
"properties": {
71
-
"val": {
72
-
"type": "string",
73
-
"maxLength": 128,
74
-
"description": "The short string name of the value or type of this label."
75
-
}
76
-
}
77
-
},
78
-
"labelValueDefinition": {
79
-
"type": "object",
80
-
"description": "Declares a label value and its expected interpretations and behaviors.",
81
-
"required": ["identifier", "severity", "blurs", "locales"],
82
-
"properties": {
83
-
"identifier": {
84
-
"type": "string",
85
-
"description": "The value of the label being defined. Must only include lowercase ascii and the '-' character ([a-z-]+).",
86
-
"maxLength": 100,
87
-
"maxGraphemes": 100
88
-
},
89
-
"severity": {
90
-
"type": "string",
91
-
"description": "How should a client visually convey this label? 'inform' means neutral and informational; 'alert' means negative and warning; 'none' means show nothing.",
92
-
"knownValues": ["inform", "alert", "none"]
93
-
},
94
-
"blurs": {
95
-
"type": "string",
96
-
"description": "What should this label hide in the UI, if applied? 'content' hides all of the target; 'media' hides the images/video/audio; 'none' hides nothing.",
97
-
"knownValues": ["content", "media", "none"]
98
-
},
99
-
"defaultSetting": {
100
-
"type": "string",
101
-
"description": "The default setting for this label.",
102
-
"knownValues": ["ignore", "warn", "hide"],
103
-
"default": "warn"
104
-
},
105
-
"adultOnly": {
106
-
"type": "boolean",
107
-
"description": "Does the user need to have adult content enabled in order to configure this label?"
108
-
},
109
-
"locales": {
110
-
"type": "array",
111
-
"items": { "type": "ref", "ref": "#labelValueDefinitionStrings" }
112
-
}
113
-
}
114
-
},
115
-
"labelValueDefinitionStrings": {
116
-
"type": "object",
117
-
"description": "Strings which describe the label in the UI, localized into a specific language.",
118
-
"required": ["lang", "name", "description"],
119
-
"properties": {
120
-
"lang": {
121
-
"type": "string",
122
-
"description": "The code of the language these strings are written in.",
123
-
"format": "language"
124
-
},
125
-
"name": {
126
-
"type": "string",
127
-
"description": "A short human-readable name for the label.",
128
-
"maxGraphemes": 64,
129
-
"maxLength": 640
130
-
},
131
-
"description": {
132
-
"type": "string",
133
-
"description": "A longer description of what the label means and why it might be applied.",
134
-
"maxGraphemes": 10000,
135
-
"maxLength": 100000
136
-
}
137
-
}
138
-
},
139
-
"labelValue": {
140
-
"type": "string",
141
-
"knownValues": [
142
-
"!hide",
143
-
"!no-promote",
144
-
"!warn",
145
-
"!no-unauthenticated",
146
-
"dmca-violation",
147
-
"doxxing",
148
-
"porn",
149
-
"sexual",
150
-
"nudity",
151
-
"nsfl",
152
-
"gore"
153
-
]
154
-
}
155
-
}
156
-
}
-15
lexicons/com/atproto/repo/strongRef.json
-15
lexicons/com/atproto/repo/strongRef.json
···
1
-
{
2
-
"lexicon": 1,
3
-
"id": "com.atproto.repo.strongRef",
4
-
"description": "A URI with a content-hash fingerprint.",
5
-
"defs": {
6
-
"main": {
7
-
"type": "object",
8
-
"required": ["uri", "cid"],
9
-
"properties": {
10
-
"uri": { "type": "string", "format": "at-uri" },
11
-
"cid": { "type": "string", "format": "cid" }
12
-
}
13
-
}
14
-
}
15
-
}
+4
-6
libs/database/drizzle.config.ts
+4
-6
libs/database/drizzle.config.ts
···
1
-
import env from './src/config';
2
1
import type { Config } from "drizzle-kit";
3
2
4
3
export default {
5
-
schema: "./src/schema.ts",
4
+
schema: "./lib/schema.ts",
6
5
out: "./migrations",
7
-
dialect: "turso",
6
+
dialect: "postgresql",
8
7
dbCredentials: {
9
-
url: env.TURSO_CONNECTION_URL,
10
-
authToken: env.TURSO_AUTH_TOKEN,
11
-
},
8
+
url: process.env.DATABASE_URL || 'postgres://postgres:postgres@localhost:5432/postgres',
9
+
}
12
10
} satisfies Config;
+12
libs/database/lib/index.ts
+12
libs/database/lib/index.ts
···
1
+
import { drizzle } from 'drizzle-orm/node-postgres';
2
+
import { Pool } from 'pg';
3
+
4
+
const pool = new Pool({
5
+
connectionString: process.env.DATABASE_URL || 'postgres://postgres:postgres@localhost:5432/postgres',
6
+
});
7
+
8
+
import * as schema from './schema.js';
9
+
export const db = drizzle(pool, { schema });
10
+
11
+
// Re-export drizzle-orm functions to ensure single instance
12
+
export { eq, and, or, desc, asc, sql } from 'drizzle-orm';
+114
libs/database/lib/schema.ts
+114
libs/database/lib/schema.ts
···
1
+
import { customType, index, integer, primaryKey, pgTable, text, jsonb, varchar } from "drizzle-orm/pg-core";
2
+
import { BlueRecipesFeedRecipe } from "@cookware/lexicons";
3
+
import { type Cid, isCid, type ResourceUri, type AtprotoDid } from "@atcute/lexicons/syntax";
4
+
import type { Blob, LegacyBlob } from "@atcute/lexicons";
5
+
import { relations, sql, type SQL } from "drizzle-orm";
6
+
import { isBlob, isCidLink, isLegacyBlob } from "@atcute/lexicons/interfaces";
7
+
8
+
const dateIsoText = customType<{ data: Date; driverData: string }>({
9
+
dataType() {
10
+
return "text";
11
+
},
12
+
toDriver: (value) => value.toISOString(),
13
+
fromDriver: (value) => new Date(value),
14
+
});
15
+
16
+
const atBlob = customType<{ data: Blob | LegacyBlob; driverData: string; }>({
17
+
dataType() {
18
+
return "text";
19
+
},
20
+
toDriver: (value) => {
21
+
if (isLegacyBlob(value)) {
22
+
return `l:${value.cid}:${value.mimeType}`;
23
+
} else if (isBlob(value)) {
24
+
return `b:${value.ref.$link}:${value.mimeType}:${value.size}`;
25
+
} else {
26
+
throw new Error('Invalid blob value');
27
+
}
28
+
},
29
+
fromDriver: (value): Blob | LegacyBlob => {
30
+
if (typeof value !== 'string') throw new Error('Invalid blob ref data type');
31
+
var parts = value.split(':');
32
+
if (value.startsWith('l:')) {
33
+
if (parts.length !== 3) throw new Error('Invalid legacy blob ref format');
34
+
if (!isCid(parts[1]!)) throw new Error('Invalid CID in legacy blob ref');
35
+
return {
36
+
cid: parts[1]!,
37
+
mimeType: parts[2]!,
38
+
} as LegacyBlob;
39
+
} else if (value.startsWith('b:')) {
40
+
if (parts.length !== 4) throw new Error('Invalid blob ref format');
41
+
if (!isCidLink({ $link: parts[1] })) throw new Error('Invalid CID link in blob ref');
42
+
if (isNaN(parseInt(parts[3]!, 10))) throw new Error('Invalid size in blob ref');
43
+
44
+
return {
45
+
$type: 'blob',
46
+
mimeType: parts[2],
47
+
size: parseInt(parts[3]!),
48
+
ref: { $link: parts[1] }
49
+
} as Blob;
50
+
} else {
51
+
throw new Error('Invalid blob ref prefix');
52
+
}
53
+
},
54
+
});
55
+
56
+
export const profilesTable = pgTable("profiles", {
57
+
uri: text('uri')
58
+
.generatedAlwaysAs((): SQL => sql`'at://' || ${profilesTable.did} || '/blue.recipes.actor.profile/self'`)
59
+
.$type<ResourceUri>(),
60
+
61
+
cid: text("cid").$type<Cid>().notNull(),
62
+
did: text("did").$type<AtprotoDid>().notNull().primaryKey(),
63
+
ingestedAt: dateIsoText("ingested_at").notNull().default(sql`CURRENT_TIMESTAMP`),
64
+
65
+
displayName: varchar('display_name', { length: 640 }).notNull(),
66
+
description: varchar('description', { length: 2500 }),
67
+
pronouns: varchar('pronouns', { length: 200 }),
68
+
website: text('website'),
69
+
avatarRef: atBlob('avatar'),
70
+
bannerRef: atBlob('banner'),
71
+
createdAt: dateIsoText("created_at").notNull(),
72
+
}, t => ([
73
+
index('profiles_cid_idx').on(t.cid),
74
+
index('profiles_cat_idx').on(t.createdAt),
75
+
index('profiles_iat_idx').on(t.ingestedAt),
76
+
]));
77
+
78
+
export const recipeTable = pgTable("recipes", {
79
+
uri: text('uri')
80
+
.generatedAlwaysAs((): SQL => sql`'at://' || ${recipeTable.did} || '/blue.recipes.feed.recipe/' || ${recipeTable.rkey}`),
81
+
82
+
cid: text("cid").$type<Cid>().notNull(),
83
+
did: text("author_did")
84
+
.$type<AtprotoDid>()
85
+
.notNull()
86
+
.references(() => profilesTable.did, { onDelete: 'cascade' }),
87
+
rkey: text('rkey').notNull(),
88
+
89
+
imageRef: atBlob('image'),
90
+
91
+
title: text('title').notNull(),
92
+
time: integer('time').notNull().default(0),
93
+
serves: integer('serves'),
94
+
description: text('description'),
95
+
96
+
ingredients: jsonb('ingredients').$type<BlueRecipesFeedRecipe.Main['ingredients']>().notNull(),
97
+
ingredientsCount: integer('ingredients_count').generatedAlwaysAs((): SQL => sql`jsonb_array_length(${recipeTable.ingredients})`),
98
+
99
+
steps: jsonb('steps').$type<BlueRecipesFeedRecipe.Main['steps']>().notNull(),
100
+
stepsCount: integer('steps_count').generatedAlwaysAs((): SQL => sql`jsonb_array_length(${recipeTable.steps})`),
101
+
102
+
createdAt: dateIsoText("created_at").notNull(),
103
+
ingestedAt: dateIsoText("ingested_at").notNull().default(sql`CURRENT_TIMESTAMP`),
104
+
}, t => ([
105
+
index('recipes_title_idx').on(t.title),
106
+
index('recipes_cid_idx').on(t.cid),
107
+
index('recipes_cat_idx').on(t.createdAt),
108
+
index('recipes_iat_idx').on(t.ingestedAt),
109
+
primaryKey({ columns: [ t.did, t.rkey ] }),
110
+
]));
111
+
112
+
export const recipeTableRelations = relations(recipeTable, ({ one }) => ({
113
+
author: one(profilesTable, { fields: [recipeTable.did], references: [profilesTable.did] })
114
+
}));
-23
libs/database/migrations/0000_boring_tenebrous.sql
-23
libs/database/migrations/0000_boring_tenebrous.sql
···
1
-
CREATE TABLE `auth_session` (
2
-
`key` text PRIMARY KEY NOT NULL,
3
-
`session` text NOT NULL
4
-
);
5
-
--> statement-breakpoint
6
-
CREATE TABLE `auth_state` (
7
-
`key` text PRIMARY KEY NOT NULL,
8
-
`state` text NOT NULL
9
-
);
10
-
--> statement-breakpoint
11
-
CREATE TABLE `recipes` (
12
-
`id` integer PRIMARY KEY NOT NULL,
13
-
`rkey` text NOT NULL,
14
-
`title` text NOT NULL,
15
-
`description` text,
16
-
`ingredients` text NOT NULL,
17
-
`steps` text NOT NULL,
18
-
`created_at` text NOT NULL,
19
-
`author_did` text NOT NULL
20
-
);
21
-
--> statement-breakpoint
22
-
CREATE UNIQUE INDEX `recipes_id_unique` ON `recipes` (`id`);--> statement-breakpoint
23
-
CREATE UNIQUE INDEX `recipes_rkey_author_did_unique` ON `recipes` (`rkey`,`author_did`);
+46
libs/database/migrations/0000_young_hellcat.sql
+46
libs/database/migrations/0000_young_hellcat.sql
···
1
+
CREATE TABLE IF NOT EXISTS "profiles" (
2
+
"uri" text GENERATED ALWAYS AS ('at://' || "profiles"."did" || '/blue.recipes.actor.profile/self') STORED,
3
+
"cid" text NOT NULL,
4
+
"did" text PRIMARY KEY NOT NULL,
5
+
"ingested_at" text DEFAULT CURRENT_TIMESTAMP NOT NULL,
6
+
"display_name" varchar(640) NOT NULL,
7
+
"description" varchar(2500),
8
+
"pronouns" varchar(200),
9
+
"website" text,
10
+
"avatar" text,
11
+
"banner" text,
12
+
"created_at" text NOT NULL
13
+
);
14
+
--> statement-breakpoint
15
+
CREATE TABLE IF NOT EXISTS "recipes" (
16
+
"uri" text GENERATED ALWAYS AS ('at://' || "recipes"."author_did" || '/blue.recipes.feed.recipe/' || "recipes"."rkey") STORED,
17
+
"cid" text NOT NULL,
18
+
"author_did" text NOT NULL,
19
+
"rkey" text NOT NULL,
20
+
"image" text,
21
+
"title" text NOT NULL,
22
+
"time" integer DEFAULT 0 NOT NULL,
23
+
"serves" integer,
24
+
"description" text,
25
+
"ingredients" jsonb NOT NULL,
26
+
"ingredients_count" integer GENERATED ALWAYS AS (jsonb_array_length("recipes"."ingredients")) STORED,
27
+
"steps" jsonb NOT NULL,
28
+
"steps_count" integer GENERATED ALWAYS AS (jsonb_array_length("recipes"."steps")) STORED,
29
+
"created_at" text NOT NULL,
30
+
"ingested_at" text DEFAULT CURRENT_TIMESTAMP NOT NULL,
31
+
CONSTRAINT "recipes_author_did_rkey_pk" PRIMARY KEY("author_did","rkey")
32
+
);
33
+
--> statement-breakpoint
34
+
DO $$ BEGIN
35
+
ALTER TABLE "recipes" ADD CONSTRAINT "recipes_author_did_profiles_did_fk" FOREIGN KEY ("author_did") REFERENCES "public"."profiles"("did") ON DELETE cascade ON UPDATE no action;
36
+
EXCEPTION
37
+
WHEN duplicate_object THEN null;
38
+
END $$;
39
+
--> statement-breakpoint
40
+
CREATE INDEX IF NOT EXISTS "profiles_cid_idx" ON "profiles" USING btree ("cid");--> statement-breakpoint
41
+
CREATE INDEX IF NOT EXISTS "profiles_cat_idx" ON "profiles" USING btree ("created_at");--> statement-breakpoint
42
+
CREATE INDEX IF NOT EXISTS "profiles_iat_idx" ON "profiles" USING btree ("ingested_at");--> statement-breakpoint
43
+
CREATE INDEX IF NOT EXISTS "recipes_title_idx" ON "recipes" USING btree ("title");--> statement-breakpoint
44
+
CREATE INDEX IF NOT EXISTS "recipes_cid_idx" ON "recipes" USING btree ("cid");--> statement-breakpoint
45
+
CREATE INDEX IF NOT EXISTS "recipes_cat_idx" ON "recipes" USING btree ("created_at");--> statement-breakpoint
46
+
CREATE INDEX IF NOT EXISTS "recipes_iat_idx" ON "recipes" USING btree ("ingested_at");
-1
libs/database/migrations/0001_icy_killmonger.sql
-1
libs/database/migrations/0001_icy_killmonger.sql
···
1
-
ALTER TABLE `recipes` ADD `time` integer DEFAULT 0 NOT NULL;
-5
libs/database/migrations/0002_redundant_wither.sql
-5
libs/database/migrations/0002_redundant_wither.sql
···
1
-
DROP INDEX IF EXISTS "recipes_id_unique";--> statement-breakpoint
2
-
DROP INDEX IF EXISTS "recipes_rkey_author_did_unique";--> statement-breakpoint
3
-
ALTER TABLE `recipes` ALTER COLUMN "title" TO "title" text;--> statement-breakpoint
4
-
CREATE UNIQUE INDEX `recipes_id_unique` ON `recipes` (`id`);--> statement-breakpoint
5
-
CREATE UNIQUE INDEX `recipes_rkey_author_did_unique` ON `recipes` (`rkey`,`author_did`);
-6
libs/database/migrations/0003_fixed_peter_parker.sql
-6
libs/database/migrations/0003_fixed_peter_parker.sql
···
1
-
DROP INDEX IF EXISTS "recipes_id_unique";--> statement-breakpoint
2
-
DROP INDEX IF EXISTS "recipes_rkey_author_did_unique";--> statement-breakpoint
3
-
ALTER TABLE `recipes` ALTER COLUMN "title" TO "title" text NOT NULL;--> statement-breakpoint
4
-
CREATE UNIQUE INDEX `recipes_id_unique` ON `recipes` (`id`);--> statement-breakpoint
5
-
CREATE UNIQUE INDEX `recipes_rkey_author_did_unique` ON `recipes` (`rkey`,`author_did`);--> statement-breakpoint
6
-
ALTER TABLE `recipes` ADD `image_ref` text;
-1
libs/database/migrations/0004_left_sersi.sql
-1
libs/database/migrations/0004_left_sersi.sql
···
1
-
ALTER TABLE `recipes` ADD `serves` integer;
+275
-74
libs/database/migrations/meta/0000_snapshot.json
+275
-74
libs/database/migrations/meta/0000_snapshot.json
···
1
1
{
2
-
"version": "6",
3
-
"dialect": "sqlite",
4
-
"id": "1c01d686-877c-426c-ac8a-31f47df9385d",
2
+
"id": "5d896b70-087b-421e-8d94-c100476cd926",
5
3
"prevId": "00000000-0000-0000-0000-000000000000",
4
+
"version": "7",
5
+
"dialect": "postgresql",
6
6
"tables": {
7
-
"auth_session": {
8
-
"name": "auth_session",
7
+
"public.profiles": {
8
+
"name": "profiles",
9
+
"schema": "",
9
10
"columns": {
10
-
"key": {
11
-
"name": "key",
11
+
"uri": {
12
+
"name": "uri",
13
+
"type": "text",
14
+
"primaryKey": false,
15
+
"notNull": false,
16
+
"generated": {
17
+
"as": "'at://' || \"profiles\".\"did\" || '/blue.recipes.actor.profile/self'",
18
+
"type": "stored"
19
+
}
20
+
},
21
+
"cid": {
22
+
"name": "cid",
23
+
"type": "text",
24
+
"primaryKey": false,
25
+
"notNull": true
26
+
},
27
+
"did": {
28
+
"name": "did",
12
29
"type": "text",
13
30
"primaryKey": true,
14
-
"notNull": true,
15
-
"autoincrement": false
31
+
"notNull": true
16
32
},
17
-
"session": {
18
-
"name": "session",
33
+
"ingested_at": {
34
+
"name": "ingested_at",
19
35
"type": "text",
20
36
"primaryKey": false,
21
37
"notNull": true,
22
-
"autoincrement": false
23
-
}
24
-
},
25
-
"indexes": {},
26
-
"foreignKeys": {},
27
-
"compositePrimaryKeys": {},
28
-
"uniqueConstraints": {},
29
-
"checkConstraints": {}
30
-
},
31
-
"auth_state": {
32
-
"name": "auth_state",
33
-
"columns": {
34
-
"key": {
35
-
"name": "key",
38
+
"default": "CURRENT_TIMESTAMP"
39
+
},
40
+
"display_name": {
41
+
"name": "display_name",
42
+
"type": "varchar(640)",
43
+
"primaryKey": false,
44
+
"notNull": true
45
+
},
46
+
"description": {
47
+
"name": "description",
48
+
"type": "varchar(2500)",
49
+
"primaryKey": false,
50
+
"notNull": false
51
+
},
52
+
"pronouns": {
53
+
"name": "pronouns",
54
+
"type": "varchar(200)",
55
+
"primaryKey": false,
56
+
"notNull": false
57
+
},
58
+
"website": {
59
+
"name": "website",
36
60
"type": "text",
37
-
"primaryKey": true,
38
-
"notNull": true,
39
-
"autoincrement": false
61
+
"primaryKey": false,
62
+
"notNull": false
63
+
},
64
+
"avatar": {
65
+
"name": "avatar",
66
+
"type": "text",
67
+
"primaryKey": false,
68
+
"notNull": false
69
+
},
70
+
"banner": {
71
+
"name": "banner",
72
+
"type": "text",
73
+
"primaryKey": false,
74
+
"notNull": false
40
75
},
41
-
"state": {
42
-
"name": "state",
76
+
"created_at": {
77
+
"name": "created_at",
43
78
"type": "text",
44
79
"primaryKey": false,
45
-
"notNull": true,
46
-
"autoincrement": false
80
+
"notNull": true
81
+
}
82
+
},
83
+
"indexes": {
84
+
"profiles_cid_idx": {
85
+
"name": "profiles_cid_idx",
86
+
"columns": [
87
+
{
88
+
"expression": "cid",
89
+
"isExpression": false,
90
+
"asc": true,
91
+
"nulls": "last"
92
+
}
93
+
],
94
+
"isUnique": false,
95
+
"concurrently": false,
96
+
"method": "btree",
97
+
"with": {}
98
+
},
99
+
"profiles_cat_idx": {
100
+
"name": "profiles_cat_idx",
101
+
"columns": [
102
+
{
103
+
"expression": "created_at",
104
+
"isExpression": false,
105
+
"asc": true,
106
+
"nulls": "last"
107
+
}
108
+
],
109
+
"isUnique": false,
110
+
"concurrently": false,
111
+
"method": "btree",
112
+
"with": {}
113
+
},
114
+
"profiles_iat_idx": {
115
+
"name": "profiles_iat_idx",
116
+
"columns": [
117
+
{
118
+
"expression": "ingested_at",
119
+
"isExpression": false,
120
+
"asc": true,
121
+
"nulls": "last"
122
+
}
123
+
],
124
+
"isUnique": false,
125
+
"concurrently": false,
126
+
"method": "btree",
127
+
"with": {}
47
128
}
48
129
},
49
-
"indexes": {},
50
130
"foreignKeys": {},
51
131
"compositePrimaryKeys": {},
52
132
"uniqueConstraints": {},
53
-
"checkConstraints": {}
133
+
"policies": {},
134
+
"checkConstraints": {},
135
+
"isRLSEnabled": false
54
136
},
55
-
"recipes": {
137
+
"public.recipes": {
56
138
"name": "recipes",
139
+
"schema": "",
57
140
"columns": {
58
-
"id": {
59
-
"name": "id",
60
-
"type": "integer",
61
-
"primaryKey": true,
62
-
"notNull": true,
63
-
"autoincrement": false
141
+
"uri": {
142
+
"name": "uri",
143
+
"type": "text",
144
+
"primaryKey": false,
145
+
"notNull": false,
146
+
"generated": {
147
+
"as": "'at://' || \"recipes\".\"author_did\" || '/blue.recipes.feed.recipe/' || \"recipes\".\"rkey\"",
148
+
"type": "stored"
149
+
}
150
+
},
151
+
"cid": {
152
+
"name": "cid",
153
+
"type": "text",
154
+
"primaryKey": false,
155
+
"notNull": true
156
+
},
157
+
"author_did": {
158
+
"name": "author_did",
159
+
"type": "text",
160
+
"primaryKey": false,
161
+
"notNull": true
64
162
},
65
163
"rkey": {
66
164
"name": "rkey",
67
165
"type": "text",
68
166
"primaryKey": false,
69
-
"notNull": true,
70
-
"autoincrement": false
167
+
"notNull": true
168
+
},
169
+
"image": {
170
+
"name": "image",
171
+
"type": "text",
172
+
"primaryKey": false,
173
+
"notNull": false
71
174
},
72
175
"title": {
73
176
"name": "title",
74
177
"type": "text",
75
178
"primaryKey": false,
179
+
"notNull": true
180
+
},
181
+
"time": {
182
+
"name": "time",
183
+
"type": "integer",
184
+
"primaryKey": false,
76
185
"notNull": true,
77
-
"autoincrement": false
186
+
"default": 0
187
+
},
188
+
"serves": {
189
+
"name": "serves",
190
+
"type": "integer",
191
+
"primaryKey": false,
192
+
"notNull": false
78
193
},
79
194
"description": {
80
195
"name": "description",
81
196
"type": "text",
82
197
"primaryKey": false,
83
-
"notNull": false,
84
-
"autoincrement": false
198
+
"notNull": false
85
199
},
86
200
"ingredients": {
87
201
"name": "ingredients",
88
-
"type": "text",
202
+
"type": "jsonb",
89
203
"primaryKey": false,
90
-
"notNull": true,
91
-
"autoincrement": false
204
+
"notNull": true
205
+
},
206
+
"ingredients_count": {
207
+
"name": "ingredients_count",
208
+
"type": "integer",
209
+
"primaryKey": false,
210
+
"notNull": false,
211
+
"generated": {
212
+
"as": "jsonb_array_length(\"recipes\".\"ingredients\")",
213
+
"type": "stored"
214
+
}
92
215
},
93
216
"steps": {
94
217
"name": "steps",
95
-
"type": "text",
218
+
"type": "jsonb",
96
219
"primaryKey": false,
97
-
"notNull": true,
98
-
"autoincrement": false
220
+
"notNull": true
221
+
},
222
+
"steps_count": {
223
+
"name": "steps_count",
224
+
"type": "integer",
225
+
"primaryKey": false,
226
+
"notNull": false,
227
+
"generated": {
228
+
"as": "jsonb_array_length(\"recipes\".\"steps\")",
229
+
"type": "stored"
230
+
}
99
231
},
100
232
"created_at": {
101
233
"name": "created_at",
102
234
"type": "text",
103
235
"primaryKey": false,
104
-
"notNull": true,
105
-
"autoincrement": false
236
+
"notNull": true
106
237
},
107
-
"author_did": {
108
-
"name": "author_did",
238
+
"ingested_at": {
239
+
"name": "ingested_at",
109
240
"type": "text",
110
241
"primaryKey": false,
111
242
"notNull": true,
112
-
"autoincrement": false
243
+
"default": "CURRENT_TIMESTAMP"
113
244
}
114
245
},
115
246
"indexes": {
116
-
"recipes_id_unique": {
117
-
"name": "recipes_id_unique",
247
+
"recipes_title_idx": {
248
+
"name": "recipes_title_idx",
118
249
"columns": [
119
-
"id"
250
+
{
251
+
"expression": "title",
252
+
"isExpression": false,
253
+
"asc": true,
254
+
"nulls": "last"
255
+
}
120
256
],
121
-
"isUnique": true
257
+
"isUnique": false,
258
+
"concurrently": false,
259
+
"method": "btree",
260
+
"with": {}
122
261
},
123
-
"recipes_rkey_author_did_unique": {
124
-
"name": "recipes_rkey_author_did_unique",
262
+
"recipes_cid_idx": {
263
+
"name": "recipes_cid_idx",
125
264
"columns": [
126
-
"rkey",
265
+
{
266
+
"expression": "cid",
267
+
"isExpression": false,
268
+
"asc": true,
269
+
"nulls": "last"
270
+
}
271
+
],
272
+
"isUnique": false,
273
+
"concurrently": false,
274
+
"method": "btree",
275
+
"with": {}
276
+
},
277
+
"recipes_cat_idx": {
278
+
"name": "recipes_cat_idx",
279
+
"columns": [
280
+
{
281
+
"expression": "created_at",
282
+
"isExpression": false,
283
+
"asc": true,
284
+
"nulls": "last"
285
+
}
286
+
],
287
+
"isUnique": false,
288
+
"concurrently": false,
289
+
"method": "btree",
290
+
"with": {}
291
+
},
292
+
"recipes_iat_idx": {
293
+
"name": "recipes_iat_idx",
294
+
"columns": [
295
+
{
296
+
"expression": "ingested_at",
297
+
"isExpression": false,
298
+
"asc": true,
299
+
"nulls": "last"
300
+
}
301
+
],
302
+
"isUnique": false,
303
+
"concurrently": false,
304
+
"method": "btree",
305
+
"with": {}
306
+
}
307
+
},
308
+
"foreignKeys": {
309
+
"recipes_author_did_profiles_did_fk": {
310
+
"name": "recipes_author_did_profiles_did_fk",
311
+
"tableFrom": "recipes",
312
+
"tableTo": "profiles",
313
+
"columnsFrom": [
127
314
"author_did"
128
315
],
129
-
"isUnique": true
316
+
"columnsTo": [
317
+
"did"
318
+
],
319
+
"onDelete": "cascade",
320
+
"onUpdate": "no action"
321
+
}
322
+
},
323
+
"compositePrimaryKeys": {
324
+
"recipes_author_did_rkey_pk": {
325
+
"name": "recipes_author_did_rkey_pk",
326
+
"columns": [
327
+
"author_did",
328
+
"rkey"
329
+
]
130
330
}
131
331
},
132
-
"foreignKeys": {},
133
-
"compositePrimaryKeys": {},
134
332
"uniqueConstraints": {},
135
-
"checkConstraints": {}
333
+
"policies": {},
334
+
"checkConstraints": {},
335
+
"isRLSEnabled": false
136
336
}
137
337
},
338
+
"enums": {},
339
+
"schemas": {},
340
+
"sequences": {},
341
+
"roles": {},
342
+
"policies": {},
138
343
"views": {},
139
-
"enums": {},
140
344
"_meta": {
345
+
"columns": {},
141
346
"schemas": {},
142
-
"tables": {},
143
-
"columns": {}
144
-
},
145
-
"internal": {
146
-
"indexes": {}
347
+
"tables": {}
147
348
}
148
349
}
-156
libs/database/migrations/meta/0001_snapshot.json
-156
libs/database/migrations/meta/0001_snapshot.json
···
1
-
{
2
-
"version": "6",
3
-
"dialect": "sqlite",
4
-
"id": "2c6fca6c-38c3-4482-b189-6defabb5f8c8",
5
-
"prevId": "1c01d686-877c-426c-ac8a-31f47df9385d",
6
-
"tables": {
7
-
"auth_session": {
8
-
"name": "auth_session",
9
-
"columns": {
10
-
"key": {
11
-
"name": "key",
12
-
"type": "text",
13
-
"primaryKey": true,
14
-
"notNull": true,
15
-
"autoincrement": false
16
-
},
17
-
"session": {
18
-
"name": "session",
19
-
"type": "text",
20
-
"primaryKey": false,
21
-
"notNull": true,
22
-
"autoincrement": false
23
-
}
24
-
},
25
-
"indexes": {},
26
-
"foreignKeys": {},
27
-
"compositePrimaryKeys": {},
28
-
"uniqueConstraints": {},
29
-
"checkConstraints": {}
30
-
},
31
-
"auth_state": {
32
-
"name": "auth_state",
33
-
"columns": {
34
-
"key": {
35
-
"name": "key",
36
-
"type": "text",
37
-
"primaryKey": true,
38
-
"notNull": true,
39
-
"autoincrement": false
40
-
},
41
-
"state": {
42
-
"name": "state",
43
-
"type": "text",
44
-
"primaryKey": false,
45
-
"notNull": true,
46
-
"autoincrement": false
47
-
}
48
-
},
49
-
"indexes": {},
50
-
"foreignKeys": {},
51
-
"compositePrimaryKeys": {},
52
-
"uniqueConstraints": {},
53
-
"checkConstraints": {}
54
-
},
55
-
"recipes": {
56
-
"name": "recipes",
57
-
"columns": {
58
-
"id": {
59
-
"name": "id",
60
-
"type": "integer",
61
-
"primaryKey": true,
62
-
"notNull": true,
63
-
"autoincrement": false
64
-
},
65
-
"rkey": {
66
-
"name": "rkey",
67
-
"type": "text",
68
-
"primaryKey": false,
69
-
"notNull": true,
70
-
"autoincrement": false
71
-
},
72
-
"title": {
73
-
"name": "title",
74
-
"type": "text",
75
-
"primaryKey": false,
76
-
"notNull": true,
77
-
"autoincrement": false
78
-
},
79
-
"time": {
80
-
"name": "time",
81
-
"type": "integer",
82
-
"primaryKey": false,
83
-
"notNull": true,
84
-
"autoincrement": false,
85
-
"default": 0
86
-
},
87
-
"description": {
88
-
"name": "description",
89
-
"type": "text",
90
-
"primaryKey": false,
91
-
"notNull": false,
92
-
"autoincrement": false
93
-
},
94
-
"ingredients": {
95
-
"name": "ingredients",
96
-
"type": "text",
97
-
"primaryKey": false,
98
-
"notNull": true,
99
-
"autoincrement": false
100
-
},
101
-
"steps": {
102
-
"name": "steps",
103
-
"type": "text",
104
-
"primaryKey": false,
105
-
"notNull": true,
106
-
"autoincrement": false
107
-
},
108
-
"created_at": {
109
-
"name": "created_at",
110
-
"type": "text",
111
-
"primaryKey": false,
112
-
"notNull": true,
113
-
"autoincrement": false
114
-
},
115
-
"author_did": {
116
-
"name": "author_did",
117
-
"type": "text",
118
-
"primaryKey": false,
119
-
"notNull": true,
120
-
"autoincrement": false
121
-
}
122
-
},
123
-
"indexes": {
124
-
"recipes_id_unique": {
125
-
"name": "recipes_id_unique",
126
-
"columns": [
127
-
"id"
128
-
],
129
-
"isUnique": true
130
-
},
131
-
"recipes_rkey_author_did_unique": {
132
-
"name": "recipes_rkey_author_did_unique",
133
-
"columns": [
134
-
"rkey",
135
-
"author_did"
136
-
],
137
-
"isUnique": true
138
-
}
139
-
},
140
-
"foreignKeys": {},
141
-
"compositePrimaryKeys": {},
142
-
"uniqueConstraints": {},
143
-
"checkConstraints": {}
144
-
}
145
-
},
146
-
"views": {},
147
-
"enums": {},
148
-
"_meta": {
149
-
"schemas": {},
150
-
"tables": {},
151
-
"columns": {}
152
-
},
153
-
"internal": {
154
-
"indexes": {}
155
-
}
156
-
}
-156
libs/database/migrations/meta/0002_snapshot.json
-156
libs/database/migrations/meta/0002_snapshot.json
···
1
-
{
2
-
"version": "6",
3
-
"dialect": "sqlite",
4
-
"id": "5e0d9054-f192-4db9-8afe-afcabe08e661",
5
-
"prevId": "2c6fca6c-38c3-4482-b189-6defabb5f8c8",
6
-
"tables": {
7
-
"auth_session": {
8
-
"name": "auth_session",
9
-
"columns": {
10
-
"key": {
11
-
"name": "key",
12
-
"type": "text",
13
-
"primaryKey": true,
14
-
"notNull": true,
15
-
"autoincrement": false
16
-
},
17
-
"session": {
18
-
"name": "session",
19
-
"type": "text",
20
-
"primaryKey": false,
21
-
"notNull": true,
22
-
"autoincrement": false
23
-
}
24
-
},
25
-
"indexes": {},
26
-
"foreignKeys": {},
27
-
"compositePrimaryKeys": {},
28
-
"uniqueConstraints": {},
29
-
"checkConstraints": {}
30
-
},
31
-
"auth_state": {
32
-
"name": "auth_state",
33
-
"columns": {
34
-
"key": {
35
-
"name": "key",
36
-
"type": "text",
37
-
"primaryKey": true,
38
-
"notNull": true,
39
-
"autoincrement": false
40
-
},
41
-
"state": {
42
-
"name": "state",
43
-
"type": "text",
44
-
"primaryKey": false,
45
-
"notNull": true,
46
-
"autoincrement": false
47
-
}
48
-
},
49
-
"indexes": {},
50
-
"foreignKeys": {},
51
-
"compositePrimaryKeys": {},
52
-
"uniqueConstraints": {},
53
-
"checkConstraints": {}
54
-
},
55
-
"recipes": {
56
-
"name": "recipes",
57
-
"columns": {
58
-
"id": {
59
-
"name": "id",
60
-
"type": "integer",
61
-
"primaryKey": true,
62
-
"notNull": true,
63
-
"autoincrement": false
64
-
},
65
-
"rkey": {
66
-
"name": "rkey",
67
-
"type": "text",
68
-
"primaryKey": false,
69
-
"notNull": true,
70
-
"autoincrement": false
71
-
},
72
-
"title": {
73
-
"name": "title",
74
-
"type": "text",
75
-
"primaryKey": false,
76
-
"notNull": false,
77
-
"autoincrement": false
78
-
},
79
-
"time": {
80
-
"name": "time",
81
-
"type": "integer",
82
-
"primaryKey": false,
83
-
"notNull": true,
84
-
"autoincrement": false,
85
-
"default": 0
86
-
},
87
-
"description": {
88
-
"name": "description",
89
-
"type": "text",
90
-
"primaryKey": false,
91
-
"notNull": false,
92
-
"autoincrement": false
93
-
},
94
-
"ingredients": {
95
-
"name": "ingredients",
96
-
"type": "text",
97
-
"primaryKey": false,
98
-
"notNull": true,
99
-
"autoincrement": false
100
-
},
101
-
"steps": {
102
-
"name": "steps",
103
-
"type": "text",
104
-
"primaryKey": false,
105
-
"notNull": true,
106
-
"autoincrement": false
107
-
},
108
-
"created_at": {
109
-
"name": "created_at",
110
-
"type": "text",
111
-
"primaryKey": false,
112
-
"notNull": true,
113
-
"autoincrement": false
114
-
},
115
-
"author_did": {
116
-
"name": "author_did",
117
-
"type": "text",
118
-
"primaryKey": false,
119
-
"notNull": true,
120
-
"autoincrement": false
121
-
}
122
-
},
123
-
"indexes": {
124
-
"recipes_id_unique": {
125
-
"name": "recipes_id_unique",
126
-
"columns": [
127
-
"id"
128
-
],
129
-
"isUnique": true
130
-
},
131
-
"recipes_rkey_author_did_unique": {
132
-
"name": "recipes_rkey_author_did_unique",
133
-
"columns": [
134
-
"rkey",
135
-
"author_did"
136
-
],
137
-
"isUnique": true
138
-
}
139
-
},
140
-
"foreignKeys": {},
141
-
"compositePrimaryKeys": {},
142
-
"uniqueConstraints": {},
143
-
"checkConstraints": {}
144
-
}
145
-
},
146
-
"views": {},
147
-
"enums": {},
148
-
"_meta": {
149
-
"schemas": {},
150
-
"tables": {},
151
-
"columns": {}
152
-
},
153
-
"internal": {
154
-
"indexes": {}
155
-
}
156
-
}
-163
libs/database/migrations/meta/0003_snapshot.json
-163
libs/database/migrations/meta/0003_snapshot.json
···
1
-
{
2
-
"version": "6",
3
-
"dialect": "sqlite",
4
-
"id": "fa77a98d-2ae1-49d5-ab93-81492dcbdebd",
5
-
"prevId": "5e0d9054-f192-4db9-8afe-afcabe08e661",
6
-
"tables": {
7
-
"auth_session": {
8
-
"name": "auth_session",
9
-
"columns": {
10
-
"key": {
11
-
"name": "key",
12
-
"type": "text",
13
-
"primaryKey": true,
14
-
"notNull": true,
15
-
"autoincrement": false
16
-
},
17
-
"session": {
18
-
"name": "session",
19
-
"type": "text",
20
-
"primaryKey": false,
21
-
"notNull": true,
22
-
"autoincrement": false
23
-
}
24
-
},
25
-
"indexes": {},
26
-
"foreignKeys": {},
27
-
"compositePrimaryKeys": {},
28
-
"uniqueConstraints": {},
29
-
"checkConstraints": {}
30
-
},
31
-
"auth_state": {
32
-
"name": "auth_state",
33
-
"columns": {
34
-
"key": {
35
-
"name": "key",
36
-
"type": "text",
37
-
"primaryKey": true,
38
-
"notNull": true,
39
-
"autoincrement": false
40
-
},
41
-
"state": {
42
-
"name": "state",
43
-
"type": "text",
44
-
"primaryKey": false,
45
-
"notNull": true,
46
-
"autoincrement": false
47
-
}
48
-
},
49
-
"indexes": {},
50
-
"foreignKeys": {},
51
-
"compositePrimaryKeys": {},
52
-
"uniqueConstraints": {},
53
-
"checkConstraints": {}
54
-
},
55
-
"recipes": {
56
-
"name": "recipes",
57
-
"columns": {
58
-
"id": {
59
-
"name": "id",
60
-
"type": "integer",
61
-
"primaryKey": true,
62
-
"notNull": true,
63
-
"autoincrement": false
64
-
},
65
-
"rkey": {
66
-
"name": "rkey",
67
-
"type": "text",
68
-
"primaryKey": false,
69
-
"notNull": true,
70
-
"autoincrement": false
71
-
},
72
-
"title": {
73
-
"name": "title",
74
-
"type": "text",
75
-
"primaryKey": false,
76
-
"notNull": true,
77
-
"autoincrement": false
78
-
},
79
-
"image_ref": {
80
-
"name": "image_ref",
81
-
"type": "text",
82
-
"primaryKey": false,
83
-
"notNull": false,
84
-
"autoincrement": false
85
-
},
86
-
"time": {
87
-
"name": "time",
88
-
"type": "integer",
89
-
"primaryKey": false,
90
-
"notNull": true,
91
-
"autoincrement": false,
92
-
"default": 0
93
-
},
94
-
"description": {
95
-
"name": "description",
96
-
"type": "text",
97
-
"primaryKey": false,
98
-
"notNull": false,
99
-
"autoincrement": false
100
-
},
101
-
"ingredients": {
102
-
"name": "ingredients",
103
-
"type": "text",
104
-
"primaryKey": false,
105
-
"notNull": true,
106
-
"autoincrement": false
107
-
},
108
-
"steps": {
109
-
"name": "steps",
110
-
"type": "text",
111
-
"primaryKey": false,
112
-
"notNull": true,
113
-
"autoincrement": false
114
-
},
115
-
"created_at": {
116
-
"name": "created_at",
117
-
"type": "text",
118
-
"primaryKey": false,
119
-
"notNull": true,
120
-
"autoincrement": false
121
-
},
122
-
"author_did": {
123
-
"name": "author_did",
124
-
"type": "text",
125
-
"primaryKey": false,
126
-
"notNull": true,
127
-
"autoincrement": false
128
-
}
129
-
},
130
-
"indexes": {
131
-
"recipes_id_unique": {
132
-
"name": "recipes_id_unique",
133
-
"columns": [
134
-
"id"
135
-
],
136
-
"isUnique": true
137
-
},
138
-
"recipes_rkey_author_did_unique": {
139
-
"name": "recipes_rkey_author_did_unique",
140
-
"columns": [
141
-
"rkey",
142
-
"author_did"
143
-
],
144
-
"isUnique": true
145
-
}
146
-
},
147
-
"foreignKeys": {},
148
-
"compositePrimaryKeys": {},
149
-
"uniqueConstraints": {},
150
-
"checkConstraints": {}
151
-
}
152
-
},
153
-
"views": {},
154
-
"enums": {},
155
-
"_meta": {
156
-
"schemas": {},
157
-
"tables": {},
158
-
"columns": {}
159
-
},
160
-
"internal": {
161
-
"indexes": {}
162
-
}
163
-
}
-170
libs/database/migrations/meta/0004_snapshot.json
-170
libs/database/migrations/meta/0004_snapshot.json
···
1
-
{
2
-
"version": "6",
3
-
"dialect": "sqlite",
4
-
"id": "d6e34451-dba5-4458-8471-ac988decffec",
5
-
"prevId": "fa77a98d-2ae1-49d5-ab93-81492dcbdebd",
6
-
"tables": {
7
-
"auth_session": {
8
-
"name": "auth_session",
9
-
"columns": {
10
-
"key": {
11
-
"name": "key",
12
-
"type": "text",
13
-
"primaryKey": true,
14
-
"notNull": true,
15
-
"autoincrement": false
16
-
},
17
-
"session": {
18
-
"name": "session",
19
-
"type": "text",
20
-
"primaryKey": false,
21
-
"notNull": true,
22
-
"autoincrement": false
23
-
}
24
-
},
25
-
"indexes": {},
26
-
"foreignKeys": {},
27
-
"compositePrimaryKeys": {},
28
-
"uniqueConstraints": {},
29
-
"checkConstraints": {}
30
-
},
31
-
"auth_state": {
32
-
"name": "auth_state",
33
-
"columns": {
34
-
"key": {
35
-
"name": "key",
36
-
"type": "text",
37
-
"primaryKey": true,
38
-
"notNull": true,
39
-
"autoincrement": false
40
-
},
41
-
"state": {
42
-
"name": "state",
43
-
"type": "text",
44
-
"primaryKey": false,
45
-
"notNull": true,
46
-
"autoincrement": false
47
-
}
48
-
},
49
-
"indexes": {},
50
-
"foreignKeys": {},
51
-
"compositePrimaryKeys": {},
52
-
"uniqueConstraints": {},
53
-
"checkConstraints": {}
54
-
},
55
-
"recipes": {
56
-
"name": "recipes",
57
-
"columns": {
58
-
"id": {
59
-
"name": "id",
60
-
"type": "integer",
61
-
"primaryKey": true,
62
-
"notNull": true,
63
-
"autoincrement": false
64
-
},
65
-
"rkey": {
66
-
"name": "rkey",
67
-
"type": "text",
68
-
"primaryKey": false,
69
-
"notNull": true,
70
-
"autoincrement": false
71
-
},
72
-
"title": {
73
-
"name": "title",
74
-
"type": "text",
75
-
"primaryKey": false,
76
-
"notNull": true,
77
-
"autoincrement": false
78
-
},
79
-
"image_ref": {
80
-
"name": "image_ref",
81
-
"type": "text",
82
-
"primaryKey": false,
83
-
"notNull": false,
84
-
"autoincrement": false
85
-
},
86
-
"time": {
87
-
"name": "time",
88
-
"type": "integer",
89
-
"primaryKey": false,
90
-
"notNull": true,
91
-
"autoincrement": false,
92
-
"default": 0
93
-
},
94
-
"serves": {
95
-
"name": "serves",
96
-
"type": "integer",
97
-
"primaryKey": false,
98
-
"notNull": false,
99
-
"autoincrement": false
100
-
},
101
-
"description": {
102
-
"name": "description",
103
-
"type": "text",
104
-
"primaryKey": false,
105
-
"notNull": false,
106
-
"autoincrement": false
107
-
},
108
-
"ingredients": {
109
-
"name": "ingredients",
110
-
"type": "text",
111
-
"primaryKey": false,
112
-
"notNull": true,
113
-
"autoincrement": false
114
-
},
115
-
"steps": {
116
-
"name": "steps",
117
-
"type": "text",
118
-
"primaryKey": false,
119
-
"notNull": true,
120
-
"autoincrement": false
121
-
},
122
-
"created_at": {
123
-
"name": "created_at",
124
-
"type": "text",
125
-
"primaryKey": false,
126
-
"notNull": true,
127
-
"autoincrement": false
128
-
},
129
-
"author_did": {
130
-
"name": "author_did",
131
-
"type": "text",
132
-
"primaryKey": false,
133
-
"notNull": true,
134
-
"autoincrement": false
135
-
}
136
-
},
137
-
"indexes": {
138
-
"recipes_id_unique": {
139
-
"name": "recipes_id_unique",
140
-
"columns": [
141
-
"id"
142
-
],
143
-
"isUnique": true
144
-
},
145
-
"recipes_rkey_author_did_unique": {
146
-
"name": "recipes_rkey_author_did_unique",
147
-
"columns": [
148
-
"rkey",
149
-
"author_did"
150
-
],
151
-
"isUnique": true
152
-
}
153
-
},
154
-
"foreignKeys": {},
155
-
"compositePrimaryKeys": {},
156
-
"uniqueConstraints": {},
157
-
"checkConstraints": {}
158
-
}
159
-
},
160
-
"views": {},
161
-
"enums": {},
162
-
"_meta": {
163
-
"schemas": {},
164
-
"tables": {},
165
-
"columns": {}
166
-
},
167
-
"internal": {
168
-
"indexes": {}
169
-
}
170
-
}
+4
-32
libs/database/migrations/meta/_journal.json
+4
-32
libs/database/migrations/meta/_journal.json
···
1
1
{
2
2
"version": "7",
3
-
"dialect": "sqlite",
3
+
"dialect": "postgresql",
4
4
"entries": [
5
5
{
6
6
"idx": 0,
7
-
"version": "6",
8
-
"when": 1733683012154,
9
-
"tag": "0000_boring_tenebrous",
10
-
"breakpoints": true
11
-
},
12
-
{
13
-
"idx": 1,
14
-
"version": "6",
15
-
"when": 1734630004978,
16
-
"tag": "0001_icy_killmonger",
17
-
"breakpoints": true
18
-
},
19
-
{
20
-
"idx": 2,
21
-
"version": "6",
22
-
"when": 1734642833768,
23
-
"tag": "0002_redundant_wither",
24
-
"breakpoints": true
25
-
},
26
-
{
27
-
"idx": 3,
28
-
"version": "6",
29
-
"when": 1734643156502,
30
-
"tag": "0003_fixed_peter_parker",
31
-
"breakpoints": true
32
-
},
33
-
{
34
-
"idx": 4,
35
-
"version": "6",
36
-
"when": 1735493787990,
37
-
"tag": "0004_left_sersi",
7
+
"version": "7",
8
+
"when": 1764420650497,
9
+
"tag": "0000_young_hellcat",
38
10
"breakpoints": true
39
11
}
40
12
]
+19
-6
libs/database/package.json
+19
-6
libs/database/package.json
···
1
1
{
2
+
"type": "module",
2
3
"name": "@cookware/database",
3
4
"version": "0.0.0",
4
5
"private": true,
5
-
"main": "dist/index.js",
6
-
"type": "module",
6
+
"files": [
7
+
"dist/",
8
+
"lib/",
9
+
"!lib/**/*.bench.ts",
10
+
"!lib/**/*.test.ts"
11
+
],
12
+
"exports": {
13
+
".": "./dist/index.js",
14
+
"./schema": "./dist/schema.js"
15
+
},
7
16
"scripts": {
8
-
"dev": "tsc --watch",
9
-
"build": "tsc",
17
+
"dev": "tsc --watch --project tsconfig.build.json",
18
+
"build": "tsc --project tsconfig.build.json",
10
19
"db:generate": "drizzle-kit generate",
11
20
"db:migrate": "drizzle-kit migrate",
12
21
"db:studio": "drizzle-kit studio"
13
22
},
14
23
"devDependencies": {
24
+
"@atcute/lexicons": "catalog:",
15
25
"@atproto/oauth-client-node": "^0.2.3",
16
26
"@cookware/lexicons": "workspace:*",
17
27
"@cookware/tsconfig": "workspace:*",
28
+
"@types/bun": "catalog:",
18
29
"@types/node": "^22.10.1",
30
+
"@types/pg": "^8.15.6",
19
31
"drizzle-kit": "^0.29.0",
20
32
"typescript": "^5.2.2"
21
33
},
22
34
"dependencies": {
23
-
"@libsql/client": "^0.14.0",
24
-
"drizzle-orm": "^0.37.0",
35
+
"@libsql/client": "^0.15.15",
36
+
"drizzle-orm": "catalog:",
37
+
"pg": "^8.16.3",
25
38
"zod": "^3.23.8"
26
39
}
27
40
}
-18
libs/database/src/config.ts
-18
libs/database/src/config.ts
···
1
-
import { z } from "zod";
2
-
3
-
const envSchema = z.object({
4
-
TURSO_CONNECTION_URL: z.string().default('https://turso.dev.hayden.moe'),
5
-
TURSO_AUTH_TOKEN: z.string().or(z.undefined()),
6
-
7
-
ENV: z
8
-
.union([
9
-
z.literal('development'),
10
-
z.literal('production'),
11
-
])
12
-
.default('development'),
13
-
});
14
-
15
-
const env = envSchema.parse(process.env);
16
-
17
-
export default env;
18
-
export type Env = z.infer<typeof envSchema>;
-11
libs/database/src/database.ts
-11
libs/database/src/database.ts
···
1
-
import { drizzle } from "drizzle-orm/libsql";
2
-
import { createClient } from "@libsql/client";
3
-
import * as schema from "./schema.js";
4
-
import env from "./config.js";
5
-
6
-
const client = createClient({
7
-
url: env.TURSO_CONNECTION_URL,
8
-
authToken: env.TURSO_AUTH_TOKEN,
9
-
});
10
-
11
-
export const db = drizzle(client, { schema });
-2
libs/database/src/index.ts
-2
libs/database/src/index.ts
-44
libs/database/src/schema.ts
-44
libs/database/src/schema.ts
···
1
-
import { customType, int, sqliteTable, text, unique } from "drizzle-orm/sqlite-core";
2
-
import { DID } from "@cookware/lexicons";
3
-
import { Ingredient, Step } from "@cookware/lexicons";
4
-
import { NodeSavedSession, NodeSavedState } from "@atproto/oauth-client-node";
5
-
6
-
const did = customType<{ data: DID }>({
7
-
dataType() {
8
-
return "text";
9
-
},
10
-
});
11
-
12
-
const dateIsoText = customType<{ data: Date; driverData: string }>({
13
-
dataType() {
14
-
return "text";
15
-
},
16
-
toDriver: (value) => value.toISOString(),
17
-
fromDriver: (value) => new Date(value),
18
-
});
19
-
20
-
export const recipeTable = sqliteTable("recipes", {
21
-
id: int('id').primaryKey().notNull().unique(),
22
-
rkey: text('rkey').notNull(),
23
-
title: text('title').notNull(),
24
-
imageRef: text('image_ref'),
25
-
time: int('time').notNull().default(0),
26
-
serves: int('serves'),
27
-
description: text('description'),
28
-
ingredients: text('ingredients', { mode: 'json' }).$type<Partial<Ingredient>[]>().notNull(),
29
-
steps: text('steps', { mode: 'json' }).$type<Partial<Step>[]>().notNull(),
30
-
createdAt: dateIsoText("created_at").notNull(),
31
-
authorDid: did("author_did").notNull(),
32
-
}, t => ({
33
-
unique_author_rkey: unique().on(t.rkey, t.authorDid),
34
-
}));
35
-
36
-
export const authStateTable = sqliteTable("auth_state", {
37
-
key: text().primaryKey(),
38
-
state: text({ mode: 'json' }).$type<NodeSavedState>().notNull(),
39
-
});
40
-
41
-
export const authSessionTable = sqliteTable("auth_session", {
42
-
key: text().primaryKey(),
43
-
session: text({ mode: 'json' }).$type<NodeSavedSession>().notNull(),
44
-
});
+8
libs/database/tsconfig.build.json
+8
libs/database/tsconfig.build.json
+2
-3
libs/database/tsconfig.json
+2
-3
libs/database/tsconfig.json
+1
libs/lexicons/.gitignore
+1
libs/lexicons/.gitignore
···
1
+
tsp-output
+7
libs/lexicons/lex.config.ts
+7
libs/lexicons/lex.config.ts
+20
libs/lexicons/lexicons/feed/defs.tsp
+20
libs/lexicons/lexicons/feed/defs.tsp
···
1
+
import "@typelex/emitter";
2
+
import "../profiles";
3
+
4
+
namespace blue.recipes.feed.defs {
5
+
/** Response model for fetching multiple recipes. */
6
+
model RecipeView {
7
+
@required uri: atUri;
8
+
@required cid: cid;
9
+
@required rkey: string;
10
+
imageUrl?: url;
11
+
@required author: blue.recipes.actor.defs.ProfileViewBasic;
12
+
@required record: blue.recipes.feed.recipe.Main;
13
+
@required indexedAt: datetime;
14
+
}
15
+
16
+
model NotFoundRecipe {
17
+
@required uri: atUri;
18
+
@readOnly @required notFound: boolean = true;
19
+
}
20
+
}
+16
libs/lexicons/lexicons/feed/getRecipe.tsp
+16
libs/lexicons/lexicons/feed/getRecipe.tsp
···
1
+
import "@typelex/emitter";
2
+
import "./defs.tsp";
3
+
4
+
namespace blue.recipes.feed.getRecipe {
5
+
/** Response model for fetching multiple recipes. */
6
+
@query
7
+
@errors(NotFound, InvalidUri)
8
+
op main(
9
+
@required uris: atUri[],
10
+
): {
11
+
@required recipes: blue.recipes.feed.defs.RecipeView[];
12
+
};
13
+
14
+
@error model NotFound {}
15
+
@error model InvalidUri {}
16
+
}
+15
libs/lexicons/lexicons/feed/getRecipes.tsp
+15
libs/lexicons/lexicons/feed/getRecipes.tsp
···
1
+
import "@typelex/emitter";
2
+
import "./defs.tsp";
3
+
4
+
namespace blue.recipes.feed.getRecipes {
5
+
/** Response model for fetching multiple recipes. */
6
+
@query
7
+
op main(
8
+
author?: atIdentifier,
9
+
@minValue(1) @maxValue(100) limit?: integer = 50,
10
+
cursor?: string,
11
+
): {
12
+
@required recipes: blue.recipes.feed.defs.RecipeView[];
13
+
@required nextCursor: string;
14
+
};
15
+
}
+4
libs/lexicons/lexicons/feed/main.tsp
+4
libs/lexicons/lexicons/feed/main.tsp
+48
libs/lexicons/lexicons/feed/recipe.tsp
+48
libs/lexicons/lexicons/feed/recipe.tsp
···
1
+
import "@typelex/emitter";
2
+
3
+
namespace blue.recipes.feed.recipe {
4
+
/** Record containing a recipe. */
5
+
@rec("tid")
6
+
model Main {
7
+
@maxGraphemes(300)
8
+
@maxLength(3000)
9
+
@required title: string;
10
+
11
+
/** Free-form recipe description text. */
12
+
@maxGraphemes(300)
13
+
@maxLength(3000)
14
+
description?: string;
15
+
16
+
/** Image representing the recipe. */
17
+
image?: Blob<#["image/png", "image/jpeg"], 1000000>; // 1mb image
18
+
19
+
/** The amount of time (in minutes) it takes to complete the recipe. */
20
+
time?: integer;
21
+
22
+
/** The number of servings the recipe prepares. */
23
+
serves?: integer;
24
+
25
+
@required steps: Step[];
26
+
@required ingredients: Ingredient[];
27
+
28
+
@format("datetime")
29
+
createdAt?: string;
30
+
}
31
+
32
+
model Ingredient {
33
+
/** The name of the ingredient. */
34
+
@maxLength(3000)
35
+
@maxGraphemes(300)
36
+
@required name: string;
37
+
38
+
/** The amount of the ingredient needed. */
39
+
amount?: string;
40
+
}
41
+
42
+
model Step {
43
+
/** The instruction to provide to the user. */
44
+
@maxLength(5000)
45
+
@maxGraphemes(500)
46
+
@required text: string;
47
+
}
48
+
}
+41
libs/lexicons/lexicons/profiles/defs.tsp
+41
libs/lexicons/lexicons/profiles/defs.tsp
···
1
+
import "@typelex/emitter";
2
+
3
+
namespace blue.recipes.actor.defs {
4
+
model ProfileViewBasic {
5
+
@required did: did;
6
+
@required handle: handle;
7
+
8
+
@maxGraphemes(64)
9
+
@maxLength(640)
10
+
displayName?: string;
11
+
12
+
pronouns?: string;
13
+
avatar?: url;
14
+
15
+
@format("datetime")
16
+
createdAt?: string;
17
+
}
18
+
19
+
model ProfileViewDetailed {
20
+
@required did: did;
21
+
@required handle: handle;
22
+
23
+
@maxGraphemes(64)
24
+
@maxLength(640)
25
+
displayName?: string;
26
+
27
+
@maxGraphemes(256)
28
+
@maxLength(2500)
29
+
description?: string;
30
+
31
+
pronouns?: string;
32
+
website?: url;
33
+
avatar?: url;
34
+
banner?: url;
35
+
36
+
recipesCount?: integer;
37
+
38
+
@format("datetime")
39
+
createdAt?: string;
40
+
}
41
+
}
+9
libs/lexicons/lexicons/profiles/getProfile.tsp
+9
libs/lexicons/lexicons/profiles/getProfile.tsp
+3
libs/lexicons/lexicons/profiles/main.tsp
+3
libs/lexicons/lexicons/profiles/main.tsp
+31
libs/lexicons/lexicons/profiles/profile.tsp
+31
libs/lexicons/lexicons/profiles/profile.tsp
···
1
+
import "@typelex/emitter";
2
+
3
+
namespace blue.recipes.actor.profile {
4
+
@rec("literal:self")
5
+
model Main {
6
+
@maxGraphemes(64)
7
+
@maxLength(640)
8
+
@required displayName: string;
9
+
10
+
/** Free-form profile description text. */
11
+
@maxGraphemes(256)
12
+
@maxLength(2500)
13
+
description?: string;
14
+
15
+
/** Free-form text to describe pronouns. */
16
+
@maxGraphemes(20)
17
+
@maxLength(200)
18
+
pronouns?: string;
19
+
20
+
website?: uri;
21
+
22
+
/** Small image to be displayed on the profile. */
23
+
avatar?: Blob<#["image/png", "image/jpeg"], 1000000>; // 1mb image
24
+
25
+
/** Larger header image to be displayed on the profile. */
26
+
banner?: Blob<#["image/png", "image/jpeg"], 1000000>; // 1mb image
27
+
28
+
@format("datetime")
29
+
createdAt?: string;
30
+
}
31
+
}
+7
libs/lexicons/lib/index.ts
+7
libs/lexicons/lib/index.ts
···
1
+
export * as BlueRecipesActorDefs from "./types/blue/recipes/actor/defs.js";
2
+
export * as BlueRecipesActorGetProfile from "./types/blue/recipes/actor/getProfile.js";
3
+
export * as BlueRecipesActorProfile from "./types/blue/recipes/actor/profile.js";
4
+
export * as BlueRecipesFeedDefs from "./types/blue/recipes/feed/defs.js";
5
+
export * as BlueRecipesFeedGetRecipe from "./types/blue/recipes/feed/getRecipe.js";
6
+
export * as BlueRecipesFeedGetRecipes from "./types/blue/recipes/feed/getRecipes.js";
7
+
export * as BlueRecipesFeedRecipe from "./types/blue/recipes/feed/recipe.js";
+73
libs/lexicons/lib/types/blue/recipes/actor/defs.ts
+73
libs/lexicons/lib/types/blue/recipes/actor/defs.ts
···
1
+
import type {} from "@atcute/lexicons";
2
+
import * as v from "@atcute/lexicons/validations";
3
+
4
+
const _profileViewBasicSchema = /*#__PURE__*/ v.object({
5
+
$type: /*#__PURE__*/ v.optional(
6
+
/*#__PURE__*/ v.literal("blue.recipes.actor.defs#profileViewBasic"),
7
+
),
8
+
avatar: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()),
9
+
createdAt: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()),
10
+
did: /*#__PURE__*/ v.didString(),
11
+
/**
12
+
* @maxLength 640
13
+
* @maxGraphemes 64
14
+
*/
15
+
displayName: /*#__PURE__*/ v.optional(
16
+
/*#__PURE__*/ v.constrain(/*#__PURE__*/ v.string(), [
17
+
/*#__PURE__*/ v.stringLength(0, 640),
18
+
/*#__PURE__*/ v.stringGraphemes(0, 64),
19
+
]),
20
+
),
21
+
handle: /*#__PURE__*/ v.handleString(),
22
+
pronouns: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()),
23
+
});
24
+
const _profileViewDetailedSchema = /*#__PURE__*/ v.object({
25
+
$type: /*#__PURE__*/ v.optional(
26
+
/*#__PURE__*/ v.literal("blue.recipes.actor.defs#profileViewDetailed"),
27
+
),
28
+
avatar: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()),
29
+
banner: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()),
30
+
createdAt: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()),
31
+
/**
32
+
* @maxLength 2500
33
+
* @maxGraphemes 256
34
+
*/
35
+
description: /*#__PURE__*/ v.optional(
36
+
/*#__PURE__*/ v.constrain(/*#__PURE__*/ v.string(), [
37
+
/*#__PURE__*/ v.stringLength(0, 2500),
38
+
/*#__PURE__*/ v.stringGraphemes(0, 256),
39
+
]),
40
+
),
41
+
did: /*#__PURE__*/ v.didString(),
42
+
/**
43
+
* @maxLength 640
44
+
* @maxGraphemes 64
45
+
*/
46
+
displayName: /*#__PURE__*/ v.optional(
47
+
/*#__PURE__*/ v.constrain(/*#__PURE__*/ v.string(), [
48
+
/*#__PURE__*/ v.stringLength(0, 640),
49
+
/*#__PURE__*/ v.stringGraphemes(0, 64),
50
+
]),
51
+
),
52
+
handle: /*#__PURE__*/ v.handleString(),
53
+
pronouns: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()),
54
+
recipesCount: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.integer()),
55
+
website: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()),
56
+
});
57
+
58
+
type profileViewBasic$schematype = typeof _profileViewBasicSchema;
59
+
type profileViewDetailed$schematype = typeof _profileViewDetailedSchema;
60
+
61
+
export interface profileViewBasicSchema extends profileViewBasic$schematype {}
62
+
export interface profileViewDetailedSchema
63
+
extends profileViewDetailed$schematype {}
64
+
65
+
export const profileViewBasicSchema =
66
+
_profileViewBasicSchema as profileViewBasicSchema;
67
+
export const profileViewDetailedSchema =
68
+
_profileViewDetailedSchema as profileViewDetailedSchema;
69
+
70
+
export interface ProfileViewBasic
71
+
extends v.InferInput<typeof profileViewBasicSchema> {}
72
+
export interface ProfileViewDetailed
73
+
extends v.InferInput<typeof profileViewDetailedSchema> {}
+31
libs/lexicons/lib/types/blue/recipes/actor/getProfile.ts
+31
libs/lexicons/lib/types/blue/recipes/actor/getProfile.ts
···
1
+
import type {} from "@atcute/lexicons";
2
+
import * as v from "@atcute/lexicons/validations";
3
+
import type {} from "@atcute/lexicons/ambient";
4
+
import * as BlueRecipesActorDefs from "./defs.js";
5
+
6
+
const _mainSchema = /*#__PURE__*/ v.query("blue.recipes.actor.getProfile", {
7
+
params: /*#__PURE__*/ v.object({
8
+
actor: /*#__PURE__*/ v.actorIdentifierString(),
9
+
}),
10
+
output: {
11
+
type: "lex",
12
+
get schema() {
13
+
return BlueRecipesActorDefs.profileViewDetailedSchema;
14
+
},
15
+
},
16
+
});
17
+
18
+
type main$schematype = typeof _mainSchema;
19
+
20
+
export interface mainSchema extends main$schematype {}
21
+
22
+
export const mainSchema = _mainSchema as mainSchema;
23
+
24
+
export interface $params extends v.InferInput<mainSchema["params"]> {}
25
+
export type $output = v.InferXRPCBodyInput<mainSchema["output"]>;
26
+
27
+
declare module "@atcute/lexicons/ambient" {
28
+
interface XRPCQueries {
29
+
"blue.recipes.actor.getProfile": mainSchema;
30
+
}
31
+
}
+68
libs/lexicons/lib/types/blue/recipes/actor/profile.ts
+68
libs/lexicons/lib/types/blue/recipes/actor/profile.ts
···
1
+
import type {} from "@atcute/lexicons";
2
+
import * as v from "@atcute/lexicons/validations";
3
+
import type {} from "@atcute/lexicons/ambient";
4
+
5
+
const _mainSchema = /*#__PURE__*/ v.record(
6
+
/*#__PURE__*/ v.literal("self"),
7
+
/*#__PURE__*/ v.object({
8
+
$type: /*#__PURE__*/ v.literal("blue.recipes.actor.profile"),
9
+
/**
10
+
* Small image to be displayed on the profile.
11
+
* @accept image/png, image/jpeg
12
+
* @maxSize 1000000
13
+
*/
14
+
avatar: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.blob()),
15
+
/**
16
+
* Larger header image to be displayed on the profile.
17
+
* @accept image/png, image/jpeg
18
+
* @maxSize 1000000
19
+
*/
20
+
banner: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.blob()),
21
+
createdAt: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()),
22
+
/**
23
+
* Free-form profile description text.
24
+
* @maxLength 2500
25
+
* @maxGraphemes 256
26
+
*/
27
+
description: /*#__PURE__*/ v.optional(
28
+
/*#__PURE__*/ v.constrain(/*#__PURE__*/ v.string(), [
29
+
/*#__PURE__*/ v.stringLength(0, 2500),
30
+
/*#__PURE__*/ v.stringGraphemes(0, 256),
31
+
]),
32
+
),
33
+
/**
34
+
* @maxLength 640
35
+
* @maxGraphemes 64
36
+
*/
37
+
displayName: /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.string(), [
38
+
/*#__PURE__*/ v.stringLength(0, 640),
39
+
/*#__PURE__*/ v.stringGraphemes(0, 64),
40
+
]),
41
+
/**
42
+
* Free-form text to describe pronouns.
43
+
* @maxLength 200
44
+
* @maxGraphemes 20
45
+
*/
46
+
pronouns: /*#__PURE__*/ v.optional(
47
+
/*#__PURE__*/ v.constrain(/*#__PURE__*/ v.string(), [
48
+
/*#__PURE__*/ v.stringLength(0, 200),
49
+
/*#__PURE__*/ v.stringGraphemes(0, 20),
50
+
]),
51
+
),
52
+
website: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.genericUriString()),
53
+
}),
54
+
);
55
+
56
+
type main$schematype = typeof _mainSchema;
57
+
58
+
export interface mainSchema extends main$schematype {}
59
+
60
+
export const mainSchema = _mainSchema as mainSchema;
61
+
62
+
export interface Main extends v.InferInput<typeof mainSchema> {}
63
+
64
+
declare module "@atcute/lexicons/ambient" {
65
+
interface Records {
66
+
"blue.recipes.actor.profile": mainSchema;
67
+
}
68
+
}
+42
libs/lexicons/lib/types/blue/recipes/feed/defs.ts
+42
libs/lexicons/lib/types/blue/recipes/feed/defs.ts
···
1
+
import type {} from "@atcute/lexicons";
2
+
import * as v from "@atcute/lexicons/validations";
3
+
import * as BlueRecipesActorDefs from "../actor/defs.js";
4
+
import * as BlueRecipesFeedRecipe from "./recipe.js";
5
+
6
+
const _notFoundRecipeSchema = /*#__PURE__*/ v.object({
7
+
$type: /*#__PURE__*/ v.optional(
8
+
/*#__PURE__*/ v.literal("blue.recipes.feed.defs#notFoundRecipe"),
9
+
),
10
+
notFound: /*#__PURE__*/ v.literal(true),
11
+
uri: /*#__PURE__*/ v.resourceUriString(),
12
+
});
13
+
const _recipeViewSchema = /*#__PURE__*/ v.object({
14
+
$type: /*#__PURE__*/ v.optional(
15
+
/*#__PURE__*/ v.literal("blue.recipes.feed.defs#recipeView"),
16
+
),
17
+
get author() {
18
+
return BlueRecipesActorDefs.profileViewBasicSchema;
19
+
},
20
+
cid: /*#__PURE__*/ v.cidString(),
21
+
imageUrl: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()),
22
+
indexedAt: /*#__PURE__*/ v.datetimeString(),
23
+
get record() {
24
+
return BlueRecipesFeedRecipe.mainSchema;
25
+
},
26
+
rkey: /*#__PURE__*/ v.string(),
27
+
uri: /*#__PURE__*/ v.resourceUriString(),
28
+
});
29
+
30
+
type notFoundRecipe$schematype = typeof _notFoundRecipeSchema;
31
+
type recipeView$schematype = typeof _recipeViewSchema;
32
+
33
+
export interface notFoundRecipeSchema extends notFoundRecipe$schematype {}
34
+
export interface recipeViewSchema extends recipeView$schematype {}
35
+
36
+
export const notFoundRecipeSchema =
37
+
_notFoundRecipeSchema as notFoundRecipeSchema;
38
+
export const recipeViewSchema = _recipeViewSchema as recipeViewSchema;
39
+
40
+
export interface NotFoundRecipe
41
+
extends v.InferInput<typeof notFoundRecipeSchema> {}
42
+
export interface RecipeView extends v.InferInput<typeof recipeViewSchema> {}
+39
libs/lexicons/lib/types/blue/recipes/feed/getRecipe.ts
+39
libs/lexicons/lib/types/blue/recipes/feed/getRecipe.ts
···
1
+
import type {} from "@atcute/lexicons";
2
+
import * as v from "@atcute/lexicons/validations";
3
+
import type {} from "@atcute/lexicons/ambient";
4
+
import * as BlueRecipesFeedDefs from "./defs.js";
5
+
6
+
const _mainSchema = /*#__PURE__*/ v.query("blue.recipes.feed.getRecipe", {
7
+
params: /*#__PURE__*/ v.object({
8
+
/**
9
+
* @minLength 1
10
+
*/
11
+
uris: /*#__PURE__*/ v.constrain(
12
+
/*#__PURE__*/ v.array(/*#__PURE__*/ v.resourceUriString()),
13
+
[/*#__PURE__*/ v.arrayLength(1)],
14
+
),
15
+
}),
16
+
output: {
17
+
type: "lex",
18
+
schema: /*#__PURE__*/ v.object({
19
+
get recipes() {
20
+
return /*#__PURE__*/ v.array(BlueRecipesFeedDefs.recipeViewSchema);
21
+
},
22
+
}),
23
+
},
24
+
});
25
+
26
+
type main$schematype = typeof _mainSchema;
27
+
28
+
export interface mainSchema extends main$schematype {}
29
+
30
+
export const mainSchema = _mainSchema as mainSchema;
31
+
32
+
export interface $params extends v.InferInput<mainSchema["params"]> {}
33
+
export interface $output extends v.InferXRPCBodyInput<mainSchema["output"]> {}
34
+
35
+
declare module "@atcute/lexicons/ambient" {
36
+
interface XRPCQueries {
37
+
"blue.recipes.feed.getRecipe": mainSchema;
38
+
}
39
+
}
+46
libs/lexicons/lib/types/blue/recipes/feed/getRecipes.ts
+46
libs/lexicons/lib/types/blue/recipes/feed/getRecipes.ts
···
1
+
import type {} from "@atcute/lexicons";
2
+
import * as v from "@atcute/lexicons/validations";
3
+
import type {} from "@atcute/lexicons/ambient";
4
+
import * as BlueRecipesFeedDefs from "./defs.js";
5
+
6
+
const _mainSchema = /*#__PURE__*/ v.query("blue.recipes.feed.getRecipes", {
7
+
params: /*#__PURE__*/ v.object({
8
+
author: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.actorIdentifierString()),
9
+
cursor: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()),
10
+
/**
11
+
* @minimum 1
12
+
* @maximum 100
13
+
* @default 50
14
+
*/
15
+
limit: /*#__PURE__*/ v.optional(
16
+
/*#__PURE__*/ v.constrain(/*#__PURE__*/ v.integer(), [
17
+
/*#__PURE__*/ v.integerRange(1, 100),
18
+
]),
19
+
50,
20
+
),
21
+
}),
22
+
output: {
23
+
type: "lex",
24
+
schema: /*#__PURE__*/ v.object({
25
+
nextCursor: /*#__PURE__*/ v.string(),
26
+
get recipes() {
27
+
return /*#__PURE__*/ v.array(BlueRecipesFeedDefs.recipeViewSchema);
28
+
},
29
+
}),
30
+
},
31
+
});
32
+
33
+
type main$schematype = typeof _mainSchema;
34
+
35
+
export interface mainSchema extends main$schematype {}
36
+
37
+
export const mainSchema = _mainSchema as mainSchema;
38
+
39
+
export interface $params extends v.InferInput<mainSchema["params"]> {}
40
+
export interface $output extends v.InferXRPCBodyInput<mainSchema["output"]> {}
41
+
42
+
declare module "@atcute/lexicons/ambient" {
43
+
interface XRPCQueries {
44
+
"blue.recipes.feed.getRecipes": mainSchema;
45
+
}
46
+
}
+104
libs/lexicons/lib/types/blue/recipes/feed/recipe.ts
+104
libs/lexicons/lib/types/blue/recipes/feed/recipe.ts
···
1
+
import type {} from "@atcute/lexicons";
2
+
import * as v from "@atcute/lexicons/validations";
3
+
import type {} from "@atcute/lexicons/ambient";
4
+
5
+
const _ingredientSchema = /*#__PURE__*/ v.object({
6
+
$type: /*#__PURE__*/ v.optional(
7
+
/*#__PURE__*/ v.literal("blue.recipes.feed.recipe#ingredient"),
8
+
),
9
+
/**
10
+
* The amount of the ingredient needed.
11
+
*/
12
+
amount: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()),
13
+
/**
14
+
* The name of the ingredient.
15
+
* @maxLength 3000
16
+
* @maxGraphemes 300
17
+
*/
18
+
name: /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.string(), [
19
+
/*#__PURE__*/ v.stringLength(0, 3000),
20
+
/*#__PURE__*/ v.stringGraphemes(0, 300),
21
+
]),
22
+
});
23
+
const _mainSchema = /*#__PURE__*/ v.record(
24
+
/*#__PURE__*/ v.tidString(),
25
+
/*#__PURE__*/ v.object({
26
+
$type: /*#__PURE__*/ v.literal("blue.recipes.feed.recipe"),
27
+
createdAt: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()),
28
+
/**
29
+
* Free-form recipe description text.
30
+
* @maxLength 3000
31
+
* @maxGraphemes 300
32
+
*/
33
+
description: /*#__PURE__*/ v.optional(
34
+
/*#__PURE__*/ v.constrain(/*#__PURE__*/ v.string(), [
35
+
/*#__PURE__*/ v.stringLength(0, 3000),
36
+
/*#__PURE__*/ v.stringGraphemes(0, 300),
37
+
]),
38
+
),
39
+
/**
40
+
* Image representing the recipe.
41
+
* @accept image/png, image/jpeg
42
+
* @maxSize 1000000
43
+
*/
44
+
image: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.blob()),
45
+
get ingredients() {
46
+
return /*#__PURE__*/ v.array(ingredientSchema);
47
+
},
48
+
/**
49
+
* The number of servings the recipe prepares.
50
+
*/
51
+
serves: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.integer()),
52
+
get steps() {
53
+
return /*#__PURE__*/ v.array(stepSchema);
54
+
},
55
+
/**
56
+
* The amount of time (in minutes) it takes to complete the recipe.
57
+
*/
58
+
time: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.integer()),
59
+
/**
60
+
* @maxLength 3000
61
+
* @maxGraphemes 300
62
+
*/
63
+
title: /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.string(), [
64
+
/*#__PURE__*/ v.stringLength(0, 3000),
65
+
/*#__PURE__*/ v.stringGraphemes(0, 300),
66
+
]),
67
+
}),
68
+
);
69
+
const _stepSchema = /*#__PURE__*/ v.object({
70
+
$type: /*#__PURE__*/ v.optional(
71
+
/*#__PURE__*/ v.literal("blue.recipes.feed.recipe#step"),
72
+
),
73
+
/**
74
+
* The instruction to provide to the user.
75
+
* @maxLength 5000
76
+
* @maxGraphemes 500
77
+
*/
78
+
text: /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.string(), [
79
+
/*#__PURE__*/ v.stringLength(0, 5000),
80
+
/*#__PURE__*/ v.stringGraphemes(0, 500),
81
+
]),
82
+
});
83
+
84
+
type ingredient$schematype = typeof _ingredientSchema;
85
+
type main$schematype = typeof _mainSchema;
86
+
type step$schematype = typeof _stepSchema;
87
+
88
+
export interface ingredientSchema extends ingredient$schematype {}
89
+
export interface mainSchema extends main$schematype {}
90
+
export interface stepSchema extends step$schematype {}
91
+
92
+
export const ingredientSchema = _ingredientSchema as ingredientSchema;
93
+
export const mainSchema = _mainSchema as mainSchema;
94
+
export const stepSchema = _stepSchema as stepSchema;
95
+
96
+
export interface Ingredient extends v.InferInput<typeof ingredientSchema> {}
97
+
export interface Main extends v.InferInput<typeof mainSchema> {}
98
+
export interface Step extends v.InferInput<typeof stepSchema> {}
99
+
100
+
declare module "@atcute/lexicons/ambient" {
101
+
interface Records {
102
+
"blue.recipes.feed.recipe": mainSchema;
103
+
}
104
+
}
+41
-12
libs/lexicons/package.json
+41
-12
libs/lexicons/package.json
···
1
1
{
2
+
"type": "module",
2
3
"name": "@cookware/lexicons",
3
4
"version": "0.0.0",
4
-
"type": "module",
5
-
"private": true,
6
-
"main": "src/index.ts",
7
-
"publishConfig": {
8
-
"access": "public"
5
+
"description": "TypeScript definitions for Atproto lexicons used in recipes.blue",
6
+
"keywords": ["atproto", "recipes.blue", "lexicons"],
7
+
"license": "BSD",
8
+
"repository": {
9
+
"url": "https://tangled.org/roost.moe/recipes.blue",
10
+
"directory": "libs/lexicons"
11
+
},
12
+
"files": [
13
+
"dist/",
14
+
"lib/*",
15
+
"!lib/**/*.bench.ts",
16
+
"!lib/**/*.test.ts"
17
+
],
18
+
"exports": {
19
+
".": "./dist/index.js",
20
+
"./did": "./dist/did.js"
21
+
},
22
+
"scripts": {
23
+
"dev": "tsc --watch --project tsconfig.build.json",
24
+
"build": "tsc --project tsconfig.build.json",
25
+
"lexcomp": "rm -rf tsp-output && tsp compile ./lexicons --emit @typelex/emitter",
26
+
"lexgen": "bun run -b lexcomp && rm -rf lib/types && lex-cli generate --config ./lex.config.ts",
27
+
"prepublish": "rm -rf dist; bun run build"
28
+
},
29
+
"dependencies": {
30
+
"@atcute/atproto": "catalog:",
31
+
"@atcute/bluesky": "catalog:",
32
+
"@atcute/client": "catalog:",
33
+
"@atcute/lexicons": "catalog:"
9
34
},
10
35
"devDependencies": {
11
-
"@atcute/client": "^2.0.6",
12
-
"@atcute/lex-cli": "^1.0.3",
36
+
"@atcute/lex-cli": "^2.3.3",
13
37
"@cookware/tsconfig": "workspace:*",
14
-
"typescript": "^5.7.2",
15
-
"zod": "^3.23.8"
38
+
"@typelex/emitter": "^0.4.0",
39
+
"@types/bun": "catalog:",
40
+
"@typespec/compiler": "^1.6.0"
16
41
},
17
-
"peerDependencies": {
18
-
"@atcute/client": "^2.0.6",
19
-
"zod": "^3.23.8"
42
+
"atcute:lexicons": {
43
+
"mappings": {
44
+
"blue.recipes.*": {
45
+
"type": "namespace",
46
+
"path": "./types/{{nsid_remainder}}"
47
+
}
48
+
}
20
49
}
21
50
}
+1
-1
libs/lexicons/scripts/generate.sh
+1
-1
libs/lexicons/scripts/generate.sh
+83
libs/lexicons/scripts/publish.ts
+83
libs/lexicons/scripts/publish.ts
···
1
+
import { readdirSync, statSync } from "fs";
2
+
import { join } from "path";
3
+
4
+
const TSP_OUTPUT_DIR = join(import.meta.dir, "../tsp-output/@typelex/emitter");
5
+
6
+
interface LexiconFile {
7
+
path: string;
8
+
id: string;
9
+
content: unknown;
10
+
}
11
+
12
+
async function crawlJsonFiles(dir: string): Promise<LexiconFile[]> {
13
+
const results: LexiconFile[] = [];
14
+
15
+
const entries = readdirSync(dir);
16
+
17
+
for (const entry of entries) {
18
+
const fullPath = join(dir, entry);
19
+
const stat = statSync(fullPath);
20
+
21
+
if (stat.isDirectory()) {
22
+
results.push(...(await crawlJsonFiles(fullPath)));
23
+
} else if (entry.endsWith(".json")) {
24
+
const file = Bun.file(fullPath);
25
+
const content = await file.json();
26
+
27
+
results.push({
28
+
path: fullPath,
29
+
id: content.id || entry.replace(".json", ""),
30
+
content,
31
+
});
32
+
}
33
+
}
34
+
35
+
return results;
36
+
}
37
+
38
+
async function generateDNSRecords(did: string): Promise<string> {
39
+
const lexicons = await crawlJsonFiles(TSP_OUTPUT_DIR);
40
+
const authorities = new Map<string, string[]>();
41
+
42
+
// group lexicons by authority (everything except the final "name" part)
43
+
for (const lex of lexicons) {
44
+
// blue.recipes.feed.getRecipe -> blue.recipes.feed (authority)
45
+
const parts = lex.id.split(".");
46
+
const authority = parts.slice(0, -1).join(".");
47
+
48
+
if (!authorities.has(authority)) {
49
+
authorities.set(authority, []);
50
+
}
51
+
authorities.get(authority)!.push(lex.id);
52
+
}
53
+
54
+
// generate DNS TXT records
55
+
const records: string[] = [];
56
+
records.push("; Lexicon DNS TXT Records for Cloudflare");
57
+
records.push("; Upload these to your Cloudflare DNS settings\n");
58
+
59
+
for (const [authority, nsids] of authorities) {
60
+
// blue.recipes.feed -> _lexicon.feed.recipes.blue
61
+
const reversedAuthority = authority.split(".").reverse().join(".");
62
+
const txtName = `_lexicon.${reversedAuthority}`;
63
+
64
+
records.push(`; Authority: ${authority}`);
65
+
records.push(`; NSIDs: ${nsids.join(", ")}`);
66
+
records.push(`${txtName}\tTXT\tdid=${did}`);
67
+
records.push("");
68
+
}
69
+
70
+
return records.join("\n");
71
+
}
72
+
73
+
// main
74
+
const did = process.argv[2];
75
+
76
+
if (!did || !did.startsWith("did:")) {
77
+
console.error("usage: bun run scripts/publish.ts <did>");
78
+
console.error("example: bun run scripts/publish.ts did:plc:xyz123");
79
+
process.exit(1);
80
+
}
81
+
82
+
const dnsRecords = await generateDNSRecords(did);
83
+
console.log(dnsRecords);
-134
libs/lexicons/src/atcute.ts
-134
libs/lexicons/src/atcute.ts
···
1
-
/* eslint-disable */
2
-
// This file is automatically generated, do not edit!
3
-
4
-
/**
5
-
* @module
6
-
* Contains type declarations for Cookware lexicons
7
-
*/
8
-
9
-
import "@atcute/client/lexicons";
10
-
11
-
declare module "@atcute/client/lexicons" {
12
-
namespace BlueRecipesFeedDefs {
13
-
interface AuthorInfo {
14
-
[Brand.Type]?: "blue.recipes.feed.defs#authorInfo";
15
-
did: string;
16
-
handle: string;
17
-
avatarUrl?: string;
18
-
displayName?: string;
19
-
}
20
-
interface Ingredient {
21
-
[Brand.Type]?: "blue.recipes.feed.defs#ingredient";
22
-
/** How much of the ingredient is needed. */
23
-
amount?: string;
24
-
/**
25
-
* The name of the ingredient. \
26
-
* Maximum string length: 3000 \
27
-
* Maximum grapheme length: 300
28
-
*/
29
-
name?: string;
30
-
}
31
-
interface Step {
32
-
[Brand.Type]?: "blue.recipes.feed.defs#step";
33
-
/**
34
-
* The instruction to provide to the user. \
35
-
* Maximum string length: 5000 \
36
-
* Maximum grapheme length: 300
37
-
*/
38
-
text: string;
39
-
}
40
-
}
41
-
42
-
/** Gets a recipe from the index by author DID and rkey. */
43
-
namespace BlueRecipesFeedGetRecipe {
44
-
interface Params {
45
-
did: string;
46
-
rkey: string;
47
-
}
48
-
type Input = undefined;
49
-
interface Output {
50
-
recipe: Result;
51
-
}
52
-
interface Result {
53
-
[Brand.Type]?: "blue.recipes.feed.getRecipe#result";
54
-
author: BlueRecipesFeedDefs.AuthorInfo;
55
-
ingredients: BlueRecipesFeedDefs.Ingredient[];
56
-
steps: BlueRecipesFeedDefs.Step[];
57
-
title: string;
58
-
description?: string;
59
-
imageUrl?: string;
60
-
serves?: number;
61
-
time?: number;
62
-
}
63
-
}
64
-
65
-
/** Gets recipes from the index. */
66
-
namespace BlueRecipesFeedGetRecipes {
67
-
interface Params {
68
-
cursor: string;
69
-
did?: string;
70
-
}
71
-
type Input = undefined;
72
-
interface Output {
73
-
recipes: Result[];
74
-
author?: BlueRecipesFeedDefs.AuthorInfo;
75
-
}
76
-
interface Result {
77
-
[Brand.Type]?: "blue.recipes.feed.getRecipes#result";
78
-
author: BlueRecipesFeedDefs.AuthorInfo;
79
-
ingredients: number;
80
-
rkey: string;
81
-
steps: number;
82
-
time: number;
83
-
title: string;
84
-
description?: string;
85
-
imageUrl?: string;
86
-
serves?: number;
87
-
type?: string;
88
-
}
89
-
}
90
-
91
-
namespace BlueRecipesFeedRecipe {
92
-
/** Record containing a Cookware recipe. */
93
-
interface Record {
94
-
$type: "blue.recipes.feed.recipe";
95
-
ingredients: BlueRecipesFeedDefs.Ingredient[];
96
-
steps: BlueRecipesFeedDefs.Step[];
97
-
/**
98
-
* The title of the recipe. \
99
-
* Maximum string length: 3000 \
100
-
* Maximum grapheme length: 300
101
-
*/
102
-
title: string;
103
-
/**
104
-
* The description of the recipe. \
105
-
* Maximum string length: 3000 \
106
-
* Maximum grapheme length: 300
107
-
*/
108
-
description?: string;
109
-
/** The recipe's cover image. */
110
-
image?: At.Blob;
111
-
/** The amount of people the recipe will make servings for. */
112
-
serves?: number;
113
-
/** The amount of time (in minutes) the recipe takes to complete. */
114
-
time?: number;
115
-
}
116
-
}
117
-
118
-
interface Records {
119
-
"blue.recipes.feed.recipe": BlueRecipesFeedRecipe.Record;
120
-
}
121
-
122
-
interface Queries {
123
-
"blue.recipes.feed.getRecipe": {
124
-
params: BlueRecipesFeedGetRecipe.Params;
125
-
output: BlueRecipesFeedGetRecipe.Output;
126
-
};
127
-
"blue.recipes.feed.getRecipes": {
128
-
params: BlueRecipesFeedGetRecipes.Params;
129
-
output: BlueRecipesFeedGetRecipes.Output;
130
-
};
131
-
}
132
-
133
-
interface Procedures {}
134
-
}
-14
libs/lexicons/src/defs.ts
-14
libs/lexicons/src/defs.ts
···
1
-
import { z } from 'zod';
2
-
3
-
export const IngredientObject = z.object({
4
-
amount: z.string().nullable(),
5
-
name: z.string().max(3000, 'Ingredient names must be under 3000 characters.'),
6
-
});
7
-
8
-
export type Ingredient = z.infer<typeof IngredientObject>;
9
-
10
-
export const StepObject = z.object({
11
-
text: z.string().max(5000, 'Recipe steps must be under 5000 characters.'),
12
-
});
13
-
14
-
export type Step = z.infer<typeof StepObject>;
-134
libs/lexicons/src/did.ts
-134
libs/lexicons/src/did.ts
···
1
-
import { z } from "zod";
2
-
3
-
type Brand<K, T> = K & { __brand: T };
4
-
export type DID = Brand<string, "DID">;
5
-
6
-
export function isDid(s: string): s is DID {
7
-
return s.startsWith("did:");
8
-
}
9
-
10
-
export function parseDid(s: string): DID | null {
11
-
if (!isDid(s)) {
12
-
return null;
13
-
}
14
-
return s;
15
-
}
16
-
17
-
export const getDidDoc = async (did: DID) => {
18
-
let url = `https://plc.directory/${did}`;
19
-
if (did.startsWith('did:web')) {
20
-
url = `https://${did.split(':')[2]}/.well-known/did.json`;
21
-
}
22
-
23
-
const response = await fetch(url);
24
-
25
-
return PlcDocument.parse(await response.json());
26
-
};
27
-
28
-
export const getPdsUrl = async (did: DID) => {
29
-
const plc = await getDidDoc(did);
30
-
31
-
return (
32
-
plc.service.find((s) => s.type === "AtprotoPersonalDataServer")
33
-
?.serviceEndpoint ?? null
34
-
);
35
-
};
36
-
37
-
const PlcDocument = z.object({
38
-
id: z.string(),
39
-
alsoKnownAs: z.array(z.string()),
40
-
service: z.array(
41
-
z.object({
42
-
id: z.string(),
43
-
type: z.string(),
44
-
serviceEndpoint: z.string(),
45
-
}),
46
-
),
47
-
});
48
-
49
-
const DnsQueryResponse = z.object({
50
-
Answer: z.array(
51
-
z.object({
52
-
name: z.string(),
53
-
type: z.number(),
54
-
TTL: z.number(),
55
-
data: z.string(),
56
-
}),
57
-
),
58
-
});
59
-
60
-
async function getAtprotoDidFromDns(handle: string) {
61
-
const url = new URL("https://cloudflare-dns.com/dns-query");
62
-
url.searchParams.set("type", "TXT");
63
-
url.searchParams.set("name", `_atproto.${handle}`);
64
-
65
-
const response = await fetch(url, {
66
-
headers: {
67
-
Accept: "application/dns-json",
68
-
},
69
-
});
70
-
71
-
const { Answer } = DnsQueryResponse.parse(await response.json());
72
-
// Answer[0].data is "\"did=...\"" (with quotes)
73
-
const val = Answer[0]?.data
74
-
? JSON.parse(Answer[0]?.data).split("did=")[1]
75
-
: null;
76
-
77
-
return val ? parseDid(val) : null;
78
-
}
79
-
80
-
const getAtprotoFromHttps = async (handle: string) => {
81
-
let res;
82
-
const timeoutSignal = AbortSignal.timeout(1500);
83
-
try {
84
-
res = await fetch(`https://${handle}/.well-known/atproto-did`, {
85
-
signal: timeoutSignal,
86
-
});
87
-
} catch (_e) {
88
-
// We're caching failures here, we should at some point invalidate the cache by listening to handle changes on the network
89
-
return null;
90
-
}
91
-
92
-
if (!res.ok) {
93
-
return null;
94
-
}
95
-
return parseDid((await res.text()).trim());
96
-
};
97
-
98
-
export const getVerifiedDid = async (handle: string) => {
99
-
const [dnsDid, httpDid] = await Promise.all([
100
-
getAtprotoDidFromDns(handle).catch((_) => {
101
-
return null;
102
-
}),
103
-
getAtprotoFromHttps(handle).catch(() => {
104
-
return null;
105
-
}),
106
-
]);
107
-
108
-
if (dnsDid && httpDid && dnsDid !== httpDid) {
109
-
return null;
110
-
}
111
-
112
-
const did = dnsDid ?? (httpDid ? parseDid(httpDid) : null);
113
-
if (!did) {
114
-
return null;
115
-
}
116
-
117
-
const plcDoc = await getDidDoc(did);
118
-
const plcHandle = plcDoc.alsoKnownAs
119
-
.find((handle) => handle.startsWith("at://"))
120
-
?.replace("at://", "");
121
-
122
-
if (!plcHandle) return null;
123
-
124
-
return plcHandle.toLowerCase() === handle.toLowerCase() ? did : null;
125
-
};
126
-
127
-
export const getDidFromHandleOrDid = async (handleOrDid: string) => {
128
-
const decodedHandleOrDid = decodeURIComponent(handleOrDid);
129
-
if (isDid(decodedHandleOrDid)) {
130
-
return decodedHandleOrDid;
131
-
}
132
-
133
-
return getVerifiedDid(decodedHandleOrDid);
134
-
};
-4
libs/lexicons/src/index.ts
-4
libs/lexicons/src/index.ts
-15
libs/lexicons/src/recipe.ts
-15
libs/lexicons/src/recipe.ts
···
1
-
import { z } from 'zod';
2
-
import { IngredientObject, StepObject } from './defs.js';
3
-
4
-
export const RecipeCollection = 'blue.recipes.feed.recipe' as const;
5
-
6
-
export const RecipeRecord = z.object({
7
-
title: z.string().max(3000, 'Recipe titles must be under 3000 characters.'),
8
-
description: z.string().max(3000, 'Recipe descriptions must be under 3000 characters.').nullable(),
9
-
time: z.number({ message: 'Time must be a number.' }),
10
-
serves: z.number({ message: 'Serves must be a number.' }),
11
-
ingredients: z.array(IngredientObject),
12
-
steps: z.array(StepObject),
13
-
});
14
-
15
-
export type Recipe = z.infer<typeof RecipeRecord>;
+8
libs/lexicons/tsconfig.build.json
+8
libs/lexicons/tsconfig.build.json
+5
-1
libs/lexicons/tsconfig.json
+5
-1
libs/lexicons/tsconfig.json
+13
-5
libs/tsconfig/base.json
+13
-5
libs/tsconfig/base.json
···
1
+
/* vim:ft=jsonc */
1
2
{
2
3
"$schema": "https://json.schemastore.org/tsconfig",
3
4
"display": "Default",
···
8
9
"incremental": false,
9
10
"isolatedModules": true,
10
11
"lib": ["es2022", "DOM", "DOM.Iterable"],
11
-
"module": "NodeNext",
12
-
"moduleDetection": "force",
13
-
"moduleResolution": "NodeNext",
14
-
"noUncheckedIndexedAccess": true,
12
+
"module": "nodenext",
13
+
"moduleResolution": "nodenext",
14
+
"verbatimModuleSyntax": true,
15
15
"resolveJsonModule": true,
16
16
"skipLibCheck": true,
17
17
"strict": true,
18
-
"target": "ES2022"
18
+
"target": "ES2022",
19
+
20
+
/* Rules */
21
+
"noUncheckedIndexedAccess": true,
22
+
"noUnusedLocals": true,
23
+
"noUnusedParameters": true,
24
+
"erasableSyntaxOnly": true,
25
+
"noFallthroughCasesInSwitch": true,
26
+
"noUncheckedSideEffectImports": true
19
27
}
20
28
}
+3
libs/tsconfig/package.json
+3
libs/tsconfig/package.json
+3
-3
libs/tsconfig/react.json
+3
-3
libs/tsconfig/react.json
···
1
+
/* vim:ft=jsonc */
1
2
{
2
3
"$schema": "https://json.schemastore.org/tsconfig",
3
-
"display": "Next.js",
4
4
"extends": "./base.json",
5
5
"compilerOptions": {
6
6
"module": "ESNext",
7
7
"moduleResolution": "Bundler",
8
8
"allowJs": true,
9
-
"jsx": "preserve",
10
-
"noEmit": true
9
+
"jsx": "react-jsx",
10
+
"noEmit": true,
11
11
}
12
12
}
+20
-2
package.json
+20
-2
package.json
···
1
1
{
2
+
"name": "@cookware/monorepo",
2
3
"private": true,
3
4
"packageManager": "bun@1.3.3",
4
5
"devDependencies": {
5
-
"turbo": "^2.3.3"
6
+
"@tanstack/react-router-devtools": "^1.140.0",
7
+
"@tanstack/router-plugin": "^1.140.0",
8
+
"turbo": "^2.3.3",
9
+
"typescript": "^5.9.3"
6
10
},
7
11
"scripts": {
8
12
"dev": "turbo dev",
···
11
15
"db:migrate": "turbo db:migrate"
12
16
},
13
17
"workspaces": {
14
-
"packages": ["apps/**", "libs/**"]
18
+
"packages": ["apps/**", "libs/**"],
19
+
"catalog": {
20
+
"@types/bun": "^1.3.3",
21
+
"@atcute/atproto": "^3.1.9",
22
+
"@atcute/bluesky": "^3.2.11",
23
+
"@atcute/client": "^4.0.5",
24
+
"@atcute/identity": "^1.1.3",
25
+
"@atcute/identity-resolver": "^1.1.4",
26
+
"@atcute/lexicons": "^1.2.5",
27
+
"drizzle-orm": "^0.44.7"
28
+
}
29
+
},
30
+
"dependencies": {
31
+
"@atcute/oauth-browser-client": "^2.0.2",
32
+
"@tanstack/react-router": "^1.140.0"
15
33
}
16
34
}