@gallop.software/studio 0.1.92 → 0.1.94

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.
@@ -7,8 +7,8 @@ import {
7
7
  } from "./chunk-HXE6XCG2.mjs";
8
8
 
9
9
  // src/components/StudioUI.tsx
10
- import { useEffect as useEffect4, useCallback as useCallback3, useState as useState9 } from "react";
11
- import { css as css10 } from "@emotion/react";
10
+ import { useEffect as useEffect5, useCallback as useCallback5, useState as useState10 } from "react";
11
+ import { css as css11 } from "@emotion/react";
12
12
 
13
13
  // src/components/StudioContext.tsx
14
14
  import { createContext, useContext } from "react";
@@ -70,8 +70,8 @@ function useStudio() {
70
70
  }
71
71
 
72
72
  // src/components/StudioToolbar.tsx
73
- import { useCallback, useEffect as useEffect2, useRef, useState as useState3 } from "react";
74
- import { css as css4, keyframes as keyframes3 } from "@emotion/react";
73
+ import { useCallback as useCallback2, useEffect as useEffect2, useRef as useRef2, useState as useState4 } from "react";
74
+ import { css as css5, keyframes as keyframes4 } from "@emotion/react";
75
75
 
76
76
  // src/components/StudioModal.tsx
77
77
  import React from "react";
@@ -355,16 +355,30 @@ function ProgressModal({
355
355
  " before stopping."
356
356
  ] }) : isComplete ? /* @__PURE__ */ jsxs(Fragment, { children: [
357
357
  /* @__PURE__ */ jsxs("p", { css: styles.message, children: [
358
- "Processed ",
359
- progress.processed,
360
- " new image",
361
- progress.processed !== 1 ? "s" : "",
362
- ".",
363
- progress.alreadyProcessed !== void 0 && progress.alreadyProcessed > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
364
- " ",
365
- progress.alreadyProcessed,
366
- " already processed."
367
- ] }) : null,
358
+ progress.isScan ? /* @__PURE__ */ jsxs(Fragment, { children: [
359
+ progress.alreadyProcessed !== void 0 && progress.alreadyProcessed > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
360
+ progress.alreadyProcessed,
361
+ " image",
362
+ progress.alreadyProcessed !== 1 ? "s" : "",
363
+ " already exist. "
364
+ ] }) : null,
365
+ "Scanned ",
366
+ progress.processed,
367
+ " new image",
368
+ progress.processed !== 1 ? "s" : "",
369
+ "."
370
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
371
+ "Processed ",
372
+ progress.processed,
373
+ " new image",
374
+ progress.processed !== 1 ? "s" : "",
375
+ ".",
376
+ progress.alreadyProcessed !== void 0 && progress.alreadyProcessed > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
377
+ " ",
378
+ progress.alreadyProcessed,
379
+ " already processed."
380
+ ] }) : null
381
+ ] }),
368
382
  progress.orphansRemoved !== void 0 && progress.orphansRemoved > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
369
383
  " Removed ",
370
384
  progress.orphansRemoved,
@@ -1093,14 +1107,386 @@ function R2SetupModal({ isOpen, onClose }) {
1093
1107
  ] }) });
1094
1108
  }
1095
1109
 
1096
- // src/components/StudioToolbar.tsx
1110
+ // src/components/AddNewModal.tsx
1111
+ import { useState as useState3, useRef, useCallback } from "react";
1112
+ import { css as css4, keyframes as keyframes3 } from "@emotion/react";
1097
1113
  import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs4 } from "@emotion/react/jsx-runtime";
