@vibecodeapp/cloud-studio 0.1.3 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/client/index.html
CHANGED
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
mq.addEventListener('change', update);
|
|
16
16
|
})();
|
|
17
17
|
</script>
|
|
18
|
-
<script type="module" crossorigin src="/assets/index-
|
|
19
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
18
|
+
<script type="module" crossorigin src="/assets/index-uiOGXfRY.js"></script>
|
|
19
|
+
<link rel="stylesheet" crossorigin href="/assets/index-Dm0NurdA.css">
|
|
20
20
|
</head>
|
|
21
21
|
<body>
|
|
22
22
|
<div id="root"></div>
|
package/dist/server/index.js
CHANGED
|
@@ -2358,7 +2358,6 @@ var cors = (options) => {
|
|
|
2358
2358
|
// server/db.ts
|
|
2359
2359
|
import { pathToFileURL } from "url";
|
|
2360
2360
|
import { join as join2 } from "path";
|
|
2361
|
-
var prismaClient = null;
|
|
2362
2361
|
var cachedSchema = null;
|
|
2363
2362
|
var PrismaClientConstructor = null;
|
|
2364
2363
|
async function loadPrismaClient() {
|
|
@@ -2379,18 +2378,14 @@ async function loadPrismaClient() {
|
|
|
2379
2378
|
);
|
|
2380
2379
|
}
|
|
2381
2380
|
}
|
|
2382
|
-
async function
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
} catch (error) {
|
|
2390
|
-
throw error;
|
|
2391
|
-
}
|
|
2381
|
+
async function withPrisma(fn) {
|
|
2382
|
+
const ClientConstructor = await loadPrismaClient();
|
|
2383
|
+
const prisma = new ClientConstructor({ log: ["error"] });
|
|
2384
|
+
try {
|
|
2385
|
+
return await fn(prisma);
|
|
2386
|
+
} finally {
|
|
2387
|
+
await prisma.$disconnect();
|
|
2392
2388
|
}
|
|
2393
|
-
return prismaClient;
|
|
2394
2389
|
}
|
|
2395
2390
|
async function getDatabaseSchema() {
|
|
2396
2391
|
await loadPrismaClient();
|
|
@@ -2399,29 +2394,18 @@ async function getDatabaseSchema() {
|
|
|
2399
2394
|
}
|
|
2400
2395
|
return cachedSchema;
|
|
2401
2396
|
}
|
|
2402
|
-
async function
|
|
2403
|
-
const prisma = await getPrismaClient();
|
|
2397
|
+
async function withModel(tableName, fn) {
|
|
2404
2398
|
const schema = await getDatabaseSchema();
|
|
2405
2399
|
const modelExists = schema.models.some((m) => m.name === tableName);
|
|
2406
2400
|
if (!modelExists) {
|
|
2407
2401
|
throw new Error(`Table '${tableName}' not found`);
|
|
2408
2402
|
}
|
|
2409
2403
|
const modelName = tableName.charAt(0).toLowerCase() + tableName.slice(1);
|
|
2410
|
-
return prisma
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
await prismaClient.$disconnect();
|
|
2415
|
-
}
|
|
2404
|
+
return withPrisma(async (prisma) => {
|
|
2405
|
+
const model = prisma[modelName];
|
|
2406
|
+
return fn(model, prisma);
|
|
2407
|
+
});
|
|
2416
2408
|
}
|
|
2417
|
-
process.on("SIGINT", async () => {
|
|
2418
|
-
await disconnectPrisma();
|
|
2419
|
-
process.exit(0);
|
|
2420
|
-
});
|
|
2421
|
-
process.on("SIGTERM", async () => {
|
|
2422
|
-
await disconnectPrisma();
|
|
2423
|
-
process.exit(0);
|
|
2424
|
-
});
|
|
2425
2409
|
|
|
2426
2410
|
// server/lib/errors.ts
|
|
2427
2411
|
function getCleanMessage(message) {
|
|
@@ -6608,49 +6592,50 @@ tableRoutes.get("/:tableName", async (c) => {
|
|
|
6608
6592
|
const tableName = c.req.param("tableName");
|
|
6609
6593
|
const query = listQuerySchema.parse(c.req.query());
|
|
6610
6594
|
try {
|
|
6611
|
-
|
|
6612
|
-
|
|
6613
|
-
|
|
6614
|
-
|
|
6615
|
-
|
|
6616
|
-
|
|
6617
|
-
const schema = await getDatabaseSchema();
|
|
6618
|
-
const modelDef = schema.models.find((m) => m.name === tableName);
|
|
6619
|
-
const field = modelDef?.fields.find((f) => f.name === query.orderBy);
|
|
6620
|
-
if (field && field.kind !== "object") {
|
|
6621
|
-
queryOptions.orderBy = {
|
|
6622
|
-
[query.orderBy]: query.orderDir
|
|
6623
|
-
};
|
|
6624
|
-
}
|
|
6625
|
-
}
|
|
6626
|
-
if (query.filters) {
|
|
6627
|
-
try {
|
|
6595
|
+
return await withModel(tableName, async (model) => {
|
|
6596
|
+
const queryOptions = {
|
|
6597
|
+
skip: query.offset,
|
|
6598
|
+
take: query.limit
|
|
6599
|
+
};
|
|
6600
|
+
if (query.orderBy) {
|
|
6628
6601
|
const schema = await getDatabaseSchema();
|
|
6629
6602
|
const modelDef = schema.models.find((m) => m.name === tableName);
|
|
6630
|
-
|
|
6631
|
-
|
|
6632
|
-
|
|
6633
|
-
|
|
6634
|
-
|
|
6635
|
-
}
|
|
6603
|
+
const field = modelDef?.fields.find((f) => f.name === query.orderBy);
|
|
6604
|
+
if (field && field.kind !== "object") {
|
|
6605
|
+
queryOptions.orderBy = {
|
|
6606
|
+
[query.orderBy]: query.orderDir
|
|
6607
|
+
};
|
|
6636
6608
|
}
|
|
6637
|
-
} catch {
|
|
6638
6609
|
}
|
|
6639
|
-
|
|
6640
|
-
|
|
6641
|
-
|
|
6642
|
-
|
|
6643
|
-
|
|
6644
|
-
|
|
6645
|
-
|
|
6646
|
-
|
|
6647
|
-
|
|
6648
|
-
|
|
6649
|
-
|
|
6650
|
-
|
|
6610
|
+
if (query.filters) {
|
|
6611
|
+
try {
|
|
6612
|
+
const schema = await getDatabaseSchema();
|
|
6613
|
+
const modelDef = schema.models.find((m) => m.name === tableName);
|
|
6614
|
+
if (modelDef) {
|
|
6615
|
+
const filters = JSON.parse(query.filters);
|
|
6616
|
+
const filterWhere = buildFilterWhereClause(filters, modelDef);
|
|
6617
|
+
if (filterWhere) {
|
|
6618
|
+
queryOptions.where = filterWhere;
|
|
6619
|
+
}
|
|
6620
|
+
}
|
|
6621
|
+
} catch {
|
|
6622
|
+
}
|
|
6651
6623
|
}
|
|
6652
|
-
|
|
6653
|
-
|
|
6624
|
+
const [rows, total] = await Promise.all([
|
|
6625
|
+
model.findMany(queryOptions),
|
|
6626
|
+
model.count(queryOptions.where ? { where: queryOptions.where } : {})
|
|
6627
|
+
]);
|
|
6628
|
+
const response = {
|
|
6629
|
+
success: true,
|
|
6630
|
+
data: {
|
|
6631
|
+
rows,
|
|
6632
|
+
total,
|
|
6633
|
+
offset: query.offset,
|
|
6634
|
+
limit: query.limit
|
|
6635
|
+
}
|
|
6636
|
+
};
|
|
6637
|
+
return c.json(response);
|
|
6638
|
+
});
|
|
6654
6639
|
} catch (error) {
|
|
6655
6640
|
return handlePrismaError(error, c);
|
|
6656
6641
|
}
|
|
@@ -6659,26 +6644,27 @@ tableRoutes.get("/:tableName/:id", async (c) => {
|
|
|
6659
6644
|
const tableName = c.req.param("tableName");
|
|
6660
6645
|
const rawId = c.req.param("id");
|
|
6661
6646
|
try {
|
|
6662
|
-
const model = await getModelDelegate(tableName);
|
|
6663
6647
|
const id = await convertIdParameter(tableName, rawId);
|
|
6664
|
-
|
|
6665
|
-
|
|
6648
|
+
return await withModel(tableName, async (model) => {
|
|
6649
|
+
const record = await model.findUnique({
|
|
6650
|
+
where: { id }
|
|
6651
|
+
});
|
|
6652
|
+
if (!record) {
|
|
6653
|
+
return c.json(
|
|
6654
|
+
{
|
|
6655
|
+
success: false,
|
|
6656
|
+
error: "Record not found",
|
|
6657
|
+
code: "NOT_FOUND"
|
|
6658
|
+
},
|
|
6659
|
+
404
|
|
6660
|
+
);
|
|
6661
|
+
}
|
|
6662
|
+
const response = {
|
|
6663
|
+
success: true,
|
|
6664
|
+
data: record
|
|
6665
|
+
};
|
|
6666
|
+
return c.json(response);
|
|
6666
6667
|
});
|
|
6667
|
-
if (!record) {
|
|
6668
|
-
return c.json(
|
|
6669
|
-
{
|
|
6670
|
-
success: false,
|
|
6671
|
-
error: "Record not found",
|
|
6672
|
-
code: "NOT_FOUND"
|
|
6673
|
-
},
|
|
6674
|
-
404
|
|
6675
|
-
);
|
|
6676
|
-
}
|
|
6677
|
-
const response = {
|
|
6678
|
-
success: true,
|
|
6679
|
-
data: record
|
|
6680
|
-
};
|
|
6681
|
-
return c.json(response);
|
|
6682
6668
|
} catch (error) {
|
|
6683
6669
|
return handlePrismaError(error, c);
|
|
6684
6670
|
}
|
|
@@ -6687,16 +6673,17 @@ tableRoutes.post("/:tableName", async (c) => {
|
|
|
6687
6673
|
const tableName = c.req.param("tableName");
|
|
6688
6674
|
try {
|
|
6689
6675
|
const body = await c.req.json();
|
|
6690
|
-
const model = await getModelDelegate(tableName);
|
|
6691
6676
|
const safeData = await filterEditableFields(tableName, body);
|
|
6692
|
-
|
|
6693
|
-
|
|
6677
|
+
return await withModel(tableName, async (model) => {
|
|
6678
|
+
const record = await model.create({
|
|
6679
|
+
data: safeData
|
|
6680
|
+
});
|
|
6681
|
+
const response = {
|
|
6682
|
+
success: true,
|
|
6683
|
+
data: record
|
|
6684
|
+
};
|
|
6685
|
+
return c.json(response, 201);
|
|
6694
6686
|
});
|
|
6695
|
-
const response = {
|
|
6696
|
-
success: true,
|
|
6697
|
-
data: record
|
|
6698
|
-
};
|
|
6699
|
-
return c.json(response, 201);
|
|
6700
6687
|
} catch (error) {
|
|
6701
6688
|
return handlePrismaError(error, c);
|
|
6702
6689
|
}
|
|
@@ -6706,18 +6693,19 @@ tableRoutes.patch("/:tableName/:id", async (c) => {
|
|
|
6706
6693
|
const rawId = c.req.param("id");
|
|
6707
6694
|
try {
|
|
6708
6695
|
const body = await c.req.json();
|
|
6709
|
-
const model = await getModelDelegate(tableName);
|
|
6710
6696
|
const id = await convertIdParameter(tableName, rawId);
|
|
6711
6697
|
const safeData = await filterEditableFields(tableName, body);
|
|
6712
|
-
|
|
6713
|
-
|
|
6714
|
-
|
|
6698
|
+
return await withModel(tableName, async (model) => {
|
|
6699
|
+
const record = await model.update({
|
|
6700
|
+
where: { id },
|
|
6701
|
+
data: safeData
|
|
6702
|
+
});
|
|
6703
|
+
const response = {
|
|
6704
|
+
success: true,
|
|
6705
|
+
data: record
|
|
6706
|
+
};
|
|
6707
|
+
return c.json(response);
|
|
6715
6708
|
});
|
|
6716
|
-
const response = {
|
|
6717
|
-
success: true,
|
|
6718
|
-
data: record
|
|
6719
|
-
};
|
|
6720
|
-
return c.json(response);
|
|
6721
6709
|
} catch (error) {
|
|
6722
6710
|
return handlePrismaError(error, c);
|
|
6723
6711
|
}
|
|
@@ -6726,16 +6714,17 @@ tableRoutes.delete("/:tableName/:id", async (c) => {
|
|
|
6726
6714
|
const tableName = c.req.param("tableName");
|
|
6727
6715
|
const rawId = c.req.param("id");
|
|
6728
6716
|
try {
|
|
6729
|
-
const model = await getModelDelegate(tableName);
|
|
6730
6717
|
const id = await convertIdParameter(tableName, rawId);
|
|
6731
|
-
await model
|
|
6732
|
-
|
|
6718
|
+
return await withModel(tableName, async (model) => {
|
|
6719
|
+
await model.delete({
|
|
6720
|
+
where: { id }
|
|
6721
|
+
});
|
|
6722
|
+
const response = {
|
|
6723
|
+
success: true,
|
|
6724
|
+
data: { message: "Record deleted successfully" }
|
|
6725
|
+
};
|
|
6726
|
+
return c.json(response);
|
|
6733
6727
|
});
|
|
6734
|
-
const response = {
|
|
6735
|
-
success: true,
|
|
6736
|
-
data: { message: "Record deleted successfully" }
|
|
6737
|
-
};
|
|
6738
|
-
return c.json(response);
|
|
6739
6728
|
} catch (error) {
|
|
6740
6729
|
return handlePrismaError(error, c);
|
|
6741
6730
|
}
|
|
@@ -6778,7 +6767,9 @@ app.get("/health", (c) => {
|
|
|
6778
6767
|
app.use("/*", serveStatic({ root: clientPath }));
|
|
6779
6768
|
console.log(`Cloud Studio starting on http://${HOSTNAME}:${PORT}`);
|
|
6780
6769
|
try {
|
|
6781
|
-
await
|
|
6770
|
+
await withPrisma(async (prisma) => {
|
|
6771
|
+
await prisma.$queryRaw`SELECT 1`;
|
|
6772
|
+
});
|
|
6782
6773
|
console.log("Prisma Client connected");
|
|
6783
6774
|
} catch (error) {
|
|
6784
6775
|
console.error("Failed to connect to Prisma Client:", error);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibecodeapp/cloud-studio",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "Lightweight database UI for SQLite with Prisma",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/server/index.js",
|
|
@@ -47,8 +47,11 @@
|
|
|
47
47
|
"@types/react": "^18.3.0",
|
|
48
48
|
"@types/react-dom": "^18.3.0",
|
|
49
49
|
"@vitejs/plugin-react": "^4.3.4",
|
|
50
|
+
"autoprefixer": "^10.4.22",
|
|
50
51
|
"esbuild": "^0.19.12",
|
|
51
52
|
"npm-run-all": "^4.1.5",
|
|
53
|
+
"postcss": "8.4.49",
|
|
54
|
+
"tailwindcss": "3.4.17",
|
|
52
55
|
"tsx": "^4.19.2",
|
|
53
56
|
"typescript": "^5.7.2",
|
|
54
57
|
"vite": "^5.4.11"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}:root{--background: 0 0% 100%;--foreground: 222.2 84% 4.9%;--card: 0 0% 100%;--card-foreground: 222.2 84% 4.9%;--popover: 0 0% 100%;--popover-foreground: 222.2 84% 4.9%;--primary: 222.2 47.4% 11.2%;--primary-foreground: 210 40% 98%;--secondary: 210 40% 96.1%;--secondary-foreground: 222.2 47.4% 11.2%;--muted: 210 40% 96.1%;--muted-foreground: 215.4 16.3% 46.9%;--accent: 210 40% 96.1%;--accent-foreground: 222.2 47.4% 11.2%;--destructive: 0 84.2% 60.2%;--destructive-foreground: 210 40% 98%;--border: 214.3 31.8% 91.4%;--input: 214.3 31.8% 91.4%;--ring: 222.2 84% 4.9%;--radius: .5rem;--text-primary: 0 0% 0%;--text-secondary: 0 0% 0% / .6;--text-tertiary: 0 0% 0% / .4;--bg-secondary: 0 0% 0% / .05;--border-tertiary: 0 0% 0% / .05;--button-primary: 0 0% 0% / .05;--button-disabled: 0 0% 0% / .025;--kiwi-500: 164 66% 48%;--kiwi-600: 160 76% 39%;--kiwi-800: 163 66% 22%;--blueberry-500: 223 100% 53%;--blackberry-1000: 0 0% 0%;--coconut-1000: 0 0% 100%;--text-disabled: 0 0% 0% / .2;--icon-primary: 0 0% 0%;--icon-secondary: 0 0% 0% / .6;--icon-tertiary: 0 0% 0% / .4;--shadow-color: 0 0% 0%}.dark{--background: 0 0% 5%;--foreground: 210 40% 98%;--card: 222.2 84% 4.9%;--card-foreground: 210 40% 98%;--popover: 222.2 84% 4.9%;--popover-foreground: 210 40% 98%;--primary: 210 40% 98%;--primary-foreground: 222.2 47.4% 11.2%;--secondary: 217.2 32.6% 17.5%;--secondary-foreground: 210 40% 98%;--muted: 217.2 32.6% 17.5%;--muted-foreground: 215 20.2% 65.1%;--accent: 217.2 32.6% 17.5%;--accent-foreground: 210 40% 98%;--destructive: 0 62.8% 30.6%;--destructive-foreground: 210 40% 98%;--border: 217.2 32.6% 17.5%;--input: 217.2 32.6% 17.5%;--ring: 212.7 26.8% 83.9%;--text-primary: 0 0% 100%;--text-secondary: 0 0% 100% / .7;--text-tertiary: 0 0% 100% / .5;--bg-secondary: 0 0% 100% / .05;--border-tertiary: 0 0% 100% / .1;--button-primary: 0 0% 100% / .1;--button-disabled: 0 0% 100% / .05;--kiwi-500: 164 69% 51%;--kiwi-600: 162 67% 45%;--kiwi-800: 161 67% 29%;--blueberry-500: 220 99% 53%;--blackberry-1000: 0 0% 100%;--coconut-1000: 0 0% 0%;--text-disabled: 0 0% 100% / .2;--icon-primary: 0 0% 100%;--icon-secondary: 0 0% 100% / .7;--icon-tertiary: 0 0% 100% / .5;--shadow-color: 0 0% 100%}*{border-color:hsl(var(--border))}body{background-color:hsl(var(--background));color:hsl(var(--foreground))}.visible{visibility:visible}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.bottom-0{bottom:0}.left-0{left:0}.right-0{right:0}.top-0{top:0}.z-10{z-index:10}.z-50{z-index:50}.mx-auto{margin-left:auto;margin-right:auto}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.ml-0\.5{margin-left:.125rem}.mt-4{margin-top:1rem}.block{display:block}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-12{height:3rem}.h-14{height:3.5rem}.h-3{height:.75rem}.h-4{height:1rem}.h-44{height:11rem}.h-48{height:12rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-64{height:16rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-\[80vh\]{max-height:80vh}.w-10{width:2.5rem}.w-12{width:3rem}.w-14{width:3.5rem}.w-2\.5{width:.625rem}.w-28{width:7rem}.w-3{width:.75rem}.w-4{width:1rem}.w-40{width:10rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-64{width:16rem}.w-7{width:1.75rem}.w-8{width:2rem}.w-9{width:2.25rem}.w-full{width:100%}.min-w-20{min-width:5rem}.min-w-24{min-width:6rem}.min-w-32{min-width:8rem}.min-w-\[100px\]{min-width:100px}.min-w-\[160px\]{min-width:160px}.min-w-max{min-width:-moz-max-content;min-width:max-content}.max-w-40{max-width:10rem}.max-w-md{max-width:28rem}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.resize-none{resize:none}.scroll-mt-14{scroll-margin-top:3.5rem}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-stretch{align-items:stretch}.justify-start{justify-content:flex-start}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-6{gap:1.5rem}.space-y-0>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(0px * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(0px * var(--tw-space-y-reverse))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.rounded{border-radius:.25rem}.rounded-\[20px\]{border-radius:20px}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-sm{border-radius:calc(var(--radius) - 4px)}.rounded-xl{border-radius:.75rem}.rounded-t-\[20px\]{border-top-left-radius:20px;border-top-right-radius:20px}.rounded-bl-lg{border-bottom-left-radius:var(--radius)}.rounded-bl-xl{border-bottom-left-radius:.75rem}.rounded-br-xl{border-bottom-right-radius:.75rem}.rounded-tl-lg{border-top-left-radius:var(--radius)}.rounded-tl-xl{border-top-left-radius:.75rem}.rounded-tr-xl{border-top-right-radius:.75rem}.border{border-width:1px}.border-y{border-top-width:1px;border-bottom-width:1px}.border-b{border-bottom-width:1px}.border-b-2{border-bottom-width:2px}.border-l{border-left-width:1px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-border-tertiary{border-color:hsl(var(--border-tertiary))}.border-kiwi-800{border-color:hsl(var(--kiwi-800))}.border-transparent{border-color:transparent}.\!border-b-destructive\/20{border-bottom-color:hsl(var(--destructive) / .2)!important}.\!border-b-kiwi-600\/20{border-bottom-color:hsl(var(--kiwi-600) / .2)!important}.\!border-l-destructive\/20{border-left-color:hsl(var(--destructive) / .2)!important}.\!border-l-kiwi-600\/20{border-left-color:hsl(var(--kiwi-600) / .2)!important}.\!border-t-destructive\/20{border-top-color:hsl(var(--destructive) / .2)!important}.\!border-t-kiwi-600\/20{border-top-color:hsl(var(--kiwi-600) / .2)!important}.border-b-border-tertiary{border-bottom-color:hsl(var(--border-tertiary))}.border-b-transparent{border-bottom-color:transparent}.border-l-border-tertiary{border-left-color:hsl(var(--border-tertiary))}.border-r-border-tertiary{border-right-color:hsl(var(--border-tertiary))}.border-t-border-tertiary{border-top-color:hsl(var(--border-tertiary))}.border-t-transparent{border-top-color:transparent}.bg-background{background-color:hsl(var(--background))}.bg-bg-secondary{background-color:hsl(var(--bg-secondary))}.bg-blackberry-1000{background-color:hsl(var(--blackberry-1000))}.bg-border-tertiary{background-color:hsl(var(--border-tertiary))}.bg-button-disabled{background-color:hsl(var(--button-disabled))}.bg-button-primary{background-color:hsl(var(--button-primary))}.bg-destructive{background-color:hsl(var(--destructive))}.bg-destructive\/10{background-color:hsl(var(--destructive) / .1)}.bg-kiwi-600{background-color:hsl(var(--kiwi-600))}.bg-kiwi-600\/10{background-color:hsl(var(--kiwi-600) / .1)}.bg-kiwi-800{background-color:hsl(var(--kiwi-800))}.bg-transparent{background-color:transparent}.stroke-2{stroke-width:2}.p-1{padding:.25rem}.p-1\.5{padding:.375rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.pb-1{padding-bottom:.25rem}.pb-16{padding-bottom:4rem}.pb-32{padding-bottom:8rem}.pb-44{padding-bottom:11rem}.pl-1{padding-left:.25rem}.pl-2{padding-left:.5rem}.pl-2\.5{padding-left:.625rem}.pl-3{padding-left:.75rem}.pr-1{padding-right:.25rem}.pr-1\.5{padding-right:.375rem}.pr-2{padding-right:.5rem}.pr-4{padding-right:1rem}.pt-5{padding-top:1.25rem}.text-left{text-align:left}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-base{font-size:1rem;line-height:1.5rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-extrabold{font-weight:800}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.tracking-tight{letter-spacing:-.025em}.text-blackberry-1000{color:hsl(var(--blackberry-1000))}.text-blueberry-500{color:hsl(var(--blueberry-500))}.text-coconut-1000{color:hsl(var(--coconut-1000))}.text-destructive{color:hsl(var(--destructive))}.text-icon-primary{color:hsl(var(--icon-primary))}.text-icon-secondary{color:hsl(var(--icon-secondary))}.text-icon-tertiary{color:hsl(var(--icon-tertiary))}.text-kiwi-500{color:hsl(var(--kiwi-500))}.text-kiwi-600{color:hsl(var(--kiwi-600))}.text-kiwi-800{color:hsl(var(--kiwi-800))}.text-muted-foreground{color:hsl(var(--muted-foreground))}.text-primary{color:hsl(var(--primary))}.text-text-disabled{color:hsl(var(--text-disabled))}.text-text-primary{color:hsl(var(--text-primary))}.text-text-secondary{color:hsl(var(--text-secondary))}.text-text-tertiary{color:hsl(var(--text-tertiary))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-white\/90{color:#ffffffe6}.opacity-50{opacity:.5}.shadow-\[0px_0px_20px_0px_hsl\(var\(--shadow-color\)\/0\.05\)\]{--tw-shadow: 0px 0px 20px 0px hsl(var(--shadow-color)/.05);--tw-shadow-colored: 0px 0px 20px 0px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.outline-none{outline:2px solid transparent;outline-offset:2px}.ring-1{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-primary\/20{--tw-ring-color: hsl(var(--primary) / .2)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.scrollbar-hide{-ms-overflow-style:none;scrollbar-width:none}.scrollbar-hide::-webkit-scrollbar{display:none}.\[-ms-overflow-style\:none\]{-ms-overflow-style:none}.\[scrollbar-width\:none\]{scrollbar-width:none}*{-webkit-tap-highlight-color:transparent;touch-action:manipulation}.placeholder\:text-text-tertiary::-moz-placeholder{color:hsl(var(--text-tertiary))}.placeholder\:text-text-tertiary::placeholder{color:hsl(var(--text-tertiary))}.hover\:bg-bg-secondary:hover{background-color:hsl(var(--bg-secondary))}.hover\:bg-bg-secondary\/50:hover{background-color:hsl(var(--bg-secondary) / .5)}.hover\:bg-button-primary:hover{background-color:hsl(var(--button-primary))}.hover\:text-icon-primary:hover{color:hsl(var(--icon-primary))}.hover\:text-text-primary:hover{color:hsl(var(--text-primary))}.hover\:opacity-100:hover{opacity:1}.hover\:opacity-80:hover{opacity:.8}.hover\:opacity-90:hover{opacity:.9}.focus\:border-primary:focus{border-color:hsl(var(--primary))}.focus\:outline:focus{outline-style:solid}.focus\:outline-1:focus{outline-width:1px}.focus\:outline-2:focus{outline-width:2px}.focus\:outline-offset-2:focus{outline-offset:2px}.focus\:outline-border-tertiary:focus{outline-color:hsl(var(--border-tertiary))}.focus\:outline-ring:focus{outline-color:hsl(var(--ring))}.active\:opacity-100:active{opacity:1}.active\:opacity-80:active{opacity:.8}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.data-\[highlighted\]\:bg-bg-secondary[data-highlighted]{background-color:hsl(var(--bg-secondary))}@media (min-width: 640px){.sm\:block{display:block}.sm\:hidden{display:none}.sm\:w-auto{width:auto}.sm\:grid-cols-\[repeat\(auto-fit\,minmax\(380px\,1fr\)\)\]{grid-template-columns:repeat(auto-fit,minmax(380px,1fr))}.sm\:flex-row{flex-direction:row}.sm\:border-l{border-left-width:1px}}.\[\&\:\:-webkit-scrollbar\]\:hidden::-webkit-scrollbar{display:none}
|