@gallop.software/studio 0.1.29 → 0.1.31

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.
@@ -951,7 +951,7 @@ function ImageStackIcon() {
951
951
  }
952
952
 
953
953
  // src/components/StudioFileGrid.tsx
954
- import { useEffect, useState as useState2 } from "react";
954
+ import { useEffect, useState as useState2, useRef as useRef2 } from "react";
955
955
  import { css as css3, keyframes as keyframes3 } from "@emotion/react";
956
956
  import { jsx as jsx3, jsxs as jsxs3 } from "@emotion/react/jsx-runtime";
957
957
  var spin2 = keyframes3`
@@ -1173,9 +1173,15 @@ function StudioFileGrid() {
1173
1173
  const { currentPath, setCurrentPath, navigateUp, selectedItems, toggleSelection, selectRange, lastSelectedPath, selectAll, clearSelection, refreshKey, setFocusedItem } = useStudio();
1174
1174
  const [items, setItems] = useState2([]);
1175
1175
  const [loading, setLoading] = useState2(true);
1176
+ const isInitialLoad = useRef2(true);
1177
+ const lastPath = useRef2(currentPath);
1176
1178
  useEffect(() => {
1177
1179
  async function loadItems() {
1178
- setLoading(true);
1180
+ const isPathChange = lastPath.current !== currentPath;
1181
+ if (isInitialLoad.current || isPathChange) {
1182
+ setLoading(true);
1183
+ }
1184
+ lastPath.current = currentPath;
1179
1185
  try {
1180
1186
  const response = await fetch(`/api/studio/list?path=${encodeURIComponent(currentPath)}`);
1181
1187
  if (response.ok) {
@@ -1186,6 +1192,7 @@ function StudioFileGrid() {
1186
1192
  console.error("Failed to load items:", error);
1187
1193
  }
1188
1194
  setLoading(false);
1195
+ isInitialLoad.current = false;
1189
1196
  }
1190
1197
  loadItems();
1191
1198
  }, [currentPath, refreshKey]);
@@ -1353,7 +1360,7 @@ function truncateMiddle(str, maxLength = 24) {
1353
1360
  }
1354
1361
 
1355
1362
  // src/components/StudioFileList.tsx
1356
- import { useEffect as useEffect2, useState as useState3 } from "react";
1363
+ import { useEffect as useEffect2, useState as useState3, useRef as useRef3 } from "react";
1357
1364
  import { css as css4, keyframes as keyframes4 } from "@emotion/react";
1358
1365
  import { jsx as jsx4, jsxs as jsxs4 } from "@emotion/react/jsx-runtime";
1359
1366
  var spin3 = keyframes4`