1114
+ var fadeIn3 = keyframes3`
1115
+ from { opacity: 0; }
1116
+ to { opacity: 1; }
1117
+ `;
1118
+ var slideIn3 = keyframes3`
1119
+ from {
1120
+ opacity: 0;
1121
+ transform: translateY(-8px) scale(0.98);
1122
+ }
1123
+ to {
1124
+ opacity: 1;
1125
+ transform: translateY(0) scale(1);
1126
+ }
1127
+ `;
1128
+ var styles4 = {
1129
+ overlay: css4`
1130
+ position: fixed;
1131
+ inset: 0;
1132
+ background-color: rgba(26, 31, 54, 0.4);
1133
+ backdrop-filter: blur(4px);
1134
+ display: flex;
1135
+ align-items: center;
1136
+ justify-content: center;
1137
+ z-index: 10000;
1138
+ animation: ${fadeIn3} 0.15s ease-out;
1139
+ font-family: ${fontStack};
1140
+ `,
1141
+ modal: css4`
1142
+ ${baseReset}
1143
+ background-color: ${colors.surface};
1144
+ border-radius: 12px;
1145
+ box-shadow: 0 30px 60px -12px rgba(50, 50, 93, 0.25), 0 18px 36px -18px rgba(0, 0, 0, 0.3);
1146
+ max-width: 520px;
1147
+ width: 90%;
1148
+ animation: ${slideIn3} 0.2s ease-out;
1149
+ overflow: hidden;
1150
+ `,
1151
+ header: css4`
1152
+ padding: 24px 24px 0;
1153
+ `,
1154
+ title: css4`
1155
+ font-size: ${fontSize.lg};
1156
+ font-weight: 600;
1157
+ color: ${colors.text};
1158
+ margin: 0;
1159
+ letter-spacing: -0.02em;
1160
+ `,
1161
+ tabs: css4`
1162
+ display: flex;
1163
+ gap: 0;
1164
+ margin-top: 16px;
1165
+ border-bottom: 1px solid ${colors.border};
1166
+ `,
1167
+ tab: css4`
1168
+ padding: 12px 20px;
1169
+ font-size: ${fontSize.base};
1170
+ font-weight: 500;
1171
+ color: ${colors.textSecondary};
1172
+ background: none;
1173
+ border: none;
1174
+ cursor: pointer;
1175
+ position: relative;
1176
+ transition: color 0.15s;
1177
+
1178
+ &:hover {
1179
+ color: ${colors.text};
1180
+ }
1181
+ `,
1182
+ tabActive: css4`
1183
+ color: ${colors.primary};
1184
+
1185
+ &::after {
1186
+ content: '';
1187
+ position: absolute;
1188
+ bottom: -1px;
1189
+ left: 0;
1190
+ right: 0;
1191
+ height: 2px;
1192
+ background-color: ${colors.primary};
1193
+ }
1194
+ `,
1195
+ body: css4`
1196
+ padding: 24px;
1197
+ min-height: 200px;
1198
+ `,
1199
+ dropzone: css4`
1200
+ border: 2px dashed ${colors.border};
1201
+ border-radius: 8px;
1202
+ padding: 40px 24px;
1203
+ text-align: center;
1204
+ cursor: pointer;
1205
+ transition: all 0.15s;
1206
+
1207
+ &:hover {
1208
+ border-color: ${colors.primary};
1209
+ background-color: ${colors.primaryLight};
1210
+ }
1211
+ `,
1212
+ dropzoneActive: css4`
1213
+ border-color: ${colors.primary};
1214
+ background-color: ${colors.primaryLight};
1215
+ `,
1216
+ dropzoneIcon: css4`
1217
+ width: 48px;
1218
+ height: 48px;
1219
+ margin: 0 auto 16px;
1220
+ color: ${colors.textMuted};
1221
+ `,
1222
+ dropzoneText: css4`
1223
+ font-size: ${fontSize.base};
1224
+ color: ${colors.text};
1225
+ margin: 0 0 4px;
1226
+ `,
1227
+ dropzoneHint: css4`
1228
+ font-size: ${fontSize.sm};
1229
+ color: ${colors.textSecondary};
1230
+ margin: 0;
1231
+ `,
1232
+ textarea: css4`
1233
+ width: 100%;
1234
+ min-height: 150px;
1235
+ padding: 12px;
1236
+ font-size: ${fontSize.sm};
1237
+ font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
1238
+ border: 1px solid ${colors.border};
1239
+ border-radius: 8px;
1240
+ resize: vertical;
1241
+
1242
+ &:focus {
1243
+ outline: none;
1244
+ border-color: ${colors.primary};
1245
+ box-shadow: 0 0 0 3px ${colors.primaryLight};
1246
+ }
1247
+
1248
+ &::placeholder {
1249
+ color: ${colors.textMuted};
1250
+ }
1251
+ `,
1252
+ textareaLabel: css4`
1253
+ font-size: ${fontSize.sm};
1254
+ color: ${colors.textSecondary};
1255
+ margin: 0 0 8px;
1256
+ `,
1257
+ footer: css4`
1258
+ display: flex;
1259
+ justify-content: flex-end;
1260
+ gap: 12px;
1261
+ padding: 16px 24px;
1262
+ border-top: 1px solid ${colors.border};
1263
+ background-color: ${colors.background};
1264
+ `,
1265
+ btn: css4`
1266
+ padding: 10px 18px;
1267
+ font-size: ${fontSize.base};
1268
+ font-weight: 500;
1269
+ border-radius: 6px;
1270
+ cursor: pointer;
1271
+ transition: all 0.15s ease;
1272
+ letter-spacing: -0.01em;
1273
+ `,
1274
+ btnCancel: css4`
1275
+ background-color: ${colors.surface};
1276
+ border: 1px solid ${colors.border};
1277
+ color: ${colors.text};
1278
+
1279
+ &:hover {
1280
+ background-color: ${colors.surfaceHover};
1281
+ border-color: ${colors.borderHover};
1282
+ }
1283
+ `,
1284
+ btnConfirm: css4`
1285
+ background-color: ${colors.primary};
1286
+ border: 1px solid ${colors.primary};
1287
+ color: white;
1288
+
1289
+ &:hover:not(:disabled) {
1290
+ background-color: ${colors.primaryHover};
1291
+ border-color: ${colors.primaryHover};
1292
+ }
1293
+
1294
+ &:disabled {
1295
+ opacity: 0.6;
1296
+ cursor: not-allowed;
1297
+ }
1298
+ `,
1299
+ fileInput: css4`
1300
+ display: none;
1301
+ `,
1302
+ selectedFiles: css4`
1303
+ margin-top: 16px;
1304
+ padding: 12px;
1305
+ background-color: ${colors.background};
1306
+ border-radius: 6px;
1307
+ font-size: ${fontSize.sm};
1308
+ color: ${colors.text};
1309
+ `
1310
+ };
1311
+ function AddNewModal({ currentPath, onClose, onUploadComplete }) {
1312
+ const [activeTab, setActiveTab] = useState3("upload");
1313
+ const [selectedFiles, setSelectedFiles] = useState3([]);
1314
+ const [urlInput, setUrlInput] = useState3("");
1315
+ const [isDragging, setIsDragging] = useState3(false);
1316
+ const [uploading, setUploading] = useState3(false);
1317
+ const [importing, setImporting] = useState3(false);
1318
+ const fileInputRef = useRef(null);
1319
+ const handleFileSelect = useCallback((files) => {
1320
+ if (files) {
1321
+ setSelectedFiles(Array.from(files));
1322
+ }
1323
+ }, []);
1324
+ const handleDrop = useCallback((e) => {
1325
+ e.preventDefault();
1326
+ setIsDragging(false);
1327
+ handleFileSelect(e.dataTransfer.files);
1328
+ }, [handleFileSelect]);
1329
+ const handleUpload = useCallback(async () => {
1330
+ if (selectedFiles.length === 0) return;
1331
+ setUploading(true);
1332
+ try {
1333
+ for (const file of selectedFiles) {
1334
+ const formData = new FormData();
1335
+ formData.append("file", file);
1336
+ formData.append("path", currentPath);
1337
+ await fetch("/api/studio/upload", {
1338
+ method: "POST",
1339
+ body: formData
1340
+ });
1341
+ }
1342
+ onUploadComplete();
1343
+ onClose();
1344
+ } catch (error) {
1345
+ console.error("Upload failed:", error);
1346
+ } finally {
1347
+ setUploading(false);
1348
+ }
1349
+ }, [selectedFiles, currentPath, onUploadComplete, onClose]);
1350
+ const handleImport = useCallback(async () => {
1351
+ const urls = urlInput.split("\n").map((url) => url.trim()).filter((url) => url.length > 0);
1352
+ if (urls.length === 0) return;
1353
+ setImporting(true);
1354
+ try {
1355
+ const response = await fetch("/api/studio/import", {
1356
+ method: "POST",
1357
+ headers: { "Content-Type": "application/json" },
1358
+ body: JSON.stringify({ urls })
1359
+ });
1360
+ const reader = response.body?.getReader();
1361
+ if (!reader) throw new Error("No reader");
1362
+ const decoder = new TextDecoder();
1363
+ while (true) {
1364
+ const { done, value } = await reader.read();
1365
+ if (done) break;
1366
+ const text = decoder.decode(value);
1367
+ const lines = text.split("\n\n").filter((line) => line.startsWith("data: "));
1368
+ for (const line of lines) {
1369
+ const data = JSON.parse(line.replace("data: ", ""));
1370
+ if (data.type === "complete") {
1371
+ onUploadComplete();
1372
+ onClose();
1373
+ }
1374
+ }
1375
+ }
1376
+ } catch (error) {
1377
+ console.error("Import failed:", error);
1378
+ } finally {
1379
+ setImporting(false);
1380
+ }
1381
+ }, [urlInput, onUploadComplete, onClose]);
1382
+ return /* @__PURE__ */ jsx4("div", { css: styles4.overlay, onClick: onClose, children: /* @__PURE__ */ jsxs4("div", { css: styles4.modal, onClick: (e) => e.stopPropagation(), children: [
1383
+ /* @__PURE__ */ jsxs4("div", { css: styles4.header, children: [
1384
+ /* @__PURE__ */ jsx4("h3", { css: styles4.title, children: "Add New" }),
1385
+ /* @__PURE__ */ jsxs4("div", { css: styles4.tabs, children: [
1386
+ /* @__PURE__ */ jsx4(
1387
+ "button",
1388
+ {
1389
+ css: [styles4.tab, activeTab === "upload" && styles4.tabActive],
1390
+ onClick: () => setActiveTab("upload"),
1391
+ children: "Upload Files"
1392
+ }
1393
+ ),
1394
+ /* @__PURE__ */ jsx4(
1395
+ "button",
1396
+ {
1397
+ css: [styles4.tab, activeTab === "import" && styles4.tabActive],
1398
+ onClick: () => setActiveTab("import"),
1399
+ children: "Import URLs"
1400
+ }
1401
+ )
1402
+ ] })
1403
+ ] }),
1404
+ /* @__PURE__ */ jsx4("div", { css: styles4.body, children: activeTab === "upload" ? /* @__PURE__ */ jsxs4(Fragment2, { children: [
1405
+ /* @__PURE__ */ jsxs4(
1406
+ "div",
1407
+ {
1408
+ css: [styles4.dropzone, isDragging && styles4.dropzoneActive],
1409
+ onClick: () => fileInputRef.current?.click(),
1410
+ onDragOver: (e) => {
1411
+ e.preventDefault();
1412
+ setIsDragging(true);
1413
+ },
1414
+ onDragLeave: () => setIsDragging(false),
1415
+ onDrop: handleDrop,
1416
+ children: [
1417
+ /* @__PURE__ */ jsx4("svg", { css: styles4.dropzoneIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" }) }),
1418
+ /* @__PURE__ */ jsx4("p", { css: styles4.dropzoneText, children: "Drop files here or click to browse" }),
1419
+ /* @__PURE__ */ jsx4("p", { css: styles4.dropzoneHint, children: "Supports images and other media files" })
1420
+ ]
1421
+ }
1422
+ ),
1423
+ /* @__PURE__ */ jsx4(
1424
+ "input",
1425
+ {
1426
+ ref: fileInputRef,
1427
+ type: "file",
1428
+ multiple: true,
1429
+ css: styles4.fileInput,
1430
+ onChange: (e) => handleFileSelect(e.target.files)
1431
+ }
1432
+ ),
1433
+ selectedFiles.length > 0 && /* @__PURE__ */ jsxs4("div", { css: styles4.selectedFiles, children: [
1434
+ selectedFiles.length,
1435
+ " file",
1436
+ selectedFiles.length !== 1 ? "s" : "",
1437
+ " selected"
1438
+ ] })
1439
+ ] }) : /* @__PURE__ */ jsxs4(Fragment2, { children: [
1440
+ /* @__PURE__ */ jsx4("p", { css: styles4.textareaLabel, children: "Paste image URLs (one per line)" }),
1441
+ /* @__PURE__ */ jsx4(
1442
+ "textarea",
1443
+ {
1444
+ css: styles4.textarea,
1445
+ value: urlInput,
1446
+ onChange: (e) => setUrlInput(e.target.value),
1447
+ placeholder: `https://cdn.example.com/photos/image1.jpg
1448
+ https://cdn.example.com/photos/image2.jpg`
1449
+ }
1450
+ )
1451
+ ] }) }),
1452
+ /* @__PURE__ */ jsxs4("div", { css: styles4.footer, children: [
1453
+ /* @__PURE__ */ jsx4(
1454
+ "button",
1455
+ {
1456
+ css: [styles4.btn, styles4.btnCancel],
1457
+ onClick: onClose,
1458
+ children: "Cancel"
1459
+ }
1460
+ ),
1461
+ activeTab === "upload" ? /* @__PURE__ */ jsx4(
1462
+ "button",
1463
+ {
1464
+ css: [styles4.btn, styles4.btnConfirm],
1465
+ onClick: handleUpload,
1466
+ disabled: selectedFiles.length === 0 || uploading,
1467
+ children: uploading ? "Uploading..." : "Upload"
1468
+ }
1469
+ ) : /* @__PURE__ */ jsx4(
1470
+ "button",
1471
+ {
1472
+ css: [styles4.btn, styles4.btnConfirm],
1473
+ onClick: handleImport,
1474
+ disabled: !urlInput.trim() || importing,
1475
+ children: importing ? "Importing..." : "Import"
1476
+ }
1477
+ )
1478
+ ] })
1479
+ ] }) });
1480
+ }
1481
+
1482
+ // src/components/StudioToolbar.tsx
1483
+ import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs5 } from "@emotion/react/jsx-runtime";
1098
1484
  var btnHeight = "36px";
1099
- var spin = keyframes3`
1485
+ var spin = keyframes4`
1100
1486
  to { transform: rotate(360deg); }
1101
1487
  `;
1102
- var styles4 = {
1103
- toolbar: css4`
1488
+ var styles5 = {
1489
+ toolbar: css5`
1104
1490
  display: flex;
1105
1491
  flex-wrap: nowrap;
1106
1492
  align-items: center;
@@ -1116,21 +1502,21 @@ var styles4 = {
1116
1502
  padding: 12px 24px;
1117
1503
  }
1118
1504
  `,
1119
- left: css4`
1505
+ left: css5`
1120
1506
  display: flex;
1121
1507
  flex-wrap: nowrap;
1122
1508
  flex-shrink: 0;
1123
1509
  align-items: center;
1124
1510
  gap: 8px;
1125
1511
  `,
1126
- right: css4`
1512
+ right: css5`
1127
1513
  display: flex;
1128
1514
  flex-wrap: nowrap;
1129
1515
  flex-shrink: 0;
1130
1516
  align-items: center;
1131
1517
  gap: 8px;
1132
1518
  `,
1133
- btn: css4`
1519
+ btn: css5`
1134
1520
  display: inline-flex;
1135
1521
  align-items: center;
1136
1522
  justify-content: center;
@@ -1157,10 +1543,10 @@ var styles4 = {
1157
1543
  opacity: 0.5;
1158
1544
  }
1159
1545
  `,
1160
- btnIconOnly: css4`
1546
+ btnIconOnly: css5`
1161
1547
  padding: 0 10px;
1162
1548
  `,
1163
- btnPrimary: css4`
1549
+ btnPrimary: css5`
1164
1550
  background: ${colors.primary};
1165
1551
  border-color: ${colors.primary};
1166
1552
  color: white;
@@ -1170,7 +1556,7 @@ var styles4 = {
1170
1556
  border-color: ${colors.primaryHover};
1171
1557
  }
1172
1558
  `,
1173
- btnDanger: css4`
1559
+ btnDanger: css5`
1174
1560
  color: ${colors.danger};
1175
1561
 
1176
1562
  &:hover:not(:disabled) {
@@ -1178,14 +1564,14 @@ var styles4 = {
1178
1564
  border-color: ${colors.danger};
1179
1565
  }
1180
1566
  `,
1181
- icon: css4`
1567
+ icon: css5`
1182
1568
  width: 16px;
1183
1569
  height: 16px;
1184
1570
  `,
1185
- iconSpin: css4`
1571
+ iconSpin: css5`
1186
1572
  animation: ${spin} 1s linear infinite;
1187
1573
  `,
1188
- selectionCount: css4`
1574
+ selectionCount: css5`
1189
1575
  font-size: ${fontSize.base};
1190
1576
  color: ${colors.textSecondary};
1191
1577
  display: flex;
@@ -1193,7 +1579,7 @@ var styles4 = {
1193
1579
  gap: 8px;
1194
1580
  margin-right: 8px;
1195
1581
  `,
1196
- clearBtn: css4`
1582
+ clearBtn: css5`
1197
1583
  color: ${colors.primary};
1198
1584
  background: none;
1199
1585
  border: none;
@@ -1206,13 +1592,13 @@ var styles4 = {
1206
1592
  text-decoration: underline;
1207
1593
  }
1208
1594
  `,
1209
- divider: css4`
1595
+ divider: css5`
1210
1596
  width: 1px;
1211
1597
  height: 24px;
1212
1598
  background: ${colors.border};
1213
1599
  margin: 0 4px;
1214
1600
  `,
1215
- viewToggle: css4`
1601
+ viewToggle: css5`
1216
1602
  display: flex;
1217
1603
  align-items: center;
1218
1604
  height: ${btnHeight};
@@ -1221,12 +1607,12 @@ var styles4 = {
1221
1607
  border-radius: 6px;
1222
1608
  overflow: hidden;
1223
1609
  `,
1224
- searchWrapper: css4`
1610
+ searchWrapper: css5`
1225
1611
  position: relative;
1226
1612
  display: flex;
1227
1613
  align-items: center;
1228
1614
  `,
1229
- searchInput: css4`
1615
+ searchInput: css5`
1230
1616
  height: ${btnHeight};
1231
1617
  padding: 0 32px 0 12px;
1232
1618
  border: 1px solid ${colors.border};
@@ -1247,7 +1633,7 @@ var styles4 = {
1247
1633
  color: ${colors.textMuted};
1248
1634
  }
1249
1635
  `,
1250
- searchClearBtn: css4`
1636
+ searchClearBtn: css5`
1251
1637
  position: absolute;
1252
1638
  right: 5px;
1253
1639
  top: 5px;
@@ -1267,7 +1653,7 @@ var styles4 = {
1267
1653
  background: ${colors.primaryHover};
1268
1654
  }
1269
1655
  `,
1270
- viewBtn: css4`
1656
+ viewBtn: css5`
1271
1657
  height: 100%;
1272
1658
  padding: 0 10px;
1273
1659
  background: transparent;
@@ -1284,7 +1670,7 @@ var styles4 = {
1284
1670
  background-color: ${colors.surfaceHover};
1285
1671
  }
1286
1672
  `,
1287
- viewBtnActive: css4`
1673
+ viewBtnActive: css5`
1288
1674
  background-color: ${colors.primaryLight};
1289
1675
  color: ${colors.primary};
1290
1676
 
@@ -1296,37 +1682,40 @@ var styles4 = {
1296
1682
  };
1297
1683
  function StudioToolbar() {
1298
1684
  const { selectedItems, viewMode, setViewMode, clearSelection, currentPath, triggerRefresh, focusedItem, scanRequested, clearScanRequest } = useStudio();
1299
- const fileInputRef = useRef(null);
1300
- const abortControllerRef = useRef(null);
1301
- const [uploading, setUploading] = useState3(false);
1302
- const [scanning, setScanning] = useState3(false);
1303
- const [processing, setProcessing] = useState3(false);
1304
- const [showDeleteConfirm, setShowDeleteConfirm] = useState3(false);
1305
- const [showProcessConfirm, setShowProcessConfirm] = useState3(false);
1306
- const [showSyncConfirm, setShowSyncConfirm] = useState3(false);
1307
- const [syncImageCount, setSyncImageCount] = useState3(0);
1308
- const [showProgress, setShowProgress] = useState3(false);
1309
- const [progressState, setProgressState] = useState3({
1685
+ const fileInputRef = useRef2(null);
1686
+ const abortControllerRef = useRef2(null);
1687
+ const [showAddNewModal, setShowAddNewModal] = useState4(false);
1688
+ const [uploading, setUploading] = useState4(false);
1689
+ const [scanning, setScanning] = useState4(false);
1690
+ const [processing, setProcessing] = useState4(false);
1691
+ const [showDeleteConfirm, setShowDeleteConfirm] = useState4(false);
1692
+ const [showProcessConfirm, setShowProcessConfirm] = useState4(false);
1693
+ const [showSyncConfirm, setShowSyncConfirm] = useState4(false);
1694
+ const [syncImageCount, setSyncImageCount] = useState4(0);
1695
+ const [showProgress, setShowProgress] = useState4(false);
1696
+ const [progressTitle, setProgressTitle] = useState4("Processing Images");
1697
+ const [progressState, setProgressState] = useState4({
1310
1698
  current: 0,
1311
1699
  total: 0,
1312
1700
  percent: 0,
1313
1701
  status: "processing"
1314
1702
  });
1315
- const [processCount, setProcessCount] = useState3(0);
1316
- const [processMode, setProcessMode] = useState3("all");
1317
- const [imagesToProcess, setImagesToProcess] = useState3([]);
1318
- const [alertMessage, setAlertMessage] = useState3(null);
1319
- const [showNewFolderModal, setShowNewFolderModal] = useState3(false);
1320
- const [showRenameFolderModal, setShowRenameFolderModal] = useState3(false);
1321
- const [showMoveModal, setShowMoveModal] = useState3(false);
1322
- const [showR2SetupModal, setShowR2SetupModal] = useState3(false);
1323
- const [pushing, setPushing] = useState3(false);
1703
+ const [processCount, setProcessCount] = useState4(0);
1704
+ const [processMode, setProcessMode] = useState4("all");
1705
+ const [imagesToProcess, setImagesToProcess] = useState4([]);
1706
+ const [alertMessage, setAlertMessage] = useState4(null);
1707
+ const [showNewFolderModal, setShowNewFolderModal] = useState4(false);
1708
+ const [showRenameFolderModal, setShowRenameFolderModal] = useState4(false);
1709
+ const [showMoveModal, setShowMoveModal] = useState4(false);
1710
+ const [showR2SetupModal, setShowR2SetupModal] = useState4(false);
1711
+ const [pushing, setPushing] = useState4(false);
1324
1712
  const isInImagesFolder = currentPath === "public/images" || currentPath.startsWith("public/images/");
1325
- const handleUpload = useCallback(() => {
1713
+ const handleUpload = useCallback2(() => {
1326
1714
  fileInputRef.current?.click();
1327
1715
  }, []);
1328
- const handleScan = useCallback(async () => {
1716
+ const handleScan = useCallback2(async () => {
1329
1717
  setScanning(true);
1718
+ setProgressTitle("Scanning Files");
1330
1719
  setShowProgress(true);
1331
1720
  setProgressState({
1332
1721
  current: 0,
@@ -1373,8 +1762,10 @@ function StudioToolbar() {
1373
1762
  percent: 100,
1374
1763
  status: "complete",
1375
1764
  processed: data.added,
1765
+ alreadyProcessed: data.existingCount,
1376
1766
  errors: data.errors,
1377
- message: data.renamed > 0 ? `${data.renamed} file(s) renamed due to conflicts` : void 0
1767
+ message: data.renamed > 0 ? `${data.renamed} file(s) renamed due to conflicts` : void 0,
1768
+ isScan: true
1378
1769
  });
1379
1770
  triggerRefresh();
1380
1771
  } else if (data.type === "error") {
@@ -1407,7 +1798,7 @@ function StudioToolbar() {
1407
1798
  handleScan();
1408
1799
  }
1409
1800
  }, [scanRequested, scanning, clearScanRequest, handleScan]);
1410
- const handleFileChange = useCallback(async (e) => {
1801
+ const handleFileChange = useCallback2(async (e) => {
1411
1802
  const files = e.target.files;
1412
1803
  if (!files || files.length === 0) return;
1413
1804
  const fileList = Array.from(files);
@@ -1503,7 +1894,7 @@ function StudioToolbar() {
1503
1894
  }
1504
1895
  }
1505
1896
  }, [currentPath, triggerRefresh]);
1506
- const handleProcessImages = useCallback(async () => {
1897
+ const handleProcessImages = useCallback2(async () => {
1507
1898
  const hasSelection2 = selectedItems.size > 0;
1508
1899
  if (hasSelection2) {
1509
1900
  const selectedPaths2 = Array.from(selectedItems);
@@ -1563,13 +1954,14 @@ function StudioToolbar() {
1563
1954
  }
1564
1955
  }
1565
1956
  }, [selectedItems]);
1566
- const handleProcessConfirm = useCallback(async () => {
1957
+ const handleProcessConfirm = useCallback2(async () => {
1567
1958
  setShowProcessConfirm(false);
1568
1959
  setProcessing(true);
1569
1960
  abortControllerRef.current = new AbortController();
1570
1961
  const signal = abortControllerRef.current.signal;
1571
1962
  try {
1572
1963
  if (processMode === "all") {
1964
+ setProgressTitle("Processing Images");
1573
1965
  setShowProgress(true);
1574
1966
  setProgressState({
1575
1967
  current: 0,
@@ -1713,16 +2105,16 @@ function StudioToolbar() {
1713
2105
  abortControllerRef.current = null;
1714
2106
  }
1715
2107
  }, [processMode, processCount, imagesToProcess, clearSelection, triggerRefresh]);
1716
- const handleStopProcessing = useCallback(() => {
2108
+ const handleStopProcessing = useCallback2(() => {
1717
2109
  if (abortControllerRef.current) {
1718
2110
  abortControllerRef.current.abort();
1719
2111
  }
1720
2112
  }, []);
1721
- const handleDeleteClick = useCallback(() => {
2113
+ const handleDeleteClick = useCallback2(() => {
1722
2114
  if (selectedItems.size === 0) return;
1723
2115
  setShowDeleteConfirm(true);
1724
2116
  }, [selectedItems]);
1725
- const handleDeleteConfirm = useCallback(async () => {
2117
+ const handleDeleteConfirm = useCallback2(async () => {
1726
2118
  setShowDeleteConfirm(false);
1727
2119
  try {
1728
2120
  const response = await fetch("/api/studio/delete", {
@@ -1748,7 +2140,7 @@ function StudioToolbar() {
1748
2140
  });
1749
2141
  }
1750
2142
  }, [selectedItems, clearSelection, triggerRefresh]);
1751
- const handleSyncClick = useCallback(async () => {
2143
+ const handleSyncClick = useCallback2(async () => {
1752
2144
  if (selectedItems.size === 0) return;
1753
2145
  const selectedPaths2 = Array.from(selectedItems);
1754
2146
  const imageExtensions = ["jpg", "jpeg", "png", "gif", "webp", "svg", "ico", "bmp", "tiff", "tif"];
@@ -1783,7 +2175,7 @@ function StudioToolbar() {
1783
2175
  setSyncImageCount(selectedImagePaths.length);
1784
2176
  setShowSyncConfirm(true);
1785
2177
  }, [selectedItems]);
1786
- const handleSyncConfirm = useCallback(async () => {
2178
+ const handleSyncConfirm = useCallback2(async () => {
1787
2179
  setShowSyncConfirm(false);
1788
2180
  const selectedPaths2 = Array.from(selectedItems);
1789
2181
  const imageExtensions = ["jpg", "jpeg", "png", "gif", "webp", "svg", "ico", "bmp", "tiff", "tif"];
@@ -1809,6 +2201,7 @@ function StudioToolbar() {
1809
2201
  }
1810
2202
  }
1811
2203
  const imageKeys = selectedImagePaths.map((p) => "/" + p.replace(/^public\//, ""));
2204
+ setProgressTitle("Pushing to CDN");
1812
2205
  setProgressState({
1813
2206
  current: 0,
1814
2207
  total: imageKeys.length,
@@ -1880,7 +2273,7 @@ function StudioToolbar() {
1880
2273
  });
1881
2274
  }
1882
2275
  }, [selectedItems, clearSelection, triggerRefresh]);
1883
- const handleCreateFolder = useCallback(async (folderName) => {
2276
+ const handleCreateFolder = useCallback2(async (folderName) => {
1884
2277
  setShowNewFolderModal(false);
1885
2278
  try {
1886
2279
  const response = await fetch("/api/studio/create-folder", {
@@ -1905,11 +2298,11 @@ function StudioToolbar() {
1905
2298
  });
1906
2299
  }
1907
2300
  }, [currentPath, triggerRefresh]);
1908
- const handleMoveClick = useCallback(() => {
2301
+ const handleMoveClick = useCallback2(() => {
1909
2302
  if (selectedItems.size === 0) return;
1910
2303
  setShowMoveModal(true);
1911
2304
  }, [selectedItems]);
1912
- const handleMoveConfirm = useCallback(async (destination) => {
2305
+ const handleMoveConfirm = useCallback2(async (destination) => {
1913
2306
  try {
1914
2307
  const response = await fetch("/api/studio/move", {
1915
2308
  method: "POST",
@@ -1941,10 +2334,10 @@ function StudioToolbar() {
1941
2334
  }
1942
2335
  }, [selectedItems, clearSelection, triggerRefresh]);
1943
2336
  const { searchQuery, setSearchQuery } = useStudio();
1944
- const handleSearch = useCallback((e) => {
2337
+ const handleSearch = useCallback2((e) => {
1945
2338
  setSearchQuery(e.target.value);
1946
2339
  }, [setSearchQuery]);
1947
- const handleSearchKeyDown = useCallback((e) => {
2340
+ const handleSearchKeyDown = useCallback2((e) => {
1948
2341
  if (e.key === "Escape") {
1949
2342
  e.stopPropagation();
1950
2343
  setSearchQuery("");
@@ -1956,7 +2349,7 @@ function StudioToolbar() {
1956
2349
  const singleFolderSelected = selectedPaths.length === 1 && !selectedPaths[0].includes(".");
1957
2350
  const selectedFolderPath = singleFolderSelected ? selectedPaths[0] : null;
1958
2351
  const selectedFolderName = selectedFolderPath ? selectedFolderPath.split("/").pop() || "" : "";
1959
- const handleRenameFolder = useCallback(async (newName) => {
2352
+ const handleRenameFolder = useCallback2(async (newName) => {
1960
2353
  if (!selectedFolderPath) return;
1961
2354
  setShowRenameFolderModal(false);
1962
2355
  try {
@@ -1976,8 +2369,8 @@ function StudioToolbar() {
1976
2369
  if (focusedItem) {
1977
2370
  return null;
1978
2371
  }
1979
- return /* @__PURE__ */ jsxs4(Fragment2, { children: [
1980
- showDeleteConfirm && /* @__PURE__ */ jsx4(
2372
+ return /* @__PURE__ */ jsxs5(Fragment3, { children: [
2373
+ showDeleteConfirm && /* @__PURE__ */ jsx5(
1981
2374
  ConfirmModal,
1982
2375
  {
1983
2376
  title: "Delete Items",
@@ -1988,7 +2381,7 @@ function StudioToolbar() {
1988
2381
  onCancel: () => setShowDeleteConfirm(false)
1989
2382
  }
1990
2383
  ),
1991
- showSyncConfirm && /* @__PURE__ */ jsx4(
2384
+ showSyncConfirm && /* @__PURE__ */ jsx5(
1992
2385
  ConfirmModal,
1993
2386
  {
1994
2387
  title: "Push to CDN",
@@ -1998,7 +2391,7 @@ function StudioToolbar() {
1998
2391
  onCancel: () => setShowSyncConfirm(false)
1999
2392
  }
2000
2393
  ),
2001
- showProcessConfirm && /* @__PURE__ */ jsx4(
2394
+ showProcessConfirm && /* @__PURE__ */ jsx5(
2002
2395
  ConfirmModal,
2003
2396
  {
2004
2397
  title: "Process Images",
@@ -2008,10 +2401,10 @@ function StudioToolbar() {
2008
2401
  onCancel: () => setShowProcessConfirm(false)
2009
2402
  }
2010
2403
  ),
2011
- showProgress && /* @__PURE__ */ jsx4(
2404
+ showProgress && /* @__PURE__ */ jsx5(
2012
2405
  ProgressModal,
2013
2406
  {
2014
- title: "Processing Images",
2407
+ title: progressTitle,
2015
2408
  progress: progressState,
2016
2409
  onStop: handleStopProcessing,
2017
2410
  onClose: () => {
@@ -2025,7 +2418,7 @@ function StudioToolbar() {
2025
2418
  }
2026
2419
  }
2027
2420
  ),
2028
- showNewFolderModal && /* @__PURE__ */ jsx4(
2421
+ showNewFolderModal && /* @__PURE__ */ jsx5(
2029
2422
  InputModal,
2030
2423
  {
2031
2424
  title: "New Folder",
@@ -2036,7 +2429,7 @@ function StudioToolbar() {
2036
2429
  onCancel: () => setShowNewFolderModal(false)
2037
2430
  }
2038
2431
  ),
2039
- showMoveModal && /* @__PURE__ */ jsx4(
2432
+ showMoveModal && /* @__PURE__ */ jsx5(
2040
2433
  StudioFolderPicker,
2041
2434
  {
2042
2435
  selectedItems,
@@ -2048,7 +2441,7 @@ function StudioToolbar() {
2048
2441
  onCancel: () => setShowMoveModal(false)
2049
2442
  }
2050
2443
  ),
2051
- showRenameFolderModal && selectedFolderPath && /* @__PURE__ */ jsx4(
2444
+ showRenameFolderModal && selectedFolderPath && /* @__PURE__ */ jsx5(
2052
2445
  InputModal,
2053
2446
  {
2054
2447
  title: "Rename Folder",
@@ -2060,7 +2453,7 @@ function StudioToolbar() {
2060
2453
  onCancel: () => setShowRenameFolderModal(false)
2061
2454
  }
2062
2455
  ),
2063
- alertMessage && /* @__PURE__ */ jsx4(
2456
+ alertMessage && /* @__PURE__ */ jsx5(
2064
2457
  AlertModal,
2065
2458
  {
2066
2459
  title: alertMessage.title,
@@ -2068,15 +2461,26 @@ function StudioToolbar() {
2068
2461
  onClose: () => setAlertMessage(null)
2069
2462
  }
2070
2463
  ),
2071
- /* @__PURE__ */ jsx4(
2464
+ /* @__PURE__ */ jsx5(
2072
2465
  R2SetupModal,
2073
2466
  {
2074
2467
  isOpen: showR2SetupModal,
2075
2468
  onClose: () => setShowR2SetupModal(false)
2076
2469
  }
2077
2470
  ),
2078
- /* @__PURE__ */ jsxs4("div", { css: styles4.toolbar, children: [
2079
- /* @__PURE__ */ jsx4(
2471
+ showAddNewModal && /* @__PURE__ */ jsx5(
2472
+ AddNewModal,
2473
+ {
2474
+ currentPath,
2475
+ onClose: () => setShowAddNewModal(false),
2476
+ onUploadComplete: () => {
2477
+ setShowAddNewModal(false);
2478
+ triggerRefresh();
2479
+ }
2480
+ }
2481
+ ),
2482
+ /* @__PURE__ */ jsxs5("div", { css: styles5.toolbar, children: [
2483
+ /* @__PURE__ */ jsx5(
2080
2484
  "input",
2081
2485
  {
2082
2486
  ref: fileInputRef,
@@ -2087,87 +2491,87 @@ function StudioToolbar() {
2087
2491
  style: { display: "none" }
2088
2492
  }
2089
2493
  ),
2090
- /* @__PURE__ */ jsxs4("div", { css: styles4.left, children: [
2091
- /* @__PURE__ */ jsxs4(
2494
+ /* @__PURE__ */ jsxs5("div", { css: styles5.left, children: [
2495
+ /* @__PURE__ */ jsxs5(
2092
2496
  "button",
2093
2497
  {
2094
- css: [styles4.btn, styles4.btnPrimary],
2095
- onClick: handleUpload,
2498
+ css: [styles5.btn, styles5.btnPrimary],
2499
+ onClick: () => setShowAddNewModal(true),
2096
2500
  disabled: uploading || isInImagesFolder,
2097
2501
  children: [
2098
- /* @__PURE__ */ jsx4(UploadIcon, {}),
2099
- uploading ? "Uploading..." : "Upload"
2502
+ /* @__PURE__ */ jsx5(UploadIcon, {}),
2503
+ "Add New"
2100
2504
  ]
2101
2505
  }
2102
2506
  ),
2103
- /* @__PURE__ */ jsxs4(
2507
+ /* @__PURE__ */ jsxs5(
2104
2508
  "button",
2105
2509
  {
2106
- css: styles4.btn,
2510
+ css: styles5.btn,
2107
2511
  onClick: () => singleFolderSelected ? setShowRenameFolderModal(true) : setShowNewFolderModal(true),
2108
2512
  disabled: isInImagesFolder && !singleFolderSelected,
2109
2513
  title: isInImagesFolder && !singleFolderSelected ? "Cannot create folders in protected images folder" : void 0,
2110
2514
  children: [
2111
- singleFolderSelected ? /* @__PURE__ */ jsx4(RenameIcon, {}) : /* @__PURE__ */ jsx4(FolderPlusIcon, {}),
2515
+ singleFolderSelected ? /* @__PURE__ */ jsx5(RenameIcon, {}) : /* @__PURE__ */ jsx5(FolderPlusIcon, {}),
2112
2516
  singleFolderSelected ? "Rename Folder" : "New Folder"
2113
2517
  ]
2114
2518
  }
2115
2519
  ),
2116
- /* @__PURE__ */ jsx4("div", { css: styles4.divider }),
2117
- /* @__PURE__ */ jsxs4(
2520
+ /* @__PURE__ */ jsx5("div", { css: styles5.divider }),
2521
+ /* @__PURE__ */ jsxs5(
2118
2522
  "button",
2119
2523
  {
2120
- css: styles4.btn,
2524
+ css: styles5.btn,
2121
2525
  onClick: handleProcessImages,
2122
2526
  disabled: processing || isInImagesFolder,
2123
2527
  title: isInImagesFolder ? "Cannot process images folder" : void 0,
2124
2528
  children: [
2125
- /* @__PURE__ */ jsx4(ImageStackIcon, {}),
2529
+ /* @__PURE__ */ jsx5(ImageStackIcon, {}),
2126
2530
  processing ? "Processing..." : "Process Images"
2127
2531
  ]
2128
2532
  }
2129
2533
  ),
2130
- /* @__PURE__ */ jsxs4(
2534
+ /* @__PURE__ */ jsxs5(
2131
2535
  "button",
2132
2536
  {
2133
- css: [styles4.btn, styles4.btnDanger],
2537
+ css: [styles5.btn, styles5.btnDanger],
2134
2538
  onClick: handleDeleteClick,
2135
2539
  disabled: !hasSelection,
2136
2540
  children: [
2137
- /* @__PURE__ */ jsx4(TrashIcon, {}),
2541
+ /* @__PURE__ */ jsx5(TrashIcon, {}),
2138
2542
  "Delete"
2139
2543
  ]
2140
2544
  }
2141
2545
  ),
2142
- /* @__PURE__ */ jsxs4(
2546
+ /* @__PURE__ */ jsxs5(
2143
2547
  "button",
2144
2548
  {
2145
- css: styles4.btn,
2549
+ css: styles5.btn,
2146
2550
  onClick: handleMoveClick,
2147
2551
  disabled: !hasSelection,
2148
2552
  children: [
2149
- /* @__PURE__ */ jsx4(MoveIcon, {}),
2553
+ /* @__PURE__ */ jsx5(MoveIcon, {}),
2150
2554
  "Move"
2151
2555
  ]
2152
2556
  }
2153
2557
  ),
2154
- /* @__PURE__ */ jsxs4(
2558
+ /* @__PURE__ */ jsxs5(
2155
2559
  "button",
2156
2560
  {
2157
- css: styles4.btn,
2561
+ css: styles5.btn,
2158
2562
  onClick: handleSyncClick,
2159
2563
  disabled: !hasSelection,
2160
2564
  children: [
2161
- /* @__PURE__ */ jsx4(CloudIcon, {}),
2565
+ /* @__PURE__ */ jsx5(CloudIcon, {}),
2162
2566
  "Push CDN"
2163
2567
  ]
2164
2568
  }
2165
2569
  ),
2166
- /* @__PURE__ */ jsxs4("div", { css: styles4.searchWrapper, children: [
2167
- /* @__PURE__ */ jsx4(
2570
+ /* @__PURE__ */ jsxs5("div", { css: styles5.searchWrapper, children: [
2571
+ /* @__PURE__ */ jsx5(
2168
2572
  "input",
2169
2573
  {
2170
- css: styles4.searchInput,
2574
+ css: styles5.searchInput,
2171
2575
  type: "text",
2172
2576
  placeholder: "Search images...",
2173
2577
  value: searchQuery,
@@ -2175,52 +2579,52 @@ function StudioToolbar() {
2175
2579
  onKeyDown: handleSearchKeyDown
2176
2580
  }
2177
2581
  ),
2178
- searchQuery && /* @__PURE__ */ jsx4(
2582
+ searchQuery && /* @__PURE__ */ jsx5(
2179
2583
  "button",
2180
2584
  {
2181
- css: styles4.searchClearBtn,
2585
+ css: styles5.searchClearBtn,
2182
2586
  onClick: () => setSearchQuery(""),
2183
2587
  title: "Clear search",
2184
- children: /* @__PURE__ */ jsx4("svg", { width: "14", height: "14", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
2588
+ children: /* @__PURE__ */ jsx5("svg", { width: "14", height: "14", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
2185
2589
  }
2186
2590
  )
2187
2591
  ] })
2188
2592
  ] }),
2189
- /* @__PURE__ */ jsxs4("div", { css: styles4.right, children: [
2190
- hasSelection && /* @__PURE__ */ jsxs4("span", { css: styles4.selectionCount, children: [
2593
+ /* @__PURE__ */ jsxs5("div", { css: styles5.right, children: [
2594
+ hasSelection && /* @__PURE__ */ jsxs5("span", { css: styles5.selectionCount, children: [
2191
2595
  selectedItems.size,
2192
2596
  " selected",
2193
- /* @__PURE__ */ jsx4("button", { css: styles4.clearBtn, onClick: clearSelection, children: "Clear" })
2597
+ /* @__PURE__ */ jsx5("button", { css: styles5.clearBtn, onClick: clearSelection, children: "Clear" })
2194
2598
  ] }),
2195
- /* @__PURE__ */ jsxs4(
2599
+ /* @__PURE__ */ jsxs5(
2196
2600
  "button",
2197
2601
  {
2198
- css: styles4.btn,
2602
+ css: styles5.btn,
2199
2603
  onClick: handleScan,
2200
2604
  disabled: scanning,
2201
2605
  children: [
2202
- /* @__PURE__ */ jsx4(ScanIcon, { spinning: scanning }),
2606
+ /* @__PURE__ */ jsx5(ScanIcon, { spinning: scanning }),
2203
2607
  "Scan"
2204
2608
  ]
2205
2609
  }
2206
2610
  ),
2207
- /* @__PURE__ */ jsxs4("div", { css: styles4.viewToggle, children: [
2208
- /* @__PURE__ */ jsx4(
2611
+ /* @__PURE__ */ jsxs5("div", { css: styles5.viewToggle, children: [
2612
+ /* @__PURE__ */ jsx5(
2209
2613
  "button",
2210
2614
  {
2211
- css: [styles4.viewBtn, viewMode === "grid" && styles4.viewBtnActive],
2615
+ css: [styles5.viewBtn, viewMode === "grid" && styles5.viewBtnActive],
2212
2616
  onClick: () => setViewMode("grid"),
2213
2617
  "aria-label": "Grid view",
2214
- children: /* @__PURE__ */ jsx4(GridIcon, {})
2618
+ children: /* @__PURE__ */ jsx5(GridIcon, {})
2215
2619
  }
2216
2620
  ),
2217
- /* @__PURE__ */ jsx4(
2621
+ /* @__PURE__ */ jsx5(
2218
2622
  "button",
2219
2623
  {
2220
- css: [styles4.viewBtn, viewMode === "list" && styles4.viewBtnActive],
2624
+ css: [styles5.viewBtn, viewMode === "list" && styles5.viewBtnActive],
2221
2625
  onClick: () => setViewMode("list"),
2222
2626
  "aria-label": "List view",
2223
- children: /* @__PURE__ */ jsx4(ListIcon, {})
2627
+ children: /* @__PURE__ */ jsx5(ListIcon, {})
2224
2628
  }
2225
2629
  )
2226
2630
  ] })
@@ -2229,42 +2633,42 @@ function StudioToolbar() {
2229
2633
  ] });
2230
2634
  }
2231
2635
  function UploadIcon() {
2232
- return /* @__PURE__ */ jsx4("svg", { css: styles4.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12" }) });
2636
+ return /* @__PURE__ */ jsx5("svg", { css: styles5.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12" }) });
2233
2637
  }
2234
2638
  function ScanIcon({ spinning }) {
2235
- return /* @__PURE__ */ jsx4("svg", { css: [styles4.icon, spinning && styles4.iconSpin], fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" }) });
2639
+ return /* @__PURE__ */ jsx5("svg", { css: [styles5.icon, spinning && styles5.iconSpin], fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" }) });
2236
2640
  }
2237
2641
  function TrashIcon() {
2238
- return /* @__PURE__ */ jsx4("svg", { css: styles4.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) });
2642
+ return /* @__PURE__ */ jsx5("svg", { css: styles5.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) });
2239
2643
  }
2240
2644
  function FolderPlusIcon() {
2241
- return /* @__PURE__ */ jsx4("svg", { css: styles4.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 13h6m-3-3v6m-9 1V7a2 2 0 012-2h6l2 2h6a2 2 0 012 2v8a2 2 0 01-2 2H5a2 2 0 01-2-2z" }) });
2645
+ return /* @__PURE__ */ jsx5("svg", { css: styles5.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 13h6m-3-3v6m-9 1V7a2 2 0 012-2h6l2 2h6a2 2 0 012 2v8a2 2 0 01-2 2H5a2 2 0 01-2-2z" }) });
2242
2646
  }
2243
2647
  function RenameIcon() {
2244
- return /* @__PURE__ */ jsx4("svg", { css: styles4.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" }) });
2648
+ return /* @__PURE__ */ jsx5("svg", { css: styles5.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" }) });
2245
2649
  }
2246
2650
  function MoveIcon() {
2247
- return /* @__PURE__ */ jsx4("svg", { css: styles4.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4" }) });
2651
+ return /* @__PURE__ */ jsx5("svg", { css: styles5.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4" }) });
2248
2652
  }
2249
2653
  function CloudIcon() {
2250
- return /* @__PURE__ */ jsx4("svg", { css: styles4.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" }) });
2654
+ return /* @__PURE__ */ jsx5("svg", { css: styles5.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" }) });
2251
2655
  }
2252
2656
  function GridIcon() {
2253
- return /* @__PURE__ */ jsx4("svg", { css: styles4.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z" }) });
2657
+ return /* @__PURE__ */ jsx5("svg", { css: styles5.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z" }) });
2254
2658
  }
2255
2659
  function ListIcon() {
2256
- return /* @__PURE__ */ jsx4("svg", { css: styles4.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6h16M4 10h16M4 14h16M4 18h16" }) });
2660
+ return /* @__PURE__ */ jsx5("svg", { css: styles5.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6h16M4 10h16M4 14h16M4 18h16" }) });
2257
2661
  }
2258
2662
  function ImageStackIcon() {
2259
- return /* @__PURE__ */ jsx4("svg", { css: styles4.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) });
2663
+ return /* @__PURE__ */ jsx5("svg", { css: styles5.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) });
2260
2664
  }
2261
2665
 
2262
2666
  // src/components/StudioFileGrid.tsx
2263
- import { useState as useState5 } from "react";
2264
- import { css as css5, keyframes as keyframes4 } from "@emotion/react";
2667
+ import { useState as useState6 } from "react";
2668
+ import { css as css6, keyframes as keyframes5 } from "@emotion/react";
2265
2669
 
2266
2670
  // src/hooks/useFileList.ts
2267
- import { useEffect as useEffect3, useState as useState4, useRef as useRef2, useCallback as useCallback2 } from "react";
2671
+ import { useEffect as useEffect3, useState as useState5, useRef as useRef3, useCallback as useCallback3 } from "react";
2268
2672
 
2269
2673
  // src/lib/api.ts
2270
2674
  var StudioApiClient = class {
@@ -2364,11 +2768,11 @@ function useFileList() {
2364
2768
  searchQuery,
2365
2769
  showError
2366
2770
  } = useStudio();
2367
- const [items, setItems] = useState4([]);
2368
- const [loading, setLoading] = useState4(true);
2369
- const [metaEmpty, setMetaEmpty] = useState4(false);
2370
- const isInitialLoad = useRef2(true);
2371
- const lastPath = useRef2(currentPath);
2771
+ const [items, setItems] = useState5([]);
2772
+ const [loading, setLoading] = useState5(true);
2773
+ const [metaEmpty, setMetaEmpty] = useState5(false);
2774
+ const isInitialLoad = useRef3(true);
2775
+ const lastPath = useRef3(currentPath);
2372
2776
  useEffect3(() => {
2373
2777
  async function loadItems() {
2374
2778
  const isPathChange = lastPath.current !== currentPath;
@@ -2400,21 +2804,21 @@ function useFileList() {
2400
2804
  });
2401
2805
  const allItemsSelected = sortedItems.length > 0 && sortedItems.every((item) => selectedItems.has(item.path));
2402
2806
  const someItemsSelected = sortedItems.some((item) => selectedItems.has(item.path));
2403
- const handleItemClick = useCallback2((item, e) => {
2807
+ const handleItemClick = useCallback3((item, e) => {
2404
2808
  if (e.shiftKey && lastSelectedPath) {
2405
2809
  selectRange(lastSelectedPath, item.path, sortedItems);
2406
2810
  } else {
2407
2811
  toggleSelection(item.path);
2408
2812
  }
2409
2813
  }, [lastSelectedPath, selectRange, sortedItems, toggleSelection]);
2410
- const handleOpen = useCallback2((item) => {
2814
+ const handleOpen = useCallback3((item) => {
2411
2815
  if (item.type === "folder") {
2412
2816
  setCurrentPath(item.path);
2413
2817
  } else {
2414
2818
  setFocusedItem(item);
2415
2819
  }
2416
2820
  }, [setCurrentPath, setFocusedItem]);
2417
- const handleGenerateThumbnail = useCallback2(async (item) => {
2821
+ const handleGenerateThumbnail = useCallback3(async (item) => {
2418
2822
  try {
2419
2823
  const imageKey = "/" + item.path.replace(/^public\//, "");
2420
2824
  await studioApi.reprocess([imageKey]);
@@ -2424,7 +2828,7 @@ function useFileList() {
2424
2828
  showError("Processing Error", message);
2425
2829
  }
2426
2830
  }, [triggerRefresh, showError]);
2427
- const handleSelectAll = useCallback2(() => {
2831
+ const handleSelectAll = useCallback3(() => {
2428
2832
  if (allItemsSelected) {
2429
2833
  clearSelection();
2430
2834
  } else {
@@ -2456,19 +2860,19 @@ function useFileList() {
2456
2860
  }
2457
2861
 
2458
2862
  // src/components/StudioFileGrid.tsx
2459
- import { jsx as jsx5, jsxs as jsxs5 } from "@emotion/react/jsx-runtime";
2460
- var spin2 = keyframes4`
2863
+ import { jsx as jsx6, jsxs as jsxs6 } from "@emotion/react/jsx-runtime";
2864
+ var spin2 = keyframes5`
2461
2865
  to { transform: rotate(360deg); }
2462
2866
  `;
2463
- var styles5 = {
2464
- loading: css5`
2867
+ var styles6 = {
2868
+ loading: css6`
2465
2869
  display: flex;
2466
2870
  align-items: center;
2467
2871
  justify-content: center;
2468
2872
  flex: 1;
2469
2873
  min-height: 300px;
2470
2874
  `,
2471
- spinner: css5`
2875
+ spinner: css6`
2472
2876
  width: 32px;
2473
2877
  height: 32px;
2474
2878
  border-radius: 50%;
@@ -2476,7 +2880,7 @@ var styles5 = {
2476
2880
  border-top-color: ${colors.primary};
2477
2881
  animation: ${spin2} 0.8s linear infinite;
2478
2882
  `,
2479
- empty: css5`
2883
+ empty: css6`
2480
2884
  display: flex;
2481
2885
  flex-direction: column;
2482
2886
  align-items: center;
@@ -2485,13 +2889,13 @@ var styles5 = {
2485
2889
  min-height: 300px;
2486
2890
  color: ${colors.textSecondary};
2487
2891
  `,
2488
- emptyIcon: css5`
2892
+ emptyIcon: css6`
2489
2893
  width: 48px;
2490
2894
  height: 48px;
2491
2895
  margin-bottom: 16px;
2492
2896
  opacity: 0.5;
2493
2897
  `,
2494
- emptyText: css5`
2898
+ emptyText: css6`
2495
2899
  font-size: ${fontSize.base};
2496
2900
  margin: 0 0 4px 0;
2497
2901
 
@@ -2500,7 +2904,7 @@ var styles5 = {
2500
2904
  font-size: ${fontSize.sm};
2501
2905
  }
2502
2906
  `,
2503
- scanButton: css5`
2907
+ scanButton: css6`
2504
2908
  margin-top: 16px;
2505
2909
  padding: 10px 24px;
2506
2910
  font-size: ${fontSize.base};
@@ -2521,7 +2925,7 @@ var styles5 = {
2521
2925
  cursor: not-allowed;
2522
2926
  }
2523
2927
  `,
2524
- grid: css5`
2928
+ grid: css6`
2525
2929
  display: grid;
2526
2930
  grid-template-columns: 1fr;
2527
2931
  gap: 12px;
@@ -2531,7 +2935,7 @@ var styles5 = {
2531
2935
  @media (min-width: 1024px) { grid-template-columns: repeat(4, 1fr); }
2532
2936
  @media (min-width: 1280px) { grid-template-columns: repeat(5, 1fr); }
2533
2937
  `,
2534
- item: css5`
2938
+ item: css6`
2535
2939
  position: relative;
2536
2940
  border-radius: 8px;
2537
2941
  border: 1px solid ${colors.border};
@@ -2547,7 +2951,7 @@ var styles5 = {
2547
2951
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.06);
2548
2952
  }
2549
2953
  `,
2550
- itemSelected: css5`
2954
+ itemSelected: css6`
2551
2955
  border-color: ${colors.primary};
2552
2956
  box-shadow: 0 0 0 1px ${colors.primary};
2553
2957
 
@@ -2556,14 +2960,14 @@ var styles5 = {
2556
2960
  box-shadow: 0 0 0 1px ${colors.primary};
2557
2961
  }
2558
2962
  `,
2559
- parentItem: css5`
2963
+ parentItem: css6`
2560
2964
  cursor: pointer;
2561
2965
 
2562
2966
  &:hover {
2563
2967
  border-color: ${colors.primary};
2564
2968
  }
2565
2969
  `,
2566
- checkboxWrapper: css5`
2970
+ checkboxWrapper: css6`
2567
2971
  position: absolute;
2568
2972
  top: 0;
2569
2973
  left: 0;
@@ -2571,13 +2975,13 @@ var styles5 = {
2571
2975
  padding: 8px;
2572
2976
  cursor: pointer;
2573
2977
  `,
2574
- checkbox: css5`
2978
+ checkbox: css6`
2575
2979
  width: 18px;
2576
2980
  height: 18px;
2577
2981
  accent-color: ${colors.primary};
2578
2982
  cursor: pointer;
2579
2983
  `,
2580
- cdnBadge: css5`
2984
+ cdnBadge: css6`
2581
2985
  position: absolute;
2582
2986
  top: 8px;
2583
2987
  right: 8px;
@@ -2589,7 +2993,7 @@ var styles5 = {
2589
2993
  padding: 2px 8px;
2590
2994
  border-radius: 4px;
2591
2995
  `,
2592
- content: css5`
2996
+ content: css6`
2593
2997
  position: relative;
2594
2998
  aspect-ratio: 1;
2595
2999
  display: flex;
@@ -2598,20 +3002,20 @@ var styles5 = {
2598
3002
  padding: 16px;
2599
3003
  background: ${colors.background};
2600
3004
  `,
2601
- folderIcon: css5`
3005
+ folderIcon: css6`
2602
3006
  width: 56px;
2603
3007
  height: 56px;
2604
3008
  color: #f9935e;
2605
3009
  `,
2606
- imagesFolderIcon: css5`
3010
+ imagesFolderIcon: css6`
2607
3011
  width: 56px;
2608
3012
  height: 56px;
2609
3013
  color: ${colors.imagesFolder};
2610
3014
  `,
2611
- imagesFolderWrapper: css5`
3015
+ imagesFolderWrapper: css6`
2612
3016
  position: relative;
2613
3017
  `,
2614
- lockIcon: css5`
3018
+ lockIcon: css6`
2615
3019
  position: absolute;
2616
3020
  bottom: 4px;
2617
3021
  right: 4px;
@@ -2622,23 +3026,23 @@ var styles5 = {
2622
3026
  border-radius: 50%;
2623
3027
  padding: 2px;
2624
3028
  `,
2625
- parentIcon: css5`
3029
+ parentIcon: css6`
2626
3030
  width: 56px;
2627
3031
  height: 56px;
2628
3032
  color: ${colors.textMuted};
2629
3033
  `,
2630
- fileIcon: css5`
3034
+ fileIcon: css6`
2631
3035
  width: 40px;
2632
3036
  height: 40px;
2633
3037
  color: ${colors.textMuted};
2634
3038
  `,
2635
- image: css5`
3039
+ image: css6`
2636
3040
  max-width: 100%;
2637
3041
  max-height: 100%;
2638
3042
  object-fit: contain;
2639
3043
  border-radius: 4px;
2640
3044
  `,
2641
- noThumbnail: css5`
3045
+ noThumbnail: css6`
2642
3046
  display: flex;
2643
3047
  flex-direction: column;
2644
3048
  align-items: center;
@@ -2658,31 +3062,31 @@ var styles5 = {
2658
3062
  background: ${colors.surfaceHover};
2659
3063
  }
2660
3064
  `,
2661
- noThumbnailIcon: css5`
3065
+ noThumbnailIcon: css6`
2662
3066
  width: 32px;
2663
3067
  height: 32px;
2664
3068
  color: ${colors.textMuted};
2665
3069
  `,
2666
- noThumbnailText: css5`
3070
+ noThumbnailText: css6`
2667
3071
  font-size: ${fontSize.xs};
2668
3072
  color: ${colors.textMuted};
2669
3073
  text-align: center;
2670
3074
  `,
2671
- label: css5`
3075
+ label: css6`
2672
3076
  padding: 10px 12px;
2673
3077
  background-color: ${colors.surface};
2674
3078
  border-top: 1px solid ${colors.borderLight};
2675
3079
  `,
2676
- labelRow: css5`
3080
+ labelRow: css6`
2677
3081
  display: flex;
2678
3082
  flex-direction: column;
2679
3083
  gap: 2px;
2680
3084
  `,
2681
- labelText: css5`
3085
+ labelText: css6`
2682
3086
  flex: 1;
2683
3087
  min-width: 0;
2684
3088
  `,
2685
- copyBtn: css5`
3089
+ copyBtn: css6`
2686
3090
  position: absolute;
2687
3091
  top: 4px;
2688
3092
  right: 4px;
@@ -2704,11 +3108,11 @@ var styles5 = {
2704
3108
  color: ${colors.text};
2705
3109
  }
2706
3110
  `,
2707
- copyIcon: css5`
3111
+ copyIcon: css6`
2708
3112
  width: 18px;
2709
3113
  height: 18px;
2710
3114
  `,
2711
- tooltip: css5`
3115
+ tooltip: css6`
2712
3116
  position: absolute;
2713
3117
  top: 50%;
2714
3118
  right: 100%;
@@ -2733,7 +3137,7 @@ var styles5 = {
2733
3137
  border-left-color: #1a1f36;
2734
3138
  }
2735
3139
  `,
2736
- openBtn: css5`
3140
+ openBtn: css6`
2737
3141
  position: absolute;
2738
3142
  bottom: 8px;
2739
3143
  right: 8px;
@@ -2757,7 +3161,7 @@ var styles5 = {
2757
3161
  border-color: ${colors.primary};
2758
3162
  }
2759
3163
  `,
2760
- name: css5`
3164
+ name: css6`
2761
3165
  font-size: ${fontSize.sm};
2762
3166
  font-weight: 500;
2763
3167
  color: ${colors.text};
@@ -2767,12 +3171,12 @@ var styles5 = {
2767
3171
  margin: 0;
2768
3172
  letter-spacing: -0.01em;
2769
3173
  `,
2770
- size: css5`
3174
+ size: css6`
2771
3175
  font-size: ${fontSize.xs};
2772
3176
  color: ${colors.textMuted};
2773
3177
  margin: 2px 0 0 0;
2774
3178
  `,
2775
- selectAllRow: css5`
3179
+ selectAllRow: css6`
2776
3180
  display: flex;
2777
3181
  align-items: center;
2778
3182
  margin-bottom: 16px;
@@ -2781,7 +3185,7 @@ var styles5 = {
2781
3185
  border-radius: 8px;
2782
3186
  border: 1px solid ${colors.border};
2783
3187
  `,
2784
- selectAllLabel: css5`
3188
+ selectAllLabel: css6`
2785
3189
  display: flex;
2786
3190
  align-items: center;
2787
3191
  gap: 10px;
@@ -2794,7 +3198,7 @@ var styles5 = {
2794
3198
  color: ${colors.text};
2795
3199
  }
2796
3200
  `,
2797
- selectAllCheckbox: css5`
3201
+ selectAllCheckbox: css6`
2798
3202
  width: 16px;
2799
3203
  height: 16px;
2800
3204
  accent-color: ${colors.primary};
@@ -2818,17 +3222,17 @@ function StudioFileGrid() {
2818
3222
  triggerScan
2819
3223
  } = useFileList();
2820
3224
  if (loading) {
2821
- return /* @__PURE__ */ jsx5("div", { css: styles5.loading, children: /* @__PURE__ */ jsx5("div", { css: styles5.spinner }) });
3225
+ return /* @__PURE__ */ jsx6("div", { css: styles6.loading, children: /* @__PURE__ */ jsx6("div", { css: styles6.spinner }) });
2822
3226
  }
2823
3227
  if (metaEmpty && isAtRoot) {
2824
- return /* @__PURE__ */ jsxs5("div", { css: styles5.empty, children: [
2825
- /* @__PURE__ */ jsx5("svg", { css: styles5.emptyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }),
2826
- /* @__PURE__ */ jsx5("p", { css: styles5.emptyText, children: "No files tracked yet" }),
2827
- /* @__PURE__ */ jsx5("p", { css: styles5.emptyText, children: "Click Scan to discover files in your public folder" }),
2828
- /* @__PURE__ */ jsx5(
3228
+ return /* @__PURE__ */ jsxs6("div", { css: styles6.empty, children: [
3229
+ /* @__PURE__ */ jsx6("svg", { css: styles6.emptyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }),
3230
+ /* @__PURE__ */ jsx6("p", { css: styles6.emptyText, children: "No files tracked yet" }),
3231
+ /* @__PURE__ */ jsx6("p", { css: styles6.emptyText, children: "Click Scan to discover files in your public folder" }),
3232
+ /* @__PURE__ */ jsx6(
2829
3233
  "button",
2830
3234
  {
2831
- css: styles5.scanButton,
3235
+ css: styles6.scanButton,
2832
3236
  onClick: triggerScan,
2833
3237
  children: "Scan for Files"
2834
3238
  }
@@ -2836,19 +3240,19 @@ function StudioFileGrid() {
2836
3240
  ] });
2837
3241
  }
2838
3242
  if (sortedItems.length === 0 && isAtRoot) {
2839
- return /* @__PURE__ */ jsxs5("div", { css: styles5.empty, children: [
2840
- /* @__PURE__ */ jsx5("svg", { css: styles5.emptyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) }),
2841
- /* @__PURE__ */ jsx5("p", { css: styles5.emptyText, children: "No files in this folder" }),
2842
- /* @__PURE__ */ jsx5("p", { css: styles5.emptyText, children: "Upload images or click Scan in the toolbar" })
3243
+ return /* @__PURE__ */ jsxs6("div", { css: styles6.empty, children: [
3244
+ /* @__PURE__ */ jsx6("svg", { css: styles6.emptyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) }),
3245
+ /* @__PURE__ */ jsx6("p", { css: styles6.emptyText, children: "No files in this folder" }),
3246
+ /* @__PURE__ */ jsx6("p", { css: styles6.emptyText, children: "Upload images or click Scan in the toolbar" })
2843
3247
  ] });
2844
3248
  }
2845
- return /* @__PURE__ */ jsxs5("div", { children: [
2846
- sortedItems.length > 0 && /* @__PURE__ */ jsx5("div", { css: styles5.selectAllRow, children: /* @__PURE__ */ jsxs5("label", { css: styles5.selectAllLabel, children: [
2847
- /* @__PURE__ */ jsx5(
3249
+ return /* @__PURE__ */ jsxs6("div", { children: [
3250
+ sortedItems.length > 0 && /* @__PURE__ */ jsx6("div", { css: styles6.selectAllRow, children: /* @__PURE__ */ jsxs6("label", { css: styles6.selectAllLabel, children: [
3251
+ /* @__PURE__ */ jsx6(
2848
3252
  "input",
2849
3253
  {
2850
3254
  type: "checkbox",
2851
- css: styles5.selectAllCheckbox,
3255
+ css: styles6.selectAllCheckbox,
2852
3256
  checked: allItemsSelected,
2853
3257
  ref: (el) => {
2854
3258
  if (el) el.indeterminate = someItemsSelected && !allItemsSelected;
@@ -2860,22 +3264,22 @@ function StudioFileGrid() {
2860
3264
  sortedItems.length,
2861
3265
  ")"
2862
3266
  ] }) }),
2863
- /* @__PURE__ */ jsxs5("div", { css: styles5.grid, children: [
2864
- !isAtRoot && !isSearching && /* @__PURE__ */ jsxs5(
3267
+ /* @__PURE__ */ jsxs6("div", { css: styles6.grid, children: [
3268
+ !isAtRoot && !isSearching && /* @__PURE__ */ jsxs6(
2865
3269
  "div",
2866
3270
  {
2867
- css: [styles5.item, styles5.parentItem],
3271
+ css: [styles6.item, styles6.parentItem],
2868
3272
  onClick: navigateUp,
2869
3273
  children: [
2870
- /* @__PURE__ */ jsx5("div", { css: styles5.content, children: /* @__PURE__ */ jsx5("svg", { css: styles5.parentIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" }) }) }),
2871
- /* @__PURE__ */ jsxs5("div", { css: styles5.label, children: [
2872
- /* @__PURE__ */ jsx5("p", { css: styles5.name, children: ".." }),
2873
- /* @__PURE__ */ jsx5("p", { css: styles5.size, children: "Parent folder" })
3274
+ /* @__PURE__ */ jsx6("div", { css: styles6.content, children: /* @__PURE__ */ jsx6("svg", { css: styles6.parentIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" }) }) }),
3275
+ /* @__PURE__ */ jsxs6("div", { css: styles6.label, children: [
3276
+ /* @__PURE__ */ jsx6("p", { css: styles6.name, children: ".." }),
3277
+ /* @__PURE__ */ jsx6("p", { css: styles6.size, children: "Parent folder" })
2874
3278
  ] })
2875
3279
  ]
2876
3280
  }
2877
3281
  ),
2878
- sortedItems.map((item) => /* @__PURE__ */ jsx5(
3282
+ sortedItems.map((item) => /* @__PURE__ */ jsx6(
2879
3283
  GridItem,
2880
3284
  {
2881
3285
  item,
@@ -2890,7 +3294,7 @@ function StudioFileGrid() {
2890
3294
  ] });
2891
3295
  }
2892
3296
  function GridItem({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
2893
- const [showCopied, setShowCopied] = useState5(false);
3297
+ const [showCopied, setShowCopied] = useState6(false);
2894
3298
  const isFolder = item.type === "folder";
2895
3299
  const isImage = !isFolder && item.thumbnail !== void 0;
2896
3300
  const isImagesFolder = isFolder && (item.name === "images" || item.path.includes("/images/"));
@@ -2901,46 +3305,46 @@ function GridItem({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
2901
3305
  setShowCopied(true);
2902
3306
  setTimeout(() => setShowCopied(false), 1500);
2903
3307
  };
2904
- return /* @__PURE__ */ jsxs5(
3308
+ return /* @__PURE__ */ jsxs6(
2905
3309
  "div",
2906
3310
  {
2907
- css: [styles5.item, isSelected && styles5.itemSelected],
3311
+ css: [styles6.item, isSelected && styles6.itemSelected],
2908
3312
  onClick,
2909
3313
  children: [
2910
- /* @__PURE__ */ jsx5(
3314
+ /* @__PURE__ */ jsx6(
2911
3315
  "div",
2912
3316
  {
2913
- css: styles5.checkboxWrapper,
3317
+ css: styles6.checkboxWrapper,
2914
3318
  onClick: (e) => e.stopPropagation(),
2915
- children: /* @__PURE__ */ jsx5(
3319
+ children: /* @__PURE__ */ jsx6(
2916
3320
  "input",
2917
3321
  {
2918
3322
  type: "checkbox",
2919
- css: styles5.checkbox,
3323
+ css: styles6.checkbox,
2920
3324
  checked: isSelected,
2921
3325
  onChange: () => onClick({})
2922
3326
  }
2923
3327
  )
2924
3328
  }
2925
3329
  ),
2926
- item.cdnPushed && /* @__PURE__ */ jsx5("span", { css: styles5.cdnBadge, children: "CDN" }),
2927
- /* @__PURE__ */ jsxs5("div", { css: styles5.content, children: [
2928
- /* @__PURE__ */ jsxs5(
3330
+ item.cdnPushed && /* @__PURE__ */ jsx6("span", { css: styles6.cdnBadge, children: "CDN" }),
3331
+ /* @__PURE__ */ jsxs6("div", { css: styles6.content, children: [
3332
+ /* @__PURE__ */ jsxs6(
2929
3333
  "button",
2930
3334
  {
2931
- css: styles5.copyBtn,
3335
+ css: styles6.copyBtn,
2932
3336
  onClick: handleCopyPath,
2933
3337
  title: "Copy file path",
2934
3338
  children: [
2935
- showCopied && /* @__PURE__ */ jsx5("span", { css: styles5.tooltip, children: "Copied!" }),
2936
- /* @__PURE__ */ jsx5("svg", { css: styles5.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" }) })
3339
+ showCopied && /* @__PURE__ */ jsx6("span", { css: styles6.tooltip, children: "Copied!" }),
3340
+ /* @__PURE__ */ jsx6("svg", { css: styles6.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" }) })
2937
3341
  ]
2938
3342
  }
2939
3343
  ),
2940
- /* @__PURE__ */ jsx5(
3344
+ /* @__PURE__ */ jsx6(
2941
3345
  "button",
2942
3346
  {
2943
- css: styles5.openBtn,
3347
+ css: styles6.openBtn,
2944
3348
  onClick: (e) => {
2945
3349
  e.stopPropagation();
2946
3350
  onOpen();
@@ -2948,40 +3352,40 @@ function GridItem({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
2948
3352
  children: "Open"
2949
3353
  }
2950
3354
  ),
2951
- isFolder ? isImagesFolder ? /* @__PURE__ */ jsxs5("div", { css: styles5.imagesFolderWrapper, children: [
2952
- /* @__PURE__ */ jsx5("svg", { css: styles5.imagesFolderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("path", { d: "M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z" }) }),
2953
- /* @__PURE__ */ jsx5("svg", { css: styles5.lockIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx5("path", { fillRule: "evenodd", d: "M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z", clipRule: "evenodd" }) })
2954
- ] }) : /* @__PURE__ */ jsx5("svg", { css: styles5.folderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("path", { d: "M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z" }) }) : isImage && item.hasThumbnail ? /* @__PURE__ */ jsx5(
3355
+ isFolder ? isImagesFolder ? /* @__PURE__ */ jsxs6("div", { css: styles6.imagesFolderWrapper, children: [
3356
+ /* @__PURE__ */ jsx6("svg", { css: styles6.imagesFolderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6("path", { d: "M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z" }) }),
3357
+ /* @__PURE__ */ jsx6("svg", { css: styles6.lockIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx6("path", { fillRule: "evenodd", d: "M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z", clipRule: "evenodd" }) })
3358
+ ] }) : /* @__PURE__ */ jsx6("svg", { css: styles6.folderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6("path", { d: "M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z" }) }) : isImage && item.hasThumbnail ? /* @__PURE__ */ jsx6(
2955
3359
  "img",
2956
3360
  {
2957
- css: styles5.image,
3361
+ css: styles6.image,
2958
3362
  src: item.thumbnail,
2959
3363
  alt: item.name,
2960
3364
  loading: "lazy"
2961
3365
  }
2962
- ) : isImage && !item.hasThumbnail ? /* @__PURE__ */ jsxs5(
3366
+ ) : isImage && !item.hasThumbnail ? /* @__PURE__ */ jsxs6(
2963
3367
  "button",
2964
3368
  {
2965
- css: styles5.noThumbnail,
3369
+ css: styles6.noThumbnail,
2966
3370
  onClick: (e) => {
2967
3371
  e.stopPropagation();
2968
3372
  onGenerateThumbnail();
2969
3373
  },
2970
3374
  title: "Generate thumbnail",
2971
3375
  children: [
2972
- /* @__PURE__ */ jsx5("svg", { css: styles5.noThumbnailIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) }),
2973
- /* @__PURE__ */ jsx5("span", { css: styles5.noThumbnailText, children: "Generate" })
3376
+ /* @__PURE__ */ jsx6("svg", { css: styles6.noThumbnailIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) }),
3377
+ /* @__PURE__ */ jsx6("span", { css: styles6.noThumbnailText, children: "Generate" })
2974
3378
  ]
2975
3379
  }
2976
- ) : /* @__PURE__ */ jsx5("svg", { css: styles5.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) })
3380
+ ) : /* @__PURE__ */ jsx6("svg", { css: styles6.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) })
2977
3381
  ] }),
2978
- /* @__PURE__ */ jsx5("div", { css: styles5.label, children: /* @__PURE__ */ jsx5("div", { css: styles5.labelRow, children: /* @__PURE__ */ jsxs5("div", { css: styles5.labelText, children: [
2979
- /* @__PURE__ */ jsx5("p", { css: styles5.name, title: item.name, children: truncateMiddle(item.name) }),
2980
- isFolder ? /* @__PURE__ */ jsxs5("p", { css: styles5.size, children: [
3382
+ /* @__PURE__ */ jsx6("div", { css: styles6.label, children: /* @__PURE__ */ jsx6("div", { css: styles6.labelRow, children: /* @__PURE__ */ jsxs6("div", { css: styles6.labelText, children: [
3383
+ /* @__PURE__ */ jsx6("p", { css: styles6.name, title: item.name, children: truncateMiddle(item.name) }),
3384
+ isFolder ? /* @__PURE__ */ jsxs6("p", { css: styles6.size, children: [
2981
3385
  item.fileCount !== void 0 ? `${item.fileCount} files` : "",
2982
3386
  item.fileCount !== void 0 && item.totalSize !== void 0 ? " \xB7 " : "",
2983
3387
  item.totalSize !== void 0 ? formatFileSize(item.totalSize) : ""
2984
- ] }) : item.size !== void 0 && /* @__PURE__ */ jsx5("p", { css: styles5.size, children: formatFileSize(item.size) })
3388
+ ] }) : item.size !== void 0 && /* @__PURE__ */ jsx6("p", { css: styles6.size, children: formatFileSize(item.size) })
2985
3389
  ] }) }) })
2986
3390
  ]
2987
3391
  }
@@ -3007,21 +3411,21 @@ function truncateMiddle(str, maxLength = 24) {
3007
3411
  }
3008
3412
 
3009
3413
  // src/components/StudioFileList.tsx
3010
- import { useState as useState6 } from "react";
3011
- import { css as css6, keyframes as keyframes5 } from "@emotion/react";
3012
- import { jsx as jsx6, jsxs as jsxs6 } from "@emotion/react/jsx-runtime";
3013
- var spin3 = keyframes5`
3414
+ import { useState as useState7 } from "react";
3415
+ import { css as css7, keyframes as keyframes6 } from "@emotion/react";
3416
+ import { jsx as jsx7, jsxs as jsxs7 } from "@emotion/react/jsx-runtime";
3417
+ var spin3 = keyframes6`
3014
3418
  to { transform: rotate(360deg); }
3015
3419
  `;
3016
- var styles6 = {
3017
- loading: css6`
3420
+ var styles7 = {
3421
+ loading: css7`
3018
3422
  display: flex;
3019
3423
  align-items: center;
3020
3424
  justify-content: center;
3021
3425
  flex: 1;
3022
3426
  min-height: 300px;
3023
3427
  `,
3024
- spinner: css6`
3428
+ spinner: css7`
3025
3429
  width: 32px;
3026
3430
  height: 32px;
3027
3431
  border-radius: 50%;
@@ -3029,7 +3433,7 @@ var styles6 = {
3029
3433
  border-top-color: ${colors.primary};
3030
3434
  animation: ${spin3} 0.8s linear infinite;
3031
3435
  `,
3032
- empty: css6`
3436
+ empty: css7`
3033
3437
  display: flex;
3034
3438
  flex-direction: column;
3035
3439
  align-items: center;
@@ -3038,12 +3442,12 @@ var styles6 = {
3038
3442
  min-height: 300px;
3039
3443
  color: ${colors.textSecondary};
3040
3444
  `,
3041
- emptyHint: css6`
3445
+ emptyHint: css7`
3042
3446
  font-size: ${fontSize.sm};
3043
3447
  color: ${colors.textMuted};
3044
3448
  margin-top: 4px;
3045
3449
  `,
3046
- scanButton: css6`
3450
+ scanButton: css7`
3047
3451
  margin-top: 16px;
3048
3452
  padding: 10px 24px;
3049
3453
  font-size: ${fontSize.base};
@@ -3064,19 +3468,19 @@ var styles6 = {
3064
3468
  cursor: not-allowed;
3065
3469
  }
3066
3470
  `,
3067
- tableWrapper: css6`
3471
+ tableWrapper: css7`
3068
3472
  background: ${colors.surface};
3069
3473
  border-radius: 8px;
3070
3474
  border: 1px solid ${colors.border};
3071
3475
  overflow-x: auto;
3072
3476
  `,
3073
- table: css6`
3477
+ table: css7`
3074
3478
  width: 100%;
3075
3479
  min-width: 600px;
3076
3480
  border-collapse: collapse;
3077
3481
  white-space: nowrap;
3078
3482
  `,
3079
- th: css6`
3483
+ th: css7`
3080
3484
  text-align: left;
3081
3485
  font-size: 11px;
3082
3486
  color: ${colors.textMuted};
@@ -3087,20 +3491,20 @@ var styles6 = {
3087
3491
  background: ${colors.background};
3088
3492
  border-bottom: 1px solid ${colors.border};
3089
3493
  `,
3090
- thCheckbox: css6`
3494
+ thCheckbox: css7`
3091
3495
  width: 48px;
3092
3496
  `,
3093
- thSize: css6`
3497
+ thSize: css7`
3094
3498
  width: 96px;
3095
3499
  `,
3096
- thDimensions: css6`
3500
+ thDimensions: css7`
3097
3501
  width: 128px;
3098
3502
  `,
3099
- thCdn: css6`
3503
+ thCdn: css7`
3100
3504
  width: 96px;
3101
3505
  `,
3102
- tbody: css6``,
3103
- row: css6`
3506
+ tbody: css7``,
3507
+ row: css7`
3104
3508
  cursor: pointer;
3105
3509
  transition: background-color 0.15s ease;
3106
3510
  user-select: none;
@@ -3113,14 +3517,14 @@ var styles6 = {
3113
3517
  border-bottom: 1px solid ${colors.borderLight};
3114
3518
  }
3115
3519
  `,
3116
- rowSelected: css6`
3520
+ rowSelected: css7`
3117
3521
  background-color: ${colors.primaryLight};
3118
3522
 
3119
3523
  &:hover {
3120
3524
  background-color: ${colors.primaryLight};
3121
3525
  }
3122
3526
  `,
3123
- parentRow: css6`
3527
+ parentRow: css7`
3124
3528
  cursor: pointer;
3125
3529
  border-bottom: 1px solid ${colors.border};
3126
3530
 
@@ -3128,22 +3532,22 @@ var styles6 = {
3128
3532
  background-color: ${colors.surfaceHover};
3129
3533
  }
3130
3534
  `,
3131
- td: css6`
3535
+ td: css7`
3132
3536
  padding: 12px 16px;
3133
3537
  `,
3134
- checkboxCell: css6`
3538
+ checkboxCell: css7`
3135
3539
  padding: 12px 16px;
3136
3540
  cursor: pointer;
3137
3541
  vertical-align: middle;
3138
3542
  `,
3139
- checkbox: css6`
3543
+ checkbox: css7`
3140
3544
  width: 18px;
3141
3545
  height: 18px;
3142
3546
  accent-color: ${colors.primary};
3143
3547
  cursor: pointer;
3144
3548
  display: block;
3145
3549
  `,
3146
- actionsCell: css6`
3550
+ actionsCell: css7`
3147
3551
  display: flex;
3148
3552
  align-items: center;
3149
3553
  justify-content: flex-end;
@@ -3151,7 +3555,7 @@ var styles6 = {
3151
3555
  margin-left: auto;
3152
3556
  flex-shrink: 0;
3153
3557
  `,
3154
- copyBtn: css6`
3558
+ copyBtn: css7`
3155
3559
  position: relative;
3156
3560
  flex-shrink: 0;
3157
3561
  height: 32px;
@@ -3174,11 +3578,11 @@ var styles6 = {
3174
3578
  color: ${colors.text};
3175
3579
  }
3176
3580
  `,
3177
- copyIcon: css6`
3581
+ copyIcon: css7`
3178
3582
  width: 16px;
3179
3583
  height: 16px;
3180
3584
  `,
3181
- tooltip: css6`
3585
+ tooltip: css7`
3182
3586
  position: absolute;
3183
3587
  top: 50%;
3184
3588
  right: 100%;
@@ -3203,13 +3607,13 @@ var styles6 = {
3203
3607
  border-left-color: #1a1f36;
3204
3608
  }
3205
3609
  `,
3206
- nameCell: css6`
3610
+ nameCell: css7`
3207
3611
  display: flex;
3208
3612
  align-items: center;
3209
3613
  gap: 12px;
3210
3614
  flex: 1;
3211
3615
  `,
3212
- thumbnailWrapper: css6`
3616
+ thumbnailWrapper: css7`
3213
3617
  width: 48px;
3214
3618
  height: 36px;
3215
3619
  display: flex;
@@ -3217,7 +3621,7 @@ var styles6 = {
3217
3621
  justify-content: center;
3218
3622
  flex-shrink: 0;
3219
3623
  `,
3220
- folderIconWrapper: css6`
3624
+ folderIconWrapper: css7`
3221
3625
  width: 48px;
3222
3626
  height: 36px;
3223
3627
  display: flex;
@@ -3225,12 +3629,12 @@ var styles6 = {
3225
3629
  justify-content: center;
3226
3630
  flex-shrink: 0;
3227
3631
  `,
3228
- folderIcon: css6`
3632
+ folderIcon: css7`
3229
3633
  width: 24px;
3230
3634
  height: 24px;
3231
3635
  color: #f9935e;
3232
3636
  `,
3233
- imagesFolderWrapper: css6`
3637
+ imagesFolderWrapper: css7`
3234
3638
  width: 48px;
3235
3639
  height: 36px;
3236
3640
  display: flex;
@@ -3240,31 +3644,31 @@ var styles6 = {
3240
3644
  position: relative;
3241
3645
  align-items: center;
3242
3646
  `,
3243
- imagesFolderIcon: css6`
3647
+ imagesFolderIcon: css7`
3244
3648
  width: 24px;
3245
3649
  height: 24px;
3246
3650
  color: ${colors.imagesFolder};
3247
3651
  `,
3248
- lockIcon: css6`
3652
+ lockIcon: css7`
3249
3653
  width: 10px;
3250
3654
  height: 10px;
3251
3655
  color: ${colors.imagesFolder};
3252
3656
  margin-left: -6px;
3253
3657
  margin-top: 8px;
3254
3658
  `,
3255
- parentIcon: css6`
3659
+ parentIcon: css7`
3256
3660
  width: 20px;
3257
3661
  height: 20px;
3258
3662
  color: ${colors.textMuted};
3259
3663
  flex-shrink: 0;
3260
3664
  `,
3261
- fileIcon: css6`
3665
+ fileIcon: css7`
3262
3666
  width: 20px;
3263
3667
  height: 20px;
3264
3668
  color: ${colors.textMuted};
3265
3669
  flex-shrink: 0;
3266
3670
  `,
3267
- thumbnail: css6`
3671
+ thumbnail: css7`
3268
3672
  max-width: 100%;
3269
3673
  max-height: 100%;
3270
3674
  width: auto;
@@ -3273,7 +3677,7 @@ var styles6 = {
3273
3677
  border-radius: 4px;
3274
3678
  border: 1px solid ${colors.borderLight};
3275
3679
  `,
3276
- noThumbnail: css6`
3680
+ noThumbnail: css7`
3277
3681
  width: 36px;
3278
3682
  height: 36px;
3279
3683
  display: flex;
@@ -3291,12 +3695,12 @@ var styles6 = {
3291
3695
  background: ${colors.surfaceHover};
3292
3696
  }
3293
3697
  `,
3294
- noThumbnailIcon: css6`
3698
+ noThumbnailIcon: css7`
3295
3699
  width: 16px;
3296
3700
  height: 16px;
3297
3701
  color: ${colors.textMuted};
3298
3702
  `,
3299
- name: css6`
3703
+ name: css7`
3300
3704
  font-size: ${fontSize.base};
3301
3705
  font-weight: 500;
3302
3706
  color: ${colors.text};
@@ -3306,11 +3710,11 @@ var styles6 = {
3306
3710
  white-space: nowrap;
3307
3711
  max-width: 300px;
3308
3712
  `,
3309
- meta: css6`
3713
+ meta: css7`
3310
3714
  font-size: ${fontSize.sm};
3311
3715
  color: ${colors.textSecondary};
3312
3716
  `,
3313
- cdnBadge: css6`
3717
+ cdnBadge: css7`
3314
3718
  display: inline-flex;
3315
3719
  align-items: center;
3316
3720
  gap: 4px;
@@ -3318,15 +3722,15 @@ var styles6 = {
3318
3722
  font-weight: 500;
3319
3723
  color: ${colors.success};
3320
3724
  `,
3321
- cdnIcon: css6`
3725
+ cdnIcon: css7`
3322
3726
  width: 12px;
3323
3727
  height: 12px;
3324
3728
  `,
3325
- cdnEmpty: css6`
3729
+ cdnEmpty: css7`
3326
3730
  font-size: ${fontSize.sm};
3327
3731
  color: ${colors.textMuted};
3328
3732
  `,
3329
- openBtn: css6`
3733
+ openBtn: css7`
3330
3734
  height: 32px;
3331
3735
  font-size: ${fontSize.sm};
3332
3736
  font-weight: 500;
@@ -3364,16 +3768,16 @@ function StudioFileList() {
3364
3768
  triggerScan
3365
3769
  } = useFileList();
3366
3770
  if (loading) {
3367
- return /* @__PURE__ */ jsx6("div", { css: styles6.loading, children: /* @__PURE__ */ jsx6("div", { css: styles6.spinner }) });
3771
+ return /* @__PURE__ */ jsx7("div", { css: styles7.loading, children: /* @__PURE__ */ jsx7("div", { css: styles7.spinner }) });
3368
3772
  }
3369
3773
  if (metaEmpty && isAtRoot) {
3370
- return /* @__PURE__ */ jsxs6("div", { css: styles6.empty, children: [
3371
- /* @__PURE__ */ jsx6("p", { children: "No files tracked yet" }),
3372
- /* @__PURE__ */ jsx6("p", { css: styles6.emptyHint, children: "Click Scan to discover files in your public folder" }),
3373
- /* @__PURE__ */ jsx6(
3774
+ return /* @__PURE__ */ jsxs7("div", { css: styles7.empty, children: [
3775
+ /* @__PURE__ */ jsx7("p", { children: "No files tracked yet" }),
3776
+ /* @__PURE__ */ jsx7("p", { css: styles7.emptyHint, children: "Click Scan to discover files in your public folder" }),
3777
+ /* @__PURE__ */ jsx7(
3374
3778
  "button",
3375
3779
  {
3376
- css: styles6.scanButton,
3780
+ css: styles7.scanButton,
3377
3781
  onClick: triggerScan,
3378
3782
  children: "Scan for Files"
3379
3783
  }
@@ -3381,18 +3785,18 @@ function StudioFileList() {
3381
3785
  ] });
3382
3786
  }
3383
3787
  if (sortedItems.length === 0 && isAtRoot) {
3384
- return /* @__PURE__ */ jsxs6("div", { css: styles6.empty, children: [
3385
- /* @__PURE__ */ jsx6("p", { children: "No files in this folder" }),
3386
- /* @__PURE__ */ jsx6("p", { css: styles6.emptyHint, children: "Upload images or click Scan in the toolbar" })
3788
+ return /* @__PURE__ */ jsxs7("div", { css: styles7.empty, children: [
3789
+ /* @__PURE__ */ jsx7("p", { children: "No files in this folder" }),
3790
+ /* @__PURE__ */ jsx7("p", { css: styles7.emptyHint, children: "Upload images or click Scan in the toolbar" })
3387
3791
  ] });
3388
3792
  }
3389
- return /* @__PURE__ */ jsx6("div", { css: styles6.tableWrapper, children: /* @__PURE__ */ jsxs6("table", { css: styles6.table, children: [
3390
- /* @__PURE__ */ jsx6("thead", { children: /* @__PURE__ */ jsxs6("tr", { children: [
3391
- /* @__PURE__ */ jsx6("th", { css: [styles6.th, styles6.thCheckbox], children: sortedItems.length > 0 && /* @__PURE__ */ jsx6(
3793
+ return /* @__PURE__ */ jsx7("div", { css: styles7.tableWrapper, children: /* @__PURE__ */ jsxs7("table", { css: styles7.table, children: [
3794
+ /* @__PURE__ */ jsx7("thead", { children: /* @__PURE__ */ jsxs7("tr", { children: [
3795
+ /* @__PURE__ */ jsx7("th", { css: [styles7.th, styles7.thCheckbox], children: sortedItems.length > 0 && /* @__PURE__ */ jsx7(
3392
3796
  "input",
3393
3797
  {
3394
3798
  type: "checkbox",
3395
- css: styles6.checkbox,
3799
+ css: styles7.checkbox,
3396
3800
  checked: allItemsSelected,
3397
3801
  ref: (el) => {
3398
3802
  if (el) el.indeterminate = someItemsSelected && !allItemsSelected;
@@ -3400,23 +3804,23 @@ function StudioFileList() {
3400
3804
  onChange: handleSelectAll
3401
3805
  }
3402
3806
  ) }),
3403
- /* @__PURE__ */ jsx6("th", { css: styles6.th, children: "Name" }),
3404
- /* @__PURE__ */ jsx6("th", { css: [styles6.th, styles6.thSize], children: "Size" }),
3405
- /* @__PURE__ */ jsx6("th", { css: [styles6.th, styles6.thDimensions], children: "Dimensions" }),
3406
- /* @__PURE__ */ jsx6("th", { css: [styles6.th, styles6.thCdn], children: "CDN" })
3807
+ /* @__PURE__ */ jsx7("th", { css: styles7.th, children: "Name" }),
3808
+ /* @__PURE__ */ jsx7("th", { css: [styles7.th, styles7.thSize], children: "Size" }),
3809
+ /* @__PURE__ */ jsx7("th", { css: [styles7.th, styles7.thDimensions], children: "Dimensions" }),
3810
+ /* @__PURE__ */ jsx7("th", { css: [styles7.th, styles7.thCdn], children: "CDN" })
3407
3811
  ] }) }),
3408
- /* @__PURE__ */ jsxs6("tbody", { css: styles6.tbody, children: [
3409
- !isAtRoot && !isSearching && /* @__PURE__ */ jsxs6("tr", { css: styles6.parentRow, onClick: navigateUp, children: [
3410
- /* @__PURE__ */ jsx6("td", { css: styles6.td }),
3411
- /* @__PURE__ */ jsx6("td", { css: styles6.td, children: /* @__PURE__ */ jsxs6("div", { css: styles6.nameCell, children: [
3412
- /* @__PURE__ */ jsx6("svg", { css: styles6.parentIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" }) }),
3413
- /* @__PURE__ */ jsx6("span", { css: styles6.name, children: ".." })
3812
+ /* @__PURE__ */ jsxs7("tbody", { css: styles7.tbody, children: [
3813
+ !isAtRoot && !isSearching && /* @__PURE__ */ jsxs7("tr", { css: styles7.parentRow, onClick: navigateUp, children: [
3814
+ /* @__PURE__ */ jsx7("td", { css: styles7.td }),
3815
+ /* @__PURE__ */ jsx7("td", { css: styles7.td, children: /* @__PURE__ */ jsxs7("div", { css: styles7.nameCell, children: [
3816
+ /* @__PURE__ */ jsx7("svg", { css: styles7.parentIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" }) }),
3817
+ /* @__PURE__ */ jsx7("span", { css: styles7.name, children: ".." })
3414
3818
  ] }) }),
3415
- /* @__PURE__ */ jsx6("td", { css: [styles6.td, styles6.meta], children: "--" }),
3416
- /* @__PURE__ */ jsx6("td", { css: [styles6.td, styles6.meta], children: "Parent folder" }),
3417
- /* @__PURE__ */ jsx6("td", { css: styles6.td, children: "--" })
3819
+ /* @__PURE__ */ jsx7("td", { css: [styles7.td, styles7.meta], children: "--" }),
3820
+ /* @__PURE__ */ jsx7("td", { css: [styles7.td, styles7.meta], children: "Parent folder" }),
3821
+ /* @__PURE__ */ jsx7("td", { css: styles7.td, children: "--" })
3418
3822
  ] }),
3419
- sortedItems.map((item) => /* @__PURE__ */ jsx6(
3823
+ sortedItems.map((item) => /* @__PURE__ */ jsx7(
3420
3824
  ListRow,
3421
3825
  {
3422
3826
  item,
@@ -3431,7 +3835,7 @@ function StudioFileList() {
3431
3835
  ] }) });
3432
3836
  }
3433
3837
  function ListRow({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
3434
- const [showCopied, setShowCopied] = useState6(false);
3838
+ const [showCopied, setShowCopied] = useState7(false);
3435
3839
  const isFolder = item.type === "folder";
3436
3840
  const isImage = !isFolder && item.thumbnail !== void 0;
3437
3841
  const isImagesFolder = isFolder && (item.name === "images" || item.path.includes("/images/"));
@@ -3442,62 +3846,62 @@ function ListRow({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
3442
3846
  setShowCopied(true);
3443
3847
  setTimeout(() => setShowCopied(false), 1500);
3444
3848
  };
3445
- return /* @__PURE__ */ jsxs6(
3849
+ return /* @__PURE__ */ jsxs7(
3446
3850
  "tr",
3447
3851
  {
3448
- css: [styles6.row, isSelected && styles6.rowSelected],
3852
+ css: [styles7.row, isSelected && styles7.rowSelected],
3449
3853
  onClick,
3450
3854
  children: [
3451
- /* @__PURE__ */ jsx6(
3855
+ /* @__PURE__ */ jsx7(
3452
3856
  "td",
3453
3857
  {
3454
- css: [styles6.td, styles6.checkboxCell],
3858
+ css: [styles7.td, styles7.checkboxCell],
3455
3859
  onClick: (e) => e.stopPropagation(),
3456
- children: /* @__PURE__ */ jsx6(
3860
+ children: /* @__PURE__ */ jsx7(
3457
3861
  "input",
3458
3862
  {
3459
3863
  type: "checkbox",
3460
- css: styles6.checkbox,
3864
+ css: styles7.checkbox,
3461
3865
  checked: isSelected,
3462
3866
  onChange: () => onClick({})
3463
3867
  }
3464
3868
  )
3465
3869
  }
3466
3870
  ),
3467
- /* @__PURE__ */ jsx6("td", { css: styles6.td, children: /* @__PURE__ */ jsxs6("div", { css: styles6.nameCell, children: [
3468
- isFolder ? isImagesFolder ? /* @__PURE__ */ jsxs6("div", { css: styles6.imagesFolderWrapper, children: [
3469
- /* @__PURE__ */ jsx6("svg", { css: styles6.imagesFolderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6("path", { d: "M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z" }) }),
3470
- /* @__PURE__ */ jsx6("svg", { css: styles6.lockIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx6("path", { fillRule: "evenodd", d: "M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z", clipRule: "evenodd" }) })
3471
- ] }) : /* @__PURE__ */ jsx6("div", { css: styles6.folderIconWrapper, children: /* @__PURE__ */ jsx6("svg", { css: styles6.folderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6("path", { d: "M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z" }) }) }) : isImage && item.hasThumbnail ? /* @__PURE__ */ jsx6("div", { css: styles6.thumbnailWrapper, children: /* @__PURE__ */ jsx6("img", { css: styles6.thumbnail, src: item.thumbnail, alt: item.name, loading: "lazy" }) }) : isImage && !item.hasThumbnail ? /* @__PURE__ */ jsx6("div", { css: styles6.thumbnailWrapper, children: /* @__PURE__ */ jsx6(
3871
+ /* @__PURE__ */ jsx7("td", { css: styles7.td, children: /* @__PURE__ */ jsxs7("div", { css: styles7.nameCell, children: [
3872
+ isFolder ? isImagesFolder ? /* @__PURE__ */ jsxs7("div", { css: styles7.imagesFolderWrapper, children: [
3873
+ /* @__PURE__ */ jsx7("svg", { css: styles7.imagesFolderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7("path", { d: "M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z" }) }),
3874
+ /* @__PURE__ */ jsx7("svg", { css: styles7.lockIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx7("path", { fillRule: "evenodd", d: "M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z", clipRule: "evenodd" }) })
3875
+ ] }) : /* @__PURE__ */ jsx7("div", { css: styles7.folderIconWrapper, children: /* @__PURE__ */ jsx7("svg", { css: styles7.folderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7("path", { d: "M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z" }) }) }) : isImage && item.hasThumbnail ? /* @__PURE__ */ jsx7("div", { css: styles7.thumbnailWrapper, children: /* @__PURE__ */ jsx7("img", { css: styles7.thumbnail, src: item.thumbnail, alt: item.name, loading: "lazy" }) }) : isImage && !item.hasThumbnail ? /* @__PURE__ */ jsx7("div", { css: styles7.thumbnailWrapper, children: /* @__PURE__ */ jsx7(
3472
3876
  "button",
3473
3877
  {
3474
- css: styles6.noThumbnail,
3878
+ css: styles7.noThumbnail,
3475
3879
  onClick: (e) => {
3476
3880
  e.stopPropagation();
3477
3881
  onGenerateThumbnail();
3478
3882
  },
3479
3883
  title: "Generate thumbnail",
3480
- children: /* @__PURE__ */ jsx6("svg", { css: styles6.noThumbnailIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) })
3884
+ children: /* @__PURE__ */ jsx7("svg", { css: styles7.noThumbnailIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) })
3481
3885
  }
3482
- ) }) : /* @__PURE__ */ jsx6("div", { css: styles6.thumbnailWrapper, children: /* @__PURE__ */ jsx6("svg", { css: styles6.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) }) }),
3483
- /* @__PURE__ */ jsx6("span", { css: styles6.name, title: item.name, children: truncateMiddle2(item.name) }),
3484
- /* @__PURE__ */ jsxs6("div", { css: styles6.actionsCell, children: [
3485
- /* @__PURE__ */ jsxs6(
3886
+ ) }) : /* @__PURE__ */ jsx7("div", { css: styles7.thumbnailWrapper, children: /* @__PURE__ */ jsx7("svg", { css: styles7.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) }) }),
3887
+ /* @__PURE__ */ jsx7("span", { css: styles7.name, title: item.name, children: truncateMiddle2(item.name) }),
3888
+ /* @__PURE__ */ jsxs7("div", { css: styles7.actionsCell, children: [
3889
+ /* @__PURE__ */ jsxs7(
3486
3890
  "button",
3487
3891
  {
3488
- css: styles6.copyBtn,
3892
+ css: styles7.copyBtn,
3489
3893
  onClick: handleCopyPath,
3490
3894
  title: "Copy file path",
3491
3895
  children: [
3492
- showCopied && /* @__PURE__ */ jsx6("span", { css: styles6.tooltip, children: "Copied!" }),
3493
- /* @__PURE__ */ jsx6("svg", { css: styles6.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" }) })
3896
+ showCopied && /* @__PURE__ */ jsx7("span", { css: styles7.tooltip, children: "Copied!" }),
3897
+ /* @__PURE__ */ jsx7("svg", { css: styles7.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" }) })
3494
3898
  ]
3495
3899
  }
3496
3900
  ),
3497
- /* @__PURE__ */ jsx6(
3901
+ /* @__PURE__ */ jsx7(
3498
3902
  "button",
3499
3903
  {
3500
- css: styles6.openBtn,
3904
+ css: styles7.openBtn,
3501
3905
  onClick: (e) => {
3502
3906
  e.stopPropagation();
3503
3907
  onOpen();
@@ -3507,12 +3911,12 @@ function ListRow({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
3507
3911
  )
3508
3912
  ] })
3509
3913
  ] }) }),
3510
- /* @__PURE__ */ jsx6("td", { css: [styles6.td, styles6.meta], children: isFolder ? item.fileCount !== void 0 ? `${item.fileCount} files` : "--" : item.size !== void 0 ? formatFileSize2(item.size) : "--" }),
3511
- /* @__PURE__ */ jsx6("td", { css: [styles6.td, styles6.meta], children: isFolder ? item.totalSize !== void 0 ? formatFileSize2(item.totalSize) : "--" : item.dimensions ? `${item.dimensions.width}x${item.dimensions.height}` : "--" }),
3512
- /* @__PURE__ */ jsx6("td", { css: styles6.td, children: item.cdnPushed ? /* @__PURE__ */ jsxs6("span", { css: styles6.cdnBadge, children: [
3513
- /* @__PURE__ */ jsx6("svg", { css: styles6.cdnIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx6("path", { fillRule: "evenodd", d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z", clipRule: "evenodd" }) }),
3914
+ /* @__PURE__ */ jsx7("td", { css: [styles7.td, styles7.meta], children: isFolder ? item.fileCount !== void 0 ? `${item.fileCount} files` : "--" : item.size !== void 0 ? formatFileSize2(item.size) : "--" }),
3915
+ /* @__PURE__ */ jsx7("td", { css: [styles7.td, styles7.meta], children: isFolder ? item.totalSize !== void 0 ? formatFileSize2(item.totalSize) : "--" : item.dimensions ? `${item.dimensions.width}x${item.dimensions.height}` : "--" }),
3916
+ /* @__PURE__ */ jsx7("td", { css: styles7.td, children: item.cdnPushed ? /* @__PURE__ */ jsxs7("span", { css: styles7.cdnBadge, children: [
3917
+ /* @__PURE__ */ jsx7("svg", { css: styles7.cdnIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx7("path", { fillRule: "evenodd", d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z", clipRule: "evenodd" }) }),
3514
3918
  "Synced"
3515
- ] }) : /* @__PURE__ */ jsx6("span", { css: styles6.cdnEmpty, children: "--" }) })
3919
+ ] }) : /* @__PURE__ */ jsx7("span", { css: styles7.cdnEmpty, children: "--" }) })
3516
3920
  ]
3517
3921
  }
3518
3922
  );
@@ -3537,9 +3941,9 @@ function truncateMiddle2(str, maxLength = 32) {
3537
3941
  }
3538
3942
 
3539
3943
  // src/components/StudioDetailView.tsx
3540
- import { useState as useState7 } from "react";
3541
- import { css as css7 } from "@emotion/react";
3542
- import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs7 } from "@emotion/react/jsx-runtime";
3944
+ import { useState as useState8 } from "react";
3945
+ import { css as css8 } from "@emotion/react";
3946
+ import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs8 } from "@emotion/react/jsx-runtime";
3543
3947
  var IMAGE_EXTENSIONS = [".jpg", ".jpeg", ".png", ".gif", ".webp", ".svg", ".ico", ".bmp", ".tiff", ".tif"];
3544
3948
  var VIDEO_EXTENSIONS = [".mp4", ".webm", ".mov", ".avi", ".mkv", ".m4v"];
3545
3949
  function isImageFile(filename) {
@@ -3550,8 +3954,8 @@ function isVideoFile(filename) {
3550
3954
  const ext = filename.toLowerCase().substring(filename.lastIndexOf("."));
3551
3955
  return VIDEO_EXTENSIONS.includes(ext);
3552
3956
  }
3553
- var styles7 = {
3554
- overlay: css7`
3957
+ var styles8 = {
3958
+ overlay: css8`
3555
3959
  position: absolute;
3556
3960
  top: 0;
3557
3961
  left: 0;
@@ -3561,7 +3965,7 @@ var styles7 = {
3561
3965
  display: flex;
3562
3966
  background: transparent;
3563
3967
  `,
3564
- container: css7`
3968
+ container: css8`
3565
3969
  display: flex;
3566
3970
  flex: 1;
3567
3971
  margin: 24px;
@@ -3571,7 +3975,7 @@ var styles7 = {
3571
3975
  overflow: hidden;
3572
3976
  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2);
3573
3977
  `,
3574
- main: css7`
3978
+ main: css8`
3575
3979
  position: relative;
3576
3980
  flex: 1;
3577
3981
  display: flex;
@@ -3582,7 +3986,7 @@ var styles7 = {
3582
3986
  background: ${colors.background};
3583
3987
  overflow: auto;
3584
3988
  `,
3585
- headerButtons: css7`
3989
+ headerButtons: css8`
3586
3990
  position: absolute;
3587
3991
  top: 16px;
3588
3992
  right: 16px;
@@ -3590,7 +3994,7 @@ var styles7 = {
3590
3994
  gap: 8px;
3591
3995
  z-index: 10;
3592
3996
  `,
3593
- copyBtn: css7`
3997
+ copyBtn: css8`
3594
3998
  position: relative;
3595
3999
  padding: 8px;
3596
4000
  background: ${colors.surface};
@@ -3608,12 +4012,12 @@ var styles7 = {
3608
4012
  border-color: ${colors.borderHover};
3609
4013
  }
3610
4014
  `,
3611
- copyIcon: css7`
4015
+ copyIcon: css8`
3612
4016
  width: 20px;
3613
4017
  height: 20px;
3614
4018
  color: ${colors.textSecondary};
3615
4019
  `,
3616
- tooltip: css7`
4020
+ tooltip: css8`
3617
4021
  position: absolute;
3618
4022
  right: 100%;
3619
4023
  top: 50%;
@@ -3638,7 +4042,7 @@ var styles7 = {
3638
4042
  border-left-color: #1a1f36;
3639
4043
  }
3640
4044
  `,
3641
- mainCloseBtn: css7`
4045
+ mainCloseBtn: css8`
3642
4046
  padding: 8px;
3643
4047
  background: ${colors.surface};
3644
4048
  border: 1px solid ${colors.border};
@@ -3655,32 +4059,32 @@ var styles7 = {
3655
4059
  border-color: ${colors.borderHover};
3656
4060
  }
3657
4061
  `,
3658
- mainCloseIcon: css7`
4062
+ mainCloseIcon: css8`
3659
4063
  width: 20px;
3660
4064
  height: 20px;
3661
4065
  color: ${colors.textSecondary};
3662
4066
  `,
3663
- mediaWrapper: css7`
4067
+ mediaWrapper: css8`
3664
4068
  max-width: 100%;
3665
4069
  max-height: 100%;
3666
4070
  display: flex;
3667
4071
  align-items: center;
3668
4072
  justify-content: center;
3669
4073
  `,
3670
- image: css7`
4074
+ image: css8`
3671
4075
  max-width: 100%;
3672
4076
  max-height: calc(100vh - 200px);
3673
4077
  object-fit: contain;
3674
4078
  border-radius: 8px;
3675
4079
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
3676
4080
  `,
3677
- video: css7`
4081
+ video: css8`
3678
4082
  max-width: 100%;
3679
4083
  max-height: calc(100vh - 200px);
3680
4084
  border-radius: 8px;
3681
4085
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
3682
4086
  `,
3683
- filePlaceholder: css7`
4087
+ filePlaceholder: css8`
3684
4088
  display: flex;
3685
4089
  flex-direction: column;
3686
4090
  align-items: center;
@@ -3690,19 +4094,19 @@ var styles7 = {
3690
4094
  border-radius: 12px;
3691
4095
  border: 1px solid ${colors.border};
3692
4096
  `,
3693
- fileIcon: css7`
4097
+ fileIcon: css8`
3694
4098
  width: 80px;
3695
4099
  height: 80px;
3696
4100
  color: ${colors.textMuted};
3697
4101
  margin-bottom: 16px;
3698
4102
  `,
3699
- fileName: css7`
4103
+ fileName: css8`
3700
4104
  font-size: ${fontSize.lg};
3701
4105
  font-weight: 600;
3702
4106
  color: ${colors.text};
3703
4107
  margin: 0;
3704
4108
  `,
3705
- sidebar: css7`
4109
+ sidebar: css8`
3706
4110
  width: 280px;
3707
4111
  background: ${colors.surface};
3708
4112
  border-left: 1px solid ${colors.border};
@@ -3710,36 +4114,36 @@ var styles7 = {
3710
4114
  flex-direction: column;
3711
4115
  overflow: hidden;
3712
4116
  `,
3713
- sidebarHeader: css7`
4117
+ sidebarHeader: css8`
3714
4118
  padding: 16px 20px;
3715
4119
  border-bottom: 1px solid ${colors.border};
3716
4120
  `,
3717
- sidebarTitle: css7`
4121
+ sidebarTitle: css8`
3718
4122
  font-size: ${fontSize.base};
3719
4123
  font-weight: 600;
3720
4124
  color: ${colors.text};
3721
4125
  margin: 0;
3722
4126
  `,
3723
- sidebarContent: css7`
4127
+ sidebarContent: css8`
3724
4128
  flex: 1;
3725
4129
  padding: 20px;
3726
4130
  overflow: auto;
3727
4131
  `,
3728
- info: css7`
4132
+ info: css8`
3729
4133
  display: flex;
3730
4134
  flex-direction: column;
3731
4135
  gap: 12px;
3732
4136
  margin-bottom: 24px;
3733
4137
  `,
3734
- infoRow: css7`
4138
+ infoRow: css8`
3735
4139
  display: flex;
3736
4140
  justify-content: space-between;
3737
4141
  font-size: ${fontSize.sm};
3738
4142
  `,
3739
- infoLabel: css7`
4143
+ infoLabel: css8`
3740
4144
  color: ${colors.textSecondary};
3741
4145
  `,
3742
- infoValue: css7`
4146
+ infoValue: css8`
3743
4147
  color: ${colors.text};
3744
4148
  font-weight: 500;
3745
4149
  text-align: right;
@@ -3748,7 +4152,7 @@ var styles7 = {
3748
4152
  text-overflow: ellipsis;
3749
4153
  white-space: nowrap;
3750
4154
  `,
3751
- infoValueWrap: css7`
4155
+ infoValueWrap: css8`
3752
4156
  color: ${colors.text};
3753
4157
  font-weight: 500;
3754
4158
  text-align: right;
@@ -3756,12 +4160,12 @@ var styles7 = {
3756
4160
  word-break: break-all;
3757
4161
  white-space: normal;
3758
4162
  `,
3759
- actions: css7`
4163
+ actions: css8`
3760
4164
  display: flex;
3761
4165
  flex-direction: column;
3762
4166
  gap: 8px;
3763
4167
  `,
3764
- actionBtn: css7`
4168
+ actionBtn: css8`
3765
4169
  display: flex;
3766
4170
  align-items: center;
3767
4171
  gap: 10px;
@@ -3782,7 +4186,7 @@ var styles7 = {
3782
4186
  border-color: ${colors.borderHover};
3783
4187
  }
3784
4188
  `,
3785
- actionBtnDanger: css7`
4189
+ actionBtnDanger: css8`
3786
4190
  color: ${colors.danger};
3787
4191
 
3788
4192
  &:hover {
@@ -3790,7 +4194,7 @@ var styles7 = {
3790
4194
  border-color: ${colors.danger};
3791
4195
  }
3792
4196
  `,
3793
- actionIcon: css7`
4197
+ actionIcon: css8`
3794
4198
  width: 16px;
3795
4199
  height: 16px;
3796
4200
  flex-shrink: 0;
@@ -3798,14 +4202,14 @@ var styles7 = {
3798
4202
  };
3799
4203
  function StudioDetailView() {
3800
4204
  const { focusedItem, setFocusedItem, triggerRefresh, clearSelection } = useStudio();
3801
- const [showDeleteConfirm, setShowDeleteConfirm] = useState7(false);
3802
- const [showRenameModal, setShowRenameModal] = useState7(false);
3803
- const [showProcessConfirm, setShowProcessConfirm] = useState7(false);
3804
- const [showR2SetupModal, setShowR2SetupModal] = useState7(false);
3805
- const [processProgress, setProcessProgress] = useState7(null);
3806
- const [alertMessage, setAlertMessage] = useState7(null);
3807
- const [showCopied, setShowCopied] = useState7(false);
3808
- const [pushing, setPushing] = useState7(false);
4205
+ const [showDeleteConfirm, setShowDeleteConfirm] = useState8(false);
4206
+ const [showRenameModal, setShowRenameModal] = useState8(false);
4207
+ const [showProcessConfirm, setShowProcessConfirm] = useState8(false);
4208
+ const [showR2SetupModal, setShowR2SetupModal] = useState8(false);
4209
+ const [processProgress, setProcessProgress] = useState8(null);
4210
+ const [alertMessage, setAlertMessage] = useState8(null);
4211
+ const [showCopied, setShowCopied] = useState8(false);
4212
+ const [pushing, setPushing] = useState8(false);
3809
4213
  if (!focusedItem) return null;
3810
4214
  const isImage = isImageFile(focusedItem.name);
3811
4215
  const isVideo = isVideoFile(focusedItem.name);
@@ -3969,18 +4373,18 @@ function StudioDetailView() {
3969
4373
  };
3970
4374
  const renderMedia = () => {
3971
4375
  if (isImage) {
3972
- return /* @__PURE__ */ jsx7("img", { css: styles7.image, src: imageSrc, alt: focusedItem.name });
4376
+ return /* @__PURE__ */ jsx8("img", { css: styles8.image, src: imageSrc, alt: focusedItem.name });
3973
4377
  }
3974
4378
  if (isVideo) {
3975
- return /* @__PURE__ */ jsx7("video", { css: styles7.video, src: imageSrc, controls: true });
4379
+ return /* @__PURE__ */ jsx8("video", { css: styles8.video, src: imageSrc, controls: true });
3976
4380
  }
3977
- return /* @__PURE__ */ jsxs7("div", { css: styles7.filePlaceholder, children: [
3978
- /* @__PURE__ */ jsx7("svg", { css: styles7.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) }),
3979
- /* @__PURE__ */ jsx7("p", { css: styles7.fileName, children: focusedItem.name })
4381
+ return /* @__PURE__ */ jsxs8("div", { css: styles8.filePlaceholder, children: [
4382
+ /* @__PURE__ */ jsx8("svg", { css: styles8.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx8("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) }),
4383
+ /* @__PURE__ */ jsx8("p", { css: styles8.fileName, children: focusedItem.name })
3980
4384
  ] });
3981
4385
  };
3982
- return /* @__PURE__ */ jsxs7(Fragment3, { children: [
3983
- showDeleteConfirm && /* @__PURE__ */ jsx7(
4386
+ return /* @__PURE__ */ jsxs8(Fragment4, { children: [
4387
+ showDeleteConfirm && /* @__PURE__ */ jsx8(
3984
4388
  ConfirmModal,
3985
4389
  {
3986
4390
  title: "Delete File",
@@ -3991,7 +4395,7 @@ function StudioDetailView() {
3991
4395
  onCancel: () => setShowDeleteConfirm(false)
3992
4396
  }
3993
4397
  ),
3994
- alertMessage && /* @__PURE__ */ jsx7(
4398
+ alertMessage && /* @__PURE__ */ jsx8(
3995
4399
  AlertModal,
3996
4400
  {
3997
4401
  title: alertMessage.title,
@@ -3999,14 +4403,14 @@ function StudioDetailView() {
3999
4403
  onClose: () => setAlertMessage(null)
4000
4404
  }
4001
4405
  ),
4002
- /* @__PURE__ */ jsx7(
4406
+ /* @__PURE__ */ jsx8(
4003
4407
  R2SetupModal,
4004
4408
  {
4005
4409
  isOpen: showR2SetupModal,
4006
4410
  onClose: () => setShowR2SetupModal(false)
4007
4411
  }
4008
4412
  ),
4009
- showRenameModal && /* @__PURE__ */ jsx7(
4413
+ showRenameModal && /* @__PURE__ */ jsx8(
4010
4414
  InputModal,
4011
4415
  {
4012
4416
  title: "Rename File",
@@ -4018,7 +4422,7 @@ function StudioDetailView() {
4018
4422
  onCancel: () => setShowRenameModal(false)
4019
4423
  }
4020
4424
  ),
4021
- showProcessConfirm && /* @__PURE__ */ jsx7(
4425
+ showProcessConfirm && /* @__PURE__ */ jsx8(
4022
4426
  ConfirmModal,
4023
4427
  {
4024
4428
  title: "Process Image",
@@ -4028,7 +4432,7 @@ function StudioDetailView() {
4028
4432
  onCancel: () => setShowProcessConfirm(false)
4029
4433
  }
4030
4434
  ),
4031
- processProgress && /* @__PURE__ */ jsx7(
4435
+ processProgress && /* @__PURE__ */ jsx8(
4032
4436
  ProgressModal,
4033
4437
  {
4034
4438
  title: "Processing Image",
@@ -4036,61 +4440,61 @@ function StudioDetailView() {
4036
4440
  onClose: () => setProcessProgress(null)
4037
4441
  }
4038
4442
  ),
4039
- /* @__PURE__ */ jsx7("div", { css: styles7.overlay, onClick: handleClose, children: /* @__PURE__ */ jsxs7("div", { css: styles7.container, onClick: (e) => e.stopPropagation(), children: [
4040
- /* @__PURE__ */ jsxs7("div", { css: styles7.main, children: [
4041
- /* @__PURE__ */ jsxs7("div", { css: styles7.headerButtons, children: [
4042
- /* @__PURE__ */ jsxs7("button", { css: styles7.copyBtn, onClick: handleCopyPath, title: "Copy file path", children: [
4043
- showCopied && /* @__PURE__ */ jsx7("span", { css: styles7.tooltip, children: "Copied!" }),
4044
- /* @__PURE__ */ jsx7("svg", { css: styles7.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" }) })
4443
+ /* @__PURE__ */ jsx8("div", { css: styles8.overlay, onClick: handleClose, children: /* @__PURE__ */ jsxs8("div", { css: styles8.container, onClick: (e) => e.stopPropagation(), children: [
4444
+ /* @__PURE__ */ jsxs8("div", { css: styles8.main, children: [
4445
+ /* @__PURE__ */ jsxs8("div", { css: styles8.headerButtons, children: [
4446
+ /* @__PURE__ */ jsxs8("button", { css: styles8.copyBtn, onClick: handleCopyPath, title: "Copy file path", children: [
4447
+ showCopied && /* @__PURE__ */ jsx8("span", { css: styles8.tooltip, children: "Copied!" }),
4448
+ /* @__PURE__ */ jsx8("svg", { css: styles8.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx8("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" }) })
4045
4449
  ] }),
4046
- /* @__PURE__ */ jsx7("button", { css: styles7.mainCloseBtn, onClick: handleClose, "aria-label": "Close", children: /* @__PURE__ */ jsx7("svg", { css: styles7.mainCloseIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })
4450
+ /* @__PURE__ */ jsx8("button", { css: styles8.mainCloseBtn, onClick: handleClose, "aria-label": "Close", children: /* @__PURE__ */ jsx8("svg", { css: styles8.mainCloseIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx8("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })
4047
4451
  ] }),
4048
- /* @__PURE__ */ jsx7("div", { css: styles7.mediaWrapper, children: renderMedia() })
4452
+ /* @__PURE__ */ jsx8("div", { css: styles8.mediaWrapper, children: renderMedia() })
4049
4453
  ] }),
4050
- /* @__PURE__ */ jsxs7("div", { css: styles7.sidebar, children: [
4051
- /* @__PURE__ */ jsx7("div", { css: styles7.sidebarHeader, children: /* @__PURE__ */ jsx7("h3", { css: styles7.sidebarTitle, children: "Details" }) }),
4052
- /* @__PURE__ */ jsxs7("div", { css: styles7.sidebarContent, children: [
4053
- /* @__PURE__ */ jsxs7("div", { css: styles7.info, children: [
4054
- /* @__PURE__ */ jsxs7("div", { css: styles7.infoRow, children: [
4055
- /* @__PURE__ */ jsx7("span", { css: styles7.infoLabel, children: "Name" }),
4056
- /* @__PURE__ */ jsx7("span", { css: styles7.infoValueWrap, children: focusedItem.name })
4454
+ /* @__PURE__ */ jsxs8("div", { css: styles8.sidebar, children: [
4455
+ /* @__PURE__ */ jsx8("div", { css: styles8.sidebarHeader, children: /* @__PURE__ */ jsx8("h3", { css: styles8.sidebarTitle, children: "Details" }) }),
4456
+ /* @__PURE__ */ jsxs8("div", { css: styles8.sidebarContent, children: [
4457
+ /* @__PURE__ */ jsxs8("div", { css: styles8.info, children: [
4458
+ /* @__PURE__ */ jsxs8("div", { css: styles8.infoRow, children: [
4459
+ /* @__PURE__ */ jsx8("span", { css: styles8.infoLabel, children: "Name" }),
4460
+ /* @__PURE__ */ jsx8("span", { css: styles8.infoValueWrap, children: focusedItem.name })
4057
4461
  ] }),
4058
- /* @__PURE__ */ jsxs7("div", { css: styles7.infoRow, children: [
4059
- /* @__PURE__ */ jsx7("span", { css: styles7.infoLabel, children: "Path" }),
4060
- /* @__PURE__ */ jsx7("span", { css: styles7.infoValueWrap, children: focusedItem.path.replace(/^public\//, "") })
4462
+ /* @__PURE__ */ jsxs8("div", { css: styles8.infoRow, children: [
4463
+ /* @__PURE__ */ jsx8("span", { css: styles8.infoLabel, children: "Path" }),
4464
+ /* @__PURE__ */ jsx8("span", { css: styles8.infoValueWrap, children: focusedItem.path.replace(/^public\//, "") })
4061
4465
  ] }),
4062
- focusedItem.size !== void 0 && /* @__PURE__ */ jsxs7("div", { css: styles7.infoRow, children: [
4063
- /* @__PURE__ */ jsx7("span", { css: styles7.infoLabel, children: "Size" }),
4064
- /* @__PURE__ */ jsx7("span", { css: styles7.infoValue, children: formatFileSize3(focusedItem.size) })
4466
+ focusedItem.size !== void 0 && /* @__PURE__ */ jsxs8("div", { css: styles8.infoRow, children: [
4467
+ /* @__PURE__ */ jsx8("span", { css: styles8.infoLabel, children: "Size" }),
4468
+ /* @__PURE__ */ jsx8("span", { css: styles8.infoValue, children: formatFileSize3(focusedItem.size) })
4065
4469
  ] }),
4066
- focusedItem.dimensions && /* @__PURE__ */ jsxs7("div", { css: styles7.infoRow, children: [
4067
- /* @__PURE__ */ jsx7("span", { css: styles7.infoLabel, children: "Dimensions" }),
4068
- /* @__PURE__ */ jsxs7("span", { css: styles7.infoValue, children: [
4470
+ focusedItem.dimensions && /* @__PURE__ */ jsxs8("div", { css: styles8.infoRow, children: [
4471
+ /* @__PURE__ */ jsx8("span", { css: styles8.infoLabel, children: "Dimensions" }),
4472
+ /* @__PURE__ */ jsxs8("span", { css: styles8.infoValue, children: [
4069
4473
  focusedItem.dimensions.width,
4070
4474
  " \xD7 ",
4071
4475
  focusedItem.dimensions.height
4072
4476
  ] })
4073
4477
  ] }),
4074
- /* @__PURE__ */ jsxs7("div", { css: styles7.infoRow, children: [
4075
- /* @__PURE__ */ jsx7("span", { css: styles7.infoLabel, children: "CDN Status" }),
4076
- /* @__PURE__ */ jsx7("span", { css: styles7.infoValue, children: focusedItem.cdnPushed ? "Pushed" : "Not pushed" })
4478
+ /* @__PURE__ */ jsxs8("div", { css: styles8.infoRow, children: [
4479
+ /* @__PURE__ */ jsx8("span", { css: styles8.infoLabel, children: "CDN Status" }),
4480
+ /* @__PURE__ */ jsx8("span", { css: styles8.infoValue, children: focusedItem.cdnPushed ? "Pushed" : "Not pushed" })
4077
4481
  ] })
4078
4482
  ] }),
4079
- /* @__PURE__ */ jsxs7("div", { css: styles7.actions, children: [
4080
- /* @__PURE__ */ jsxs7("button", { css: styles7.actionBtn, onClick: () => setShowRenameModal(true), children: [
4081
- /* @__PURE__ */ jsx7("svg", { css: styles7.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" }) }),
4483
+ /* @__PURE__ */ jsxs8("div", { css: styles8.actions, children: [
4484
+ /* @__PURE__ */ jsxs8("button", { css: styles8.actionBtn, onClick: () => setShowRenameModal(true), children: [
4485
+ /* @__PURE__ */ jsx8("svg", { css: styles8.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx8("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" }) }),
4082
4486
  "Rename"
4083
4487
  ] }),
4084
- /* @__PURE__ */ jsxs7("button", { css: styles7.actionBtn, onClick: handleSync, disabled: pushing, children: [
4085
- /* @__PURE__ */ jsx7("svg", { css: styles7.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" }) }),
4488
+ /* @__PURE__ */ jsxs8("button", { css: styles8.actionBtn, onClick: handleSync, disabled: pushing, children: [
4489
+ /* @__PURE__ */ jsx8("svg", { css: styles8.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx8("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" }) }),
4086
4490
  syncing ? "Pushing..." : "Push to CDN"
4087
4491
  ] }),
4088
- /* @__PURE__ */ jsxs7("button", { css: styles7.actionBtn, onClick: () => setShowProcessConfirm(true), children: [
4089
- /* @__PURE__ */ jsx7("svg", { css: styles7.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) }),
4492
+ /* @__PURE__ */ jsxs8("button", { css: styles8.actionBtn, onClick: () => setShowProcessConfirm(true), children: [
4493
+ /* @__PURE__ */ jsx8("svg", { css: styles8.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx8("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) }),
4090
4494
  "Process Image"
4091
4495
  ] }),
4092
- /* @__PURE__ */ jsxs7("button", { css: [styles7.actionBtn, styles7.actionBtnDanger], onClick: () => setShowDeleteConfirm(true), children: [
4093
- /* @__PURE__ */ jsx7("svg", { css: styles7.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) }),
4496
+ /* @__PURE__ */ jsxs8("button", { css: [styles8.actionBtn, styles8.actionBtnDanger], onClick: () => setShowDeleteConfirm(true), children: [
4497
+ /* @__PURE__ */ jsx8("svg", { css: styles8.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx8("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) }),
4094
4498
  "Delete"
4095
4499
  ] })
4096
4500
  ] })
@@ -4106,12 +4510,12 @@ function formatFileSize3(bytes) {
4106
4510
  }
4107
4511
 
4108
4512
  // src/components/StudioSettings.tsx
4109
- import { useState as useState8 } from "react";
4110
- import { css as css8 } from "@emotion/react";
4111
- import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs8 } from "@emotion/react/jsx-runtime";
4513
+ import { useState as useState9, useEffect as useEffect4, useCallback as useCallback4 } from "react";
4514
+ import { css as css9 } from "@emotion/react";
4515
+ import { Fragment as Fragment5, jsx as jsx9, jsxs as jsxs9 } from "@emotion/react/jsx-runtime";
4112
4516
  var btnHeight2 = "36px";
4113
- var styles8 = {
4114
- btn: css8`
4517
+ var styles9 = {
4518
+ btn: css9`
4115
4519
  height: ${btnHeight2};
4116
4520
  padding: 0 12px;
4117
4521
  background: ${colors.surface};
@@ -4128,12 +4532,12 @@ var styles8 = {
4128
4532
  border-color: ${colors.borderHover};
4129
4533
  }
4130
4534
  `,
4131
- icon: css8`
4535
+ icon: css9`
4132
4536
  width: 16px;
4133
4537
  height: 16px;
4134
4538
  color: ${colors.textSecondary};
4135
4539
  `,
4136
- overlay: css8`
4540
+ overlay: css9`
4137
4541
  position: fixed;
4138
4542
  top: 0;
4139
4543
  right: 0;
@@ -4146,7 +4550,7 @@ var styles8 = {
4146
4550
  background-color: rgba(26, 31, 54, 0.4);
4147
4551
  backdrop-filter: blur(4px);
4148
4552
  `,
4149
- panel: css8`
4553
+ panel: css9`
4150
4554
  ${baseReset}
4151
4555
  position: relative;
4152
4556
  background-color: ${colors.surface};
@@ -4156,20 +4560,20 @@ var styles8 = {
4156
4560
  max-width: 512px;
4157
4561
  padding: 24px;
4158
4562
  `,
4159
- header: css8`
4563
+ header: css9`
4160
4564
  display: flex;
4161
4565
  align-items: center;
4162
4566
  justify-content: space-between;
4163
4567
  margin-bottom: 24px;
4164
4568
  `,
4165
- title: css8`
4569
+ title: css9`
4166
4570
  font-size: ${fontSize.xl};
4167
4571
  font-weight: 600;
4168
4572
  color: ${colors.text};
4169
4573
  margin: 0;
4170
4574
  letter-spacing: -0.02em;
4171
4575
  `,
4172
- closeBtn: css8`
4576
+ closeBtn: css9`
4173
4577
  padding: 6px;
4174
4578
  background: ${colors.surface};
4175
4579
  border: 1px solid ${colors.border};
@@ -4185,26 +4589,26 @@ var styles8 = {
4185
4589
  border-color: ${colors.borderHover};
4186
4590
  }
4187
4591
  `,
4188
- sections: css8`
4592
+ sections: css9`
4189
4593
  display: flex;
4190
4594
  flex-direction: column;
4191
4595
  gap: 24px;
4192
4596
  `,
4193
- sectionTitle: css8`
4597
+ sectionTitle: css9`
4194
4598
  font-size: ${fontSize.base};
4195
4599
  font-weight: 600;
4196
4600
  color: ${colors.text};
4197
4601
  margin: 0 0 12px 0;
4198
4602
  `,
4199
- description: css8`
4603
+ description: css9`
4200
4604
  font-size: ${fontSize.sm};
4201
4605
  color: ${colors.textSecondary};
4202
4606
  margin: 0 0 12px 0;
4203
4607
  `,
4204
- codeWrapper: css8`
4608
+ codeWrapper: css9`
4205
4609
  position: relative;
4206
4610
  `,
4207
- code: css8`
4611
+ code: css9`
4208
4612
  background-color: ${colors.background};
4209
4613
  border-radius: 8px;
4210
4614
  padding: 12px;
@@ -4216,7 +4620,7 @@ var styles8 = {
4216
4620
  overflow-x: auto;
4217
4621
  white-space: nowrap;
4218
4622
  `,
4219
- copyBtn: css8`
4623
+ copyBtn: css9`
4220
4624
  position: absolute;
4221
4625
  top: 8px;
4222
4626
  right: 8px;
@@ -4235,7 +4639,7 @@ var styles8 = {
4235
4639
  border-color: ${colors.borderHover};
4236
4640
  }
4237
4641
  `,
4238
- tooltip: css8`
4642
+ tooltip: css9`
4239
4643
  position: absolute;
4240
4644
  bottom: 100%;
4241
4645
  left: 50%;
@@ -4260,19 +4664,19 @@ var styles8 = {
4260
4664
  border-top-color: #1a1f36;
4261
4665
  }
4262
4666
  `,
4263
- copyIcon: css8`
4667
+ copyIcon: css9`
4264
4668
  width: 14px;
4265
4669
  height: 14px;
4266
4670
  color: ${colors.textSecondary};
4267
4671
  `,
4268
- codeLine: css8`
4672
+ codeLine: css9`
4269
4673
  margin: 0 0 4px 0;
4270
4674
 
4271
4675
  &:last-child {
4272
4676
  margin: 0;
4273
4677
  }
4274
4678
  `,
4275
- input: css8`
4679
+ input: css9`
4276
4680
  width: 100%;
4277
4681
  padding: 10px 14px;
4278
4682
  border: 1px solid ${colors.border};
@@ -4292,19 +4696,19 @@ var styles8 = {
4292
4696
  color: ${colors.textMuted};
4293
4697
  }
4294
4698
  `,
4295
- grid: css8`
4699
+ grid: css9`
4296
4700
  display: grid;
4297
4701
  grid-template-columns: repeat(3, 1fr);
4298
4702
  gap: 12px;
4299
4703
  `,
4300
- label: css8`
4704
+ label: css9`
4301
4705
  font-size: ${fontSize.xs};
4302
4706
  font-weight: 500;
4303
4707
  color: ${colors.textSecondary};
4304
4708
  display: block;
4305
4709
  margin-bottom: 6px;
4306
4710
  `,
4307
- footer: css8`
4711
+ footer: css9`
4308
4712
  margin-top: 24px;
4309
4713
  padding-top: 20px;
4310
4714
  border-top: 1px solid ${colors.border};
@@ -4312,7 +4716,7 @@ var styles8 = {
4312
4716
  justify-content: flex-end;
4313
4717
  gap: 12px;
4314
4718
  `,
4315
- cancelBtn: css8`
4719
+ cancelBtn: css9`
4316
4720
  padding: 10px 18px;
4317
4721
  font-size: ${fontSize.base};
4318
4722
  font-weight: 500;
@@ -4328,7 +4732,7 @@ var styles8 = {
4328
4732
  border-color: ${colors.borderHover};
4329
4733
  }
4330
4734
  `,
4331
- saveBtn: css8`
4735
+ saveBtn: css9`
4332
4736
  padding: 10px 18px;
4333
4737
  font-size: ${fontSize.base};
4334
4738
  font-weight: 500;
@@ -4343,15 +4747,94 @@ var styles8 = {
4343
4747
  background-color: ${colors.primaryHover};
4344
4748
  border-color: ${colors.primaryHover};
4345
4749
  }
4750
+
4751
+ &:disabled {
4752
+ opacity: 0.6;
4753
+ cursor: not-allowed;
4754
+ }
4755
+ `,
4756
+ cdnList: css9`
4757
+ display: flex;
4758
+ flex-direction: column;
4759
+ gap: 8px;
4760
+ `,
4761
+ cdnRow: css9`
4762
+ display: flex;
4763
+ gap: 8px;
4764
+ align-items: center;
4765
+ `,
4766
+ cdnInput: css9`
4767
+ flex: 1;
4768
+ padding: 8px 12px;
4769
+ border: 1px solid ${colors.border};
4770
+ border-radius: 6px;
4771
+ font-size: ${fontSize.sm};
4772
+ color: ${colors.text};
4773
+ background: ${colors.surface};
4774
+ transition: all 0.15s ease;
4775
+
4776
+ &:focus {
4777
+ outline: none;
4778
+ border-color: ${colors.primary};
4779
+ box-shadow: 0 0 0 3px ${colors.primaryLight};
4780
+ }
4781
+ `,
4782
+ cdnIndex: css9`
4783
+ font-size: ${fontSize.xs};
4784
+ color: ${colors.textMuted};
4785
+ width: 24px;
4786
+ text-align: center;
4787
+ flex-shrink: 0;
4788
+ `,
4789
+ cdnDeleteBtn: css9`
4790
+ padding: 6px;
4791
+ background: none;
4792
+ border: none;
4793
+ cursor: pointer;
4794
+ color: ${colors.textMuted};
4795
+ transition: color 0.15s;
4796
+ flex-shrink: 0;
4797
+
4798
+ &:hover {
4799
+ color: ${colors.danger};
4800
+ }
4801
+ `,
4802
+ cdnAddBtn: css9`
4803
+ padding: 8px 12px;
4804
+ font-size: ${fontSize.sm};
4805
+ font-weight: 500;
4806
+ color: ${colors.primary};
4807
+ background: ${colors.primaryLight};
4808
+ border: 1px dashed ${colors.primary};
4809
+ border-radius: 6px;
4810
+ cursor: pointer;
4811
+ transition: all 0.15s ease;
4812
+ display: flex;
4813
+ align-items: center;
4814
+ justify-content: center;
4815
+ gap: 6px;
4816
+ margin-top: 8px;
4817
+
4818
+ &:hover {
4819
+ background: ${colors.surface};
4820
+ }
4821
+ `,
4822
+ warning: css9`
4823
+ font-size: ${fontSize.xs};
4824
+ color: ${colors.danger};
4825
+ margin-top: 8px;
4826
+ padding: 8px 12px;
4827
+ background: ${colors.dangerLight};
4828
+ border-radius: 6px;
4346
4829
  `
4347
4830
  };
4348
4831
  function StudioSettings() {
4349
- const [isOpen, setIsOpen] = useState8(false);
4350
- return /* @__PURE__ */ jsxs8(Fragment4, { children: [
4351
- /* @__PURE__ */ jsx8("button", { css: styles8.btn, onClick: () => setIsOpen(true), "aria-label": "Settings", children: /* @__PURE__ */ jsxs8(
4832
+ const [isOpen, setIsOpen] = useState9(false);
4833
+ return /* @__PURE__ */ jsxs9(Fragment5, { children: [
4834
+ /* @__PURE__ */ jsx9("button", { css: styles9.btn, onClick: () => setIsOpen(true), "aria-label": "Settings", children: /* @__PURE__ */ jsxs9(
4352
4835
  "svg",
4353
4836
  {
4354
- css: styles8.icon,
4837
+ css: styles9.icon,
4355
4838
  xmlns: "http://www.w3.org/2000/svg",
4356
4839
  viewBox: "0 0 24 24",
4357
4840
  fill: "none",
@@ -4360,12 +4843,12 @@ function StudioSettings() {
4360
4843
  strokeLinecap: "round",
4361
4844
  strokeLinejoin: "round",
4362
4845
  children: [
4363
- /* @__PURE__ */ jsx8("circle", { cx: "12", cy: "12", r: "3" }),
4364
- /* @__PURE__ */ jsx8("path", { d: "M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 010 2.83 2 2 0 01-2.83 0l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-2 2 2 2 0 01-2-2v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83 0 2 2 0 010-2.83l.06-.06a1.65 1.65 0 00.33-1.82 1.65 1.65 0 00-1.51-1H3a2 2 0 01-2-2 2 2 0 012-2h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 010-2.83 2 2 0 012.83 0l.06.06a1.65 1.65 0 001.82.33H9a1.65 1.65 0 001-1.51V3a2 2 0 012-2 2 2 0 012 2v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 0 2 2 0 010 2.83l-.06.06a1.65 1.65 0 00-.33 1.82V9a1.65 1.65 0 001.51 1H21a2 2 0 012 2 2 2 0 01-2 2h-.09a1.65 1.65 0 00-1.51 1z" })
4846
+ /* @__PURE__ */ jsx9("circle", { cx: "12", cy: "12", r: "3" }),
4847
+ /* @__PURE__ */ jsx9("path", { d: "M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 010 2.83 2 2 0 01-2.83 0l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-2 2 2 2 0 01-2-2v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83 0 2 2 0 010-2.83l.06-.06a1.65 1.65 0 00.33-1.82 1.65 1.65 0 00-1.51-1H3a2 2 0 01-2-2 2 2 0 012-2h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 010-2.83 2 2 0 012.83 0l.06.06a1.65 1.65 0 001.82.33H9a1.65 1.65 0 001-1.51V3a2 2 0 012-2 2 2 0 012 2v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 0 2 2 0 010 2.83l-.06.06a1.65 1.65 0 00-.33 1.82V9a1.65 1.65 0 001.51 1H21a2 2 0 012 2 2 2 0 01-2 2h-.09a1.65 1.65 0 00-1.51 1z" })
4365
4848
  ]
4366
4849
  }
4367
4850
  ) }),
4368
- isOpen && /* @__PURE__ */ jsx8(SettingsPanel, { onClose: () => setIsOpen(false) })
4851
+ isOpen && /* @__PURE__ */ jsx9(SettingsPanel, { onClose: () => setIsOpen(false) })
4369
4852
  ] });
4370
4853
  }
4371
4854
  var envTemplate = `CLOUDFLARE_R2_ACCOUNT_ID=abc123def456ghi789
@@ -4374,65 +4857,152 @@ CLOUDFLARE_R2_SECRET_ACCESS_KEY=your_secret_access_key_here
4374
4857
  CLOUDFLARE_R2_BUCKET_NAME=my-images-bucket
4375
4858
  CLOUDFLARE_R2_PUBLIC_URL=https://cdn.yourdomain.com`;
4376
4859
  function SettingsPanel({ onClose }) {
4377
- const [copied, setCopied] = useState8(false);
4860
+ const { triggerRefresh } = useStudio();
4861
+ const [copied, setCopied] = useState9(false);
4862
+ const [cdnUrls, setCdnUrls] = useState9([]);
4863
+ const [loading, setLoading] = useState9(true);
4864
+ const [saving, setSaving] = useState9(false);
4865
+ const [hasChanges, setHasChanges] = useState9(false);
4866
+ useEffect4(() => {
4867
+ async function loadCdns() {
4868
+ try {
4869
+ const response = await fetch("/api/studio/cdns");
4870
+ const data = await response.json();
4871
+ setCdnUrls(data.cdns || []);
4872
+ } catch (error) {
4873
+ console.error("Failed to load CDN URLs:", error);
4874
+ } finally {
4875
+ setLoading(false);
4876
+ }
4877
+ }
4878
+ loadCdns();
4879
+ }, []);
4378
4880
  const handleCopy = () => {
4379
4881
  navigator.clipboard.writeText(envTemplate);
4380
4882
  setCopied(true);
4381
4883
  setTimeout(() => setCopied(false), 2e3);
4382
4884
  };
4383
- return /* @__PURE__ */ jsx8("div", { css: styles8.overlay, onClick: onClose, children: /* @__PURE__ */ jsxs8("div", { css: styles8.panel, onClick: (e) => e.stopPropagation(), children: [
4384
- /* @__PURE__ */ jsxs8("div", { css: styles8.header, children: [
4385
- /* @__PURE__ */ jsx8("h2", { css: styles8.title, children: "Settings" }),
4386
- /* @__PURE__ */ jsx8("button", { css: styles8.closeBtn, onClick: onClose, children: /* @__PURE__ */ jsx8("svg", { css: styles8.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx8("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })
4885
+ const handleCdnChange = useCallback4((index, value) => {
4886
+ setCdnUrls((prev) => {
4887
+ const updated = [...prev];
4888
+ updated[index] = value;
4889
+ return updated;
4890
+ });
4891
+ setHasChanges(true);
4892
+ }, []);
4893
+ const handleAddCdn = useCallback4(() => {
4894
+ setCdnUrls((prev) => [...prev, ""]);
4895
+ setHasChanges(true);
4896
+ }, []);
4897
+ const handleDeleteCdn = useCallback4((index) => {
4898
+ setCdnUrls((prev) => prev.filter((_, i) => i !== index));
4899
+ setHasChanges(true);
4900
+ }, []);
4901
+ const handleSave = useCallback4(async () => {
4902
+ setSaving(true);
4903
+ try {
4904
+ const response = await fetch("/api/studio/cdns", {
4905
+ method: "POST",
4906
+ headers: { "Content-Type": "application/json" },
4907
+ body: JSON.stringify({ cdns: cdnUrls.filter((url) => url.trim()) })
4908
+ });
4909
+ if (response.ok) {
4910
+ setHasChanges(false);
4911
+ triggerRefresh();
4912
+ onClose();
4913
+ }
4914
+ } catch (error) {
4915
+ console.error("Failed to save CDN URLs:", error);
4916
+ } finally {
4917
+ setSaving(false);
4918
+ }
4919
+ }, [cdnUrls, triggerRefresh, onClose]);
4920
+ return /* @__PURE__ */ jsx9("div", { css: styles9.overlay, onClick: onClose, children: /* @__PURE__ */ jsxs9("div", { css: styles9.panel, onClick: (e) => e.stopPropagation(), children: [
4921
+ /* @__PURE__ */ jsxs9("div", { css: styles9.header, children: [
4922
+ /* @__PURE__ */ jsx9("h2", { css: styles9.title, children: "Settings" }),
4923
+ /* @__PURE__ */ jsx9("button", { css: styles9.closeBtn, onClick: onClose, children: /* @__PURE__ */ jsx9("svg", { css: styles9.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx9("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })
4387
4924
  ] }),
4388
- /* @__PURE__ */ jsxs8("div", { css: styles8.sections, children: [
4389
- /* @__PURE__ */ jsxs8("section", { children: [
4390
- /* @__PURE__ */ jsx8("h3", { css: styles8.sectionTitle, children: "Cloudflare R2" }),
4391
- /* @__PURE__ */ jsx8("p", { css: styles8.description, children: "Configure in .env.local file:" }),
4392
- /* @__PURE__ */ jsxs8("div", { css: styles8.codeWrapper, children: [
4393
- /* @__PURE__ */ jsxs8("button", { css: styles8.copyBtn, onClick: handleCopy, title: "Copy to clipboard", children: [
4394
- copied && /* @__PURE__ */ jsx8("span", { css: styles8.tooltip, children: "Copied!" }),
4395
- /* @__PURE__ */ jsx8("svg", { css: styles8.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx8("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" }) })
4925
+ /* @__PURE__ */ jsxs9("div", { css: styles9.sections, children: [
4926
+ /* @__PURE__ */ jsxs9("section", { children: [
4927
+ /* @__PURE__ */ jsx9("h3", { css: styles9.sectionTitle, children: "CDN URLs" }),
4928
+ /* @__PURE__ */ jsx9("p", { css: styles9.description, children: "Manage CDN base URLs used by your images:" }),
4929
+ loading ? /* @__PURE__ */ jsx9("p", { css: styles9.description, children: "Loading..." }) : /* @__PURE__ */ jsxs9(Fragment5, { children: [
4930
+ /* @__PURE__ */ jsx9("div", { css: styles9.cdnList, children: cdnUrls.map((url, index) => /* @__PURE__ */ jsxs9("div", { css: styles9.cdnRow, children: [
4931
+ /* @__PURE__ */ jsx9("span", { css: styles9.cdnIndex, children: index }),
4932
+ /* @__PURE__ */ jsx9(
4933
+ "input",
4934
+ {
4935
+ css: styles9.cdnInput,
4936
+ type: "text",
4937
+ value: url,
4938
+ onChange: (e) => handleCdnChange(index, e.target.value),
4939
+ placeholder: "https://cdn.example.com"
4940
+ }
4941
+ ),
4942
+ /* @__PURE__ */ jsx9(
4943
+ "button",
4944
+ {
4945
+ css: styles9.cdnDeleteBtn,
4946
+ onClick: () => handleDeleteCdn(index),
4947
+ title: "Delete CDN URL",
4948
+ children: /* @__PURE__ */ jsx9("svg", { width: "16", height: "16", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx9("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) })
4949
+ }
4950
+ )
4951
+ ] }, index)) }),
4952
+ /* @__PURE__ */ jsxs9("button", { css: styles9.cdnAddBtn, onClick: handleAddCdn, children: [
4953
+ /* @__PURE__ */ jsx9("svg", { width: "14", height: "14", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx9("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 4v16m8-8H4" }) }),
4954
+ "Add CDN URL"
4955
+ ] }),
4956
+ cdnUrls.length > 0 && /* @__PURE__ */ jsx9("p", { css: styles9.warning, children: "Warning: Changing CDN URLs may break image references. The index numbers correspond to image `c` values." })
4957
+ ] })
4958
+ ] }),
4959
+ /* @__PURE__ */ jsxs9("section", { children: [
4960
+ /* @__PURE__ */ jsx9("h3", { css: styles9.sectionTitle, children: "Cloudflare R2 Credentials" }),
4961
+ /* @__PURE__ */ jsx9("p", { css: styles9.description, children: "Configure in .env.local file:" }),
4962
+ /* @__PURE__ */ jsxs9("div", { css: styles9.codeWrapper, children: [
4963
+ /* @__PURE__ */ jsxs9("button", { css: styles9.copyBtn, onClick: handleCopy, title: "Copy to clipboard", children: [
4964
+ copied && /* @__PURE__ */ jsx9("span", { css: styles9.tooltip, children: "Copied!" }),
4965
+ /* @__PURE__ */ jsx9("svg", { css: styles9.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx9("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" }) })
4396
4966
  ] }),
4397
- /* @__PURE__ */ jsxs8("div", { css: styles8.code, children: [
4398
- /* @__PURE__ */ jsx8("p", { css: styles8.codeLine, children: "CLOUDFLARE_R2_ACCOUNT_ID=abc123def456ghi789" }),
4399
- /* @__PURE__ */ jsx8("p", { css: styles8.codeLine, children: "CLOUDFLARE_R2_ACCESS_KEY_ID=your_access_key_id_here" }),
4400
- /* @__PURE__ */ jsx8("p", { css: styles8.codeLine, children: "CLOUDFLARE_R2_SECRET_ACCESS_KEY=your_secret_access_key_here" }),
4401
- /* @__PURE__ */ jsx8("p", { css: styles8.codeLine, children: "CLOUDFLARE_R2_BUCKET_NAME=my-images-bucket" }),
4402
- /* @__PURE__ */ jsx8("p", { css: styles8.codeLine, children: "CLOUDFLARE_R2_PUBLIC_URL=https://cdn.yourdomain.com" })
4967
+ /* @__PURE__ */ jsxs9("div", { css: styles9.code, children: [
4968
+ /* @__PURE__ */ jsx9("p", { css: styles9.codeLine, children: "CLOUDFLARE_R2_ACCOUNT_ID=abc123def456ghi789" }),
4969
+ /* @__PURE__ */ jsx9("p", { css: styles9.codeLine, children: "CLOUDFLARE_R2_ACCESS_KEY_ID=your_access_key_id_here" }),
4970
+ /* @__PURE__ */ jsx9("p", { css: styles9.codeLine, children: "CLOUDFLARE_R2_SECRET_ACCESS_KEY=your_secret_access_key_here" }),
4971
+ /* @__PURE__ */ jsx9("p", { css: styles9.codeLine, children: "CLOUDFLARE_R2_BUCKET_NAME=my-images-bucket" }),
4972
+ /* @__PURE__ */ jsx9("p", { css: styles9.codeLine, children: "CLOUDFLARE_R2_PUBLIC_URL=https://cdn.yourdomain.com" })
4403
4973
  ] })
4404
4974
  ] })
4405
4975
  ] }),
4406
- /* @__PURE__ */ jsxs8("section", { children: [
4407
- /* @__PURE__ */ jsx8("h3", { css: styles8.sectionTitle, children: "Thumbnail Sizes" }),
4408
- /* @__PURE__ */ jsxs8("div", { css: styles8.grid, children: [
4409
- /* @__PURE__ */ jsxs8("div", { children: [
4410
- /* @__PURE__ */ jsx8("label", { css: styles8.label, children: "Small" }),
4411
- /* @__PURE__ */ jsx8("input", { css: styles8.input, type: "number", defaultValue: 300 })
4976
+ /* @__PURE__ */ jsxs9("section", { children: [
4977
+ /* @__PURE__ */ jsx9("h3", { css: styles9.sectionTitle, children: "Thumbnail Sizes" }),
4978
+ /* @__PURE__ */ jsxs9("div", { css: styles9.grid, children: [
4979
+ /* @__PURE__ */ jsxs9("div", { children: [
4980
+ /* @__PURE__ */ jsx9("label", { css: styles9.label, children: "Small" }),
4981
+ /* @__PURE__ */ jsx9("input", { css: styles9.input, type: "number", defaultValue: 300 })
4412
4982
  ] }),
4413
- /* @__PURE__ */ jsxs8("div", { children: [
4414
- /* @__PURE__ */ jsx8("label", { css: styles8.label, children: "Medium" }),
4415
- /* @__PURE__ */ jsx8("input", { css: styles8.input, type: "number", defaultValue: 700 })
4983
+ /* @__PURE__ */ jsxs9("div", { children: [
4984
+ /* @__PURE__ */ jsx9("label", { css: styles9.label, children: "Medium" }),
4985
+ /* @__PURE__ */ jsx9("input", { css: styles9.input, type: "number", defaultValue: 700 })
4416
4986
  ] }),
4417
- /* @__PURE__ */ jsxs8("div", { children: [
4418
- /* @__PURE__ */ jsx8("label", { css: styles8.label, children: "Large" }),
4419
- /* @__PURE__ */ jsx8("input", { css: styles8.input, type: "number", defaultValue: 1400 })
4987
+ /* @__PURE__ */ jsxs9("div", { children: [
4988
+ /* @__PURE__ */ jsx9("label", { css: styles9.label, children: "Large" }),
4989
+ /* @__PURE__ */ jsx9("input", { css: styles9.input, type: "number", defaultValue: 1400 })
4420
4990
  ] })
4421
4991
  ] })
4422
4992
  ] })
4423
4993
  ] }),
4424
- /* @__PURE__ */ jsxs8("div", { css: styles8.footer, children: [
4425
- /* @__PURE__ */ jsx8("button", { css: styles8.cancelBtn, onClick: onClose, children: "Cancel" }),
4426
- /* @__PURE__ */ jsx8("button", { css: styles8.saveBtn, children: "Save Changes" })
4994
+ /* @__PURE__ */ jsxs9("div", { css: styles9.footer, children: [
4995
+ /* @__PURE__ */ jsx9("button", { css: styles9.cancelBtn, onClick: onClose, children: "Cancel" }),
4996
+ /* @__PURE__ */ jsx9("button", { css: styles9.saveBtn, onClick: handleSave, disabled: saving || !hasChanges, children: saving ? "Saving..." : "Save Changes" })
4427
4997
  ] })
4428
4998
  ] }) });
4429
4999
  }
4430
5000
 
4431
5001
  // src/components/ErrorModal.tsx
4432
- import { css as css9 } from "@emotion/react";
4433
- import { jsx as jsx9, jsxs as jsxs9 } from "@emotion/react/jsx-runtime";
4434
- var styles9 = {
4435
- overlay: css9`
5002
+ import { css as css10 } from "@emotion/react";
5003
+ import { jsx as jsx10, jsxs as jsxs10 } from "@emotion/react/jsx-runtime";
5004
+ var styles10 = {
5005
+ overlay: css10`
4436
5006
  position: fixed;
4437
5007
  inset: 0;
4438
5008
  background: rgba(0, 0, 0, 0.5);
@@ -4441,7 +5011,7 @@ var styles9 = {
4441
5011
  justify-content: center;
4442
5012
  z-index: 1100;
4443
5013
  `,
4444
- modal: css9`
5014
+ modal: css10`
4445
5015
  background: ${colors.surface};
4446
5016
  border-radius: 12px;
4447
5017
  padding: 24px;
@@ -4449,31 +5019,31 @@ var styles9 = {
4449
5019
  width: 90%;
4450
5020
  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2);
4451
5021
  `,
4452
- header: css9`
5022
+ header: css10`
4453
5023
  display: flex;
4454
5024
  align-items: center;
4455
5025
  gap: 12px;
4456
5026
  margin-bottom: 12px;
4457
5027
  `,
4458
- icon: css9`
5028
+ icon: css10`
4459
5029
  width: 24px;
4460
5030
  height: 24px;
4461
5031
  color: ${colors.danger};
4462
5032
  flex-shrink: 0;
4463
5033
  `,
4464
- title: css9`
5034
+ title: css10`
4465
5035
  font-size: ${fontSize.lg};
4466
5036
  font-weight: 600;
4467
5037
  color: ${colors.text};
4468
5038
  margin: 0;
4469
5039
  `,
4470
- message: css9`
5040
+ message: css10`
4471
5041
  font-size: ${fontSize.base};
4472
5042
  color: ${colors.textSecondary};
4473
5043
  margin: 0 0 20px 0;
4474
5044
  line-height: 1.5;
4475
5045
  `,
4476
- button: css9`
5046
+ button: css10`
4477
5047
  width: 100%;
4478
5048
  padding: 10px 16px;
4479
5049
  border-radius: 6px;
@@ -4493,28 +5063,28 @@ var styles9 = {
4493
5063
  function ErrorModal() {
4494
5064
  const { error, clearError } = useStudio();
4495
5065
  if (!error) return null;
4496
- return /* @__PURE__ */ jsx9("div", { css: styles9.overlay, onClick: clearError, children: /* @__PURE__ */ jsxs9("div", { css: styles9.modal, onClick: (e) => e.stopPropagation(), children: [
4497
- /* @__PURE__ */ jsxs9("div", { css: styles9.header, children: [
4498
- /* @__PURE__ */ jsx9("svg", { css: styles9.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx9("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" }) }),
4499
- /* @__PURE__ */ jsx9("h3", { css: styles9.title, children: error.title })
5066
+ return /* @__PURE__ */ jsx10("div", { css: styles10.overlay, onClick: clearError, children: /* @__PURE__ */ jsxs10("div", { css: styles10.modal, onClick: (e) => e.stopPropagation(), children: [
5067
+ /* @__PURE__ */ jsxs10("div", { css: styles10.header, children: [
5068
+ /* @__PURE__ */ jsx10("svg", { css: styles10.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx10("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" }) }),
5069
+ /* @__PURE__ */ jsx10("h3", { css: styles10.title, children: error.title })
4500
5070
  ] }),
4501
- /* @__PURE__ */ jsx9("p", { css: styles9.message, children: error.message }),
4502
- /* @__PURE__ */ jsx9("button", { css: styles9.button, onClick: clearError, children: "OK" })
5071
+ /* @__PURE__ */ jsx10("p", { css: styles10.message, children: error.message }),
5072
+ /* @__PURE__ */ jsx10("button", { css: styles10.button, onClick: clearError, children: "OK" })
4503
5073
  ] }) });
4504
5074
  }
4505
5075
 
4506
5076
  // src/components/StudioUI.tsx
4507
- import { jsx as jsx10, jsxs as jsxs10 } from "@emotion/react/jsx-runtime";
5077
+ import { jsx as jsx11, jsxs as jsxs11 } from "@emotion/react/jsx-runtime";
4508
5078
  var btnHeight3 = "36px";
4509
- var styles10 = {
4510
- container: css10`
5079
+ var styles11 = {
5080
+ container: css11`
4511
5081
  ${baseReset}
4512
5082
  display: flex;
4513
5083
  flex-direction: column;
4514
5084
  height: 100%;
4515
5085
  background: ${colors.background};
4516
5086
  `,
4517
- header: css10`
5087
+ header: css11`
4518
5088
  display: flex;
4519
5089
  align-items: center;
4520
5090
  justify-content: space-between;
@@ -4523,7 +5093,7 @@ var styles10 = {
4523
5093
  border-bottom: 1px solid ${colors.border};
4524
5094
  position: relative;
4525
5095
  `,
4526
- title: css10`
5096
+ title: css11`
4527
5097
  font-size: ${fontSize.lg};
4528
5098
  font-weight: 600;
4529
5099
  color: ${colors.text};
@@ -4531,14 +5101,14 @@ var styles10 = {
4531
5101
  letter-spacing: -0.02em;
4532
5102
  flex-shrink: 0;
4533
5103
  `,
4534
- headerLeft: css10`
5104
+ headerLeft: css11`
4535
5105
  display: flex;
4536
5106
  align-items: center;
4537
5107
  gap: 12px;
4538
5108
  flex: 1;
4539
5109
  min-width: 0;
4540
5110
  `,
4541
- headerCenter: css10`
5111
+ headerCenter: css11`
4542
5112
  position: absolute;
4543
5113
  left: 50%;
4544
5114
  transform: translateX(-50%);
@@ -4546,7 +5116,7 @@ var styles10 = {
4546
5116
  align-items: center;
4547
5117
  max-width: 50%;
4548
5118
  `,
4549
- breadcrumbs: css10`
5119
+ breadcrumbs: css11`
4550
5120
  display: flex;
4551
5121
  align-items: center;
4552
5122
  gap: 6px;
@@ -4554,11 +5124,11 @@ var styles10 = {
4554
5124
  color: ${colors.textSecondary};
4555
5125
  overflow: hidden;
4556
5126
  `,
4557
- breadcrumbSeparator: css10`
5127
+ breadcrumbSeparator: css11`
4558
5128
  color: ${colors.border};
4559
5129
  flex-shrink: 0;
4560
5130
  `,
4561
- breadcrumbItem: css10`
5131
+ breadcrumbItem: css11`
4562
5132
  color: ${colors.textSecondary};
4563
5133
  text-decoration: none;
4564
5134
  cursor: pointer;
@@ -4569,19 +5139,19 @@ var styles10 = {
4569
5139
  color: ${colors.primary};
4570
5140
  }
4571
5141
  `,
4572
- breadcrumbCurrent: css10`
5142
+ breadcrumbCurrent: css11`
4573
5143
  color: ${colors.text};
4574
5144
  font-weight: 500;
4575
5145
  white-space: nowrap;
4576
5146
  overflow: hidden;
4577
5147
  text-overflow: ellipsis;
4578
5148
  `,
4579
- headerActions: css10`
5149
+ headerActions: css11`
4580
5150
  display: flex;
4581
5151
  align-items: center;
4582
5152
  gap: 8px;
4583
5153
  `,
4584
- headerBtn: css10`
5154
+ headerBtn: css11`
4585
5155
  height: ${btnHeight3};
4586
5156
  padding: 0 12px;
4587
5157
  background: ${colors.surface};
@@ -4598,17 +5168,17 @@ var styles10 = {
4598
5168
  border-color: ${colors.borderHover};
4599
5169
  }
4600
5170
  `,
4601
- headerIcon: css10`
5171
+ headerIcon: css11`
4602
5172
  width: 16px;
4603
5173
  height: 16px;
4604
5174
  color: ${colors.textSecondary};
4605
5175
  `,
4606
- content: css10`
5176
+ content: css11`
4607
5177
  flex: 1;
4608
5178
  display: flex;
4609
5179
  overflow: hidden;
4610
5180
  `,
4611
- fileBrowser: css10`
5181
+ fileBrowser: css11`
4612
5182
  flex: 1;
4613
5183
  min-width: 0;
4614
5184
  overflow: auto;
@@ -4616,7 +5186,7 @@ var styles10 = {
4616
5186
  display: flex;
4617
5187
  flex-direction: column;
4618
5188
  `,
4619
- dropOverlay: css10`
5189
+ dropOverlay: css11`
4620
5190
  position: absolute;
4621
5191
  top: 0;
4622
5192
  left: 0;
@@ -4631,7 +5201,7 @@ var styles10 = {
4631
5201
  z-index: 50;
4632
5202
  pointer-events: none;
4633
5203
  `,
4634
- dropMessage: css10`
5204
+ dropMessage: css11`
4635
5205
  display: flex;
4636
5206
  flex-direction: column;
4637
5207
  align-items: center;
@@ -4640,50 +5210,50 @@ var styles10 = {
4640
5210
  font-size: ${fontSize.lg};
4641
5211
  font-weight: 600;
4642
5212
  `,
4643
- dropIcon: css10`
5213
+ dropIcon: css11`
4644
5214
  width: 48px;
4645
5215
  height: 48px;
4646
5216
  `
4647
5217
  };
4648
5218
  function StudioUI({ onClose, isVisible = true }) {
4649
- const [currentPath, setCurrentPathInternal] = useState9("public");
4650
- const [selectedItems, setSelectedItems] = useState9(/* @__PURE__ */ new Set());
4651
- const [lastSelectedPath, setLastSelectedPath] = useState9(null);
4652
- const [viewMode, setViewMode] = useState9("grid");
4653
- const [focusedItem, setFocusedItem] = useState9(null);
4654
- const [meta, setMeta] = useState9(null);
4655
- const [isLoading, setIsLoading] = useState9(false);
4656
- const [refreshKey, setRefreshKey] = useState9(0);
4657
- const [scanRequested, setScanRequested] = useState9(false);
4658
- const [searchQuery, setSearchQuery] = useState9("");
4659
- const [error, setError] = useState9(null);
4660
- const [isDragging, setIsDragging] = useState9(false);
4661
- const triggerRefresh = useCallback3(() => {
5219
+ const [currentPath, setCurrentPathInternal] = useState10("public");
5220
+ const [selectedItems, setSelectedItems] = useState10(/* @__PURE__ */ new Set());
5221
+ const [lastSelectedPath, setLastSelectedPath] = useState10(null);
5222
+ const [viewMode, setViewMode] = useState10("grid");
5223
+ const [focusedItem, setFocusedItem] = useState10(null);
5224
+ const [meta, setMeta] = useState10(null);
5225
+ const [isLoading, setIsLoading] = useState10(false);
5226
+ const [refreshKey, setRefreshKey] = useState10(0);
5227
+ const [scanRequested, setScanRequested] = useState10(false);
5228
+ const [searchQuery, setSearchQuery] = useState10("");
5229
+ const [error, setError] = useState10(null);
5230
+ const [isDragging, setIsDragging] = useState10(false);
5231
+ const triggerRefresh = useCallback5(() => {
4662
5232
  setRefreshKey((k) => k + 1);
4663
5233
  }, []);
4664
- const triggerScan = useCallback3(() => {
5234
+ const triggerScan = useCallback5(() => {
4665
5235
  setScanRequested(true);
4666
5236
  }, []);
4667
- const clearScanRequest = useCallback3(() => {
5237
+ const clearScanRequest = useCallback5(() => {
4668
5238
  setScanRequested(false);
4669
5239
  }, []);
4670
- const showError = useCallback3((title, message) => {
5240
+ const showError = useCallback5((title, message) => {
4671
5241
  setError({ title, message });
4672
5242
  }, []);
4673
- const clearError = useCallback3(() => {
5243
+ const clearError = useCallback5(() => {
4674
5244
  setError(null);
4675
5245
  }, []);
4676
- const handleDragOver = useCallback3((e) => {
5246
+ const handleDragOver = useCallback5((e) => {
4677
5247
  e.preventDefault();
4678
5248
  e.stopPropagation();
4679
5249
  setIsDragging(true);
4680
5250
  }, []);
4681
- const handleDragLeave = useCallback3((e) => {
5251
+ const handleDragLeave = useCallback5((e) => {
4682
5252
  e.preventDefault();
4683
5253
  e.stopPropagation();
4684
5254
  setIsDragging(false);
4685
5255
  }, []);
4686
- const handleDrop = useCallback3(async (e) => {
5256
+ const handleDrop = useCallback5(async (e) => {
4687
5257
  e.preventDefault();
4688
5258
  e.stopPropagation();
4689
5259
  setIsDragging(false);
@@ -4707,19 +5277,19 @@ function StudioUI({ onClose, isVisible = true }) {
4707
5277
  }
4708
5278
  triggerRefresh();
4709
5279
  }, [currentPath, triggerRefresh]);
4710
- const navigateUp = useCallback3(() => {
5280
+ const navigateUp = useCallback5(() => {
4711
5281
  if (currentPath === "public") return;
4712
5282
  const parts = currentPath.split("/");
4713
5283
  parts.pop();
4714
5284
  setCurrentPathInternal(parts.join("/") || "public");
4715
5285
  setSelectedItems(/* @__PURE__ */ new Set());
4716
5286
  }, [currentPath]);
4717
- const setCurrentPath = useCallback3((path) => {
5287
+ const setCurrentPath = useCallback5((path) => {
4718
5288
  setCurrentPathInternal(path);
4719
5289
  setSelectedItems(/* @__PURE__ */ new Set());
4720
5290
  setFocusedItem(null);
4721
5291
  }, []);
4722
- const toggleSelection = useCallback3((path) => {
5292
+ const toggleSelection = useCallback5((path) => {
4723
5293
  setSelectedItems((prev) => {
4724
5294
  const next = new Set(prev);
4725
5295
  if (next.has(path)) {
@@ -4731,7 +5301,7 @@ function StudioUI({ onClose, isVisible = true }) {
4731
5301
  });
4732
5302
  setLastSelectedPath(path);
4733
5303
  }, []);
4734
- const selectRange = useCallback3((fromPath, toPath, allItems) => {
5304
+ const selectRange = useCallback5((fromPath, toPath, allItems) => {
4735
5305
  const fromIndex = allItems.findIndex((item) => item.path === fromPath);
4736
5306
  const toIndex = allItems.findIndex((item) => item.path === toPath);
4737
5307
  if (fromIndex === -1 || toIndex === -1) return;
@@ -4746,13 +5316,13 @@ function StudioUI({ onClose, isVisible = true }) {
4746
5316
  });
4747
5317
  setLastSelectedPath(toPath);
4748
5318
  }, []);
4749
- const selectAll = useCallback3((items) => {
5319
+ const selectAll = useCallback5((items) => {
4750
5320
  setSelectedItems(new Set(items.map((item) => item.path)));
4751
5321
  }, []);
4752
- const clearSelection = useCallback3(() => {
5322
+ const clearSelection = useCallback5(() => {
4753
5323
  setSelectedItems(/* @__PURE__ */ new Set());
4754
5324
  }, []);
4755
- const handleKeyDown = useCallback3(
5325
+ const handleKeyDown = useCallback5(
4756
5326
  (e) => {
4757
5327
  if (e.key === "Escape") {
4758
5328
  const target = e.target;
@@ -4768,7 +5338,7 @@ function StudioUI({ onClose, isVisible = true }) {
4768
5338
  },
4769
5339
  [onClose, focusedItem]
4770
5340
  );
4771
- useEffect4(() => {
5341
+ useEffect5(() => {
4772
5342
  if (isVisible) {
4773
5343
  document.addEventListener("keydown", handleKeyDown);
4774
5344
  document.body.style.overflow = "hidden";
@@ -4812,42 +5382,42 @@ function StudioUI({ onClose, isVisible = true }) {
4812
5382
  showError,
4813
5383
  clearError
4814
5384
  };
4815
- return /* @__PURE__ */ jsx10(StudioContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs10("div", { css: styles10.container, children: [
4816
- /* @__PURE__ */ jsxs10("div", { css: styles10.header, children: [
4817
- /* @__PURE__ */ jsx10("div", { css: styles10.headerLeft, children: /* @__PURE__ */ jsx10("h1", { css: styles10.title, children: "Studio" }) }),
4818
- /* @__PURE__ */ jsx10("div", { css: styles10.headerCenter, children: /* @__PURE__ */ jsx10(Breadcrumbs, { currentPath, onNavigate: setCurrentPath }) }),
4819
- /* @__PURE__ */ jsxs10("div", { css: styles10.headerActions, children: [
4820
- /* @__PURE__ */ jsx10(StudioSettings, {}),
4821
- /* @__PURE__ */ jsx10(
5385
+ return /* @__PURE__ */ jsx11(StudioContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs11("div", { css: styles11.container, children: [
5386
+ /* @__PURE__ */ jsxs11("div", { css: styles11.header, children: [
5387
+ /* @__PURE__ */ jsx11("div", { css: styles11.headerLeft, children: /* @__PURE__ */ jsx11("h1", { css: styles11.title, children: "Studio" }) }),
5388
+ /* @__PURE__ */ jsx11("div", { css: styles11.headerCenter, children: /* @__PURE__ */ jsx11(Breadcrumbs, { currentPath, onNavigate: setCurrentPath }) }),
5389
+ /* @__PURE__ */ jsxs11("div", { css: styles11.headerActions, children: [
5390
+ /* @__PURE__ */ jsx11(StudioSettings, {}),
5391
+ /* @__PURE__ */ jsx11(
4822
5392
  "button",
4823
5393
  {
4824
- css: styles10.headerBtn,
5394
+ css: styles11.headerBtn,
4825
5395
  onClick: onClose,
4826
5396
  "aria-label": "Close Studio",
4827
- children: /* @__PURE__ */ jsx10(CloseIcon, {})
5397
+ children: /* @__PURE__ */ jsx11(CloseIcon, {})
4828
5398
  }
4829
5399
  )
4830
5400
  ] })
4831
5401
  ] }),
4832
- /* @__PURE__ */ jsx10(StudioToolbar, {}),
4833
- /* @__PURE__ */ jsxs10(
5402
+ /* @__PURE__ */ jsx11(StudioToolbar, {}),
5403
+ /* @__PURE__ */ jsxs11(
4834
5404
  "div",
4835
5405
  {
4836
- css: styles10.content,
5406
+ css: styles11.content,
4837
5407
  onDragOver: handleDragOver,
4838
5408
  onDragLeave: handleDragLeave,
4839
5409
  onDrop: handleDrop,
4840
5410
  children: [
4841
- isDragging && /* @__PURE__ */ jsx10("div", { css: styles10.dropOverlay, children: /* @__PURE__ */ jsxs10("div", { css: styles10.dropMessage, children: [
4842
- /* @__PURE__ */ jsx10("svg", { css: styles10.dropIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx10("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12" }) }),
4843
- /* @__PURE__ */ jsx10("span", { children: "Drop files to upload" })
5411
+ isDragging && /* @__PURE__ */ jsx11("div", { css: styles11.dropOverlay, children: /* @__PURE__ */ jsxs11("div", { css: styles11.dropMessage, children: [
5412
+ /* @__PURE__ */ jsx11("svg", { css: styles11.dropIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx11("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12" }) }),
5413
+ /* @__PURE__ */ jsx11("span", { children: "Drop files to upload" })
4844
5414
  ] }) }),
4845
- /* @__PURE__ */ jsx10("div", { css: styles10.fileBrowser, children: viewMode === "grid" ? /* @__PURE__ */ jsx10(StudioFileGrid, {}) : /* @__PURE__ */ jsx10(StudioFileList, {}) })
5415
+ /* @__PURE__ */ jsx11("div", { css: styles11.fileBrowser, children: viewMode === "grid" ? /* @__PURE__ */ jsx11(StudioFileGrid, {}) : /* @__PURE__ */ jsx11(StudioFileList, {}) })
4846
5416
  ]
4847
5417
  }
4848
5418
  ),
4849
- focusedItem && /* @__PURE__ */ jsx10(StudioDetailView, {}),
4850
- /* @__PURE__ */ jsx10(ErrorModal, {})
5419
+ focusedItem && /* @__PURE__ */ jsx11(StudioDetailView, {}),
5420
+ /* @__PURE__ */ jsx11(ErrorModal, {})
4851
5421
  ] }) });
4852
5422
  }
4853
5423
  function Breadcrumbs({ currentPath, onNavigate }) {
@@ -4856,12 +5426,12 @@ function Breadcrumbs({ currentPath, onNavigate }) {
4856
5426
  name: part,
4857
5427
  path: parts.slice(0, index + 1).join("/")
4858
5428
  }));
4859
- return /* @__PURE__ */ jsx10("div", { css: styles10.breadcrumbs, children: breadcrumbs.map((crumb, index) => /* @__PURE__ */ jsxs10("span", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
4860
- index > 0 && /* @__PURE__ */ jsx10("span", { css: styles10.breadcrumbSeparator, children: "/" }),
4861
- index === breadcrumbs.length - 1 ? /* @__PURE__ */ jsx10("span", { css: styles10.breadcrumbCurrent, children: crumb.name }) : /* @__PURE__ */ jsx10(
5429
+ return /* @__PURE__ */ jsx11("div", { css: styles11.breadcrumbs, children: breadcrumbs.map((crumb, index) => /* @__PURE__ */ jsxs11("span", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
5430
+ index > 0 && /* @__PURE__ */ jsx11("span", { css: styles11.breadcrumbSeparator, children: "/" }),
5431
+ index === breadcrumbs.length - 1 ? /* @__PURE__ */ jsx11("span", { css: styles11.breadcrumbCurrent, children: crumb.name }) : /* @__PURE__ */ jsx11(
4862
5432
  "span",
4863
5433
  {
4864
- css: styles10.breadcrumbItem,
5434
+ css: styles11.breadcrumbItem,
4865
5435
  onClick: () => onNavigate(crumb.path),
4866
5436
  children: crumb.name
4867
5437
  }
@@ -4869,10 +5439,10 @@ function Breadcrumbs({ currentPath, onNavigate }) {
4869
5439
  ] }, crumb.path)) });
4870
5440
  }
4871
5441
  function CloseIcon() {
4872
- return /* @__PURE__ */ jsxs10(
5442
+ return /* @__PURE__ */ jsxs11(
4873
5443
  "svg",
4874
5444
  {
4875
- css: styles10.headerIcon,
5445
+ css: styles11.headerIcon,
4876
5446
  xmlns: "http://www.w3.org/2000/svg",
4877
5447
  viewBox: "0 0 24 24",
4878
5448
  fill: "none",
@@ -4881,8 +5451,8 @@ function CloseIcon() {
4881
5451
  strokeLinecap: "round",
4882
5452
  strokeLinejoin: "round",
4883
5453
  children: [
4884
- /* @__PURE__ */ jsx10("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
4885
- /* @__PURE__ */ jsx10("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
5454
+ /* @__PURE__ */ jsx11("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
5455
+ /* @__PURE__ */ jsx11("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
4886
5456
  ]
4887
5457
  }
4888
5458
  );
@@ -4892,4 +5462,4 @@ export {
4892
5462
  StudioUI,
4893
5463
  StudioUI_default as default
4894
5464
  };
4895
- //# sourceMappingURL=StudioUI-7VQHCHFQ.mjs.map
5465
+ //# sourceMappingURL=StudioUI-GKE5ZWKW.mjs.map