@@ -1538,9 +1545,15 @@ function StudioFileList() {
1538
1545
  const { currentPath, setCurrentPath, navigateUp, selectedItems, toggleSelection, selectRange, lastSelectedPath, selectAll, clearSelection, refreshKey, setFocusedItem } = useStudio();
1539
1546
  const [items, setItems] = useState3([]);
1540
1547
  const [loading, setLoading] = useState3(true);
1548
+ const isInitialLoad = useRef3(true);
1549
+ const lastPath = useRef3(currentPath);
1541
1550
  useEffect2(() => {
1542
1551
  async function loadItems() {
1543
- setLoading(true);
1552
+ const isPathChange = lastPath.current !== currentPath;
1553
+ if (isInitialLoad.current || isPathChange) {
1554
+ setLoading(true);
1555
+ }
1556
+ lastPath.current = currentPath;
1544
1557
  try {
1545
1558
  const response = await fetch(`/api/studio/list?path=${encodeURIComponent(currentPath)}`);
1546
1559
  if (response.ok) {
@@ -1551,6 +1564,7 @@ function StudioFileList() {
1551
1564
  console.error("Failed to load items:", error);
1552
1565
  }
1553
1566
  setLoading(false);
1567
+ isInitialLoad.current = false;
1554
1568
  }
1555
1569
  loadItems();
1556
1570
  }, [currentPath, refreshKey]);
@@ -2355,7 +2369,7 @@ var styles7 = {
2355
2369
  padding: 20px 24px;
2356
2370
  `
2357
2371
  };
2358
- function StudioUI({ onClose }) {
2372
+ function StudioUI({ onClose, isVisible = true }) {
2359
2373
  const [currentPath, setCurrentPathInternal] = useState6("public");
2360
2374
  const [selectedItems, setSelectedItems] = useState6(/* @__PURE__ */ new Set());
2361
2375
  const [lastSelectedPath, setLastSelectedPath] = useState6(null);
@@ -2425,13 +2439,15 @@ function StudioUI({ onClose }) {
2425
2439
  [onClose, focusedItem]
2426
2440
  );
2427
2441
  useEffect3(() => {
2428
- document.addEventListener("keydown", handleKeyDown);
2429
- document.body.style.overflow = "hidden";
2442
+ if (isVisible) {
2443
+ document.addEventListener("keydown", handleKeyDown);
2444
+ document.body.style.overflow = "hidden";
2445
+ }
2430
2446
  return () => {
2431
2447
  document.removeEventListener("keydown", handleKeyDown);
2432
2448
  document.body.style.overflow = "";
2433
2449
  };
2434
- }, [handleKeyDown]);
2450
+ }, [handleKeyDown, isVisible]);
2435
2451
  const contextValue = {
2436
2452
  isOpen: true,
2437
2453
  openStudio: () => {
@@ -2502,4 +2518,4 @@ export {
2502
2518
  StudioUI,
2503
2519
  StudioUI_default as default
2504
2520
  };
2505
- //# sourceMappingURL=StudioUI-SW6ULBQI.mjs.map
2521
+ //# sourceMappingURL=StudioUI-WOZEZEKH.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/StudioUI.tsx","../src/components/StudioContext.tsx","../src/components/StudioToolbar.tsx","../src/components/StudioModal.tsx","../src/components/StudioFileGrid.tsx","../src/components/StudioFileList.tsx","../src/components/StudioDetailView.tsx","../src/components/StudioSettings.tsx"],"sourcesContent":["/** @jsxImportSource @emotion/react */\n'use client'\n\nimport { useEffect, useCallback, useState } from 'react'\nimport { css } from '@emotion/react'\nimport { StudioContext } from './StudioContext'\nimport { StudioToolbar } from './StudioToolbar'\nimport { StudioFileGrid } from './StudioFileGrid'\nimport { StudioFileList } from './StudioFileList'\nimport { StudioDetailView } from './StudioDetailView'\nimport { StudioSettings } from './StudioSettings'\nimport { colors, fontSize, baseReset } from './tokens'\nimport type { FileItem, StudioMeta } from '../types'\n\ninterface StudioUIProps {\n onClose: () => void\n isVisible?: boolean\n}\n\n// Standard button height for consistency\nconst btnHeight = '36px'\n\nconst styles = {\n container: css`\n ${baseReset}\n display: flex;\n flex-direction: column;\n height: 100%;\n background: ${colors.background};\n `,\n header: css`\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 24px;\n background: ${colors.surface};\n border-bottom: 1px solid ${colors.border};\n `,\n title: css`\n font-size: ${fontSize.lg};\n font-weight: 600;\n color: ${colors.text};\n margin: 0;\n letter-spacing: -0.02em;\n `,\n headerActions: css`\n display: flex;\n align-items: center;\n gap: 8px;\n `,\n headerBtn: css`\n height: ${btnHeight};\n padding: 0 12px;\n background: ${colors.surface};\n border: 1px solid ${colors.border};\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n \n &:hover {\n background-color: ${colors.surfaceHover};\n border-color: ${colors.borderHover};\n }\n `,\n headerIcon: css`\n width: 16px;\n height: 16px;\n color: ${colors.textSecondary};\n `,\n content: css`\n flex: 1;\n display: flex;\n overflow: hidden;\n `,\n fileBrowser: css`\n flex: 1;\n min-width: 0;\n overflow: auto;\n padding: 20px 24px;\n `,\n}\n\n/**\n * Main Studio UI - contains all panels and manages internal state\n * Rendered inside the modal via lazy loading\n */\nexport function StudioUI({ onClose, isVisible = true }: StudioUIProps) {\n const [currentPath, setCurrentPathInternal] = useState('public')\n const [selectedItems, setSelectedItems] = useState<Set<string>>(new Set())\n const [lastSelectedPath, setLastSelectedPath] = useState<string | null>(null)\n const [viewMode, setViewMode] = useState<'grid' | 'list'>('grid')\n const [focusedItem, setFocusedItem] = useState<FileItem | null>(null)\n const [meta, setMeta] = useState<StudioMeta | null>(null)\n const [isLoading, setIsLoading] = useState(false)\n const [refreshKey, setRefreshKey] = useState(0)\n\n const triggerRefresh = useCallback(() => {\n setRefreshKey((k) => k + 1)\n }, [])\n\n const navigateUp = useCallback(() => {\n if (currentPath === 'public') return\n const parts = currentPath.split('/')\n parts.pop()\n setCurrentPathInternal(parts.join('/') || 'public')\n setSelectedItems(new Set())\n }, [currentPath])\n\n const setCurrentPath = useCallback((path: string) => {\n setCurrentPathInternal(path)\n setSelectedItems(new Set())\n setFocusedItem(null)\n }, [])\n\n const toggleSelection = useCallback((path: string) => {\n setSelectedItems((prev) => {\n const next = new Set(prev)\n if (next.has(path)) {\n next.delete(path)\n } else {\n next.add(path)\n }\n return next\n })\n setLastSelectedPath(path)\n }, [])\n\n const selectRange = useCallback((fromPath: string, toPath: string, allItems: FileItem[]) => {\n const fromIndex = allItems.findIndex(item => item.path === fromPath)\n const toIndex = allItems.findIndex(item => item.path === toPath)\n \n if (fromIndex === -1 || toIndex === -1) return\n \n const start = Math.min(fromIndex, toIndex)\n const end = Math.max(fromIndex, toIndex)\n \n setSelectedItems((prev) => {\n const next = new Set(prev)\n for (let i = start; i <= end; i++) {\n next.add(allItems[i].path)\n }\n return next\n })\n setLastSelectedPath(toPath)\n }, [])\n\n const selectAll = useCallback((items: FileItem[]) => {\n setSelectedItems(new Set(items.map((item) => item.path)))\n }, [])\n\n const clearSelection = useCallback(() => {\n setSelectedItems(new Set())\n }, [])\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n if (focusedItem) {\n setFocusedItem(null)\n } else {\n onClose()\n }\n }\n },\n [onClose, focusedItem]\n )\n\n useEffect(() => {\n if (isVisible) {\n document.addEventListener('keydown', handleKeyDown)\n document.body.style.overflow = 'hidden'\n }\n return () => {\n document.removeEventListener('keydown', handleKeyDown)\n document.body.style.overflow = ''\n }\n }, [handleKeyDown, isVisible])\n\n const contextValue = {\n isOpen: true,\n openStudio: () => {},\n closeStudio: onClose,\n toggleStudio: onClose,\n currentPath,\n setCurrentPath,\n navigateUp,\n selectedItems,\n toggleSelection,\n selectRange,\n selectAll,\n clearSelection,\n lastSelectedPath,\n viewMode,\n setViewMode,\n focusedItem,\n setFocusedItem,\n meta,\n setMeta,\n isLoading,\n setIsLoading,\n refreshKey,\n triggerRefresh,\n }\n\n return (\n <StudioContext.Provider value={contextValue}>\n <div css={styles.container}>\n <div css={styles.header}>\n <h1 css={styles.title}>Studio</h1>\n <div css={styles.headerActions}>\n <StudioSettings />\n <button\n css={styles.headerBtn}\n onClick={onClose}\n aria-label=\"Close Studio\"\n >\n <CloseIcon />\n </button>\n </div>\n </div>\n\n <StudioToolbar />\n\n <div css={styles.content}>\n {focusedItem ? (\n <StudioDetailView />\n ) : (\n <div css={styles.fileBrowser}>\n {viewMode === 'grid' ? <StudioFileGrid /> : <StudioFileList />}\n </div>\n )}\n </div>\n </div>\n </StudioContext.Provider>\n )\n}\n\nfunction CloseIcon() {\n return (\n <svg\n css={styles.headerIcon}\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n )\n}\n\nexport default StudioUI\n","'use client'\n\nimport { createContext, useContext } from 'react'\nimport type { FileItem, StudioMeta } from '../types'\n\n/**\n * Studio state interface\n * State is managed by StudioUI and provided to all child components\n */\nexport interface StudioState {\n isOpen: boolean\n openStudio: () => void\n closeStudio: () => void\n toggleStudio: () => void\n\n // Navigation\n currentPath: string\n setCurrentPath: (path: string) => void\n navigateUp: () => void\n\n // Selection\n selectedItems: Set<string>\n toggleSelection: (path: string) => void\n selectRange: (fromPath: string, toPath: string, allItems: FileItem[]) => void\n selectAll: (items: FileItem[]) => void\n clearSelection: () => void\n lastSelectedPath: string | null\n\n // View\n viewMode: 'grid' | 'list'\n setViewMode: (mode: 'grid' | 'list') => void\n\n // Focused item (for detail view)\n focusedItem: FileItem | null\n setFocusedItem: (item: FileItem | null) => void\n\n // Meta\n meta: StudioMeta | null\n setMeta: (meta: StudioMeta) => void\n\n // Loading\n isLoading: boolean\n setIsLoading: (loading: boolean) => void\n\n // Refresh trigger\n refreshKey: number\n triggerRefresh: () => void\n}\n\nconst defaultState: StudioState = {\n isOpen: false,\n openStudio: () => {},\n closeStudio: () => {},\n toggleStudio: () => {},\n currentPath: 'public',\n setCurrentPath: () => {},\n navigateUp: () => {},\n selectedItems: new Set(),\n toggleSelection: () => {},\n selectRange: () => {},\n selectAll: () => {},\n clearSelection: () => {},\n lastSelectedPath: null,\n viewMode: 'grid',\n setViewMode: () => {},\n focusedItem: null,\n setFocusedItem: () => {},\n meta: null,\n setMeta: () => {},\n isLoading: false,\n setIsLoading: () => {},\n refreshKey: 0,\n triggerRefresh: () => {},\n}\n\nexport const StudioContext = createContext<StudioState>(defaultState)\n\n/**\n * Hook to access Studio state from child components\n */\nexport function useStudio() {\n return useContext(StudioContext)\n}\n","/** @jsxImportSource @emotion/react */\n'use client'\n\nimport { useCallback, useRef, useState } from 'react'\nimport { css, keyframes } from '@emotion/react'\nimport { useStudio } from './StudioContext'\nimport { ConfirmModal, AlertModal, ProgressModal, type ProgressState } from './StudioModal'\nimport { colors, fontSize } from './tokens'\n\n// Standard button height for consistency\nconst btnHeight = '36px'\n\nconst spin = keyframes`\n to { transform: rotate(360deg); }\n`\n\nconst styles = {\n toolbar: css`\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 24px;\n background-color: ${colors.surface};\n border-bottom: 1px solid ${colors.border};\n `,\n left: css`\n display: flex;\n align-items: center;\n gap: 8px;\n `,\n right: css`\n display: flex;\n align-items: center;\n gap: 8px;\n `,\n btn: css`\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n height: ${btnHeight};\n padding: 0 14px;\n border-radius: 6px;\n font-size: ${fontSize.base};\n font-weight: 500;\n background: ${colors.surface};\n border: 1px solid ${colors.border};\n cursor: pointer;\n transition: all 0.15s ease;\n color: ${colors.text};\n letter-spacing: -0.01em;\n \n &:hover:not(:disabled) {\n background-color: ${colors.surfaceHover};\n border-color: ${colors.borderHover};\n }\n \n &:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n }\n `,\n btnIconOnly: css`\n padding: 0 10px;\n `,\n btnPrimary: css`\n background: ${colors.primary};\n border-color: ${colors.primary};\n color: white;\n \n &:hover:not(:disabled) {\n background: ${colors.primaryHover};\n border-color: ${colors.primaryHover};\n }\n `,\n btnDanger: css`\n color: ${colors.danger};\n \n &:hover:not(:disabled) {\n background-color: ${colors.dangerLight};\n border-color: ${colors.danger};\n }\n `,\n icon: css`\n width: 16px;\n height: 16px;\n `,\n iconSpin: css`\n animation: ${spin} 1s linear infinite;\n `,\n selectionCount: css`\n font-size: ${fontSize.base};\n color: ${colors.textSecondary};\n display: flex;\n align-items: center;\n gap: 8px;\n margin-right: 8px;\n `,\n clearBtn: css`\n color: ${colors.primary};\n background: none;\n border: none;\n cursor: pointer;\n font-size: ${fontSize.base};\n font-weight: 500;\n padding: 0;\n \n &:hover {\n text-decoration: underline;\n }\n `,\n divider: css`\n width: 1px;\n height: 24px;\n background: ${colors.border};\n margin: 0 4px;\n `,\n viewToggle: css`\n display: flex;\n align-items: center;\n height: ${btnHeight};\n background-color: ${colors.surface};\n border: 1px solid ${colors.border};\n border-radius: 6px;\n overflow: hidden;\n `,\n viewBtn: css`\n height: 100%;\n padding: 0 10px;\n background: transparent;\n border: none;\n cursor: pointer;\n color: ${colors.textSecondary};\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n \n &:hover {\n color: ${colors.text};\n background-color: ${colors.surfaceHover};\n }\n `,\n viewBtnActive: css`\n background-color: ${colors.background};\n color: ${colors.text};\n `,\n}\n\nexport function StudioToolbar() {\n const { selectedItems, viewMode, setViewMode, clearSelection, currentPath, triggerRefresh, focusedItem } = useStudio()\n const fileInputRef = useRef<HTMLInputElement>(null)\n const abortControllerRef = useRef<AbortController | null>(null)\n const [uploading, setUploading] = useState(false)\n const [refreshing, setRefreshing] = useState(false)\n const [processing, setProcessing] = useState(false)\n const [showDeleteConfirm, setShowDeleteConfirm] = useState(false)\n const [showProcessConfirm, setShowProcessConfirm] = useState(false)\n const [showProgress, setShowProgress] = useState(false)\n const [progressState, setProgressState] = useState<ProgressState>({\n current: 0,\n total: 0,\n percent: 0,\n status: 'processing',\n })\n const [processCount, setProcessCount] = useState(0)\n const [processMode, setProcessMode] = useState<'all' | 'selected'>('all')\n const [imagesToProcess, setImagesToProcess] = useState<string[]>([])\n const [alertMessage, setAlertMessage] = useState<{ title: string; message: string } | null>(null)\n\n // Check if we're in the images folder (uploads not allowed there)\n const isInImagesFolder = currentPath === 'public/images' || currentPath.startsWith('public/images/')\n\n const handleUpload = useCallback(() => {\n fileInputRef.current?.click()\n }, [])\n\n const handleRefresh = useCallback(() => {\n setRefreshing(true)\n triggerRefresh()\n setTimeout(() => setRefreshing(false), 600)\n }, [triggerRefresh])\n\n const handleFileChange = useCallback(async (e: React.ChangeEvent<HTMLInputElement>) => {\n const files = e.target.files\n if (!files || files.length === 0) return\n\n setUploading(true)\n try {\n for (const file of Array.from(files)) {\n const formData = new FormData()\n formData.append('file', file)\n formData.append('path', currentPath)\n\n const response = await fetch('/api/studio/upload', {\n method: 'POST',\n body: formData,\n })\n\n if (!response.ok) {\n const error = await response.json()\n if (response.status >= 500) {\n console.error('Upload error:', error)\n setAlertMessage({\n title: 'Upload Failed',\n message: `Failed to upload ${file.name}: ${error.error || 'Unknown error'}`,\n })\n } else {\n setAlertMessage({\n title: 'Cannot Upload Here',\n message: error.error || 'Upload not allowed in this location.',\n })\n }\n }\n }\n triggerRefresh()\n } catch (error) {\n console.error('Upload error:', error)\n setAlertMessage({\n title: 'Upload Failed',\n message: 'Upload failed. Check console for details.',\n })\n } finally {\n setUploading(false)\n if (fileInputRef.current) {\n fileInputRef.current.value = ''\n }\n }\n }, [currentPath, triggerRefresh])\n\n const handleProcessImages = useCallback(async () => {\n const hasSelection = selectedItems.size > 0\n \n if (hasSelection) {\n const selectedPaths = Array.from(selectedItems)\n \n // Separate folders and image files\n const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg', 'ico', 'bmp', 'tiff', 'tif']\n const selectedImagePaths = selectedPaths.filter(p => {\n const ext = p.split('.').pop()?.toLowerCase() || ''\n return imageExtensions.includes(ext)\n })\n const selectedFolders = selectedPaths.filter(p => !p.includes('.') || p.endsWith('/'))\n \n // If folders are selected, fetch all images from them\n if (selectedFolders.length > 0) {\n try {\n const response = await fetch(`/api/studio/folder-images?folders=${encodeURIComponent(selectedFolders.join(','))}`)\n const data = await response.json()\n \n if (data.images) {\n // Add folder images to selectedImagePaths (as public/ paths)\n for (const img of data.images) {\n const fullPath = `public/${img}`\n if (!selectedImagePaths.includes(fullPath)) {\n selectedImagePaths.push(fullPath)\n }\n }\n }\n } catch (error) {\n console.error('Failed to get folder images:', error)\n }\n }\n \n if (selectedImagePaths.length === 0) {\n setAlertMessage({\n title: 'No Images Found',\n message: 'No images found in the selected items.',\n })\n return\n }\n \n setProcessCount(selectedImagePaths.length)\n setImagesToProcess(selectedImagePaths)\n setProcessMode('selected')\n setShowProcessConfirm(true)\n } else {\n // Count ALL images for \"process all\"\n try {\n const response = await fetch('/api/studio/count-images')\n const data = await response.json()\n \n if (data.count === 0) {\n setAlertMessage({\n title: 'No Images Found',\n message: 'No images found in the public folder to process.',\n })\n return\n }\n \n setProcessCount(data.count)\n setProcessMode('all')\n setShowProcessConfirm(true)\n } catch (error) {\n console.error('Failed to count images:', error)\n setAlertMessage({\n title: 'Error',\n message: 'Failed to count images.',\n })\n }\n }\n }, [selectedItems])\n\n const handleProcessConfirm = useCallback(async () => {\n setShowProcessConfirm(false)\n setProcessing(true)\n\n // Create new AbortController for this request\n abortControllerRef.current = new AbortController()\n const signal = abortControllerRef.current.signal\n\n try {\n if (processMode === 'all') {\n // Process all images with streaming progress\n setShowProgress(true)\n setProgressState({\n current: 0,\n total: processCount,\n percent: 0,\n status: 'processing',\n })\n\n const response = await fetch('/api/studio/process-all', {\n method: 'POST',\n signal,\n })\n\n if (!response.body) {\n throw new Error('No response body')\n }\n\n const reader = response.body.getReader()\n const decoder = new TextDecoder()\n\n try {\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n\n // Check if aborted\n if (signal.aborted) {\n reader.cancel()\n break\n }\n\n const text = decoder.decode(value)\n const lines = text.split('\\n\\n').filter(line => line.startsWith('data: '))\n\n for (const line of lines) {\n try {\n const data = JSON.parse(line.replace('data: ', ''))\n \n if (data.type === 'start') {\n setProgressState(prev => ({\n ...prev,\n total: data.total,\n }))\n } else if (data.type === 'progress') {\n setProgressState({\n current: data.current,\n total: data.total,\n percent: data.percent,\n currentFile: data.currentFile,\n status: 'processing',\n })\n } else if (data.type === 'cleanup') {\n setProgressState(prev => ({\n ...prev,\n status: 'cleanup',\n currentFile: undefined,\n }))\n } else if (data.type === 'complete') {\n setProgressState({\n current: data.processed,\n total: data.processed,\n percent: 100,\n status: 'complete',\n processed: data.processed,\n orphansRemoved: data.orphansRemoved,\n errors: data.errors,\n })\n triggerRefresh()\n } else if (data.type === 'error') {\n setProgressState(prev => ({\n ...prev,\n status: 'error',\n message: data.message,\n }))\n }\n } catch {\n // Ignore parse errors\n }\n }\n }\n } catch (err) {\n if (signal.aborted) {\n // User stopped - update state to show stopped status\n setProgressState(prev => ({\n ...prev,\n status: 'stopped',\n processed: prev.current,\n }))\n triggerRefresh()\n } else {\n throw err\n }\n }\n } else {\n // Process selected images (no streaming for now)\n setShowProgress(true)\n setProgressState({\n current: 0,\n total: processCount,\n percent: 0,\n status: 'processing',\n })\n\n // Use stored imagesToProcess instead of selectedItems\n const selectedImageKeys = imagesToProcess.map(p => p.replace(/^public\\//, ''))\n \n const response = await fetch('/api/studio/reprocess', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ imageKeys: selectedImageKeys }),\n signal,\n })\n \n const data = await response.json()\n \n if (response.ok) {\n setProgressState({\n current: data.processed?.length || 0,\n total: data.processed?.length || 0,\n percent: 100,\n status: 'complete',\n processed: data.processed?.length || 0,\n errors: data.errors?.length || 0,\n })\n clearSelection()\n triggerRefresh()\n } else {\n setProgressState({\n current: 0,\n total: 0,\n percent: 0,\n status: 'error',\n message: data.error || 'Unknown error',\n })\n }\n }\n } catch (error) {\n if (signal.aborted) {\n // User stopped\n setProgressState(prev => ({\n ...prev,\n status: 'stopped',\n processed: prev.current,\n }))\n triggerRefresh()\n } else {\n console.error('Processing error:', error)\n setProgressState({\n current: 0,\n total: 0,\n percent: 0,\n status: 'error',\n message: 'Processing failed. Check console for details.',\n })\n }\n } finally {\n setProcessing(false)\n abortControllerRef.current = null\n }\n }, [processMode, processCount, imagesToProcess, clearSelection, triggerRefresh])\n\n const handleStopProcessing = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort()\n }\n }, [])\n\n const handleDeleteClick = useCallback(() => {\n if (selectedItems.size === 0) return\n setShowDeleteConfirm(true)\n }, [selectedItems])\n\n const handleDeleteConfirm = useCallback(async () => {\n setShowDeleteConfirm(false)\n \n try {\n const response = await fetch('/api/studio/delete', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ paths: Array.from(selectedItems) }),\n })\n\n if (response.ok) {\n clearSelection()\n triggerRefresh()\n } else {\n const error = await response.json()\n setAlertMessage({\n title: 'Delete Failed',\n message: error.error || 'Unknown error',\n })\n }\n } catch (error) {\n console.error('Delete error:', error)\n setAlertMessage({\n title: 'Delete Failed',\n message: 'Delete failed. Check console for details.',\n })\n }\n }, [selectedItems, clearSelection, triggerRefresh])\n\n const handleSyncCdn = useCallback(() => {\n console.log('Sync CDN clicked', selectedItems)\n }, [selectedItems])\n\n const handleScan = useCallback(() => {\n console.log('Scan clicked')\n }, [])\n\n const hasSelection = selectedItems.size > 0\n\n // Hide toolbar actions when viewing detail\n if (focusedItem) {\n return null\n }\n\n return (\n <>\n {showDeleteConfirm && (\n <ConfirmModal\n title=\"Delete Items\"\n message={`Are you sure you want to delete ${selectedItems.size} item(s)? This action cannot be undone.`}\n confirmLabel=\"Delete\"\n variant=\"danger\"\n onConfirm={handleDeleteConfirm}\n onCancel={() => setShowDeleteConfirm(false)}\n />\n )}\n\n {showProcessConfirm && (\n <ConfirmModal\n title=\"Process Images\"\n message={processMode === 'all' \n ? `Found ${processCount} image${processCount !== 1 ? 's' : ''} in the public folder. This will regenerate all thumbnails and remove any orphaned files from the images folder.`\n : `Process ${processCount} selected image${processCount !== 1 ? 's' : ''}? This will regenerate thumbnails for these files.`\n }\n confirmLabel={processing ? 'Processing...' : 'Process'}\n onConfirm={handleProcessConfirm}\n onCancel={() => setShowProcessConfirm(false)}\n />\n )}\n\n {showProgress && (\n <ProgressModal\n title=\"Processing Images\"\n progress={progressState}\n onStop={handleStopProcessing}\n onClose={() => {\n setShowProgress(false)\n setProgressState({\n current: 0,\n total: 0,\n percent: 0,\n status: 'processing',\n })\n }}\n />\n )}\n\n {alertMessage && (\n <AlertModal\n title={alertMessage.title}\n message={alertMessage.message}\n onClose={() => setAlertMessage(null)}\n />\n )}\n\n <div css={styles.toolbar}>\n <input\n ref={fileInputRef}\n type=\"file\"\n multiple\n accept=\"image/*,video/*,audio/*,.pdf\"\n onChange={handleFileChange}\n style={{ display: 'none' }}\n />\n \n <div css={styles.left}>\n <button\n css={[styles.btn, styles.btnPrimary]}\n onClick={handleUpload}\n disabled={uploading || isInImagesFolder}\n >\n <UploadIcon />\n {uploading ? 'Uploading...' : 'Upload'}\n </button>\n \n <div css={styles.divider} />\n \n <button\n css={styles.btn}\n onClick={handleProcessImages}\n disabled={processing}\n >\n <ImageStackIcon />\n {processing ? 'Processing...' : 'Process Images'}\n </button>\n <button\n css={[styles.btn, styles.btnDanger]}\n onClick={handleDeleteClick}\n disabled={!hasSelection}\n >\n <TrashIcon />\n Delete\n </button>\n <button\n css={styles.btn}\n onClick={handleSyncCdn}\n disabled={!hasSelection}\n >\n <CloudIcon />\n Sync CDN\n </button>\n <button css={styles.btn} onClick={handleScan}>\n <ScanIcon />\n Scan\n </button>\n </div>\n\n <div css={styles.right}>\n {hasSelection && (\n <span css={styles.selectionCount}>\n {selectedItems.size} selected\n <button css={styles.clearBtn} onClick={clearSelection}>\n Clear\n </button>\n </span>\n )}\n\n <button\n css={[styles.btn, styles.btnIconOnly]}\n onClick={handleRefresh}\n >\n <RefreshIcon spinning={refreshing} />\n </button>\n\n <div css={styles.viewToggle}>\n <button\n css={[styles.viewBtn, viewMode === 'grid' && styles.viewBtnActive]}\n onClick={() => setViewMode('grid')}\n aria-label=\"Grid view\"\n >\n <GridIcon />\n </button>\n <button\n css={[styles.viewBtn, viewMode === 'list' && styles.viewBtnActive]}\n onClick={() => setViewMode('list')}\n aria-label=\"List view\"\n >\n <ListIcon />\n </button>\n </div>\n </div>\n </div>\n </>\n )\n}\n\nfunction UploadIcon() {\n return (\n <svg css={styles.icon} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <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\" />\n </svg>\n )\n}\n\nfunction RefreshIcon({ spinning }: { spinning?: boolean }) {\n return (\n <svg css={[styles.icon, spinning && styles.iconSpin]} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <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\" />\n </svg>\n )\n}\n\nfunction TrashIcon() {\n return (\n <svg css={styles.icon} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <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\" />\n </svg>\n )\n}\n\nfunction CloudIcon() {\n return (\n <svg css={styles.icon} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <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\" />\n </svg>\n )\n}\n\nfunction ScanIcon() {\n return (\n <svg css={styles.icon} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\" />\n </svg>\n )\n}\n\nfunction GridIcon() {\n return (\n <svg css={styles.icon} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <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\" />\n </svg>\n )\n}\n\nfunction ListIcon() {\n return (\n <svg css={styles.icon} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 6h16M4 10h16M4 14h16M4 18h16\" />\n </svg>\n )\n}\n\nfunction ImageStackIcon() {\n return (\n <svg css={styles.icon} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <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\" />\n </svg>\n )\n}\n","/** @jsxImportSource @emotion/react */\n'use client'\n\nimport { css, keyframes } from '@emotion/react'\nimport { colors, fontSize, fontStack, baseReset } from './tokens'\n\nconst fadeIn = keyframes`\n from { opacity: 0; }\n to { opacity: 1; }\n`\n\nconst slideIn = keyframes`\n from { \n opacity: 0;\n transform: translateY(-8px) scale(0.98);\n }\n to { \n opacity: 1;\n transform: translateY(0) scale(1);\n }\n`\n\nconst styles = {\n overlay: css`\n position: fixed;\n inset: 0;\n background-color: rgba(26, 31, 54, 0.4);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n animation: ${fadeIn} 0.15s ease-out;\n font-family: ${fontStack};\n `,\n modal: css`\n ${baseReset}\n background-color: ${colors.surface};\n border-radius: 12px;\n box-shadow: 0 30px 60px -12px rgba(50, 50, 93, 0.25), 0 18px 36px -18px rgba(0, 0, 0, 0.3);\n max-width: 420px;\n width: 90%;\n animation: ${slideIn} 0.2s ease-out;\n overflow: hidden;\n `,\n header: css`\n padding: 24px 24px 0;\n `,\n title: css`\n font-size: ${fontSize.lg};\n font-weight: 600;\n color: ${colors.text};\n margin: 0;\n letter-spacing: -0.02em;\n `,\n body: css`\n padding: 12px 24px 24px;\n `,\n message: css`\n font-size: ${fontSize.base};\n color: ${colors.textSecondary};\n margin: 0;\n line-height: 1.6;\n `,\n footer: css`\n display: flex;\n justify-content: flex-end;\n gap: 12px;\n padding: 16px 24px;\n border-top: 1px solid ${colors.border};\n background-color: ${colors.background};\n `,\n btn: css`\n padding: 10px 18px;\n font-size: ${fontSize.base};\n font-weight: 500;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s ease;\n letter-spacing: -0.01em;\n `,\n btnCancel: css`\n background-color: ${colors.surface};\n border: 1px solid ${colors.border};\n color: ${colors.text};\n \n &:hover {\n background-color: ${colors.surfaceHover};\n border-color: ${colors.borderHover};\n }\n `,\n btnConfirm: css`\n background-color: ${colors.primary};\n border: 1px solid ${colors.primary};\n color: white;\n \n &:hover {\n background-color: ${colors.primaryHover};\n border-color: ${colors.primaryHover};\n }\n `,\n btnDanger: css`\n background-color: ${colors.danger};\n border: 1px solid ${colors.danger};\n color: white;\n \n &:hover {\n background-color: ${colors.dangerHover};\n border-color: ${colors.dangerHover};\n }\n `,\n}\n\ninterface ConfirmModalProps {\n title: string\n message: string\n confirmLabel?: string\n cancelLabel?: string\n variant?: 'default' | 'danger'\n onConfirm: () => void\n onCancel: () => void\n}\n\nexport function ConfirmModal({\n title,\n message,\n confirmLabel = 'Confirm',\n cancelLabel = 'Cancel',\n variant = 'default',\n onConfirm,\n onCancel,\n}: ConfirmModalProps) {\n return (\n <div css={styles.overlay} onClick={onCancel}>\n <div css={styles.modal} onClick={(e) => e.stopPropagation()}>\n <div css={styles.header}>\n <h3 css={styles.title}>{title}</h3>\n </div>\n <div css={styles.body}>\n <p css={styles.message}>{message}</p>\n </div>\n <div css={styles.footer}>\n <button css={[styles.btn, styles.btnCancel]} onClick={onCancel}>\n {cancelLabel}\n </button>\n <button\n css={[styles.btn, variant === 'danger' ? styles.btnDanger : styles.btnConfirm]}\n onClick={onConfirm}\n >\n {confirmLabel}\n </button>\n </div>\n </div>\n </div>\n )\n}\n\ninterface AlertModalProps {\n title: string\n message: string\n buttonLabel?: string\n onClose: () => void\n}\n\nexport function AlertModal({\n title,\n message,\n buttonLabel = 'OK',\n onClose,\n}: AlertModalProps) {\n return (\n <div css={styles.overlay} onClick={onClose}>\n <div css={styles.modal} onClick={(e) => e.stopPropagation()}>\n <div css={styles.header}>\n <h3 css={styles.title}>{title}</h3>\n </div>\n <div css={styles.body}>\n <p css={styles.message}>{message}</p>\n </div>\n <div css={styles.footer}>\n <button css={[styles.btn, styles.btnConfirm]} onClick={onClose}>\n {buttonLabel}\n </button>\n </div>\n </div>\n </div>\n )\n}\n\nconst progressStyles = {\n progressContainer: css`\n margin-top: 16px;\n `,\n progressBar: css`\n width: 100%;\n height: 8px;\n background-color: ${colors.background};\n border-radius: 4px;\n overflow: hidden;\n margin-bottom: 12px;\n `,\n progressFill: css`\n height: 100%;\n background: linear-gradient(90deg, ${colors.primary}, ${colors.primaryHover});\n border-radius: 4px;\n transition: width 0.3s ease;\n `,\n progressText: css`\n font-size: ${fontSize.sm};\n color: ${colors.textSecondary};\n margin: 0;\n display: flex;\n justify-content: space-between;\n align-items: center;\n `,\n currentFile: css`\n font-size: ${fontSize.xs};\n color: ${colors.textMuted};\n margin: 8px 0 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n `,\n}\n\nexport interface ProgressState {\n current: number\n total: number\n percent: number\n currentFile?: string\n status: 'processing' | 'cleanup' | 'complete' | 'error' | 'stopped'\n message?: string\n processed?: number\n orphansRemoved?: number\n errors?: number\n}\n\ninterface ProgressModalProps {\n title: string\n progress: ProgressState\n onClose?: () => void\n onStop?: () => void\n}\n\nexport function ProgressModal({\n title,\n progress,\n onClose,\n onStop,\n}: ProgressModalProps) {\n const isComplete = progress.status === 'complete'\n const isError = progress.status === 'error'\n const isStopped = progress.status === 'stopped'\n const canClose = isComplete || isError || isStopped\n const isRunning = !canClose\n\n return (\n <div css={styles.overlay}>\n <div css={styles.modal} onClick={(e) => e.stopPropagation()}>\n <div css={styles.header}>\n <h3 css={styles.title}>{title}</h3>\n </div>\n <div css={styles.body}>\n {isError ? (\n <p css={styles.message}>{progress.message || 'An error occurred'}</p>\n ) : isStopped ? (\n <p css={styles.message}>\n Processing stopped. Processed {progress.processed ?? progress.current} image{(progress.processed ?? progress.current) !== 1 ? 's' : ''} before stopping.\n </p>\n ) : isComplete ? (\n <p css={styles.message}>\n Processed {progress.processed} image{progress.processed !== 1 ? 's' : ''}.\n {progress.orphansRemoved !== undefined && progress.orphansRemoved > 0 ? (\n <> Removed {progress.orphansRemoved} orphaned thumbnail{progress.orphansRemoved !== 1 ? 's' : ''}.</>\n ) : null}\n {progress.errors !== undefined && progress.errors > 0 ? (\n <> {progress.errors} error{progress.errors !== 1 ? 's' : ''} occurred.</>\n ) : null}\n </p>\n ) : (\n <>\n <p css={styles.message}>\n {progress.status === 'cleanup' \n ? 'Cleaning up orphaned files...' \n : `Processing images...`}\n </p>\n <div css={progressStyles.progressContainer}>\n <div css={progressStyles.progressBar}>\n <div \n css={progressStyles.progressFill} \n style={{ width: `${progress.percent}%` }} \n />\n </div>\n <div css={progressStyles.progressText}>\n <span>{progress.current} of {progress.total}</span>\n <span>{progress.percent}%</span>\n </div>\n {progress.currentFile && (\n <p css={progressStyles.currentFile} title={progress.currentFile}>\n {progress.currentFile}\n </p>\n )}\n </div>\n </>\n )}\n </div>\n <div css={styles.footer}>\n {isRunning && onStop && (\n <button css={[styles.btn, styles.btnDanger]} onClick={onStop}>\n Stop\n </button>\n )}\n {canClose && (\n <button css={[styles.btn, styles.btnConfirm]} onClick={onClose}>\n Done\n </button>\n )}\n </div>\n </div>\n </div>\n )\n}\n","/** @jsxImportSource @emotion/react */\n'use client'\n\nimport { useEffect, useState, useRef } from 'react'\nimport { css, keyframes } from '@emotion/react'\nimport { useStudio } from './StudioContext'\nimport { colors, fontSize } from './tokens'\nimport type { FileItem } from '../types'\n\nconst spin = keyframes`\n to { transform: rotate(360deg); }\n`\n\nconst styles = {\n loading: css`\n display: flex;\n align-items: center;\n justify-content: center;\n height: 256px;\n `,\n spinner: css`\n width: 32px;\n height: 32px;\n border-radius: 50%;\n border: 3px solid ${colors.border};\n border-top-color: ${colors.primary};\n animation: ${spin} 0.8s linear infinite;\n `,\n empty: css`\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 256px;\n color: ${colors.textSecondary};\n `,\n emptyIcon: css`\n width: 48px;\n height: 48px;\n margin-bottom: 16px;\n opacity: 0.5;\n `,\n emptyText: css`\n font-size: ${fontSize.base};\n margin: 0 0 4px 0;\n \n &:last-child {\n color: ${colors.textMuted};\n font-size: ${fontSize.sm};\n }\n `,\n grid: css`\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 12px;\n \n @media (min-width: 640px) { grid-template-columns: repeat(3, 1fr); }\n @media (min-width: 768px) { grid-template-columns: repeat(4, 1fr); }\n @media (min-width: 1024px) { grid-template-columns: repeat(5, 1fr); }\n @media (min-width: 1280px) { grid-template-columns: repeat(6, 1fr); }\n `,\n item: css`\n position: relative;\n border-radius: 8px;\n border: 1px solid ${colors.border};\n overflow: hidden;\n cursor: pointer;\n transition: all 0.15s ease;\n background-color: ${colors.surface};\n user-select: none;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);\n \n &:hover {\n border-color: #d0d5dd;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.06);\n }\n `,\n itemSelected: css`\n border-color: ${colors.primary};\n box-shadow: 0 0 0 1px ${colors.primary};\n \n &:hover {\n border-color: ${colors.primary};\n }\n `,\n parentItem: css`\n cursor: pointer;\n \n &:hover {\n border-color: ${colors.primary};\n }\n `,\n checkboxWrapper: css`\n position: absolute;\n top: 0;\n left: 0;\n z-index: 10;\n padding: 8px;\n cursor: pointer;\n `,\n checkbox: css`\n width: 16px;\n height: 16px;\n accent-color: ${colors.primary};\n cursor: pointer;\n `,\n cdnBadge: css`\n position: absolute;\n top: 8px;\n right: 8px;\n z-index: 10;\n background-color: ${colors.successLight};\n color: ${colors.success};\n font-size: 11px;\n font-weight: 500;\n padding: 2px 8px;\n border-radius: 4px;\n `,\n content: css`\n aspect-ratio: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 16px;\n background: ${colors.background};\n `,\n folderIcon: css`\n width: 56px;\n height: 56px;\n color: #f5a623;\n `,\n parentIcon: css`\n width: 56px;\n height: 56px;\n color: ${colors.textMuted};\n `,\n fileIcon: css`\n width: 40px;\n height: 40px;\n color: ${colors.textMuted};\n `,\n image: css`\n max-width: 100%;\n max-height: 100%;\n object-fit: contain;\n border-radius: 4px;\n `,\n label: css`\n padding: 10px 12px;\n background-color: ${colors.surface};\n border-top: 1px solid ${colors.borderLight};\n `,\n labelRow: css`\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n `,\n labelText: css`\n flex: 1;\n min-width: 0;\n `,\n name: css`\n font-size: ${fontSize.sm};\n font-weight: 500;\n color: ${colors.text};\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n margin: 0;\n letter-spacing: -0.01em;\n `,\n size: css`\n font-size: ${fontSize.xs};\n color: ${colors.textMuted};\n margin: 2px 0 0 0;\n `,\n openBtn: css`\n flex-shrink: 0;\n height: 28px;\n font-size: ${fontSize.xs};\n font-weight: 500;\n color: ${colors.primary};\n background: ${colors.surface};\n border: 1px solid ${colors.border};\n padding: 0 10px;\n cursor: pointer;\n border-radius: 4px;\n transition: all 0.15s ease;\n display: inline-flex;\n align-items: center;\n \n &:hover {\n background-color: ${colors.primaryLight};\n border-color: ${colors.primary};\n }\n `,\n selectAllRow: css`\n display: flex;\n align-items: center;\n margin-bottom: 16px;\n padding: 12px 16px;\n background: ${colors.surface};\n border-radius: 8px;\n border: 1px solid ${colors.border};\n `,\n selectAllLabel: css`\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: ${fontSize.base};\n font-weight: 500;\n color: ${colors.textSecondary};\n cursor: pointer;\n \n &:hover {\n color: ${colors.text};\n }\n `,\n selectAllCheckbox: css`\n width: 16px;\n height: 16px;\n accent-color: ${colors.primary};\n `,\n}\n\nexport function StudioFileGrid() {\n const { currentPath, setCurrentPath, navigateUp, selectedItems, toggleSelection, selectRange, lastSelectedPath, selectAll, clearSelection, refreshKey, setFocusedItem } = useStudio()\n const [items, setItems] = useState<FileItem[]>([])\n const [loading, setLoading] = useState(true)\n const isInitialLoad = useRef(true)\n const lastPath = useRef(currentPath)\n\n useEffect(() => {\n async function loadItems() {\n // Only show loading spinner on initial load or path change, not on refresh\n const isPathChange = lastPath.current !== currentPath\n if (isInitialLoad.current || isPathChange) {\n setLoading(true)\n }\n lastPath.current = currentPath\n \n try {\n const response = await fetch(`/api/studio/list?path=${encodeURIComponent(currentPath)}`)\n if (response.ok) {\n const data = await response.json()\n setItems(data.items || [])\n }\n } catch (error) {\n console.error('Failed to load items:', error)\n }\n setLoading(false)\n isInitialLoad.current = false\n }\n loadItems()\n }, [currentPath, refreshKey])\n\n if (loading) {\n return (\n <div css={styles.loading}>\n <div css={styles.spinner} />\n </div>\n )\n }\n\n const isAtRoot = currentPath === 'public'\n\n // Empty state only when truly empty (not counting parent folder)\n if (items.length === 0 && isAtRoot) {\n return (\n <div css={styles.empty}>\n <svg css={styles.emptyIcon} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <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\" />\n </svg>\n <p css={styles.emptyText}>No files in this folder</p>\n <p css={styles.emptyText}>Upload images to get started</p>\n </div>\n )\n }\n\n const sortedItems = [...items].sort((a, b) => {\n if (a.type === 'folder' && b.type !== 'folder') return -1\n if (a.type !== 'folder' && b.type === 'folder') return 1\n return a.name.localeCompare(b.name)\n })\n\n const handleItemClick = (item: FileItem, e: React.MouseEvent) => {\n if (e.shiftKey && lastSelectedPath) {\n selectRange(lastSelectedPath, item.path, sortedItems)\n } else {\n toggleSelection(item.path)\n }\n }\n\n const handleOpen = (item: FileItem) => {\n if (item.type === 'folder') {\n setCurrentPath(item.path)\n } else {\n setFocusedItem(item)\n }\n }\n\n const allItemsSelected = sortedItems.length > 0 && sortedItems.every(item => selectedItems.has(item.path))\n const someItemsSelected = sortedItems.some(item => selectedItems.has(item.path))\n\n const handleSelectAll = () => {\n if (allItemsSelected) {\n clearSelection()\n } else {\n selectAll(sortedItems)\n }\n }\n\n return (\n <div>\n {sortedItems.length > 0 && (\n <div css={styles.selectAllRow}>\n <label css={styles.selectAllLabel}>\n <input\n type=\"checkbox\"\n css={styles.selectAllCheckbox}\n checked={allItemsSelected}\n ref={(el) => {\n if (el) el.indeterminate = someItemsSelected && !allItemsSelected\n }}\n onChange={handleSelectAll}\n />\n Select all ({sortedItems.length})\n </label>\n </div>\n )}\n <div css={styles.grid}>\n {/* Parent folder navigation */}\n {!isAtRoot && (\n <div \n css={[styles.item, styles.parentItem]}\n onClick={navigateUp}\n >\n <div css={styles.content}>\n <svg css={styles.parentIcon} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={1.5} d=\"M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6\" />\n </svg>\n </div>\n <div css={styles.label}>\n <p css={styles.name}>..</p>\n <p css={styles.size}>Parent folder</p>\n </div>\n </div>\n )}\n \n {sortedItems.map((item) => (\n <GridItem\n key={item.path}\n item={item}\n isSelected={selectedItems.has(item.path)}\n onClick={(e) => handleItemClick(item, e)}\n onOpen={() => handleOpen(item)}\n />\n ))}\n </div>\n </div>\n )\n}\n\ninterface GridItemProps {\n item: FileItem\n isSelected: boolean\n onClick: (e: React.MouseEvent) => void\n onOpen: () => void\n}\n\nfunction GridItem({ item, isSelected, onClick, onOpen }: GridItemProps) {\n const isFolder = item.type === 'folder'\n\n return (\n <div \n css={[styles.item, isSelected && styles.itemSelected]} \n onClick={onClick}\n >\n <div\n css={styles.checkboxWrapper}\n onClick={(e) => e.stopPropagation()}\n >\n <input\n type=\"checkbox\"\n css={styles.checkbox}\n checked={isSelected}\n onChange={() => onClick({} as React.MouseEvent)}\n />\n </div>\n\n {item.cdnSynced && <span css={styles.cdnBadge}>CDN</span>}\n\n <div css={styles.content}>\n {isFolder ? (\n <svg css={styles.folderIcon} fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <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\" />\n </svg>\n ) : item.thumbnail ? (\n <img\n css={styles.image}\n src={item.thumbnail}\n alt={item.name}\n loading=\"lazy\"\n />\n ) : (\n <svg css={styles.fileIcon} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <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\" />\n </svg>\n )}\n </div>\n\n <div css={styles.label}>\n <div css={styles.labelRow}>\n <div css={styles.labelText}>\n <p css={styles.name} title={item.name}>{truncateMiddle(item.name)}</p>\n {isFolder ? (\n <p css={styles.size}>\n {item.fileCount !== undefined ? `${item.fileCount} files` : ''}\n {item.fileCount !== undefined && item.totalSize !== undefined ? ' · ' : ''}\n {item.totalSize !== undefined ? formatFileSize(item.totalSize) : ''}\n </p>\n ) : (\n item.size !== undefined && <p css={styles.size}>{formatFileSize(item.size)}</p>\n )}\n </div>\n <button\n css={styles.openBtn}\n onClick={(e) => {\n e.stopPropagation()\n onOpen()\n }}\n >\n Open\n </button>\n </div>\n </div>\n </div>\n )\n}\n\nfunction formatFileSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`\n}\n\nfunction truncateMiddle(str: string, maxLength: number = 24): string {\n if (str.length <= maxLength) return str\n \n // Find the extension\n const lastDot = str.lastIndexOf('.')\n const ext = lastDot > 0 ? str.substring(lastDot) : ''\n const name = lastDot > 0 ? str.substring(0, lastDot) : str\n \n // Calculate how much we can show of the name\n const availableLength = maxLength - ext.length - 3 // 3 for \"...\"\n if (availableLength < 6) {\n // Too short, just truncate from end\n return str.substring(0, maxLength - 3) + '...'\n }\n \n const startLength = Math.ceil(availableLength / 2)\n const endLength = Math.floor(availableLength / 2)\n \n return name.substring(0, startLength) + '...' + name.substring(name.length - endLength) + ext\n}\n","/** @jsxImportSource @emotion/react */\n'use client'\n\nimport { useEffect, useState, useRef } from 'react'\nimport { css, keyframes } from '@emotion/react'\nimport { useStudio } from './StudioContext'\nimport { colors, fontSize } from './tokens'\nimport type { FileItem } from '../types'\n\nconst spin = keyframes`\n to { transform: rotate(360deg); }\n`\n\nconst styles = {\n loading: css`\n display: flex;\n align-items: center;\n justify-content: center;\n height: 256px;\n `,\n spinner: css`\n width: 32px;\n height: 32px;\n border-radius: 50%;\n border: 3px solid ${colors.border};\n border-top-color: ${colors.primary};\n animation: ${spin} 0.8s linear infinite;\n `,\n empty: css`\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 256px;\n color: ${colors.textSecondary};\n `,\n tableWrapper: css`\n background: ${colors.surface};\n border-radius: 8px;\n border: 1px solid ${colors.border};\n overflow: hidden;\n `,\n table: css`\n width: 100%;\n border-collapse: collapse;\n `,\n th: css`\n text-align: left;\n font-size: 11px;\n color: ${colors.textMuted};\n text-transform: uppercase;\n letter-spacing: 0.05em;\n padding: 12px 16px;\n font-weight: 600;\n background: ${colors.background};\n border-bottom: 1px solid ${colors.border};\n `,\n thCheckbox: css`\n width: 48px;\n `,\n thSize: css`\n width: 96px;\n `,\n thDimensions: css`\n width: 128px;\n `,\n thCdn: css`\n width: 96px;\n `,\n tbody: css``,\n row: css`\n cursor: pointer;\n transition: background-color 0.15s ease;\n user-select: none;\n \n &:hover {\n background-color: ${colors.surfaceHover};\n }\n \n &:not(:last-child) td {\n border-bottom: 1px solid ${colors.borderLight};\n }\n `,\n rowSelected: css`\n background-color: ${colors.primaryLight};\n \n &:hover {\n background-color: ${colors.primaryLight};\n }\n `,\n parentRow: css`\n cursor: pointer;\n \n &:hover {\n background-color: ${colors.surfaceHover};\n }\n `,\n td: css`\n padding: 12px 16px;\n `,\n checkboxCell: css`\n padding: 12px 16px;\n cursor: pointer;\n `,\n checkbox: css`\n width: 16px;\n height: 16px;\n accent-color: ${colors.primary};\n cursor: pointer;\n `,\n nameCell: css`\n display: flex;\n align-items: center;\n gap: 12px;\n `,\n folderIcon: css`\n width: 20px;\n height: 20px;\n color: #f5a623;\n flex-shrink: 0;\n `,\n parentIcon: css`\n width: 20px;\n height: 20px;\n color: ${colors.textMuted};\n flex-shrink: 0;\n `,\n fileIcon: css`\n width: 20px;\n height: 20px;\n color: ${colors.textMuted};\n flex-shrink: 0;\n `,\n thumbnail: css`\n width: 36px;\n height: 36px;\n object-fit: cover;\n border-radius: 6px;\n flex-shrink: 0;\n border: 1px solid ${colors.borderLight};\n `,\n name: css`\n font-size: ${fontSize.base};\n font-weight: 500;\n color: ${colors.text};\n letter-spacing: -0.01em;\n `,\n meta: css`\n font-size: ${fontSize.sm};\n color: ${colors.textSecondary};\n `,\n cdnBadge: css`\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: ${fontSize.xs};\n font-weight: 500;\n color: ${colors.success};\n `,\n cdnIcon: css`\n width: 12px;\n height: 12px;\n `,\n cdnEmpty: css`\n font-size: ${fontSize.sm};\n color: ${colors.textMuted};\n `,\n openBtn: css`\n height: 28px;\n font-size: ${fontSize.xs};\n font-weight: 500;\n color: ${colors.primary};\n background: ${colors.surface};\n border: 1px solid ${colors.border};\n padding: 0 12px;\n cursor: pointer;\n border-radius: 4px;\n transition: all 0.15s ease;\n display: inline-flex;\n align-items: center;\n margin-left: auto;\n \n &:hover {\n background-color: ${colors.primaryLight};\n border-color: ${colors.primary};\n }\n `,\n}\n\nexport function StudioFileList() {\n const { currentPath, setCurrentPath, navigateUp, selectedItems, toggleSelection, selectRange, lastSelectedPath, selectAll, clearSelection, refreshKey, setFocusedItem } = useStudio()\n const [items, setItems] = useState<FileItem[]>([])\n const [loading, setLoading] = useState(true)\n const isInitialLoad = useRef(true)\n const lastPath = useRef(currentPath)\n\n useEffect(() => {\n async function loadItems() {\n // Only show loading spinner on initial load or path change, not on refresh\n const isPathChange = lastPath.current !== currentPath\n if (isInitialLoad.current || isPathChange) {\n setLoading(true)\n }\n lastPath.current = currentPath\n \n try {\n const response = await fetch(`/api/studio/list?path=${encodeURIComponent(currentPath)}`)\n if (response.ok) {\n const data = await response.json()\n setItems(data.items || [])\n }\n } catch (error) {\n console.error('Failed to load items:', error)\n }\n setLoading(false)\n isInitialLoad.current = false\n }\n loadItems()\n }, [currentPath, refreshKey])\n\n if (loading) {\n return (\n <div css={styles.loading}>\n <div css={styles.spinner} />\n </div>\n )\n }\n\n const isAtRoot = currentPath === 'public'\n\n if (items.length === 0 && isAtRoot) {\n return (\n <div css={styles.empty}>\n <p>No files in this folder</p>\n </div>\n )\n }\n\n const sortedItems = [...items].sort((a, b) => {\n if (a.type === 'folder' && b.type !== 'folder') return -1\n if (a.type !== 'folder' && b.type === 'folder') return 1\n return a.name.localeCompare(b.name)\n })\n\n const handleItemClick = (item: FileItem, e: React.MouseEvent) => {\n if (e.shiftKey && lastSelectedPath) {\n selectRange(lastSelectedPath, item.path, sortedItems)\n } else {\n toggleSelection(item.path)\n }\n }\n\n const handleOpen = (item: FileItem) => {\n if (item.type === 'folder') {\n setCurrentPath(item.path)\n } else {\n setFocusedItem(item)\n }\n }\n\n const allItemsSelected = sortedItems.length > 0 && sortedItems.every(item => selectedItems.has(item.path))\n const someItemsSelected = sortedItems.some(item => selectedItems.has(item.path))\n\n const handleSelectAll = () => {\n if (allItemsSelected) {\n clearSelection()\n } else {\n selectAll(sortedItems)\n }\n }\n\n return (\n <div css={styles.tableWrapper}>\n <table css={styles.table}>\n <thead>\n <tr>\n <th css={[styles.th, styles.thCheckbox]}>\n {sortedItems.length > 0 && (\n <input\n type=\"checkbox\"\n css={styles.checkbox}\n checked={allItemsSelected}\n ref={(el) => {\n if (el) el.indeterminate = someItemsSelected && !allItemsSelected\n }}\n onChange={handleSelectAll}\n />\n )}\n </th>\n <th css={styles.th}>Name</th>\n <th css={[styles.th, styles.thSize]}>Size</th>\n <th css={[styles.th, styles.thDimensions]}>Dimensions</th>\n <th css={[styles.th, styles.thCdn]}>CDN</th>\n </tr>\n </thead>\n <tbody css={styles.tbody}>\n {/* Parent folder navigation */}\n {!isAtRoot && (\n <tr css={styles.parentRow} onClick={navigateUp}>\n <td css={styles.td}></td>\n <td css={styles.td}>\n <div css={styles.nameCell}>\n <svg css={styles.parentIcon} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={1.5} d=\"M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6\" />\n </svg>\n <span css={styles.name}>..</span>\n </div>\n </td>\n <td css={[styles.td, styles.meta]}>--</td>\n <td css={[styles.td, styles.meta]}>Parent folder</td>\n <td css={styles.td}>--</td>\n </tr>\n )}\n \n {sortedItems.map((item) => (\n <ListRow\n key={item.path}\n item={item}\n isSelected={selectedItems.has(item.path)}\n onClick={(e) => handleItemClick(item, e)}\n onOpen={() => handleOpen(item)}\n />\n ))}\n </tbody>\n </table>\n </div>\n )\n}\n\ninterface ListRowProps {\n item: FileItem\n isSelected: boolean\n onClick: (e: React.MouseEvent) => void\n onOpen: () => void\n}\n\nfunction ListRow({ item, isSelected, onClick, onOpen }: ListRowProps) {\n const isFolder = item.type === 'folder'\n\n return (\n <tr \n css={[styles.row, isSelected && styles.rowSelected]} \n onClick={onClick}\n >\n <td\n css={[styles.td, styles.checkboxCell]}\n onClick={(e) => e.stopPropagation()}\n >\n <input\n type=\"checkbox\"\n css={styles.checkbox}\n checked={isSelected}\n onChange={() => onClick({} as React.MouseEvent)}\n />\n </td>\n <td css={styles.td}>\n <div css={styles.nameCell}>\n {isFolder ? (\n <svg css={styles.folderIcon} fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <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\" />\n </svg>\n ) : item.thumbnail ? (\n <img css={styles.thumbnail} src={item.thumbnail} alt={item.name} loading=\"lazy\" />\n ) : (\n <svg css={styles.fileIcon} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <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\" />\n </svg>\n )}\n <span css={styles.name} title={item.name}>{truncateMiddle(item.name)}</span>\n <button\n css={styles.openBtn}\n onClick={(e) => {\n e.stopPropagation()\n onOpen()\n }}\n >\n Open\n </button>\n </div>\n </td>\n <td css={[styles.td, styles.meta]}>\n {isFolder \n ? (item.fileCount !== undefined ? `${item.fileCount} files` : '--')\n : (item.size !== undefined ? formatFileSize(item.size) : '--')\n }\n </td>\n <td css={[styles.td, styles.meta]}>\n {isFolder \n ? (item.totalSize !== undefined ? formatFileSize(item.totalSize) : '--')\n : (item.dimensions ? `${item.dimensions.width}x${item.dimensions.height}` : '--')\n }\n </td>\n <td css={styles.td}>\n {item.cdnSynced ? (\n <span css={styles.cdnBadge}>\n <svg css={styles.cdnIcon} fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <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\" />\n </svg>\n Synced\n </span>\n ) : (\n <span css={styles.cdnEmpty}>--</span>\n )}\n </td>\n </tr>\n )\n}\n\nfunction formatFileSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`\n}\n\nfunction truncateMiddle(str: string, maxLength: number = 32): string {\n if (str.length <= maxLength) return str\n \n // Find the extension\n const lastDot = str.lastIndexOf('.')\n const ext = lastDot > 0 ? str.substring(lastDot) : ''\n const name = lastDot > 0 ? str.substring(0, lastDot) : str\n \n // Calculate how much we can show of the name\n const availableLength = maxLength - ext.length - 3 // 3 for \"...\"\n if (availableLength < 6) {\n // Too short, just truncate from end\n return str.substring(0, maxLength - 3) + '...'\n }\n \n const startLength = Math.ceil(availableLength / 2)\n const endLength = Math.floor(availableLength / 2)\n \n return name.substring(0, startLength) + '...' + name.substring(name.length - endLength) + ext\n}\n","/** @jsxImportSource @emotion/react */\n'use client'\n\nimport { useState } from 'react'\nimport { css } from '@emotion/react'\nimport { useStudio } from './StudioContext'\nimport { ConfirmModal, AlertModal } from './StudioModal'\nimport { colors, fontSize } from './tokens'\n\nconst IMAGE_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.svg', '.ico', '.bmp', '.tiff', '.tif']\nconst VIDEO_EXTENSIONS = ['.mp4', '.webm', '.mov', '.avi', '.mkv', '.m4v']\n\nfunction isImageFile(filename: string): boolean {\n const ext = filename.toLowerCase().substring(filename.lastIndexOf('.'))\n return IMAGE_EXTENSIONS.includes(ext)\n}\n\nfunction isVideoFile(filename: string): boolean {\n const ext = filename.toLowerCase().substring(filename.lastIndexOf('.'))\n return VIDEO_EXTENSIONS.includes(ext)\n}\n\nconst styles = {\n container: css`\n display: flex;\n flex: 1;\n overflow: hidden;\n `,\n main: css`\n position: relative;\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 24px;\n background: ${colors.background};\n overflow: auto;\n `,\n mainCloseBtn: css`\n position: absolute;\n top: 16px;\n right: 16px;\n padding: 8px;\n background: ${colors.surface};\n border: 1px solid ${colors.border};\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);\n \n &:hover {\n background-color: ${colors.surfaceHover};\n border-color: ${colors.borderHover};\n }\n `,\n mainCloseIcon: css`\n width: 20px;\n height: 20px;\n color: ${colors.textSecondary};\n `,\n mediaWrapper: css`\n max-width: 100%;\n max-height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n `,\n image: css`\n max-width: 100%;\n max-height: calc(100vh - 200px);\n object-fit: contain;\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n `,\n video: css`\n max-width: 100%;\n max-height: calc(100vh - 200px);\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n `,\n filePlaceholder: css`\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 48px;\n background: ${colors.surface};\n border-radius: 12px;\n border: 1px solid ${colors.border};\n `,\n fileIcon: css`\n width: 80px;\n height: 80px;\n color: ${colors.textMuted};\n margin-bottom: 16px;\n `,\n fileName: css`\n font-size: ${fontSize.lg};\n font-weight: 600;\n color: ${colors.text};\n margin: 0;\n `,\n sidebar: css`\n width: 280px;\n background: ${colors.surface};\n border-left: 1px solid ${colors.border};\n display: flex;\n flex-direction: column;\n overflow: hidden;\n `,\n sidebarHeader: css`\n padding: 16px 20px;\n border-bottom: 1px solid ${colors.border};\n `,\n sidebarTitle: css`\n font-size: ${fontSize.base};\n font-weight: 600;\n color: ${colors.text};\n margin: 0;\n `,\n sidebarContent: css`\n flex: 1;\n padding: 20px;\n overflow: auto;\n `,\n info: css`\n display: flex;\n flex-direction: column;\n gap: 12px;\n margin-bottom: 24px;\n `,\n infoRow: css`\n display: flex;\n justify-content: space-between;\n font-size: ${fontSize.sm};\n `,\n infoLabel: css`\n color: ${colors.textSecondary};\n `,\n infoValue: css`\n color: ${colors.text};\n font-weight: 500;\n text-align: right;\n max-width: 160px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n `,\n infoValueWrap: css`\n color: ${colors.text};\n font-weight: 500;\n text-align: right;\n max-width: 160px;\n word-break: break-all;\n white-space: normal;\n `,\n actions: css`\n display: flex;\n flex-direction: column;\n gap: 8px;\n `,\n actionBtn: css`\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 12px 14px;\n font-size: ${fontSize.base};\n font-weight: 500;\n background: ${colors.surface};\n border: 1px solid ${colors.border};\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s ease;\n color: ${colors.text};\n text-align: left;\n \n &:hover {\n background-color: ${colors.surfaceHover};\n border-color: ${colors.borderHover};\n }\n `,\n actionBtnDanger: css`\n color: ${colors.danger};\n \n &:hover {\n background-color: ${colors.dangerLight};\n border-color: ${colors.danger};\n }\n `,\n actionIcon: css`\n width: 16px;\n height: 16px;\n flex-shrink: 0;\n `,\n}\n\nexport function StudioDetailView() {\n const { focusedItem, setFocusedItem, triggerRefresh, clearSelection } = useStudio()\n const [showDeleteConfirm, setShowDeleteConfirm] = useState(false)\n const [alertMessage, setAlertMessage] = useState<{ title: string; message: string } | null>(null)\n\n if (!focusedItem) return null\n\n const isImage = isImageFile(focusedItem.name)\n const isVideo = isVideoFile(focusedItem.name)\n const imageSrc = focusedItem.path.replace('public', '')\n\n const handleClose = () => {\n setFocusedItem(null)\n }\n\n const handleRename = () => {\n const newName = prompt('Enter new name:', focusedItem.name)\n if (newName && newName !== focusedItem.name) {\n console.log('Rename to:', newName)\n // TODO: Implement rename API\n }\n }\n\n const handleDelete = async () => {\n setShowDeleteConfirm(false)\n try {\n const response = await fetch('/api/studio/delete', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ paths: [focusedItem.path] }),\n })\n\n if (response.ok) {\n clearSelection()\n triggerRefresh()\n setFocusedItem(null)\n } else {\n const error = await response.json()\n setAlertMessage({\n title: 'Delete Failed',\n message: error.error || 'Unknown error',\n })\n }\n } catch (error) {\n console.error('Delete error:', error)\n setAlertMessage({\n title: 'Delete Failed',\n message: 'Delete failed. Check console for details.',\n })\n }\n }\n\n const handleSync = () => {\n console.log('Sync to CDN:', focusedItem.path)\n // TODO: Implement sync API\n }\n\n const handleRegenerate = () => {\n console.log('Regenerate:', focusedItem.path)\n // TODO: Implement regenerate API\n }\n\n const renderMedia = () => {\n if (isImage) {\n return <img css={styles.image} src={imageSrc} alt={focusedItem.name} />\n }\n if (isVideo) {\n return <video css={styles.video} src={imageSrc} controls />\n }\n return (\n <div css={styles.filePlaceholder}>\n <svg css={styles.fileIcon} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <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\" />\n </svg>\n <p css={styles.fileName}>{focusedItem.name}</p>\n </div>\n )\n }\n\n return (\n <>\n {showDeleteConfirm && (\n <ConfirmModal\n title=\"Delete File\"\n message={`Are you sure you want to delete \"${focusedItem.name}\"? This action cannot be undone.`}\n confirmLabel=\"Delete\"\n variant=\"danger\"\n onConfirm={handleDelete}\n onCancel={() => setShowDeleteConfirm(false)}\n />\n )}\n\n {alertMessage && (\n <AlertModal\n title={alertMessage.title}\n message={alertMessage.message}\n onClose={() => setAlertMessage(null)}\n />\n )}\n\n <div css={styles.container}>\n <div css={styles.main}>\n <button css={styles.mainCloseBtn} onClick={handleClose} aria-label=\"Close\">\n <svg css={styles.mainCloseIcon} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n <div css={styles.mediaWrapper}>\n {renderMedia()}\n </div>\n </div>\n\n <div css={styles.sidebar}>\n <div css={styles.sidebarHeader}>\n <h3 css={styles.sidebarTitle}>Details</h3>\n </div>\n\n <div css={styles.sidebarContent}>\n <div css={styles.info}>\n <div css={styles.infoRow}>\n <span css={styles.infoLabel}>Name</span>\n <span css={styles.infoValueWrap}>{focusedItem.name}</span>\n </div>\n {focusedItem.size !== undefined && (\n <div css={styles.infoRow}>\n <span css={styles.infoLabel}>Size</span>\n <span css={styles.infoValue}>{formatFileSize(focusedItem.size)}</span>\n </div>\n )}\n {focusedItem.dimensions && (\n <div css={styles.infoRow}>\n <span css={styles.infoLabel}>Dimensions</span>\n <span css={styles.infoValue}>{focusedItem.dimensions.width} × {focusedItem.dimensions.height}</span>\n </div>\n )}\n <div css={styles.infoRow}>\n <span css={styles.infoLabel}>CDN Status</span>\n <span css={styles.infoValue}>{focusedItem.cdnSynced ? 'Synced' : 'Not synced'}</span>\n </div>\n </div>\n\n <div css={styles.actions}>\n <button css={styles.actionBtn} onClick={handleRename}>\n <svg css={styles.actionIcon} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <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\" />\n </svg>\n Rename\n </button>\n <button css={styles.actionBtn} onClick={handleSync}>\n <svg css={styles.actionIcon} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <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\" />\n </svg>\n Sync to CDN\n </button>\n <button css={styles.actionBtn} onClick={handleRegenerate}>\n <svg css={styles.actionIcon} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <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\" />\n </svg>\n Regenerate\n </button>\n <button css={[styles.actionBtn, styles.actionBtnDanger]} onClick={() => setShowDeleteConfirm(true)}>\n <svg css={styles.actionIcon} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <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\" />\n </svg>\n Delete\n </button>\n </div>\n </div>\n </div>\n </div>\n </>\n )\n}\n\nfunction formatFileSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`\n}\n","/** @jsxImportSource @emotion/react */\n'use client'\n\nimport { useState } from 'react'\nimport { css } from '@emotion/react'\nimport { colors, fontSize, baseReset } from './tokens'\n\n// Standard button height for consistency\nconst btnHeight = '36px'\n\nconst styles = {\n btn: css`\n height: ${btnHeight};\n padding: 0 12px;\n background: ${colors.surface};\n border: 1px solid ${colors.border};\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n \n &:hover {\n background-color: ${colors.surfaceHover};\n border-color: ${colors.borderHover};\n }\n `,\n icon: css`\n width: 16px;\n height: 16px;\n color: ${colors.textSecondary};\n `,\n overlay: css`\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n background-color: rgba(26, 31, 54, 0.4);\n backdrop-filter: blur(4px);\n `,\n panel: css`\n ${baseReset}\n position: relative;\n background-color: ${colors.surface};\n border-radius: 12px;\n box-shadow: 0 30px 60px -12px rgba(50, 50, 93, 0.25), 0 18px 36px -18px rgba(0, 0, 0, 0.3);\n width: 100%;\n max-width: 512px;\n padding: 24px;\n `,\n header: css`\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 24px;\n `,\n title: css`\n font-size: ${fontSize.xl};\n font-weight: 600;\n color: ${colors.text};\n margin: 0;\n letter-spacing: -0.02em;\n `,\n closeBtn: css`\n padding: 6px;\n background: ${colors.surface};\n border: 1px solid ${colors.border};\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n \n &:hover {\n background-color: ${colors.surfaceHover};\n border-color: ${colors.borderHover};\n }\n `,\n sections: css`\n display: flex;\n flex-direction: column;\n gap: 24px;\n `,\n sectionTitle: css`\n font-size: ${fontSize.base};\n font-weight: 600;\n color: ${colors.text};\n margin: 0 0 12px 0;\n `,\n description: css`\n font-size: ${fontSize.sm};\n color: ${colors.textSecondary};\n margin: 0 0 12px 0;\n `,\n code: css`\n background-color: ${colors.background};\n border-radius: 8px;\n padding: 12px;\n font-family: 'SF Mono', Monaco, Consolas, monospace;\n font-size: ${fontSize.xs};\n color: ${colors.textSecondary};\n border: 1px solid ${colors.border};\n `,\n codeLine: css`\n margin: 0 0 4px 0;\n \n &:last-child {\n margin: 0;\n }\n `,\n input: css`\n width: 100%;\n padding: 10px 14px;\n border: 1px solid ${colors.border};\n border-radius: 6px;\n font-size: ${fontSize.base};\n color: ${colors.text};\n background: ${colors.surface};\n transition: all 0.15s ease;\n \n &:focus {\n outline: none;\n border-color: ${colors.primary};\n box-shadow: 0 0 0 3px ${colors.primaryLight};\n }\n \n &::placeholder {\n color: ${colors.textMuted};\n }\n `,\n grid: css`\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 12px;\n `,\n label: css`\n font-size: ${fontSize.xs};\n font-weight: 500;\n color: ${colors.textSecondary};\n display: block;\n margin-bottom: 6px;\n `,\n footer: css`\n margin-top: 24px;\n padding-top: 20px;\n border-top: 1px solid ${colors.border};\n display: flex;\n justify-content: flex-end;\n gap: 12px;\n `,\n cancelBtn: css`\n padding: 10px 18px;\n font-size: ${fontSize.base};\n font-weight: 500;\n color: ${colors.text};\n background: ${colors.surface};\n border: 1px solid ${colors.border};\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s ease;\n \n &:hover {\n background-color: ${colors.surfaceHover};\n border-color: ${colors.borderHover};\n }\n `,\n saveBtn: css`\n padding: 10px 18px;\n font-size: ${fontSize.base};\n font-weight: 500;\n color: white;\n background-color: ${colors.primary};\n border: 1px solid ${colors.primary};\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s ease;\n \n &:hover {\n background-color: ${colors.primaryHover};\n border-color: ${colors.primaryHover};\n }\n `,\n}\n\nexport function StudioSettings() {\n const [isOpen, setIsOpen] = useState(false)\n\n return (\n <>\n <button css={styles.btn} onClick={() => setIsOpen(true)} aria-label=\"Settings\">\n <svg\n css={styles.icon}\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n <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\" />\n </svg>\n </button>\n\n {isOpen && <SettingsPanel onClose={() => setIsOpen(false)} />}\n </>\n )\n}\n\nfunction SettingsPanel({ onClose }: { onClose: () => void }) {\n return (\n <div css={styles.overlay} onClick={onClose}>\n <div css={styles.panel} onClick={(e) => e.stopPropagation()}>\n <div css={styles.header}>\n <h2 css={styles.title}>Settings</h2>\n <button css={styles.closeBtn} onClick={onClose}>\n <svg css={styles.icon} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n\n <div css={styles.sections}>\n <section>\n <h3 css={styles.sectionTitle}>Cloudflare R2</h3>\n <p css={styles.description}>Configure in .env.local file:</p>\n <div css={styles.code}>\n <p css={styles.codeLine}>CLOUDFLARE_R2_ACCOUNT_ID</p>\n <p css={styles.codeLine}>CLOUDFLARE_R2_ACCESS_KEY_ID</p>\n <p css={styles.codeLine}>CLOUDFLARE_R2_SECRET_ACCESS_KEY</p>\n <p css={styles.codeLine}>CLOUDFLARE_R2_BUCKET_NAME</p>\n <p css={styles.codeLine}>CLOUDFLARE_R2_PUBLIC_URL</p>\n </div>\n </section>\n\n <section>\n <h3 css={styles.sectionTitle}>Custom CDN URL</h3>\n <p css={styles.description}>Override the default R2 URL with a custom domain:</p>\n <input css={styles.input} type=\"text\" placeholder=\"https://cdn.yourdomain.com\" />\n </section>\n\n <section>\n <h3 css={styles.sectionTitle}>Thumbnail Sizes</h3>\n <div css={styles.grid}>\n <div>\n <label css={styles.label}>Small</label>\n <input css={styles.input} type=\"number\" defaultValue={300} />\n </div>\n <div>\n <label css={styles.label}>Medium</label>\n <input css={styles.input} type=\"number\" defaultValue={700} />\n </div>\n <div>\n <label css={styles.label}>Large</label>\n <input css={styles.input} type=\"number\" defaultValue={1400} />\n </div>\n </div>\n </section>\n </div>\n\n <div css={styles.footer}>\n <button css={styles.cancelBtn} onClick={onClose}>Cancel</button>\n <button css={styles.saveBtn}>Save Changes</button>\n </div>\n </div>\n </div>\n )\n}\n"],"mappings":";;;;;;;;;AAGA,SAAS,aAAAA,YAAW,eAAAC,cAAa,YAAAC,iBAAgB;AACjD,SAAS,OAAAC,YAAW;;;ACFpB,SAAS,eAAe,kBAAkB;AA+C1C,IAAM,eAA4B;AAAA,EAChC,QAAQ;AAAA,EACR,YAAY,MAAM;AAAA,EAAC;AAAA,EACnB,aAAa,MAAM;AAAA,EAAC;AAAA,EACpB,cAAc,MAAM;AAAA,EAAC;AAAA,EACrB,aAAa;AAAA,EACb,gBAAgB,MAAM;AAAA,EAAC;AAAA,EACvB,YAAY,MAAM;AAAA,EAAC;AAAA,EACnB,eAAe,oBAAI,IAAI;AAAA,EACvB,iBAAiB,MAAM;AAAA,EAAC;AAAA,EACxB,aAAa,MAAM;AAAA,EAAC;AAAA,EACpB,WAAW,MAAM;AAAA,EAAC;AAAA,EAClB,gBAAgB,MAAM;AAAA,EAAC;AAAA,EACvB,kBAAkB;AAAA,EAClB,UAAU;AAAA,EACV,aAAa,MAAM;AAAA,EAAC;AAAA,EACpB,aAAa;AAAA,EACb,gBAAgB,MAAM;AAAA,EAAC;AAAA,EACvB,MAAM;AAAA,EACN,SAAS,MAAM;AAAA,EAAC;AAAA,EAChB,WAAW;AAAA,EACX,cAAc,MAAM;AAAA,EAAC;AAAA,EACrB,YAAY;AAAA,EACZ,gBAAgB,MAAM;AAAA,EAAC;AACzB;AAEO,IAAM,gBAAgB,cAA2B,YAAY;AAK7D,SAAS,YAAY;AAC1B,SAAO,WAAW,aAAa;AACjC;;;AC/EA,SAAS,aAAa,QAAQ,gBAAgB;AAC9C,SAAS,OAAAC,MAAK,aAAAC,kBAAiB;;;ACD/B,SAAS,KAAK,iBAAiB;AAqIrB,SAyIM,UAzIN,KAKF,YALE;AAlIV,IAAM,SAAS;AAAA;AAAA;AAAA;AAKf,IAAM,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWhB,IAAM,SAAS;AAAA,EACb,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBASM,MAAM;AAAA,mBACJ,SAAS;AAAA;AAAA,EAE1B,OAAO;AAAA,MACH,SAAS;AAAA,wBACS,OAAO,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,iBAKrB,OAAO;AAAA;AAAA;AAAA,EAGtB,QAAQ;AAAA;AAAA;AAAA,EAGR,OAAO;AAAA,iBACQ,SAAS,EAAE;AAAA;AAAA,aAEf,OAAO,IAAI;AAAA;AAAA;AAAA;AAAA,EAItB,MAAM;AAAA;AAAA;AAAA,EAGN,SAAS;AAAA,iBACM,SAAS,IAAI;AAAA,aACjB,OAAO,aAAa;AAAA;AAAA;AAAA;AAAA,EAI/B,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,4BAKkB,OAAO,MAAM;AAAA,wBACjB,OAAO,UAAU;AAAA;AAAA,EAEvC,KAAK;AAAA;AAAA,iBAEU,SAAS,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO5B,WAAW;AAAA,wBACW,OAAO,OAAO;AAAA,wBACd,OAAO,MAAM;AAAA,aACxB,OAAO,IAAI;AAAA;AAAA;AAAA,0BAGE,OAAO,YAAY;AAAA,sBACvB,OAAO,WAAW;AAAA;AAAA;AAAA,EAGtC,YAAY;AAAA,wBACU,OAAO,OAAO;AAAA,wBACd,OAAO,OAAO;AAAA;AAAA;AAAA;AAAA,0BAIZ,OAAO,YAAY;AAAA,sBACvB,OAAO,YAAY;AAAA;AAAA;AAAA,EAGvC,WAAW;AAAA,wBACW,OAAO,MAAM;AAAA,wBACb,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA,0BAIX,OAAO,WAAW;AAAA,sBACtB,OAAO,WAAW;AAAA;AAAA;AAGxC;AAYO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf,cAAc;AAAA,EACd,UAAU;AAAA,EACV;AAAA,EACA;AACF,GAAsB;AACpB,SACE,oBAAC,SAAI,KAAK,OAAO,SAAS,SAAS,UACjC,+BAAC,SAAI,KAAK,OAAO,OAAO,SAAS,CAAC,MAAM,EAAE,gBAAgB,GACxD;AAAA,wBAAC,SAAI,KAAK,OAAO,QACf,8BAAC,QAAG,KAAK,OAAO,OAAQ,iBAAM,GAChC;AAAA,IACA,oBAAC,SAAI,KAAK,OAAO,MACf,8BAAC,OAAE,KAAK,OAAO,SAAU,mBAAQ,GACnC;AAAA,IACA,qBAAC,SAAI,KAAK,OAAO,QACf;AAAA,0BAAC,YAAO,KAAK,CAAC,OAAO,KAAK,OAAO,SAAS,GAAG,SAAS,UACnD,uBACH;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,KAAK,CAAC,OAAO,KAAK,YAAY,WAAW,OAAO,YAAY,OAAO,UAAU;AAAA,UAC7E,SAAS;AAAA,UAER;AAAA;AAAA,MACH;AAAA,OACF;AAAA,KACF,GACF;AAEJ;AASO,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd;AACF,GAAoB;AAClB,SACE,oBAAC,SAAI,KAAK,OAAO,SAAS,SAAS,SACjC,+BAAC,SAAI,KAAK,OAAO,OAAO,SAAS,CAAC,MAAM,EAAE,gBAAgB,GACxD;AAAA,wBAAC,SAAI,KAAK,OAAO,QACf,8BAAC,QAAG,KAAK,OAAO,OAAQ,iBAAM,GAChC;AAAA,IACA,oBAAC,SAAI,KAAK,OAAO,MACf,8BAAC,OAAE,KAAK,OAAO,SAAU,mBAAQ,GACnC;AAAA,IACA,oBAAC,SAAI,KAAK,OAAO,QACf,8BAAC,YAAO,KAAK,CAAC,OAAO,KAAK,OAAO,UAAU,GAAG,SAAS,SACpD,uBACH,GACF;AAAA,KACF,GACF;AAEJ;AAEA,IAAM,iBAAiB;AAAA,EACrB,mBAAmB;AAAA;AAAA;AAAA,EAGnB,aAAa;AAAA;AAAA;AAAA,wBAGS,OAAO,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA,EAKvC,cAAc;AAAA;AAAA,yCAEyB,OAAO,OAAO,KAAK,OAAO,YAAY;AAAA;AAAA;AAAA;AAAA,EAI7E,cAAc;AAAA,iBACC,SAAS,EAAE;AAAA,aACf,OAAO,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAM/B,aAAa;AAAA,iBACE,SAAS,EAAE;AAAA,aACf,OAAO,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAM7B;AAqBO,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAuB;AACrB,QAAM,aAAa,SAAS,WAAW;AACvC,QAAM,UAAU,SAAS,WAAW;AACpC,QAAM,YAAY,SAAS,WAAW;AACtC,QAAM,WAAW,cAAc,WAAW;AAC1C,QAAM,YAAY,CAAC;AAEnB,SACE,oBAAC,SAAI,KAAK,OAAO,SACf,+BAAC,SAAI,KAAK,OAAO,OAAO,SAAS,CAAC,MAAM,EAAE,gBAAgB,GACxD;AAAA,wBAAC,SAAI,KAAK,OAAO,QACf,8BAAC,QAAG,KAAK,OAAO,OAAQ,iBAAM,GAChC;AAAA,IACA,oBAAC,SAAI,KAAK,OAAO,MACd,oBACC,oBAAC,OAAE,KAAK,OAAO,SAAU,mBAAS,WAAW,qBAAoB,IAC/D,YACF,qBAAC,OAAE,KAAK,OAAO,SAAS;AAAA;AAAA,MACS,SAAS,aAAa,SAAS;AAAA,MAAQ;AAAA,OAAQ,SAAS,aAAa,SAAS,aAAa,IAAI,MAAM;AAAA,MAAG;AAAA,OACzI,IACE,aACF,qBAAC,OAAE,KAAK,OAAO,SAAS;AAAA;AAAA,MACX,SAAS;AAAA,MAAU;AAAA,MAAO,SAAS,cAAc,IAAI,MAAM;AAAA,MAAG;AAAA,MACxE,SAAS,mBAAmB,UAAa,SAAS,iBAAiB,IAClE,iCAAE;AAAA;AAAA,QAAU,SAAS;AAAA,QAAe;AAAA,QAAoB,SAAS,mBAAmB,IAAI,MAAM;AAAA,QAAG;AAAA,SAAC,IAChG;AAAA,MACH,SAAS,WAAW,UAAa,SAAS,SAAS,IAClD,iCAAE;AAAA;AAAA,QAAE,SAAS;AAAA,QAAO;AAAA,QAAO,SAAS,WAAW,IAAI,MAAM;AAAA,QAAG;AAAA,SAAU,IACpE;AAAA,OACN,IAEA,iCACE;AAAA,0BAAC,OAAE,KAAK,OAAO,SACZ,mBAAS,WAAW,YACjB,kCACA,wBACN;AAAA,MACA,qBAAC,SAAI,KAAK,eAAe,mBACvB;AAAA,4BAAC,SAAI,KAAK,eAAe,aACvB;AAAA,UAAC;AAAA;AAAA,YACC,KAAK,eAAe;AAAA,YACpB,OAAO,EAAE,OAAO,GAAG,SAAS,OAAO,IAAI;AAAA;AAAA,QACzC,GACF;AAAA,QACA,qBAAC,SAAI,KAAK,eAAe,cACvB;AAAA,+BAAC,UAAM;AAAA,qBAAS;AAAA,YAAQ;AAAA,YAAK,SAAS;AAAA,aAAM;AAAA,UAC5C,qBAAC,UAAM;AAAA,qBAAS;AAAA,YAAQ;AAAA,aAAC;AAAA,WAC3B;AAAA,QACC,SAAS,eACR,oBAAC,OAAE,KAAK,eAAe,aAAa,OAAO,SAAS,aACjD,mBAAS,aACZ;AAAA,SAEJ;AAAA,OACF,GAEJ;AAAA,IACA,qBAAC,SAAI,KAAK,OAAO,QACd;AAAA,mBAAa,UACZ,oBAAC,YAAO,KAAK,CAAC,OAAO,KAAK,OAAO,SAAS,GAAG,SAAS,QAAQ,kBAE9D;AAAA,MAED,YACC,oBAAC,YAAO,KAAK,CAAC,OAAO,KAAK,OAAO,UAAU,GAAG,SAAS,SAAS,kBAEhE;AAAA,OAEJ;AAAA,KACF,GACF;AAEJ;;;ADkNI,qBAAAC,WAEI,OAAAC,MA2DE,QAAAC,aA7DN;AAzgBJ,IAAM,YAAY;AAElB,IAAM,OAAOC;AAAA;AAAA;AAIb,IAAMC,UAAS;AAAA,EACb,SAASC;AAAA;AAAA;AAAA;AAAA;AAAA,wBAKa,OAAO,OAAO;AAAA,+BACP,OAAO,MAAM;AAAA;AAAA,EAE1C,MAAMA;AAAA;AAAA;AAAA;AAAA;AAAA,EAKN,OAAOA;AAAA;AAAA;AAAA;AAAA;AAAA,EAKP,KAAKA;AAAA;AAAA;AAAA;AAAA;AAAA,cAKO,SAAS;AAAA;AAAA;AAAA,iBAGN,SAAS,IAAI;AAAA;AAAA,kBAEZ,OAAO,OAAO;AAAA,wBACR,OAAO,MAAM;AAAA;AAAA;AAAA,aAGxB,OAAO,IAAI;AAAA;AAAA;AAAA;AAAA,0BAIE,OAAO,YAAY;AAAA,sBACvB,OAAO,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQtC,aAAaA;AAAA;AAAA;AAAA,EAGb,YAAYA;AAAA,kBACI,OAAO,OAAO;AAAA,oBACZ,OAAO,OAAO;AAAA;AAAA;AAAA;AAAA,oBAId,OAAO,YAAY;AAAA,sBACjB,OAAO,YAAY;AAAA;AAAA;AAAA,EAGvC,WAAWA;AAAA,aACA,OAAO,MAAM;AAAA;AAAA;AAAA,0BAGA,OAAO,WAAW;AAAA,sBACtB,OAAO,MAAM;AAAA;AAAA;AAAA,EAGjC,MAAMA;AAAA;AAAA;AAAA;AAAA,EAIN,UAAUA;AAAA,iBACK,IAAI;AAAA;AAAA,EAEnB,gBAAgBA;AAAA,iBACD,SAAS,IAAI;AAAA,aACjB,OAAO,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAM/B,UAAUA;AAAA,aACC,OAAO,OAAO;AAAA;AAAA;AAAA;AAAA,iBAIV,SAAS,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQ5B,SAASA;AAAA;AAAA;AAAA,kBAGO,OAAO,MAAM;AAAA;AAAA;AAAA,EAG7B,YAAYA;AAAA;AAAA;AAAA,cAGA,SAAS;AAAA,wBACC,OAAO,OAAO;AAAA,wBACd,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA,EAInC,SAASA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,aAME,OAAO,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAOlB,OAAO,IAAI;AAAA,0BACA,OAAO,YAAY;AAAA;AAAA;AAAA,EAG3C,eAAeA;AAAA,wBACO,OAAO,UAAU;AAAA,aAC5B,OAAO,IAAI;AAAA;AAExB;AAEO,SAAS,gBAAgB;AAC9B,QAAM,EAAE,eAAe,UAAU,aAAa,gBAAgB,aAAa,gBAAgB,YAAY,IAAI,UAAU;AACrH,QAAM,eAAe,OAAyB,IAAI;AAClD,QAAM,qBAAqB,OAA+B,IAAI;AAC9D,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,KAAK;AAChD,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,KAAK;AAClD,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,KAAK;AAClD,QAAM,CAAC,mBAAmB,oBAAoB,IAAI,SAAS,KAAK;AAChE,QAAM,CAAC,oBAAoB,qBAAqB,IAAI,SAAS,KAAK;AAClE,QAAM,CAAC,cAAc,eAAe,IAAI,SAAS,KAAK;AACtD,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAAwB;AAAA,IAChE,SAAS;AAAA,IACT,OAAO;AAAA,IACP,SAAS;AAAA,IACT,QAAQ;AAAA,EACV,CAAC;AACD,QAAM,CAAC,cAAc,eAAe,IAAI,SAAS,CAAC;AAClD,QAAM,CAAC,aAAa,cAAc,IAAI,SAA6B,KAAK;AACxE,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,SAAmB,CAAC,CAAC;AACnE,QAAM,CAAC,cAAc,eAAe,IAAI,SAAoD,IAAI;AAGhG,QAAM,mBAAmB,gBAAgB,mBAAmB,YAAY,WAAW,gBAAgB;AAEnG,QAAM,eAAe,YAAY,MAAM;AACrC,iBAAa,SAAS,MAAM;AAAA,EAC9B,GAAG,CAAC,CAAC;AAEL,QAAM,gBAAgB,YAAY,MAAM;AACtC,kBAAc,IAAI;AAClB,mBAAe;AACf,eAAW,MAAM,cAAc,KAAK,GAAG,GAAG;AAAA,EAC5C,GAAG,CAAC,cAAc,CAAC;AAEnB,QAAM,mBAAmB,YAAY,OAAO,MAA2C;AACrF,UAAM,QAAQ,EAAE,OAAO;AACvB,QAAI,CAAC,SAAS,MAAM,WAAW,EAAG;AAElC,iBAAa,IAAI;AACjB,QAAI;AACF,iBAAW,QAAQ,MAAM,KAAK,KAAK,GAAG;AACpC,cAAM,WAAW,IAAI,SAAS;AAC9B,iBAAS,OAAO,QAAQ,IAAI;AAC5B,iBAAS,OAAO,QAAQ,WAAW;AAEnC,cAAM,WAAW,MAAM,MAAM,sBAAsB;AAAA,UACjD,QAAQ;AAAA,UACR,MAAM;AAAA,QACR,CAAC;AAED,YAAI,CAAC,SAAS,IAAI;AAChB,gBAAM,QAAQ,MAAM,SAAS,KAAK;AAClC,cAAI,SAAS,UAAU,KAAK;AAC1B,oBAAQ,MAAM,iBAAiB,KAAK;AACpC,4BAAgB;AAAA,cACd,OAAO;AAAA,cACP,SAAS,oBAAoB,KAAK,IAAI,KAAK,MAAM,SAAS,eAAe;AAAA,YAC3E,CAAC;AAAA,UACH,OAAO;AACL,4BAAgB;AAAA,cACd,OAAO;AAAA,cACP,SAAS,MAAM,SAAS;AAAA,YAC1B,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AACA,qBAAe;AAAA,IACjB,SAAS,OAAO;AACd,cAAQ,MAAM,iBAAiB,KAAK;AACpC,sBAAgB;AAAA,QACd,OAAO;AAAA,QACP,SAAS;AAAA,MACX,CAAC;AAAA,IACH,UAAE;AACA,mBAAa,KAAK;AAClB,UAAI,aAAa,SAAS;AACxB,qBAAa,QAAQ,QAAQ;AAAA,MAC/B;AAAA,IACF;AAAA,EACF,GAAG,CAAC,aAAa,cAAc,CAAC;AAEhC,QAAM,sBAAsB,YAAY,YAAY;AAClD,UAAMC,gBAAe,cAAc,OAAO;AAE1C,QAAIA,eAAc;AAChB,YAAM,gBAAgB,MAAM,KAAK,aAAa;AAG9C,YAAM,kBAAkB,CAAC,OAAO,QAAQ,OAAO,OAAO,QAAQ,OAAO,OAAO,OAAO,QAAQ,KAAK;AAChG,YAAM,qBAAqB,cAAc,OAAO,OAAK;AACnD,cAAM,MAAM,EAAE,MAAM,GAAG,EAAE,IAAI,GAAG,YAAY,KAAK;AACjD,eAAO,gBAAgB,SAAS,GAAG;AAAA,MACrC,CAAC;AACD,YAAM,kBAAkB,cAAc,OAAO,OAAK,CAAC,EAAE,SAAS,GAAG,KAAK,EAAE,SAAS,GAAG,CAAC;AAGrF,UAAI,gBAAgB,SAAS,GAAG;AAC9B,YAAI;AACF,gBAAM,WAAW,MAAM,MAAM,qCAAqC,mBAAmB,gBAAgB,KAAK,GAAG,CAAC,CAAC,EAAE;AACjH,gBAAM,OAAO,MAAM,SAAS,KAAK;AAEjC,cAAI,KAAK,QAAQ;AAEf,uBAAW,OAAO,KAAK,QAAQ;AAC7B,oBAAM,WAAW,UAAU,GAAG;AAC9B,kBAAI,CAAC,mBAAmB,SAAS,QAAQ,GAAG;AAC1C,mCAAmB,KAAK,QAAQ;AAAA,cAClC;AAAA,YACF;AAAA,UACF;AAAA,QACF,SAAS,OAAO;AACd,kBAAQ,MAAM,gCAAgC,KAAK;AAAA,QACrD;AAAA,MACF;AAEA,UAAI,mBAAmB,WAAW,GAAG;AACnC,wBAAgB;AAAA,UACd,OAAO;AAAA,UACP,SAAS;AAAA,QACX,CAAC;AACD;AAAA,MACF;AAEA,sBAAgB,mBAAmB,MAAM;AACzC,yBAAmB,kBAAkB;AACrC,qBAAe,UAAU;AACzB,4BAAsB,IAAI;AAAA,IAC5B,OAAO;AAEL,UAAI;AACF,cAAM,WAAW,MAAM,MAAM,0BAA0B;AACvD,cAAM,OAAO,MAAM,SAAS,KAAK;AAEjC,YAAI,KAAK,UAAU,GAAG;AACpB,0BAAgB;AAAA,YACd,OAAO;AAAA,YACP,SAAS;AAAA,UACX,CAAC;AACD;AAAA,QACF;AAEA,wBAAgB,KAAK,KAAK;AAC1B,uBAAe,KAAK;AACpB,8BAAsB,IAAI;AAAA,MAC5B,SAAS,OAAO;AACd,gBAAQ,MAAM,2BAA2B,KAAK;AAC9C,wBAAgB;AAAA,UACd,OAAO;AAAA,UACP,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF,GAAG,CAAC,aAAa,CAAC;AAElB,QAAM,uBAAuB,YAAY,YAAY;AACnD,0BAAsB,KAAK;AAC3B,kBAAc,IAAI;AAGlB,uBAAmB,UAAU,IAAI,gBAAgB;AACjD,UAAM,SAAS,mBAAmB,QAAQ;AAE1C,QAAI;AACF,UAAI,gBAAgB,OAAO;AAEzB,wBAAgB,IAAI;AACpB,yBAAiB;AAAA,UACf,SAAS;AAAA,UACT,OAAO;AAAA,UACP,SAAS;AAAA,UACT,QAAQ;AAAA,QACV,CAAC;AAED,cAAM,WAAW,MAAM,MAAM,2BAA2B;AAAA,UACtD,QAAQ;AAAA,UACR;AAAA,QACF,CAAC;AAED,YAAI,CAAC,SAAS,MAAM;AAClB,gBAAM,IAAI,MAAM,kBAAkB;AAAA,QACpC;AAEA,cAAM,SAAS,SAAS,KAAK,UAAU;AACvC,cAAM,UAAU,IAAI,YAAY;AAEhC,YAAI;AACF,iBAAO,MAAM;AACX,kBAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,gBAAI,KAAM;AAGV,gBAAI,OAAO,SAAS;AAClB,qBAAO,OAAO;AACd;AAAA,YACF;AAEA,kBAAM,OAAO,QAAQ,OAAO,KAAK;AACjC,kBAAM,QAAQ,KAAK,MAAM,MAAM,EAAE,OAAO,UAAQ,KAAK,WAAW,QAAQ,CAAC;AAEzE,uBAAW,QAAQ,OAAO;AACxB,kBAAI;AACF,sBAAM,OAAO,KAAK,MAAM,KAAK,QAAQ,UAAU,EAAE,CAAC;AAElD,oBAAI,KAAK,SAAS,SAAS;AACzB,mCAAiB,WAAS;AAAA,oBACxB,GAAG;AAAA,oBACH,OAAO,KAAK;AAAA,kBACd,EAAE;AAAA,gBACJ,WAAW,KAAK,SAAS,YAAY;AACnC,mCAAiB;AAAA,oBACf,SAAS,KAAK;AAAA,oBACd,OAAO,KAAK;AAAA,oBACZ,SAAS,KAAK;AAAA,oBACd,aAAa,KAAK;AAAA,oBAClB,QAAQ;AAAA,kBACV,CAAC;AAAA,gBACH,WAAW,KAAK,SAAS,WAAW;AAClC,mCAAiB,WAAS;AAAA,oBACxB,GAAG;AAAA,oBACH,QAAQ;AAAA,oBACR,aAAa;AAAA,kBACf,EAAE;AAAA,gBACJ,WAAW,KAAK,SAAS,YAAY;AACnC,mCAAiB;AAAA,oBACf,SAAS,KAAK;AAAA,oBACd,OAAO,KAAK;AAAA,oBACZ,SAAS;AAAA,oBACT,QAAQ;AAAA,oBACR,WAAW,KAAK;AAAA,oBAChB,gBAAgB,KAAK;AAAA,oBACrB,QAAQ,KAAK;AAAA,kBACf,CAAC;AACD,iCAAe;AAAA,gBACjB,WAAW,KAAK,SAAS,SAAS;AAChC,mCAAiB,WAAS;AAAA,oBACxB,GAAG;AAAA,oBACH,QAAQ;AAAA,oBACR,SAAS,KAAK;AAAA,kBAChB,EAAE;AAAA,gBACJ;AAAA,cACF,QAAQ;AAAA,cAER;AAAA,YACF;AAAA,UACF;AAAA,QACF,SAAS,KAAK;AACZ,cAAI,OAAO,SAAS;AAElB,6BAAiB,WAAS;AAAA,cACxB,GAAG;AAAA,cACH,QAAQ;AAAA,cACR,WAAW,KAAK;AAAA,YAClB,EAAE;AACF,2BAAe;AAAA,UACjB,OAAO;AACL,kBAAM;AAAA,UACR;AAAA,QACF;AAAA,MACF,OAAO;AAEL,wBAAgB,IAAI;AACpB,yBAAiB;AAAA,UACf,SAAS;AAAA,UACT,OAAO;AAAA,UACP,SAAS;AAAA,UACT,QAAQ;AAAA,QACV,CAAC;AAGD,cAAM,oBAAoB,gBAAgB,IAAI,OAAK,EAAE,QAAQ,aAAa,EAAE,CAAC;AAE7E,cAAM,WAAW,MAAM,MAAM,yBAAyB;AAAA,UACpD,QAAQ;AAAA,UACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,UAC9C,MAAM,KAAK,UAAU,EAAE,WAAW,kBAAkB,CAAC;AAAA,UACrD;AAAA,QACF,CAAC;AAED,cAAM,OAAO,MAAM,SAAS,KAAK;AAEjC,YAAI,SAAS,IAAI;AACf,2BAAiB;AAAA,YACf,SAAS,KAAK,WAAW,UAAU;AAAA,YACnC,OAAO,KAAK,WAAW,UAAU;AAAA,YACjC,SAAS;AAAA,YACT,QAAQ;AAAA,YACR,WAAW,KAAK,WAAW,UAAU;AAAA,YACrC,QAAQ,KAAK,QAAQ,UAAU;AAAA,UACjC,CAAC;AACD,yBAAe;AACf,yBAAe;AAAA,QACjB,OAAO;AACL,2BAAiB;AAAA,YACf,SAAS;AAAA,YACT,OAAO;AAAA,YACP,SAAS;AAAA,YACT,QAAQ;AAAA,YACR,SAAS,KAAK,SAAS;AAAA,UACzB,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,UAAI,OAAO,SAAS;AAElB,yBAAiB,WAAS;AAAA,UACxB,GAAG;AAAA,UACH,QAAQ;AAAA,UACR,WAAW,KAAK;AAAA,QAClB,EAAE;AACF,uBAAe;AAAA,MACjB,OAAO;AACL,gBAAQ,MAAM,qBAAqB,KAAK;AACxC,yBAAiB;AAAA,UACf,SAAS;AAAA,UACT,OAAO;AAAA,UACP,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AAAA,IACF,UAAE;AACA,oBAAc,KAAK;AACnB,yBAAmB,UAAU;AAAA,IAC/B;AAAA,EACF,GAAG,CAAC,aAAa,cAAc,iBAAiB,gBAAgB,cAAc,CAAC;AAE/E,QAAM,uBAAuB,YAAY,MAAM;AAC7C,QAAI,mBAAmB,SAAS;AAC9B,yBAAmB,QAAQ,MAAM;AAAA,IACnC;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,oBAAoB,YAAY,MAAM;AAC1C,QAAI,cAAc,SAAS,EAAG;AAC9B,yBAAqB,IAAI;AAAA,EAC3B,GAAG,CAAC,aAAa,CAAC;AAElB,QAAM,sBAAsB,YAAY,YAAY;AAClD,yBAAqB,KAAK;AAE1B,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,sBAAsB;AAAA,QACjD,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAC9C,MAAM,KAAK,UAAU,EAAE,OAAO,MAAM,KAAK,aAAa,EAAE,CAAC;AAAA,MAC3D,CAAC;AAED,UAAI,SAAS,IAAI;AACf,uBAAe;AACf,uBAAe;AAAA,MACjB,OAAO;AACL,cAAM,QAAQ,MAAM,SAAS,KAAK;AAClC,wBAAgB;AAAA,UACd,OAAO;AAAA,UACP,SAAS,MAAM,SAAS;AAAA,QAC1B,CAAC;AAAA,MACH;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,MAAM,iBAAiB,KAAK;AACpC,sBAAgB;AAAA,QACd,OAAO;AAAA,QACP,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AAAA,EACF,GAAG,CAAC,eAAe,gBAAgB,cAAc,CAAC;AAElD,QAAM,gBAAgB,YAAY,MAAM;AACtC,YAAQ,IAAI,oBAAoB,aAAa;AAAA,EAC/C,GAAG,CAAC,aAAa,CAAC;AAElB,QAAM,aAAa,YAAY,MAAM;AACnC,YAAQ,IAAI,cAAc;AAAA,EAC5B,GAAG,CAAC,CAAC;AAEL,QAAM,eAAe,cAAc,OAAO;AAG1C,MAAI,aAAa;AACf,WAAO;AAAA,EACT;AAEA,SACE,gBAAAJ,MAAAF,WAAA,EACG;AAAA,yBACC,gBAAAC;AAAA,MAAC;AAAA;AAAA,QACC,OAAM;AAAA,QACN,SAAS,mCAAmC,cAAc,IAAI;AAAA,QAC9D,cAAa;AAAA,QACb,SAAQ;AAAA,QACR,WAAW;AAAA,QACX,UAAU,MAAM,qBAAqB,KAAK;AAAA;AAAA,IAC5C;AAAA,IAGD,sBACC,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,OAAM;AAAA,QACN,SAAS,gBAAgB,QACrB,SAAS,YAAY,SAAS,iBAAiB,IAAI,MAAM,EAAE,qHAC3D,WAAW,YAAY,kBAAkB,iBAAiB,IAAI,MAAM,EAAE;AAAA,QAE1E,cAAc,aAAa,kBAAkB;AAAA,QAC7C,WAAW;AAAA,QACX,UAAU,MAAM,sBAAsB,KAAK;AAAA;AAAA,IAC7C;AAAA,IAGD,gBACC,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,OAAM;AAAA,QACN,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,SAAS,MAAM;AACb,0BAAgB,KAAK;AACrB,2BAAiB;AAAA,YACf,SAAS;AAAA,YACT,OAAO;AAAA,YACP,SAAS;AAAA,YACT,QAAQ;AAAA,UACV,CAAC;AAAA,QACH;AAAA;AAAA,IACF;AAAA,IAGD,gBACC,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,aAAa;AAAA,QACpB,SAAS,aAAa;AAAA,QACtB,SAAS,MAAM,gBAAgB,IAAI;AAAA;AAAA,IACrC;AAAA,IAGF,gBAAAC,MAAC,SAAI,KAAKE,QAAO,SACf;AAAA,sBAAAH;AAAA,QAAC;AAAA;AAAA,UACC,KAAK;AAAA,UACL,MAAK;AAAA,UACL,UAAQ;AAAA,UACR,QAAO;AAAA,UACP,UAAU;AAAA,UACV,OAAO,EAAE,SAAS,OAAO;AAAA;AAAA,MAC3B;AAAA,MAEA,gBAAAC,MAAC,SAAI,KAAKE,QAAO,MACf;AAAA,wBAAAF;AAAA,UAAC;AAAA;AAAA,YACC,KAAK,CAACE,QAAO,KAAKA,QAAO,UAAU;AAAA,YACnC,SAAS;AAAA,YACT,UAAU,aAAa;AAAA,YAEvB;AAAA,8BAAAH,KAAC,cAAW;AAAA,cACX,YAAY,iBAAiB;AAAA;AAAA;AAAA,QAChC;AAAA,QAEA,gBAAAA,KAAC,SAAI,KAAKG,QAAO,SAAS;AAAA,QAE1B,gBAAAF;AAAA,UAAC;AAAA;AAAA,YACC,KAAKE,QAAO;AAAA,YACZ,SAAS;AAAA,YACT,UAAU;AAAA,YAEV;AAAA,8BAAAH,KAAC,kBAAe;AAAA,cACf,aAAa,kBAAkB;AAAA;AAAA;AAAA,QAClC;AAAA,QACA,gBAAAC;AAAA,UAAC;AAAA;AAAA,YACC,KAAK,CAACE,QAAO,KAAKA,QAAO,SAAS;AAAA,YAClC,SAAS;AAAA,YACT,UAAU,CAAC;AAAA,YAEX;AAAA,8BAAAH,KAAC,aAAU;AAAA,cAAE;AAAA;AAAA;AAAA,QAEf;AAAA,QACA,gBAAAC;AAAA,UAAC;AAAA;AAAA,YACC,KAAKE,QAAO;AAAA,YACZ,SAAS;AAAA,YACT,UAAU,CAAC;AAAA,YAEX;AAAA,8BAAAH,KAAC,aAAU;AAAA,cAAE;AAAA;AAAA;AAAA,QAEf;AAAA,QACA,gBAAAC,MAAC,YAAO,KAAKE,QAAO,KAAK,SAAS,YAChC;AAAA,0BAAAH,KAAC,YAAS;AAAA,UAAE;AAAA,WAEd;AAAA,SACF;AAAA,MAEA,gBAAAC,MAAC,SAAI,KAAKE,QAAO,OACd;AAAA,wBACC,gBAAAF,MAAC,UAAK,KAAKE,QAAO,gBACf;AAAA,wBAAc;AAAA,UAAK;AAAA,UACpB,gBAAAH,KAAC,YAAO,KAAKG,QAAO,UAAU,SAAS,gBAAgB,mBAEvD;AAAA,WACF;AAAA,QAGF,gBAAAH;AAAA,UAAC;AAAA;AAAA,YACC,KAAK,CAACG,QAAO,KAAKA,QAAO,WAAW;AAAA,YACpC,SAAS;AAAA,YAET,0BAAAH,KAAC,eAAY,UAAU,YAAY;AAAA;AAAA,QACrC;AAAA,QAEA,gBAAAC,MAAC,SAAI,KAAKE,QAAO,YACf;AAAA,0BAAAH;AAAA,YAAC;AAAA;AAAA,cACC,KAAK,CAACG,QAAO,SAAS,aAAa,UAAUA,QAAO,aAAa;AAAA,cACjE,SAAS,MAAM,YAAY,MAAM;AAAA,cACjC,cAAW;AAAA,cAEX,0BAAAH,KAAC,YAAS;AAAA;AAAA,UACZ;AAAA,UACA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,KAAK,CAACG,QAAO,SAAS,aAAa,UAAUA,QAAO,aAAa;AAAA,cACjE,SAAS,MAAM,YAAY,MAAM;AAAA,cACjC,cAAW;AAAA,cAEX,0BAAAH,KAAC,YAAS;AAAA;AAAA,UACZ;AAAA,WACF;AAAA,SACF;AAAA,OACF;AAAA,KACF;AAEJ;AAEA,SAAS,aAAa;AACpB,SACE,gBAAAA,KAAC,SAAI,KAAKG,QAAO,MAAM,MAAK,QAAO,QAAO,gBAAe,SAAQ,aAC/D,0BAAAH,KAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,kEAAiE,GACxI;AAEJ;AAEA,SAAS,YAAY,EAAE,SAAS,GAA2B;AACzD,SACE,gBAAAA,KAAC,SAAI,KAAK,CAACG,QAAO,MAAM,YAAYA,QAAO,QAAQ,GAAG,MAAK,QAAO,QAAO,gBAAe,SAAQ,aAC9F,0BAAAH,KAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,+GAA8G,GACrL;AAEJ;AAEA,SAAS,YAAY;AACnB,SACE,gBAAAA,KAAC,SAAI,KAAKG,QAAO,MAAM,MAAK,QAAO,QAAO,gBAAe,SAAQ,aAC/D,0BAAAH,KAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,gIAA+H,GACtM;AAEJ;AAEA,SAAS,YAAY;AACnB,SACE,gBAAAA,KAAC,SAAI,KAAKG,QAAO,MAAM,MAAK,QAAO,QAAO,gBAAe,SAAQ,aAC/D,0BAAAH,KAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,yFAAwF,GAC/J;AAEJ;AAEA,SAAS,WAAW;AAClB,SACE,gBAAAA,KAAC,SAAI,KAAKG,QAAO,MAAM,MAAK,QAAO,QAAO,gBAAe,SAAQ,aAC/D,0BAAAH,KAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,+CAA8C,GACrH;AAEJ;AAEA,SAAS,WAAW;AAClB,SACE,gBAAAA,KAAC,SAAI,KAAKG,QAAO,MAAM,MAAK,QAAO,QAAO,gBAAe,SAAQ,aAC/D,0BAAAH,KAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,wQAAuQ,GAC9U;AAEJ;AAEA,SAAS,WAAW;AAClB,SACE,gBAAAA,KAAC,SAAI,KAAKG,QAAO,MAAM,MAAK,QAAO,QAAO,gBAAe,SAAQ,aAC/D,0BAAAH,KAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,mCAAkC,GACzG;AAEJ;AAEA,SAAS,iBAAiB;AACxB,SACE,gBAAAA,KAAC,SAAI,KAAKG,QAAO,MAAM,MAAK,QAAO,QAAO,gBAAe,SAAQ,aAC/D,0BAAAH,KAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,6JAA4J,GACnO;AAEJ;;;AE3tBA,SAAS,WAAW,YAAAM,WAAU,UAAAC,eAAc;AAC5C,SAAS,OAAAC,MAAK,aAAAC,kBAAiB;AAgQvB,gBAAAC,MAUF,QAAAC,aAVE;AA3PR,IAAMC,QAAOC;AAAA;AAAA;AAIb,IAAMC,UAAS;AAAA,EACb,SAASC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMT,SAASA;AAAA;AAAA;AAAA;AAAA,wBAIa,OAAO,MAAM;AAAA,wBACb,OAAO,OAAO;AAAA,iBACrBH,KAAI;AAAA;AAAA,EAEnB,OAAOG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,aAMI,OAAO,aAAa;AAAA;AAAA,EAE/B,WAAWA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMX,WAAWA;AAAA,iBACI,SAAS,IAAI;AAAA;AAAA;AAAA;AAAA,eAIf,OAAO,SAAS;AAAA,mBACZ,SAAS,EAAE;AAAA;AAAA;AAAA,EAG5B,MAAMA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUN,MAAMA;AAAA;AAAA;AAAA,wBAGgB,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA,wBAIb,OAAO,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASpC,cAAcA;AAAA,oBACI,OAAO,OAAO;AAAA,4BACN,OAAO,OAAO;AAAA;AAAA;AAAA,sBAGpB,OAAO,OAAO;AAAA;AAAA;AAAA,EAGlC,YAAYA;AAAA;AAAA;AAAA;AAAA,sBAIQ,OAAO,OAAO;AAAA;AAAA;AAAA,EAGlC,iBAAiBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQjB,UAAUA;AAAA;AAAA;AAAA,oBAGQ,OAAO,OAAO;AAAA;AAAA;AAAA,EAGhC,UAAUA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAKY,OAAO,YAAY;AAAA,aAC9B,OAAO,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMzB,SAASA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAMO,OAAO,UAAU;AAAA;AAAA,EAEjC,YAAYA;AAAA;AAAA;AAAA;AAAA;AAAA,EAKZ,YAAYA;AAAA;AAAA;AAAA,aAGD,OAAO,SAAS;AAAA;AAAA,EAE3B,UAAUA;AAAA;AAAA;AAAA,aAGC,OAAO,SAAS;AAAA;AAAA,EAE3B,OAAOA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMP,OAAOA;AAAA;AAAA,wBAEe,OAAO,OAAO;AAAA,4BACV,OAAO,WAAW;AAAA;AAAA,EAE5C,UAAUA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMV,WAAWA;AAAA;AAAA;AAAA;AAAA,EAIX,MAAMA;AAAA,iBACS,SAAS,EAAE;AAAA;AAAA,aAEf,OAAO,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOtB,MAAMA;AAAA,iBACS,SAAS,EAAE;AAAA,aACf,OAAO,SAAS;AAAA;AAAA;AAAA,EAG3B,SAASA;AAAA;AAAA;AAAA,iBAGM,SAAS,EAAE;AAAA;AAAA,aAEf,OAAO,OAAO;AAAA,kBACT,OAAO,OAAO;AAAA,wBACR,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BASX,OAAO,YAAY;AAAA,sBACvB,OAAO,OAAO;AAAA;AAAA;AAAA,EAGlC,cAAcA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAKE,OAAO,OAAO;AAAA;AAAA,wBAER,OAAO,MAAM;AAAA;AAAA,EAEnC,gBAAgBA;AAAA;AAAA;AAAA;AAAA,iBAID,SAAS,IAAI;AAAA;AAAA,aAEjB,OAAO,aAAa;AAAA;AAAA;AAAA;AAAA,eAIlB,OAAO,IAAI;AAAA;AAAA;AAAA,EAGxB,mBAAmBA;AAAA;AAAA;AAAA,oBAGD,OAAO,OAAO;AAAA;AAElC;AAEO,SAAS,iBAAiB;AAC/B,QAAM,EAAE,aAAa,gBAAgB,YAAY,eAAe,iBAAiB,aAAa,kBAAkB,WAAW,gBAAgB,YAAY,eAAe,IAAI,UAAU;AACpL,QAAM,CAAC,OAAO,QAAQ,IAAIC,UAAqB,CAAC,CAAC;AACjD,QAAM,CAAC,SAAS,UAAU,IAAIA,UAAS,IAAI;AAC3C,QAAM,gBAAgBC,QAAO,IAAI;AACjC,QAAM,WAAWA,QAAO,WAAW;AAEnC,YAAU,MAAM;AACd,mBAAe,YAAY;AAEzB,YAAM,eAAe,SAAS,YAAY;AAC1C,UAAI,cAAc,WAAW,cAAc;AACzC,mBAAW,IAAI;AAAA,MACjB;AACA,eAAS,UAAU;AAEnB,UAAI;AACF,cAAM,WAAW,MAAM,MAAM,yBAAyB,mBAAmB,WAAW,CAAC,EAAE;AACvF,YAAI,SAAS,IAAI;AACf,gBAAM,OAAO,MAAM,SAAS,KAAK;AACjC,mBAAS,KAAK,SAAS,CAAC,CAAC;AAAA,QAC3B;AAAA,MACF,SAAS,OAAO;AACd,gBAAQ,MAAM,yBAAyB,KAAK;AAAA,MAC9C;AACA,iBAAW,KAAK;AAChB,oBAAc,UAAU;AAAA,IAC1B;AACA,cAAU;AAAA,EACZ,GAAG,CAAC,aAAa,UAAU,CAAC;AAE5B,MAAI,SAAS;AACX,WACE,gBAAAP,KAAC,SAAI,KAAKI,QAAO,SACf,0BAAAJ,KAAC,SAAI,KAAKI,QAAO,SAAS,GAC5B;AAAA,EAEJ;AAEA,QAAM,WAAW,gBAAgB;AAGjC,MAAI,MAAM,WAAW,KAAK,UAAU;AAClC,WACE,gBAAAH,MAAC,SAAI,KAAKG,QAAO,OACf;AAAA,sBAAAJ,KAAC,SAAI,KAAKI,QAAO,WAAW,MAAK,QAAO,QAAO,gBAAe,SAAQ,aACpE,0BAAAJ,KAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,KAAK,GAAE,6JAA4J,GACrO;AAAA,MACA,gBAAAA,KAAC,OAAE,KAAKI,QAAO,WAAW,qCAAuB;AAAA,MACjD,gBAAAJ,KAAC,OAAE,KAAKI,QAAO,WAAW,0CAA4B;AAAA,OACxD;AAAA,EAEJ;AAEA,QAAM,cAAc,CAAC,GAAG,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM;AAC5C,QAAI,EAAE,SAAS,YAAY,EAAE,SAAS,SAAU,QAAO;AACvD,QAAI,EAAE,SAAS,YAAY,EAAE,SAAS,SAAU,QAAO;AACvD,WAAO,EAAE,KAAK,cAAc,EAAE,IAAI;AAAA,EACpC,CAAC;AAED,QAAM,kBAAkB,CAAC,MAAgB,MAAwB;AAC/D,QAAI,EAAE,YAAY,kBAAkB;AAClC,kBAAY,kBAAkB,KAAK,MAAM,WAAW;AAAA,IACtD,OAAO;AACL,sBAAgB,KAAK,IAAI;AAAA,IAC3B;AAAA,EACF;AAEA,QAAM,aAAa,CAAC,SAAmB;AACrC,QAAI,KAAK,SAAS,UAAU;AAC1B,qBAAe,KAAK,IAAI;AAAA,IAC1B,OAAO;AACL,qBAAe,IAAI;AAAA,IACrB;AAAA,EACF;AAEA,QAAM,mBAAmB,YAAY,SAAS,KAAK,YAAY,MAAM,UAAQ,cAAc,IAAI,KAAK,IAAI,CAAC;AACzG,QAAM,oBAAoB,YAAY,KAAK,UAAQ,cAAc,IAAI,KAAK,IAAI,CAAC;AAE/E,QAAM,kBAAkB,MAAM;AAC5B,QAAI,kBAAkB;AACpB,qBAAe;AAAA,IACjB,OAAO;AACL,gBAAU,WAAW;AAAA,IACvB;AAAA,EACF;AAEA,SACE,gBAAAH,MAAC,SACE;AAAA,gBAAY,SAAS,KACpB,gBAAAD,KAAC,SAAI,KAAKI,QAAO,cACf,0BAAAH,MAAC,WAAM,KAAKG,QAAO,gBACjB;AAAA,sBAAAJ;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,KAAKI,QAAO;AAAA,UACZ,SAAS;AAAA,UACT,KAAK,CAAC,OAAO;AACX,gBAAI,GAAI,IAAG,gBAAgB,qBAAqB,CAAC;AAAA,UACnD;AAAA,UACA,UAAU;AAAA;AAAA,MACZ;AAAA,MAAE;AAAA,MACW,YAAY;AAAA,MAAO;AAAA,OAClC,GACF;AAAA,IAEF,gBAAAH,MAAC,SAAI,KAAKG,QAAO,MAEd;AAAA,OAAC,YACA,gBAAAH;AAAA,QAAC;AAAA;AAAA,UACC,KAAK,CAACG,QAAO,MAAMA,QAAO,UAAU;AAAA,UACpC,SAAS;AAAA,UAET;AAAA,4BAAAJ,KAAC,SAAI,KAAKI,QAAO,SACf,0BAAAJ,KAAC,SAAI,KAAKI,QAAO,YAAY,MAAK,QAAO,QAAO,gBAAe,SAAQ,aACrE,0BAAAJ,KAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,KAAK,GAAE,4CAA2C,GACpH,GACF;AAAA,YACA,gBAAAC,MAAC,SAAI,KAAKG,QAAO,OACf;AAAA,8BAAAJ,KAAC,OAAE,KAAKI,QAAO,MAAM,gBAAE;AAAA,cACvB,gBAAAJ,KAAC,OAAE,KAAKI,QAAO,MAAM,2BAAa;AAAA,eACpC;AAAA;AAAA;AAAA,MACF;AAAA,MAGD,YAAY,IAAI,CAAC,SAChB,gBAAAJ;AAAA,QAAC;AAAA;AAAA,UAEC;AAAA,UACA,YAAY,cAAc,IAAI,KAAK,IAAI;AAAA,UACvC,SAAS,CAAC,MAAM,gBAAgB,MAAM,CAAC;AAAA,UACvC,QAAQ,MAAM,WAAW,IAAI;AAAA;AAAA,QAJxB,KAAK;AAAA,MAKZ,CACD;AAAA,OACH;AAAA,KACF;AAEJ;AASA,SAAS,SAAS,EAAE,MAAM,YAAY,SAAS,OAAO,GAAkB;AACtE,QAAM,WAAW,KAAK,SAAS;AAE/B,SACE,gBAAAC;AAAA,IAAC;AAAA;AAAA,MACC,KAAK,CAACG,QAAO,MAAM,cAAcA,QAAO,YAAY;AAAA,MACpD;AAAA,MAEA;AAAA,wBAAAJ;AAAA,UAAC;AAAA;AAAA,YACC,KAAKI,QAAO;AAAA,YACZ,SAAS,CAAC,MAAM,EAAE,gBAAgB;AAAA,YAElC,0BAAAJ;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,KAAKI,QAAO;AAAA,gBACZ,SAAS;AAAA,gBACT,UAAU,MAAM,QAAQ,CAAC,CAAqB;AAAA;AAAA,YAChD;AAAA;AAAA,QACF;AAAA,QAEC,KAAK,aAAa,gBAAAJ,KAAC,UAAK,KAAKI,QAAO,UAAU,iBAAG;AAAA,QAElD,gBAAAJ,KAAC,SAAI,KAAKI,QAAO,SACd,qBACC,gBAAAJ,KAAC,SAAI,KAAKI,QAAO,YAAY,MAAK,gBAAe,SAAQ,aACvD,0BAAAJ,KAAC,UAAK,GAAE,8EAA6E,GACvF,IACE,KAAK,YACP,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,KAAKI,QAAO;AAAA,YACZ,KAAK,KAAK;AAAA,YACV,KAAK,KAAK;AAAA,YACV,SAAQ;AAAA;AAAA,QACV,IAEA,gBAAAJ,KAAC,SAAI,KAAKI,QAAO,UAAU,MAAK,QAAO,QAAO,gBAAe,SAAQ,aACnE,0BAAAJ,KAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,KAAK,GAAE,8GAA6G,GACtL,GAEJ;AAAA,QAEA,gBAAAA,KAAC,SAAI,KAAKI,QAAO,OACf,0BAAAH,MAAC,SAAI,KAAKG,QAAO,UACf;AAAA,0BAAAH,MAAC,SAAI,KAAKG,QAAO,WACf;AAAA,4BAAAJ,KAAC,OAAE,KAAKI,QAAO,MAAM,OAAO,KAAK,MAAO,yBAAe,KAAK,IAAI,GAAE;AAAA,YACjE,WACC,gBAAAH,MAAC,OAAE,KAAKG,QAAO,MACZ;AAAA,mBAAK,cAAc,SAAY,GAAG,KAAK,SAAS,WAAW;AAAA,cAC3D,KAAK,cAAc,UAAa,KAAK,cAAc,SAAY,WAAQ;AAAA,cACvE,KAAK,cAAc,SAAY,eAAe,KAAK,SAAS,IAAI;AAAA,eACnE,IAEA,KAAK,SAAS,UAAa,gBAAAJ,KAAC,OAAE,KAAKI,QAAO,MAAO,yBAAe,KAAK,IAAI,GAAE;AAAA,aAE/E;AAAA,UACA,gBAAAJ;AAAA,YAAC;AAAA;AAAA,cACC,KAAKI,QAAO;AAAA,cACZ,SAAS,CAAC,MAAM;AACd,kBAAE,gBAAgB;AAClB,uBAAO;AAAA,cACT;AAAA,cACD;AAAA;AAAA,UAED;AAAA,WACF,GACF;AAAA;AAAA;AAAA,EACF;AAEJ;AAEA,SAAS,eAAe,OAAuB;AAC7C,MAAI,QAAQ,KAAM,QAAO,GAAG,KAAK;AACjC,MAAI,QAAQ,OAAO,KAAM,QAAO,IAAI,QAAQ,MAAM,QAAQ,CAAC,CAAC;AAC5D,SAAO,IAAI,SAAS,OAAO,OAAO,QAAQ,CAAC,CAAC;AAC9C;AAEA,SAAS,eAAe,KAAa,YAAoB,IAAY;AACnE,MAAI,IAAI,UAAU,UAAW,QAAO;AAGpC,QAAM,UAAU,IAAI,YAAY,GAAG;AACnC,QAAM,MAAM,UAAU,IAAI,IAAI,UAAU,OAAO,IAAI;AACnD,QAAM,OAAO,UAAU,IAAI,IAAI,UAAU,GAAG,OAAO,IAAI;AAGvD,QAAM,kBAAkB,YAAY,IAAI,SAAS;AACjD,MAAI,kBAAkB,GAAG;AAEvB,WAAO,IAAI,UAAU,GAAG,YAAY,CAAC,IAAI;AAAA,EAC3C;AAEA,QAAM,cAAc,KAAK,KAAK,kBAAkB,CAAC;AACjD,QAAM,YAAY,KAAK,MAAM,kBAAkB,CAAC;AAEhD,SAAO,KAAK,UAAU,GAAG,WAAW,IAAI,QAAQ,KAAK,UAAU,KAAK,SAAS,SAAS,IAAI;AAC5F;;;AC/cA,SAAS,aAAAI,YAAW,YAAAC,WAAU,UAAAC,eAAc;AAC5C,SAAS,OAAAC,MAAK,aAAAC,kBAAiB;AA2NvB,gBAAAC,MAoDE,QAAAC,aApDF;AAtNR,IAAMC,QAAOC;AAAA;AAAA;AAIb,IAAMC,UAAS;AAAA,EACb,SAASC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMT,SAASA;AAAA;AAAA;AAAA;AAAA,wBAIa,OAAO,MAAM;AAAA,wBACb,OAAO,OAAO;AAAA,iBACrBH,KAAI;AAAA;AAAA,EAEnB,OAAOG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,aAMI,OAAO,aAAa;AAAA;AAAA,EAE/B,cAAcA;AAAA,kBACE,OAAO,OAAO;AAAA;AAAA,wBAER,OAAO,MAAM;AAAA;AAAA;AAAA,EAGnC,OAAOA;AAAA;AAAA;AAAA;AAAA,EAIP,IAAIA;AAAA;AAAA;AAAA,aAGO,OAAO,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA,kBAKX,OAAO,UAAU;AAAA,+BACJ,OAAO,MAAM;AAAA;AAAA,EAE1C,YAAYA;AAAA;AAAA;AAAA,EAGZ,QAAQA;AAAA;AAAA;AAAA,EAGR,cAAcA;AAAA;AAAA;AAAA,EAGd,OAAOA;AAAA;AAAA;AAAA,EAGP,OAAOA;AAAA,EACP,KAAKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAMmB,OAAO,YAAY;AAAA;AAAA;AAAA;AAAA,iCAIZ,OAAO,WAAW;AAAA;AAAA;AAAA,EAGjD,aAAaA;AAAA,wBACS,OAAO,YAAY;AAAA;AAAA;AAAA,0BAGjB,OAAO,YAAY;AAAA;AAAA;AAAA,EAG3C,WAAWA;AAAA;AAAA;AAAA;AAAA,0BAIa,OAAO,YAAY;AAAA;AAAA;AAAA,EAG3C,IAAIA;AAAA;AAAA;AAAA,EAGJ,cAAcA;AAAA;AAAA;AAAA;AAAA,EAId,UAAUA;AAAA;AAAA;AAAA,oBAGQ,OAAO,OAAO;AAAA;AAAA;AAAA,EAGhC,UAAUA;AAAA;AAAA;AAAA;AAAA;AAAA,EAKV,YAAYA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMZ,YAAYA;AAAA;AAAA;AAAA,aAGD,OAAO,SAAS;AAAA;AAAA;AAAA,EAG3B,UAAUA;AAAA;AAAA;AAAA,aAGC,OAAO,SAAS;AAAA;AAAA;AAAA,EAG3B,WAAWA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAMW,OAAO,WAAW;AAAA;AAAA,EAExC,MAAMA;AAAA,iBACS,SAAS,IAAI;AAAA;AAAA,aAEjB,OAAO,IAAI;AAAA;AAAA;AAAA,EAGtB,MAAMA;AAAA,iBACS,SAAS,EAAE;AAAA,aACf,OAAO,aAAa;AAAA;AAAA,EAE/B,UAAUA;AAAA;AAAA;AAAA;AAAA,iBAIK,SAAS,EAAE;AAAA;AAAA,aAEf,OAAO,OAAO;AAAA;AAAA,EAEzB,SAASA;AAAA;AAAA;AAAA;AAAA,EAIT,UAAUA;AAAA,iBACK,SAAS,EAAE;AAAA,aACf,OAAO,SAAS;AAAA;AAAA,EAE3B,SAASA;AAAA;AAAA,iBAEM,SAAS,EAAE;AAAA;AAAA,aAEf,OAAO,OAAO;AAAA,kBACT,OAAO,OAAO;AAAA,wBACR,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAUX,OAAO,YAAY;AAAA,sBACvB,OAAO,OAAO;AAAA;AAAA;AAGpC;AAEO,SAAS,iBAAiB;AAC/B,QAAM,EAAE,aAAa,gBAAgB,YAAY,eAAe,iBAAiB,aAAa,kBAAkB,WAAW,gBAAgB,YAAY,eAAe,IAAI,UAAU;AACpL,QAAM,CAAC,OAAO,QAAQ,IAAIC,UAAqB,CAAC,CAAC;AACjD,QAAM,CAAC,SAAS,UAAU,IAAIA,UAAS,IAAI;AAC3C,QAAM,gBAAgBC,QAAO,IAAI;AACjC,QAAM,WAAWA,QAAO,WAAW;AAEnC,EAAAC,WAAU,MAAM;AACd,mBAAe,YAAY;AAEzB,YAAM,eAAe,SAAS,YAAY;AAC1C,UAAI,cAAc,WAAW,cAAc;AACzC,mBAAW,IAAI;AAAA,MACjB;AACA,eAAS,UAAU;AAEnB,UAAI;AACF,cAAM,WAAW,MAAM,MAAM,yBAAyB,mBAAmB,WAAW,CAAC,EAAE;AACvF,YAAI,SAAS,IAAI;AACf,gBAAM,OAAO,MAAM,SAAS,KAAK;AACjC,mBAAS,KAAK,SAAS,CAAC,CAAC;AAAA,QAC3B;AAAA,MACF,SAAS,OAAO;AACd,gBAAQ,MAAM,yBAAyB,KAAK;AAAA,MAC9C;AACA,iBAAW,KAAK;AAChB,oBAAc,UAAU;AAAA,IAC1B;AACA,cAAU;AAAA,EACZ,GAAG,CAAC,aAAa,UAAU,CAAC;AAE5B,MAAI,SAAS;AACX,WACE,gBAAAR,KAAC,SAAI,KAAKI,QAAO,SACf,0BAAAJ,KAAC,SAAI,KAAKI,QAAO,SAAS,GAC5B;AAAA,EAEJ;AAEA,QAAM,WAAW,gBAAgB;AAEjC,MAAI,MAAM,WAAW,KAAK,UAAU;AAClC,WACE,gBAAAJ,KAAC,SAAI,KAAKI,QAAO,OACf,0BAAAJ,KAAC,OAAE,qCAAuB,GAC5B;AAAA,EAEJ;AAEA,QAAM,cAAc,CAAC,GAAG,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM;AAC5C,QAAI,EAAE,SAAS,YAAY,EAAE,SAAS,SAAU,QAAO;AACvD,QAAI,EAAE,SAAS,YAAY,EAAE,SAAS,SAAU,QAAO;AACvD,WAAO,EAAE,KAAK,cAAc,EAAE,IAAI;AAAA,EACpC,CAAC;AAED,QAAM,kBAAkB,CAAC,MAAgB,MAAwB;AAC/D,QAAI,EAAE,YAAY,kBAAkB;AAClC,kBAAY,kBAAkB,KAAK,MAAM,WAAW;AAAA,IACtD,OAAO;AACL,sBAAgB,KAAK,IAAI;AAAA,IAC3B;AAAA,EACF;AAEA,QAAM,aAAa,CAAC,SAAmB;AACrC,QAAI,KAAK,SAAS,UAAU;AAC1B,qBAAe,KAAK,IAAI;AAAA,IAC1B,OAAO;AACL,qBAAe,IAAI;AAAA,IACrB;AAAA,EACF;AAEA,QAAM,mBAAmB,YAAY,SAAS,KAAK,YAAY,MAAM,UAAQ,cAAc,IAAI,KAAK,IAAI,CAAC;AACzG,QAAM,oBAAoB,YAAY,KAAK,UAAQ,cAAc,IAAI,KAAK,IAAI,CAAC;AAE/E,QAAM,kBAAkB,MAAM;AAC5B,QAAI,kBAAkB;AACpB,qBAAe;AAAA,IACjB,OAAO;AACL,gBAAU,WAAW;AAAA,IACvB;AAAA,EACF;AAEA,SACE,gBAAAA,KAAC,SAAI,KAAKI,QAAO,cACf,0BAAAH,MAAC,WAAM,KAAKG,QAAO,OACjB;AAAA,oBAAAJ,KAAC,WACC,0BAAAC,MAAC,QACC;AAAA,sBAAAD,KAAC,QAAG,KAAK,CAACI,QAAO,IAAIA,QAAO,UAAU,GACnC,sBAAY,SAAS,KACpB,gBAAAJ;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,KAAKI,QAAO;AAAA,UACZ,SAAS;AAAA,UACT,KAAK,CAAC,OAAO;AACX,gBAAI,GAAI,IAAG,gBAAgB,qBAAqB,CAAC;AAAA,UACnD;AAAA,UACA,UAAU;AAAA;AAAA,MACZ,GAEJ;AAAA,MACA,gBAAAJ,KAAC,QAAG,KAAKI,QAAO,IAAI,kBAAI;AAAA,MACxB,gBAAAJ,KAAC,QAAG,KAAK,CAACI,QAAO,IAAIA,QAAO,MAAM,GAAG,kBAAI;AAAA,MACzC,gBAAAJ,KAAC,QAAG,KAAK,CAACI,QAAO,IAAIA,QAAO,YAAY,GAAG,wBAAU;AAAA,MACrD,gBAAAJ,KAAC,QAAG,KAAK,CAACI,QAAO,IAAIA,QAAO,KAAK,GAAG,iBAAG;AAAA,OACzC,GACF;AAAA,IACA,gBAAAH,MAAC,WAAM,KAAKG,QAAO,OAEhB;AAAA,OAAC,YACA,gBAAAH,MAAC,QAAG,KAAKG,QAAO,WAAW,SAAS,YAClC;AAAA,wBAAAJ,KAAC,QAAG,KAAKI,QAAO,IAAI;AAAA,QACpB,gBAAAJ,KAAC,QAAG,KAAKI,QAAO,IACd,0BAAAH,MAAC,SAAI,KAAKG,QAAO,UACf;AAAA,0BAAAJ,KAAC,SAAI,KAAKI,QAAO,YAAY,MAAK,QAAO,QAAO,gBAAe,SAAQ,aACrE,0BAAAJ,KAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,KAAK,GAAE,4CAA2C,GACpH;AAAA,UACA,gBAAAA,KAAC,UAAK,KAAKI,QAAO,MAAM,gBAAE;AAAA,WAC5B,GACF;AAAA,QACA,gBAAAJ,KAAC,QAAG,KAAK,CAACI,QAAO,IAAIA,QAAO,IAAI,GAAG,gBAAE;AAAA,QACrC,gBAAAJ,KAAC,QAAG,KAAK,CAACI,QAAO,IAAIA,QAAO,IAAI,GAAG,2BAAa;AAAA,QAChD,gBAAAJ,KAAC,QAAG,KAAKI,QAAO,IAAI,gBAAE;AAAA,SACxB;AAAA,MAGD,YAAY,IAAI,CAAC,SAChB,gBAAAJ;AAAA,QAAC;AAAA;AAAA,UAEC;AAAA,UACA,YAAY,cAAc,IAAI,KAAK,IAAI;AAAA,UACvC,SAAS,CAAC,MAAM,gBAAgB,MAAM,CAAC;AAAA,UACvC,QAAQ,MAAM,WAAW,IAAI;AAAA;AAAA,QAJxB,KAAK;AAAA,MAKZ,CACD;AAAA,OACH;AAAA,KACF,GACF;AAEJ;AASA,SAAS,QAAQ,EAAE,MAAM,YAAY,SAAS,OAAO,GAAiB;AACpE,QAAM,WAAW,KAAK,SAAS;AAE/B,SACE,gBAAAC;AAAA,IAAC;AAAA;AAAA,MACC,KAAK,CAACG,QAAO,KAAK,cAAcA,QAAO,WAAW;AAAA,MAClD;AAAA,MAEA;AAAA,wBAAAJ;AAAA,UAAC;AAAA;AAAA,YACC,KAAK,CAACI,QAAO,IAAIA,QAAO,YAAY;AAAA,YACpC,SAAS,CAAC,MAAM,EAAE,gBAAgB;AAAA,YAElC,0BAAAJ;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,KAAKI,QAAO;AAAA,gBACZ,SAAS;AAAA,gBACT,UAAU,MAAM,QAAQ,CAAC,CAAqB;AAAA;AAAA,YAChD;AAAA;AAAA,QACF;AAAA,QACA,gBAAAJ,KAAC,QAAG,KAAKI,QAAO,IACd,0BAAAH,MAAC,SAAI,KAAKG,QAAO,UACd;AAAA,qBACC,gBAAAJ,KAAC,SAAI,KAAKI,QAAO,YAAY,MAAK,gBAAe,SAAQ,aACvD,0BAAAJ,KAAC,UAAK,GAAE,8EAA6E,GACvF,IACE,KAAK,YACP,gBAAAA,KAAC,SAAI,KAAKI,QAAO,WAAW,KAAK,KAAK,WAAW,KAAK,KAAK,MAAM,SAAQ,QAAO,IAEhF,gBAAAJ,KAAC,SAAI,KAAKI,QAAO,UAAU,MAAK,QAAO,QAAO,gBAAe,SAAQ,aACnE,0BAAAJ,KAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,KAAK,GAAE,8GAA6G,GACtL;AAAA,UAEF,gBAAAA,KAAC,UAAK,KAAKI,QAAO,MAAM,OAAO,KAAK,MAAO,UAAAK,gBAAe,KAAK,IAAI,GAAE;AAAA,UACrE,gBAAAT;AAAA,YAAC;AAAA;AAAA,cACC,KAAKI,QAAO;AAAA,cACZ,SAAS,CAAC,MAAM;AACd,kBAAE,gBAAgB;AAClB,uBAAO;AAAA,cACT;AAAA,cACD;AAAA;AAAA,UAED;AAAA,WACF,GACF;AAAA,QACA,gBAAAJ,KAAC,QAAG,KAAK,CAACI,QAAO,IAAIA,QAAO,IAAI,GAC7B,qBACI,KAAK,cAAc,SAAY,GAAG,KAAK,SAAS,WAAW,OAC3D,KAAK,SAAS,SAAYM,gBAAe,KAAK,IAAI,IAAI,MAE7D;AAAA,QACA,gBAAAV,KAAC,QAAG,KAAK,CAACI,QAAO,IAAIA,QAAO,IAAI,GAC7B,qBACI,KAAK,cAAc,SAAYM,gBAAe,KAAK,SAAS,IAAI,OAChE,KAAK,aAAa,GAAG,KAAK,WAAW,KAAK,IAAI,KAAK,WAAW,MAAM,KAAK,MAEhF;AAAA,QACA,gBAAAV,KAAC,QAAG,KAAKI,QAAO,IACb,eAAK,YACJ,gBAAAH,MAAC,UAAK,KAAKG,QAAO,UAChB;AAAA,0BAAAJ,KAAC,SAAI,KAAKI,QAAO,SAAS,MAAK,gBAAe,SAAQ,aACpD,0BAAAJ,KAAC,UAAK,UAAS,WAAU,GAAE,sHAAqH,UAAS,WAAU,GACrK;AAAA,UAAM;AAAA,WAER,IAEA,gBAAAA,KAAC,UAAK,KAAKI,QAAO,UAAU,gBAAE,GAElC;AAAA;AAAA;AAAA,EACF;AAEJ;AAEA,SAASM,gBAAe,OAAuB;AAC7C,MAAI,QAAQ,KAAM,QAAO,GAAG,KAAK;AACjC,MAAI,QAAQ,OAAO,KAAM,QAAO,IAAI,QAAQ,MAAM,QAAQ,CAAC,CAAC;AAC5D,SAAO,IAAI,SAAS,OAAO,OAAO,QAAQ,CAAC,CAAC;AAC9C;AAEA,SAASD,gBAAe,KAAa,YAAoB,IAAY;AACnE,MAAI,IAAI,UAAU,UAAW,QAAO;AAGpC,QAAM,UAAU,IAAI,YAAY,GAAG;AACnC,QAAM,MAAM,UAAU,IAAI,IAAI,UAAU,OAAO,IAAI;AACnD,QAAM,OAAO,UAAU,IAAI,IAAI,UAAU,GAAG,OAAO,IAAI;AAGvD,QAAM,kBAAkB,YAAY,IAAI,SAAS;AACjD,MAAI,kBAAkB,GAAG;AAEvB,WAAO,IAAI,UAAU,GAAG,YAAY,CAAC,IAAI;AAAA,EAC3C;AAEA,QAAM,cAAc,KAAK,KAAK,kBAAkB,CAAC;AACjD,QAAM,YAAY,KAAK,MAAM,kBAAkB,CAAC;AAEhD,SAAO,KAAK,UAAU,GAAG,WAAW,IAAI,QAAQ,KAAK,UAAU,KAAK,SAAS,SAAS,IAAI;AAC5F;;;AC9aA,SAAS,YAAAE,iBAAgB;AACzB,SAAS,OAAAC,YAAW;AAsQP,SAgBT,YAAAC,WAhBS,OAAAC,MAMP,QAAAC,aANO;AAjQb,IAAM,mBAAmB,CAAC,QAAQ,SAAS,QAAQ,QAAQ,SAAS,QAAQ,QAAQ,QAAQ,SAAS,MAAM;AAC3G,IAAM,mBAAmB,CAAC,QAAQ,SAAS,QAAQ,QAAQ,QAAQ,MAAM;AAEzE,SAAS,YAAY,UAA2B;AAC9C,QAAM,MAAM,SAAS,YAAY,EAAE,UAAU,SAAS,YAAY,GAAG,CAAC;AACtE,SAAO,iBAAiB,SAAS,GAAG;AACtC;AAEA,SAAS,YAAY,UAA2B;AAC9C,QAAM,MAAM,SAAS,YAAY,EAAE,UAAU,SAAS,YAAY,GAAG,CAAC;AACtE,SAAO,iBAAiB,SAAS,GAAG;AACtC;AAEA,IAAMC,UAAS;AAAA,EACb,WAAWC;AAAA;AAAA;AAAA;AAAA;AAAA,EAKX,MAAMA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAQU,OAAO,UAAU;AAAA;AAAA;AAAA,EAGjC,cAAcA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAKE,OAAO,OAAO;AAAA,wBACR,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAWX,OAAO,YAAY;AAAA,sBACvB,OAAO,WAAW;AAAA;AAAA;AAAA,EAGtC,eAAeA;AAAA;AAAA;AAAA,aAGJ,OAAO,aAAa;AAAA;AAAA,EAE/B,cAAcA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOd,OAAOA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOP,OAAOA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMP,iBAAiBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAMD,OAAO,OAAO;AAAA;AAAA,wBAER,OAAO,MAAM;AAAA;AAAA,EAEnC,UAAUA;AAAA;AAAA;AAAA,aAGC,OAAO,SAAS;AAAA;AAAA;AAAA,EAG3B,UAAUA;AAAA,iBACK,SAAS,EAAE;AAAA;AAAA,aAEf,OAAO,IAAI;AAAA;AAAA;AAAA,EAGtB,SAASA;AAAA;AAAA,kBAEO,OAAO,OAAO;AAAA,6BACH,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,EAKxC,eAAeA;AAAA;AAAA,+BAEc,OAAO,MAAM;AAAA;AAAA,EAE1C,cAAcA;AAAA,iBACC,SAAS,IAAI;AAAA;AAAA,aAEjB,OAAO,IAAI;AAAA;AAAA;AAAA,EAGtB,gBAAgBA;AAAA;AAAA;AAAA;AAAA;AAAA,EAKhB,MAAMA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMN,SAASA;AAAA;AAAA;AAAA,iBAGM,SAAS,EAAE;AAAA;AAAA,EAE1B,WAAWA;AAAA,aACA,OAAO,aAAa;AAAA;AAAA,EAE/B,WAAWA;AAAA,aACA,OAAO,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQtB,eAAeA;AAAA,aACJ,OAAO,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOtB,SAASA;AAAA;AAAA;AAAA;AAAA;AAAA,EAKT,WAAWA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAMI,SAAS,IAAI;AAAA;AAAA,kBAEZ,OAAO,OAAO;AAAA,wBACR,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA,aAIxB,OAAO,IAAI;AAAA;AAAA;AAAA;AAAA,0BAIE,OAAO,YAAY;AAAA,sBACvB,OAAO,WAAW;AAAA;AAAA;AAAA,EAGtC,iBAAiBA;AAAA,aACN,OAAO,MAAM;AAAA;AAAA;AAAA,0BAGA,OAAO,WAAW;AAAA,sBACtB,OAAO,MAAM;AAAA;AAAA;AAAA,EAGjC,YAAYA;AAAA;AAAA;AAAA;AAAA;AAKd;AAEO,SAAS,mBAAmB;AACjC,QAAM,EAAE,aAAa,gBAAgB,gBAAgB,eAAe,IAAI,UAAU;AAClF,QAAM,CAAC,mBAAmB,oBAAoB,IAAIC,UAAS,KAAK;AAChE,QAAM,CAAC,cAAc,eAAe,IAAIA,UAAoD,IAAI;AAEhG,MAAI,CAAC,YAAa,QAAO;AAEzB,QAAM,UAAU,YAAY,YAAY,IAAI;AAC5C,QAAM,UAAU,YAAY,YAAY,IAAI;AAC5C,QAAM,WAAW,YAAY,KAAK,QAAQ,UAAU,EAAE;AAEtD,QAAM,cAAc,MAAM;AACxB,mBAAe,IAAI;AAAA,EACrB;AAEA,QAAM,eAAe,MAAM;AACzB,UAAM,UAAU,OAAO,mBAAmB,YAAY,IAAI;AAC1D,QAAI,WAAW,YAAY,YAAY,MAAM;AAC3C,cAAQ,IAAI,cAAc,OAAO;AAAA,IAEnC;AAAA,EACF;AAEA,QAAM,eAAe,YAAY;AAC/B,yBAAqB,KAAK;AAC1B,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,sBAAsB;AAAA,QACjD,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAC9C,MAAM,KAAK,UAAU,EAAE,OAAO,CAAC,YAAY,IAAI,EAAE,CAAC;AAAA,MACpD,CAAC;AAED,UAAI,SAAS,IAAI;AACf,uBAAe;AACf,uBAAe;AACf,uBAAe,IAAI;AAAA,MACrB,OAAO;AACL,cAAM,QAAQ,MAAM,SAAS,KAAK;AAClC,wBAAgB;AAAA,UACd,OAAO;AAAA,UACP,SAAS,MAAM,SAAS;AAAA,QAC1B,CAAC;AAAA,MACH;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,MAAM,iBAAiB,KAAK;AACpC,sBAAgB;AAAA,QACd,OAAO;AAAA,QACP,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AAAA,EACF;AAEA,QAAM,aAAa,MAAM;AACvB,YAAQ,IAAI,gBAAgB,YAAY,IAAI;AAAA,EAE9C;AAEA,QAAM,mBAAmB,MAAM;AAC7B,YAAQ,IAAI,eAAe,YAAY,IAAI;AAAA,EAE7C;AAEA,QAAM,cAAc,MAAM;AACxB,QAAI,SAAS;AACX,aAAO,gBAAAJ,KAAC,SAAI,KAAKE,QAAO,OAAO,KAAK,UAAU,KAAK,YAAY,MAAM;AAAA,IACvE;AACA,QAAI,SAAS;AACX,aAAO,gBAAAF,KAAC,WAAM,KAAKE,QAAO,OAAO,KAAK,UAAU,UAAQ,MAAC;AAAA,IAC3D;AACA,WACE,gBAAAD,MAAC,SAAI,KAAKC,QAAO,iBACf;AAAA,sBAAAF,KAAC,SAAI,KAAKE,QAAO,UAAU,MAAK,QAAO,QAAO,gBAAe,SAAQ,aACnE,0BAAAF,KAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,KAAK,GAAE,8GAA6G,GACtL;AAAA,MACA,gBAAAA,KAAC,OAAE,KAAKE,QAAO,UAAW,sBAAY,MAAK;AAAA,OAC7C;AAAA,EAEJ;AAEA,SACE,gBAAAD,MAAAF,WAAA,EACG;AAAA,yBACC,gBAAAC;AAAA,MAAC;AAAA;AAAA,QACC,OAAM;AAAA,QACN,SAAS,oCAAoC,YAAY,IAAI;AAAA,QAC7D,cAAa;AAAA,QACb,SAAQ;AAAA,QACR,WAAW;AAAA,QACX,UAAU,MAAM,qBAAqB,KAAK;AAAA;AAAA,IAC5C;AAAA,IAGD,gBACC,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,aAAa;AAAA,QACpB,SAAS,aAAa;AAAA,QACtB,SAAS,MAAM,gBAAgB,IAAI;AAAA;AAAA,IACrC;AAAA,IAGF,gBAAAC,MAAC,SAAI,KAAKC,QAAO,WACf;AAAA,sBAAAD,MAAC,SAAI,KAAKC,QAAO,MACf;AAAA,wBAAAF,KAAC,YAAO,KAAKE,QAAO,cAAc,SAAS,aAAa,cAAW,SACjE,0BAAAF,KAAC,SAAI,KAAKE,QAAO,eAAe,MAAK,QAAO,QAAO,gBAAe,SAAQ,aACxE,0BAAAF,KAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,wBAAuB,GAC9F,GACF;AAAA,QACA,gBAAAA,KAAC,SAAI,KAAKE,QAAO,cACd,sBAAY,GACf;AAAA,SACF;AAAA,MAEA,gBAAAD,MAAC,SAAI,KAAKC,QAAO,SACf;AAAA,wBAAAF,KAAC,SAAI,KAAKE,QAAO,eACf,0BAAAF,KAAC,QAAG,KAAKE,QAAO,cAAc,qBAAO,GACvC;AAAA,QAEA,gBAAAD,MAAC,SAAI,KAAKC,QAAO,gBACf;AAAA,0BAAAD,MAAC,SAAI,KAAKC,QAAO,MACf;AAAA,4BAAAD,MAAC,SAAI,KAAKC,QAAO,SACf;AAAA,8BAAAF,KAAC,UAAK,KAAKE,QAAO,WAAW,kBAAI;AAAA,cACjC,gBAAAF,KAAC,UAAK,KAAKE,QAAO,eAAgB,sBAAY,MAAK;AAAA,eACrD;AAAA,YACC,YAAY,SAAS,UACpB,gBAAAD,MAAC,SAAI,KAAKC,QAAO,SACf;AAAA,8BAAAF,KAAC,UAAK,KAAKE,QAAO,WAAW,kBAAI;AAAA,cACjC,gBAAAF,KAAC,UAAK,KAAKE,QAAO,WAAY,UAAAG,gBAAe,YAAY,IAAI,GAAE;AAAA,eACjE;AAAA,YAED,YAAY,cACX,gBAAAJ,MAAC,SAAI,KAAKC,QAAO,SACf;AAAA,8BAAAF,KAAC,UAAK,KAAKE,QAAO,WAAW,wBAAU;AAAA,cACvC,gBAAAD,MAAC,UAAK,KAAKC,QAAO,WAAY;AAAA,4BAAY,WAAW;AAAA,gBAAM;AAAA,gBAAI,YAAY,WAAW;AAAA,iBAAO;AAAA,eAC/F;AAAA,YAEF,gBAAAD,MAAC,SAAI,KAAKC,QAAO,SACf;AAAA,8BAAAF,KAAC,UAAK,KAAKE,QAAO,WAAW,wBAAU;AAAA,cACvC,gBAAAF,KAAC,UAAK,KAAKE,QAAO,WAAY,sBAAY,YAAY,WAAW,cAAa;AAAA,eAChF;AAAA,aACF;AAAA,UAEA,gBAAAD,MAAC,SAAI,KAAKC,QAAO,SACf;AAAA,4BAAAD,MAAC,YAAO,KAAKC,QAAO,WAAW,SAAS,cACtC;AAAA,8BAAAF,KAAC,SAAI,KAAKE,QAAO,YAAY,MAAK,QAAO,QAAO,gBAAe,SAAQ,aACrE,0BAAAF,KAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,0HAAyH,GAChM;AAAA,cAAM;AAAA,eAER;AAAA,YACA,gBAAAC,MAAC,YAAO,KAAKC,QAAO,WAAW,SAAS,YACtC;AAAA,8BAAAF,KAAC,SAAI,KAAKE,QAAO,YAAY,MAAK,QAAO,QAAO,gBAAe,SAAQ,aACrE,0BAAAF,KAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,yFAAwF,GAC/J;AAAA,cAAM;AAAA,eAER;AAAA,YACA,gBAAAC,MAAC,YAAO,KAAKC,QAAO,WAAW,SAAS,kBACtC;AAAA,8BAAAF,KAAC,SAAI,KAAKE,QAAO,YAAY,MAAK,QAAO,QAAO,gBAAe,SAAQ,aACrE,0BAAAF,KAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,+GAA8G,GACrL;AAAA,cAAM;AAAA,eAER;AAAA,YACA,gBAAAC,MAAC,YAAO,KAAK,CAACC,QAAO,WAAWA,QAAO,eAAe,GAAG,SAAS,MAAM,qBAAqB,IAAI,GAC/F;AAAA,8BAAAF,KAAC,SAAI,KAAKE,QAAO,YAAY,MAAK,QAAO,QAAO,gBAAe,SAAQ,aACrE,0BAAAF,KAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,gIAA+H,GACtM;AAAA,cAAM;AAAA,eAER;AAAA,aACF;AAAA,WACF;AAAA,SACF;AAAA,OACF;AAAA,KACF;AAEJ;AAEA,SAASK,gBAAe,OAAuB;AAC7C,MAAI,QAAQ,KAAM,QAAO,GAAG,KAAK;AACjC,MAAI,QAAQ,OAAO,KAAM,QAAO,IAAI,QAAQ,MAAM,QAAQ,CAAC,CAAC;AAC5D,SAAO,IAAI,SAAS,OAAO,OAAO,QAAQ,CAAC,CAAC;AAC9C;;;ACzXA,SAAS,YAAAC,iBAAgB;AACzB,SAAS,OAAAC,YAAW;AA+LhB,qBAAAC,WAYM,OAAAC,MAVF,QAAAC,aAFJ;AA3LJ,IAAMC,aAAY;AAElB,IAAMC,UAAS;AAAA,EACb,KAAKC;AAAA,cACOF,UAAS;AAAA;AAAA,kBAEL,OAAO,OAAO;AAAA,wBACR,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BASX,OAAO,YAAY;AAAA,sBACvB,OAAO,WAAW;AAAA;AAAA;AAAA,EAGtC,MAAME;AAAA;AAAA;AAAA,aAGK,OAAO,aAAa;AAAA;AAAA,EAE/B,SAASA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaT,OAAOA;AAAA,MACH,SAAS;AAAA;AAAA,wBAES,OAAO,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOpC,QAAQA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMR,OAAOA;AAAA,iBACQ,SAAS,EAAE;AAAA;AAAA,aAEf,OAAO,IAAI;AAAA;AAAA;AAAA;AAAA,EAItB,UAAUA;AAAA;AAAA,kBAEM,OAAO,OAAO;AAAA,wBACR,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BASX,OAAO,YAAY;AAAA,sBACvB,OAAO,WAAW;AAAA;AAAA;AAAA,EAGtC,UAAUA;AAAA;AAAA;AAAA;AAAA;AAAA,EAKV,cAAcA;AAAA,iBACC,SAAS,IAAI;AAAA;AAAA,aAEjB,OAAO,IAAI;AAAA;AAAA;AAAA,EAGtB,aAAaA;AAAA,iBACE,SAAS,EAAE;AAAA,aACf,OAAO,aAAa;AAAA;AAAA;AAAA,EAG/B,MAAMA;AAAA,wBACgB,OAAO,UAAU;AAAA;AAAA;AAAA;AAAA,iBAIxB,SAAS,EAAE;AAAA,aACf,OAAO,aAAa;AAAA,wBACT,OAAO,MAAM;AAAA;AAAA,EAEnC,UAAUA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOV,OAAOA;AAAA;AAAA;AAAA,wBAGe,OAAO,MAAM;AAAA;AAAA,iBAEpB,SAAS,IAAI;AAAA,aACjB,OAAO,IAAI;AAAA,kBACN,OAAO,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,sBAKV,OAAO,OAAO;AAAA,8BACN,OAAO,YAAY;AAAA;AAAA;AAAA;AAAA,eAIlC,OAAO,SAAS;AAAA;AAAA;AAAA,EAG7B,MAAMA;AAAA;AAAA;AAAA;AAAA;AAAA,EAKN,OAAOA;AAAA,iBACQ,SAAS,EAAE;AAAA;AAAA,aAEf,OAAO,aAAa;AAAA;AAAA;AAAA;AAAA,EAI/B,QAAQA;AAAA;AAAA;AAAA,4BAGkB,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,EAKvC,WAAWA;AAAA;AAAA,iBAEI,SAAS,IAAI;AAAA;AAAA,aAEjB,OAAO,IAAI;AAAA,kBACN,OAAO,OAAO;AAAA,wBACR,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAMX,OAAO,YAAY;AAAA,sBACvB,OAAO,WAAW;AAAA;AAAA;AAAA,EAGtC,SAASA;AAAA;AAAA,iBAEM,SAAS,IAAI;AAAA;AAAA;AAAA,wBAGN,OAAO,OAAO;AAAA,wBACd,OAAO,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAMZ,OAAO,YAAY;AAAA,sBACvB,OAAO,YAAY;AAAA;AAAA;AAGzC;AAEO,SAAS,iBAAiB;AAC/B,QAAM,CAAC,QAAQ,SAAS,IAAIC,UAAS,KAAK;AAE1C,SACE,gBAAAJ,MAAAF,WAAA,EACE;AAAA,oBAAAC,KAAC,YAAO,KAAKG,QAAO,KAAK,SAAS,MAAM,UAAU,IAAI,GAAG,cAAW,YAClE,0BAAAF;AAAA,MAAC;AAAA;AAAA,QACC,KAAKE,QAAO;AAAA,QACZ,OAAM;AAAA,QACN,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,QAAO;AAAA,QACP,aAAa;AAAA,QACb,eAAc;AAAA,QACd,gBAAe;AAAA,QAEf;AAAA,0BAAAH,KAAC,YAAO,IAAG,MAAK,IAAG,MAAK,GAAE,KAAI;AAAA,UAC9B,gBAAAA,KAAC,UAAK,GAAE,+qBAA8qB;AAAA;AAAA;AAAA,IACxrB,GACF;AAAA,IAEC,UAAU,gBAAAA,KAAC,iBAAc,SAAS,MAAM,UAAU,KAAK,GAAG;AAAA,KAC7D;AAEJ;AAEA,SAAS,cAAc,EAAE,QAAQ,GAA4B;AAC3D,SACE,gBAAAA,KAAC,SAAI,KAAKG,QAAO,SAAS,SAAS,SACjC,0BAAAF,MAAC,SAAI,KAAKE,QAAO,OAAO,SAAS,CAAC,MAAM,EAAE,gBAAgB,GACxD;AAAA,oBAAAF,MAAC,SAAI,KAAKE,QAAO,QACf;AAAA,sBAAAH,KAAC,QAAG,KAAKG,QAAO,OAAO,sBAAQ;AAAA,MAC/B,gBAAAH,KAAC,YAAO,KAAKG,QAAO,UAAU,SAAS,SACrC,0BAAAH,KAAC,SAAI,KAAKG,QAAO,MAAM,MAAK,QAAO,QAAO,gBAAe,SAAQ,aAC/D,0BAAAH,KAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,wBAAuB,GAC9F,GACF;AAAA,OACF;AAAA,IAEA,gBAAAC,MAAC,SAAI,KAAKE,QAAO,UACf;AAAA,sBAAAF,MAAC,aACC;AAAA,wBAAAD,KAAC,QAAG,KAAKG,QAAO,cAAc,2BAAa;AAAA,QAC3C,gBAAAH,KAAC,OAAE,KAAKG,QAAO,aAAa,2CAA6B;AAAA,QACzD,gBAAAF,MAAC,SAAI,KAAKE,QAAO,MACf;AAAA,0BAAAH,KAAC,OAAE,KAAKG,QAAO,UAAU,sCAAwB;AAAA,UACjD,gBAAAH,KAAC,OAAE,KAAKG,QAAO,UAAU,yCAA2B;AAAA,UACpD,gBAAAH,KAAC,OAAE,KAAKG,QAAO,UAAU,6CAA+B;AAAA,UACxD,gBAAAH,KAAC,OAAE,KAAKG,QAAO,UAAU,uCAAyB;AAAA,UAClD,gBAAAH,KAAC,OAAE,KAAKG,QAAO,UAAU,sCAAwB;AAAA,WACnD;AAAA,SACF;AAAA,MAEA,gBAAAF,MAAC,aACC;AAAA,wBAAAD,KAAC,QAAG,KAAKG,QAAO,cAAc,4BAAc;AAAA,QAC5C,gBAAAH,KAAC,OAAE,KAAKG,QAAO,aAAa,+DAAiD;AAAA,QAC7E,gBAAAH,KAAC,WAAM,KAAKG,QAAO,OAAO,MAAK,QAAO,aAAY,8BAA6B;AAAA,SACjF;AAAA,MAEA,gBAAAF,MAAC,aACC;AAAA,wBAAAD,KAAC,QAAG,KAAKG,QAAO,cAAc,6BAAe;AAAA,QAC7C,gBAAAF,MAAC,SAAI,KAAKE,QAAO,MACf;AAAA,0BAAAF,MAAC,SACC;AAAA,4BAAAD,KAAC,WAAM,KAAKG,QAAO,OAAO,mBAAK;AAAA,YAC/B,gBAAAH,KAAC,WAAM,KAAKG,QAAO,OAAO,MAAK,UAAS,cAAc,KAAK;AAAA,aAC7D;AAAA,UACA,gBAAAF,MAAC,SACC;AAAA,4BAAAD,KAAC,WAAM,KAAKG,QAAO,OAAO,oBAAM;AAAA,YAChC,gBAAAH,KAAC,WAAM,KAAKG,QAAO,OAAO,MAAK,UAAS,cAAc,KAAK;AAAA,aAC7D;AAAA,UACA,gBAAAF,MAAC,SACC;AAAA,4BAAAD,KAAC,WAAM,KAAKG,QAAO,OAAO,mBAAK;AAAA,YAC/B,gBAAAH,KAAC,WAAM,KAAKG,QAAO,OAAO,MAAK,UAAS,cAAc,MAAM;AAAA,aAC9D;AAAA,WACF;AAAA,SACF;AAAA,OACF;AAAA,IAEA,gBAAAF,MAAC,SAAI,KAAKE,QAAO,QACf;AAAA,sBAAAH,KAAC,YAAO,KAAKG,QAAO,WAAW,SAAS,SAAS,oBAAM;AAAA,MACvD,gBAAAH,KAAC,YAAO,KAAKG,QAAO,SAAS,0BAAY;AAAA,OAC3C;AAAA,KACF,GACF;AAEJ;;;APhEU,gBAAAG,MACA,QAAAC,aADA;AA/LV,IAAMC,aAAY;AAElB,IAAMC,UAAS;AAAA,EACb,WAAWC;AAAA,MACP,SAAS;AAAA;AAAA;AAAA;AAAA,kBAIG,OAAO,UAAU;AAAA;AAAA,EAEjC,QAAQA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAKQ,OAAO,OAAO;AAAA,+BACD,OAAO,MAAM;AAAA;AAAA,EAE1C,OAAOA;AAAA,iBACQ,SAAS,EAAE;AAAA;AAAA,aAEf,OAAO,IAAI;AAAA;AAAA;AAAA;AAAA,EAItB,eAAeA;AAAA;AAAA;AAAA;AAAA;AAAA,EAKf,WAAWA;AAAA,cACCF,UAAS;AAAA;AAAA,kBAEL,OAAO,OAAO;AAAA,wBACR,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BASX,OAAO,YAAY;AAAA,sBACvB,OAAO,WAAW;AAAA;AAAA;AAAA,EAGtC,YAAYE;AAAA;AAAA;AAAA,aAGD,OAAO,aAAa;AAAA;AAAA,EAE/B,SAASA;AAAA;AAAA;AAAA;AAAA;AAAA,EAKT,aAAaA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMf;AAMO,SAAS,SAAS,EAAE,SAAS,YAAY,KAAK,GAAkB;AACrE,QAAM,CAAC,aAAa,sBAAsB,IAAIC,UAAS,QAAQ;AAC/D,QAAM,CAAC,eAAe,gBAAgB,IAAIA,UAAsB,oBAAI,IAAI,CAAC;AACzE,QAAM,CAAC,kBAAkB,mBAAmB,IAAIA,UAAwB,IAAI;AAC5E,QAAM,CAAC,UAAU,WAAW,IAAIA,UAA0B,MAAM;AAChE,QAAM,CAAC,aAAa,cAAc,IAAIA,UAA0B,IAAI;AACpE,QAAM,CAAC,MAAM,OAAO,IAAIA,UAA4B,IAAI;AACxD,QAAM,CAAC,WAAW,YAAY,IAAIA,UAAS,KAAK;AAChD,QAAM,CAAC,YAAY,aAAa,IAAIA,UAAS,CAAC;AAE9C,QAAM,iBAAiBC,aAAY,MAAM;AACvC,kBAAc,CAAC,MAAM,IAAI,CAAC;AAAA,EAC5B,GAAG,CAAC,CAAC;AAEL,QAAM,aAAaA,aAAY,MAAM;AACnC,QAAI,gBAAgB,SAAU;AAC9B,UAAM,QAAQ,YAAY,MAAM,GAAG;AACnC,UAAM,IAAI;AACV,2BAAuB,MAAM,KAAK,GAAG,KAAK,QAAQ;AAClD,qBAAiB,oBAAI,IAAI,CAAC;AAAA,EAC5B,GAAG,CAAC,WAAW,CAAC;AAEhB,QAAM,iBAAiBA,aAAY,CAAC,SAAiB;AACnD,2BAAuB,IAAI;AAC3B,qBAAiB,oBAAI,IAAI,CAAC;AAC1B,mBAAe,IAAI;AAAA,EACrB,GAAG,CAAC,CAAC;AAEL,QAAM,kBAAkBA,aAAY,CAAC,SAAiB;AACpD,qBAAiB,CAAC,SAAS;AACzB,YAAM,OAAO,IAAI,IAAI,IAAI;AACzB,UAAI,KAAK,IAAI,IAAI,GAAG;AAClB,aAAK,OAAO,IAAI;AAAA,MAClB,OAAO;AACL,aAAK,IAAI,IAAI;AAAA,MACf;AACA,aAAO;AAAA,IACT,CAAC;AACD,wBAAoB,IAAI;AAAA,EAC1B,GAAG,CAAC,CAAC;AAEL,QAAM,cAAcA,aAAY,CAAC,UAAkB,QAAgB,aAAyB;AAC1F,UAAM,YAAY,SAAS,UAAU,UAAQ,KAAK,SAAS,QAAQ;AACnE,UAAM,UAAU,SAAS,UAAU,UAAQ,KAAK,SAAS,MAAM;AAE/D,QAAI,cAAc,MAAM,YAAY,GAAI;AAExC,UAAM,QAAQ,KAAK,IAAI,WAAW,OAAO;AACzC,UAAM,MAAM,KAAK,IAAI,WAAW,OAAO;AAEvC,qBAAiB,CAAC,SAAS;AACzB,YAAM,OAAO,IAAI,IAAI,IAAI;AACzB,eAAS,IAAI,OAAO,KAAK,KAAK,KAAK;AACjC,aAAK,IAAI,SAAS,CAAC,EAAE,IAAI;AAAA,MAC3B;AACA,aAAO;AAAA,IACT,CAAC;AACD,wBAAoB,MAAM;AAAA,EAC5B,GAAG,CAAC,CAAC;AAEL,QAAM,YAAYA,aAAY,CAAC,UAAsB;AACnD,qBAAiB,IAAI,IAAI,MAAM,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC;AAAA,EAC1D,GAAG,CAAC,CAAC;AAEL,QAAM,iBAAiBA,aAAY,MAAM;AACvC,qBAAiB,oBAAI,IAAI,CAAC;AAAA,EAC5B,GAAG,CAAC,CAAC;AAEL,QAAM,gBAAgBA;AAAA,IACpB,CAAC,MAAqB;AACpB,UAAI,EAAE,QAAQ,UAAU;AACtB,YAAI,aAAa;AACf,yBAAe,IAAI;AAAA,QACrB,OAAO;AACL,kBAAQ;AAAA,QACV;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,SAAS,WAAW;AAAA,EACvB;AAEA,EAAAC,WAAU,MAAM;AACd,QAAI,WAAW;AACb,eAAS,iBAAiB,WAAW,aAAa;AAClD,eAAS,KAAK,MAAM,WAAW;AAAA,IACjC;AACA,WAAO,MAAM;AACX,eAAS,oBAAoB,WAAW,aAAa;AACrD,eAAS,KAAK,MAAM,WAAW;AAAA,IACjC;AAAA,EACF,GAAG,CAAC,eAAe,SAAS,CAAC;AAE7B,QAAM,eAAe;AAAA,IACnB,QAAQ;AAAA,IACR,YAAY,MAAM;AAAA,IAAC;AAAA,IACnB,aAAa;AAAA,IACb,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SACE,gBAAAP,KAAC,cAAc,UAAd,EAAuB,OAAO,cAC7B,0BAAAC,MAAC,SAAI,KAAKE,QAAO,WACf;AAAA,oBAAAF,MAAC,SAAI,KAAKE,QAAO,QACf;AAAA,sBAAAH,KAAC,QAAG,KAAKG,QAAO,OAAO,oBAAM;AAAA,MAC7B,gBAAAF,MAAC,SAAI,KAAKE,QAAO,eACf;AAAA,wBAAAH,KAAC,kBAAe;AAAA,QAChB,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,KAAKG,QAAO;AAAA,YACZ,SAAS;AAAA,YACT,cAAW;AAAA,YAEX,0BAAAH,KAAC,aAAU;AAAA;AAAA,QACb;AAAA,SACF;AAAA,OACF;AAAA,IAEA,gBAAAA,KAAC,iBAAc;AAAA,IAEf,gBAAAA,KAAC,SAAI,KAAKG,QAAO,SACd,wBACC,gBAAAH,KAAC,oBAAiB,IAElB,gBAAAA,KAAC,SAAI,KAAKG,QAAO,aACd,uBAAa,SAAS,gBAAAH,KAAC,kBAAe,IAAK,gBAAAA,KAAC,kBAAe,GAC9D,GAEJ;AAAA,KACF,GACF;AAEJ;AAEA,SAAS,YAAY;AACnB,SACE,gBAAAC;AAAA,IAAC;AAAA;AAAA,MACC,KAAKE,QAAO;AAAA,MACZ,OAAM;AAAA,MACN,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,QAAO;AAAA,MACP,aAAa;AAAA,MACb,eAAc;AAAA,MACd,gBAAe;AAAA,MAEf;AAAA,wBAAAH,KAAC,UAAK,IAAG,MAAK,IAAG,KAAI,IAAG,KAAI,IAAG,MAAK;AAAA,QACpC,gBAAAA,KAAC,UAAK,IAAG,KAAI,IAAG,KAAI,IAAG,MAAK,IAAG,MAAK;AAAA;AAAA;AAAA,EACtC;AAEJ;AAEA,IAAO,mBAAQ;","names":["useEffect","useCallback","useState","css","css","keyframes","Fragment","jsx","jsxs","keyframes","styles","css","hasSelection","useState","useRef","css","keyframes","jsx","jsxs","spin","keyframes","styles","css","useState","useRef","useEffect","useState","useRef","css","keyframes","jsx","jsxs","spin","keyframes","styles","css","useState","useRef","useEffect","truncateMiddle","formatFileSize","useState","css","Fragment","jsx","jsxs","styles","css","useState","formatFileSize","useState","css","Fragment","jsx","jsxs","btnHeight","styles","css","useState","jsx","jsxs","btnHeight","styles","css","useState","useCallback","useEffect"]}
@@ -1173,9 +1173,15 @@ function StudioFileGrid() {
1173
1173
  const { currentPath, setCurrentPath, navigateUp, selectedItems, toggleSelection, selectRange, lastSelectedPath, selectAll, clearSelection, refreshKey, setFocusedItem } = useStudio();
1174
1174
  const [items, setItems] = _react.useState.call(void 0, []);
1175
1175
  const [loading, setLoading] = _react.useState.call(void 0, true);
1176
+ const isInitialLoad = _react.useRef.call(void 0, true);
1177
+ const lastPath = _react.useRef.call(void 0, currentPath);
1176
1178
  _react.useEffect.call(void 0, () => {
1177
1179
  async function loadItems() {
1178
- setLoading(true);
1180
+ const isPathChange = lastPath.current !== currentPath;
1181
+ if (isInitialLoad.current || isPathChange) {
1182
+ setLoading(true);
1183
+ }
1184
+ lastPath.current = currentPath;
1179
1185
  try {
1180
1186
  const response = await fetch(`/api/studio/list?path=${encodeURIComponent(currentPath)}`);
1181
1187
  if (response.ok) {
@@ -1186,6 +1192,7 @@ function StudioFileGrid() {
1186
1192
  console.error("Failed to load items:", error);
1187
1193
  }
1188
1194
  setLoading(false);
1195
+ isInitialLoad.current = false;
1189
1196
  }
1190
1197
  loadItems();
1191
1198
  }, [currentPath, refreshKey]);
@@ -1538,9 +1545,15 @@ function StudioFileList() {
1538
1545
  const { currentPath, setCurrentPath, navigateUp, selectedItems, toggleSelection, selectRange, lastSelectedPath, selectAll, clearSelection, refreshKey, setFocusedItem } = useStudio();
1539
1546
  const [items, setItems] = _react.useState.call(void 0, []);
1540
1547
  const [loading, setLoading] = _react.useState.call(void 0, true);
1548
+ const isInitialLoad = _react.useRef.call(void 0, true);
1549
+ const lastPath = _react.useRef.call(void 0, currentPath);
1541
1550
  _react.useEffect.call(void 0, () => {
1542
1551
  async function loadItems() {
1543
- setLoading(true);
1552
+ const isPathChange = lastPath.current !== currentPath;
1553
+ if (isInitialLoad.current || isPathChange) {
1554
+ setLoading(true);
1555
+ }
1556
+ lastPath.current = currentPath;
1544
1557
  try {
1545
1558
  const response = await fetch(`/api/studio/list?path=${encodeURIComponent(currentPath)}`);
1546
1559
  if (response.ok) {
@@ -1551,6 +1564,7 @@ function StudioFileList() {
1551
1564
  console.error("Failed to load items:", error);
1552
1565
  }
1553
1566
  setLoading(false);
1567
+ isInitialLoad.current = false;
1554
1568
  }
1555
1569
  loadItems();
1556
1570
  }, [currentPath, refreshKey]);
@@ -2355,7 +2369,7 @@ var styles7 = {
2355
2369
  padding: 20px 24px;
2356
2370
  `
2357
2371
  };
2358
- function StudioUI({ onClose }) {
2372
+ function StudioUI({ onClose, isVisible = true }) {
2359
2373
  const [currentPath, setCurrentPathInternal] = _react.useState.call(void 0, "public");
2360
2374
  const [selectedItems, setSelectedItems] = _react.useState.call(void 0, /* @__PURE__ */ new Set());
2361
2375
  const [lastSelectedPath, setLastSelectedPath] = _react.useState.call(void 0, null);
@@ -2425,13 +2439,15 @@ function StudioUI({ onClose }) {
2425
2439
  [onClose, focusedItem]
2426
2440
  );
2427
2441
  _react.useEffect.call(void 0, () => {
2428
- document.addEventListener("keydown", handleKeyDown);
2429
- document.body.style.overflow = "hidden";
2442
+ if (isVisible) {
2443
+ document.addEventListener("keydown", handleKeyDown);
2444
+ document.body.style.overflow = "hidden";
2445
+ }
2430
2446
  return () => {
2431
2447
  document.removeEventListener("keydown", handleKeyDown);
2432
2448
  document.body.style.overflow = "";
2433
2449
  };
2434
- }, [handleKeyDown]);
2450
+ }, [handleKeyDown, isVisible]);
2435
2451
  const contextValue = {
2436
2452
  isOpen: true,
2437
2453
  openStudio: () => {
@@ -2502,4 +2518,4 @@ var StudioUI_default = StudioUI;
2502
2518
 
2503
2519
 
2504
2520
  exports.StudioUI = StudioUI; exports.default = StudioUI_default;
2505
- //# sourceMappingURL=StudioUI-2COJSQR5.js.map
2521
+ //# sourceMappingURL=StudioUI-YCICS4Z3.js.map