@teamflojo/floimg-studio-ui 0.4.0 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -8
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../node_modules/.pnpm/zustand@5.0.9_@types+react@18.3.27_immer@10.2.0_react@19.2.3_use-sync-external-store@1.6.0_react@19.2.3_/node_modules/zustand/esm/middleware.mjs","../src/api/client.ts","../src/api/sse.ts","../src/stores/settingsStore.ts","../src/stores/workflowStore.ts","../src/editor/nodeTypes.tsx","../src/editor/WorkflowEditor.tsx","../src/components/UploadGallery.tsx","../src/components/NodePalette.tsx","../src/components/NodeInspector.tsx","../src/utils/codeGenerator.ts","../src/components/ImportModal.tsx","../src/components/Toolbar.tsx","../src/components/Gallery.tsx","../../../../packages/floimg-templates/dist/templates/data-viz.js","../../../../packages/floimg-templates/dist/templates/ai-workflows.js","../../../../packages/floimg-templates/dist/templates/marketing.js","../../../../packages/floimg-templates/dist/templates/utilities.js","../../../../packages/floimg-templates/dist/index.js","../src/components/TemplateGallery.tsx","../src/components/WorkflowLibrary.tsx","../src/components/AISettings.tsx","../src/components/AIChat.tsx","../src/components/OutputInspector.tsx","../src/App.tsx"],"sourcesContent":["const reduxImpl = (reducer, initial) => (set, _get, api) => {\n api.dispatch = (action) => {\n set((state) => reducer(state, action), false, action);\n return action;\n };\n api.dispatchFromDevtools = true;\n return { dispatch: (...args) => api.dispatch(...args), ...initial };\n};\nconst redux = reduxImpl;\n\nconst trackedConnections = /* @__PURE__ */ new Map();\nconst getTrackedConnectionState = (name) => {\n const api = trackedConnections.get(name);\n if (!api) return {};\n return Object.fromEntries(\n Object.entries(api.stores).map(([key, api2]) => [key, api2.getState()])\n );\n};\nconst extractConnectionInformation = (store, extensionConnector, options) => {\n if (store === void 0) {\n return {\n type: \"untracked\",\n connection: extensionConnector.connect(options)\n };\n }\n const existingConnection = trackedConnections.get(options.name);\n if (existingConnection) {\n return { type: \"tracked\", store, ...existingConnection };\n }\n const newConnection = {\n connection: extensionConnector.connect(options),\n stores: {}\n };\n trackedConnections.set(options.name, newConnection);\n return { type: \"tracked\", store, ...newConnection };\n};\nconst removeStoreFromTrackedConnections = (name, store) => {\n if (store === void 0) return;\n const connectionInfo = trackedConnections.get(name);\n if (!connectionInfo) return;\n delete connectionInfo.stores[store];\n if (Object.keys(connectionInfo.stores).length === 0) {\n trackedConnections.delete(name);\n }\n};\nconst findCallerName = (stack) => {\n var _a, _b;\n if (!stack) return void 0;\n const traceLines = stack.split(\"\\n\");\n const apiSetStateLineIndex = traceLines.findIndex(\n (traceLine) => traceLine.includes(\"api.setState\")\n );\n if (apiSetStateLineIndex < 0) return void 0;\n const callerLine = ((_a = traceLines[apiSetStateLineIndex + 1]) == null ? void 0 : _a.trim()) || \"\";\n return (_b = /.+ (.+) .+/.exec(callerLine)) == null ? void 0 : _b[1];\n};\nconst devtoolsImpl = (fn, devtoolsOptions = {}) => (set, get, api) => {\n const { enabled, anonymousActionType, store, ...options } = devtoolsOptions;\n let extensionConnector;\n try {\n extensionConnector = (enabled != null ? enabled : (import.meta.env ? import.meta.env.MODE : void 0) !== \"production\") && window.__REDUX_DEVTOOLS_EXTENSION__;\n } catch (e) {\n }\n if (!extensionConnector) {\n return fn(set, get, api);\n }\n const { connection, ...connectionInformation } = extractConnectionInformation(store, extensionConnector, options);\n let isRecording = true;\n api.setState = ((state, replace, nameOrAction) => {\n const r = set(state, replace);\n if (!isRecording) return r;\n const action = nameOrAction === void 0 ? {\n type: anonymousActionType || findCallerName(new Error().stack) || \"anonymous\"\n } : typeof nameOrAction === \"string\" ? { type: nameOrAction } : nameOrAction;\n if (store === void 0) {\n connection == null ? void 0 : connection.send(action, get());\n return r;\n }\n connection == null ? void 0 : connection.send(\n {\n ...action,\n type: `${store}/${action.type}`\n },\n {\n ...getTrackedConnectionState(options.name),\n [store]: api.getState()\n }\n );\n return r;\n });\n api.devtools = {\n cleanup: () => {\n if (connection && typeof connection.unsubscribe === \"function\") {\n connection.unsubscribe();\n }\n removeStoreFromTrackedConnections(options.name, store);\n }\n };\n const setStateFromDevtools = (...a) => {\n const originalIsRecording = isRecording;\n isRecording = false;\n set(...a);\n isRecording = originalIsRecording;\n };\n const initialState = fn(api.setState, get, api);\n if (connectionInformation.type === \"untracked\") {\n connection == null ? void 0 : connection.init(initialState);\n } else {\n connectionInformation.stores[connectionInformation.store] = api;\n connection == null ? void 0 : connection.init(\n Object.fromEntries(\n Object.entries(connectionInformation.stores).map(([key, store2]) => [\n key,\n key === connectionInformation.store ? initialState : store2.getState()\n ])\n )\n );\n }\n if (api.dispatchFromDevtools && typeof api.dispatch === \"function\") {\n let didWarnAboutReservedActionType = false;\n const originalDispatch = api.dispatch;\n api.dispatch = (...args) => {\n if ((import.meta.env ? import.meta.env.MODE : void 0) !== \"production\" && args[0].type === \"__setState\" && !didWarnAboutReservedActionType) {\n console.warn(\n '[zustand devtools middleware] \"__setState\" action type is reserved to set state from the devtools. Avoid using it.'\n );\n didWarnAboutReservedActionType = true;\n }\n originalDispatch(...args);\n };\n }\n connection.subscribe((message) => {\n var _a;\n switch (message.type) {\n case \"ACTION\":\n if (typeof message.payload !== \"string\") {\n console.error(\n \"[zustand devtools middleware] Unsupported action format\"\n );\n return;\n }\n return parseJsonThen(\n message.payload,\n (action) => {\n if (action.type === \"__setState\") {\n if (store === void 0) {\n setStateFromDevtools(action.state);\n return;\n }\n if (Object.keys(action.state).length !== 1) {\n console.error(\n `\n [zustand devtools middleware] Unsupported __setState action format.\n When using 'store' option in devtools(), the 'state' should have only one key, which is a value of 'store' that was passed in devtools(),\n and value of this only key should be a state object. Example: { \"type\": \"__setState\", \"state\": { \"abc123Store\": { \"foo\": \"bar\" } } }\n `\n );\n }\n const stateFromDevtools = action.state[store];\n if (stateFromDevtools === void 0 || stateFromDevtools === null) {\n return;\n }\n if (JSON.stringify(api.getState()) !== JSON.stringify(stateFromDevtools)) {\n setStateFromDevtools(stateFromDevtools);\n }\n return;\n }\n if (!api.dispatchFromDevtools) return;\n if (typeof api.dispatch !== \"function\") return;\n api.dispatch(action);\n }\n );\n case \"DISPATCH\":\n switch (message.payload.type) {\n case \"RESET\":\n setStateFromDevtools(initialState);\n if (store === void 0) {\n return connection == null ? void 0 : connection.init(api.getState());\n }\n return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n case \"COMMIT\":\n if (store === void 0) {\n connection == null ? void 0 : connection.init(api.getState());\n return;\n }\n return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n case \"ROLLBACK\":\n return parseJsonThen(message.state, (state) => {\n if (store === void 0) {\n setStateFromDevtools(state);\n connection == null ? void 0 : connection.init(api.getState());\n return;\n }\n setStateFromDevtools(state[store]);\n connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n });\n case \"JUMP_TO_STATE\":\n case \"JUMP_TO_ACTION\":\n return parseJsonThen(message.state, (state) => {\n if (store === void 0) {\n setStateFromDevtools(state);\n return;\n }\n if (JSON.stringify(api.getState()) !== JSON.stringify(state[store])) {\n setStateFromDevtools(state[store]);\n }\n });\n case \"IMPORT_STATE\": {\n const { nextLiftedState } = message.payload;\n const lastComputedState = (_a = nextLiftedState.computedStates.slice(-1)[0]) == null ? void 0 : _a.state;\n if (!lastComputedState) return;\n if (store === void 0) {\n setStateFromDevtools(lastComputedState);\n } else {\n setStateFromDevtools(lastComputedState[store]);\n }\n connection == null ? void 0 : connection.send(\n null,\n // FIXME no-any\n nextLiftedState\n );\n return;\n }\n case \"PAUSE_RECORDING\":\n return isRecording = !isRecording;\n }\n return;\n }\n });\n return initialState;\n};\nconst devtools = devtoolsImpl;\nconst parseJsonThen = (stringified, fn) => {\n let parsed;\n try {\n parsed = JSON.parse(stringified);\n } catch (e) {\n console.error(\n \"[zustand devtools middleware] Could not parse the received json\",\n e\n );\n }\n if (parsed !== void 0) fn(parsed);\n};\n\nconst subscribeWithSelectorImpl = (fn) => (set, get, api) => {\n const origSubscribe = api.subscribe;\n api.subscribe = ((selector, optListener, options) => {\n let listener = selector;\n if (optListener) {\n const equalityFn = (options == null ? void 0 : options.equalityFn) || Object.is;\n let currentSlice = selector(api.getState());\n listener = (state) => {\n const nextSlice = selector(state);\n if (!equalityFn(currentSlice, nextSlice)) {\n const previousSlice = currentSlice;\n optListener(currentSlice = nextSlice, previousSlice);\n }\n };\n if (options == null ? void 0 : options.fireImmediately) {\n optListener(currentSlice, currentSlice);\n }\n }\n return origSubscribe(listener);\n });\n const initialState = fn(set, get, api);\n return initialState;\n};\nconst subscribeWithSelector = subscribeWithSelectorImpl;\n\nfunction combine(initialState, create) {\n return (...args) => Object.assign({}, initialState, create(...args));\n}\n\nfunction createJSONStorage(getStorage, options) {\n let storage;\n try {\n storage = getStorage();\n } catch (e) {\n return;\n }\n const persistStorage = {\n getItem: (name) => {\n var _a;\n const parse = (str2) => {\n if (str2 === null) {\n return null;\n }\n return JSON.parse(str2, options == null ? void 0 : options.reviver);\n };\n const str = (_a = storage.getItem(name)) != null ? _a : null;\n if (str instanceof Promise) {\n return str.then(parse);\n }\n return parse(str);\n },\n setItem: (name, newValue) => storage.setItem(name, JSON.stringify(newValue, options == null ? void 0 : options.replacer)),\n removeItem: (name) => storage.removeItem(name)\n };\n return persistStorage;\n}\nconst toThenable = (fn) => (input) => {\n try {\n const result = fn(input);\n if (result instanceof Promise) {\n return result;\n }\n return {\n then(onFulfilled) {\n return toThenable(onFulfilled)(result);\n },\n catch(_onRejected) {\n return this;\n }\n };\n } catch (e) {\n return {\n then(_onFulfilled) {\n return this;\n },\n catch(onRejected) {\n return toThenable(onRejected)(e);\n }\n };\n }\n};\nconst persistImpl = (config, baseOptions) => (set, get, api) => {\n let options = {\n storage: createJSONStorage(() => localStorage),\n partialize: (state) => state,\n version: 0,\n merge: (persistedState, currentState) => ({\n ...currentState,\n ...persistedState\n }),\n ...baseOptions\n };\n let hasHydrated = false;\n const hydrationListeners = /* @__PURE__ */ new Set();\n const finishHydrationListeners = /* @__PURE__ */ new Set();\n let storage = options.storage;\n if (!storage) {\n return config(\n (...args) => {\n console.warn(\n `[zustand persist middleware] Unable to update item '${options.name}', the given storage is currently unavailable.`\n );\n set(...args);\n },\n get,\n api\n );\n }\n const setItem = () => {\n const state = options.partialize({ ...get() });\n return storage.setItem(options.name, {\n state,\n version: options.version\n });\n };\n const savedSetState = api.setState;\n api.setState = (state, replace) => {\n savedSetState(state, replace);\n return setItem();\n };\n const configResult = config(\n (...args) => {\n set(...args);\n return setItem();\n },\n get,\n api\n );\n api.getInitialState = () => configResult;\n let stateFromStorage;\n const hydrate = () => {\n var _a, _b;\n if (!storage) return;\n hasHydrated = false;\n hydrationListeners.forEach((cb) => {\n var _a2;\n return cb((_a2 = get()) != null ? _a2 : configResult);\n });\n const postRehydrationCallback = ((_b = options.onRehydrateStorage) == null ? void 0 : _b.call(options, (_a = get()) != null ? _a : configResult)) || void 0;\n return toThenable(storage.getItem.bind(storage))(options.name).then((deserializedStorageValue) => {\n if (deserializedStorageValue) {\n if (typeof deserializedStorageValue.version === \"number\" && deserializedStorageValue.version !== options.version) {\n if (options.migrate) {\n const migration = options.migrate(\n deserializedStorageValue.state,\n deserializedStorageValue.version\n );\n if (migration instanceof Promise) {\n return migration.then((result) => [true, result]);\n }\n return [true, migration];\n }\n console.error(\n `State loaded from storage couldn't be migrated since no migrate function was provided`\n );\n } else {\n return [false, deserializedStorageValue.state];\n }\n }\n return [false, void 0];\n }).then((migrationResult) => {\n var _a2;\n const [migrated, migratedState] = migrationResult;\n stateFromStorage = options.merge(\n migratedState,\n (_a2 = get()) != null ? _a2 : configResult\n );\n set(stateFromStorage, true);\n if (migrated) {\n return setItem();\n }\n }).then(() => {\n postRehydrationCallback == null ? void 0 : postRehydrationCallback(stateFromStorage, void 0);\n stateFromStorage = get();\n hasHydrated = true;\n finishHydrationListeners.forEach((cb) => cb(stateFromStorage));\n }).catch((e) => {\n postRehydrationCallback == null ? void 0 : postRehydrationCallback(void 0, e);\n });\n };\n api.persist = {\n setOptions: (newOptions) => {\n options = {\n ...options,\n ...newOptions\n };\n if (newOptions.storage) {\n storage = newOptions.storage;\n }\n },\n clearStorage: () => {\n storage == null ? void 0 : storage.removeItem(options.name);\n },\n getOptions: () => options,\n rehydrate: () => hydrate(),\n hasHydrated: () => hasHydrated,\n onHydrate: (cb) => {\n hydrationListeners.add(cb);\n return () => {\n hydrationListeners.delete(cb);\n };\n },\n onFinishHydration: (cb) => {\n finishHydrationListeners.add(cb);\n return () => {\n finishHydrationListeners.delete(cb);\n };\n }\n };\n if (!options.skipHydration) {\n hydrate();\n }\n return stateFromStorage || configResult;\n};\nconst persist = persistImpl;\n\nfunction ssrSafe(config, isSSR = typeof window === \"undefined\") {\n return (set, get, api) => {\n if (!isSSR) {\n return config(set, get, api);\n }\n const ssrSet = () => {\n throw new Error(\"Cannot set state of Zustand store in SSR\");\n };\n api.setState = ssrSet;\n return config(ssrSet, get, api);\n };\n}\n\nexport { combine, createJSONStorage, devtools, persist, redux, subscribeWithSelector, ssrSafe as unstable_ssrSafe };\n","import type {\n NodeDefinition,\n StudioNode,\n StudioEdge,\n ImageMetadata,\n GenerateWorkflowRequest,\n GenerateWorkflowResponse,\n GenerateStatusResponse,\n} from \"@teamflojo/floimg-studio-shared\";\n\nconst API_BASE = \"/api\";\n\nasync function fetchJson<T>(url: string, options?: RequestInit): Promise<T> {\n const response = await fetch(url, {\n ...options,\n headers: {\n \"Content-Type\": \"application/json\",\n ...options?.headers,\n },\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({ error: \"Unknown error\" }));\n throw new Error(error.error || `HTTP ${response.status}`);\n }\n\n return response.json();\n}\n\n// Node registry\nexport async function getGenerators(): Promise<NodeDefinition[]> {\n return fetchJson(`${API_BASE}/nodes/generators`);\n}\n\nexport async function getTransforms(): Promise<NodeDefinition[]> {\n return fetchJson(`${API_BASE}/nodes/transforms`);\n}\n\nexport async function getTextProviders(): Promise<NodeDefinition[]> {\n return fetchJson(`${API_BASE}/nodes/text`);\n}\n\nexport async function getVisionProviders(): Promise<NodeDefinition[]> {\n return fetchJson(`${API_BASE}/nodes/vision`);\n}\n\n// AI provider configuration passed to backend\nexport interface AIProviderConfig {\n openai?: { apiKey: string };\n anthropic?: { apiKey: string };\n gemini?: { apiKey: string };\n grok?: { apiKey: string };\n openrouter?: { apiKey: string };\n ollama?: { baseUrl: string };\n lmstudio?: { baseUrl: string };\n}\n\n// Execution\nexport async function executeWorkflow(\n nodes: StudioNode[],\n edges: StudioEdge[],\n aiProviders?: AIProviderConfig\n): Promise<{\n status: string;\n imageIds: string[];\n imageUrls?: string[]; // Presigned cloud URLs (FSC only)\n previews?: Record<string, string>;\n dataOutputs?: Record<\n string,\n { dataType: \"text\" | \"json\"; content: string; parsed?: Record<string, unknown> }\n >;\n error?: string;\n}> {\n return fetchJson(`${API_BASE}/execute/sync`, {\n method: \"POST\",\n body: JSON.stringify({ nodes, edges, aiProviders }),\n });\n}\n\n// Export\nexport async function exportYaml(\n nodes: StudioNode[],\n edges: StudioEdge[]\n): Promise<{ yaml: string }> {\n return fetchJson(`${API_BASE}/export/yaml`, {\n method: \"POST\",\n body: JSON.stringify({ nodes, edges }),\n });\n}\n\n// Images\nexport interface ImageInfo {\n id: string;\n filename: string;\n mime: string;\n size: number;\n createdAt: number;\n}\n\nexport async function listImages(): Promise<ImageInfo[]> {\n return fetchJson(`${API_BASE}/images`);\n}\n\nexport function getImageUrl(id: string): string {\n return `${API_BASE}/images/${id}/blob`;\n}\n\nexport async function getImageWorkflow(id: string): Promise<ImageMetadata | null> {\n try {\n return await fetchJson(`${API_BASE}/images/${id}/workflow`);\n } catch {\n return null; // Workflow metadata not available for this image\n }\n}\n\n// Uploads\nexport interface UploadInfo {\n id: string;\n filename: string;\n mime: string;\n size: number;\n createdAt: number;\n}\n\nexport async function uploadImage(file: File): Promise<UploadInfo> {\n const formData = new FormData();\n formData.append(\"file\", file);\n\n const response = await fetch(`${API_BASE}/uploads`, {\n method: \"POST\",\n body: formData,\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({ error: \"Upload failed\" }));\n throw new Error(error.error || `HTTP ${response.status}`);\n }\n\n return response.json();\n}\n\nexport async function listUploads(): Promise<UploadInfo[]> {\n return fetchJson(`${API_BASE}/uploads`);\n}\n\nexport async function getUploadThumbnail(id: string): Promise<{ dataUrl: string }> {\n return fetchJson(`${API_BASE}/uploads/${id}/thumbnail`);\n}\n\nexport async function deleteUpload(id: string): Promise<void> {\n const response = await fetch(`${API_BASE}/uploads/${id}`, {\n method: \"DELETE\",\n });\n if (!response.ok) {\n throw new Error(`Failed to delete upload: ${response.status}`);\n }\n}\n\nexport function getUploadBlobUrl(id: string): string {\n return `${API_BASE}/uploads/${id}/blob`;\n}\n\n// Input nodes\nexport async function getInputNodes(): Promise<NodeDefinition[]> {\n return fetchJson(`${API_BASE}/nodes/inputs`);\n}\n\n// Import\nexport interface ImportResult {\n success: boolean;\n nodes: StudioNode[];\n edges: StudioEdge[];\n name: string;\n error?: string;\n line?: number;\n column?: number;\n}\n\nexport interface ImportValidationResult {\n valid: boolean;\n errors: Array<{ message: string; line?: number; column?: number }>;\n}\n\nexport async function importYaml(yaml: string): Promise<ImportResult> {\n return fetchJson(`${API_BASE}/import`, {\n method: \"POST\",\n body: JSON.stringify({ yaml }),\n });\n}\n\nexport async function validateYaml(yaml: string): Promise<ImportValidationResult> {\n return fetchJson(`${API_BASE}/import/validate`, {\n method: \"POST\",\n body: JSON.stringify({ yaml }),\n });\n}\n\n// Workflow Generation\nexport async function generateWorkflow(\n request: GenerateWorkflowRequest\n): Promise<GenerateWorkflowResponse> {\n return fetchJson(`${API_BASE}/generate/workflow`, {\n method: \"POST\",\n body: JSON.stringify(request),\n });\n}\n\nexport async function getGenerateStatus(): Promise<GenerateStatusResponse> {\n return fetchJson(`${API_BASE}/generate/status`);\n}\n","/**\n * Server-Sent Events (SSE) client utility\n *\n * Handles POST-based SSE connections for streaming execution and generation updates.\n * Uses fetch with streaming response body parsing.\n */\n\nexport interface SSEConnectionHandlers<T> {\n onMessage: (event: T) => void;\n onError: (error: Error) => void;\n onClose: () => void;\n}\n\nexport interface SSEConnection {\n abort: () => void;\n}\n\n/**\n * Create an SSE connection using POST request with JSON body.\n *\n * SSE typically uses GET, but we need POST to send workflow data.\n * This implements manual SSE parsing over a fetch streaming response.\n */\nexport function createSSEConnection<T>(\n url: string,\n body: unknown,\n handlers: SSEConnectionHandlers<T>\n): SSEConnection {\n const controller = new AbortController();\n\n // Start the streaming request\n (async () => {\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n signal: controller.signal,\n });\n\n if (!response.ok) {\n const errorBody = await response.json().catch(() => ({ error: \"Unknown error\" }));\n throw new Error(errorBody.error || `HTTP ${response.status}`);\n }\n\n const reader = response.body?.getReader();\n if (!reader) {\n throw new Error(\"Response body is not readable\");\n }\n\n const decoder = new globalThis.TextDecoder();\n let buffer = \"\";\n\n // Read the stream\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n // Process any remaining data in buffer\n if (buffer.trim()) {\n processBuffer(buffer, handlers);\n }\n break;\n }\n\n // Decode chunk and add to buffer\n buffer += decoder.decode(value, { stream: true });\n\n // Process complete SSE messages (separated by double newlines)\n const messages = buffer.split(\"\\n\\n\");\n buffer = messages.pop() || \"\"; // Keep incomplete message in buffer\n\n for (const message of messages) {\n if (message.trim()) {\n processSSEMessage(message, handlers);\n }\n }\n }\n\n handlers.onClose();\n } catch (error) {\n // Don't report abort errors\n if (error instanceof Error && error.name === \"AbortError\") {\n handlers.onClose();\n return;\n }\n handlers.onError(error instanceof Error ? error : new Error(String(error)));\n }\n })();\n\n return {\n abort: () => controller.abort(),\n };\n}\n\n/**\n * Process a single SSE message block\n */\nfunction processSSEMessage<T>(message: string, handlers: SSEConnectionHandlers<T>): void {\n const lines = message.split(\"\\n\");\n let data = \"\";\n\n for (const line of lines) {\n if (line.startsWith(\"data: \")) {\n // Accumulate data lines (SSE spec allows multiple data: lines)\n data += (data ? \"\\n\" : \"\") + line.slice(6);\n }\n // Ignore other SSE fields (event:, id:, retry:) for simplicity\n }\n\n if (data) {\n try {\n const parsed = JSON.parse(data) as T;\n handlers.onMessage(parsed);\n } catch (error) {\n console.warn(\"SSE: Failed to parse message data:\", {\n error: error instanceof Error ? error.message : String(error),\n dataPreview: data.slice(0, 200),\n dataLength: data.length,\n });\n }\n }\n}\n\n/**\n * Process remaining buffer content\n */\nfunction processBuffer<T>(buffer: string, handlers: SSEConnectionHandlers<T>): void {\n const lines = buffer.split(\"\\n\");\n let data = \"\";\n\n for (const line of lines) {\n if (line.startsWith(\"data: \")) {\n data += (data ? \"\\n\" : \"\") + line.slice(6);\n }\n }\n\n if (data) {\n try {\n const parsed = JSON.parse(data) as T;\n handlers.onMessage(parsed);\n } catch (error) {\n // Log incomplete/malformed data at end of stream for debugging\n console.warn(\"SSE: Incomplete data at end of stream:\", {\n error: error instanceof Error ? error.message : String(error),\n dataPreview: data.slice(0, 200),\n dataLength: data.length,\n });\n }\n }\n}\n","import { create } from \"zustand\";\nimport { persist } from \"zustand/middleware\";\n\n// Provider configuration for cloud APIs\ninterface CloudProvider {\n apiKey: string;\n enabled: boolean;\n}\n\n// Provider configuration for local APIs\ninterface LocalProvider {\n baseUrl: string;\n enabled: boolean;\n}\n\n// All AI provider settings\nexport interface AISettings {\n // Cloud providers (require API keys)\n openai?: CloudProvider;\n anthropic?: CloudProvider;\n gemini?: CloudProvider;\n grok?: CloudProvider;\n openrouter?: CloudProvider;\n\n // Local providers (no API key, just URL)\n ollama?: LocalProvider;\n lmstudio?: LocalProvider;\n}\n\ninterface SettingsStore {\n // AI provider settings\n ai: AISettings;\n setAIProvider: (provider: keyof AISettings, config: CloudProvider | LocalProvider) => void;\n clearAIProvider: (provider: keyof AISettings) => void;\n\n // Settings modal visibility\n showSettings: boolean;\n openSettings: () => void;\n closeSettings: () => void;\n\n // Get configured providers for API calls\n getConfiguredProviders: () => {\n openai?: { apiKey: string };\n anthropic?: { apiKey: string };\n gemini?: { apiKey: string };\n grok?: { apiKey: string };\n openrouter?: { apiKey: string };\n ollama?: { baseUrl: string };\n lmstudio?: { baseUrl: string };\n };\n}\n\n// Default URLs for local providers\nconst DEFAULT_OLLAMA_URL = \"http://localhost:11434\";\nconst DEFAULT_LMSTUDIO_URL = \"http://localhost:1234\";\n\nexport const useSettingsStore = create<SettingsStore>()(\n persist(\n (set, get) => ({\n ai: {\n ollama: {\n baseUrl: DEFAULT_OLLAMA_URL,\n enabled: false,\n },\n lmstudio: {\n baseUrl: DEFAULT_LMSTUDIO_URL,\n enabled: false,\n },\n },\n showSettings: false,\n\n setAIProvider: (provider, config) => {\n set((state) => ({\n ai: {\n ...state.ai,\n [provider]: config,\n },\n }));\n },\n\n clearAIProvider: (provider) => {\n set((state) => {\n const newAI = { ...state.ai };\n delete newAI[provider];\n return { ai: newAI };\n });\n },\n\n openSettings: () => set({ showSettings: true }),\n closeSettings: () => set({ showSettings: false }),\n\n getConfiguredProviders: () => {\n const { ai } = get();\n const result: ReturnType<SettingsStore[\"getConfiguredProviders\"]> = {};\n\n // Cloud providers - only include if enabled and has API key\n if (ai.openai?.enabled && ai.openai.apiKey) {\n result.openai = { apiKey: ai.openai.apiKey };\n }\n if (ai.anthropic?.enabled && ai.anthropic.apiKey) {\n result.anthropic = { apiKey: ai.anthropic.apiKey };\n }\n if (ai.gemini?.enabled && ai.gemini.apiKey) {\n result.gemini = { apiKey: ai.gemini.apiKey };\n }\n if (ai.grok?.enabled && ai.grok.apiKey) {\n result.grok = { apiKey: ai.grok.apiKey };\n }\n if (ai.openrouter?.enabled && ai.openrouter.apiKey) {\n result.openrouter = { apiKey: ai.openrouter.apiKey };\n }\n\n // Local providers - only include if enabled\n if (ai.ollama?.enabled) {\n result.ollama = { baseUrl: ai.ollama.baseUrl || DEFAULT_OLLAMA_URL };\n }\n if (ai.lmstudio?.enabled) {\n result.lmstudio = { baseUrl: ai.lmstudio.baseUrl || DEFAULT_LMSTUDIO_URL };\n }\n\n return result;\n },\n }),\n {\n name: \"floimg-studio-settings\",\n // Only persist AI settings, not modal visibility\n partialize: (state) => ({ ai: state.ai }),\n }\n )\n);\n","import { create } from \"zustand\";\nimport { persist } from \"zustand/middleware\";\nimport type { Node, Edge, Connection } from \"reactflow\";\nimport type {\n GeneratorNodeData,\n TransformNodeData,\n SaveNodeData,\n InputNodeData,\n VisionNodeData,\n TextNodeData,\n NodeDefinition,\n GeneratedWorkflowData,\n StudioNodeType,\n ExecutionSSEEvent,\n} from \"@teamflojo/floimg-studio-shared\";\nimport type { Template } from \"@teamflojo/floimg-templates\";\nimport { exportYaml } from \"../api/client\";\nimport { createSSEConnection, type SSEConnection } from \"../api/sse\";\n\n// Module-level variable to store active SSE connection (not in store since it's not serializable)\nlet activeExecutionConnection: SSEConnection | null = null;\nimport type { StudioNode, StudioEdge } from \"@teamflojo/floimg-studio-shared\";\nimport { useSettingsStore } from \"./settingsStore\";\n\ntype NodeData =\n | GeneratorNodeData\n | TransformNodeData\n | SaveNodeData\n | InputNodeData\n | VisionNodeData\n | TextNodeData;\n\ntype NodeExecutionStatus = \"idle\" | \"pending\" | \"running\" | \"completed\" | \"error\";\n\ninterface DataOutput {\n dataType: \"text\" | \"json\";\n content: string;\n parsed?: Record<string, unknown>;\n}\n\n// Saved workflow structure for persistence\nexport interface SavedWorkflow {\n id: string;\n name: string;\n nodes: Node<NodeData>[];\n edges: Edge[];\n createdAt: number;\n updatedAt: number;\n templateId?: string;\n}\n\ninterface ExecutionState {\n status: \"idle\" | \"running\" | \"completed\" | \"error\";\n imageIds: string[];\n imageUrls: string[]; // Presigned cloud URLs for thumbnails (FSC only)\n previews: Record<string, string>; // nodeId -> data URL\n dataOutputs: Record<string, DataOutput>; // nodeId -> text/json output (for vision/text nodes)\n nodeStatus: Record<string, NodeExecutionStatus>; // per-node execution status\n error?: string;\n}\n\ninterface WorkflowStore {\n // Nodes and edges (React Flow compatible)\n nodes: Node<NodeData>[];\n edges: Edge[];\n selectedNodeId: string | null;\n\n // Template tracking\n currentTemplateId: string | null;\n loadTemplate: (template: Template) => void;\n clearWorkflow: () => void;\n\n // Workflow persistence\n savedWorkflows: SavedWorkflow[];\n activeWorkflowId: string | null;\n activeWorkflowName: string;\n hasUnsavedChanges: boolean;\n showLibrary: boolean;\n\n // Workflow persistence methods\n saveWorkflow: (name?: string) => string;\n loadWorkflow: (id: string) => void;\n deleteWorkflow: (id: string) => void;\n renameWorkflow: (id: string, name: string) => void;\n duplicateWorkflow: (id: string) => string;\n newWorkflow: () => void;\n setActiveWorkflowName: (name: string) => void;\n toggleLibrary: () => void;\n markDirty: () => void;\n\n // Preview visibility per node (default: true)\n previewVisible: Record<string, boolean>;\n togglePreview: (id: string) => void;\n\n // Node registry\n generators: NodeDefinition[];\n transforms: NodeDefinition[];\n textProviders: NodeDefinition[];\n visionProviders: NodeDefinition[];\n setGenerators: (generators: NodeDefinition[]) => void;\n setTransforms: (transforms: NodeDefinition[]) => void;\n setTextProviders: (textProviders: NodeDefinition[]) => void;\n setVisionProviders: (visionProviders: NodeDefinition[]) => void;\n\n // Node operations\n addNode: (definition: NodeDefinition, position: { x: number; y: number }) => void;\n updateNodeData: (id: string, data: Partial<NodeData>) => void;\n deleteNode: (id: string) => void;\n duplicateNode: (id: string) => void;\n setNodes: (nodes: Node<NodeData>[]) => void;\n\n // Edge operations\n addEdge: (connection: Connection) => void;\n deleteEdge: (id: string) => void;\n setEdges: (edges: Edge[]) => void;\n\n // Selection\n setSelectedNode: (id: string | null) => void;\n\n // Execution\n execution: ExecutionState;\n execute: () => Promise<void>;\n cancelExecution: () => void;\n\n // Export\n exportToYaml: () => Promise<string>;\n\n // Import\n importFromYaml: (nodes: StudioNode[], edges: StudioEdge[], name?: string) => void;\n\n // AI-generated workflow\n loadGeneratedWorkflow: (workflow: GeneratedWorkflowData) => void;\n\n // Output inspector\n inspectedNodeId: string | null;\n openOutputInspector: (nodeId: string) => void;\n closeOutputInspector: () => void;\n}\n\nlet nodeIdCounter = 0;\n\nfunction generateNodeId(): string {\n return `node_${++nodeIdCounter}`;\n}\n\n// Helper to generate unique workflow IDs\nfunction generateWorkflowId(): string {\n const timestamp = Date.now();\n const random = Math.random().toString(36).substring(2, 8);\n return `wf_${timestamp}_${random}`;\n}\n\nexport const useWorkflowStore = create<WorkflowStore>()(\n persist(\n (set, get) => ({\n nodes: [],\n edges: [],\n selectedNodeId: null,\n currentTemplateId: null,\n previewVisible: {},\n generators: [],\n transforms: [],\n textProviders: [],\n visionProviders: [],\n\n // Workflow persistence state\n savedWorkflows: [],\n activeWorkflowId: null,\n activeWorkflowName: \"Untitled Workflow\",\n hasUnsavedChanges: false,\n showLibrary: false,\n\n execution: {\n status: \"idle\",\n imageIds: [],\n imageUrls: [],\n previews: {},\n dataOutputs: {},\n nodeStatus: {},\n },\n\n // Output inspector state\n inspectedNodeId: null,\n openOutputInspector: (nodeId) => set({ inspectedNodeId: nodeId }),\n closeOutputInspector: () => set({ inspectedNodeId: null }),\n\n loadTemplate: (template) => {\n // Convert StudioNodes to React Flow nodes with new IDs\n const idMap = new Map<string, string>();\n\n const nodes: Node<NodeData>[] = template.workflow.nodes.map((studioNode) => {\n const newId = generateNodeId();\n idMap.set(studioNode.id, newId);\n\n return {\n id: newId,\n type: studioNode.type,\n position: studioNode.position,\n data: studioNode.data as NodeData,\n };\n });\n\n // Convert edges with mapped IDs\n const edges: Edge[] = template.workflow.edges.map((studioEdge) => {\n const newSource = idMap.get(studioEdge.source) || studioEdge.source;\n const newTarget = idMap.get(studioEdge.target) || studioEdge.target;\n\n return {\n id: `edge_${newSource}_${newTarget}`,\n source: newSource,\n target: newTarget,\n };\n });\n\n set({\n nodes,\n edges,\n selectedNodeId: null,\n currentTemplateId: template.id,\n previewVisible: {},\n execution: {\n status: \"idle\",\n imageIds: [],\n imageUrls: [],\n previews: {},\n dataOutputs: {},\n nodeStatus: {},\n },\n });\n },\n\n clearWorkflow: () => {\n set({\n nodes: [],\n edges: [],\n selectedNodeId: null,\n currentTemplateId: null,\n previewVisible: {},\n execution: {\n status: \"idle\",\n imageIds: [],\n imageUrls: [],\n previews: {},\n dataOutputs: {},\n nodeStatus: {},\n },\n });\n },\n\n togglePreview: (id) => {\n set((state) => ({\n previewVisible: {\n ...state.previewVisible,\n [id]: state.previewVisible[id] === false ? true : false, // default true, toggle\n },\n }));\n },\n\n setGenerators: (generators) => set({ generators }),\n setTransforms: (transforms) => set({ transforms }),\n setTextProviders: (textProviders) => set({ textProviders }),\n setVisionProviders: (visionProviders) => set({ visionProviders }),\n\n addNode: (definition, position) => {\n const id = generateNodeId();\n let data: NodeData;\n\n if (definition.type === \"generator\") {\n data = {\n generatorName: definition.name,\n params: getDefaultParams(definition),\n isAI: definition.isAI, // Track if this is an AI generator (can accept text input)\n acceptsReferenceImages: definition.acceptsReferenceImages,\n maxReferenceImages: definition.maxReferenceImages,\n } as GeneratorNodeData;\n } else if (definition.type === \"transform\") {\n data = {\n operation: definition.name,\n providerName: definition.providerName, // Track which provider this transform belongs to\n isAI: definition.isAI, // Track if this is an AI transform (can accept text input)\n params: getDefaultParams(definition),\n acceptsReferenceImages: definition.acceptsReferenceImages,\n maxReferenceImages: definition.maxReferenceImages,\n } as TransformNodeData;\n } else if (definition.type === \"input\") {\n data = {\n uploadId: undefined,\n filename: undefined,\n mime: undefined,\n } as InputNodeData;\n } else if (definition.type === \"vision\") {\n data = {\n providerName: definition.name,\n providerLabel: definition.label, // Human-readable label (e.g., \"Gemini Vision\")\n params: getDefaultParams(definition),\n } as VisionNodeData;\n } else if (definition.type === \"text\") {\n data = {\n providerName: definition.name,\n providerLabel: definition.label, // Human-readable label (e.g., \"Gemini Text\")\n params: getDefaultParams(definition),\n } as TextNodeData;\n } else {\n // Save node - read provider and destination from definition params\n const props = definition.params?.properties || {};\n const provider = (props.provider?.default as string) || \"filesystem\";\n const destination = (props.destination?.default as string) || \"./output/image.png\";\n data = {\n destination,\n provider,\n } as SaveNodeData;\n }\n\n const newNode: Node<NodeData> = {\n id,\n type: definition.type,\n position,\n data,\n };\n\n set((state) => ({\n nodes: [...state.nodes, newNode],\n }));\n },\n\n updateNodeData: (id, data) => {\n set((state) => ({\n nodes: state.nodes.map((node) =>\n node.id === id ? { ...node, data: { ...node.data, ...data } } : node\n ),\n }));\n },\n\n deleteNode: (id) => {\n set((state) => ({\n nodes: state.nodes.filter((n) => n.id !== id),\n edges: state.edges.filter((e) => e.source !== id && e.target !== id),\n selectedNodeId: state.selectedNodeId === id ? null : state.selectedNodeId,\n }));\n },\n\n duplicateNode: (id) => {\n const state = get();\n const nodeToDuplicate = state.nodes.find((n) => n.id === id);\n if (!nodeToDuplicate) return;\n\n const newId = generateNodeId();\n const newNode: Node<NodeData> = {\n ...nodeToDuplicate,\n id: newId,\n position: {\n x: nodeToDuplicate.position.x + 50,\n y: nodeToDuplicate.position.y + 50,\n },\n data: JSON.parse(JSON.stringify(nodeToDuplicate.data)), // Deep clone\n selected: false,\n };\n\n set({\n nodes: [...state.nodes, newNode],\n selectedNodeId: newId, // Select the new node\n });\n },\n\n setNodes: (nodes) => set({ nodes }),\n\n addEdge: (connection) => {\n if (!connection.source || !connection.target) return;\n\n // Include sourceHandle and targetHandle in edge ID for uniqueness\n const handleSuffix = [connection.sourceHandle, connection.targetHandle]\n .filter(Boolean)\n .join(\"_\");\n const id = handleSuffix\n ? `edge_${connection.source}_${connection.target}_${handleSuffix}`\n : `edge_${connection.source}_${connection.target}`;\n\n const newEdge: Edge = {\n id,\n source: connection.source,\n target: connection.target,\n sourceHandle: connection.sourceHandle ?? undefined,\n targetHandle: connection.targetHandle ?? undefined,\n };\n\n set((state) => ({\n edges: [...state.edges, newEdge],\n }));\n },\n\n deleteEdge: (id) => {\n set((state) => ({\n edges: state.edges.filter((e) => e.id !== id),\n }));\n },\n\n setEdges: (edges) => set({ edges }),\n\n setSelectedNode: (id) => set({ selectedNodeId: id }),\n\n execute: async () => {\n const { nodes, edges } = get();\n\n // Convert React Flow nodes to StudioNodes\n const studioNodes = nodes.map((n) => ({\n id: n.id,\n type: n.type as \"generator\" | \"transform\" | \"save\",\n position: n.position,\n data: n.data,\n }));\n\n const studioEdges = edges.map((e) => ({\n id: e.id,\n source: e.source,\n target: e.target,\n sourceHandle: e.sourceHandle ?? undefined,\n targetHandle: e.targetHandle ?? undefined,\n }));\n\n // Get AI provider settings\n const aiProviders = useSettingsStore.getState().getConfiguredProviders();\n\n // Set all nodes to \"pending\" status (not running yet)\n const initialNodeStatus: Record<string, NodeExecutionStatus> = {};\n for (const node of nodes) {\n initialNodeStatus[node.id] = \"pending\";\n }\n\n set({\n execution: {\n status: \"running\",\n imageIds: [],\n imageUrls: [],\n previews: {},\n dataOutputs: {},\n nodeStatus: initialNodeStatus,\n },\n });\n\n // Use SSE streaming for real-time progress updates\n return new Promise<void>((resolve, reject) => {\n activeExecutionConnection = createSSEConnection<ExecutionSSEEvent>(\n \"/api/execute/stream\",\n { nodes: studioNodes, edges: studioEdges, aiProviders },\n {\n onMessage: (event) => {\n const state = get();\n\n if (event.type === \"execution.started\") {\n // All nodes start as pending, they'll transition to running as they execute\n }\n\n if (event.type === \"execution.step\") {\n const step = event.data;\n\n // Update the specific node's status\n const newNodeStatus = {\n ...state.execution.nodeStatus,\n [step.nodeId]: step.status as NodeExecutionStatus,\n };\n\n // Update previews if this step has one\n const newPreviews = step.preview\n ? { ...state.execution.previews, [step.nodeId]: step.preview }\n : state.execution.previews;\n\n // Update dataOutputs if this is a text/vision node\n const newDataOutputs =\n step.dataType && step.content\n ? {\n ...state.execution.dataOutputs,\n [step.nodeId]: {\n dataType: step.dataType,\n content: step.content,\n parsed: step.parsed,\n },\n }\n : state.execution.dataOutputs;\n\n set({\n execution: {\n ...state.execution,\n nodeStatus: newNodeStatus,\n previews: newPreviews,\n dataOutputs: newDataOutputs,\n },\n });\n }\n\n if (event.type === \"execution.completed\") {\n // Mark any remaining pending nodes as completed\n const finalNodeStatus = { ...state.execution.nodeStatus };\n for (const nodeId of Object.keys(finalNodeStatus)) {\n if (\n finalNodeStatus[nodeId] === \"pending\" ||\n finalNodeStatus[nodeId] === \"running\"\n ) {\n finalNodeStatus[nodeId] = \"completed\";\n }\n }\n\n set({\n execution: {\n ...state.execution,\n status: \"completed\",\n imageIds: event.data.imageIds,\n imageUrls: event.data.imageUrls,\n nodeStatus: finalNodeStatus,\n },\n });\n resolve();\n }\n\n if (event.type === \"execution.error\") {\n // Mark nodes as error\n const errorNodeStatus = { ...state.execution.nodeStatus };\n if (event.data.nodeId) {\n errorNodeStatus[event.data.nodeId] = \"error\";\n }\n\n set({\n execution: {\n ...state.execution,\n status: \"error\",\n nodeStatus: errorNodeStatus,\n error: event.data.error,\n },\n });\n reject(new Error(event.data.error));\n }\n },\n onError: (error) => {\n const state = get();\n const errorNodeStatus: Record<string, NodeExecutionStatus> = {};\n for (const nodeId of Object.keys(state.execution.nodeStatus)) {\n errorNodeStatus[nodeId] = \"error\";\n }\n\n set({\n execution: {\n ...state.execution,\n status: \"error\",\n nodeStatus: errorNodeStatus,\n error: error.message,\n },\n });\n reject(error);\n },\n onClose: () => {\n // Clear the connection reference\n activeExecutionConnection = null;\n\n // Stream closed - check why\n const state = get();\n if (state.execution.status === \"running\") {\n // Check if this was a user cancellation (status would be 'cancelled' if so)\n // Otherwise treat as unexpected closure\n set({\n execution: {\n ...state.execution,\n status: \"error\",\n error: \"Connection closed unexpectedly\",\n },\n });\n reject(new Error(\"Connection closed unexpectedly\"));\n }\n },\n }\n );\n });\n },\n\n cancelExecution: () => {\n // Abort the active connection if any\n if (activeExecutionConnection) {\n activeExecutionConnection.abort();\n activeExecutionConnection = null;\n }\n\n // Reset execution state to idle\n set({\n execution: {\n status: \"idle\",\n imageIds: [],\n imageUrls: [],\n previews: {},\n dataOutputs: {},\n nodeStatus: {},\n },\n });\n },\n\n exportToYaml: async () => {\n const { nodes, edges } = get();\n\n const studioNodes = nodes.map((n) => ({\n id: n.id,\n type: n.type as \"generator\" | \"transform\" | \"save\",\n position: n.position,\n data: n.data,\n }));\n\n const studioEdges = edges.map((e) => ({\n id: e.id,\n source: e.source,\n target: e.target,\n sourceHandle: e.sourceHandle ?? undefined,\n targetHandle: e.targetHandle ?? undefined,\n }));\n\n const result = await exportYaml(studioNodes, studioEdges);\n return result.yaml;\n },\n\n importFromYaml: (studioNodes, studioEdges, name) => {\n // Convert StudioNodes to React Flow nodes with new IDs\n const idMap = new Map<string, string>();\n\n const nodes: Node<NodeData>[] = studioNodes.map((studioNode) => {\n const newId = generateNodeId();\n idMap.set(studioNode.id, newId);\n\n return {\n id: newId,\n type: studioNode.type,\n position: studioNode.position,\n data: studioNode.data as NodeData,\n };\n });\n\n // Convert edges with mapped IDs\n const edges: Edge[] = studioEdges.map((studioEdge) => {\n const newSource = idMap.get(studioEdge.source) || studioEdge.source;\n const newTarget = idMap.get(studioEdge.target) || studioEdge.target;\n\n return {\n id: `edge_${newSource}_${newTarget}`,\n source: newSource,\n target: newTarget,\n };\n });\n\n set({\n nodes,\n edges,\n selectedNodeId: null,\n currentTemplateId: null,\n previewVisible: {},\n activeWorkflowId: null,\n activeWorkflowName: name || \"Imported Workflow\",\n hasUnsavedChanges: true,\n execution: {\n status: \"idle\",\n imageIds: [],\n imageUrls: [],\n previews: {},\n dataOutputs: {},\n nodeStatus: {},\n },\n });\n },\n\n // Workflow persistence methods\n markDirty: () => set({ hasUnsavedChanges: true }),\n\n toggleLibrary: () => set((state) => ({ showLibrary: !state.showLibrary })),\n\n setActiveWorkflowName: (name) => set({ activeWorkflowName: name, hasUnsavedChanges: true }),\n\n newWorkflow: () => {\n set({\n nodes: [],\n edges: [],\n selectedNodeId: null,\n currentTemplateId: null,\n previewVisible: {},\n activeWorkflowId: null,\n activeWorkflowName: \"Untitled Workflow\",\n hasUnsavedChanges: false,\n execution: {\n status: \"idle\",\n imageIds: [],\n imageUrls: [],\n previews: {},\n dataOutputs: {},\n nodeStatus: {},\n },\n });\n },\n\n saveWorkflow: (name) => {\n const {\n nodes,\n edges,\n activeWorkflowId,\n activeWorkflowName,\n savedWorkflows,\n currentTemplateId,\n } = get();\n const now = Date.now();\n\n if (activeWorkflowId) {\n // Update existing workflow\n const updated = savedWorkflows.map((wf) =>\n wf.id === activeWorkflowId\n ? { ...wf, name: name || activeWorkflowName, nodes, edges, updatedAt: now }\n : wf\n );\n set({\n savedWorkflows: updated,\n activeWorkflowName: name || activeWorkflowName,\n hasUnsavedChanges: false,\n });\n return activeWorkflowId;\n } else {\n // Create new workflow\n const id = generateWorkflowId();\n const newWorkflow: SavedWorkflow = {\n id,\n name: name || activeWorkflowName,\n nodes,\n edges,\n createdAt: now,\n updatedAt: now,\n templateId: currentTemplateId || undefined,\n };\n set({\n savedWorkflows: [...savedWorkflows, newWorkflow],\n activeWorkflowId: id,\n activeWorkflowName: name || activeWorkflowName,\n hasUnsavedChanges: false,\n });\n return id;\n }\n },\n\n loadWorkflow: (id) => {\n const { savedWorkflows } = get();\n const workflow = savedWorkflows.find((wf) => wf.id === id);\n if (!workflow) return;\n\n set({\n nodes: workflow.nodes,\n edges: workflow.edges,\n selectedNodeId: null,\n currentTemplateId: workflow.templateId || null,\n previewVisible: {},\n activeWorkflowId: id,\n activeWorkflowName: workflow.name,\n hasUnsavedChanges: false,\n execution: {\n status: \"idle\",\n imageIds: [],\n imageUrls: [],\n previews: {},\n dataOutputs: {},\n nodeStatus: {},\n },\n });\n },\n\n deleteWorkflow: (id) => {\n const { savedWorkflows, activeWorkflowId } = get();\n const filtered = savedWorkflows.filter((wf) => wf.id !== id);\n\n if (activeWorkflowId === id) {\n // If deleting the active workflow, clear the canvas\n set({\n savedWorkflows: filtered,\n nodes: [],\n edges: [],\n selectedNodeId: null,\n currentTemplateId: null,\n previewVisible: {},\n activeWorkflowId: null,\n activeWorkflowName: \"Untitled Workflow\",\n hasUnsavedChanges: false,\n execution: {\n status: \"idle\",\n imageIds: [],\n imageUrls: [],\n previews: {},\n dataOutputs: {},\n nodeStatus: {},\n },\n });\n } else {\n set({ savedWorkflows: filtered });\n }\n },\n\n renameWorkflow: (id, name) => {\n const { savedWorkflows, activeWorkflowId } = get();\n const updated = savedWorkflows.map((wf) =>\n wf.id === id ? { ...wf, name, updatedAt: Date.now() } : wf\n );\n set({\n savedWorkflows: updated,\n ...(activeWorkflowId === id ? { activeWorkflowName: name } : {}),\n });\n },\n\n duplicateWorkflow: (id) => {\n const { savedWorkflows } = get();\n const workflow = savedWorkflows.find((wf) => wf.id === id);\n if (!workflow) return \"\";\n\n const now = Date.now();\n const newId = generateWorkflowId();\n const duplicate: SavedWorkflow = {\n ...workflow,\n id: newId,\n name: `${workflow.name} (Copy)`,\n createdAt: now,\n updatedAt: now,\n };\n set({ savedWorkflows: [...savedWorkflows, duplicate] });\n return newId;\n },\n\n loadGeneratedWorkflow: (workflow: GeneratedWorkflowData) => {\n // Convert AI-generated workflow to React Flow nodes\n const idMap = new Map<string, string>();\n\n // Auto-layout: arrange nodes in a grid\n const GRID_SPACING_X = 250;\n const GRID_SPACING_Y = 150;\n const NODES_PER_ROW = 3;\n\n const nodes: Node<NodeData>[] = workflow.nodes.map((genNode, index) => {\n const newId = generateNodeId();\n idMap.set(genNode.id, newId);\n\n // Parse nodeType to extract type and name\n // Format: \"generator:dalle-3\", \"transform:sharp:resize\", \"input:upload\", etc.\n const parts = genNode.nodeType.split(\":\");\n const nodeType = parts[0] as StudioNodeType;\n\n // Calculate grid position\n const row = Math.floor(index / NODES_PER_ROW);\n const col = index % NODES_PER_ROW;\n const position = {\n x: 100 + col * GRID_SPACING_X,\n y: 100 + row * GRID_SPACING_Y,\n };\n\n // Build node data based on type\n let data: NodeData;\n\n if (nodeType === \"generator\") {\n const generatorName = parts.slice(1).join(\":\");\n data = {\n generatorName,\n params: genNode.parameters,\n isAI: true, // Assume AI since we're generating from AI\n } as GeneratorNodeData;\n } else if (nodeType === \"transform\") {\n const providerName = parts[1];\n const operation = parts.slice(2).join(\":\");\n data = {\n operation,\n providerName,\n params: genNode.parameters,\n } as TransformNodeData;\n } else if (nodeType === \"input\") {\n data = {\n uploadId: undefined,\n filename: undefined,\n mime: undefined,\n } as InputNodeData;\n } else if (nodeType === \"vision\") {\n const providerName = parts.slice(1).join(\":\");\n data = {\n providerName,\n params: genNode.parameters,\n } as VisionNodeData;\n } else if (nodeType === \"text\") {\n const providerName = parts.slice(1).join(\":\");\n // Extract jsonSchema from params and convert to outputSchema for UI\n const jsonSchema = genNode.parameters.jsonSchema as\n | { properties?: Record<string, { type?: string; description?: string }> }\n | undefined;\n const outputSchema = jsonSchema?.properties\n ? {\n type: \"object\" as const,\n properties: Object.fromEntries(\n Object.entries(jsonSchema.properties).map(([key, prop]) => [\n key,\n {\n type:\n (prop.type as \"string\" | \"number\" | \"boolean\" | \"object\" | \"array\") ||\n \"string\",\n description: prop.description,\n },\n ])\n ),\n }\n : undefined;\n data = {\n providerName,\n params: genNode.parameters,\n outputSchema,\n } as TextNodeData;\n } else {\n // Default to save node\n data = {\n destination: (genNode.parameters.destination as string) || \"./output/image.png\",\n provider: (genNode.parameters.provider as string) || \"filesystem\",\n } as SaveNodeData;\n }\n\n return {\n id: newId,\n type: nodeType,\n position,\n data,\n };\n });\n\n // Convert edges with mapped IDs\n const edges: Edge[] = workflow.edges.map((genEdge) => {\n const newSource = idMap.get(genEdge.source) || genEdge.source;\n const newTarget = idMap.get(genEdge.target) || genEdge.target;\n\n // Include handles in edge ID for uniqueness (multiple edges from same source)\n const handleSuffix = [genEdge.sourceHandle, genEdge.targetHandle]\n .filter(Boolean)\n .join(\"_\");\n const edgeId = handleSuffix\n ? `edge_${newSource}_${newTarget}_${handleSuffix}`\n : `edge_${newSource}_${newTarget}`;\n\n return {\n id: edgeId,\n source: newSource,\n target: newTarget,\n sourceHandle: genEdge.sourceHandle ?? undefined,\n targetHandle: genEdge.targetHandle ?? undefined,\n };\n });\n\n set({\n nodes,\n edges,\n selectedNodeId: null,\n currentTemplateId: null,\n previewVisible: {},\n activeWorkflowId: null,\n activeWorkflowName: \"AI Generated Workflow\",\n hasUnsavedChanges: true,\n execution: {\n status: \"idle\",\n imageIds: [],\n imageUrls: [],\n previews: {},\n dataOutputs: {},\n nodeStatus: {},\n },\n });\n },\n }),\n {\n name: \"floimg-studio-workflows\",\n // Only persist savedWorkflows - current canvas state is ephemeral\n partialize: (state) => ({\n savedWorkflows: state.savedWorkflows,\n }),\n }\n )\n);\n\n// Helper to extract default values from schema\nfunction getDefaultParams(definition: NodeDefinition): Record<string, unknown> {\n const params: Record<string, unknown> = {};\n\n if (definition.params?.properties) {\n for (const [key, field] of Object.entries(definition.params.properties)) {\n if (field.default !== undefined) {\n params[key] = field.default;\n }\n }\n }\n\n return params;\n}\n","import { memo, useCallback, useRef } from \"react\";\nimport { Handle, Position, type NodeProps } from \"reactflow\";\nimport type {\n GeneratorNodeData,\n TransformNodeData,\n SaveNodeData,\n InputNodeData,\n VisionNodeData,\n TextNodeData,\n} from \"@teamflojo/floimg-studio-shared\";\nimport { useWorkflowStore } from \"../stores/workflowStore\";\nimport { uploadImage, getUploadBlobUrl } from \"../api/client\";\n\n// Helper to get execution status class for node border\nfunction getExecutionClass(nodeStatus: string | undefined): string {\n if (nodeStatus === \"pending\") {\n return \"border-gray-400 dark:border-zinc-500\";\n }\n if (nodeStatus === \"running\") {\n return \"border-yellow-400 animate-pulse\";\n }\n if (nodeStatus === \"completed\") {\n return \"border-green-500\";\n }\n if (nodeStatus === \"error\") {\n return \"border-red-500\";\n }\n return \"\";\n}\n\n// Eye icon for preview toggle\nfunction PreviewToggle({ nodeId, color }: { nodeId: string; color: string }) {\n const previewVisible = useWorkflowStore((s) => s.previewVisible[nodeId] !== false);\n const togglePreview = useWorkflowStore((s) => s.togglePreview);\n\n return (\n <button\n onClick={(e) => {\n e.stopPropagation();\n togglePreview(nodeId);\n }}\n className={`ml-auto p-1 rounded hover:bg-gray-200 dark:hover:bg-zinc-600 transition-colors ${previewVisible ? \"opacity-100\" : \"opacity-40\"}`}\n title={previewVisible ? \"Hide preview\" : \"Show preview\"}\n >\n <svg className={`w-3.5 h-3.5 ${color}`} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n {previewVisible ? (\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M15 12a3 3 0 11-6 0 3 3 0 016 0z M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z\"\n />\n ) : (\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21\"\n />\n )}\n </svg>\n </button>\n );\n}\n\n// Generator Node (source nodes - have output only)\n// AI generators may also have a text input handle and/or references input handle\nexport const GeneratorNode = memo(function GeneratorNode({\n id,\n data,\n selected,\n}: NodeProps<GeneratorNodeData>) {\n const preview = useWorkflowStore((s) => s.execution.previews[id]);\n const nodeStatus = useWorkflowStore((s) => s.execution.nodeStatus[id]);\n const previewVisible = useWorkflowStore((s) => s.previewVisible[id] !== false);\n\n const executionClass = getExecutionClass(nodeStatus);\n const borderClass = executionClass || (selected ? \"border-blue-500\" : \"border-blue-200\");\n\n // AI generators get a text input handle for dynamic prompts\n const isAI = data.isAI;\n // Check if this generator accepts reference images\n const acceptsReferences = data.acceptsReferenceImages;\n\n return (\n <div\n className={`rounded-lg border-2 bg-white dark:bg-zinc-800 shadow-md min-w-[180px] overflow-hidden ${borderClass}`}\n >\n {/* Text input handle for AI generators (optional - for dynamic prompts) */}\n {isAI && (\n <Handle\n type=\"target\"\n position={Position.Top}\n id=\"text\"\n className=\"w-3 h-3 !bg-pink-500\"\n title=\"Text input (optional prompt from text/vision node)\"\n />\n )}\n {/* Reference images input handle (for AI generators) */}\n {acceptsReferences && (\n <Handle\n type=\"target\"\n position={Position.Left}\n id=\"references\"\n className=\"w-3 h-3 !bg-violet-500\"\n style={{ top: \"50%\" }}\n title={`Reference images (up to ${data.maxReferenceImages || 14})`}\n />\n )}\n {preview && previewVisible && (\n <div className=\"bg-gray-100 dark:bg-zinc-900 border-b border-gray-200 dark:border-zinc-700\">\n <img src={preview} alt=\"Preview\" className=\"w-full h-24 object-contain\" />\n </div>\n )}\n <div className=\"px-4 py-3\">\n <div className=\"flex items-center gap-2 mb-2\">\n <div className=\"w-3 h-3 rounded-full bg-blue-500\" />\n <span className=\"font-semibold text-sm text-blue-700 dark:text-blue-400\">\n {data.generatorName}\n </span>\n <PreviewToggle nodeId={id} color=\"text-blue-500 dark:text-blue-400\" />\n </div>\n {isAI && (\n <div className=\"text-[10px] text-pink-500 dark:text-pink-400 mb-1\">\n ↑ Connect text node for dynamic prompt\n </div>\n )}\n {acceptsReferences && (\n <div className=\"text-[10px] text-violet-500 dark:text-violet-400 mb-1\">\n ← Connect reference images\n </div>\n )}\n <div className=\"text-xs text-gray-500 dark:text-zinc-400\">\n {Object.entries(data.params)\n .filter(([, value]) => typeof value !== \"object\" || value === null)\n .slice(0, 2)\n .map(([key, value]) => (\n <div key={key} className=\"truncate\">\n {key}: {String(value).slice(0, 20)}\n </div>\n ))}\n </div>\n </div>\n <Handle type=\"source\" position={Position.Right} className=\"w-3 h-3 !bg-blue-500\" />\n </div>\n );\n});\n\n// Transform Node (have both input and output)\n// AI transforms also have an optional text input at the top\n// AI transforms that accept references have a references input at the bottom\nexport const TransformNode = memo(function TransformNode({\n id,\n data,\n selected,\n}: NodeProps<TransformNodeData>) {\n const preview = useWorkflowStore((s) => s.execution.previews[id]);\n const nodeStatus = useWorkflowStore((s) => s.execution.nodeStatus[id]);\n const previewVisible = useWorkflowStore((s) => s.previewVisible[id] !== false);\n\n const executionClass = getExecutionClass(nodeStatus);\n const borderClass = executionClass || (selected ? \"border-teal-500\" : \"border-teal-200\");\n\n // AI transforms get a purple accent to indicate AI-powered\n const isAI = data.isAI;\n // Check if this transform accepts reference images\n const acceptsReferences = data.acceptsReferenceImages;\n\n return (\n <div\n className={`rounded-lg border-2 bg-white dark:bg-zinc-800 shadow-md min-w-[180px] overflow-hidden ${borderClass}`}\n >\n {/* Text input handle for AI transforms (optional - for dynamic prompts) */}\n {isAI && (\n <Handle\n type=\"target\"\n position={Position.Top}\n id=\"text\"\n className=\"w-3 h-3 !bg-pink-500\"\n title=\"Text input (optional prompt from text/vision node)\"\n />\n )}\n {/* Image input handle */}\n <Handle type=\"target\" position={Position.Left} id=\"image\" className=\"w-3 h-3 !bg-teal-500\" />\n {/* Reference images input handle (for AI transforms that accept additional references) */}\n {acceptsReferences && (\n <Handle\n type=\"target\"\n position={Position.Bottom}\n id=\"references\"\n className=\"w-3 h-3 !bg-violet-500\"\n title={`Reference images (up to ${data.maxReferenceImages || 13})`}\n />\n )}\n {preview && previewVisible && (\n <div className=\"bg-gray-100 dark:bg-zinc-900 border-b border-gray-200 dark:border-zinc-700\">\n <img src={preview} alt=\"Preview\" className=\"w-full h-24 object-contain\" />\n </div>\n )}\n <div className=\"px-4 py-3\">\n <div className=\"flex items-center gap-2 mb-2\">\n {isAI ? (\n <svg className=\"w-3 h-3 text-purple-500\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path d=\"M13 7H7v6h6V7z\" />\n <path\n fillRule=\"evenodd\"\n d=\"M7 2a1 1 0 012 0v1h2V2a1 1 0 112 0v1h2a2 2 0 012 2v2h1a1 1 0 110 2h-1v2h1a1 1 0 110 2h-1v2a2 2 0 01-2 2h-2v1a1 1 0 11-2 0v-1H9v1a1 1 0 11-2 0v-1H5a2 2 0 01-2-2v-2H2a1 1 0 110-2h1V9H2a1 1 0 010-2h1V5a2 2 0 012-2h2V2zM5 5h10v10H5V5z\"\n clipRule=\"evenodd\"\n />\n </svg>\n ) : (\n <div className=\"w-3 h-3 rounded-full bg-teal-500\" />\n )}\n <span\n className={`font-semibold text-sm ${isAI ? \"text-purple-700 dark:text-purple-400\" : \"text-teal-700 dark:text-teal-400\"}`}\n >\n {data.operation}\n </span>\n <PreviewToggle\n nodeId={id}\n color={\n isAI ? \"text-purple-500 dark:text-purple-400\" : \"text-teal-500 dark:text-teal-400\"\n }\n />\n </div>\n {isAI && (\n <div className=\"text-[10px] text-pink-500 dark:text-pink-400 mb-1\">\n ↑ Connect text node for dynamic prompt\n </div>\n )}\n {acceptsReferences && (\n <div className=\"text-[10px] text-violet-500 dark:text-violet-400 mb-1\">\n ↓ Connect reference images\n </div>\n )}\n <div className=\"text-xs text-gray-500 dark:text-zinc-400\">\n {Object.entries(data.params)\n .filter(([, value]) => typeof value !== \"object\" || value === null)\n .slice(0, 2)\n .map(([key, value]) => (\n <div key={key} className=\"truncate\">\n {key}: {String(value).slice(0, 20)}\n </div>\n ))}\n </div>\n </div>\n <Handle type=\"source\" position={Position.Right} className=\"w-3 h-3 !bg-teal-500\" />\n </div>\n );\n});\n\n// Save Node (sink nodes - have input only)\nexport const SaveNode = memo(function SaveNode({ id, data, selected }: NodeProps<SaveNodeData>) {\n const nodeStatus = useWorkflowStore((s) => s.execution.nodeStatus[id]);\n\n const executionClass = getExecutionClass(nodeStatus);\n const borderClass = executionClass || (selected ? \"border-green-500\" : \"border-green-200\");\n\n return (\n <div\n className={`px-4 py-3 rounded-lg border-2 bg-white dark:bg-zinc-800 shadow-md min-w-[180px] ${borderClass}`}\n >\n <Handle type=\"target\" position={Position.Left} className=\"w-3 h-3 !bg-green-500\" />\n <div className=\"flex items-center gap-2 mb-2\">\n <div className=\"w-3 h-3 rounded-full bg-green-500\" />\n <span className=\"font-semibold text-sm text-green-700 dark:text-green-400\">Save</span>\n </div>\n <div className=\"text-xs text-gray-500 dark:text-zinc-400 truncate\">{data.destination}</div>\n </div>\n );\n});\n\n// Input Node (source nodes with uploaded images - have output only)\nexport const InputNode = memo(function InputNode({ id, data, selected }: NodeProps<InputNodeData>) {\n const preview = useWorkflowStore((s) => s.execution.previews[id]);\n const nodeStatus = useWorkflowStore((s) => s.execution.nodeStatus[id]);\n const previewVisible = useWorkflowStore((s) => s.previewVisible[id] !== false);\n const updateNodeData = useWorkflowStore((s) => s.updateNodeData);\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const executionClass = getExecutionClass(nodeStatus);\n const borderClass = executionClass || (selected ? \"border-amber-500\" : \"border-amber-200\");\n\n // Handle file selection\n const handleFileSelect = useCallback(\n async (file: File) => {\n try {\n const result = await uploadImage(file);\n updateNodeData(id, {\n uploadId: result.id,\n filename: result.filename,\n mime: result.mime,\n });\n } catch (error) {\n console.error(\"Upload failed:\", error);\n }\n },\n [id, updateNodeData]\n );\n\n // Handle drag and drop\n const handleDrop = useCallback(\n (e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n const file = e.dataTransfer.files[0];\n if (file && file.type.startsWith(\"image/\")) {\n handleFileSelect(file);\n }\n },\n [handleFileSelect]\n );\n\n const handleDragOver = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n }, []);\n\n // Handle file input change\n const handleInputChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (file) {\n handleFileSelect(file);\n }\n },\n [handleFileSelect]\n );\n\n // Get preview URL - either execution preview or static upload URL\n const previewUrl = preview || (data.uploadId ? getUploadBlobUrl(data.uploadId) : null);\n\n return (\n <div\n className={`rounded-lg border-2 bg-white dark:bg-zinc-800 shadow-md min-w-[180px] overflow-hidden ${borderClass}`}\n onDrop={handleDrop}\n onDragOver={handleDragOver}\n >\n {previewUrl && previewVisible ? (\n <div className=\"bg-gray-100 dark:bg-zinc-900 border-b border-gray-200 dark:border-zinc-700\">\n <img src={previewUrl} alt=\"Uploaded\" className=\"w-full h-24 object-contain\" />\n </div>\n ) : !previewUrl ? (\n <div\n className=\"bg-amber-50 dark:bg-amber-900/30 border-b border-amber-100 dark:border-amber-800 h-24 flex items-center justify-center cursor-pointer hover:bg-amber-100 dark:hover:bg-amber-900/50 transition-colors\"\n onClick={() => fileInputRef.current?.click()}\n >\n <div className=\"text-center text-amber-600 dark:text-amber-400\">\n <div className=\"text-2xl mb-1\">+</div>\n <div className=\"text-xs\">Drop image or click</div>\n </div>\n </div>\n ) : null}\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/*\"\n className=\"hidden\"\n onChange={handleInputChange}\n />\n <div className=\"px-4 py-3\">\n <div className=\"flex items-center gap-2 mb-2\">\n <div className=\"w-3 h-3 rounded-full bg-amber-500\" />\n <span className=\"font-semibold text-sm text-amber-700 dark:text-amber-400\">Input</span>\n <PreviewToggle nodeId={id} color=\"text-amber-500 dark:text-amber-400\" />\n </div>\n <div className=\"text-xs text-gray-500 dark:text-zinc-400 truncate\">\n {data.filename || \"No image selected\"}\n </div>\n </div>\n <Handle type=\"source\" position={Position.Right} className=\"w-3 h-3 !bg-amber-500\" />\n </div>\n );\n});\n\n// Vision Node (AI image analysis - has input and output)\n// Supports multiple output handles when outputSchema is defined\nexport const VisionNode = memo(function VisionNode({\n id,\n data,\n selected,\n}: NodeProps<VisionNodeData>) {\n const nodeStatus = useWorkflowStore((s) => s.execution.nodeStatus[id]);\n const dataOutput = useWorkflowStore((s) => s.execution.dataOutputs?.[id]);\n const openOutputInspector = useWorkflowStore((s) => s.openOutputInspector);\n\n const executionClass = getExecutionClass(nodeStatus);\n const borderClass = executionClass || (selected ? \"border-cyan-500\" : \"border-cyan-200\");\n\n // Get output schema properties for multi-output handles\n const outputProperties = data.outputSchema?.properties\n ? Object.entries(data.outputSchema.properties)\n : [];\n const hasMultiOutput = outputProperties.length > 0;\n\n return (\n <div\n className={`rounded-lg border-2 bg-white dark:bg-zinc-800 shadow-md min-w-[180px] overflow-hidden ${borderClass}`}\n >\n <Handle type=\"target\" position={Position.Left} className=\"w-3 h-3 !bg-cyan-500\" />\n {dataOutput && (\n <div className=\"bg-cyan-50 dark:bg-cyan-900/30 border-b border-cyan-100 dark:border-cyan-800 p-2 max-h-24 overflow-auto\">\n <pre className=\"text-xs text-cyan-800 dark:text-cyan-200 whitespace-pre-wrap\">\n {dataOutput.content?.slice(0, 200)}\n {(dataOutput.content?.length || 0) > 200 && \"...\"}\n </pre>\n {dataOutput.content && dataOutput.content.length > 100 && (\n <button\n onClick={(e) => {\n e.stopPropagation();\n openOutputInspector(id);\n }}\n className=\"mt-1 text-xs text-cyan-600 dark:text-cyan-400 hover:text-cyan-800 dark:hover:text-cyan-300 hover:underline\"\n >\n View Full Output\n </button>\n )}\n </div>\n )}\n <div className=\"px-4 py-3\">\n <div className=\"flex items-center gap-2 mb-2\">\n <svg className=\"w-3 h-3 text-cyan-500\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path d=\"M10 12a2 2 0 100-4 2 2 0 000 4z\" />\n <path\n fillRule=\"evenodd\"\n d=\"M.458 10C1.732 5.943 5.522 3 10 3s8.268 2.943 9.542 7c-1.274 4.057-5.064 7-9.542 7S1.732 14.057.458 10zM14 10a4 4 0 11-8 0 4 4 0 018 0z\"\n clipRule=\"evenodd\"\n />\n </svg>\n <span className=\"font-semibold text-sm text-cyan-700 dark:text-cyan-400\">\n {data.providerLabel || data.providerName}\n </span>\n </div>\n <div className=\"text-xs text-gray-500 dark:text-zinc-400\">\n {data.params.prompt ? (\n <div className=\"truncate\">{String(data.params.prompt).slice(0, 30)}...</div>\n ) : null}\n </div>\n {/* Show output schema info if defined */}\n {hasMultiOutput && (\n <div className=\"mt-2 pt-2 border-t border-cyan-200 dark:border-cyan-800\">\n <div className=\"text-[10px] text-cyan-500 dark:text-cyan-400 font-medium mb-1\">\n Outputs:\n </div>\n {outputProperties.map(([key]) => (\n <div\n key={key}\n className=\"text-[10px] text-gray-500 dark:text-zinc-400 flex items-center gap-1\"\n >\n <span className=\"w-1.5 h-1.5 rounded-full bg-cyan-400\"></span>\n {key}\n </div>\n ))}\n </div>\n )}\n </div>\n {/* Multi-output handles: one for each schema property */}\n {hasMultiOutput ? (\n <>\n {/* Full output handle (backward compat) */}\n <Handle\n type=\"source\"\n position={Position.Right}\n id=\"output\"\n className=\"w-3 h-3 !bg-cyan-500\"\n style={{ top: \"50%\" }}\n title=\"Full JSON output\"\n />\n {/* Individual property handles */}\n {outputProperties.map(([key, prop], index) => (\n <Handle\n key={key}\n type=\"source\"\n position={Position.Right}\n id={`output.${key}`}\n className=\"w-2.5 h-2.5 !bg-cyan-400\"\n style={{\n top: `${70 + index * 14}%`,\n }}\n title={`${key}: ${prop.description || prop.type}`}\n />\n ))}\n </>\n ) : (\n <Handle type=\"source\" position={Position.Right} className=\"w-3 h-3 !bg-cyan-500\" />\n )}\n </div>\n );\n});\n\n// Text Node (AI text generation - has optional input and output)\n// Supports multiple output handles when outputSchema is defined\nexport const TextNode = memo(function TextNode({ id, data, selected }: NodeProps<TextNodeData>) {\n const nodeStatus = useWorkflowStore((s) => s.execution.nodeStatus[id]);\n const dataOutput = useWorkflowStore((s) => s.execution.dataOutputs?.[id]);\n const openOutputInspector = useWorkflowStore((s) => s.openOutputInspector);\n\n const executionClass = getExecutionClass(nodeStatus);\n const borderClass = executionClass || (selected ? \"border-pink-500\" : \"border-pink-200\");\n\n // Get output schema properties for multi-output handles\n const outputProperties = data.outputSchema?.properties\n ? Object.entries(data.outputSchema.properties)\n : [];\n const hasMultiOutput = outputProperties.length > 0;\n\n return (\n <div\n className={`rounded-lg border-2 bg-white dark:bg-zinc-800 shadow-md min-w-[180px] overflow-hidden ${borderClass}`}\n >\n <Handle type=\"target\" position={Position.Left} className=\"w-3 h-3 !bg-pink-500\" />\n {dataOutput && (\n <div className=\"bg-pink-50 dark:bg-pink-900/30 border-b border-pink-100 dark:border-pink-800 p-2 max-h-24 overflow-auto\">\n <pre className=\"text-xs text-pink-800 dark:text-pink-200 whitespace-pre-wrap\">\n {dataOutput.content?.slice(0, 200)}\n {(dataOutput.content?.length || 0) > 200 && \"...\"}\n </pre>\n {dataOutput.content && dataOutput.content.length > 100 && (\n <button\n onClick={(e) => {\n e.stopPropagation();\n openOutputInspector(id);\n }}\n className=\"mt-1 text-xs text-pink-600 dark:text-pink-400 hover:text-pink-800 dark:hover:text-pink-300 hover:underline\"\n >\n View Full Output\n </button>\n )}\n </div>\n )}\n <div className=\"px-4 py-3\">\n <div className=\"flex items-center gap-2 mb-2\">\n <svg className=\"w-3 h-3 text-pink-500\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path\n fillRule=\"evenodd\"\n d=\"M18 13V5a2 2 0 00-2-2H4a2 2 0 00-2 2v8a2 2 0 002 2h3l3 3 3-3h3a2 2 0 002-2zM5 7a1 1 0 011-1h8a1 1 0 110 2H6a1 1 0 01-1-1zm1 3a1 1 0 100 2h3a1 1 0 100-2H6z\"\n clipRule=\"evenodd\"\n />\n </svg>\n <span className=\"font-semibold text-sm text-pink-700 dark:text-pink-400\">\n {data.providerLabel || data.providerName}\n </span>\n </div>\n <div className=\"text-xs text-gray-500 dark:text-zinc-400\">\n {data.params.prompt ? (\n <div className=\"truncate\">{String(data.params.prompt).slice(0, 30)}...</div>\n ) : null}\n </div>\n {/* Show output schema info if defined */}\n {hasMultiOutput && (\n <div className=\"mt-2 pt-2 border-t border-pink-200 dark:border-pink-800\">\n <div className=\"text-[10px] text-pink-500 dark:text-pink-400 font-medium mb-1\">\n Outputs:\n </div>\n {outputProperties.map(([key]) => (\n <div\n key={key}\n className=\"text-[10px] text-gray-500 dark:text-zinc-400 flex items-center gap-1\"\n >\n <span className=\"w-1.5 h-1.5 rounded-full bg-pink-400\"></span>\n {key}\n </div>\n ))}\n </div>\n )}\n </div>\n {/* Multi-output handles: one for each schema property */}\n {hasMultiOutput ? (\n <>\n {/* Full output handle (backward compat) */}\n <Handle\n type=\"source\"\n position={Position.Right}\n id=\"output\"\n className=\"w-3 h-3 !bg-pink-500\"\n style={{ top: \"50%\" }}\n title=\"Full JSON output\"\n />\n {/* Individual property handles */}\n {outputProperties.map(([key, prop], index) => (\n <Handle\n key={key}\n type=\"source\"\n position={Position.Right}\n id={`output.${key}`}\n className=\"w-2.5 h-2.5 !bg-pink-400\"\n style={{\n top: `${70 + index * 14}%`,\n }}\n title={`${key}: ${prop.description || prop.type}`}\n />\n ))}\n </>\n ) : (\n <Handle type=\"source\" position={Position.Right} className=\"w-3 h-3 !bg-pink-500\" />\n )}\n </div>\n );\n});\n\nexport const nodeTypes = {\n generator: GeneratorNode,\n transform: TransformNode,\n save: SaveNode,\n input: InputNode,\n vision: VisionNode,\n text: TextNode,\n};\n","import { useCallback, useMemo } from \"react\";\nimport ReactFlow, {\n Background,\n Controls,\n MiniMap,\n MarkerType,\n type Connection,\n type NodeMouseHandler,\n type OnNodesChange,\n type OnEdgesChange,\n type DefaultEdgeOptions,\n applyNodeChanges,\n applyEdgeChanges,\n} from \"reactflow\";\nimport \"reactflow/dist/style.css\";\nimport type { GeneratorNodeData } from \"@teamflojo/floimg-studio-shared\";\nimport { useWorkflowStore } from \"../stores/workflowStore\";\nimport { nodeTypes } from \"./nodeTypes\";\n\n// Default edge styling with arrows to show direction\nconst defaultEdgeOptions: DefaultEdgeOptions = {\n type: \"smoothstep\",\n animated: false,\n markerEnd: {\n type: MarkerType.ArrowClosed,\n color: \"#64748b\",\n width: 20,\n height: 20,\n },\n style: {\n stroke: \"#64748b\",\n strokeWidth: 2,\n },\n // Make edges easier to select\n interactionWidth: 20,\n};\n\nexport function WorkflowEditor() {\n const nodes = useWorkflowStore((s) => s.nodes);\n const edges = useWorkflowStore((s) => s.edges);\n const setNodes = useWorkflowStore((s) => s.setNodes);\n const setEdges = useWorkflowStore((s) => s.setEdges);\n const addEdge = useWorkflowStore((s) => s.addEdge);\n const setSelectedNode = useWorkflowStore((s) => s.setSelectedNode);\n\n // Memoize nodeTypes to prevent React Flow warning during HMR\n // The nodeTypes object is defined outside, but HMR can cause module re-evaluation\n const memoizedNodeTypes = useMemo(() => nodeTypes, []);\n\n // Validate connections based on node types\n const isValidConnection = useCallback(\n (connection: Connection) => {\n const { source, target, targetHandle } = connection;\n if (!source || !target) return false;\n\n const sourceNode = nodes.find((n) => n.id === source);\n const targetNode = nodes.find((n) => n.id === target);\n\n if (!sourceNode || !targetNode) return false;\n\n // Rule 1: Cannot connect FROM a save node (no output)\n if (sourceNode.type === \"save\") return false;\n\n // Rule 2: Cannot connect TO a generator UNLESS it has specific input handles\n // AI generators have \"text\" (for prompts) and \"references\" (for reference images) handles\n if (targetNode.type === \"generator\") {\n const data = targetNode.data as GeneratorNodeData;\n // Allow connections to text handle if it's an AI generator\n if (targetHandle === \"text\" && data.isAI) return true;\n // Allow connections to references handle if it accepts reference images\n if (targetHandle === \"references\" && data.acceptsReferenceImages) return true;\n // Block all other connections to generators\n return false;\n }\n\n // Rule 3: Cannot connect TO an input node (no input port)\n if (targetNode.type === \"input\") return false;\n\n // Rule 4: No self-connections\n if (source === target) return false;\n\n // Note: We allow replacing existing connections - handled in onConnect\n return true;\n },\n [nodes]\n );\n\n const onNodesChange: OnNodesChange = useCallback(\n (changes) => {\n setNodes(applyNodeChanges(changes, nodes));\n },\n [nodes, setNodes]\n );\n\n const onEdgesChange: OnEdgesChange = useCallback(\n (changes) => {\n setEdges(applyEdgeChanges(changes, edges));\n },\n [edges, setEdges]\n );\n\n const onConnect = useCallback(\n (connection: Connection) => {\n // \"references\" handles accept multiple connections (for reference images)\n // All other handles (text, image, default) are single-connection and auto-replace\n const isMultiConnectionHandle = connection.targetHandle === \"references\";\n\n if (!isMultiConnectionHandle) {\n // Remove any existing connection to the same target handle before adding new one\n // Handle edge creation inconsistencies from AI generation or YAML import\n const edgesToRemove = edges.filter((e) => {\n if (e.target !== connection.target) return false;\n\n // Exact handle match (including both being null/undefined)\n const existingHandle = e.targetHandle || null;\n const newHandle = connection.targetHandle || null;\n if (existingHandle === newHandle) return true;\n\n // For \"text\" or \"image\" handle connections, also remove edges with no targetHandle\n // These are the primary single-input handles that should auto-replace\n if (\n (connection.targetHandle === \"text\" || connection.targetHandle === \"image\") &&\n !e.targetHandle\n ) {\n return true;\n }\n\n // If connecting to default handle (no targetHandle), remove edges to \"image\" handle\n // since that's the main input for transforms\n if (!connection.targetHandle && e.targetHandle === \"image\") {\n return true;\n }\n\n return false;\n });\n\n if (edgesToRemove.length > 0) {\n const removeIds = new Set(edgesToRemove.map((e) => e.id));\n setEdges(edges.filter((e) => !removeIds.has(e.id)));\n }\n }\n addEdge(connection);\n },\n [addEdge, edges, setEdges]\n );\n\n const onNodeClick: NodeMouseHandler = useCallback(\n (_event, node) => {\n setSelectedNode(node.id);\n },\n [setSelectedNode]\n );\n\n const onPaneClick = useCallback(() => {\n setSelectedNode(null);\n }, [setSelectedNode]);\n\n return (\n <div className=\"h-full w-full\">\n <ReactFlow\n nodes={nodes}\n edges={edges}\n onNodesChange={onNodesChange}\n onEdgesChange={onEdgesChange}\n onConnect={onConnect}\n onNodeClick={onNodeClick}\n onPaneClick={onPaneClick}\n nodeTypes={memoizedNodeTypes}\n defaultEdgeOptions={defaultEdgeOptions}\n isValidConnection={isValidConnection}\n nodesDraggable={true}\n nodesConnectable={true}\n elementsSelectable={true}\n edgesFocusable={true}\n deleteKeyCode={[\"Backspace\", \"Delete\"]}\n proOptions={{ hideAttribution: true }}\n fitView\n snapToGrid\n snapGrid={[15, 15]}\n >\n <Background />\n <Controls />\n <MiniMap nodeStrokeWidth={3} zoomable pannable />\n </ReactFlow>\n </div>\n );\n}\n","import { useState, useEffect } from \"react\";\nimport { listUploads, deleteUpload, getUploadBlobUrl, type UploadInfo } from \"../api/client\";\n\ninterface UploadGalleryProps {\n onSelect?: (upload: UploadInfo) => void;\n}\n\nexport function UploadGallery({ onSelect }: UploadGalleryProps) {\n const [uploads, setUploads] = useState<UploadInfo[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n const fetchUploads = async () => {\n try {\n setLoading(true);\n const data = await listUploads();\n setUploads(data);\n setError(null);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to load uploads\");\n } finally {\n setLoading(false);\n }\n };\n\n useEffect(() => {\n fetchUploads();\n }, []);\n\n const handleDelete = async (id: string, e: React.MouseEvent) => {\n e.stopPropagation();\n if (!confirm(\"Delete this upload?\")) return;\n\n try {\n await deleteUpload(id);\n setUploads((prev) => prev.filter((u) => u.id !== id));\n } catch (err) {\n console.error(\"Failed to delete:\", err);\n }\n };\n\n const formatSize = (bytes: number) => {\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\n if (loading) {\n return (\n <div className=\"p-4 text-center text-gray-500 dark:text-zinc-400\">Loading uploads...</div>\n );\n }\n\n if (error) {\n return (\n <div className=\"p-4 text-center text-red-500 dark:text-red-400\">\n {error}\n <button\n onClick={fetchUploads}\n className=\"ml-2 text-teal-500 dark:text-teal-400 hover:underline\"\n >\n Retry\n </button>\n </div>\n );\n }\n\n if (uploads.length === 0) {\n return (\n <div className=\"p-4 text-center text-gray-500 dark:text-zinc-400\">\n No uploads yet. Drag an image onto an Input node to upload.\n </div>\n );\n }\n\n return (\n <div className=\"p-2\">\n <div className=\"grid grid-cols-2 gap-2\">\n {uploads.map((upload) => (\n <div\n key={upload.id}\n className=\"relative group rounded border border-gray-200 dark:border-zinc-700 overflow-hidden cursor-pointer hover:border-amber-400 dark:hover:border-amber-500 transition-colors\"\n onClick={() => onSelect?.(upload)}\n >\n <img\n src={getUploadBlobUrl(upload.id)}\n alt={upload.filename}\n className=\"w-full h-20 object-cover\"\n />\n <div className=\"absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center\">\n <button\n onClick={(e) => handleDelete(upload.id, e)}\n className=\"p-1 bg-red-500 rounded text-white text-xs hover:bg-red-600\"\n >\n Delete\n </button>\n </div>\n <div className=\"p-1 text-xs truncate bg-white dark:bg-zinc-800 text-gray-800 dark:text-zinc-200\">\n {upload.filename}\n </div>\n <div className=\"px-1 pb-1 text-xs text-gray-400 dark:text-zinc-500 bg-white dark:bg-zinc-800\">\n {formatSize(upload.size)}\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n}\n","import { useEffect, useState } from \"react\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport type { NodeDefinition } from \"@teamflojo/floimg-studio-shared\";\nimport { getGenerators, getTransforms, getTextProviders, getVisionProviders } from \"../api/client\";\nimport { useWorkflowStore } from \"../stores/workflowStore\";\nimport { UploadGallery } from \"./UploadGallery\";\n\nexport function NodePalette() {\n const setGenerators = useWorkflowStore((s) => s.setGenerators);\n const setTransforms = useWorkflowStore((s) => s.setTransforms);\n const setTextProviders = useWorkflowStore((s) => s.setTextProviders);\n const setVisionProviders = useWorkflowStore((s) => s.setVisionProviders);\n const generators = useWorkflowStore((s) => s.generators);\n const transforms = useWorkflowStore((s) => s.transforms);\n const textProviders = useWorkflowStore((s) => s.textProviders);\n const visionProviders = useWorkflowStore((s) => s.visionProviders);\n const addNode = useWorkflowStore((s) => s.addNode);\n const [showUploads, setShowUploads] = useState(false);\n\n // Fetch node definitions\n const { data: fetchedGenerators } = useQuery({\n queryKey: [\"generators\"],\n queryFn: getGenerators,\n });\n\n const { data: fetchedTransforms } = useQuery({\n queryKey: [\"transforms\"],\n queryFn: getTransforms,\n });\n\n const { data: fetchedTextProviders } = useQuery({\n queryKey: [\"textProviders\"],\n queryFn: getTextProviders,\n });\n\n const { data: fetchedVisionProviders } = useQuery({\n queryKey: [\"visionProviders\"],\n queryFn: getVisionProviders,\n });\n\n useEffect(() => {\n if (fetchedGenerators) setGenerators(fetchedGenerators);\n }, [fetchedGenerators, setGenerators]);\n\n useEffect(() => {\n if (fetchedTransforms) setTransforms(fetchedTransforms);\n }, [fetchedTransforms, setTransforms]);\n\n useEffect(() => {\n if (fetchedTextProviders) setTextProviders(fetchedTextProviders);\n }, [fetchedTextProviders, setTextProviders]);\n\n useEffect(() => {\n if (fetchedVisionProviders) setVisionProviders(fetchedVisionProviders);\n }, [fetchedVisionProviders, setVisionProviders]);\n\n const handleDragStart = (e: React.DragEvent, definition: NodeDefinition) => {\n e.dataTransfer.setData(\"application/json\", JSON.stringify(definition));\n e.dataTransfer.effectAllowed = \"move\";\n };\n\n const handleDoubleClick = (definition: NodeDefinition) => {\n // Add node at center of canvas\n addNode(definition, { x: 250, y: 150 + Math.random() * 100 });\n };\n\n // Input node definition (special case - for uploaded images)\n const inputDefinition: NodeDefinition = {\n id: \"input:upload\",\n type: \"input\",\n name: \"upload\",\n label: \"Upload Image\",\n description: \"Use an uploaded image\",\n category: \"Input\",\n params: {\n type: \"object\",\n properties: {},\n },\n };\n\n // Save node definition (special case)\n const saveDefinition: NodeDefinition = {\n id: \"save:filesystem\",\n type: \"save\",\n name: \"save\",\n label: \"Save\",\n description: \"Save image to file\",\n category: \"Output\",\n params: {\n type: \"object\",\n properties: {\n destination: {\n type: \"string\",\n title: \"Destination\",\n default: \"./output/image.png\",\n },\n provider: {\n type: \"string\",\n default: \"filesystem\",\n },\n },\n },\n };\n\n // Group generators by category\n const generatorsByCategory = generators.reduce(\n (acc, g) => {\n const cat = g.category || \"Other\";\n if (!acc[cat]) acc[cat] = [];\n acc[cat].push(g);\n return acc;\n },\n {} as Record<string, NodeDefinition[]>\n );\n\n // Group transforms by category\n const transformsByCategory = transforms.reduce(\n (acc, t) => {\n const cat = t.category || \"Other\";\n if (!acc[cat]) acc[cat] = [];\n acc[cat].push(t);\n return acc;\n },\n {} as Record<string, NodeDefinition[]>\n );\n\n return (\n <div className=\"w-64 bg-gray-50 dark:bg-zinc-800 border-r border-gray-200 dark:border-zinc-700 overflow-y-auto\">\n <div className=\"p-4\">\n <h2 className=\"text-lg font-semibold text-gray-800 dark:text-white mb-4\">Nodes</h2>\n\n {/* Input */}\n <div className=\"mb-6\">\n <div className=\"flex items-center justify-between mb-2\">\n <h3 className=\"text-sm font-medium text-amber-600 dark:text-amber-400 uppercase tracking-wide\">\n Input\n </h3>\n <button\n onClick={() => setShowUploads(!showUploads)}\n className=\"text-xs text-amber-600 dark:text-amber-400 hover:text-amber-700 dark:hover:text-amber-300\"\n >\n {showUploads ? \"Hide\" : \"Browse\"} Uploads\n </button>\n </div>\n <div\n draggable\n onDragStart={(e) => handleDragStart(e, inputDefinition)}\n onDoubleClick={() => handleDoubleClick(inputDefinition)}\n className=\"px-3 py-2 bg-amber-50 dark:bg-amber-900/30 border border-amber-200 dark:border-amber-700 rounded cursor-grab active:cursor-grabbing hover:bg-amber-100 dark:hover:bg-amber-900/50 transition-colors\"\n >\n <div className=\"text-sm font-medium text-amber-700 dark:text-amber-300\">\n Upload Image\n </div>\n <div className=\"text-xs text-gray-500 dark:text-zinc-400\">Start with your image</div>\n </div>\n {showUploads && (\n <div className=\"mt-2 border border-amber-200 dark:border-amber-700 rounded bg-white dark:bg-zinc-900 max-h-64 overflow-y-auto\">\n <UploadGallery />\n </div>\n )}\n </div>\n\n {/* Generators */}\n <div className=\"mb-6\">\n <h3 className=\"text-sm font-medium text-blue-600 dark:text-blue-400 uppercase tracking-wide mb-2\">\n Generators\n </h3>\n {Object.entries(generatorsByCategory).map(([category, nodes]) => (\n <div key={category} className=\"mb-3\">\n <div className=\"text-xs text-gray-500 dark:text-zinc-400 mb-1\">{category}</div>\n {nodes.map((def) => (\n <div\n key={def.id}\n draggable\n onDragStart={(e) => handleDragStart(e, def)}\n onDoubleClick={() => handleDoubleClick(def)}\n className=\"px-3 py-2 bg-blue-50 dark:bg-blue-900/30 border border-blue-200 dark:border-blue-700 rounded mb-1 cursor-grab active:cursor-grabbing hover:bg-blue-100 dark:hover:bg-blue-900/50 transition-colors\"\n >\n <div className=\"text-sm font-medium text-blue-700 dark:text-blue-300\">\n {def.label}\n </div>\n {def.description && (\n <div className=\"text-xs text-gray-500 dark:text-zinc-400 truncate\">\n {def.description}\n </div>\n )}\n </div>\n ))}\n </div>\n ))}\n </div>\n\n {/* Transforms */}\n <div className=\"mb-6\">\n <h3 className=\"text-sm font-medium text-teal-600 dark:text-teal-400 uppercase tracking-wide mb-2\">\n Transforms\n </h3>\n {Object.entries(transformsByCategory).map(([category, nodes]) => (\n <div key={category} className=\"mb-3\">\n <div className=\"text-xs text-gray-500 dark:text-zinc-400 mb-1\">{category}</div>\n {nodes.map((def) => (\n <div\n key={def.id}\n draggable\n onDragStart={(e) => handleDragStart(e, def)}\n onDoubleClick={() => handleDoubleClick(def)}\n className=\"px-3 py-2 bg-teal-50 dark:bg-teal-900/30 border border-teal-200 dark:border-teal-700 rounded mb-1 cursor-grab active:cursor-grabbing hover:bg-teal-100 dark:hover:bg-teal-900/50 transition-colors\"\n >\n <div className=\"text-sm font-medium text-teal-700 dark:text-teal-300\">\n {def.label}\n </div>\n {def.description && (\n <div className=\"text-xs text-gray-500 dark:text-zinc-400 truncate\">\n {def.description}\n </div>\n )}\n </div>\n ))}\n </div>\n ))}\n </div>\n\n {/* AI Text */}\n {textProviders.length > 0 && (\n <div className=\"mb-6\">\n <h3 className=\"text-sm font-medium text-pink-600 dark:text-pink-400 uppercase tracking-wide mb-2\">\n AI Text\n </h3>\n {textProviders.map((def) => (\n <div\n key={def.id}\n draggable\n onDragStart={(e) => handleDragStart(e, def)}\n onDoubleClick={() => handleDoubleClick(def)}\n className=\"px-3 py-2 bg-pink-50 dark:bg-pink-900/30 border border-pink-200 dark:border-pink-700 rounded mb-1 cursor-grab active:cursor-grabbing hover:bg-pink-100 dark:hover:bg-pink-900/50 transition-colors\"\n >\n <div className=\"text-sm font-medium text-pink-700 dark:text-pink-300\">\n {def.label}\n </div>\n {def.description && (\n <div className=\"text-xs text-gray-500 dark:text-zinc-400 truncate\">\n {def.description}\n </div>\n )}\n </div>\n ))}\n </div>\n )}\n\n {/* AI Vision */}\n {visionProviders.length > 0 && (\n <div className=\"mb-6\">\n <h3 className=\"text-sm font-medium text-cyan-600 dark:text-cyan-400 uppercase tracking-wide mb-2\">\n AI Vision\n </h3>\n {visionProviders.map((def) => (\n <div\n key={def.id}\n draggable\n onDragStart={(e) => handleDragStart(e, def)}\n onDoubleClick={() => handleDoubleClick(def)}\n className=\"px-3 py-2 bg-cyan-50 dark:bg-cyan-900/30 border border-cyan-200 dark:border-cyan-700 rounded mb-1 cursor-grab active:cursor-grabbing hover:bg-cyan-100 dark:hover:bg-cyan-900/50 transition-colors\"\n >\n <div className=\"text-sm font-medium text-cyan-700 dark:text-cyan-300\">\n {def.label}\n </div>\n {def.description && (\n <div className=\"text-xs text-gray-500 dark:text-zinc-400 truncate\">\n {def.description}\n </div>\n )}\n </div>\n ))}\n </div>\n )}\n\n {/* Output */}\n <div className=\"mb-6\">\n <h3 className=\"text-sm font-medium text-green-600 dark:text-green-400 uppercase tracking-wide mb-2\">\n Output\n </h3>\n <div\n draggable\n onDragStart={(e) => handleDragStart(e, saveDefinition)}\n onDoubleClick={() => handleDoubleClick(saveDefinition)}\n className=\"px-3 py-2 bg-green-50 dark:bg-green-900/30 border border-green-200 dark:border-green-700 rounded cursor-grab active:cursor-grabbing hover:bg-green-100 dark:hover:bg-green-900/50 transition-colors\"\n >\n <div className=\"text-sm font-medium text-green-700 dark:text-green-300\">Save</div>\n <div className=\"text-xs text-gray-500 dark:text-zinc-400\">Save to file</div>\n </div>\n </div>\n </div>\n </div>\n );\n}\n","import { useState } from \"react\";\nimport type {\n GeneratorNodeData,\n TransformNodeData,\n SaveNodeData,\n TextNodeData,\n VisionNodeData,\n ParamField,\n OutputSchema,\n OutputProperty,\n} from \"@teamflojo/floimg-studio-shared\";\nimport { useWorkflowStore } from \"../stores/workflowStore\";\n\nexport function NodeInspector() {\n const selectedNodeId = useWorkflowStore((s) => s.selectedNodeId);\n const nodes = useWorkflowStore((s) => s.nodes);\n const generators = useWorkflowStore((s) => s.generators);\n const transforms = useWorkflowStore((s) => s.transforms);\n const textProviders = useWorkflowStore((s) => s.textProviders);\n const visionProviders = useWorkflowStore((s) => s.visionProviders);\n const updateNodeData = useWorkflowStore((s) => s.updateNodeData);\n const deleteNode = useWorkflowStore((s) => s.deleteNode);\n\n const selectedNode = nodes.find((n) => n.id === selectedNodeId);\n\n if (!selectedNode) {\n return (\n <div className=\"w-80 bg-gray-50 dark:bg-zinc-800 border-l border-gray-200 dark:border-zinc-700 p-4\">\n <div className=\"text-gray-500 dark:text-zinc-400 text-sm\">\n Select a node to edit its properties\n </div>\n </div>\n );\n }\n\n // Get schema for the selected node\n let schema: Record<string, ParamField> | undefined;\n let nodeLabel = \"\";\n\n if (selectedNode.type === \"generator\") {\n const data = selectedNode.data as GeneratorNodeData;\n const def = generators.find((g) => g.name === data.generatorName);\n schema = def?.params?.properties;\n nodeLabel = def?.label || data.generatorName;\n } else if (selectedNode.type === \"transform\") {\n const data = selectedNode.data as TransformNodeData;\n const def = transforms.find((t) => t.name === data.operation);\n schema = def?.params?.properties;\n nodeLabel = def?.label || data.operation;\n } else if (selectedNode.type === \"save\") {\n const data = selectedNode.data as SaveNodeData;\n const isCloudSave = data.provider === \"floimg-cloud\";\n\n nodeLabel = isCloudSave ? \"Save to FloImg Cloud\" : \"Save\";\n schema = {\n destination: {\n type: \"string\",\n title: isCloudSave ? \"Filename\" : \"Destination\",\n description: isCloudSave ? \"Filename for cloud storage\" : \"File path to save the image\",\n },\n };\n } else if (selectedNode.type === \"text\") {\n const data = selectedNode.data as TextNodeData;\n const def = textProviders.find((t) => t.name === data.providerName);\n schema = def?.params?.properties;\n nodeLabel = def?.label || data.providerName;\n } else if (selectedNode.type === \"vision\") {\n const data = selectedNode.data as VisionNodeData;\n const def = visionProviders.find((v) => v.name === data.providerName);\n schema = def?.params?.properties;\n nodeLabel = def?.label || data.providerName;\n }\n\n const handleParamChange = (key: string, value: unknown) => {\n if (selectedNode.type === \"generator\") {\n const data = selectedNode.data as GeneratorNodeData;\n updateNodeData(selectedNode.id, {\n params: { ...data.params, [key]: value },\n });\n } else if (selectedNode.type === \"transform\") {\n const data = selectedNode.data as TransformNodeData;\n updateNodeData(selectedNode.id, {\n params: { ...data.params, [key]: value },\n });\n } else if (selectedNode.type === \"save\") {\n updateNodeData(selectedNode.id, { [key]: value });\n } else if (selectedNode.type === \"text\") {\n const data = selectedNode.data as TextNodeData;\n updateNodeData(selectedNode.id, {\n params: { ...data.params, [key]: value },\n });\n } else if (selectedNode.type === \"vision\") {\n const data = selectedNode.data as VisionNodeData;\n updateNodeData(selectedNode.id, {\n params: { ...data.params, [key]: value },\n });\n }\n };\n\n const getParamValue = (key: string): unknown => {\n if (selectedNode.type === \"generator\") {\n return (selectedNode.data as GeneratorNodeData).params[key];\n } else if (selectedNode.type === \"transform\") {\n return (selectedNode.data as TransformNodeData).params[key];\n } else if (selectedNode.type === \"save\") {\n return (selectedNode.data as SaveNodeData)[key as keyof SaveNodeData];\n } else if (selectedNode.type === \"text\") {\n return (selectedNode.data as TextNodeData).params[key];\n } else if (selectedNode.type === \"vision\") {\n return (selectedNode.data as VisionNodeData).params[key];\n }\n return undefined;\n };\n\n // Determine which fields should be visible based on current parameter values\n const isFieldVisible = (key: string, _field: ParamField): boolean => {\n // For shapes generator, apply conditional visibility\n if (\n selectedNode.type === \"generator\" &&\n (selectedNode.data as GeneratorNodeData).generatorName === \"shapes\"\n ) {\n const shapeType = getParamValue(\"shapeType\") || \"rectangle\";\n const fillType = getParamValue(\"fillType\") || \"solid\";\n\n // Shape-specific parameters\n if (key === \"sides\") return shapeType === \"polygon\";\n if (key === \"points\" || key === \"innerRadius\") return shapeType === \"star\";\n if (key === \"cornerRadius\") return shapeType === \"rectangle\";\n\n // Fill-specific parameters\n if (key === \"fillColor\") return fillType === \"solid\";\n if (\n key === \"gradientType\" ||\n key === \"gradientColor1\" ||\n key === \"gradientColor2\" ||\n key === \"gradientAngle\"\n ) {\n return fillType === \"gradient\";\n }\n if (\n key === \"patternType\" ||\n key === \"patternColor\" ||\n key === \"patternBackground\" ||\n key === \"patternScale\"\n ) {\n return fillType === \"pattern\";\n }\n }\n\n return true;\n };\n\n return (\n <div className=\"w-80 bg-gray-50 dark:bg-zinc-800 border-l border-gray-200 dark:border-zinc-700 overflow-y-auto\">\n <div className=\"p-4\">\n <div className=\"flex items-center justify-between mb-4\">\n <h2 className=\"text-lg font-semibold text-gray-800 dark:text-white\">{nodeLabel}</h2>\n <button\n onClick={() => deleteNode(selectedNode.id)}\n className=\"text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300 text-sm\"\n >\n Delete\n </button>\n </div>\n\n <div className=\"space-y-4\">\n {schema &&\n Object.entries(schema)\n .filter(([key, field]) => isFieldVisible(key, field))\n .map(([key, field]) => (\n <FieldEditor\n key={key}\n name={key}\n field={field}\n value={getParamValue(key)}\n onChange={(value) => handleParamChange(key, value)}\n />\n ))}\n </div>\n\n {/* Output Schema Editor for text/vision nodes */}\n {(selectedNode.type === \"text\" || selectedNode.type === \"vision\") && (\n <OutputSchemaEditor\n nodeId={selectedNode.id}\n outputSchema={(selectedNode.data as TextNodeData | VisionNodeData).outputSchema}\n updateNodeData={updateNodeData}\n />\n )}\n </div>\n </div>\n );\n}\n\ninterface FieldEditorProps {\n name: string;\n field: ParamField;\n value: unknown;\n onChange: (value: unknown) => void;\n}\n\nfunction FieldEditor({ name, field, value, onChange }: FieldEditorProps) {\n const label = field.title || name;\n const inputClasses =\n \"w-full px-3 py-2 border border-gray-300 dark:border-zinc-600 rounded-md shadow-sm focus:ring-teal-500 focus:border-teal-500 bg-white dark:bg-zinc-900 text-gray-900 dark:text-zinc-100\";\n\n // Enum -> select dropdown\n if (field.enum) {\n return (\n <div>\n <label className=\"block text-sm font-medium text-gray-700 dark:text-zinc-300 mb-1\">\n {label}\n </label>\n <select\n value={String(value || \"\")}\n onChange={(e) => onChange(e.target.value)}\n className={inputClasses}\n >\n <option value=\"\">Select...</option>\n {field.enum.map((opt) => (\n <option key={opt} value={opt}>\n {opt}\n </option>\n ))}\n </select>\n {field.description && (\n <p className=\"mt-1 text-xs text-gray-500 dark:text-zinc-400\">{field.description}</p>\n )}\n </div>\n );\n }\n\n // Number input\n if (field.type === \"number\") {\n return (\n <div>\n <label className=\"block text-sm font-medium text-gray-700 dark:text-zinc-300 mb-1\">\n {label}\n </label>\n <input\n type=\"number\"\n value={value !== undefined ? Number(value) : \"\"}\n onChange={(e) => onChange(Number(e.target.value))}\n min={field.minimum}\n max={field.maximum}\n className={inputClasses}\n />\n {field.description && (\n <p className=\"mt-1 text-xs text-gray-500 dark:text-zinc-400\">{field.description}</p>\n )}\n </div>\n );\n }\n\n // Boolean -> checkbox\n if (field.type === \"boolean\") {\n return (\n <div className=\"flex items-center gap-2\">\n <input\n type=\"checkbox\"\n checked={Boolean(value)}\n onChange={(e) => onChange(e.target.checked)}\n className=\"h-4 w-4 text-teal-600 focus:ring-teal-500 border-gray-300 dark:border-zinc-600 rounded bg-white dark:bg-zinc-900\"\n />\n <label className=\"text-sm font-medium text-gray-700 dark:text-zinc-300\">{label}</label>\n </div>\n );\n }\n\n // Color picker for color-related fields\n if (name.toLowerCase().includes(\"color\") && typeof value === \"string\" && value.startsWith(\"#\")) {\n return (\n <div>\n <label className=\"block text-sm font-medium text-gray-700 dark:text-zinc-300 mb-1\">\n {label}\n </label>\n <div className=\"flex gap-2\">\n <input\n type=\"color\"\n value={String(value || \"#000000\")}\n onChange={(e) => onChange(e.target.value)}\n className=\"h-10 w-14 p-1 border border-gray-300 dark:border-zinc-600 rounded\"\n />\n <input\n type=\"text\"\n value={String(value || \"\")}\n onChange={(e) => onChange(e.target.value)}\n className={inputClasses + \" flex-1\"}\n />\n </div>\n </div>\n );\n }\n\n // Default: text input (also for objects as JSON)\n if (field.type === \"object\") {\n return (\n <div>\n <label className=\"block text-sm font-medium text-gray-700 dark:text-zinc-300 mb-1\">\n {label}\n </label>\n <textarea\n value={value ? JSON.stringify(value, null, 2) : \"{}\"}\n onChange={(e) => {\n try {\n onChange(JSON.parse(e.target.value));\n } catch {\n // Invalid JSON, ignore\n }\n }}\n rows={4}\n className={inputClasses + \" font-mono text-xs\"}\n />\n {field.description && (\n <p className=\"mt-1 text-xs text-gray-500 dark:text-zinc-400\">{field.description}</p>\n )}\n </div>\n );\n }\n\n // String input (default)\n return (\n <div>\n <label className=\"block text-sm font-medium text-gray-700 dark:text-zinc-300 mb-1\">\n {label}\n </label>\n {name === \"prompt\" || name === \"code\" || name === \"text\" ? (\n <textarea\n value={String(value || \"\")}\n onChange={(e) => onChange(e.target.value)}\n rows={3}\n className={inputClasses}\n />\n ) : (\n <input\n type=\"text\"\n value={String(value || \"\")}\n onChange={(e) => onChange(e.target.value)}\n className={inputClasses}\n />\n )}\n {field.description && (\n <p className=\"mt-1 text-xs text-gray-500 dark:text-zinc-400\">{field.description}</p>\n )}\n </div>\n );\n}\n\n// ============================================================================\n// Output Schema Editor for text/vision nodes\n// ============================================================================\n\ninterface OutputSchemaEditorProps {\n nodeId: string;\n outputSchema?: OutputSchema;\n updateNodeData: (id: string, data: Partial<TextNodeData | VisionNodeData>) => void;\n}\n\nfunction OutputSchemaEditor({ nodeId, outputSchema, updateNodeData }: OutputSchemaEditorProps) {\n const [newPropertyName, setNewPropertyName] = useState(\"\");\n\n const properties = outputSchema?.properties || {};\n const propertyEntries = Object.entries(properties);\n\n const handleAddProperty = () => {\n if (!newPropertyName.trim()) return;\n\n const newSchema: OutputSchema = {\n type: \"object\",\n properties: {\n ...properties,\n [newPropertyName.trim()]: { type: \"string\" },\n },\n };\n\n updateNodeData(nodeId, { outputSchema: newSchema });\n setNewPropertyName(\"\");\n };\n\n const handleRemoveProperty = (key: string) => {\n const newProperties = { ...properties };\n delete newProperties[key];\n\n if (Object.keys(newProperties).length === 0) {\n updateNodeData(nodeId, { outputSchema: undefined });\n } else {\n updateNodeData(nodeId, {\n outputSchema: { type: \"object\", properties: newProperties },\n });\n }\n };\n\n const handleTypeChange = (key: string, type: OutputProperty[\"type\"]) => {\n updateNodeData(nodeId, {\n outputSchema: {\n type: \"object\",\n properties: {\n ...properties,\n [key]: { ...properties[key], type },\n },\n },\n });\n };\n\n const handleDescriptionChange = (key: string, description: string) => {\n updateNodeData(nodeId, {\n outputSchema: {\n type: \"object\",\n properties: {\n ...properties,\n [key]: { ...properties[key], description: description || undefined },\n },\n },\n });\n };\n\n return (\n <div className=\"mt-6 pt-4 border-t border-gray-200 dark:border-zinc-700\">\n <div className=\"flex items-center justify-between mb-3\">\n <h3 className=\"text-sm font-medium text-gray-700 dark:text-zinc-300\">Output Schema</h3>\n <span className=\"text-xs text-gray-500 dark:text-zinc-500\">\n {propertyEntries.length > 0\n ? `${propertyEntries.length} output${propertyEntries.length > 1 ? \"s\" : \"\"}`\n : \"No outputs defined\"}\n </span>\n </div>\n\n <p className=\"text-xs text-gray-500 dark:text-zinc-400 mb-3\">\n Define output properties to enable connecting individual JSON fields to other nodes.\n </p>\n\n {/* Existing properties */}\n {propertyEntries.length > 0 && (\n <div className=\"space-y-2 mb-3\">\n {propertyEntries.map(([key, prop]) => (\n <div\n key={key}\n className=\"flex items-center gap-2 p-2 bg-pink-50 dark:bg-pink-900/20 rounded border border-pink-200 dark:border-pink-800\"\n >\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-medium text-pink-700 dark:text-pink-300 truncate\">\n {key}\n </span>\n <select\n value={prop.type}\n onChange={(e) =>\n handleTypeChange(key, e.target.value as OutputProperty[\"type\"])\n }\n className=\"text-xs px-1.5 py-0.5 rounded border border-pink-300 dark:border-pink-700 bg-white dark:bg-zinc-800 text-gray-700 dark:text-zinc-300\"\n >\n <option value=\"string\">string</option>\n <option value=\"number\">number</option>\n <option value=\"boolean\">boolean</option>\n <option value=\"object\">object</option>\n <option value=\"array\">array</option>\n </select>\n </div>\n <input\n type=\"text\"\n value={prop.description || \"\"}\n onChange={(e) => handleDescriptionChange(key, e.target.value)}\n placeholder=\"Description (optional)\"\n className=\"mt-1 w-full text-xs px-2 py-1 rounded border border-pink-200 dark:border-pink-700 bg-white dark:bg-zinc-800 text-gray-600 dark:text-zinc-400 placeholder-gray-400 dark:placeholder-zinc-500\"\n />\n </div>\n <button\n onClick={() => handleRemoveProperty(key)}\n className=\"text-pink-500 hover:text-pink-700 dark:text-pink-400 dark:hover:text-pink-300 p-1\"\n title=\"Remove property\"\n >\n <svg className=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </button>\n </div>\n ))}\n </div>\n )}\n\n {/* Add new property */}\n <div className=\"flex gap-2\">\n <input\n type=\"text\"\n value={newPropertyName}\n onChange={(e) => setNewPropertyName(e.target.value)}\n onKeyDown={(e) => e.key === \"Enter\" && handleAddProperty()}\n placeholder=\"Property name...\"\n className=\"flex-1 px-2 py-1.5 text-sm border border-gray-300 dark:border-zinc-600 rounded bg-white dark:bg-zinc-900 text-gray-900 dark:text-zinc-100 placeholder-gray-400 dark:placeholder-zinc-500\"\n />\n <button\n onClick={handleAddProperty}\n disabled={!newPropertyName.trim()}\n className=\"px-3 py-1.5 text-sm font-medium text-white bg-pink-500 rounded hover:bg-pink-600 disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n Add\n </button>\n </div>\n\n {/* Hint about usage */}\n {propertyEntries.length > 0 && (\n <p className=\"mt-3 text-xs text-gray-500 dark:text-zinc-500\">\n Connect from the small pink handles on the right of the node to route individual\n properties.\n </p>\n )}\n </div>\n );\n}\n","import type { Node, Edge } from \"reactflow\";\nimport type {\n GeneratorNodeData,\n TransformNodeData,\n SaveNodeData,\n InputNodeData,\n VisionNodeData,\n TextNodeData,\n} from \"@teamflojo/floimg-studio-shared\";\n\ntype NodeData =\n | GeneratorNodeData\n | TransformNodeData\n | SaveNodeData\n | InputNodeData\n | VisionNodeData\n | TextNodeData;\n\n/**\n * Topologically sort nodes based on edges (dependencies)\n * Returns nodes in execution order\n */\nfunction topologicalSort(nodes: Node<NodeData>[], edges: Edge[]): Node<NodeData>[] {\n const nodeMap = new Map(nodes.map((n) => [n.id, n]));\n const inDegree = new Map<string, number>();\n const adjacency = new Map<string, string[]>();\n\n // Initialize\n for (const node of nodes) {\n inDegree.set(node.id, 0);\n adjacency.set(node.id, []);\n }\n\n // Build graph\n for (const edge of edges) {\n const targets = adjacency.get(edge.source) || [];\n targets.push(edge.target);\n adjacency.set(edge.source, targets);\n inDegree.set(edge.target, (inDegree.get(edge.target) || 0) + 1);\n }\n\n // Find nodes with no incoming edges (sources)\n const queue: string[] = [];\n for (const [id, degree] of inDegree) {\n if (degree === 0) {\n queue.push(id);\n }\n }\n\n // Process in order\n const sorted: Node<NodeData>[] = [];\n while (queue.length > 0) {\n const id = queue.shift()!;\n const node = nodeMap.get(id);\n if (node) {\n sorted.push(node);\n }\n\n const neighbors = adjacency.get(id) || [];\n for (const neighbor of neighbors) {\n const newDegree = (inDegree.get(neighbor) || 1) - 1;\n inDegree.set(neighbor, newDegree);\n if (newDegree === 0) {\n queue.push(neighbor);\n }\n }\n }\n\n return sorted;\n}\n\n/**\n * Get the variable name for a node\n */\nfunction getNodeVarName(node: Node<NodeData>): string {\n const type = node.type || \"node\";\n const suffix = node.id.replace(/[^a-zA-Z0-9]/g, \"_\");\n return `${type}_${suffix}`;\n}\n\n/**\n * Stringify a value for code generation\n */\nfunction stringify(value: unknown): string {\n if (typeof value === \"string\") {\n // Escape special characters and use template literal if multiline\n if (value.includes(\"\\n\")) {\n return \"`\" + value.replace(/`/g, \"\\\\`\").replace(/\\$/g, \"\\\\$\") + \"`\";\n }\n return JSON.stringify(value);\n }\n return JSON.stringify(value, null, 2);\n}\n\n/**\n * Generate JavaScript code for a single node\n */\nfunction generateNodeCode(\n node: Node<NodeData>,\n edges: Edge[],\n nodeVarNames: Map<string, string>\n): { code: string; imports: string[] } {\n const varName = nodeVarNames.get(node.id)!;\n const imports: string[] = [];\n\n // Find input node (source of edge pointing to this node)\n const inputEdge = edges.find((e) => e.target === node.id);\n const inputVarName = inputEdge ? nodeVarNames.get(inputEdge.source) : null;\n\n switch (node.type) {\n case \"generator\": {\n const data = node.data as GeneratorNodeData;\n imports.push(data.generatorName);\n\n const params = data.params || {};\n const paramStr = Object.entries(params)\n .filter(([, v]) => v !== undefined && v !== \"\")\n .map(([k, v]) => ` ${k}: ${stringify(v)}`)\n .join(\",\\n\");\n\n return {\n code: `// Generate image using ${data.generatorName}\nconst ${varName} = await ${data.generatorName}({\n${paramStr}\n});`,\n imports,\n };\n }\n\n case \"input\": {\n return {\n code: `// Load input image\nconst ${varName} = await flo.loadImage(\"./input.png\");`,\n imports: [],\n };\n }\n\n case \"transform\": {\n const data = node.data as TransformNodeData;\n const params = data.params || {};\n const paramStr = Object.entries(params)\n .filter(([, v]) => v !== undefined && v !== \"\")\n .map(([k, v]) => `${k}: ${stringify(v)}`)\n .join(\", \");\n\n const input = inputVarName || \"image\";\n return {\n code: `// Apply ${data.operation} transform\nconst ${varName} = await flo.transform(${input}, \"${data.operation}\"${paramStr ? `, { ${paramStr} }` : \"\"});`,\n imports: [],\n };\n }\n\n case \"vision\": {\n const data = node.data as VisionNodeData;\n imports.push(data.providerName);\n\n const params = data.params || {};\n const input = inputVarName || \"image\";\n const paramStr = Object.entries(params)\n .filter(([, v]) => v !== undefined && v !== \"\")\n .map(([k, v]) => ` ${k}: ${stringify(v)}`)\n .join(\",\\n\");\n\n return {\n code: `// Analyze image with ${data.providerName}\nconst ${varName} = await ${data.providerName}.analyze(${input}, {\n${paramStr}\n});`,\n imports,\n };\n }\n\n case \"text\": {\n const data = node.data as TextNodeData;\n imports.push(data.providerName);\n\n const params = data.params || {};\n const paramStr = Object.entries(params)\n .filter(([, v]) => v !== undefined && v !== \"\")\n .map(([k, v]) => ` ${k}: ${stringify(v)}`)\n .join(\",\\n\");\n\n return {\n code: `// Generate text with ${data.providerName}\nconst ${varName} = await ${data.providerName}.generate({\n${paramStr}\n});`,\n imports,\n };\n }\n\n case \"save\": {\n const data = node.data as SaveNodeData;\n const input = inputVarName || \"result\";\n return {\n code: `// Save result\nawait flo.save(${input}, ${stringify(data.destination)});`,\n imports: [],\n };\n }\n\n default:\n return {\n code: `// Unknown node type: ${node.type}`,\n imports: [],\n };\n }\n}\n\n/**\n * Generate JavaScript code from workflow nodes and edges\n */\nexport function generateJavaScript(nodes: Node<NodeData>[], edges: Edge[]): string {\n if (nodes.length === 0) {\n return `// Empty workflow\n// Add nodes to your canvas to generate code`;\n }\n\n // Sort nodes topologically\n const sortedNodes = topologicalSort(nodes, edges);\n\n // Generate variable names\n const nodeVarNames = new Map<string, string>();\n for (const node of sortedNodes) {\n nodeVarNames.set(node.id, getNodeVarName(node));\n }\n\n // Generate code for each node\n const allImports = new Set<string>();\n const codeBlocks: string[] = [];\n\n for (const node of sortedNodes) {\n const { code, imports } = generateNodeCode(node, edges, nodeVarNames);\n codeBlocks.push(code);\n for (const imp of imports) {\n allImports.add(imp);\n }\n }\n\n // Build final code\n const importLines: string[] = [];\n if (allImports.size > 0) {\n importLines.push(`import { ${Array.from(allImports).join(\", \")} } from \"@teamflojo/floimg\";`);\n }\n importLines.push(`import * as flo from \"@teamflojo/floimg\";`);\n\n const header = `/**\n * FloImg Workflow\n * Generated by FloImg Studio\n * https://floimg.com\n */\n\n`;\n\n const mainCode = `\nasync function runWorkflow() {\n${codeBlocks\n .map((block) =>\n block\n .split(\"\\n\")\n .map((line) => \" \" + line)\n .join(\"\\n\")\n )\n .join(\"\\n\\n\")}\n}\n\n// Run the workflow\nrunWorkflow().catch(console.error);\n`;\n\n return header + importLines.join(\"\\n\") + \"\\n\" + mainCode;\n}\n","import { useState, useCallback, type DragEvent } from \"react\";\nimport { importYaml, validateYaml } from \"../api/client\";\nimport type { StudioNode, StudioEdge } from \"@teamflojo/floimg-studio-shared\";\n\ninterface ImportModalProps {\n isOpen: boolean;\n onClose: () => void;\n onImport: (nodes: StudioNode[], edges: StudioEdge[], name?: string) => void;\n}\n\ninterface ValidationError {\n message: string;\n line?: number;\n column?: number;\n}\n\nexport function ImportModal({ isOpen, onClose, onImport }: ImportModalProps) {\n const [yamlContent, setYamlContent] = useState(\"\");\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<ValidationError | null>(null);\n const [isDragging, setIsDragging] = useState(false);\n\n const handleImport = useCallback(async () => {\n if (!yamlContent.trim()) {\n setError({ message: \"Please enter or paste YAML content\" });\n return;\n }\n\n setIsLoading(true);\n setError(null);\n\n try {\n const result = await importYaml(yamlContent);\n\n if (result.success) {\n onImport(result.nodes, result.edges, result.name);\n setYamlContent(\"\");\n onClose();\n } else {\n setError({\n message: result.error || \"Import failed\",\n line: result.line,\n column: result.column,\n });\n }\n } catch (err) {\n setError({ message: err instanceof Error ? err.message : \"Import failed\" });\n } finally {\n setIsLoading(false);\n }\n }, [yamlContent, onImport, onClose]);\n\n const handleValidate = useCallback(async () => {\n if (!yamlContent.trim()) {\n setError({ message: \"Please enter or paste YAML content\" });\n return;\n }\n\n setIsLoading(true);\n setError(null);\n\n try {\n const result = await validateYaml(yamlContent);\n\n if (result.valid) {\n setError(null);\n // Show success briefly\n setError({ message: \"Valid YAML!\" });\n setTimeout(() => setError(null), 2000);\n } else if (result.errors.length > 0) {\n setError(result.errors[0]);\n }\n } catch (err) {\n setError({ message: err instanceof Error ? err.message : \"Validation failed\" });\n } finally {\n setIsLoading(false);\n }\n }, [yamlContent]);\n\n const handleFileUpload = useCallback(async (file: File) => {\n if (!file.name.endsWith(\".yaml\") && !file.name.endsWith(\".yml\")) {\n setError({ message: \"Please upload a .yaml or .yml file\" });\n return;\n }\n\n try {\n const text = await file.text();\n setYamlContent(text);\n setError(null);\n } catch {\n setError({ message: \"Failed to read file\" });\n }\n }, []);\n\n const handleDragOver = useCallback((e: DragEvent) => {\n e.preventDefault();\n setIsDragging(true);\n }, []);\n\n const handleDragLeave = useCallback((e: DragEvent) => {\n e.preventDefault();\n setIsDragging(false);\n }, []);\n\n const handleDrop = useCallback(\n (e: DragEvent) => {\n e.preventDefault();\n setIsDragging(false);\n\n const file = e.dataTransfer.files[0];\n if (file) {\n handleFileUpload(file);\n }\n },\n [handleFileUpload]\n );\n\n const handleFileInputChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (file) {\n handleFileUpload(file);\n }\n },\n [handleFileUpload]\n );\n\n if (!isOpen) return null;\n\n return (\n <div className=\"fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50\">\n <div className=\"bg-white dark:bg-zinc-800 rounded-lg shadow-xl max-w-2xl w-full mx-4 max-h-[80vh] flex flex-col\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-gray-200 dark:border-zinc-700\">\n <h3 className=\"text-lg font-semibold text-gray-900 dark:text-white\">Import Workflow</h3>\n <button\n onClick={onClose}\n className=\"text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200\"\n >\n <svg className=\"h-6 w-6\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </button>\n </div>\n\n {/* Content */}\n <div className=\"p-4 flex-1 overflow-auto\">\n <p className=\"text-sm text-gray-600 dark:text-zinc-400 mb-4\">\n Paste YAML content or drag and drop a .yaml file to import a workflow.\n </p>\n\n {/* File drop zone */}\n <div\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n className={`border-2 border-dashed rounded-lg p-4 mb-4 text-center transition-colors ${\n isDragging\n ? \"border-teal-500 bg-teal-50 dark:bg-teal-900/20\"\n : \"border-gray-300 dark:border-zinc-600\"\n }`}\n >\n <input\n type=\"file\"\n accept=\".yaml,.yml\"\n onChange={handleFileInputChange}\n className=\"hidden\"\n id=\"yaml-file-input\"\n />\n <label\n htmlFor=\"yaml-file-input\"\n className=\"cursor-pointer text-sm text-gray-600 dark:text-zinc-400\"\n >\n <svg\n className=\"h-8 w-8 mx-auto mb-2 text-gray-400 dark:text-zinc-500\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n 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 />\n </svg>\n <span className=\"text-teal-600 dark:text-teal-400 hover:underline\">\n Click to upload\n </span>{\" \"}\n or drag and drop\n <br />\n <span className=\"text-xs\">.yaml or .yml files</span>\n </label>\n </div>\n\n {/* YAML textarea */}\n <textarea\n value={yamlContent}\n onChange={(e) => {\n setYamlContent(e.target.value);\n setError(null);\n }}\n placeholder={`name: My Workflow\nsteps:\n - kind: generate\n generator: quickchart\n params:\n type: bar\n data:\n labels: [Q1, Q2, Q3, Q4]\n datasets:\n - label: Revenue\n data: [12, 19, 8, 15]\n out: v0\n\n - kind: transform\n op: resize\n in: v0\n params:\n width: 800\n out: v1`}\n className=\"w-full h-64 p-3 font-mono text-sm bg-gray-100 dark:bg-zinc-900 border border-gray-300 dark:border-zinc-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-teal-500 text-gray-800 dark:text-zinc-200\"\n />\n\n {/* Error/Success message */}\n {error && (\n <div\n className={`mt-4 p-3 rounded-lg text-sm ${\n error.message === \"Valid YAML!\"\n ? \"bg-green-50 dark:bg-green-900/30 text-green-700 dark:text-green-400\"\n : \"bg-red-50 dark:bg-red-900/30 text-red-700 dark:text-red-400\"\n }`}\n >\n <span className=\"font-medium\">{error.message}</span>\n {error.line && (\n <span className=\"ml-2 text-xs\">\n (line {error.line}\n {error.column ? `, column ${error.column}` : \"\"})\n </span>\n )}\n </div>\n )}\n </div>\n\n {/* Footer */}\n <div className=\"flex justify-between items-center px-4 py-3 border-t border-gray-200 dark:border-zinc-700\">\n <span className=\"text-xs text-gray-500 dark:text-zinc-400\">\n Use with floimg CLI: floimg run workflow.yaml\n </span>\n <div className=\"flex gap-2\">\n <button\n onClick={handleValidate}\n disabled={isLoading || !yamlContent.trim()}\n className=\"px-4 py-2 text-sm font-medium text-gray-700 dark:text-zinc-200 bg-white dark:bg-zinc-700 border border-gray-300 dark:border-zinc-600 rounded-md hover:bg-gray-50 dark:hover:bg-zinc-600 disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n Validate\n </button>\n <button\n onClick={handleImport}\n disabled={isLoading || !yamlContent.trim()}\n className=\"px-4 py-2 text-sm font-medium text-white bg-teal-600 rounded-md hover:bg-teal-700 disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2\"\n >\n {isLoading && (\n <svg className=\"animate-spin h-4 w-4\" viewBox=\"0 0 24 24\" fill=\"none\">\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z\"\n />\n </svg>\n )}\n Import\n </button>\n </div>\n </div>\n </div>\n </div>\n );\n}\n","import { useState, useEffect, useCallback, type ReactNode } from \"react\";\nimport { useWorkflowStore } from \"../stores/workflowStore\";\nimport { useSettingsStore } from \"../stores/settingsStore\";\nimport { generateJavaScript } from \"../utils/codeGenerator\";\nimport { ImportModal } from \"./ImportModal\";\nimport type { StudioNode, StudioEdge } from \"@teamflojo/floimg-studio-shared\";\n\ntype ExportTab = \"yaml\" | \"javascript\";\n\n/**\n * Props for the Toolbar component.\n * All props are optional to maintain backward compatibility.\n */\nexport interface ToolbarProps {\n /** Slot rendered after the branding text (e.g., \"Cloud\" badge) */\n brandingSlot?: ReactNode;\n /** Slot rendered before the action buttons (e.g., usage counter) */\n beforeActionsSlot?: ReactNode;\n /** Slot rendered after all action buttons (e.g., auth/user menu) */\n afterActionsSlot?: ReactNode;\n /** Hide the \"by Flojo\" attribution link */\n hideAttribution?: boolean;\n /** Hide the \"My Workflows\" library toggle button (for wrappers providing custom workflow management) */\n hideWorkflowLibrary?: boolean;\n}\n\nexport function Toolbar({\n brandingSlot,\n beforeActionsSlot,\n afterActionsSlot,\n hideAttribution = false,\n hideWorkflowLibrary = false,\n}: ToolbarProps = {}) {\n const execution = useWorkflowStore((s) => s.execution);\n const execute = useWorkflowStore((s) => s.execute);\n const cancelExecution = useWorkflowStore((s) => s.cancelExecution);\n const exportToYaml = useWorkflowStore((s) => s.exportToYaml);\n const importFromYaml = useWorkflowStore((s) => s.importFromYaml);\n const nodes = useWorkflowStore((s) => s.nodes);\n const edges = useWorkflowStore((s) => s.edges);\n const openSettings = useSettingsStore((s) => s.openSettings);\n\n // Workflow persistence state\n const activeWorkflowName = useWorkflowStore((s) => s.activeWorkflowName);\n const hasUnsavedChanges = useWorkflowStore((s) => s.hasUnsavedChanges);\n const saveWorkflow = useWorkflowStore((s) => s.saveWorkflow);\n const toggleLibrary = useWorkflowStore((s) => s.toggleLibrary);\n const setActiveWorkflowName = useWorkflowStore((s) => s.setActiveWorkflowName);\n\n // Node operations\n const selectedNodeId = useWorkflowStore((s) => s.selectedNodeId);\n const duplicateNode = useWorkflowStore((s) => s.duplicateNode);\n\n const [showExport, setShowExport] = useState(false);\n const [showImport, setShowImport] = useState(false);\n const [exportTab, setExportTab] = useState<ExportTab>(\"yaml\");\n const [yamlContent, setYamlContent] = useState(\"\");\n const [jsContent, setJsContent] = useState(\"\");\n const [notification, setNotification] = useState<string | null>(null);\n const [isEditingName, setIsEditingName] = useState(false);\n const [editingName, setEditingName] = useState(\"\");\n\n // Listen for new workflow event\n useEffect(() => {\n const handleNewWorkflow = () => {\n setNotification(\"New workflow created\");\n setTimeout(() => setNotification(null), 2000);\n };\n window.addEventListener(\"new-workflow-created\", handleNewWorkflow);\n return () => window.removeEventListener(\"new-workflow-created\", handleNewWorkflow);\n }, []);\n\n // Handle save with Cmd+S / Ctrl+S\n const handleSave = useCallback(() => {\n if (nodes.length === 0) return;\n saveWorkflow();\n setNotification(\"Saved!\");\n setTimeout(() => setNotification(null), 2000);\n }, [nodes.length, saveWorkflow]);\n\n // Handle inline rename\n const handleStartRename = () => {\n setEditingName(activeWorkflowName);\n setIsEditingName(true);\n };\n\n const handleSaveRename = () => {\n const trimmed = editingName.trim();\n if (trimmed && trimmed !== activeWorkflowName) {\n setActiveWorkflowName(trimmed);\n }\n setIsEditingName(false);\n };\n\n // Handle duplicate with Cmd+D / Ctrl+D\n const handleDuplicate = useCallback(() => {\n if (selectedNodeId) {\n duplicateNode(selectedNodeId);\n }\n }, [selectedNodeId, duplicateNode]);\n\n // Keyboard shortcuts\n useEffect(() => {\n function handleKeyDown(e: KeyboardEvent) {\n if ((e.metaKey || e.ctrlKey) && e.key === \"s\") {\n e.preventDefault();\n handleSave();\n }\n if ((e.metaKey || e.ctrlKey) && e.key === \"d\") {\n e.preventDefault();\n handleDuplicate();\n }\n }\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [handleSave, handleDuplicate]);\n\n const handleExecute = async () => {\n await execute();\n };\n\n const handleExport = async () => {\n const yaml = await exportToYaml();\n setYamlContent(yaml);\n const js = generateJavaScript(nodes, edges);\n setJsContent(js);\n setShowExport(true);\n };\n\n const handleCopy = () => {\n const content = exportTab === \"yaml\" ? yamlContent : jsContent;\n navigator.clipboard.writeText(content);\n };\n\n const handleImport = useCallback(\n (importedNodes: StudioNode[], importedEdges: StudioEdge[], name?: string) => {\n importFromYaml(importedNodes, importedEdges, name);\n setNotification(\"Workflow imported!\");\n setTimeout(() => setNotification(null), 2000);\n },\n [importFromYaml]\n );\n\n return (\n <>\n <div className=\"h-14 bg-white dark:bg-zinc-800 border-b border-gray-200 dark:border-zinc-700 flex items-center justify-between px-4\">\n <div className=\"flex items-center gap-4\">\n {/* My Workflows button - can be hidden when custom workflow management is provided */}\n {!hideWorkflowLibrary && (\n <button\n onClick={toggleLibrary}\n className=\"p-2 text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200 hover:bg-gray-100 dark:hover:bg-zinc-700 rounded-md\"\n title=\"My Workflows\"\n >\n <svg className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 6h16M4 12h16M4 18h7\"\n />\n </svg>\n </button>\n )}\n\n <div className=\"flex items-baseline gap-2\">\n <h1 className=\"text-xl font-bold text-gray-800 dark:text-white\">FloImg Studio</h1>\n {brandingSlot}\n {!hideAttribution && (\n <a\n href=\"https://flojo.io\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-xs text-gray-400 dark:text-zinc-500 hover:text-gray-600 dark:hover:text-zinc-300\"\n >\n by Flojo\n </a>\n )}\n </div>\n\n {/* Workflow name and status - click to rename */}\n <div className=\"flex items-center gap-2\">\n {isEditingName ? (\n <input\n type=\"text\"\n value={editingName}\n onChange={(e) => setEditingName(e.target.value)}\n onBlur={handleSaveRename}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") handleSaveRename();\n if (e.key === \"Escape\") {\n setEditingName(activeWorkflowName);\n setIsEditingName(false);\n }\n }}\n className=\"w-48 px-2 py-1 text-sm font-medium bg-white dark:bg-zinc-900 border border-teal-500 rounded focus:outline-none focus:ring-1 focus:ring-teal-500 text-gray-900 dark:text-zinc-100\"\n autoFocus\n />\n ) : (\n <button\n onClick={handleStartRename}\n className=\"text-sm text-gray-700 dark:text-zinc-300 font-medium hover:text-gray-900 dark:hover:text-zinc-100 rounded px-2 py-1 -mx-2 hover:bg-gray-100 dark:hover:bg-zinc-700 transition-colors\"\n title=\"Click to rename\"\n >\n {activeWorkflowName}\n </button>\n )}\n {hasUnsavedChanges && (\n <span className=\"text-xs text-amber-600 dark:text-amber-400\">(unsaved)</span>\n )}\n {notification && (\n <span className=\"text-xs text-green-600 dark:text-green-400\">{notification}</span>\n )}\n </div>\n\n <span className=\"text-sm text-gray-500 dark:text-zinc-400\">\n {nodes.length} node{nodes.length !== 1 ? \"s\" : \"\"}\n </span>\n </div>\n\n <div className=\"flex items-center gap-3\">\n {beforeActionsSlot}\n <button\n onClick={openSettings}\n className=\"p-2 text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200 hover:bg-gray-100 dark:hover:bg-zinc-700 rounded-md\"\n title=\"AI Settings\"\n >\n <svg className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z\"\n />\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M15 12a3 3 0 11-6 0 3 3 0 016 0z\"\n />\n </svg>\n </button>\n\n {/* Save button */}\n <button\n onClick={handleSave}\n disabled={nodes.length === 0}\n className=\"p-2 text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200 hover:bg-gray-100 dark:hover:bg-zinc-700 rounded-md disabled:opacity-50 disabled:cursor-not-allowed\"\n title=\"Save Workflow (Cmd+S)\"\n >\n <svg className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M8 7H5a2 2 0 00-2 2v9a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-3m-1 4l-3 3m0 0l-3-3m3 3V4\"\n />\n </svg>\n </button>\n\n <button\n onClick={() => setShowImport(true)}\n className=\"px-4 py-2 text-sm font-medium text-gray-700 dark:text-zinc-200 bg-white dark:bg-zinc-700 border border-gray-300 dark:border-zinc-600 rounded-md hover:bg-gray-50 dark:hover:bg-zinc-600\"\n >\n Import\n </button>\n\n <button\n onClick={handleExport}\n disabled={nodes.length === 0}\n className=\"px-4 py-2 text-sm font-medium text-gray-700 dark:text-zinc-200 bg-white dark:bg-zinc-700 border border-gray-300 dark:border-zinc-600 rounded-md hover:bg-gray-50 dark:hover:bg-zinc-600 disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n Export\n </button>\n\n {execution.status === \"running\" ? (\n <button\n onClick={cancelExecution}\n className=\"px-4 py-2 text-sm font-medium text-white bg-red-600 rounded-md hover:bg-red-700 flex items-center gap-2\"\n >\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n Cancel\n </button>\n ) : (\n <button\n onClick={handleExecute}\n disabled={nodes.length === 0}\n className=\"px-4 py-2 text-sm font-medium text-white bg-teal-600 rounded-md hover:bg-teal-700 disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2\"\n >\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z\"\n />\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"\n />\n </svg>\n Execute\n </button>\n )}\n {afterActionsSlot}\n </div>\n </div>\n\n {/* Execution result banner */}\n {execution.status === \"completed\" && execution.imageIds.length > 0 && (\n <div className=\"bg-green-50 dark:bg-green-900/30 border-b border-green-200 dark:border-green-800 px-4 py-3\">\n <div className=\"flex items-center gap-4\">\n <span className=\"text-green-700 dark:text-green-400 font-medium\">\n Generated {execution.imageIds.length} image\n {execution.imageIds.length !== 1 ? \"s\" : \"\"}\n </span>\n <div className=\"flex gap-2\">\n {execution.imageUrls.slice(0, 4).map((url, idx) => (\n <a key={idx} href={url} target=\"_blank\" rel=\"noopener noreferrer\" className=\"block\">\n <img\n src={url}\n alt=\"Generated\"\n className=\"h-12 w-12 object-cover rounded border border-green-300 dark:border-green-700\"\n />\n </a>\n ))}\n </div>\n </div>\n </div>\n )}\n\n {execution.status === \"error\" && (\n <div className=\"bg-red-50 dark:bg-red-900/30 border-b border-red-200 dark:border-red-800 px-4 py-3\">\n <span className=\"text-red-700 dark:text-red-400\">Error: {execution.error}</span>\n </div>\n )}\n\n {/* Export modal with tabs */}\n {showExport && (\n <div className=\"fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50\">\n <div className=\"bg-white dark:bg-zinc-800 rounded-lg shadow-xl max-w-2xl w-full mx-4 max-h-[80vh] flex flex-col\">\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-gray-200 dark:border-zinc-700\">\n <div className=\"flex items-center gap-4\">\n <h3 className=\"text-lg font-semibold text-gray-900 dark:text-white\">\n Export Workflow\n </h3>\n {/* Tabs */}\n <div className=\"flex gap-1 bg-gray-100 dark:bg-zinc-700 rounded-lg p-1\">\n <button\n onClick={() => setExportTab(\"yaml\")}\n className={`px-3 py-1 text-sm font-medium rounded-md transition-colors ${\n exportTab === \"yaml\"\n ? \"bg-white dark:bg-zinc-600 text-gray-900 dark:text-white shadow-sm\"\n : \"text-gray-600 dark:text-zinc-400 hover:text-gray-900 dark:hover:text-white\"\n }`}\n >\n YAML\n </button>\n <button\n onClick={() => setExportTab(\"javascript\")}\n className={`px-3 py-1 text-sm font-medium rounded-md transition-colors ${\n exportTab === \"javascript\"\n ? \"bg-white dark:bg-zinc-600 text-gray-900 dark:text-white shadow-sm\"\n : \"text-gray-600 dark:text-zinc-400 hover:text-gray-900 dark:hover:text-white\"\n }`}\n >\n JavaScript\n </button>\n </div>\n </div>\n <button\n onClick={() => setShowExport(false)}\n className=\"text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200\"\n >\n <svg className=\"h-6 w-6\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </button>\n </div>\n <div className=\"p-4 overflow-auto flex-1\">\n <pre className=\"bg-gray-100 dark:bg-zinc-900 p-4 rounded text-sm font-mono whitespace-pre-wrap text-gray-800 dark:text-zinc-200\">\n {exportTab === \"yaml\" ? yamlContent : jsContent}\n </pre>\n </div>\n <div className=\"flex justify-between items-center px-4 py-3 border-t border-gray-200 dark:border-zinc-700\">\n <span className=\"text-xs text-gray-500 dark:text-zinc-400\">\n {exportTab === \"yaml\"\n ? \"Use with floimg CLI: floimg run workflow.yaml\"\n : \"Run with Node.js or Bun\"}\n </span>\n <div className=\"flex gap-2\">\n <button\n onClick={handleCopy}\n className=\"px-4 py-2 text-sm font-medium text-gray-700 dark:text-zinc-200 bg-white dark:bg-zinc-700 border border-gray-300 dark:border-zinc-600 rounded-md hover:bg-gray-50 dark:hover:bg-zinc-600\"\n >\n Copy to Clipboard\n </button>\n <button\n onClick={() => setShowExport(false)}\n className=\"px-4 py-2 text-sm font-medium text-white bg-teal-600 rounded-md hover:bg-teal-700\"\n >\n Close\n </button>\n </div>\n </div>\n </div>\n </div>\n )}\n\n {/* Import modal */}\n <ImportModal\n isOpen={showImport}\n onClose={() => setShowImport(false)}\n onImport={handleImport}\n />\n </>\n );\n}\n","import { useState } from \"react\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { listImages, getImageUrl, getImageWorkflow, type ImageInfo } from \"../api/client\";\nimport { useWorkflowStore } from \"../stores/workflowStore\";\nimport type { Template } from \"@teamflojo/floimg-templates\";\n\nexport function Gallery() {\n const loadTemplate = useWorkflowStore((s) => s.loadTemplate);\n const [loadingWorkflow, setLoadingWorkflow] = useState<string | null>(null);\n\n const {\n data: images,\n isLoading,\n error,\n refetch,\n } = useQuery({\n queryKey: [\"images\"],\n queryFn: listImages,\n refetchInterval: 5000, // Auto-refresh every 5 seconds\n });\n\n const handleLoadWorkflow = async (imageId: string) => {\n setLoadingWorkflow(imageId);\n try {\n const metadata = await getImageWorkflow(imageId);\n if (metadata?.workflow) {\n // Convert to Template format for loading\n const template: Template = {\n id: `image-${imageId}`,\n name: `Workflow from ${imageId}`,\n description: \"Loaded from gallery image\",\n category: \"Utilities\",\n generator: \"unknown\",\n workflow: {\n nodes: metadata.workflow.nodes,\n edges: metadata.workflow.edges,\n },\n };\n loadTemplate(template);\n // Navigate to editor tab (parent handles this via URL or state)\n window.dispatchEvent(new CustomEvent(\"workflow-loaded\"));\n } else {\n alert(\"No workflow metadata available for this image\");\n }\n } catch (err) {\n console.error(\"Failed to load workflow:\", err);\n alert(\"Failed to load workflow\");\n } finally {\n setLoadingWorkflow(null);\n }\n };\n\n if (isLoading) {\n return (\n <div className=\"p-8 text-center text-gray-500 dark:text-zinc-400\">Loading images...</div>\n );\n }\n\n if (error) {\n return (\n <div className=\"p-8 text-center text-red-500 dark:text-red-400\">\n Error loading images: {error instanceof Error ? error.message : \"Unknown error\"}\n </div>\n );\n }\n\n if (!images || images.length === 0) {\n return (\n <div className=\"p-8 text-center text-gray-500 dark:text-zinc-400\">\n <div className=\"text-lg mb-2\">No images yet</div>\n <div className=\"text-sm\">Create a workflow and click Execute to generate images</div>\n </div>\n );\n }\n\n return (\n <div className=\"p-4 bg-gray-100 dark:bg-zinc-900 min-h-full\">\n <div className=\"flex items-center justify-between mb-4\">\n <div>\n <h2 className=\"text-lg font-semibold text-gray-800 dark:text-white\">\n Images ({images.length})\n </h2>\n <p className=\"text-xs text-gray-500 dark:text-zinc-500\">Your generated images</p>\n </div>\n <button\n onClick={() => refetch()}\n className=\"text-sm text-teal-600 dark:text-teal-400 hover:text-teal-700 dark:hover:text-violet-300\"\n >\n Refresh\n </button>\n </div>\n\n <div className=\"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4\">\n {images.map((image) => (\n <ImageCard\n key={image.id}\n image={image}\n onLoadWorkflow={() => handleLoadWorkflow(image.id)}\n isLoading={loadingWorkflow === image.id}\n />\n ))}\n </div>\n </div>\n );\n}\n\ninterface ImageCardProps {\n image: ImageInfo;\n onLoadWorkflow: () => void;\n isLoading: boolean;\n}\n\nfunction ImageCard({ image, onLoadWorkflow, isLoading }: ImageCardProps) {\n const formatDate = (timestamp: number) => {\n return new Date(timestamp).toLocaleString();\n };\n\n const formatSize = (bytes: number) => {\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\n return (\n <div className=\"bg-white dark:bg-zinc-800 rounded-lg border border-gray-200 dark:border-zinc-700 overflow-hidden shadow-sm hover:shadow-md transition-shadow group\">\n <div className=\"relative\">\n <a\n href={getImageUrl(image.id)}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"block aspect-square bg-gray-100 dark:bg-zinc-900\"\n >\n <img\n src={getImageUrl(image.id)}\n alt={image.filename}\n className=\"w-full h-full object-cover\"\n loading=\"lazy\"\n />\n </a>\n {/* Hover overlay with action buttons */}\n <div className=\"absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center gap-2\">\n <button\n onClick={(e) => {\n e.preventDefault();\n onLoadWorkflow();\n }}\n disabled={isLoading}\n className=\"px-3 py-1.5 bg-teal-600 text-white text-sm rounded-lg hover:bg-teal-700 disabled:opacity-50\"\n >\n {isLoading ? \"Loading...\" : \"Load Workflow\"}\n </button>\n <a\n href={getImageUrl(image.id)}\n download={image.filename}\n onClick={(e) => e.stopPropagation()}\n className=\"p-1.5 bg-zinc-700 text-white rounded-lg hover:bg-zinc-600\"\n title=\"Download image\"\n >\n <svg className=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4\"\n />\n </svg>\n </a>\n </div>\n </div>\n <div className=\"p-3\">\n <div className=\"text-sm font-medium text-gray-800 dark:text-white truncate\">\n {image.filename}\n </div>\n <div className=\"text-xs text-gray-500 dark:text-zinc-400 mt-1\">\n {image.mime} • {formatSize(image.size)}\n </div>\n <div className=\"text-xs text-gray-400 dark:text-zinc-500 mt-1\">\n {formatDate(image.createdAt)}\n </div>\n </div>\n </div>\n );\n}\n","/**\n * Data Visualization Templates\n *\n * Charts, graphs, and diagrams using QuickChart and Mermaid generators.\n * All templates in this category work offline (OSS-compatible).\n */\n/**\n * Revenue Dashboard Pipeline\n * Canonical ID: revenue-chart\n *\n * Multi-step workflow: Generate chart → Resize → Add caption → WebP export\n * Demonstrates: chart generation with professional output formatting\n */\nexport const revenueChart = {\n id: \"revenue-chart\",\n name: \"Revenue Dashboard\",\n description: \"Quarterly revenue chart with caption and web-optimized export\",\n category: \"Data Viz\",\n generator: \"quickchart\",\n tags: [\"bar\", \"revenue\", \"quarterly\", \"dashboard\", \"sales\", \"pipeline\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"chart\",\n preview: {\n imageUrl: \"/showcase/data-viz/quarterly-revenue.png\",\n },\n codeExample: `const chart = await floimg\n .generate('quickchart', {\n chart: {\n type: 'bar',\n data: {\n labels: ['Q1', 'Q2', 'Q3', 'Q4'],\n datasets: [{ label: 'Revenue ($K)', data: [120, 190, 175, 240] }]\n }\n }\n })\n .transform('resize', { width: 800, height: 500, fit: 'inside' })\n .transform('addCaption', {\n text: 'Source: Finance Dashboard',\n position: 'bottom-right',\n fontSize: 12\n })\n .transform('convert', { to: 'image/webp', quality: 90 })\n .toBlob();`,\n seo: {\n title: \"Revenue Dashboard Chart Template\",\n description: \"Generate professional quarterly revenue bar charts with caption and optimization\",\n keywords: [\"revenue chart\", \"bar chart\", \"quarterly report\", \"dashboard\"],\n },\n workflow: {\n nodes: [\n {\n id: \"gen-1\",\n type: \"generator\",\n position: { x: 100, y: 150 },\n data: {\n generatorName: \"quickchart\",\n params: {\n chart: {\n type: \"bar\",\n data: {\n labels: [\"Q1\", \"Q2\", \"Q3\", \"Q4\"],\n datasets: [\n {\n label: \"Revenue ($K)\",\n data: [120, 190, 175, 240],\n backgroundColor: [\n \"rgba(99, 102, 241, 0.8)\",\n \"rgba(139, 92, 246, 0.8)\",\n \"rgba(168, 85, 247, 0.8)\",\n \"rgba(192, 132, 252, 0.8)\",\n ],\n },\n ],\n },\n options: {\n plugins: {\n title: {\n display: true,\n text: \"Quarterly Revenue 2024\",\n },\n },\n },\n },\n width: 600,\n height: 400,\n },\n },\n },\n {\n id: \"transform-resize\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 800,\n height: 500,\n fit: \"inside\",\n },\n },\n },\n {\n id: \"transform-caption\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"addCaption\",\n params: {\n text: \"Source: Finance Dashboard\",\n position: \"bottom-right\",\n fontSize: 12,\n color: \"#6B7280\",\n padding: 8,\n },\n },\n },\n {\n id: \"transform-webp\",\n type: \"transform\",\n position: { x: 1000, y: 150 },\n data: {\n operation: \"convert\",\n params: {\n to: \"image/webp\",\n quality: 90,\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"gen-1\", target: \"transform-resize\" },\n { id: \"e2\", source: \"transform-resize\", target: \"transform-caption\" },\n { id: \"e3\", source: \"transform-caption\", target: \"transform-webp\" },\n ],\n },\n};\n/**\n * User Growth Chart for Investor Updates\n * Canonical ID: monthly-users\n *\n * Multi-step workflow: Generate chart → Resize for slides → Round corners for modern look → PNG export\n * JTBD: Create polished growth charts for investor decks and board presentations\n */\nexport const monthlyUsers = {\n id: \"monthly-users\",\n name: \"User Growth Chart\",\n description: \"Polished user growth chart ready for investor decks and presentations\",\n category: \"Data Viz\",\n generator: \"quickchart\",\n tags: [\"line\", \"growth\", \"users\", \"monthly\", \"analytics\", \"pipeline\", \"investor\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"chart\",\n preview: {\n imageUrl: \"/showcase/data-viz/monthly-users.png\",\n },\n codeExample: `const chart = await floimg\n .generate('quickchart', {\n chart: {\n type: 'line',\n data: {\n labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],\n datasets: [{ label: 'Active Users', data: [1200, 1900, 3000, 5000, 6200, 8100] }]\n }\n }\n })\n .transform('resize', { width: 1200, height: 675 }) // 16:9 for slides\n .transform('roundCorners', { radius: 16 })\n .transform('convert', { to: 'image/png' })\n .toBlob();`,\n seo: {\n title: \"User Growth Chart Template\",\n description: \"Visualize monthly user growth with smooth bezier curves for investor presentations\",\n keywords: [\"user growth\", \"line chart\", \"analytics\", \"investor deck\"],\n },\n workflow: {\n nodes: [\n {\n id: \"gen-1\",\n type: \"generator\",\n position: { x: 100, y: 150 },\n data: {\n generatorName: \"quickchart\",\n params: {\n chart: {\n type: \"line\",\n data: {\n labels: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\"],\n datasets: [\n {\n label: \"Active Users\",\n data: [1200, 1900, 3000, 5000, 6200, 8100],\n borderColor: \"rgb(99, 102, 241)\",\n backgroundColor: \"rgba(99, 102, 241, 0.1)\",\n fill: true,\n tension: 0.4,\n },\n ],\n },\n options: {\n plugins: {\n title: {\n display: true,\n text: \"User Growth 2024\",\n },\n },\n },\n },\n width: 600,\n height: 400,\n },\n },\n },\n {\n id: \"transform-resize\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 1200,\n height: 675,\n fit: \"contain\",\n background: \"#ffffff\",\n },\n },\n },\n {\n id: \"transform-corners\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"roundCorners\",\n params: {\n radius: 16,\n },\n },\n },\n {\n id: \"transform-png\",\n type: \"transform\",\n position: { x: 1000, y: 150 },\n data: {\n operation: \"convert\",\n params: {\n to: \"image/png\",\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"gen-1\", target: \"transform-resize\" },\n { id: \"e2\", source: \"transform-resize\", target: \"transform-corners\" },\n { id: \"e3\", source: \"transform-corners\", target: \"transform-png\" },\n ],\n },\n};\n/**\n * Framework Comparison for Blog Posts\n * Canonical ID: framework-usage\n *\n * Multi-step workflow: Generate chart → Resize for blog → Add padding → WebP for fast loading\n * JTBD: Create comparison charts for technical blog posts and documentation\n */\nexport const frameworkUsage = {\n id: \"framework-usage\",\n name: \"Framework Usage Stats\",\n description: \"Blog-ready comparison chart with optimized sizing and fast web loading\",\n category: \"Data Viz\",\n generator: \"quickchart\",\n tags: [\"bar\", \"comparison\", \"stats\", \"horizontal\", \"frameworks\", \"pipeline\", \"blog\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"chart\",\n preview: {\n imageUrl: \"/showcase/data-viz/framework-usage.png\",\n },\n codeExample: `const chart = await floimg\n .generate('quickchart', {\n chart: {\n type: 'horizontalBar',\n data: {\n labels: ['React', 'Vue', 'Angular', 'Svelte', 'Solid'],\n datasets: [{ label: 'Usage %', data: [42, 18, 15, 8, 4] }]\n }\n }\n })\n .transform('resize', { width: 800, height: 450 }) // Blog content width\n .transform('extend', { top: 16, bottom: 16, left: 16, right: 16, background: '#ffffff' })\n .transform('convert', { to: 'image/webp', quality: 85 })\n .toBlob();`,\n seo: {\n title: \"Framework Comparison Chart Template\",\n description: \"Generate comparison charts for technical blog posts with optimized web delivery\",\n keywords: [\"framework comparison\", \"bar chart\", \"tech blog\", \"documentation\"],\n },\n workflow: {\n nodes: [\n {\n id: \"gen-1\",\n type: \"generator\",\n position: { x: 100, y: 150 },\n data: {\n generatorName: \"quickchart\",\n params: {\n chart: {\n type: \"horizontalBar\",\n data: {\n labels: [\"React\", \"Vue\", \"Angular\", \"Svelte\", \"Solid\"],\n datasets: [\n {\n label: \"Usage %\",\n data: [42, 18, 15, 8, 4],\n backgroundColor: [\n \"rgba(97, 218, 251, 0.8)\",\n \"rgba(65, 184, 131, 0.8)\",\n \"rgba(221, 0, 49, 0.8)\",\n \"rgba(255, 62, 0, 0.8)\",\n \"rgba(68, 107, 158, 0.8)\",\n ],\n },\n ],\n },\n options: {\n plugins: {\n title: {\n display: true,\n text: \"Frontend Framework Usage 2024\",\n },\n },\n },\n },\n width: 600,\n height: 400,\n },\n },\n },\n {\n id: \"transform-resize\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 800,\n height: 450,\n fit: \"inside\",\n },\n },\n },\n {\n id: \"transform-padding\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"extend\",\n params: {\n top: 16,\n bottom: 16,\n left: 16,\n right: 16,\n background: \"#ffffff\",\n },\n },\n },\n {\n id: \"transform-webp\",\n type: \"transform\",\n position: { x: 1000, y: 150 },\n data: {\n operation: \"convert\",\n params: {\n to: \"image/webp\",\n quality: 85,\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"gen-1\", target: \"transform-resize\" },\n { id: \"e2\", source: \"transform-resize\", target: \"transform-padding\" },\n { id: \"e3\", source: \"transform-padding\", target: \"transform-webp\" },\n ],\n },\n};\n/**\n * Traffic Breakdown for Slack/Reports\n * Canonical ID: traffic-breakdown\n *\n * Multi-step workflow: Generate chart → Square format for Slack → Add date annotation → PNG\n * JTBD: Share analytics breakdowns in Slack channels and weekly reports\n */\nexport const trafficBreakdown = {\n id: \"traffic-breakdown\",\n name: \"Traffic by Device\",\n description: \"Analytics breakdown optimized for Slack sharing and weekly reports\",\n category: \"Data Viz\",\n generator: \"quickchart\",\n tags: [\"doughnut\", \"traffic\", \"analytics\", \"pie\", \"devices\", \"pipeline\", \"slack\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"chart\",\n preview: {\n imageUrl: \"/showcase/data-viz/traffic-by-device.png\",\n },\n codeExample: `const chart = await floimg\n .generate('quickchart', {\n chart: {\n type: 'doughnut',\n data: {\n labels: ['Desktop', 'Mobile', 'Tablet'],\n datasets: [{ data: [55, 35, 10] }]\n }\n }\n })\n .transform('resize', { width: 500, height: 500 }) // Square for Slack preview\n .transform('addCaption', {\n text: 'Week of Jan 1, 2026',\n position: 'bottom-center',\n fontSize: 14,\n color: '#6B7280'\n })\n .transform('convert', { to: 'image/png' })\n .toBlob();`,\n seo: {\n title: \"Traffic Breakdown Chart Template\",\n description: \"Generate analytics breakdown charts optimized for Slack sharing and reports\",\n keywords: [\"traffic analytics\", \"doughnut chart\", \"slack\", \"weekly report\"],\n },\n workflow: {\n nodes: [\n {\n id: \"gen-1\",\n type: \"generator\",\n position: { x: 100, y: 150 },\n data: {\n generatorName: \"quickchart\",\n params: {\n chart: {\n type: \"doughnut\",\n data: {\n labels: [\"Desktop\", \"Mobile\", \"Tablet\"],\n datasets: [\n {\n data: [55, 35, 10],\n backgroundColor: [\n \"rgba(99, 102, 241, 0.8)\",\n \"rgba(34, 197, 94, 0.8)\",\n \"rgba(249, 115, 22, 0.8)\",\n ],\n },\n ],\n },\n options: {\n plugins: {\n title: {\n display: true,\n text: \"Traffic by Device Type\",\n },\n },\n },\n },\n width: 400,\n height: 400,\n },\n },\n },\n {\n id: \"transform-resize\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 500,\n height: 500,\n fit: \"contain\",\n background: \"#ffffff\",\n },\n },\n },\n {\n id: \"transform-caption\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"addCaption\",\n params: {\n text: \"Week of Jan 1, 2026\",\n position: \"bottom-center\",\n fontSize: 14,\n color: \"#6B7280\",\n padding: 12,\n },\n },\n },\n {\n id: \"transform-png\",\n type: \"transform\",\n position: { x: 1000, y: 150 },\n data: {\n operation: \"convert\",\n params: {\n to: \"image/png\",\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"gen-1\", target: \"transform-resize\" },\n { id: \"e2\", source: \"transform-resize\", target: \"transform-caption\" },\n { id: \"e3\", source: \"transform-caption\", target: \"transform-png\" },\n ],\n },\n};\n/**\n * API Documentation Sequence Diagram\n * Canonical ID: api-flow\n *\n * Multi-step workflow: Generate diagram → Resize for docs → Add padding → PNG for docs\n * JTBD: Create API flow diagrams for technical documentation and README files\n */\nexport const apiFlow = {\n id: \"api-flow\",\n name: \"API Request Flow\",\n description: \"Sequence diagram ready for API documentation and README files\",\n category: \"Data Viz\",\n generator: \"mermaid\",\n tags: [\"sequence\", \"api\", \"authentication\", \"diagram\", \"flow\", \"pipeline\", \"docs\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"diagram\",\n preview: {\n imageUrl: \"/showcase/diagrams/api-flow.png\",\n },\n codeExample: `const diagram = await floimg\n .generate('mermaid', {\n code: \\`sequenceDiagram\n participant Client\n participant API\n participant Auth\n Client->>API: POST /login\n API->>Auth: Validate\n Auth-->>API: JWT token\n API-->>Client: 200 OK\\`\n })\n .transform('resize', { width: 800, fit: 'inside' })\n .transform('extend', { top: 24, bottom: 24, left: 24, right: 24, background: '#ffffff' })\n .transform('convert', { to: 'image/png' })\n .toBlob();`,\n seo: {\n title: \"API Flow Diagram Template\",\n description: \"Generate sequence diagrams for API documentation and README files\",\n keywords: [\"api diagram\", \"sequence diagram\", \"documentation\", \"readme\"],\n },\n workflow: {\n nodes: [\n {\n id: \"gen-1\",\n type: \"generator\",\n position: { x: 100, y: 150 },\n data: {\n generatorName: \"mermaid\",\n params: {\n code: `sequenceDiagram\n participant Client\n participant API\n participant Auth\n participant DB\n\n Client->>API: POST /login\n API->>Auth: Validate credentials\n Auth->>DB: Query user\n DB-->>Auth: User data\n Auth-->>API: JWT token\n API-->>Client: 200 OK + token\n\n Client->>API: GET /data (+ JWT)\n API->>Auth: Verify token\n Auth-->>API: Valid\n API->>DB: Fetch data\n DB-->>API: Data\n API-->>Client: 200 OK + data`,\n theme: \"default\",\n },\n },\n },\n {\n id: \"transform-resize\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 800,\n fit: \"inside\",\n },\n },\n },\n {\n id: \"transform-padding\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"extend\",\n params: {\n top: 24,\n bottom: 24,\n left: 24,\n right: 24,\n background: \"#ffffff\",\n },\n },\n },\n {\n id: \"transform-png\",\n type: \"transform\",\n position: { x: 1000, y: 150 },\n data: {\n operation: \"convert\",\n params: {\n to: \"image/png\",\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"gen-1\", target: \"transform-resize\" },\n { id: \"e2\", source: \"transform-resize\", target: \"transform-padding\" },\n { id: \"e3\", source: \"transform-padding\", target: \"transform-png\" },\n ],\n },\n};\n/**\n * System Architecture for Technical Docs\n * Canonical ID: system-architecture\n *\n * Multi-step workflow: Generate diagram → Resize for wiki → Add padding → WebP for fast loading\n * JTBD: Create architecture diagrams for Confluence/Notion/README documentation\n */\nexport const systemArchitecture = {\n id: \"system-architecture\",\n name: \"System Architecture\",\n description: \"Architecture diagram optimized for Confluence, Notion, and technical documentation\",\n category: \"Data Viz\",\n generator: \"mermaid\",\n tags: [\n \"architecture\",\n \"microservices\",\n \"flowchart\",\n \"system\",\n \"infrastructure\",\n \"pipeline\",\n \"confluence\",\n ],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"diagram\",\n preview: {\n imageUrl: \"/showcase/diagrams/system-architecture.png\",\n },\n codeExample: `const diagram = await floimg\n .generate('mermaid', {\n code: \\`flowchart TB\n subgraph Gateway\n LB[Load Balancer]\n API[API Gateway]\n end\n subgraph Services\n Auth[Auth]\n Users[Users]\n end\n LB --> API --> Auth & Users\\`\n })\n .transform('resize', { width: 1000, fit: 'inside' })\n .transform('extend', { top: 32, bottom: 32, left: 32, right: 32, background: '#ffffff' })\n .transform('convert', { to: 'image/webp', quality: 90 })\n .toBlob();`,\n seo: {\n title: \"System Architecture Diagram Template\",\n description: \"Generate architecture diagrams for Confluence, Notion, and technical documentation\",\n keywords: [\"architecture diagram\", \"microservices\", \"confluence\", \"notion\"],\n },\n workflow: {\n nodes: [\n {\n id: \"gen-1\",\n type: \"generator\",\n position: { x: 100, y: 150 },\n data: {\n generatorName: \"mermaid\",\n params: {\n code: `flowchart TB\n subgraph Client\n Web[Web App]\n Mobile[Mobile App]\n end\n\n subgraph Gateway\n LB[Load Balancer]\n API[API Gateway]\n end\n\n subgraph Services\n Auth[Auth Service]\n Users[User Service]\n Orders[Order Service]\n Notify[Notification Service]\n end\n\n subgraph Data\n PG[(PostgreSQL)]\n Redis[(Redis Cache)]\n S3[(S3 Storage)]\n end\n\n Web --> LB\n Mobile --> LB\n LB --> API\n API --> Auth\n API --> Users\n API --> Orders\n API --> Notify\n Auth --> Redis\n Users --> PG\n Orders --> PG\n Notify --> Redis`,\n theme: \"default\",\n },\n },\n },\n {\n id: \"transform-resize\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 1000,\n fit: \"inside\",\n },\n },\n },\n {\n id: \"transform-padding\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"extend\",\n params: {\n top: 32,\n bottom: 32,\n left: 32,\n right: 32,\n background: \"#ffffff\",\n },\n },\n },\n {\n id: \"transform-webp\",\n type: \"transform\",\n position: { x: 1000, y: 150 },\n data: {\n operation: \"convert\",\n params: {\n to: \"image/webp\",\n quality: 90,\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"gen-1\", target: \"transform-resize\" },\n { id: \"e2\", source: \"transform-resize\", target: \"transform-padding\" },\n { id: \"e3\", source: \"transform-padding\", target: \"transform-webp\" },\n ],\n },\n};\n/**\n * Git Workflow for Team Onboarding\n * Canonical ID: git-workflow\n *\n * Multi-step workflow: Generate diagram → Resize for wiki → Add caption → PNG for docs\n * JTBD: Create git workflow diagrams for team onboarding and CONTRIBUTING.md files\n */\nexport const gitWorkflow = {\n id: \"git-workflow\",\n name: \"Git Branch Workflow\",\n description: \"Git branching diagram for team onboarding and CONTRIBUTING.md\",\n category: \"Data Viz\",\n generator: \"mermaid\",\n tags: [\n \"git\",\n \"branching\",\n \"workflow\",\n \"development\",\n \"version-control\",\n \"pipeline\",\n \"onboarding\",\n ],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"diagram\",\n preview: {\n imageUrl: \"/showcase/diagrams/git-workflow.png\",\n },\n codeExample: `const diagram = await floimg\n .generate('mermaid', {\n code: \\`gitGraph\n commit id: \"Initial\"\n branch develop\n commit id: \"Setup\"\n branch feature/auth\n commit id: \"Add login\"\n checkout develop\n merge feature/auth tag: \"v1.0.0\"\\`\n })\n .transform('resize', { width: 900, fit: 'inside' })\n .transform('addCaption', {\n text: 'Our Git Branching Strategy',\n position: 'top-center',\n fontSize: 16\n })\n .transform('convert', { to: 'image/png' })\n .toBlob();`,\n seo: {\n title: \"Git Workflow Diagram Template\",\n description: \"Generate git branching diagrams for team onboarding and CONTRIBUTING.md\",\n keywords: [\"git workflow\", \"branching strategy\", \"team onboarding\", \"contributing\"],\n },\n workflow: {\n nodes: [\n {\n id: \"gen-1\",\n type: \"generator\",\n position: { x: 100, y: 150 },\n data: {\n generatorName: \"mermaid\",\n params: {\n code: `gitGraph\n commit id: \"Initial\"\n branch develop\n checkout develop\n commit id: \"Setup\"\n branch feature/auth\n checkout feature/auth\n commit id: \"Add login\"\n commit id: \"Add signup\"\n checkout develop\n merge feature/auth\n branch feature/dashboard\n checkout feature/dashboard\n commit id: \"Add charts\"\n checkout develop\n merge feature/dashboard\n checkout main\n merge develop tag: \"v1.0.0\"\n checkout develop\n commit id: \"Post-release\"`,\n theme: \"default\",\n },\n },\n },\n {\n id: \"transform-resize\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 900,\n fit: \"inside\",\n },\n },\n },\n {\n id: \"transform-caption\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"addCaption\",\n params: {\n text: \"Our Git Branching Strategy\",\n position: \"top-center\",\n fontSize: 16,\n color: \"#374151\",\n padding: 16,\n },\n },\n },\n {\n id: \"transform-png\",\n type: \"transform\",\n position: { x: 1000, y: 150 },\n data: {\n operation: \"convert\",\n params: {\n to: \"image/png\",\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"gen-1\", target: \"transform-resize\" },\n { id: \"e2\", source: \"transform-resize\", target: \"transform-caption\" },\n { id: \"e3\", source: \"transform-caption\", target: \"transform-png\" },\n ],\n },\n};\n/**\n * All data visualization templates\n */\nexport const dataVizTemplates = [\n revenueChart,\n monthlyUsers,\n frameworkUsage,\n trafficBreakdown,\n apiFlow,\n systemArchitecture,\n gitWorkflow,\n];\n//# sourceMappingURL=data-viz.js.map","/**\n * AI Workflow Templates\n *\n * Templates that use AI image generation (OpenAI DALL-E, etc.)\n * These require API keys (cloud deployment) to execute.\n */\n/**\n * AI Product Photography for E-commerce\n * Canonical ID: ai-product-shot\n *\n * Multi-step workflow: AI generate → Remove background → Resize for listing → Add watermark\n * JTBD: Create e-commerce-ready product photos with transparent backgrounds and consistent sizing\n */\nexport const aiProductShot = {\n id: \"ai-product-shot\",\n name: \"AI Product Photography\",\n description: \"Generate AI product photos with background removal and e-commerce-ready sizing\",\n category: \"AI Workflows\",\n generator: \"openai\",\n tags: [\"product\", \"ecommerce\", \"photography\", \"dall-e\", \"ai\", \"pipeline\", \"background-removal\"],\n requiresCloud: true,\n requiresAuth: true,\n usesAI: true,\n aiCreditsNeeded: 1,\n capabilities: {\n pipeline: true,\n },\n icon: \"sparkles\",\n valueProp: \"E-commerce-ready product photos in seconds\",\n preview: {\n imageUrl: \"/showcase/ai-generation/product-headphones.png\",\n },\n codeExample: `const product = await floimg\n .generate('openai', {\n prompt: 'Professional product photo of headphones on white background',\n model: 'dall-e-3',\n size: '1024x1024'\n })\n .transform('removeBackground')\n .transform('resize', { width: 800, height: 800, fit: 'contain', background: '#ffffff' })\n .transform('addCaption', { text: 'SKU-12345', position: 'bottom-right', fontSize: 12 })\n .toBlob();`,\n seo: {\n title: \"AI Product Photography Template\",\n description: \"Generate e-commerce-ready product photos with AI and background removal\",\n keywords: [\"product photography\", \"ai generation\", \"ecommerce\", \"background removal\"],\n },\n workflow: {\n nodes: [\n {\n id: \"gen-ai\",\n type: \"generator\",\n position: { x: 100, y: 150 },\n data: {\n generatorName: \"openai\",\n params: {\n prompt: \"Professional product photo of modern wireless headphones on a clean white background, studio lighting, high-end commercial photography style\",\n model: \"dall-e-3\",\n size: \"1024x1024\",\n quality: \"hd\",\n },\n },\n },\n {\n id: \"transform-bg\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"removeBackground\",\n params: {},\n },\n },\n {\n id: \"transform-resize\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 800,\n height: 800,\n fit: \"contain\",\n background: \"#ffffff\",\n },\n },\n },\n {\n id: \"transform-caption\",\n type: \"transform\",\n position: { x: 1000, y: 150 },\n data: {\n operation: \"addCaption\",\n params: {\n text: \"SKU-12345\",\n position: \"bottom-right\",\n fontSize: 12,\n color: \"#9CA3AF\",\n padding: 8,\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"gen-ai\", target: \"transform-bg\" },\n { id: \"e2\", source: \"transform-bg\", target: \"transform-resize\" },\n { id: \"e3\", source: \"transform-resize\", target: \"transform-caption\" },\n ],\n },\n};\n/**\n * AI Hero Image for Landing Pages\n * Canonical ID: ai-hero-image\n *\n * Multi-step workflow: AI generate → Resize to OG dimensions → Round corners → WebP for fast loading\n * JTBD: Create landing page hero images optimized for web performance and social sharing\n */\nexport const aiHeroImage = {\n id: \"ai-hero-image\",\n name: \"AI Hero Image\",\n description: \"Generate landing page hero images optimized for web and social sharing\",\n category: \"AI Workflows\",\n generator: \"openai\",\n tags: [\"hero\", \"landing-page\", \"marketing\", \"dall-e\", \"ai\", \"pipeline\", \"og-image\"],\n requiresCloud: true,\n requiresAuth: true,\n usesAI: true,\n aiCreditsNeeded: 1,\n capabilities: {\n pipeline: true,\n },\n icon: \"sparkles\",\n valueProp: \"Landing page hero images in seconds\",\n preview: {\n imageUrl: \"/showcase/ai-generation/futuristic-city.png\",\n },\n codeExample: `const hero = await floimg\n .generate('openai', {\n prompt: 'Futuristic city skyline at sunset, cinematic lighting',\n model: 'dall-e-3',\n size: '1792x1024'\n })\n .transform('resize', { width: 1200, height: 630 }) // OG image dimensions\n .transform('roundCorners', { radius: 8 })\n .transform('convert', { to: 'image/webp', quality: 85 })\n .toBlob();`,\n seo: {\n title: \"AI Hero Image Generator\",\n description: \"Generate landing page hero images optimized for web and social sharing\",\n keywords: [\"hero image\", \"landing page\", \"og image\", \"social sharing\"],\n },\n workflow: {\n nodes: [\n {\n id: \"gen-ai\",\n type: \"generator\",\n position: { x: 100, y: 150 },\n data: {\n generatorName: \"openai\",\n params: {\n prompt: \"Futuristic city skyline at golden hour sunset, cinematic wide angle, volumetric lighting, sci-fi architecture, dramatic clouds, professional photography\",\n model: \"dall-e-3\",\n size: \"1792x1024\",\n quality: \"hd\",\n },\n },\n },\n {\n id: \"transform-resize\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 1200,\n height: 630,\n fit: \"cover\",\n },\n },\n },\n {\n id: \"transform-corners\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"roundCorners\",\n params: {\n radius: 8,\n },\n },\n },\n {\n id: \"transform-webp\",\n type: \"transform\",\n position: { x: 1000, y: 150 },\n data: {\n operation: \"convert\",\n params: {\n to: \"image/webp\",\n quality: 85,\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"gen-ai\", target: \"transform-resize\" },\n { id: \"e2\", source: \"transform-resize\", target: \"transform-corners\" },\n { id: \"e3\", source: \"transform-corners\", target: \"transform-webp\" },\n ],\n },\n};\n/**\n * AI Mascot with Brand Kit Export\n * Canonical ID: ai-mascot\n *\n * Multi-step workflow: AI generate → Remove background → Export multiple sizes for different uses\n * JTBD: Create mascot assets ready for favicon, social avatars, and website use\n */\nexport const aiMascot = {\n id: \"ai-mascot\",\n name: \"AI Mascot Generator\",\n description: \"Generate mascot with transparent background and multiple export sizes\",\n category: \"AI Workflows\",\n generator: \"openai\",\n tags: [\"mascot\", \"character\", \"branding\", \"dall-e\", \"ai\", \"pipeline\", \"favicon\", \"avatar\"],\n requiresCloud: true,\n requiresAuth: true,\n usesAI: true,\n aiCreditsNeeded: 1,\n capabilities: {\n pipeline: true,\n },\n icon: \"sparkles\",\n valueProp: \"Brand-ready mascot assets in seconds\",\n preview: {\n imageUrl: \"/showcase/ai-generation/robot-mascot.png\",\n },\n codeExample: `const mascot = await floimg\n .generate('openai', {\n prompt: 'Friendly robot mascot, modern flat design, teal colors, white background',\n model: 'dall-e-3',\n size: '1024x1024'\n })\n .transform('removeBackground')\n .transform('resize', { width: 512, height: 512, fit: 'contain' })\n .transform('convert', { to: 'image/png' })\n .toBlob();`,\n seo: {\n title: \"AI Mascot Generator\",\n description: \"Create brand mascots with transparent backgrounds ready for any use\",\n keywords: [\"mascot design\", \"character design\", \"branding\", \"favicon\"],\n },\n workflow: {\n nodes: [\n {\n id: \"gen-ai\",\n type: \"generator\",\n position: { x: 100, y: 150 },\n data: {\n generatorName: \"openai\",\n params: {\n prompt: \"Friendly robot mascot character, modern flat design style, vibrant teal and purple colors, simple geometric shapes, suitable for tech company branding, white background\",\n model: \"dall-e-3\",\n size: \"1024x1024\",\n quality: \"hd\",\n },\n },\n },\n {\n id: \"transform-bg\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"removeBackground\",\n params: {},\n },\n },\n {\n id: \"transform-resize\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 512,\n height: 512,\n fit: \"contain\",\n },\n },\n },\n {\n id: \"transform-png\",\n type: \"transform\",\n position: { x: 1000, y: 150 },\n data: {\n operation: \"convert\",\n params: {\n to: \"image/png\",\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"gen-ai\", target: \"transform-bg\" },\n { id: \"e2\", source: \"transform-bg\", target: \"transform-resize\" },\n { id: \"e3\", source: \"transform-resize\", target: \"transform-png\" },\n ],\n },\n};\n/**\n * AI Logo to Brand Kit (Cloud Onboarding)\n * Canonical ID: cloud-ai-logo-brand\n */\nexport const aiLogoBrandKit = {\n id: \"cloud-ai-logo-brand\",\n name: \"AI Logo to Brand Kit\",\n description: \"Generate a logo with AI, then create production-ready brand assets\",\n category: \"AI Workflows\",\n generator: \"openai\",\n tags: [\"ai\", \"logo\", \"branding\", \"dall-e\", \"pipeline\"],\n requiresCloud: true,\n requiresAuth: true,\n usesAI: true,\n aiCreditsNeeded: 1,\n capabilities: {\n pipeline: true,\n },\n icon: \"sparkles\",\n valueProp: \"From idea to brand kit in seconds\",\n seo: {\n title: \"AI Logo to Brand Kit\",\n description: \"Generate a logo with AI and create production-ready brand assets\",\n keywords: [\"logo design\", \"brand kit\", \"ai generation\", \"branding\"],\n },\n workflow: {\n nodes: [\n {\n id: \"gen-ai\",\n type: \"generator\",\n position: { x: 100, y: 150 },\n data: {\n generatorName: \"openai\",\n params: {\n prompt: \"A modern minimalist logo for a tech startup called 'Nexus', clean geometric lines, professional, suitable for business cards and websites, white background\",\n model: \"dall-e-3\",\n size: \"1024x1024\",\n quality: \"standard\",\n },\n },\n },\n {\n id: \"transform-bg\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"removeBackground\",\n params: {},\n },\n },\n {\n id: \"transform-watermark\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"addCaption\",\n params: {\n text: \"Nexus Inc.\",\n position: \"bottom-right\",\n fontSize: 14,\n color: \"#6B7280\",\n padding: 16,\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"gen-ai\", target: \"transform-bg\" },\n { id: \"e2\", source: \"transform-bg\", target: \"transform-watermark\" },\n ],\n },\n};\n/**\n * Product Photo Enhancement (Cloud Onboarding)\n * Canonical ID: cloud-product-enhance\n */\nexport const productPhotoEnhancement = {\n id: \"cloud-product-enhance\",\n name: \"Product Photo Enhancement\",\n description: \"Remove background and add professional product labeling\",\n category: \"AI Workflows\",\n generator: \"input\",\n tags: [\"product\", \"ecommerce\", \"background-removal\", \"pipeline\"],\n requiresCloud: true,\n requiresAuth: true,\n usesAI: false, // Uses AI transforms but not AI generation\n aiCreditsNeeded: 0,\n capabilities: {\n pipeline: true,\n },\n icon: \"image\",\n valueProp: \"E-commerce ready in one click\",\n workflow: {\n nodes: [\n {\n id: \"input-1\",\n type: \"input\",\n position: { x: 100, y: 150 },\n data: {},\n },\n {\n id: \"transform-bg\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"removeBackground\",\n params: {},\n },\n },\n {\n id: \"transform-caption\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"addCaption\",\n params: {\n text: \"Premium Quality\",\n position: \"bottom-center\",\n fontSize: 24,\n color: \"#18181B\",\n padding: 20,\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"input-1\", target: \"transform-bg\" },\n { id: \"e2\", source: \"transform-bg\", target: \"transform-caption\" },\n ],\n },\n};\n/**\n * AI Art to Social Post (Cloud Onboarding)\n * Canonical ID: cloud-ai-social\n */\nexport const aiArtSocialPost = {\n id: \"cloud-ai-social\",\n name: \"AI Art to Social Post\",\n description: \"Generate creative AI art, optimize for social media\",\n category: \"AI Workflows\",\n generator: \"openai\",\n tags: [\"ai\", \"art\", \"social-media\", \"dall-e\", \"pipeline\"],\n requiresCloud: true,\n requiresAuth: true,\n usesAI: true,\n aiCreditsNeeded: 1,\n capabilities: {\n pipeline: true,\n },\n icon: \"share\",\n valueProp: \"Creative content for your feed\",\n workflow: {\n nodes: [\n {\n id: \"gen-ai\",\n type: \"generator\",\n position: { x: 100, y: 150 },\n data: {\n generatorName: \"openai\",\n params: {\n prompt: \"Abstract colorful digital art with flowing gradients, trending on artstation, vibrant neon colors, perfect for social media\",\n model: \"dall-e-3\",\n size: \"1024x1024\",\n style: \"vivid\",\n },\n },\n },\n {\n id: \"transform-corners\",\n type: \"transform\",\n position: { x: 400, y: 100 },\n data: {\n operation: \"roundCorners\",\n params: {\n radius: 24,\n },\n },\n },\n {\n id: \"transform-caption\",\n type: \"transform\",\n position: { x: 700, y: 100 },\n data: {\n operation: \"addCaption\",\n params: {\n text: \"@floimg\",\n position: \"bottom-right\",\n fontSize: 18,\n color: \"#FFFFFF\",\n padding: 16,\n },\n },\n },\n {\n id: \"transform-webp\",\n type: \"transform\",\n position: { x: 1000, y: 100 },\n data: {\n operation: \"convert\",\n params: {\n to: \"image/webp\",\n quality: 85,\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"gen-ai\", target: \"transform-corners\" },\n { id: \"e2\", source: \"transform-corners\", target: \"transform-caption\" },\n { id: \"e3\", source: \"transform-caption\", target: \"transform-webp\" },\n ],\n },\n};\n/**\n * All AI workflow templates\n */\nexport const aiWorkflowTemplates = [\n aiProductShot,\n aiHeroImage,\n aiMascot,\n aiLogoBrandKit,\n productPhotoEnhancement,\n aiArtSocialPost,\n];\n//# sourceMappingURL=ai-workflows.js.map","/**\n * Marketing Templates\n *\n * Social media kits, branding, and promotional asset workflows.\n * Most are pipeline templates that work offline (OSS-compatible).\n */\n/**\n * Social Media Kit\n * Canonical ID: social-media-kit\n */\nexport const socialMediaKit = {\n id: \"social-media-kit\",\n name: \"Social Media Kit\",\n description: \"Generate optimized images for all social platforms from one source\",\n category: \"Marketing\",\n generator: \"pipeline\",\n tags: [\"social\", \"og-image\", \"twitter\", \"instagram\", \"resize\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"share\",\n preview: {\n imageUrl: \"/showcase/pipelines/output/og-image.png\",\n },\n codeExample: `// One source -> all platforms\nconst socialKit = await floimg.pipeline(heroImage, [\n { op: 'resize', params: { width: 1200, height: 630 }, save: 'og-image.png' },\n { op: 'resize', params: { width: 800, height: 418 }, save: 'twitter-card.png' },\n { op: 'resize', params: { width: 1080, height: 1080 }, save: 'instagram.png' },\n]);`,\n seo: {\n title: \"Social Media Kit Generator\",\n description: \"Generate optimized images for all social platforms from one source image\",\n keywords: [\"social media\", \"og image\", \"twitter card\", \"instagram\", \"image resize\"],\n },\n workflow: {\n nodes: [\n {\n id: \"input-1\",\n type: \"input\",\n position: { x: 100, y: 200 },\n data: {},\n },\n {\n id: \"transform-og\",\n type: \"transform\",\n position: { x: 400, y: 100 },\n data: {\n operation: \"resize\",\n params: {\n width: 1200,\n height: 630,\n fit: \"cover\",\n },\n },\n },\n {\n id: \"transform-twitter\",\n type: \"transform\",\n position: { x: 400, y: 200 },\n data: {\n operation: \"resize\",\n params: {\n width: 800,\n height: 418,\n fit: \"cover\",\n },\n },\n },\n {\n id: \"transform-instagram\",\n type: \"transform\",\n position: { x: 400, y: 300 },\n data: {\n operation: \"resize\",\n params: {\n width: 1080,\n height: 1080,\n fit: \"cover\",\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"input-1\", target: \"transform-og\" },\n { id: \"e2\", source: \"input-1\", target: \"transform-twitter\" },\n { id: \"e3\", source: \"input-1\", target: \"transform-instagram\" },\n ],\n },\n};\n/**\n * Avatar Processing Pipeline\n * Canonical ID: avatar-pipeline\n */\nexport const avatarPipeline = {\n id: \"avatar-pipeline\",\n name: \"Avatar Processing\",\n description: \"Generate consistent avatar sizes with circular crop and optimization\",\n category: \"Marketing\",\n generator: \"pipeline\",\n tags: [\"avatar\", \"profile\", \"resize\", \"crop\", \"user\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"image\",\n preview: {\n imageUrl: \"/showcase/pipelines/output/avatar-128.png\",\n },\n codeExample: `const avatars = await floimg.pipeline(photo, [\n { op: 'crop', params: { shape: 'circle' } },\n { op: 'resize', params: { width: 256 }, save: 'avatar-256.png' },\n { op: 'resize', params: { width: 128 }, save: 'avatar-128.png' },\n { op: 'resize', params: { width: 64 }, save: 'avatar-64.png' },\n]);`,\n seo: {\n title: \"Avatar Processing Pipeline\",\n description: \"Generate consistent avatar sizes with circular crop and optimization\",\n keywords: [\"avatar\", \"profile picture\", \"image resize\", \"circular crop\"],\n },\n workflow: {\n nodes: [\n {\n id: \"input-1\",\n type: \"input\",\n position: { x: 100, y: 200 },\n data: {},\n },\n {\n id: \"transform-crop\",\n type: \"transform\",\n position: { x: 350, y: 200 },\n data: {\n operation: \"crop\",\n params: {\n shape: \"circle\",\n },\n },\n },\n {\n id: \"transform-256\",\n type: \"transform\",\n position: { x: 600, y: 100 },\n data: {\n operation: \"resize\",\n params: {\n width: 256,\n height: 256,\n },\n },\n },\n {\n id: \"transform-128\",\n type: \"transform\",\n position: { x: 600, y: 200 },\n data: {\n operation: \"resize\",\n params: {\n width: 128,\n height: 128,\n },\n },\n },\n {\n id: \"transform-64\",\n type: \"transform\",\n position: { x: 600, y: 300 },\n data: {\n operation: \"resize\",\n params: {\n width: 64,\n height: 64,\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"input-1\", target: \"transform-crop\" },\n { id: \"e2\", source: \"transform-crop\", target: \"transform-256\" },\n { id: \"e3\", source: \"transform-crop\", target: \"transform-128\" },\n { id: \"e4\", source: \"transform-crop\", target: \"transform-64\" },\n ],\n },\n};\n/**\n * Branded Watermark\n * Canonical ID: watermark-branding\n */\nexport const watermarkBranding = {\n id: \"watermark-branding\",\n name: \"Branded Watermark\",\n description: \"Add your logo watermark to images automatically\",\n category: \"Marketing\",\n generator: \"pipeline\",\n tags: [\"watermark\", \"branding\", \"logo\", \"protection\", \"copyright\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"image\",\n preview: {\n imageUrl: \"/showcase/pipelines/output/watermark-branded.png\",\n },\n seo: {\n title: \"Branded Watermark Template\",\n description: \"Add professional watermarks to protect and brand your images\",\n keywords: [\"watermark\", \"branding\", \"image protection\", \"logo overlay\"],\n },\n workflow: {\n nodes: [\n {\n id: \"gen-1\",\n type: \"generator\",\n position: { x: 100, y: 100 },\n data: {\n generatorName: \"quickchart\",\n params: {\n chart: {\n type: \"bar\",\n data: {\n labels: [\"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\"],\n datasets: [\n {\n label: \"Sales\",\n data: [45, 62, 38, 71, 55],\n backgroundColor: \"rgba(99, 102, 241, 0.8)\",\n },\n ],\n },\n },\n width: 600,\n height: 400,\n },\n },\n },\n {\n id: \"transform-1\",\n type: \"transform\",\n position: { x: 400, y: 100 },\n data: {\n operation: \"addCaption\",\n params: {\n text: \"floimg.com\",\n position: \"bottom-right\",\n fontSize: 14,\n color: \"#9ca3af\",\n padding: 10,\n },\n },\n },\n {\n id: \"transform-2\",\n type: \"transform\",\n position: { x: 700, y: 100 },\n data: {\n operation: \"roundCorners\",\n params: {\n radius: 16,\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"gen-1\", target: \"transform-1\" },\n { id: \"e2\", source: \"transform-1\", target: \"transform-2\" },\n ],\n },\n};\n/**\n * Image Filters\n * Canonical ID: filter-showcase\n */\nexport const filterShowcase = {\n id: \"filter-showcase\",\n name: \"Image Filters\",\n description: \"Apply artistic filters: vintage, dramatic, vibrant, and more\",\n category: \"Marketing\",\n generator: \"pipeline\",\n tags: [\"filter\", \"vintage\", \"effects\", \"artistic\", \"photo\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"image\",\n preview: {\n imageUrl: \"/showcase/pipelines/output/filter-vintage.png\",\n },\n seo: {\n title: \"Image Filter Effects\",\n description: \"Apply artistic filters like vintage, dramatic, and vibrant effects\",\n keywords: [\"image filter\", \"photo effects\", \"vintage filter\", \"artistic\"],\n },\n workflow: {\n nodes: [\n {\n id: \"input-1\",\n type: \"input\",\n position: { x: 100, y: 200 },\n data: {},\n },\n {\n id: \"transform-vintage\",\n type: \"transform\",\n position: { x: 400, y: 100 },\n data: {\n operation: \"adjustColors\",\n params: {\n saturation: 0.7,\n brightness: 0.9,\n sepia: 0.3,\n },\n },\n },\n {\n id: \"transform-vibrant\",\n type: \"transform\",\n position: { x: 400, y: 200 },\n data: {\n operation: \"adjustColors\",\n params: {\n saturation: 1.4,\n contrast: 1.2,\n },\n },\n },\n {\n id: \"transform-dramatic\",\n type: \"transform\",\n position: { x: 400, y: 300 },\n data: {\n operation: \"adjustColors\",\n params: {\n contrast: 1.5,\n brightness: 0.8,\n saturation: 0.9,\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"input-1\", target: \"transform-vintage\" },\n { id: \"e2\", source: \"input-1\", target: \"transform-vibrant\" },\n { id: \"e3\", source: \"input-1\", target: \"transform-dramatic\" },\n ],\n },\n};\n/**\n * Responsive Image Pipeline\n * Canonical ID: responsive-images\n *\n * Multi-step workflow: Input → 5 parallel resize branches for responsive web\n * JTBD: Generate all responsive image sizes from one source for web performance\n */\nexport const responsiveImages = {\n id: \"responsive-images\",\n name: \"Responsive Image Pipeline\",\n description: \"Generate thumbnail, mobile, tablet, desktop, and retina sizes from one source\",\n category: \"Marketing\",\n generator: \"pipeline\",\n tags: [\"responsive\", \"web\", \"performance\", \"srcset\", \"resize\", \"pipeline\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"image\",\n preview: {\n imageUrl: \"/showcase/pipelines/output/responsive-desktop.png\",\n },\n codeExample: `// One source → all responsive sizes\nconst responsive = await floimg.from(source)\n .transform('resize', { width: 320 }) // Mobile\n .transform('resize', { width: 768 }) // Tablet\n .transform('resize', { width: 1024 }) // Desktop\n .transform('resize', { width: 2048 }) // Retina\n .toBlob();`,\n seo: {\n title: \"Responsive Image Pipeline\",\n description: \"Generate all responsive image sizes for web srcset from one source\",\n keywords: [\"responsive images\", \"srcset\", \"web performance\", \"image optimization\"],\n },\n workflow: {\n nodes: [\n {\n id: \"input-1\",\n type: \"input\",\n position: { x: 100, y: 250 },\n data: {},\n },\n {\n id: \"transform-thumb\",\n type: \"transform\",\n position: { x: 400, y: 50 },\n data: {\n operation: \"resize\",\n params: {\n width: 150,\n fit: \"inside\",\n },\n },\n },\n {\n id: \"transform-mobile\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 320,\n fit: \"inside\",\n },\n },\n },\n {\n id: \"transform-tablet\",\n type: \"transform\",\n position: { x: 400, y: 250 },\n data: {\n operation: \"resize\",\n params: {\n width: 768,\n fit: \"inside\",\n },\n },\n },\n {\n id: \"transform-desktop\",\n type: \"transform\",\n position: { x: 400, y: 350 },\n data: {\n operation: \"resize\",\n params: {\n width: 1024,\n fit: \"inside\",\n },\n },\n },\n {\n id: \"transform-retina\",\n type: \"transform\",\n position: { x: 400, y: 450 },\n data: {\n operation: \"resize\",\n params: {\n width: 2048,\n fit: \"inside\",\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"input-1\", target: \"transform-thumb\" },\n { id: \"e2\", source: \"input-1\", target: \"transform-mobile\" },\n { id: \"e3\", source: \"input-1\", target: \"transform-tablet\" },\n { id: \"e4\", source: \"input-1\", target: \"transform-desktop\" },\n { id: \"e5\", source: \"input-1\", target: \"transform-retina\" },\n ],\n },\n};\n/**\n * Team Headshot Standardizer\n * Canonical ID: team-headshots\n *\n * Multi-step workflow: Input → Crop square → Resize → Grayscale → PNG export\n * JTBD: Standardize team photos for about pages and directories\n */\nexport const teamHeadshots = {\n id: \"team-headshots\",\n name: \"Team Headshot Standardizer\",\n description: \"Standardize team photos with consistent sizing and professional styling\",\n category: \"Marketing\",\n generator: \"pipeline\",\n tags: [\"headshot\", \"team\", \"about-page\", \"profile\", \"standardize\", \"pipeline\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"image\",\n preview: {\n imageUrl: \"/showcase/pipelines/output/headshot-standard.png\",\n },\n codeExample: `const headshot = await floimg.from(photo)\n .transform('extract', { width: 400, height: 400, gravity: 'face' })\n .transform('resize', { width: 300, height: 300 })\n .transform('grayscale')\n .transform('convert', { to: 'image/png' })\n .toBlob();`,\n seo: {\n title: \"Team Headshot Standardizer\",\n description: \"Standardize team photos with consistent sizing for about pages\",\n keywords: [\"headshot\", \"team photo\", \"about page\", \"profile picture\"],\n },\n workflow: {\n nodes: [\n {\n id: \"input-1\",\n type: \"input\",\n position: { x: 100, y: 150 },\n data: {},\n },\n {\n id: \"transform-crop\",\n type: \"transform\",\n position: { x: 350, y: 150 },\n data: {\n operation: \"extract\",\n params: {\n width: 400,\n height: 400,\n gravity: \"center\",\n },\n },\n },\n {\n id: \"transform-resize\",\n type: \"transform\",\n position: { x: 600, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 300,\n height: 300,\n fit: \"cover\",\n },\n },\n },\n {\n id: \"transform-grayscale\",\n type: \"transform\",\n position: { x: 850, y: 150 },\n data: {\n operation: \"grayscale\",\n params: {},\n },\n },\n {\n id: \"transform-png\",\n type: \"transform\",\n position: { x: 1100, y: 150 },\n data: {\n operation: \"convert\",\n params: {\n to: \"image/png\",\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"input-1\", target: \"transform-crop\" },\n { id: \"e2\", source: \"transform-crop\", target: \"transform-resize\" },\n { id: \"e3\", source: \"transform-resize\", target: \"transform-grayscale\" },\n { id: \"e4\", source: \"transform-grayscale\", target: \"transform-png\" },\n ],\n },\n};\n/**\n * Screenshot to Documentation Asset\n * Canonical ID: screenshot-docs\n *\n * Multi-step workflow: Screenshot URL → Resize → Add border/shadow → Optimize\n * JTBD: Prepare screenshots for documentation and README files\n */\nexport const screenshotDocs = {\n id: \"screenshot-docs\",\n name: \"Screenshot to Docs\",\n description: \"Prepare screenshots for documentation with borders and optimization\",\n category: \"Marketing\",\n generator: \"screenshot\",\n tags: [\"screenshot\", \"documentation\", \"readme\", \"border\", \"pipeline\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"image\",\n preview: {\n imageUrl: \"/showcase/pipelines/output/screenshot-docs.png\",\n },\n codeExample: `const docImage = await floimg\n .generate('screenshot', { url: 'https://example.com', width: 1280 })\n .transform('resize', { width: 800, fit: 'inside' })\n .transform('extend', { top: 16, bottom: 16, left: 16, right: 16, background: '#f3f4f6' })\n .transform('roundCorners', { radius: 8 })\n .transform('convert', { to: 'image/png' })\n .toBlob();`,\n seo: {\n title: \"Screenshot to Documentation Asset\",\n description: \"Prepare screenshots for documentation with professional styling\",\n keywords: [\"screenshot\", \"documentation\", \"readme\", \"developer tools\"],\n },\n workflow: {\n nodes: [\n {\n id: \"gen-1\",\n type: \"generator\",\n position: { x: 100, y: 150 },\n data: {\n generatorName: \"screenshot\",\n params: {\n url: \"https://floimg.com\",\n width: 1280,\n height: 800,\n },\n },\n },\n {\n id: \"transform-resize\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 800,\n fit: \"inside\",\n },\n },\n },\n {\n id: \"transform-border\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"extend\",\n params: {\n top: 16,\n bottom: 16,\n left: 16,\n right: 16,\n background: \"#f3f4f6\",\n },\n },\n },\n {\n id: \"transform-corners\",\n type: \"transform\",\n position: { x: 1000, y: 150 },\n data: {\n operation: \"roundCorners\",\n params: {\n radius: 8,\n },\n },\n },\n {\n id: \"transform-png\",\n type: \"transform\",\n position: { x: 1300, y: 150 },\n data: {\n operation: \"convert\",\n params: {\n to: \"image/png\",\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"gen-1\", target: \"transform-resize\" },\n { id: \"e2\", source: \"transform-resize\", target: \"transform-border\" },\n { id: \"e3\", source: \"transform-border\", target: \"transform-corners\" },\n { id: \"e4\", source: \"transform-corners\", target: \"transform-png\" },\n ],\n },\n};\n/**\n * Blog Post OG Image\n * Canonical ID: blog-og-image\n *\n * Multi-step workflow: Input → Resize to OG → Add title overlay → WebP export\n * JTBD: Create social sharing images for blog posts with title overlay\n */\nexport const blogOgImage = {\n id: \"blog-og-image\",\n name: \"Blog Post OG Image\",\n description: \"Create social sharing images for blog posts with title overlay\",\n category: \"Marketing\",\n generator: \"pipeline\",\n tags: [\"blog\", \"og-image\", \"social\", \"title\", \"overlay\", \"pipeline\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"share\",\n preview: {\n imageUrl: \"/showcase/pipelines/output/blog-og.png\",\n },\n codeExample: `const ogImage = await floimg.from(heroImage)\n .transform('resize', { width: 1200, height: 630, fit: 'cover' })\n .transform('addCaption', {\n text: 'How to Build Image Pipelines',\n position: 'center',\n fontSize: 48,\n color: '#ffffff'\n })\n .transform('convert', { to: 'image/webp', quality: 85 })\n .toBlob();`,\n seo: {\n title: \"Blog Post OG Image Generator\",\n description: \"Create social sharing images for blog posts with title overlay\",\n keywords: [\"og image\", \"blog\", \"social sharing\", \"title overlay\"],\n },\n workflow: {\n nodes: [\n {\n id: \"input-1\",\n type: \"input\",\n position: { x: 100, y: 150 },\n data: {},\n },\n {\n id: \"transform-resize\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 1200,\n height: 630,\n fit: \"cover\",\n },\n },\n },\n {\n id: \"transform-caption\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"addCaption\",\n params: {\n text: \"Your Blog Post Title\",\n position: \"center\",\n fontSize: 48,\n color: \"#ffffff\",\n padding: 32,\n },\n },\n },\n {\n id: \"transform-webp\",\n type: \"transform\",\n position: { x: 1000, y: 150 },\n data: {\n operation: \"convert\",\n params: {\n to: \"image/webp\",\n quality: 85,\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"input-1\", target: \"transform-resize\" },\n { id: \"e2\", source: \"transform-resize\", target: \"transform-caption\" },\n { id: \"e3\", source: \"transform-caption\", target: \"transform-webp\" },\n ],\n },\n};\n/**\n * Email Banner\n * Canonical ID: email-banner\n *\n * Multi-step workflow: Input → Resize 600x200 → Add CTA text → PNG export\n * JTBD: Create email header banners with consistent dimensions for newsletters\n */\nexport const emailBanner = {\n id: \"email-banner\",\n name: \"Email Banner\",\n description: \"Create email header banners with consistent dimensions for newsletters\",\n category: \"Marketing\",\n generator: \"pipeline\",\n tags: [\"email\", \"banner\", \"newsletter\", \"header\", \"marketing\", \"pipeline\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"share\",\n preview: {\n imageUrl: \"/showcase/pipelines/output/email-banner.png\",\n },\n codeExample: `const banner = await floimg.from(image)\n .transform('resize', { width: 600, height: 200, fit: 'cover' })\n .transform('addCaption', {\n text: 'Weekly Newsletter',\n position: 'center',\n fontSize: 32,\n color: '#ffffff'\n })\n .transform('convert', { to: 'image/png' })\n .toBlob();`,\n seo: {\n title: \"Email Banner Generator\",\n description: \"Create email header banners with consistent dimensions\",\n keywords: [\"email banner\", \"newsletter\", \"email marketing\", \"header image\"],\n },\n workflow: {\n nodes: [\n {\n id: \"input-1\",\n type: \"input\",\n position: { x: 100, y: 150 },\n data: {},\n },\n {\n id: \"transform-resize\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 600,\n height: 200,\n fit: \"cover\",\n },\n },\n },\n {\n id: \"transform-caption\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"addCaption\",\n params: {\n text: \"Weekly Newsletter\",\n position: \"center\",\n fontSize: 32,\n color: \"#ffffff\",\n padding: 16,\n },\n },\n },\n {\n id: \"transform-png\",\n type: \"transform\",\n position: { x: 1000, y: 150 },\n data: {\n operation: \"convert\",\n params: {\n to: \"image/png\",\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"input-1\", target: \"transform-resize\" },\n { id: \"e2\", source: \"transform-resize\", target: \"transform-caption\" },\n { id: \"e3\", source: \"transform-caption\", target: \"transform-png\" },\n ],\n },\n};\n/**\n * App Icon Generator\n * Canonical ID: app-icons\n *\n * Multi-step workflow: Input → Remove background → Multiple iOS/Android sizes\n * JTBD: Generate all required app icon sizes for iOS and Android from one source\n */\nexport const appIcons = {\n id: \"app-icons\",\n name: \"App Icon Generator\",\n description: \"Generate iOS and Android app icon sizes from one source image\",\n category: \"Marketing\",\n generator: \"pipeline\",\n tags: [\"app-icon\", \"ios\", \"android\", \"mobile\", \"resize\", \"pipeline\"],\n requiresCloud: true,\n requiresAuth: true,\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"image\",\n preview: {\n imageUrl: \"/showcase/pipelines/output/app-icon-180.png\",\n },\n codeExample: `const icons = await floimg.from(logo)\n .transform('removeBackground')\n .transform('resize', { width: 180, height: 180 }) // iOS\n .transform('resize', { width: 192, height: 192 }) // Android\n .transform('resize', { width: 512, height: 512 }) // Store\n .toBlob();`,\n seo: {\n title: \"App Icon Generator\",\n description: \"Generate all required iOS and Android app icon sizes\",\n keywords: [\"app icon\", \"ios icon\", \"android icon\", \"mobile app\"],\n },\n workflow: {\n nodes: [\n {\n id: \"input-1\",\n type: \"input\",\n position: { x: 100, y: 200 },\n data: {},\n },\n {\n id: \"transform-bg\",\n type: \"transform\",\n position: { x: 350, y: 200 },\n data: {\n operation: \"removeBackground\",\n params: {},\n },\n },\n {\n id: \"transform-ios-60\",\n type: \"transform\",\n position: { x: 600, y: 50 },\n data: {\n operation: \"resize\",\n params: {\n width: 60,\n height: 60,\n fit: \"contain\",\n },\n },\n },\n {\n id: \"transform-ios-180\",\n type: \"transform\",\n position: { x: 600, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 180,\n height: 180,\n fit: \"contain\",\n },\n },\n },\n {\n id: \"transform-android-192\",\n type: \"transform\",\n position: { x: 600, y: 250 },\n data: {\n operation: \"resize\",\n params: {\n width: 192,\n height: 192,\n fit: \"contain\",\n },\n },\n },\n {\n id: \"transform-store-512\",\n type: \"transform\",\n position: { x: 600, y: 350 },\n data: {\n operation: \"resize\",\n params: {\n width: 512,\n height: 512,\n fit: \"contain\",\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"input-1\", target: \"transform-bg\" },\n { id: \"e2\", source: \"transform-bg\", target: \"transform-ios-60\" },\n { id: \"e3\", source: \"transform-bg\", target: \"transform-ios-180\" },\n { id: \"e4\", source: \"transform-bg\", target: \"transform-android-192\" },\n { id: \"e5\", source: \"transform-bg\", target: \"transform-store-512\" },\n ],\n },\n};\n/**\n * All marketing templates\n */\nexport const marketingTemplates = [\n socialMediaKit,\n avatarPipeline,\n watermarkBranding,\n filterShowcase,\n responsiveImages,\n teamHeadshots,\n screenshotDocs,\n blogOgImage,\n emailBanner,\n appIcons,\n];\n//# sourceMappingURL=marketing.js.map","/**\n * Utility Templates\n *\n * QR codes, format conversion, and general-purpose utilities.\n * All templates in this category work offline (OSS-compatible).\n */\n/**\n * Branded QR Code Pipeline\n * Canonical ID: branded-qr\n *\n * Multi-step workflow: Generate QR → Resize → Add rounded corners → Convert to PNG\n * Demonstrates: composable transforms on generated content\n */\nexport const brandedQR = {\n id: \"branded-qr\",\n name: \"Branded QR Code\",\n description: \"QR code with custom colors, rounded corners, and optimized for print or digital\",\n category: \"Utilities\",\n generator: \"qr\",\n tags: [\"qr\", \"branded\", \"link\", \"custom\", \"url\", \"pipeline\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"qr\",\n preview: {\n imageUrl: \"/showcase/qr-codes/qr-brand.png\",\n },\n codeExample: `const qr = await floimg\n .generate('qr', {\n data: 'https://floimg.com',\n dark: '#0d9488',\n light: '#ffffff'\n })\n .transform('resize', { width: 300, height: 300 })\n .transform('roundCorners', { radius: 16 })\n .transform('convert', { to: 'image/png' })\n .toBlob();`,\n seo: {\n title: \"Branded QR Code Generator\",\n description: \"Generate QR codes with custom colors, rounded corners, and professional styling\",\n keywords: [\"qr code\", \"branded qr\", \"custom qr\", \"marketing\"],\n },\n workflow: {\n nodes: [\n {\n id: \"gen-1\",\n type: \"generator\",\n position: { x: 100, y: 150 },\n data: {\n generatorName: \"qr\",\n params: {\n data: \"https://floimg.com\",\n size: 400,\n margin: 2,\n dark: \"#0d9488\",\n light: \"#ffffff\",\n errorCorrectionLevel: \"M\",\n },\n },\n },\n {\n id: \"transform-resize\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 300,\n height: 300,\n fit: \"contain\",\n },\n },\n },\n {\n id: \"transform-corners\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"roundCorners\",\n params: {\n radius: 16,\n },\n },\n },\n {\n id: \"transform-convert\",\n type: \"transform\",\n position: { x: 1000, y: 150 },\n data: {\n operation: \"convert\",\n params: {\n to: \"image/png\",\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"gen-1\", target: \"transform-resize\" },\n { id: \"e2\", source: \"transform-resize\", target: \"transform-corners\" },\n { id: \"e3\", source: \"transform-corners\", target: \"transform-convert\" },\n ],\n },\n};\n/**\n * Dark Mode QR Code Pipeline\n * Canonical ID: dark-qr\n *\n * Multi-step workflow: Generate inverted QR → Resize → Add subtle border → WebP export\n * Demonstrates: transforms for dark UI integration\n */\nexport const darkQR = {\n id: \"dark-qr\",\n name: \"Dark Mode QR\",\n description: \"QR code optimized for dark backgrounds with subtle border and web-optimized export\",\n category: \"Utilities\",\n generator: \"qr\",\n tags: [\"qr\", \"dark-mode\", \"link\", \"inverted\", \"pipeline\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"qr\",\n preview: {\n imageUrl: \"/showcase/qr-codes/qr-dark.png\",\n },\n codeExample: `const qr = await floimg\n .generate('qr', {\n data: 'https://floimg.com',\n dark: '#ffffff',\n light: '#18181b'\n })\n .transform('resize', { width: 300, height: 300 })\n .transform('extend', {\n top: 8, bottom: 8, left: 8, right: 8,\n background: '#27272a'\n })\n .transform('convert', { to: 'image/webp', quality: 90 })\n .toBlob();`,\n seo: {\n title: \"Dark Mode QR Code\",\n description: \"QR codes optimized for dark backgrounds and dark mode UIs\",\n keywords: [\"qr code\", \"dark mode\", \"inverted qr\", \"night mode\"],\n },\n workflow: {\n nodes: [\n {\n id: \"gen-1\",\n type: \"generator\",\n position: { x: 100, y: 150 },\n data: {\n generatorName: \"qr\",\n params: {\n data: \"https://floimg.com\",\n size: 400,\n margin: 2,\n dark: \"#ffffff\",\n light: \"#18181b\",\n errorCorrectionLevel: \"M\",\n },\n },\n },\n {\n id: \"transform-resize\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 300,\n height: 300,\n fit: \"contain\",\n },\n },\n },\n {\n id: \"transform-border\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"extend\",\n params: {\n top: 8,\n bottom: 8,\n left: 8,\n right: 8,\n background: \"#27272a\",\n },\n },\n },\n {\n id: \"transform-webp\",\n type: \"transform\",\n position: { x: 1000, y: 150 },\n data: {\n operation: \"convert\",\n params: {\n to: \"image/webp\",\n quality: 90,\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"gen-1\", target: \"transform-resize\" },\n { id: \"e2\", source: \"transform-resize\", target: \"transform-border\" },\n { id: \"e3\", source: \"transform-border\", target: \"transform-webp\" },\n ],\n },\n};\n/**\n * WiFi QR Code Pipeline\n * Canonical ID: wifi-qr\n *\n * Multi-step workflow: Generate WiFi QR → Resize → Add caption label → Rounded corners\n * Demonstrates: adding context/labels to generated content\n */\nexport const wifiQR = {\n id: \"wifi-qr\",\n name: \"WiFi QR Code\",\n description: \"Scannable WiFi QR code with network name label and professional styling\",\n category: \"Utilities\",\n generator: \"qr\",\n tags: [\"qr\", \"wifi\", \"network\", \"guest\", \"access\", \"pipeline\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"qr\",\n preview: {\n imageUrl: \"/showcase/qr-codes/qr-wifi.png\",\n },\n codeExample: `const qr = await floimg\n .generate('qr', {\n data: 'WIFI:T:WPA;S:GuestNetwork;P:welcome123;;',\n dark: '#059669',\n light: '#ffffff'\n })\n .transform('resize', { width: 300, height: 300 })\n .transform('addCaption', {\n text: 'Scan for WiFi',\n position: 'bottom-center',\n fontSize: 18,\n color: '#059669'\n })\n .transform('roundCorners', { radius: 12 })\n .toBlob();`,\n seo: {\n title: \"WiFi QR Code Generator\",\n description: \"Generate scannable QR codes for easy WiFi network access sharing\",\n keywords: [\"wifi qr\", \"network access\", \"guest wifi\", \"qr code\"],\n },\n workflow: {\n nodes: [\n {\n id: \"gen-1\",\n type: \"generator\",\n position: { x: 100, y: 150 },\n data: {\n generatorName: \"qr\",\n params: {\n data: \"WIFI:T:WPA;S:GuestNetwork;P:welcome123;;\",\n size: 400,\n margin: 2,\n dark: \"#059669\",\n light: \"#ffffff\",\n errorCorrectionLevel: \"H\",\n },\n },\n },\n {\n id: \"transform-resize\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 300,\n height: 300,\n fit: \"contain\",\n },\n },\n },\n {\n id: \"transform-caption\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"addCaption\",\n params: {\n text: \"Scan for WiFi\",\n position: \"bottom-center\",\n fontSize: 18,\n color: \"#059669\",\n padding: 16,\n },\n },\n },\n {\n id: \"transform-corners\",\n type: \"transform\",\n position: { x: 1000, y: 150 },\n data: {\n operation: \"roundCorners\",\n params: {\n radius: 12,\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"gen-1\", target: \"transform-resize\" },\n { id: \"e2\", source: \"transform-resize\", target: \"transform-caption\" },\n { id: \"e3\", source: \"transform-caption\", target: \"transform-corners\" },\n ],\n },\n};\n/**\n * Thumbnail Generator\n * Canonical ID: thumbnail-generator\n */\nexport const thumbnailGenerator = {\n id: \"thumbnail-generator\",\n name: \"Thumbnail Generator\",\n description: \"Create multiple thumbnail sizes with automatic optimization\",\n category: \"Utilities\",\n generator: \"pipeline\",\n tags: [\"thumbnail\", \"resize\", \"optimize\", \"batch\", \"responsive\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"image\",\n preview: {\n imageUrl: \"/showcase/pipelines/output/thumb-200.png\",\n },\n seo: {\n title: \"Thumbnail Generator\",\n description: \"Generate multiple thumbnail sizes with automatic optimization\",\n keywords: [\"thumbnail\", \"image resize\", \"responsive images\", \"optimization\"],\n },\n workflow: {\n nodes: [\n {\n id: \"input-1\",\n type: \"input\",\n position: { x: 100, y: 200 },\n data: {},\n },\n {\n id: \"transform-800\",\n type: \"transform\",\n position: { x: 400, y: 100 },\n data: {\n operation: \"resize\",\n params: {\n width: 800,\n fit: \"inside\",\n },\n },\n },\n {\n id: \"transform-400\",\n type: \"transform\",\n position: { x: 400, y: 200 },\n data: {\n operation: \"resize\",\n params: {\n width: 400,\n fit: \"inside\",\n },\n },\n },\n {\n id: \"transform-200\",\n type: \"transform\",\n position: { x: 400, y: 300 },\n data: {\n operation: \"resize\",\n params: {\n width: 200,\n fit: \"inside\",\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"input-1\", target: \"transform-800\" },\n { id: \"e2\", source: \"input-1\", target: \"transform-400\" },\n { id: \"e3\", source: \"input-1\", target: \"transform-200\" },\n ],\n },\n};\n/**\n * Diagram to WebP Conversion\n * Canonical ID: diagram-webp\n */\nexport const diagramWebp = {\n id: \"diagram-webp\",\n name: \"Diagram to WebP\",\n description: \"Mermaid diagram converted to optimized WebP format\",\n category: \"Utilities\",\n generator: \"mermaid\",\n tags: [\"mermaid\", \"webp\", \"optimize\", \"pipeline\", \"conversion\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"diagram\",\n seo: {\n title: \"Diagram to WebP Converter\",\n description: \"Convert Mermaid diagrams to optimized WebP format\",\n keywords: [\"mermaid diagram\", \"webp conversion\", \"image optimization\"],\n },\n workflow: {\n nodes: [\n {\n id: \"gen-1\",\n type: \"generator\",\n position: { x: 100, y: 100 },\n data: {\n generatorName: \"mermaid\",\n params: {\n code: `graph LR\n A[Start] --> B{Decision}\n B -->|Yes| C[Action 1]\n B -->|No| D[Action 2]\n C --> E[End]\n D --> E`,\n theme: \"neutral\",\n },\n },\n },\n {\n id: \"transform-1\",\n type: \"transform\",\n position: { x: 400, y: 100 },\n data: {\n operation: \"convert\",\n params: {\n to: \"image/webp\",\n quality: 90,\n },\n },\n },\n ],\n edges: [{ id: \"e1\", source: \"gen-1\", target: \"transform-1\" }],\n },\n};\n/**\n * All utility templates\n */\nexport const utilityTemplates = [\n brandedQR,\n darkQR,\n wifiQR,\n thumbnailGenerator,\n diagramWebp,\n];\n//# sourceMappingURL=utilities.js.map","/**\n * @teamflojo/floimg-templates\n *\n * Official workflow templates for FloImg Studio.\n * Single source of truth for template definitions.\n *\n * @example\n * ```typescript\n * // Self-hosted: Get only templates that work offline\n * import { getCoreTemplates } from '@teamflojo/floimg-templates';\n * const templates = getCoreTemplates();\n *\n * // Cloud/full: Get all templates including those requiring API keys\n * import { getAllTemplates } from '@teamflojo/floimg-templates';\n * const templates = getAllTemplates();\n *\n * // Get specific template with metadata\n * import { getTemplateById } from '@teamflojo/floimg-templates';\n * const template = getTemplateById('revenue-chart');\n * ```\n */\n// Import all template categories\nimport { dataVizTemplates } from \"./templates/data-viz.js\";\nimport { aiWorkflowTemplates } from \"./templates/ai-workflows.js\";\nimport { marketingTemplates } from \"./templates/marketing.js\";\nimport { utilityTemplates } from \"./templates/utilities.js\";\n// Re-export individual templates for direct imports\nexport * from \"./templates/data-viz.js\";\nexport * from \"./templates/ai-workflows.js\";\nexport * from \"./templates/marketing.js\";\nexport * from \"./templates/utilities.js\";\n// ============================================\n// Template Registry\n// ============================================\n/**\n * All templates combined\n */\nexport const allTemplates = [\n ...dataVizTemplates,\n ...aiWorkflowTemplates,\n ...marketingTemplates,\n ...utilityTemplates,\n];\n/**\n * Core templates that work offline (no cloud required)\n * For FloImg Studio OSS and self-hosted deployments\n */\nexport const coreTemplates = allTemplates.filter((t) => !t.requiresCloud);\n/**\n * Cloud-only templates (require API keys like OpenAI, etc.)\n */\nexport const cloudTemplates = allTemplates.filter((t) => t.requiresCloud);\n// ============================================\n// Query Functions\n// ============================================\n/**\n * Get all templates (includes cloud-only templates)\n */\nexport function getAllTemplates() {\n return allTemplates;\n}\n/**\n * Get only core templates that work offline (for OSS Studio)\n */\nexport function getCoreTemplates() {\n return coreTemplates;\n}\n/**\n * Get cloud-only templates (require API keys)\n */\nexport function getCloudTemplates() {\n return cloudTemplates;\n}\n/**\n * Get a template by ID (searches all templates)\n */\nexport function getTemplateById(id) {\n return allTemplates.find((t) => t.id === id);\n}\n/**\n * Get a core template by ID (OSS-compatible only)\n */\nexport function getCoreTemplateById(id) {\n return coreTemplates.find((t) => t.id === id);\n}\n/**\n * Get all unique categories (from all templates)\n */\nexport function getCategories() {\n const categories = new Set(allTemplates.map((t) => t.category));\n return Array.from(categories);\n}\n/**\n * Get categories available in core templates (OSS-compatible)\n */\nexport function getCoreCategories() {\n const categories = new Set(coreTemplates.map((t) => t.category));\n return Array.from(categories);\n}\n/**\n * Get templates by category (from all templates)\n */\nexport function getTemplatesByCategory(category) {\n return allTemplates.filter((t) => t.category === category);\n}\n/**\n * Get core templates by category (OSS-compatible)\n */\nexport function getCoreTemplatesByCategory(category) {\n return coreTemplates.filter((t) => t.category === category);\n}\n/**\n * Get templates by generator type\n */\nexport function getTemplatesByGenerator(generator) {\n return allTemplates.filter((t) => t.generator === generator);\n}\n/**\n * Search templates by query (searches name, description, tags)\n */\nexport function searchTemplates(query) {\n const q = query.toLowerCase();\n return allTemplates.filter((t) => t.name.toLowerCase().includes(q) ||\n t.description.toLowerCase().includes(q) ||\n t.category.toLowerCase().includes(q) ||\n t.generator.toLowerCase().includes(q) ||\n t.tags?.some((tag) => tag.toLowerCase().includes(q)));\n}\n/**\n * Search core templates by query (OSS-compatible)\n */\nexport function searchCoreTemplates(query) {\n const q = query.toLowerCase();\n return coreTemplates.filter((t) => t.name.toLowerCase().includes(q) ||\n t.description.toLowerCase().includes(q) ||\n t.category.toLowerCase().includes(q) ||\n t.generator.toLowerCase().includes(q) ||\n t.tags?.some((tag) => tag.toLowerCase().includes(q)));\n}\n/**\n * Get templates that require authentication\n */\nexport function getAuthRequiredTemplates() {\n return allTemplates.filter((t) => t.requiresAuth);\n}\n/**\n * Get templates by capability\n */\nexport function getTemplatesByCapability(capability) {\n return allTemplates.filter((t) => t.capabilities?.[capability]);\n}\n// ============================================\n// Studio URL Helpers\n// ============================================\n/**\n * Get the Studio URL for a template\n * @param templateId - The template ID\n * @param baseUrl - Base URL (defaults to studio.floimg.com for cloud, or can be overridden for self-hosted)\n */\nexport function getStudioUrl(templateId, baseUrl = \"https://studio.floimg.com\") {\n return `${baseUrl}/?template=${templateId}`;\n}\n/**\n * Get the OSS Studio URL for a template (localhost default)\n * @param templateId - The template ID\n * @param port - Port number (defaults to 5173)\n */\nexport function getOSSStudioUrl(templateId, port = 5173) {\n return `http://localhost:${port}/?template=${templateId}`;\n}\n/**\n * Resolve a template by ID\n * @param id - Template ID\n * @returns The template or undefined\n */\nexport function resolveTemplate(id) {\n return getTemplateById(id);\n}\n// ============================================\n// Computed Metadata Helpers\n// ============================================\n/**\n * Get the node count for a template\n * Uses explicit nodeCount if set, otherwise computes from workflow.nodes.length\n */\nexport function getNodeCount(template) {\n if (template.nodeCount !== undefined) {\n return template.nodeCount;\n }\n return template.workflow.nodes.length;\n}\n/**\n * Get all templates with computed nodeCount added\n * Useful for consumers that want to display node count\n */\nexport function getAllTemplatesWithNodeCount() {\n return allTemplates.map((t) => ({\n ...t,\n nodeCount: getNodeCount(t),\n }));\n}\n/**\n * Get templates that are true pipelines (2+ nodes)\n */\nexport function getPipelineTemplates() {\n return allTemplates.filter((t) => getNodeCount(t) >= 2);\n}\n/**\n * Get templates sorted by complexity (node count, descending)\n */\nexport function getTemplatesByComplexity() {\n return [...allTemplates].sort((a, b) => getNodeCount(b) - getNodeCount(a));\n}\n//# sourceMappingURL=index.js.map","import { useState, useMemo } from \"react\";\nimport {\n coreTemplates as templates,\n getCoreCategories as getCategories,\n type Template,\n} from \"@teamflojo/floimg-templates\";\n\ninterface TemplateGalleryProps {\n onSelect: (templateId: string) => void;\n}\n\nexport function TemplateGallery({ onSelect }: TemplateGalleryProps) {\n const [selectedCategory, setSelectedCategory] = useState<string | null>(null);\n const [searchQuery, setSearchQuery] = useState(\"\");\n\n const categories = useMemo(() => getCategories(), []);\n\n const filteredTemplates = useMemo(() => {\n let result = templates;\n\n // Filter by category\n if (selectedCategory) {\n result = result.filter((t) => t.category === selectedCategory);\n }\n\n // Filter by search query\n if (searchQuery) {\n const q = searchQuery.toLowerCase();\n result = result.filter(\n (t) =>\n t.name.toLowerCase().includes(q) ||\n t.description.toLowerCase().includes(q) ||\n t.generator.toLowerCase().includes(q) ||\n t.tags?.some((tag) => tag.toLowerCase().includes(q))\n );\n }\n\n return result;\n }, [selectedCategory, searchQuery]);\n\n return (\n <div className=\"p-6\">\n <div className=\"mb-6\">\n <h2 className=\"text-2xl font-bold text-gray-900 dark:text-white mb-2\">Templates</h2>\n <p className=\"text-gray-600 dark:text-zinc-400\">\n Start with a pre-built workflow. Click any template to load it into the editor.\n </p>\n </div>\n\n {/* Search and filters */}\n <div className=\"flex flex-wrap gap-4 mb-6\">\n <input\n type=\"text\"\n placeholder=\"Search templates...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"px-4 py-2 border border-gray-300 dark:border-zinc-600 rounded-lg bg-white dark:bg-zinc-800 text-gray-900 dark:text-white focus:ring-2 focus:ring-teal-500 focus:border-transparent w-64\"\n />\n\n <div className=\"flex gap-2 flex-wrap\">\n <button\n onClick={() => setSelectedCategory(null)}\n className={`px-3 py-1.5 rounded-full text-sm font-medium transition-colors ${\n selectedCategory === null\n ? \"bg-teal-600 text-white\"\n : \"bg-gray-200 dark:bg-zinc-700 text-gray-700 dark:text-zinc-300 hover:bg-gray-300 dark:hover:bg-zinc-600\"\n }`}\n >\n All\n </button>\n {categories.map((category) => (\n <button\n key={category}\n onClick={() => setSelectedCategory(category)}\n className={`px-3 py-1.5 rounded-full text-sm font-medium transition-colors ${\n selectedCategory === category\n ? \"bg-teal-600 text-white\"\n : \"bg-gray-200 dark:bg-zinc-700 text-gray-700 dark:text-zinc-300 hover:bg-gray-300 dark:hover:bg-zinc-600\"\n }`}\n >\n {category}\n </button>\n ))}\n </div>\n </div>\n\n {/* Template grid */}\n {filteredTemplates.length === 0 ? (\n <div className=\"text-center py-12 text-gray-500 dark:text-zinc-400\">\n No templates found matching your criteria.\n </div>\n ) : (\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6\">\n {filteredTemplates.map((template) => (\n <TemplateCard\n key={template.id}\n template={template}\n onSelect={() => onSelect(template.id)}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n\ninterface TemplateCardProps {\n template: Template;\n onSelect: () => void;\n}\n\nfunction TemplateCard({ template, onSelect }: TemplateCardProps) {\n const nodeCount = template.workflow.nodes.length;\n const edgeCount = template.workflow.edges.length;\n\n // Generator badge colors\n const generatorColors: Record<string, string> = {\n quickchart: \"bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-300\",\n mermaid: \"bg-pink-100 text-pink-800 dark:bg-pink-900/30 dark:text-pink-300\",\n qr: \"bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-300\",\n d3: \"bg-orange-100 text-orange-800 dark:bg-orange-900/30 dark:text-orange-300\",\n };\n\n return (\n <div className=\"bg-white dark:bg-zinc-800 rounded-lg border border-gray-200 dark:border-zinc-700 overflow-hidden hover:shadow-lg transition-shadow\">\n {/* Preview area */}\n <div className=\"aspect-video bg-gray-100 dark:bg-zinc-900 flex items-center justify-center p-4\">\n {template.preview ? (\n <img\n src={template.preview.imageUrl}\n alt={template.name}\n className=\"max-w-full max-h-full object-contain\"\n />\n ) : (\n <div className=\"text-center text-gray-400 dark:text-zinc-500\">\n <svg\n className=\"w-12 h-12 mx-auto mb-2\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n 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 />\n </svg>\n <span className=\"text-sm\">No preview</span>\n </div>\n )}\n </div>\n\n {/* Content */}\n <div className=\"p-4\">\n <div className=\"flex items-start justify-between mb-2\">\n <h3 className=\"text-lg font-semibold text-gray-900 dark:text-white\">{template.name}</h3>\n <span\n className={`px-2 py-0.5 rounded text-xs font-medium ${\n generatorColors[template.generator] ||\n \"bg-gray-100 text-gray-800 dark:bg-zinc-700 dark:text-zinc-300\"\n }`}\n >\n {template.generator}\n </span>\n </div>\n\n <p className=\"text-sm text-gray-600 dark:text-zinc-400 mb-3\">{template.description}</p>\n\n {/* Metadata */}\n <div className=\"flex items-center gap-4 text-xs text-gray-500 dark:text-zinc-500 mb-4\">\n <span className=\"flex items-center gap-1\">\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 6h16M4 12h16M4 18h7\"\n />\n </svg>\n {nodeCount} node{nodeCount !== 1 ? \"s\" : \"\"}\n </span>\n {edgeCount > 0 && (\n <span className=\"flex items-center gap-1\">\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M13 7l5 5m0 0l-5 5m5-5H6\"\n />\n </svg>\n {edgeCount} edge{edgeCount !== 1 ? \"s\" : \"\"}\n </span>\n )}\n </div>\n\n {/* Tags */}\n {template.tags && template.tags.length > 0 && (\n <div className=\"flex flex-wrap gap-1 mb-4\">\n {template.tags.slice(0, 4).map((tag) => (\n <span\n key={tag}\n className=\"px-2 py-0.5 bg-gray-100 dark:bg-zinc-700 text-gray-600 dark:text-zinc-400 rounded text-xs\"\n >\n {tag}\n </span>\n ))}\n </div>\n )}\n\n {/* Action button */}\n <button\n onClick={onSelect}\n className=\"w-full py-2 px-4 bg-teal-600 hover:bg-teal-700 text-white rounded-lg font-medium transition-colors\"\n >\n Use Template\n </button>\n </div>\n </div>\n );\n}\n","import { useState } from \"react\";\nimport { useWorkflowStore, type SavedWorkflow } from \"../stores/workflowStore\";\n\ninterface WorkflowItemProps {\n workflow: SavedWorkflow;\n isActive: boolean;\n onLoad: () => void;\n onDelete: () => void;\n onRename: (name: string) => void;\n onDuplicate: () => void;\n}\n\nfunction WorkflowItem({\n workflow,\n isActive,\n onLoad,\n onDelete,\n onRename,\n onDuplicate,\n}: WorkflowItemProps) {\n const [isEditing, setIsEditing] = useState(false);\n const [editName, setEditName] = useState(workflow.name);\n const [showMenu, setShowMenu] = useState(false);\n\n const handleRename = () => {\n if (editName.trim() && editName !== workflow.name) {\n onRename(editName.trim());\n }\n setIsEditing(false);\n };\n\n const formatDate = (timestamp: number) => {\n const date = new Date(timestamp);\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMs / 3600000);\n const diffDays = Math.floor(diffMs / 86400000);\n\n if (diffMins < 1) return \"Just now\";\n if (diffMins < 60) return `${diffMins}m ago`;\n if (diffHours < 24) return `${diffHours}h ago`;\n if (diffDays < 7) return `${diffDays}d ago`;\n return date.toLocaleDateString();\n };\n\n return (\n <div\n className={`group relative p-3 rounded-lg border transition-colors ${\n isActive\n ? \"bg-teal-50 dark:bg-teal-900/20 border-teal-200 dark:border-teal-800\"\n : \"bg-white dark:bg-zinc-800 border-zinc-200 dark:border-zinc-700 hover:border-zinc-300 dark:hover:border-zinc-600\"\n }`}\n >\n <div className=\"flex items-start justify-between gap-2\">\n <button onClick={onLoad} className=\"flex-1 text-left min-w-0\">\n {isEditing ? (\n <input\n type=\"text\"\n value={editName}\n onChange={(e) => setEditName(e.target.value)}\n onBlur={handleRename}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") handleRename();\n if (e.key === \"Escape\") {\n setEditName(workflow.name);\n setIsEditing(false);\n }\n }}\n className=\"w-full px-1 py-0.5 text-sm font-medium bg-white dark:bg-zinc-900 border border-teal-500 rounded focus:outline-none focus:ring-1 focus:ring-teal-500\"\n autoFocus\n onClick={(e) => e.stopPropagation()}\n />\n ) : (\n <span className=\"block text-sm font-medium text-zinc-900 dark:text-zinc-100 truncate\">\n {workflow.name}\n </span>\n )}\n <span className=\"block text-xs text-zinc-500 dark:text-zinc-400 mt-0.5\">\n {workflow.nodes.length} nodes · Updated {formatDate(workflow.updatedAt)}\n </span>\n </button>\n\n <div className=\"relative\">\n <button\n onClick={(e) => {\n e.stopPropagation();\n setShowMenu(!showMenu);\n }}\n className=\"p-1 text-zinc-400 hover:text-zinc-600 dark:hover:text-zinc-300 rounded opacity-0 group-hover:opacity-100 transition-opacity\"\n >\n <svg className=\"w-4 h-4\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path d=\"M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z\" />\n </svg>\n </button>\n\n {showMenu && (\n <>\n <div className=\"fixed inset-0 z-10\" onClick={() => setShowMenu(false)} />\n <div className=\"absolute right-0 top-full mt-1 w-36 bg-white dark:bg-zinc-800 rounded-lg shadow-lg border border-zinc-200 dark:border-zinc-700 py-1 z-20\">\n <button\n onClick={(e) => {\n e.stopPropagation();\n setIsEditing(true);\n setShowMenu(false);\n }}\n className=\"w-full px-3 py-1.5 text-left text-sm text-zinc-700 dark:text-zinc-300 hover:bg-zinc-100 dark:hover:bg-zinc-700\"\n >\n Rename\n </button>\n <button\n onClick={(e) => {\n e.stopPropagation();\n onDuplicate();\n setShowMenu(false);\n }}\n className=\"w-full px-3 py-1.5 text-left text-sm text-zinc-700 dark:text-zinc-300 hover:bg-zinc-100 dark:hover:bg-zinc-700\"\n >\n Duplicate\n </button>\n <button\n onClick={(e) => {\n e.stopPropagation();\n if (window.confirm(\"Delete this workflow?\")) {\n onDelete();\n }\n setShowMenu(false);\n }}\n className=\"w-full px-3 py-1.5 text-left text-sm text-red-600 dark:text-red-400 hover:bg-zinc-100 dark:hover:bg-zinc-700\"\n >\n Delete\n </button>\n </div>\n </>\n )}\n </div>\n </div>\n\n {isActive && <span className=\"absolute top-2 right-2 w-2 h-2 bg-teal-500 rounded-full\" />}\n </div>\n );\n}\n\nexport function WorkflowLibrary() {\n const showLibrary = useWorkflowStore((s) => s.showLibrary);\n const toggleLibrary = useWorkflowStore((s) => s.toggleLibrary);\n const savedWorkflows = useWorkflowStore((s) => s.savedWorkflows);\n const activeWorkflowId = useWorkflowStore((s) => s.activeWorkflowId);\n const loadWorkflow = useWorkflowStore((s) => s.loadWorkflow);\n const deleteWorkflow = useWorkflowStore((s) => s.deleteWorkflow);\n const renameWorkflow = useWorkflowStore((s) => s.renameWorkflow);\n const duplicateWorkflow = useWorkflowStore((s) => s.duplicateWorkflow);\n const newWorkflow = useWorkflowStore((s) => s.newWorkflow);\n\n if (!showLibrary) return null;\n\n // Sort by most recently updated\n const sortedWorkflows = [...savedWorkflows].sort((a, b) => b.updatedAt - a.updatedAt);\n\n return (\n <>\n {/* Backdrop */}\n <div className=\"fixed inset-0 bg-black/20 dark:bg-black/40 z-40\" onClick={toggleLibrary} />\n\n {/* Panel */}\n <div className=\"fixed left-0 top-0 bottom-0 w-80 bg-zinc-50 dark:bg-zinc-900 border-r border-zinc-200 dark:border-zinc-700 z-50 flex flex-col shadow-xl\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-zinc-200 dark:border-zinc-700\">\n <h2 className=\"text-lg font-semibold text-zinc-900 dark:text-zinc-100\">My Workflows</h2>\n <button\n onClick={toggleLibrary}\n className=\"p-1 text-zinc-500 hover:text-zinc-700 dark:hover:text-zinc-300 rounded\"\n >\n <svg className=\"w-5 h-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </button>\n </div>\n\n {/* New Workflow Button */}\n <div className=\"p-4 border-b border-zinc-200 dark:border-zinc-700\">\n <button\n onClick={() => {\n newWorkflow();\n toggleLibrary();\n window.dispatchEvent(new window.CustomEvent(\"new-workflow-created\"));\n }}\n className=\"w-full flex items-center justify-center gap-2 px-4 py-2 text-sm font-medium text-white bg-teal-600 rounded-lg hover:bg-teal-700 transition-colors\"\n >\n <svg className=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 4v16m8-8H4\"\n />\n </svg>\n New Workflow\n </button>\n </div>\n\n {/* Workflow List */}\n <div className=\"flex-1 overflow-y-auto p-4\">\n {sortedWorkflows.length === 0 ? (\n <div className=\"text-center py-8\">\n <div className=\"w-12 h-12 mx-auto mb-3 rounded-full bg-zinc-200 dark:bg-zinc-700 flex items-center justify-center\">\n <svg\n className=\"w-6 h-6 text-zinc-400\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10\"\n />\n </svg>\n </div>\n <p className=\"text-sm text-zinc-500 dark:text-zinc-400\">No saved workflows yet</p>\n <p className=\"text-xs text-zinc-400 dark:text-zinc-500 mt-1\">\n Build a workflow and save it to see it here\n </p>\n </div>\n ) : (\n <div className=\"space-y-2\">\n {sortedWorkflows.map((workflow) => (\n <WorkflowItem\n key={workflow.id}\n workflow={workflow}\n isActive={workflow.id === activeWorkflowId}\n onLoad={() => {\n loadWorkflow(workflow.id);\n toggleLibrary();\n }}\n onDelete={() => deleteWorkflow(workflow.id)}\n onRename={(name) => renameWorkflow(workflow.id, name)}\n onDuplicate={() => duplicateWorkflow(workflow.id)}\n />\n ))}\n </div>\n )}\n </div>\n\n {/* Footer */}\n <div className=\"px-4 py-3 border-t border-zinc-200 dark:border-zinc-700 text-xs text-zinc-500 dark:text-zinc-400\">\n {savedWorkflows.length} workflow{savedWorkflows.length !== 1 ? \"s\" : \"\"} saved locally\n </div>\n </div>\n </>\n );\n}\n","import { useState } from \"react\";\nimport { useSettingsStore } from \"../stores/settingsStore\";\n\n// Provider metadata\nconst CLOUD_PROVIDERS = [\n {\n id: \"openai\" as const,\n name: \"OpenAI\",\n description: \"GPT-4 Vision, GPT-4 Text, DALL-E 3\",\n placeholder: \"sk-...\",\n docsUrl: \"https://platform.openai.com/api-keys\",\n },\n {\n id: \"anthropic\" as const,\n name: \"Anthropic\",\n description: \"Claude Vision, Claude Text\",\n placeholder: \"sk-ant-...\",\n docsUrl: \"https://console.anthropic.com/settings/keys\",\n },\n {\n id: \"gemini\" as const,\n name: \"Google AI\",\n description: \"Gemini Vision, Gemini Text, Gemini Edit\",\n placeholder: \"AIza...\",\n docsUrl: \"https://aistudio.google.com/apikey\",\n },\n {\n id: \"grok\" as const,\n name: \"xAI (Grok)\",\n description: \"Grok Vision, Grok Text\",\n placeholder: \"xai-...\",\n docsUrl: \"https://console.x.ai/\",\n },\n {\n id: \"openrouter\" as const,\n name: \"OpenRouter\",\n description: \"Access multiple models with one API key\",\n placeholder: \"sk-or-...\",\n docsUrl: \"https://openrouter.ai/keys\",\n },\n];\n\nconst LOCAL_PROVIDERS = [\n {\n id: \"ollama\" as const,\n name: \"Ollama\",\n description: \"Local LLaVA Vision, Llama/Mistral Text\",\n defaultUrl: \"http://localhost:11434\",\n docsUrl: \"https://ollama.ai\",\n },\n {\n id: \"lmstudio\" as const,\n name: \"LM Studio\",\n description: \"Local models via OpenAI-compatible API\",\n defaultUrl: \"http://localhost:1234\",\n docsUrl: \"https://lmstudio.ai\",\n },\n];\n\nfunction CloudProviderRow({ provider }: { provider: (typeof CLOUD_PROVIDERS)[number] }) {\n const ai = useSettingsStore((s) => s.ai);\n const setAIProvider = useSettingsStore((s) => s.setAIProvider);\n\n const config = ai[provider.id];\n const isEnabled = config?.enabled ?? false;\n const apiKey = (config as { apiKey?: string })?.apiKey ?? \"\";\n\n const [localKey, setLocalKey] = useState(apiKey);\n const [showKey, setShowKey] = useState(false);\n\n const handleToggle = () => {\n setAIProvider(provider.id, {\n apiKey: localKey,\n enabled: !isEnabled,\n });\n };\n\n const handleKeyChange = (value: string) => {\n setLocalKey(value);\n setAIProvider(provider.id, {\n apiKey: value,\n enabled: isEnabled,\n });\n };\n\n return (\n <div className=\"flex items-start gap-4 p-4 border border-gray-200 dark:border-zinc-700 rounded-lg\">\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium text-gray-900 dark:text-white\">{provider.name}</span>\n <a\n href={provider.docsUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-xs text-teal-600 dark:text-teal-400 hover:underline\"\n >\n Get API key\n </a>\n </div>\n <p className=\"text-sm text-gray-500 dark:text-zinc-400 mt-0.5\">{provider.description}</p>\n <div className=\"mt-2 flex items-center gap-2\">\n <div className=\"relative flex-1\">\n <input\n type={showKey ? \"text\" : \"password\"}\n value={localKey}\n onChange={(e) => handleKeyChange(e.target.value)}\n placeholder={provider.placeholder}\n className=\"w-full px-3 py-1.5 text-sm border border-gray-300 dark:border-zinc-600 rounded bg-white dark:bg-zinc-800 text-gray-900 dark:text-white placeholder-gray-400 dark:placeholder-zinc-500\"\n />\n <button\n type=\"button\"\n onClick={() => setShowKey(!showKey)}\n className=\"absolute right-2 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 dark:hover:text-zinc-300\"\n >\n <svg className=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n {showKey ? (\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21\"\n />\n ) : (\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M15 12a3 3 0 11-6 0 3 3 0 016 0z M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z\"\n />\n )}\n </svg>\n </button>\n </div>\n </div>\n </div>\n <div className=\"flex items-center\">\n <button\n onClick={handleToggle}\n className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${\n isEnabled ? \"bg-teal-600\" : \"bg-gray-300 dark:bg-zinc-600\"\n }`}\n >\n <span\n className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${\n isEnabled ? \"translate-x-6\" : \"translate-x-1\"\n }`}\n />\n </button>\n </div>\n </div>\n );\n}\n\nfunction LocalProviderRow({ provider }: { provider: (typeof LOCAL_PROVIDERS)[number] }) {\n const ai = useSettingsStore((s) => s.ai);\n const setAIProvider = useSettingsStore((s) => s.setAIProvider);\n\n const config = ai[provider.id];\n const isEnabled = config?.enabled ?? false;\n const baseUrl = (config as { baseUrl?: string })?.baseUrl ?? provider.defaultUrl;\n\n const [localUrl, setLocalUrl] = useState(baseUrl);\n\n const handleToggle = () => {\n setAIProvider(provider.id, {\n baseUrl: localUrl,\n enabled: !isEnabled,\n });\n };\n\n const handleUrlChange = (value: string) => {\n setLocalUrl(value);\n setAIProvider(provider.id, {\n baseUrl: value,\n enabled: isEnabled,\n });\n };\n\n return (\n <div className=\"flex items-start gap-4 p-4 border border-gray-200 dark:border-zinc-700 rounded-lg\">\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium text-gray-900 dark:text-white\">{provider.name}</span>\n <a\n href={provider.docsUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-xs text-teal-600 dark:text-teal-400 hover:underline\"\n >\n Docs\n </a>\n <span className=\"text-xs bg-green-100 dark:bg-green-900/50 text-green-700 dark:text-green-400 px-1.5 py-0.5 rounded\">\n Local\n </span>\n </div>\n <p className=\"text-sm text-gray-500 dark:text-zinc-400 mt-0.5\">{provider.description}</p>\n <div className=\"mt-2\">\n <input\n type=\"text\"\n value={localUrl}\n onChange={(e) => handleUrlChange(e.target.value)}\n placeholder={provider.defaultUrl}\n className=\"w-full px-3 py-1.5 text-sm border border-gray-300 dark:border-zinc-600 rounded bg-white dark:bg-zinc-800 text-gray-900 dark:text-white placeholder-gray-400 dark:placeholder-zinc-500\"\n />\n </div>\n </div>\n <div className=\"flex items-center\">\n <button\n onClick={handleToggle}\n className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${\n isEnabled ? \"bg-teal-600\" : \"bg-gray-300 dark:bg-zinc-600\"\n }`}\n >\n <span\n className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${\n isEnabled ? \"translate-x-6\" : \"translate-x-1\"\n }`}\n />\n </button>\n </div>\n </div>\n );\n}\n\nexport function AISettings() {\n const showSettings = useSettingsStore((s) => s.showSettings);\n const closeSettings = useSettingsStore((s) => s.closeSettings);\n\n if (!showSettings) return null;\n\n return (\n <div className=\"fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50\">\n <div className=\"bg-white dark:bg-zinc-800 rounded-lg shadow-xl max-w-xl w-full mx-4 max-h-[85vh] flex flex-col\">\n <div className=\"flex items-center justify-between px-6 py-4 border-b border-gray-200 dark:border-zinc-700\">\n <div>\n <h2 className=\"text-lg font-semibold text-gray-900 dark:text-white\">\n AI Provider Settings\n </h2>\n <p className=\"text-sm text-gray-500 dark:text-zinc-400 mt-0.5\">\n Configure your AI providers for vision and text generation\n </p>\n </div>\n <button\n onClick={closeSettings}\n className=\"text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200\"\n >\n <svg className=\"h-6 w-6\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </button>\n </div>\n\n <div className=\"flex-1 overflow-y-auto p-6 space-y-6\">\n {/* Cloud Providers */}\n <section>\n <h3 className=\"text-sm font-medium text-gray-700 dark:text-zinc-300 mb-3\">\n Cloud Providers\n </h3>\n <div className=\"space-y-3\">\n {CLOUD_PROVIDERS.map((provider) => (\n <CloudProviderRow key={provider.id} provider={provider} />\n ))}\n </div>\n </section>\n\n {/* Local Providers */}\n <section>\n <h3 className=\"text-sm font-medium text-gray-700 dark:text-zinc-300 mb-3\">\n Local Providers\n </h3>\n <div className=\"space-y-3\">\n {LOCAL_PROVIDERS.map((provider) => (\n <LocalProviderRow key={provider.id} provider={provider} />\n ))}\n </div>\n </section>\n\n {/* Privacy Notice */}\n <div className=\"bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg p-4\">\n <div className=\"flex items-start gap-3\">\n <svg\n className=\"w-5 h-5 text-blue-600 dark:text-blue-400 mt-0.5\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z\"\n />\n </svg>\n <div>\n <p className=\"text-sm font-medium text-blue-900 dark:text-blue-300\">\n Your keys stay local\n </p>\n <p className=\"text-sm text-blue-700 dark:text-blue-400 mt-1\">\n API keys are stored in your browser only and sent directly to providers. They\n never pass through our servers.\n </p>\n </div>\n </div>\n </div>\n </div>\n\n <div className=\"flex justify-end px-6 py-4 border-t border-gray-200 dark:border-zinc-700\">\n <button\n onClick={closeSettings}\n className=\"px-4 py-2 text-sm font-medium text-white bg-teal-600 rounded-md hover:bg-teal-700\"\n >\n Done\n </button>\n </div>\n </div>\n </div>\n );\n}\n","import { useState, useRef, useEffect, useCallback } from \"react\";\nimport type {\n GenerateWorkflowMessage,\n GeneratedWorkflowData,\n GenerateStatusReason,\n GenerationPhase,\n GenerationSSEEvent,\n} from \"@teamflojo/floimg-studio-shared\";\nimport { getGenerateStatus } from \"../api/client\";\nimport { createSSEConnection, type SSEConnection } from \"../api/sse\";\n\n// Module-level connection reference for cancellation\n// (Not in component state because SSEConnection is not serializable)\nlet activeGenerationConnection: SSEConnection | null = null;\n\ninterface AIChatProps {\n isOpen: boolean;\n onClose: () => void;\n onApplyWorkflow: (workflow: GeneratedWorkflowData) => void;\n}\n\nexport function AIChat({ isOpen, onClose, onApplyWorkflow }: AIChatProps) {\n const [messages, setMessages] = useState<GenerateWorkflowMessage[]>([]);\n const [input, setInput] = useState(\"\");\n const [isLoading, setIsLoading] = useState(false);\n const [generationPhase, setGenerationPhase] = useState<GenerationPhase | null>(null);\n const [generationMessage, setGenerationMessage] = useState(\"\");\n const [error, setError] = useState<string | null>(null);\n const [isAvailable, setIsAvailable] = useState<boolean | null>(null);\n const [statusMessage, setStatusMessage] = useState(\"\");\n const [statusReason, setStatusReason] = useState<GenerateStatusReason | undefined>();\n const [isCloudDeployment, setIsCloudDeployment] = useState(false);\n const [supportUrl, setSupportUrl] = useState<string | undefined>();\n const messagesEndRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLTextAreaElement>(null);\n\n // Check if generation is available on mount\n useEffect(() => {\n if (isOpen && isAvailable === null) {\n getGenerateStatus()\n .then((status) => {\n setIsAvailable(status.available);\n setStatusMessage(status.message);\n setStatusReason(status.reason);\n setIsCloudDeployment(status.isCloudDeployment ?? false);\n setSupportUrl(status.supportUrl);\n })\n .catch(() => {\n setIsAvailable(false);\n setStatusMessage(\"Failed to check AI availability\");\n setStatusReason(\"service_unavailable\");\n });\n }\n }, [isOpen, isAvailable]);\n\n // Focus input when opened\n useEffect(() => {\n if (isOpen && inputRef.current) {\n inputRef.current.focus();\n }\n }, [isOpen]);\n\n // Scroll to bottom on new messages\n useEffect(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: \"smooth\" });\n }, [messages]);\n\n const handleSubmit = useCallback(() => {\n if (!input.trim() || isLoading) return;\n\n const userMessage: GenerateWorkflowMessage = {\n role: \"user\",\n content: input.trim(),\n timestamp: Date.now(),\n };\n\n setMessages((prev) => [...prev, userMessage]);\n setInput(\"\");\n setIsLoading(true);\n setError(null);\n setGenerationPhase(null);\n setGenerationMessage(\"\");\n\n let receivedWorkflow: GeneratedWorkflowData | undefined;\n\n activeGenerationConnection = createSSEConnection<GenerationSSEEvent>(\n \"/api/generate/workflow/stream\",\n { prompt: userMessage.content, history: messages },\n {\n onMessage: (event) => {\n if (event.type === \"generation.started\") {\n // Started - no visible change needed\n }\n\n if (event.type === \"generation.progress\") {\n setGenerationPhase(event.data.phase);\n setGenerationMessage(event.data.message);\n }\n\n if (event.type === \"generation.completed\") {\n receivedWorkflow = event.data;\n }\n\n if (event.type === \"generation.error\") {\n setError(event.data.error);\n }\n },\n onError: (err) => {\n activeGenerationConnection = null;\n setError(err.message || \"Failed to generate workflow\");\n setIsLoading(false);\n setGenerationPhase(null);\n },\n onClose: () => {\n activeGenerationConnection = null;\n // Stream completed - add the assistant message\n const assistantMessage: GenerateWorkflowMessage = {\n role: \"assistant\",\n content: receivedWorkflow\n ? \"I've created a workflow based on your description. Click 'Apply to Canvas' to use it.\"\n : \"I couldn't generate a workflow. Please try a different description.\",\n workflow: receivedWorkflow,\n timestamp: Date.now(),\n };\n\n setMessages((prev) => [...prev, assistantMessage]);\n setIsLoading(false);\n setGenerationPhase(null);\n setGenerationMessage(\"\");\n },\n }\n );\n }, [input, isLoading, messages]);\n\n const handleCancelGeneration = useCallback(() => {\n if (activeGenerationConnection) {\n activeGenerationConnection.abort();\n activeGenerationConnection = null;\n }\n setIsLoading(false);\n setGenerationPhase(null);\n setGenerationMessage(\"\");\n }, []);\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n handleSubmit();\n }\n };\n\n const handleApply = (workflow: GeneratedWorkflowData) => {\n onApplyWorkflow(workflow);\n onClose();\n };\n\n const handleNewChat = () => {\n setMessages([]);\n setError(null);\n };\n\n if (!isOpen) return null;\n\n return (\n <div className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50\">\n <div className=\"bg-white dark:bg-zinc-800 rounded-lg shadow-xl w-full max-w-2xl mx-4 h-[80vh] flex flex-col\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-gray-200 dark:border-zinc-700\">\n <div className=\"flex items-center gap-3\">\n <div className=\"flex items-center gap-2\">\n <svg\n className=\"h-5 w-5 text-teal-600\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z\"\n />\n </svg>\n <h3 className=\"text-lg font-semibold text-gray-900 dark:text-white\">\n AI Workflow Generator\n </h3>\n </div>\n <span className=\"text-xs bg-teal-100 dark:bg-teal-900 text-teal-700 dark:text-teal-300 px-2 py-0.5 rounded\">\n Gemini 3 Pro\n </span>\n </div>\n <div className=\"flex items-center gap-2\">\n {messages.length > 0 && (\n <button\n onClick={handleNewChat}\n className=\"p-2 text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200 hover:bg-gray-100 dark:hover:bg-zinc-700 rounded\"\n title=\"New Chat\"\n >\n <svg className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 4v16m8-8H4\"\n />\n </svg>\n </button>\n )}\n <button\n onClick={onClose}\n className=\"p-2 text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200 hover:bg-gray-100 dark:hover:bg-zinc-700 rounded\"\n >\n <svg className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </button>\n </div>\n </div>\n\n {/* Messages */}\n <div className=\"flex-1 overflow-auto p-4 space-y-4\">\n {isAvailable === false && (\n <div className=\"bg-amber-50 dark:bg-amber-900/30 border border-amber-200 dark:border-amber-800 rounded-lg p-4\">\n <div className=\"flex items-start gap-3\">\n {/* Icon varies by reason */}\n {statusReason === \"tier_limit\" ? (\n <svg\n className=\"h-5 w-5 text-amber-600 dark:text-amber-400 mt-0.5\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z\"\n />\n </svg>\n ) : (\n <svg\n className=\"h-5 w-5 text-amber-600 dark:text-amber-400 mt-0.5\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\n />\n </svg>\n )}\n <div>\n <p className=\"font-medium text-amber-800 dark:text-amber-200\">\n {statusReason === \"tier_limit\"\n ? \"AI Workflow Generation Not Available\"\n : \"AI Generation Not Available\"}\n </p>\n <p className=\"text-sm text-amber-700 dark:text-amber-300 mt-1\">{statusMessage}</p>\n\n {/* Context-aware actions */}\n <div className=\"flex flex-col sm:flex-row gap-2 mt-3\">\n {statusReason === \"tier_limit\" && (\n <a\n href=\"/pricing\"\n className=\"text-sm font-medium text-teal-600 hover:text-teal-700 dark:text-teal-400 dark:hover:text-teal-300\"\n >\n View Plans\n </a>\n )}\n {statusReason === \"service_unavailable\" && supportUrl && (\n <a\n href={supportUrl}\n className=\"text-sm font-medium text-amber-700 hover:text-amber-800 dark:text-amber-400 dark:hover:text-amber-300\"\n >\n Contact Support\n </a>\n )}\n {statusReason === \"not_configured\" && !isCloudDeployment && (\n <a\n href=\"https://floimg.com/docs/studio/ai-workflows\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-sm font-medium text-teal-600 hover:text-teal-700 dark:text-teal-400 dark:hover:text-teal-300\"\n >\n View Setup Guide\n </a>\n )}\n </div>\n </div>\n </div>\n </div>\n )}\n\n {messages.length === 0 && isAvailable !== false && (\n <div className=\"text-center py-8\">\n <div className=\"inline-flex items-center justify-center w-16 h-16 bg-teal-100 dark:bg-teal-900/50 rounded-full mb-4\">\n <svg\n className=\"h-8 w-8 text-teal-600 dark:text-teal-400\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z\"\n />\n </svg>\n </div>\n <h4 className=\"text-lg font-medium text-gray-900 dark:text-white mb-2\">\n Describe your workflow\n </h4>\n <p className=\"text-sm text-gray-500 dark:text-zinc-400 max-w-md mx-auto\">\n Tell me what you want to create and I'll generate a workflow for you. For\n example:\n </p>\n <div className=\"mt-4 space-y-2\">\n {[\n \"Generate an image of a sunset and resize it to 800x600\",\n \"Use Gemini text to generate 3 creative image prompts about space exploration, then generate images from each prompt\",\n \"Generate an image with Gemini, then use it as a reference to create a variation with different lighting\",\n \"Create a product mockup: generate a minimalist logo, then composite it onto a t-shirt image\",\n \"Build an AI art pipeline: generate a base image, apply artistic style transfer, then upscale to 4K\",\n ].map((example, i) => (\n <button\n key={i}\n onClick={() => setInput(example)}\n className=\"block w-full text-left text-sm px-4 py-2 bg-gray-100 dark:bg-zinc-700 hover:bg-gray-200 dark:hover:bg-zinc-600 rounded-lg text-gray-700 dark:text-zinc-300 transition-colors\"\n >\n "{example}"\n </button>\n ))}\n </div>\n </div>\n )}\n\n {messages.map((msg, idx) => (\n <div\n key={idx}\n className={`flex ${msg.role === \"user\" ? \"justify-end\" : \"justify-start\"}`}\n >\n <div\n className={`max-w-[80%] rounded-lg px-4 py-3 ${\n msg.role === \"user\"\n ? \"bg-teal-600 text-white\"\n : \"bg-gray-100 dark:bg-zinc-700 text-gray-900 dark:text-white\"\n }`}\n >\n <p className=\"text-sm whitespace-pre-wrap\">{msg.content}</p>\n\n {/* Workflow preview for assistant messages */}\n {msg.role === \"assistant\" && msg.workflow && (\n <div className=\"mt-3 pt-3 border-t border-gray-200 dark:border-zinc-600\">\n <div className=\"flex items-center justify-between mb-2\">\n <span className=\"text-xs font-medium text-gray-500 dark:text-zinc-400\">\n Generated Workflow\n </span>\n <button\n onClick={() => handleApply(msg.workflow!)}\n className=\"text-xs px-3 py-1 bg-teal-600 hover:bg-teal-700 text-white rounded transition-colors\"\n >\n Apply to Canvas\n </button>\n </div>\n <div className=\"bg-white dark:bg-zinc-800 rounded p-2 text-xs\">\n <div className=\"space-y-1\">\n {msg.workflow.nodes.map((node, nodeIdx) => (\n <div\n key={nodeIdx}\n className=\"flex items-center gap-2 text-gray-600 dark:text-zinc-300\"\n >\n <span className=\"font-mono bg-gray-100 dark:bg-zinc-700 px-1.5 py-0.5 rounded\">\n {node.nodeType.split(\":\").pop()}\n </span>\n {node.label && <span className=\"text-gray-400\">({node.label})</span>}\n </div>\n ))}\n {msg.workflow.edges.length > 0 && (\n <div className=\"text-gray-400 dark:text-zinc-500 pt-1\">\n {msg.workflow.edges.length} connection\n {msg.workflow.edges.length !== 1 ? \"s\" : \"\"}\n </div>\n )}\n </div>\n </div>\n </div>\n )}\n </div>\n </div>\n ))}\n\n {isLoading && (\n <div className=\"flex justify-start\">\n <div className=\"bg-gray-100 dark:bg-zinc-700 rounded-lg px-4 py-3\">\n <div className=\"flex items-center gap-3\">\n {/* Phase indicator */}\n <div className=\"flex items-center gap-2\">\n {generationPhase === \"analyzing\" && (\n <svg\n className=\"h-4 w-4 text-teal-500 animate-pulse\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\"\n />\n </svg>\n )}\n {generationPhase === \"selecting_nodes\" && (\n <svg\n className=\"h-4 w-4 text-teal-500 animate-pulse\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n 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 />\n </svg>\n )}\n {generationPhase === \"generating\" && (\n <svg\n className=\"h-4 w-4 text-teal-500 animate-spin\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n 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 />\n </svg>\n )}\n {generationPhase === \"validating\" && (\n <svg\n className=\"h-4 w-4 text-teal-500 animate-pulse\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z\"\n />\n </svg>\n )}\n {!generationPhase && (\n <div className=\"flex space-x-1\">\n <div className=\"w-2 h-2 bg-teal-400 rounded-full animate-bounce\" />\n <div\n className=\"w-2 h-2 bg-teal-400 rounded-full animate-bounce\"\n style={{ animationDelay: \"0.1s\" }}\n />\n <div\n className=\"w-2 h-2 bg-teal-400 rounded-full animate-bounce\"\n style={{ animationDelay: \"0.2s\" }}\n />\n </div>\n )}\n </div>\n <span className=\"text-sm text-gray-600 dark:text-zinc-300\">\n {generationMessage || \"Connecting...\"}\n </span>\n {/* Cancel button */}\n <button\n onClick={handleCancelGeneration}\n className=\"ml-2 px-2 py-1 text-xs font-medium text-red-600 dark:text-red-400 hover:bg-red-50 dark:hover:bg-red-900/30 rounded transition-colors\"\n title=\"Cancel generation\"\n >\n Cancel\n </button>\n </div>\n {/* Progress steps */}\n {generationPhase && (\n <div className=\"flex items-center gap-1 mt-2\">\n <div\n className={`h-1 w-8 rounded-full ${generationPhase === \"analyzing\" || generationPhase === \"selecting_nodes\" || generationPhase === \"generating\" || generationPhase === \"validating\" ? \"bg-teal-500\" : \"bg-gray-300 dark:bg-zinc-600\"}`}\n />\n <div\n className={`h-1 w-8 rounded-full ${generationPhase === \"selecting_nodes\" || generationPhase === \"generating\" || generationPhase === \"validating\" ? \"bg-teal-500\" : \"bg-gray-300 dark:bg-zinc-600\"}`}\n />\n <div\n className={`h-1 w-8 rounded-full ${generationPhase === \"generating\" || generationPhase === \"validating\" ? \"bg-teal-500\" : \"bg-gray-300 dark:bg-zinc-600\"}`}\n />\n <div\n className={`h-1 w-8 rounded-full ${generationPhase === \"validating\" ? \"bg-teal-500\" : \"bg-gray-300 dark:bg-zinc-600\"}`}\n />\n </div>\n )}\n </div>\n </div>\n )}\n\n {error && (\n <div className=\"bg-red-50 dark:bg-red-900/30 border border-red-200 dark:border-red-800 rounded-lg p-3\">\n <p className=\"text-sm text-red-700 dark:text-red-300\">{error}</p>\n </div>\n )}\n\n <div ref={messagesEndRef} />\n </div>\n\n {/* Input */}\n <div className=\"border-t border-gray-200 dark:border-zinc-700 p-4\">\n <div className=\"flex gap-2\">\n <textarea\n ref={inputRef}\n value={input}\n onChange={(e) => setInput(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={\n isAvailable === false\n ? \"AI generation not available\"\n : \"Describe what workflow you want to create...\"\n }\n disabled={isLoading || isAvailable === false}\n rows={2}\n className=\"flex-1 resize-none rounded-lg border border-gray-300 dark:border-zinc-600 bg-white dark:bg-zinc-900 px-4 py-2 text-sm text-gray-900 dark:text-white placeholder-gray-400 dark:placeholder-zinc-500 focus:border-teal-500 focus:outline-none focus:ring-1 focus:ring-teal-500 disabled:opacity-50 disabled:cursor-not-allowed\"\n />\n <button\n onClick={handleSubmit}\n disabled={!input.trim() || isLoading || isAvailable === false}\n className=\"self-end px-4 py-2 bg-teal-600 hover:bg-teal-700 disabled:opacity-50 disabled:cursor-not-allowed text-white rounded-lg transition-colors\"\n >\n <svg className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 19l9 2-9-18-9 18 9-2zm0 0v-8\"\n />\n </svg>\n </button>\n </div>\n <p className=\"text-xs text-gray-400 dark:text-zinc-500 mt-2\">\n Press Enter to send, Shift+Enter for new line\n </p>\n </div>\n </div>\n </div>\n );\n}\n","import { useState, useCallback } from \"react\";\n\n// Size/depth limits to prevent browser freeze on large outputs\nconst MAX_JSON_DEPTH = 20;\nconst MAX_ARRAY_ITEMS = 500;\nconst LARGE_OUTPUT_THRESHOLD = 100_000; // 100KB\n\ninterface DataOutput {\n dataType: \"text\" | \"json\";\n content: string;\n parsed?: Record<string, unknown>;\n}\n\ninterface OutputInspectorProps {\n isOpen: boolean;\n onClose: () => void;\n nodeId: string;\n nodeLabel: string;\n output: DataOutput;\n}\n\nexport function OutputInspector({ isOpen, onClose, nodeLabel, output }: OutputInspectorProps) {\n const [viewMode, setViewMode] = useState<\"formatted\" | \"raw\">(\"formatted\");\n const [copied, setCopied] = useState(false);\n\n const handleCopy = useCallback(() => {\n const textToCopy =\n viewMode === \"formatted\" && output.parsed\n ? JSON.stringify(output.parsed, null, 2)\n : output.content;\n\n navigator.clipboard.writeText(textToCopy).then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n });\n }, [viewMode, output]);\n\n if (!isOpen) return null;\n\n const hasFormattedView = output.dataType === \"json\" && output.parsed;\n\n return (\n <div className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50\">\n <div className=\"bg-white dark:bg-zinc-800 rounded-lg shadow-xl w-full max-w-3xl mx-4 max-h-[85vh] flex flex-col\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-gray-200 dark:border-zinc-700\">\n <div className=\"flex items-center gap-3\">\n <svg\n className=\"h-5 w-5 text-pink-500\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\"\n />\n </svg>\n <div>\n <h3 className=\"text-lg font-semibold text-gray-900 dark:text-white\">\n {nodeLabel} Output\n </h3>\n <span className=\"text-xs text-gray-500 dark:text-zinc-400\">\n {output.dataType === \"json\" ? \"Structured JSON\" : \"Text\"}\n </span>\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n {/* View mode toggle */}\n {hasFormattedView && (\n <div className=\"flex bg-gray-100 dark:bg-zinc-700 rounded-lg p-0.5\">\n <button\n onClick={() => setViewMode(\"formatted\")}\n className={`px-3 py-1 text-sm rounded-md transition-colors ${\n viewMode === \"formatted\"\n ? \"bg-white dark:bg-zinc-600 text-gray-900 dark:text-white shadow-sm\"\n : \"text-gray-600 dark:text-zinc-400 hover:text-gray-900 dark:hover:text-white\"\n }`}\n >\n Formatted\n </button>\n <button\n onClick={() => setViewMode(\"raw\")}\n className={`px-3 py-1 text-sm rounded-md transition-colors ${\n viewMode === \"raw\"\n ? \"bg-white dark:bg-zinc-600 text-gray-900 dark:text-white shadow-sm\"\n : \"text-gray-600 dark:text-zinc-400 hover:text-gray-900 dark:hover:text-white\"\n }`}\n >\n Raw\n </button>\n </div>\n )}\n {/* Close button */}\n <button\n onClick={onClose}\n className=\"p-2 text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200 hover:bg-gray-100 dark:hover:bg-zinc-700 rounded\"\n >\n <svg className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </button>\n </div>\n </div>\n\n {/* Large output warning */}\n {output.content.length > LARGE_OUTPUT_THRESHOLD && (\n <div className=\"px-4 py-2 bg-amber-50 dark:bg-amber-900/20 border-b border-amber-200 dark:border-amber-800 flex items-center gap-2\">\n <svg\n className=\"h-4 w-4 text-amber-600 dark:text-amber-400\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\n />\n </svg>\n <span className=\"text-sm text-amber-700 dark:text-amber-300\">\n Large output ({Math.round(output.content.length / 1024)}KB) - rendering may be slow\n </span>\n </div>\n )}\n\n {/* Content */}\n <div className=\"flex-1 overflow-auto p-4\">\n {viewMode === \"formatted\" && hasFormattedView ? (\n <JsonTree data={output.parsed!} />\n ) : (\n <pre className=\"whitespace-pre-wrap font-mono text-sm text-gray-800 dark:text-zinc-200 bg-gray-50 dark:bg-zinc-900 rounded-lg p-4 overflow-auto\">\n {output.content}\n </pre>\n )}\n </div>\n\n {/* Footer */}\n <div className=\"flex items-center justify-between px-4 py-3 border-t border-gray-200 dark:border-zinc-700\">\n <span className=\"text-xs text-gray-500 dark:text-zinc-400\">\n {output.content.length.toLocaleString()} characters\n </span>\n <button\n onClick={handleCopy}\n className=\"flex items-center gap-2 px-3 py-1.5 text-sm font-medium text-teal-600 dark:text-teal-400 hover:bg-teal-50 dark:hover:bg-teal-900/30 rounded-lg transition-colors\"\n >\n {copied ? (\n <>\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M5 13l4 4L19 7\"\n />\n </svg>\n Copied!\n </>\n ) : (\n <>\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"\n />\n </svg>\n Copy to Clipboard\n </>\n )}\n </button>\n </div>\n </div>\n </div>\n );\n}\n\n// Simple JSON tree viewer component with depth/size limits\nfunction JsonTree({ data }: { data: Record<string, unknown> }) {\n return (\n <div className=\"font-mono text-sm\">\n <JsonNode value={data} depth={0} maxDepth={MAX_JSON_DEPTH} />\n </div>\n );\n}\n\ninterface JsonNodeProps {\n value: unknown;\n depth: number;\n keyName?: string;\n maxDepth: number;\n}\n\nfunction JsonNode({ value, depth, keyName, maxDepth }: JsonNodeProps) {\n const indent = depth * 16;\n\n // Check depth limit\n if (depth >= maxDepth) {\n return (\n <div style={{ marginLeft: indent }} className=\"py-0.5\">\n {keyName && <span className=\"text-pink-600 dark:text-pink-400\">"{keyName}"</span>}\n {keyName && <span className=\"text-gray-600 dark:text-zinc-400\">: </span>}\n <span className=\"text-zinc-500 italic\">[max depth reached]</span>\n </div>\n );\n }\n\n if (value === null) {\n return (\n <div style={{ marginLeft: indent }} className=\"py-0.5\">\n {keyName && <span className=\"text-pink-600 dark:text-pink-400\">"{keyName}"</span>}\n {keyName && <span className=\"text-gray-600 dark:text-zinc-400\">: </span>}\n <span className=\"text-gray-500 dark:text-zinc-500\">null</span>\n </div>\n );\n }\n\n if (typeof value === \"boolean\") {\n return (\n <div style={{ marginLeft: indent }} className=\"py-0.5\">\n {keyName && <span className=\"text-pink-600 dark:text-pink-400\">"{keyName}"</span>}\n {keyName && <span className=\"text-gray-600 dark:text-zinc-400\">: </span>}\n <span className=\"text-blue-600 dark:text-blue-400\">{value.toString()}</span>\n </div>\n );\n }\n\n if (typeof value === \"number\") {\n return (\n <div style={{ marginLeft: indent }} className=\"py-0.5\">\n {keyName && <span className=\"text-pink-600 dark:text-pink-400\">"{keyName}"</span>}\n {keyName && <span className=\"text-gray-600 dark:text-zinc-400\">: </span>}\n <span className=\"text-green-600 dark:text-green-400\">{value}</span>\n </div>\n );\n }\n\n if (typeof value === \"string\") {\n // Truncate long strings in the tree view\n const displayValue = value.length > 100 ? value.slice(0, 100) + \"...\" : value;\n return (\n <div style={{ marginLeft: indent }} className=\"py-0.5\">\n {keyName && <span className=\"text-pink-600 dark:text-pink-400\">"{keyName}"</span>}\n {keyName && <span className=\"text-gray-600 dark:text-zinc-400\">: </span>}\n <span className=\"text-amber-600 dark:text-amber-400\">"{displayValue}"</span>\n </div>\n );\n }\n\n if (Array.isArray(value)) {\n const itemsToRender = value.slice(0, MAX_ARRAY_ITEMS);\n const hiddenCount = value.length - itemsToRender.length;\n\n return (\n <div style={{ marginLeft: indent }}>\n {keyName && (\n <div className=\"py-0.5\">\n <span className=\"text-pink-600 dark:text-pink-400\">"{keyName}"</span>\n <span className=\"text-gray-600 dark:text-zinc-400\">: </span>\n <span className=\"text-gray-500 dark:text-zinc-500\">[{value.length} items]</span>\n </div>\n )}\n {!keyName && <span className=\"text-gray-500 dark:text-zinc-500 py-0.5 block\">[</span>}\n {itemsToRender.map((item, index) => (\n <JsonNode key={index} value={item} depth={depth + 1} maxDepth={maxDepth} />\n ))}\n {hiddenCount > 0 && (\n <div style={{ marginLeft: (depth + 1) * 16 }} className=\"py-0.5 text-zinc-500 italic\">\n ...and {hiddenCount} more items\n </div>\n )}\n {!keyName && <span className=\"text-gray-500 dark:text-zinc-500 py-0.5 block\">]</span>}\n </div>\n );\n }\n\n if (typeof value === \"object\") {\n const entries = Object.entries(value);\n return (\n <div style={{ marginLeft: indent }}>\n {keyName && (\n <div className=\"py-0.5\">\n <span className=\"text-pink-600 dark:text-pink-400\">"{keyName}"</span>\n <span className=\"text-gray-600 dark:text-zinc-400\">: </span>\n <span className=\"text-gray-500 dark:text-zinc-500\">{\"{\"}</span>\n </div>\n )}\n {!keyName && <span className=\"text-gray-500 dark:text-zinc-500 py-0.5 block\">{\"{\"}</span>}\n {entries.map(([key, val]) => (\n <JsonNode key={key} value={val} depth={depth + 1} keyName={key} maxDepth={maxDepth} />\n ))}\n <div style={{ marginLeft: keyName ? 0 : indent }} className=\"py-0.5\">\n <span className=\"text-gray-500 dark:text-zinc-500\">{\"}\"}</span>\n </div>\n </div>\n );\n }\n\n return null;\n}\n","import { useState, useCallback, useEffect, DragEvent } from \"react\";\nimport { ReactFlowProvider, useReactFlow } from \"reactflow\";\nimport { WorkflowEditor } from \"./editor/WorkflowEditor\";\nimport { NodePalette } from \"./components/NodePalette\";\nimport { NodeInspector } from \"./components/NodeInspector\";\nimport { Toolbar } from \"./components/Toolbar\";\nimport { Gallery } from \"./components/Gallery\";\nimport { TemplateGallery } from \"./components/TemplateGallery\";\nimport { WorkflowLibrary } from \"./components/WorkflowLibrary\";\nimport { AISettings } from \"./components/AISettings\";\nimport { AIChat } from \"./components/AIChat\";\nimport { OutputInspector } from \"./components/OutputInspector\";\nimport { useWorkflowStore } from \"./stores/workflowStore\";\nimport { resolveTemplate } from \"@teamflojo/floimg-templates\";\nimport type { NodeDefinition, GeneratedWorkflowData } from \"@teamflojo/floimg-studio-shared\";\n\n// EditorDropZone - handles node drops with correct coordinate conversion\n// Must be inside ReactFlowProvider to access useReactFlow hook\nfunction EditorDropZone() {\n const { screenToFlowPosition } = useReactFlow();\n const addNode = useWorkflowStore((s) => s.addNode);\n\n const handleDrop = useCallback(\n (event: DragEvent<HTMLDivElement>) => {\n event.preventDefault();\n\n const data = event.dataTransfer.getData(\"application/json\");\n if (!data) return;\n\n try {\n const definition: NodeDefinition = JSON.parse(data);\n\n // Use screenToFlowPosition to correctly convert screen coordinates\n // to flow coordinates, accounting for zoom and pan\n const position = screenToFlowPosition({\n x: event.clientX,\n y: event.clientY,\n });\n\n addNode(definition, position);\n } catch (e) {\n console.error(\"Failed to parse dropped node:\", e);\n }\n },\n [addNode, screenToFlowPosition]\n );\n\n const handleDragOver = useCallback((event: DragEvent<HTMLDivElement>) => {\n event.preventDefault();\n event.dataTransfer.dropEffect = \"move\";\n }, []);\n\n return (\n <div className=\"flex-1\" onDrop={handleDrop} onDragOver={handleDragOver}>\n <WorkflowEditor />\n </div>\n );\n}\n\ntype TabType = \"editor\" | \"gallery\" | \"templates\";\n\nfunction App() {\n const [activeTab, setActiveTab] = useState<TabType>(\"editor\");\n const [showAIChat, setShowAIChat] = useState(false);\n const loadTemplate = useWorkflowStore((s) => s.loadTemplate);\n const loadGeneratedWorkflow = useWorkflowStore((s) => s.loadGeneratedWorkflow);\n\n // Output inspector state\n const inspectedNodeId = useWorkflowStore((s) => s.inspectedNodeId);\n const executionDataOutputs = useWorkflowStore((s) => s.execution.dataOutputs);\n const closeOutputInspector = useWorkflowStore((s) => s.closeOutputInspector);\n const nodes = useWorkflowStore((s) => s.nodes);\n\n // Get inspected node info\n const inspectedNode = inspectedNodeId ? nodes.find((n) => n.id === inspectedNodeId) : null;\n const inspectedOutput = inspectedNodeId ? executionDataOutputs[inspectedNodeId] : null;\n\n // Handle ?template=<id> URL parameter\n useEffect(() => {\n const params = new URLSearchParams(window.location.search);\n const templateId = params.get(\"template\");\n\n if (templateId) {\n // resolveTemplate handles both canonical IDs and legacy IDs\n const template = resolveTemplate(templateId);\n if (template) {\n loadTemplate(template);\n // Clean up URL without reload\n window.history.replaceState({}, \"\", window.location.pathname);\n }\n }\n }, [loadTemplate]);\n\n // Listen for workflow-loaded event (from Gallery)\n useEffect(() => {\n const handleWorkflowLoaded = () => {\n setActiveTab(\"editor\");\n };\n window.addEventListener(\"workflow-loaded\", handleWorkflowLoaded);\n return () => {\n window.removeEventListener(\"workflow-loaded\", handleWorkflowLoaded);\n };\n }, []);\n\n // Handler for template selection (from TemplateGallery)\n const handleTemplateSelect = useCallback(\n (templateId: string) => {\n const template = resolveTemplate(templateId);\n if (template) {\n loadTemplate(template);\n setActiveTab(\"editor\");\n }\n },\n [loadTemplate]\n );\n\n // Handler for AI-generated workflow\n const handleApplyWorkflow = useCallback(\n (workflow: GeneratedWorkflowData) => {\n loadGeneratedWorkflow(workflow);\n setActiveTab(\"editor\");\n },\n [loadGeneratedWorkflow]\n );\n\n return (\n <ReactFlowProvider>\n {/* AI Settings Modal */}\n <AISettings />\n\n {/* AI Chat Modal */}\n <AIChat\n isOpen={showAIChat}\n onClose={() => setShowAIChat(false)}\n onApplyWorkflow={handleApplyWorkflow}\n />\n\n {/* Output Inspector Modal */}\n {inspectedNode && inspectedOutput && (\n <OutputInspector\n isOpen={true}\n onClose={closeOutputInspector}\n nodeId={inspectedNodeId!}\n nodeLabel={\n (inspectedNode.data as { providerLabel?: string }).providerLabel ||\n inspectedNode.type ||\n \"Node\"\n }\n output={inspectedOutput}\n />\n )}\n\n {/* Workflow Library slide-out panel */}\n <WorkflowLibrary />\n\n <div className=\"h-screen flex flex-col bg-gray-100 dark:bg-zinc-900\">\n <Toolbar />\n\n {/* Tab navigation */}\n <div className=\"bg-white dark:bg-zinc-800 border-b border-gray-200 dark:border-zinc-700\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex\">\n <button\n onClick={() => setActiveTab(\"editor\")}\n className={`px-6 py-3 text-sm font-medium border-b-2 transition-colors ${\n activeTab === \"editor\"\n ? \"border-teal-500 text-teal-600 dark:text-teal-400\"\n : \"border-transparent text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200\"\n }`}\n >\n Editor\n </button>\n <button\n onClick={() => setActiveTab(\"gallery\")}\n className={`px-6 py-3 text-sm font-medium border-b-2 transition-colors ${\n activeTab === \"gallery\"\n ? \"border-teal-500 text-teal-600 dark:text-teal-400\"\n : \"border-transparent text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200\"\n }`}\n >\n Images\n </button>\n <button\n onClick={() => setActiveTab(\"templates\")}\n className={`px-6 py-3 text-sm font-medium border-b-2 transition-colors ${\n activeTab === \"templates\"\n ? \"border-teal-500 text-teal-600 dark:text-teal-400\"\n : \"border-transparent text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200\"\n }`}\n >\n Templates\n </button>\n </div>\n\n {/* AI Generate button */}\n <button\n onClick={() => setShowAIChat(true)}\n className=\"mr-4 px-4 py-1.5 text-sm font-medium text-white bg-gradient-to-r from-teal-500 to-cyan-500 hover:from-teal-600 hover:to-cyan-600 rounded-full flex items-center gap-2 transition-all shadow-sm hover:shadow\"\n >\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z\"\n />\n </svg>\n AI Generate\n </button>\n </div>\n </div>\n\n {/* Main content */}\n <div className=\"flex-1 flex overflow-hidden\">\n {activeTab === \"editor\" && (\n <>\n <NodePalette />\n <EditorDropZone />\n <NodeInspector />\n </>\n )}\n {activeTab === \"gallery\" && (\n <div className=\"flex-1 overflow-auto\">\n <Gallery />\n </div>\n )}\n {activeTab === \"templates\" && (\n <div className=\"flex-1 overflow-auto\">\n <TemplateGallery onSelect={handleTemplateSelect} />\n </div>\n )}\n </div>\n </div>\n </ReactFlowProvider>\n );\n}\n\nexport default App;\n"],"names":["createJSONStorage","getStorage","options","storage","name","_a","parse","str2","str","newValue","toThenable","fn","input","result","onFulfilled","_onRejected","e","_onFulfilled","onRejected","persistImpl","config","baseOptions","set","get","api","state","persistedState","currentState","hasHydrated","hydrationListeners","finishHydrationListeners","args","setItem","savedSetState","replace","configResult","stateFromStorage","hydrate","_b","cb","_a2","postRehydrationCallback","deserializedStorageValue","migration","migrationResult","migrated","migratedState","newOptions","persist","API_BASE","fetchJson","url","response","error","getGenerators","getTransforms","getTextProviders","getVisionProviders","exportYaml","nodes","edges","listImages","getImageUrl","id","getImageWorkflow","uploadImage","file","formData","listUploads","deleteUpload","getUploadBlobUrl","importYaml","yaml","validateYaml","getGenerateStatus","createSSEConnection","body","handlers","controller","errorBody","reader","decoder","buffer","done","value","processBuffer","messages","message","processSSEMessage","lines","data","line","parsed","DEFAULT_OLLAMA_URL","DEFAULT_LMSTUDIO_URL","useSettingsStore","create","provider","newAI","ai","_c","_d","_e","_f","_g","activeExecutionConnection","nodeIdCounter","generateNodeId","generateWorkflowId","timestamp","random","useWorkflowStore","nodeId","template","idMap","studioNode","newId","studioEdge","newSource","newTarget","generators","transforms","textProviders","visionProviders","definition","position","getDefaultParams","props","newNode","node","nodeToDuplicate","n","connection","handleSuffix","newEdge","studioNodes","studioEdges","aiProviders","initialNodeStatus","resolve","reject","event","step","newNodeStatus","newPreviews","newDataOutputs","finalNodeStatus","errorNodeStatus","activeWorkflowId","activeWorkflowName","savedWorkflows","currentTemplateId","now","updated","wf","newWorkflow","workflow","filtered","duplicate","GRID_SPACING_X","GRID_SPACING_Y","NODES_PER_ROW","genNode","index","parts","nodeType","row","providerName","jsonSchema","outputSchema","key","prop","genEdge","params","field","getExecutionClass","nodeStatus","PreviewToggle","color","previewVisible","s","togglePreview","jsx","GeneratorNode","memo","selected","preview","borderClass","isAI","acceptsReferences","jsxs","Handle","Position","TransformNode","SaveNode","InputNode","updateNodeData","fileInputRef","useRef","handleFileSelect","useCallback","handleDrop","handleDragOver","handleInputChange","previewUrl","VisionNode","dataOutput","openOutputInspector","outputProperties","hasMultiOutput","Fragment","TextNode","nodeTypes","defaultEdgeOptions","MarkerType","WorkflowEditor","setNodes","setEdges","addEdge","setSelectedNode","memoizedNodeTypes","useMemo","isValidConnection","source","target","targetHandle","sourceNode","targetNode","onNodesChange","changes","applyNodeChanges","onEdgesChange","applyEdgeChanges","onConnect","edgesToRemove","existingHandle","newHandle","removeIds","onNodeClick","_event","onPaneClick","ReactFlow","Background","Controls","MiniMap","UploadGallery","onSelect","uploads","setUploads","useState","loading","setLoading","setError","fetchUploads","err","useEffect","handleDelete","prev","u","formatSize","bytes","upload","NodePalette","setGenerators","setTransforms","setTextProviders","setVisionProviders","addNode","showUploads","setShowUploads","fetchedGenerators","useQuery","fetchedTransforms","fetchedTextProviders","fetchedVisionProviders","handleDragStart","handleDoubleClick","inputDefinition","saveDefinition","generatorsByCategory","acc","g","cat","transformsByCategory","t","category","def","NodeInspector","selectedNodeId","deleteNode","selectedNode","schema","nodeLabel","isCloudSave","v","handleParamChange","getParamValue","isFieldVisible","_field","shapeType","fillType","FieldEditor","OutputSchemaEditor","onChange","label","inputClasses","opt","newPropertyName","setNewPropertyName","properties","propertyEntries","handleAddProperty","newSchema","handleRemoveProperty","newProperties","handleTypeChange","type","handleDescriptionChange","description","topologicalSort","nodeMap","inDegree","adjacency","edge","targets","queue","degree","sorted","neighbors","neighbor","newDegree","getNodeVarName","suffix","stringify","generateNodeCode","nodeVarNames","varName","imports","inputEdge","inputVarName","paramStr","k","generateJavaScript","sortedNodes","allImports","codeBlocks","code","imp","importLines","header","mainCode","block","ImportModal","isOpen","onClose","onImport","yamlContent","setYamlContent","isLoading","setIsLoading","isDragging","setIsDragging","handleImport","handleValidate","handleFileUpload","text","handleDragLeave","handleFileInputChange","Toolbar","brandingSlot","beforeActionsSlot","afterActionsSlot","hideAttribution","hideWorkflowLibrary","execution","execute","cancelExecution","exportToYaml","importFromYaml","openSettings","hasUnsavedChanges","saveWorkflow","toggleLibrary","setActiveWorkflowName","duplicateNode","showExport","setShowExport","showImport","setShowImport","exportTab","setExportTab","jsContent","setJsContent","notification","setNotification","isEditingName","setIsEditingName","editingName","setEditingName","handleNewWorkflow","handleSave","handleStartRename","handleSaveRename","trimmed","handleDuplicate","handleKeyDown","handleExecute","handleExport","js","handleCopy","content","importedNodes","importedEdges","idx","Gallery","loadTemplate","loadingWorkflow","setLoadingWorkflow","images","refetch","handleLoadWorkflow","imageId","metadata","image","ImageCard","onLoadWorkflow","formatDate","revenueChart","monthlyUsers","frameworkUsage","trafficBreakdown","apiFlow","systemArchitecture","gitWorkflow","dataVizTemplates","aiProductShot","aiHeroImage","aiMascot","aiLogoBrandKit","productPhotoEnhancement","aiArtSocialPost","aiWorkflowTemplates","socialMediaKit","avatarPipeline","watermarkBranding","filterShowcase","responsiveImages","teamHeadshots","screenshotDocs","blogOgImage","emailBanner","appIcons","marketingTemplates","brandedQR","darkQR","wifiQR","thumbnailGenerator","diagramWebp","utilityTemplates","allTemplates","coreTemplates","getTemplateById","getCoreTemplateById","getCoreCategories","categories","getCoreTemplatesByCategory","searchCoreTemplates","query","q","tag","resolveTemplate","TemplateGallery","selectedCategory","setSelectedCategory","searchQuery","setSearchQuery","getCategories","filteredTemplates","templates","TemplateCard","nodeCount","edgeCount","generatorColors","WorkflowItem","isActive","onLoad","onDelete","onRename","onDuplicate","isEditing","setIsEditing","editName","setEditName","showMenu","setShowMenu","handleRename","date","diffMs","diffMins","diffHours","diffDays","WorkflowLibrary","showLibrary","loadWorkflow","deleteWorkflow","renameWorkflow","duplicateWorkflow","sortedWorkflows","a","b","CLOUD_PROVIDERS","LOCAL_PROVIDERS","CloudProviderRow","setAIProvider","isEnabled","apiKey","localKey","setLocalKey","showKey","setShowKey","handleToggle","handleKeyChange","LocalProviderRow","baseUrl","localUrl","setLocalUrl","handleUrlChange","AISettings","showSettings","closeSettings","activeGenerationConnection","AIChat","onApplyWorkflow","setMessages","setInput","generationPhase","setGenerationPhase","generationMessage","setGenerationMessage","isAvailable","setIsAvailable","statusMessage","setStatusMessage","statusReason","setStatusReason","isCloudDeployment","setIsCloudDeployment","supportUrl","setSupportUrl","messagesEndRef","inputRef","status","handleSubmit","userMessage","receivedWorkflow","assistantMessage","handleCancelGeneration","handleApply","handleNewChat","example","i","msg","nodeIdx","MAX_JSON_DEPTH","MAX_ARRAY_ITEMS","LARGE_OUTPUT_THRESHOLD","OutputInspector","output","viewMode","setViewMode","copied","setCopied","textToCopy","hasFormattedView","JsonTree","JsonNode","depth","keyName","maxDepth","indent","displayValue","itemsToRender","hiddenCount","item","entries","val","EditorDropZone","screenToFlowPosition","useReactFlow","App","activeTab","setActiveTab","showAIChat","setShowAIChat","loadGeneratedWorkflow","inspectedNodeId","executionDataOutputs","closeOutputInspector","inspectedNode","inspectedOutput","templateId","handleWorkflowLoaded","handleTemplateSelect","handleApplyWorkflow","ReactFlowProvider"],"mappings":"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","x_google_ignoreList":[0]}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../node_modules/.pnpm/zustand@5.0.9_@types+react@18.3.27_immer@10.2.0_react@19.2.3_use-sync-external-store@1.6.0_react@19.2.3_/node_modules/zustand/esm/middleware.mjs","../src/api/client.ts","../src/api/sse.ts","../src/stores/settingsStore.ts","../src/stores/workflowStore.ts","../src/editor/nodeTypes.tsx","../src/editor/WorkflowEditor.tsx","../src/components/UploadGallery.tsx","../src/components/NodePalette.tsx","../src/components/NodeInspector.tsx","../src/utils/codeGenerator.ts","../src/components/ImportModal.tsx","../src/components/Toolbar.tsx","../src/components/Gallery.tsx","../../../../packages/floimg-templates/dist/templates/data-viz.js","../../../../packages/floimg-templates/dist/templates/ai-workflows.js","../../../../packages/floimg-templates/dist/templates/marketing.js","../../../../packages/floimg-templates/dist/templates/utilities.js","../../../../packages/floimg-templates/dist/index.js","../src/components/TemplateGallery.tsx","../src/components/WorkflowLibrary.tsx","../src/components/AISettings.tsx","../src/components/AIChat.tsx","../src/components/OutputInspector.tsx","../src/App.tsx"],"sourcesContent":["const reduxImpl = (reducer, initial) => (set, _get, api) => {\n api.dispatch = (action) => {\n set((state) => reducer(state, action), false, action);\n return action;\n };\n api.dispatchFromDevtools = true;\n return { dispatch: (...args) => api.dispatch(...args), ...initial };\n};\nconst redux = reduxImpl;\n\nconst trackedConnections = /* @__PURE__ */ new Map();\nconst getTrackedConnectionState = (name) => {\n const api = trackedConnections.get(name);\n if (!api) return {};\n return Object.fromEntries(\n Object.entries(api.stores).map(([key, api2]) => [key, api2.getState()])\n );\n};\nconst extractConnectionInformation = (store, extensionConnector, options) => {\n if (store === void 0) {\n return {\n type: \"untracked\",\n connection: extensionConnector.connect(options)\n };\n }\n const existingConnection = trackedConnections.get(options.name);\n if (existingConnection) {\n return { type: \"tracked\", store, ...existingConnection };\n }\n const newConnection = {\n connection: extensionConnector.connect(options),\n stores: {}\n };\n trackedConnections.set(options.name, newConnection);\n return { type: \"tracked\", store, ...newConnection };\n};\nconst removeStoreFromTrackedConnections = (name, store) => {\n if (store === void 0) return;\n const connectionInfo = trackedConnections.get(name);\n if (!connectionInfo) return;\n delete connectionInfo.stores[store];\n if (Object.keys(connectionInfo.stores).length === 0) {\n trackedConnections.delete(name);\n }\n};\nconst findCallerName = (stack) => {\n var _a, _b;\n if (!stack) return void 0;\n const traceLines = stack.split(\"\\n\");\n const apiSetStateLineIndex = traceLines.findIndex(\n (traceLine) => traceLine.includes(\"api.setState\")\n );\n if (apiSetStateLineIndex < 0) return void 0;\n const callerLine = ((_a = traceLines[apiSetStateLineIndex + 1]) == null ? void 0 : _a.trim()) || \"\";\n return (_b = /.+ (.+) .+/.exec(callerLine)) == null ? void 0 : _b[1];\n};\nconst devtoolsImpl = (fn, devtoolsOptions = {}) => (set, get, api) => {\n const { enabled, anonymousActionType, store, ...options } = devtoolsOptions;\n let extensionConnector;\n try {\n extensionConnector = (enabled != null ? enabled : (import.meta.env ? import.meta.env.MODE : void 0) !== \"production\") && window.__REDUX_DEVTOOLS_EXTENSION__;\n } catch (e) {\n }\n if (!extensionConnector) {\n return fn(set, get, api);\n }\n const { connection, ...connectionInformation } = extractConnectionInformation(store, extensionConnector, options);\n let isRecording = true;\n api.setState = ((state, replace, nameOrAction) => {\n const r = set(state, replace);\n if (!isRecording) return r;\n const action = nameOrAction === void 0 ? {\n type: anonymousActionType || findCallerName(new Error().stack) || \"anonymous\"\n } : typeof nameOrAction === \"string\" ? { type: nameOrAction } : nameOrAction;\n if (store === void 0) {\n connection == null ? void 0 : connection.send(action, get());\n return r;\n }\n connection == null ? void 0 : connection.send(\n {\n ...action,\n type: `${store}/${action.type}`\n },\n {\n ...getTrackedConnectionState(options.name),\n [store]: api.getState()\n }\n );\n return r;\n });\n api.devtools = {\n cleanup: () => {\n if (connection && typeof connection.unsubscribe === \"function\") {\n connection.unsubscribe();\n }\n removeStoreFromTrackedConnections(options.name, store);\n }\n };\n const setStateFromDevtools = (...a) => {\n const originalIsRecording = isRecording;\n isRecording = false;\n set(...a);\n isRecording = originalIsRecording;\n };\n const initialState = fn(api.setState, get, api);\n if (connectionInformation.type === \"untracked\") {\n connection == null ? void 0 : connection.init(initialState);\n } else {\n connectionInformation.stores[connectionInformation.store] = api;\n connection == null ? void 0 : connection.init(\n Object.fromEntries(\n Object.entries(connectionInformation.stores).map(([key, store2]) => [\n key,\n key === connectionInformation.store ? initialState : store2.getState()\n ])\n )\n );\n }\n if (api.dispatchFromDevtools && typeof api.dispatch === \"function\") {\n let didWarnAboutReservedActionType = false;\n const originalDispatch = api.dispatch;\n api.dispatch = (...args) => {\n if ((import.meta.env ? import.meta.env.MODE : void 0) !== \"production\" && args[0].type === \"__setState\" && !didWarnAboutReservedActionType) {\n console.warn(\n '[zustand devtools middleware] \"__setState\" action type is reserved to set state from the devtools. Avoid using it.'\n );\n didWarnAboutReservedActionType = true;\n }\n originalDispatch(...args);\n };\n }\n connection.subscribe((message) => {\n var _a;\n switch (message.type) {\n case \"ACTION\":\n if (typeof message.payload !== \"string\") {\n console.error(\n \"[zustand devtools middleware] Unsupported action format\"\n );\n return;\n }\n return parseJsonThen(\n message.payload,\n (action) => {\n if (action.type === \"__setState\") {\n if (store === void 0) {\n setStateFromDevtools(action.state);\n return;\n }\n if (Object.keys(action.state).length !== 1) {\n console.error(\n `\n [zustand devtools middleware] Unsupported __setState action format.\n When using 'store' option in devtools(), the 'state' should have only one key, which is a value of 'store' that was passed in devtools(),\n and value of this only key should be a state object. Example: { \"type\": \"__setState\", \"state\": { \"abc123Store\": { \"foo\": \"bar\" } } }\n `\n );\n }\n const stateFromDevtools = action.state[store];\n if (stateFromDevtools === void 0 || stateFromDevtools === null) {\n return;\n }\n if (JSON.stringify(api.getState()) !== JSON.stringify(stateFromDevtools)) {\n setStateFromDevtools(stateFromDevtools);\n }\n return;\n }\n if (!api.dispatchFromDevtools) return;\n if (typeof api.dispatch !== \"function\") return;\n api.dispatch(action);\n }\n );\n case \"DISPATCH\":\n switch (message.payload.type) {\n case \"RESET\":\n setStateFromDevtools(initialState);\n if (store === void 0) {\n return connection == null ? void 0 : connection.init(api.getState());\n }\n return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n case \"COMMIT\":\n if (store === void 0) {\n connection == null ? void 0 : connection.init(api.getState());\n return;\n }\n return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n case \"ROLLBACK\":\n return parseJsonThen(message.state, (state) => {\n if (store === void 0) {\n setStateFromDevtools(state);\n connection == null ? void 0 : connection.init(api.getState());\n return;\n }\n setStateFromDevtools(state[store]);\n connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n });\n case \"JUMP_TO_STATE\":\n case \"JUMP_TO_ACTION\":\n return parseJsonThen(message.state, (state) => {\n if (store === void 0) {\n setStateFromDevtools(state);\n return;\n }\n if (JSON.stringify(api.getState()) !== JSON.stringify(state[store])) {\n setStateFromDevtools(state[store]);\n }\n });\n case \"IMPORT_STATE\": {\n const { nextLiftedState } = message.payload;\n const lastComputedState = (_a = nextLiftedState.computedStates.slice(-1)[0]) == null ? void 0 : _a.state;\n if (!lastComputedState) return;\n if (store === void 0) {\n setStateFromDevtools(lastComputedState);\n } else {\n setStateFromDevtools(lastComputedState[store]);\n }\n connection == null ? void 0 : connection.send(\n null,\n // FIXME no-any\n nextLiftedState\n );\n return;\n }\n case \"PAUSE_RECORDING\":\n return isRecording = !isRecording;\n }\n return;\n }\n });\n return initialState;\n};\nconst devtools = devtoolsImpl;\nconst parseJsonThen = (stringified, fn) => {\n let parsed;\n try {\n parsed = JSON.parse(stringified);\n } catch (e) {\n console.error(\n \"[zustand devtools middleware] Could not parse the received json\",\n e\n );\n }\n if (parsed !== void 0) fn(parsed);\n};\n\nconst subscribeWithSelectorImpl = (fn) => (set, get, api) => {\n const origSubscribe = api.subscribe;\n api.subscribe = ((selector, optListener, options) => {\n let listener = selector;\n if (optListener) {\n const equalityFn = (options == null ? void 0 : options.equalityFn) || Object.is;\n let currentSlice = selector(api.getState());\n listener = (state) => {\n const nextSlice = selector(state);\n if (!equalityFn(currentSlice, nextSlice)) {\n const previousSlice = currentSlice;\n optListener(currentSlice = nextSlice, previousSlice);\n }\n };\n if (options == null ? void 0 : options.fireImmediately) {\n optListener(currentSlice, currentSlice);\n }\n }\n return origSubscribe(listener);\n });\n const initialState = fn(set, get, api);\n return initialState;\n};\nconst subscribeWithSelector = subscribeWithSelectorImpl;\n\nfunction combine(initialState, create) {\n return (...args) => Object.assign({}, initialState, create(...args));\n}\n\nfunction createJSONStorage(getStorage, options) {\n let storage;\n try {\n storage = getStorage();\n } catch (e) {\n return;\n }\n const persistStorage = {\n getItem: (name) => {\n var _a;\n const parse = (str2) => {\n if (str2 === null) {\n return null;\n }\n return JSON.parse(str2, options == null ? void 0 : options.reviver);\n };\n const str = (_a = storage.getItem(name)) != null ? _a : null;\n if (str instanceof Promise) {\n return str.then(parse);\n }\n return parse(str);\n },\n setItem: (name, newValue) => storage.setItem(name, JSON.stringify(newValue, options == null ? void 0 : options.replacer)),\n removeItem: (name) => storage.removeItem(name)\n };\n return persistStorage;\n}\nconst toThenable = (fn) => (input) => {\n try {\n const result = fn(input);\n if (result instanceof Promise) {\n return result;\n }\n return {\n then(onFulfilled) {\n return toThenable(onFulfilled)(result);\n },\n catch(_onRejected) {\n return this;\n }\n };\n } catch (e) {\n return {\n then(_onFulfilled) {\n return this;\n },\n catch(onRejected) {\n return toThenable(onRejected)(e);\n }\n };\n }\n};\nconst persistImpl = (config, baseOptions) => (set, get, api) => {\n let options = {\n storage: createJSONStorage(() => localStorage),\n partialize: (state) => state,\n version: 0,\n merge: (persistedState, currentState) => ({\n ...currentState,\n ...persistedState\n }),\n ...baseOptions\n };\n let hasHydrated = false;\n const hydrationListeners = /* @__PURE__ */ new Set();\n const finishHydrationListeners = /* @__PURE__ */ new Set();\n let storage = options.storage;\n if (!storage) {\n return config(\n (...args) => {\n console.warn(\n `[zustand persist middleware] Unable to update item '${options.name}', the given storage is currently unavailable.`\n );\n set(...args);\n },\n get,\n api\n );\n }\n const setItem = () => {\n const state = options.partialize({ ...get() });\n return storage.setItem(options.name, {\n state,\n version: options.version\n });\n };\n const savedSetState = api.setState;\n api.setState = (state, replace) => {\n savedSetState(state, replace);\n return setItem();\n };\n const configResult = config(\n (...args) => {\n set(...args);\n return setItem();\n },\n get,\n api\n );\n api.getInitialState = () => configResult;\n let stateFromStorage;\n const hydrate = () => {\n var _a, _b;\n if (!storage) return;\n hasHydrated = false;\n hydrationListeners.forEach((cb) => {\n var _a2;\n return cb((_a2 = get()) != null ? _a2 : configResult);\n });\n const postRehydrationCallback = ((_b = options.onRehydrateStorage) == null ? void 0 : _b.call(options, (_a = get()) != null ? _a : configResult)) || void 0;\n return toThenable(storage.getItem.bind(storage))(options.name).then((deserializedStorageValue) => {\n if (deserializedStorageValue) {\n if (typeof deserializedStorageValue.version === \"number\" && deserializedStorageValue.version !== options.version) {\n if (options.migrate) {\n const migration = options.migrate(\n deserializedStorageValue.state,\n deserializedStorageValue.version\n );\n if (migration instanceof Promise) {\n return migration.then((result) => [true, result]);\n }\n return [true, migration];\n }\n console.error(\n `State loaded from storage couldn't be migrated since no migrate function was provided`\n );\n } else {\n return [false, deserializedStorageValue.state];\n }\n }\n return [false, void 0];\n }).then((migrationResult) => {\n var _a2;\n const [migrated, migratedState] = migrationResult;\n stateFromStorage = options.merge(\n migratedState,\n (_a2 = get()) != null ? _a2 : configResult\n );\n set(stateFromStorage, true);\n if (migrated) {\n return setItem();\n }\n }).then(() => {\n postRehydrationCallback == null ? void 0 : postRehydrationCallback(stateFromStorage, void 0);\n stateFromStorage = get();\n hasHydrated = true;\n finishHydrationListeners.forEach((cb) => cb(stateFromStorage));\n }).catch((e) => {\n postRehydrationCallback == null ? void 0 : postRehydrationCallback(void 0, e);\n });\n };\n api.persist = {\n setOptions: (newOptions) => {\n options = {\n ...options,\n ...newOptions\n };\n if (newOptions.storage) {\n storage = newOptions.storage;\n }\n },\n clearStorage: () => {\n storage == null ? void 0 : storage.removeItem(options.name);\n },\n getOptions: () => options,\n rehydrate: () => hydrate(),\n hasHydrated: () => hasHydrated,\n onHydrate: (cb) => {\n hydrationListeners.add(cb);\n return () => {\n hydrationListeners.delete(cb);\n };\n },\n onFinishHydration: (cb) => {\n finishHydrationListeners.add(cb);\n return () => {\n finishHydrationListeners.delete(cb);\n };\n }\n };\n if (!options.skipHydration) {\n hydrate();\n }\n return stateFromStorage || configResult;\n};\nconst persist = persistImpl;\n\nfunction ssrSafe(config, isSSR = typeof window === \"undefined\") {\n return (set, get, api) => {\n if (!isSSR) {\n return config(set, get, api);\n }\n const ssrSet = () => {\n throw new Error(\"Cannot set state of Zustand store in SSR\");\n };\n api.setState = ssrSet;\n return config(ssrSet, get, api);\n };\n}\n\nexport { combine, createJSONStorage, devtools, persist, redux, subscribeWithSelector, ssrSafe as unstable_ssrSafe };\n","import type {\n NodeDefinition,\n StudioNode,\n StudioEdge,\n ImageMetadata,\n GenerateWorkflowRequest,\n GenerateWorkflowResponse,\n GenerateStatusResponse,\n} from \"@teamflojo/floimg-studio-shared\";\n\nconst API_BASE = \"/api\";\n\nasync function fetchJson<T>(url: string, options?: RequestInit): Promise<T> {\n const response = await fetch(url, {\n ...options,\n headers: {\n \"Content-Type\": \"application/json\",\n ...options?.headers,\n },\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({ error: \"Unknown error\" }));\n throw new Error(error.error || `HTTP ${response.status}`);\n }\n\n return response.json();\n}\n\n// Node registry\nexport async function getGenerators(): Promise<NodeDefinition[]> {\n return fetchJson(`${API_BASE}/nodes/generators`);\n}\n\nexport async function getTransforms(): Promise<NodeDefinition[]> {\n return fetchJson(`${API_BASE}/nodes/transforms`);\n}\n\nexport async function getTextProviders(): Promise<NodeDefinition[]> {\n return fetchJson(`${API_BASE}/nodes/text`);\n}\n\nexport async function getVisionProviders(): Promise<NodeDefinition[]> {\n return fetchJson(`${API_BASE}/nodes/vision`);\n}\n\n// AI provider configuration passed to backend\nexport interface AIProviderConfig {\n openai?: { apiKey: string };\n anthropic?: { apiKey: string };\n gemini?: { apiKey: string };\n grok?: { apiKey: string };\n openrouter?: { apiKey: string };\n ollama?: { baseUrl: string };\n lmstudio?: { baseUrl: string };\n}\n\n// Execution\nexport async function executeWorkflow(\n nodes: StudioNode[],\n edges: StudioEdge[],\n aiProviders?: AIProviderConfig\n): Promise<{\n status: string;\n imageIds: string[];\n imageUrls?: string[]; // Presigned cloud URLs (FSC only)\n previews?: Record<string, string>;\n dataOutputs?: Record<\n string,\n { dataType: \"text\" | \"json\"; content: string; parsed?: Record<string, unknown> }\n >;\n error?: string;\n}> {\n return fetchJson(`${API_BASE}/execute/sync`, {\n method: \"POST\",\n body: JSON.stringify({ nodes, edges, aiProviders }),\n });\n}\n\n// Export\nexport async function exportYaml(\n nodes: StudioNode[],\n edges: StudioEdge[]\n): Promise<{ yaml: string }> {\n return fetchJson(`${API_BASE}/export/yaml`, {\n method: \"POST\",\n body: JSON.stringify({ nodes, edges }),\n });\n}\n\n// Images\nexport interface ImageInfo {\n id: string;\n filename: string;\n mime: string;\n size: number;\n createdAt: number;\n}\n\nexport async function listImages(): Promise<ImageInfo[]> {\n return fetchJson(`${API_BASE}/images`);\n}\n\nexport function getImageUrl(id: string): string {\n return `${API_BASE}/images/${id}/blob`;\n}\n\nexport async function getImageWorkflow(id: string): Promise<ImageMetadata | null> {\n try {\n return await fetchJson(`${API_BASE}/images/${id}/workflow`);\n } catch {\n return null; // Workflow metadata not available for this image\n }\n}\n\n// Uploads\nexport interface UploadInfo {\n id: string;\n filename: string;\n mime: string;\n size: number;\n createdAt: number;\n}\n\nexport async function uploadImage(file: File): Promise<UploadInfo> {\n const formData = new FormData();\n formData.append(\"file\", file);\n\n const response = await fetch(`${API_BASE}/uploads`, {\n method: \"POST\",\n body: formData,\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({ error: \"Upload failed\" }));\n throw new Error(error.error || `HTTP ${response.status}`);\n }\n\n return response.json();\n}\n\nexport async function listUploads(): Promise<UploadInfo[]> {\n return fetchJson(`${API_BASE}/uploads`);\n}\n\nexport async function getUploadThumbnail(id: string): Promise<{ dataUrl: string }> {\n return fetchJson(`${API_BASE}/uploads/${id}/thumbnail`);\n}\n\nexport async function deleteUpload(id: string): Promise<void> {\n const response = await fetch(`${API_BASE}/uploads/${id}`, {\n method: \"DELETE\",\n });\n if (!response.ok) {\n throw new Error(`Failed to delete upload: ${response.status}`);\n }\n}\n\nexport function getUploadBlobUrl(id: string): string {\n return `${API_BASE}/uploads/${id}/blob`;\n}\n\n// Input nodes\nexport async function getInputNodes(): Promise<NodeDefinition[]> {\n return fetchJson(`${API_BASE}/nodes/inputs`);\n}\n\n// Import\nexport interface ImportResult {\n success: boolean;\n nodes: StudioNode[];\n edges: StudioEdge[];\n name: string;\n error?: string;\n line?: number;\n column?: number;\n}\n\nexport interface ImportValidationResult {\n valid: boolean;\n errors: Array<{ message: string; line?: number; column?: number }>;\n}\n\nexport async function importYaml(yaml: string): Promise<ImportResult> {\n return fetchJson(`${API_BASE}/import`, {\n method: \"POST\",\n body: JSON.stringify({ yaml }),\n });\n}\n\nexport async function validateYaml(yaml: string): Promise<ImportValidationResult> {\n return fetchJson(`${API_BASE}/import/validate`, {\n method: \"POST\",\n body: JSON.stringify({ yaml }),\n });\n}\n\n// Workflow Generation\nexport async function generateWorkflow(\n request: GenerateWorkflowRequest\n): Promise<GenerateWorkflowResponse> {\n return fetchJson(`${API_BASE}/generate/workflow`, {\n method: \"POST\",\n body: JSON.stringify(request),\n });\n}\n\nexport async function getGenerateStatus(): Promise<GenerateStatusResponse> {\n return fetchJson(`${API_BASE}/generate/status`);\n}\n","/**\n * Server-Sent Events (SSE) client utility\n *\n * Handles POST-based SSE connections for streaming execution and generation updates.\n * Uses fetch with streaming response body parsing.\n */\n\nexport interface SSEConnectionHandlers<T> {\n onMessage: (event: T) => void;\n onError: (error: Error) => void;\n onClose: () => void;\n}\n\nexport interface SSEConnection {\n abort: () => void;\n}\n\n/**\n * Create an SSE connection using POST request with JSON body.\n *\n * SSE typically uses GET, but we need POST to send workflow data.\n * This implements manual SSE parsing over a fetch streaming response.\n */\nexport function createSSEConnection<T>(\n url: string,\n body: unknown,\n handlers: SSEConnectionHandlers<T>\n): SSEConnection {\n const controller = new AbortController();\n\n // Start the streaming request\n (async () => {\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n signal: controller.signal,\n });\n\n if (!response.ok) {\n const errorBody = await response.json().catch(() => ({ error: \"Unknown error\" }));\n throw new Error(errorBody.error || `HTTP ${response.status}`);\n }\n\n const reader = response.body?.getReader();\n if (!reader) {\n throw new Error(\"Response body is not readable\");\n }\n\n const decoder = new globalThis.TextDecoder();\n let buffer = \"\";\n\n // Read the stream\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n // Process any remaining data in buffer\n if (buffer.trim()) {\n processBuffer(buffer, handlers);\n }\n break;\n }\n\n // Decode chunk and add to buffer\n buffer += decoder.decode(value, { stream: true });\n\n // Process complete SSE messages (separated by double newlines)\n const messages = buffer.split(\"\\n\\n\");\n buffer = messages.pop() || \"\"; // Keep incomplete message in buffer\n\n for (const message of messages) {\n if (message.trim()) {\n processSSEMessage(message, handlers);\n }\n }\n }\n\n handlers.onClose();\n } catch (error) {\n // Don't report abort errors\n if (error instanceof Error && error.name === \"AbortError\") {\n handlers.onClose();\n return;\n }\n handlers.onError(error instanceof Error ? error : new Error(String(error)));\n }\n })();\n\n return {\n abort: () => controller.abort(),\n };\n}\n\n/**\n * Process a single SSE message block\n */\nfunction processSSEMessage<T>(message: string, handlers: SSEConnectionHandlers<T>): void {\n const lines = message.split(\"\\n\");\n let data = \"\";\n\n for (const line of lines) {\n if (line.startsWith(\"data: \")) {\n // Accumulate data lines (SSE spec allows multiple data: lines)\n data += (data ? \"\\n\" : \"\") + line.slice(6);\n }\n // Ignore other SSE fields (event:, id:, retry:) for simplicity\n }\n\n if (data) {\n try {\n const parsed = JSON.parse(data) as T;\n handlers.onMessage(parsed);\n } catch (error) {\n console.warn(\"SSE: Failed to parse message data:\", {\n error: error instanceof Error ? error.message : String(error),\n dataPreview: data.slice(0, 200),\n dataLength: data.length,\n });\n }\n }\n}\n\n/**\n * Process remaining buffer content\n */\nfunction processBuffer<T>(buffer: string, handlers: SSEConnectionHandlers<T>): void {\n const lines = buffer.split(\"\\n\");\n let data = \"\";\n\n for (const line of lines) {\n if (line.startsWith(\"data: \")) {\n data += (data ? \"\\n\" : \"\") + line.slice(6);\n }\n }\n\n if (data) {\n try {\n const parsed = JSON.parse(data) as T;\n handlers.onMessage(parsed);\n } catch (error) {\n // Log incomplete/malformed data at end of stream for debugging\n console.warn(\"SSE: Incomplete data at end of stream:\", {\n error: error instanceof Error ? error.message : String(error),\n dataPreview: data.slice(0, 200),\n dataLength: data.length,\n });\n }\n }\n}\n","import { create } from \"zustand\";\nimport { persist } from \"zustand/middleware\";\n\n// Provider configuration for cloud APIs\ninterface CloudProvider {\n apiKey: string;\n enabled: boolean;\n}\n\n// Provider configuration for local APIs\ninterface LocalProvider {\n baseUrl: string;\n enabled: boolean;\n}\n\n// All AI provider settings\nexport interface AISettings {\n // Cloud providers (require API keys)\n openai?: CloudProvider;\n anthropic?: CloudProvider;\n gemini?: CloudProvider;\n grok?: CloudProvider;\n openrouter?: CloudProvider;\n\n // Local providers (no API key, just URL)\n ollama?: LocalProvider;\n lmstudio?: LocalProvider;\n}\n\ninterface SettingsStore {\n // AI provider settings\n ai: AISettings;\n setAIProvider: (provider: keyof AISettings, config: CloudProvider | LocalProvider) => void;\n clearAIProvider: (provider: keyof AISettings) => void;\n\n // Settings modal visibility\n showSettings: boolean;\n openSettings: () => void;\n closeSettings: () => void;\n\n // Get configured providers for API calls\n getConfiguredProviders: () => {\n openai?: { apiKey: string };\n anthropic?: { apiKey: string };\n gemini?: { apiKey: string };\n grok?: { apiKey: string };\n openrouter?: { apiKey: string };\n ollama?: { baseUrl: string };\n lmstudio?: { baseUrl: string };\n };\n}\n\n// Default URLs for local providers\nconst DEFAULT_OLLAMA_URL = \"http://localhost:11434\";\nconst DEFAULT_LMSTUDIO_URL = \"http://localhost:1234\";\n\nexport const useSettingsStore = create<SettingsStore>()(\n persist(\n (set, get) => ({\n ai: {\n ollama: {\n baseUrl: DEFAULT_OLLAMA_URL,\n enabled: false,\n },\n lmstudio: {\n baseUrl: DEFAULT_LMSTUDIO_URL,\n enabled: false,\n },\n },\n showSettings: false,\n\n setAIProvider: (provider, config) => {\n set((state) => ({\n ai: {\n ...state.ai,\n [provider]: config,\n },\n }));\n },\n\n clearAIProvider: (provider) => {\n set((state) => {\n const newAI = { ...state.ai };\n delete newAI[provider];\n return { ai: newAI };\n });\n },\n\n openSettings: () => set({ showSettings: true }),\n closeSettings: () => set({ showSettings: false }),\n\n getConfiguredProviders: () => {\n const { ai } = get();\n const result: ReturnType<SettingsStore[\"getConfiguredProviders\"]> = {};\n\n // Cloud providers - only include if enabled and has API key\n if (ai.openai?.enabled && ai.openai.apiKey) {\n result.openai = { apiKey: ai.openai.apiKey };\n }\n if (ai.anthropic?.enabled && ai.anthropic.apiKey) {\n result.anthropic = { apiKey: ai.anthropic.apiKey };\n }\n if (ai.gemini?.enabled && ai.gemini.apiKey) {\n result.gemini = { apiKey: ai.gemini.apiKey };\n }\n if (ai.grok?.enabled && ai.grok.apiKey) {\n result.grok = { apiKey: ai.grok.apiKey };\n }\n if (ai.openrouter?.enabled && ai.openrouter.apiKey) {\n result.openrouter = { apiKey: ai.openrouter.apiKey };\n }\n\n // Local providers - only include if enabled\n if (ai.ollama?.enabled) {\n result.ollama = { baseUrl: ai.ollama.baseUrl || DEFAULT_OLLAMA_URL };\n }\n if (ai.lmstudio?.enabled) {\n result.lmstudio = { baseUrl: ai.lmstudio.baseUrl || DEFAULT_LMSTUDIO_URL };\n }\n\n return result;\n },\n }),\n {\n name: \"floimg-studio-settings\",\n // Only persist AI settings, not modal visibility\n partialize: (state) => ({ ai: state.ai }),\n }\n )\n);\n","import { create } from \"zustand\";\nimport { persist } from \"zustand/middleware\";\nimport type { Node, Edge, Connection } from \"reactflow\";\nimport type {\n GeneratorNodeData,\n TransformNodeData,\n SaveNodeData,\n InputNodeData,\n VisionNodeData,\n TextNodeData,\n NodeDefinition,\n GeneratedWorkflowData,\n StudioNodeType,\n ExecutionSSEEvent,\n} from \"@teamflojo/floimg-studio-shared\";\nimport type { Template } from \"@teamflojo/floimg-templates\";\nimport { exportYaml } from \"../api/client\";\nimport { createSSEConnection, type SSEConnection } from \"../api/sse\";\n\n// Module-level variable to store active SSE connection (not in store since it's not serializable)\nlet activeExecutionConnection: SSEConnection | null = null;\nimport type { StudioNode, StudioEdge } from \"@teamflojo/floimg-studio-shared\";\nimport { useSettingsStore } from \"./settingsStore\";\n\ntype NodeData =\n | GeneratorNodeData\n | TransformNodeData\n | SaveNodeData\n | InputNodeData\n | VisionNodeData\n | TextNodeData;\n\ntype NodeExecutionStatus = \"idle\" | \"pending\" | \"running\" | \"completed\" | \"error\";\n\ninterface DataOutput {\n dataType: \"text\" | \"json\";\n content: string;\n parsed?: Record<string, unknown>;\n}\n\n// Saved workflow structure for persistence\nexport interface SavedWorkflow {\n id: string;\n name: string;\n nodes: Node<NodeData>[];\n edges: Edge[];\n createdAt: number;\n updatedAt: number;\n templateId?: string;\n}\n\ninterface ExecutionState {\n status: \"idle\" | \"running\" | \"completed\" | \"error\";\n imageIds: string[];\n imageUrls: string[]; // Presigned cloud URLs for thumbnails (FSC only)\n previews: Record<string, string>; // nodeId -> data URL\n dataOutputs: Record<string, DataOutput>; // nodeId -> text/json output (for vision/text nodes)\n nodeStatus: Record<string, NodeExecutionStatus>; // per-node execution status\n error?: string;\n}\n\ninterface WorkflowStore {\n // Nodes and edges (React Flow compatible)\n nodes: Node<NodeData>[];\n edges: Edge[];\n selectedNodeId: string | null;\n\n // Template tracking\n currentTemplateId: string | null;\n loadTemplate: (template: Template) => void;\n clearWorkflow: () => void;\n\n // Workflow persistence\n savedWorkflows: SavedWorkflow[];\n activeWorkflowId: string | null;\n activeWorkflowName: string;\n hasUnsavedChanges: boolean;\n showLibrary: boolean;\n\n // Workflow persistence methods\n saveWorkflow: (name?: string) => string;\n loadWorkflow: (id: string) => void;\n deleteWorkflow: (id: string) => void;\n renameWorkflow: (id: string, name: string) => void;\n duplicateWorkflow: (id: string) => string;\n newWorkflow: () => void;\n setActiveWorkflowName: (name: string) => void;\n toggleLibrary: () => void;\n markDirty: () => void;\n\n // Preview visibility per node (default: true)\n previewVisible: Record<string, boolean>;\n togglePreview: (id: string) => void;\n\n // Node registry\n generators: NodeDefinition[];\n transforms: NodeDefinition[];\n textProviders: NodeDefinition[];\n visionProviders: NodeDefinition[];\n setGenerators: (generators: NodeDefinition[]) => void;\n setTransforms: (transforms: NodeDefinition[]) => void;\n setTextProviders: (textProviders: NodeDefinition[]) => void;\n setVisionProviders: (visionProviders: NodeDefinition[]) => void;\n\n // Node operations\n addNode: (definition: NodeDefinition, position: { x: number; y: number }) => void;\n updateNodeData: (id: string, data: Partial<NodeData>) => void;\n deleteNode: (id: string) => void;\n duplicateNode: (id: string) => void;\n setNodes: (nodes: Node<NodeData>[]) => void;\n\n // Edge operations\n addEdge: (connection: Connection) => void;\n deleteEdge: (id: string) => void;\n setEdges: (edges: Edge[]) => void;\n\n // Selection\n setSelectedNode: (id: string | null) => void;\n\n // Execution\n execution: ExecutionState;\n execute: () => Promise<void>;\n cancelExecution: () => void;\n\n // Export\n exportToYaml: () => Promise<string>;\n\n // Import\n importFromYaml: (nodes: StudioNode[], edges: StudioEdge[], name?: string) => void;\n\n // AI-generated workflow\n loadGeneratedWorkflow: (workflow: GeneratedWorkflowData) => void;\n\n // Output inspector\n inspectedNodeId: string | null;\n openOutputInspector: (nodeId: string) => void;\n closeOutputInspector: () => void;\n}\n\nlet nodeIdCounter = 0;\n\nfunction generateNodeId(): string {\n return `node_${++nodeIdCounter}`;\n}\n\n// Helper to generate unique workflow IDs\nfunction generateWorkflowId(): string {\n const timestamp = Date.now();\n const random = Math.random().toString(36).substring(2, 8);\n return `wf_${timestamp}_${random}`;\n}\n\nexport const useWorkflowStore = create<WorkflowStore>()(\n persist(\n (set, get) => ({\n nodes: [],\n edges: [],\n selectedNodeId: null,\n currentTemplateId: null,\n previewVisible: {},\n generators: [],\n transforms: [],\n textProviders: [],\n visionProviders: [],\n\n // Workflow persistence state\n savedWorkflows: [],\n activeWorkflowId: null,\n activeWorkflowName: \"Untitled Workflow\",\n hasUnsavedChanges: false,\n showLibrary: false,\n\n execution: {\n status: \"idle\",\n imageIds: [],\n imageUrls: [],\n previews: {},\n dataOutputs: {},\n nodeStatus: {},\n },\n\n // Output inspector state\n inspectedNodeId: null,\n openOutputInspector: (nodeId) => set({ inspectedNodeId: nodeId }),\n closeOutputInspector: () => set({ inspectedNodeId: null }),\n\n loadTemplate: (template) => {\n // Convert StudioNodes to React Flow nodes with new IDs\n const idMap = new Map<string, string>();\n\n const nodes: Node<NodeData>[] = template.workflow.nodes.map((studioNode) => {\n const newId = generateNodeId();\n idMap.set(studioNode.id, newId);\n\n return {\n id: newId,\n type: studioNode.type,\n position: studioNode.position,\n data: studioNode.data as NodeData,\n };\n });\n\n // Convert edges with mapped IDs\n const edges: Edge[] = template.workflow.edges.map((studioEdge) => {\n const newSource = idMap.get(studioEdge.source) || studioEdge.source;\n const newTarget = idMap.get(studioEdge.target) || studioEdge.target;\n\n return {\n id: `edge_${newSource}_${newTarget}`,\n source: newSource,\n target: newTarget,\n };\n });\n\n set({\n nodes,\n edges,\n selectedNodeId: null,\n currentTemplateId: template.id,\n previewVisible: {},\n execution: {\n status: \"idle\",\n imageIds: [],\n imageUrls: [],\n previews: {},\n dataOutputs: {},\n nodeStatus: {},\n },\n });\n },\n\n clearWorkflow: () => {\n set({\n nodes: [],\n edges: [],\n selectedNodeId: null,\n currentTemplateId: null,\n previewVisible: {},\n execution: {\n status: \"idle\",\n imageIds: [],\n imageUrls: [],\n previews: {},\n dataOutputs: {},\n nodeStatus: {},\n },\n });\n },\n\n togglePreview: (id) => {\n set((state) => ({\n previewVisible: {\n ...state.previewVisible,\n [id]: state.previewVisible[id] === false ? true : false, // default true, toggle\n },\n }));\n },\n\n setGenerators: (generators) => set({ generators }),\n setTransforms: (transforms) => set({ transforms }),\n setTextProviders: (textProviders) => set({ textProviders }),\n setVisionProviders: (visionProviders) => set({ visionProviders }),\n\n addNode: (definition, position) => {\n const id = generateNodeId();\n let data: NodeData;\n\n if (definition.type === \"generator\") {\n data = {\n generatorName: definition.name,\n params: getDefaultParams(definition),\n isAI: definition.isAI, // Track if this is an AI generator (can accept text input)\n acceptsReferenceImages: definition.acceptsReferenceImages,\n maxReferenceImages: definition.maxReferenceImages,\n } as GeneratorNodeData;\n } else if (definition.type === \"transform\") {\n data = {\n operation: definition.name,\n providerName: definition.providerName, // Track which provider this transform belongs to\n isAI: definition.isAI, // Track if this is an AI transform (can accept text input)\n params: getDefaultParams(definition),\n acceptsReferenceImages: definition.acceptsReferenceImages,\n maxReferenceImages: definition.maxReferenceImages,\n } as TransformNodeData;\n } else if (definition.type === \"input\") {\n data = {\n uploadId: undefined,\n filename: undefined,\n mime: undefined,\n } as InputNodeData;\n } else if (definition.type === \"vision\") {\n data = {\n providerName: definition.name,\n providerLabel: definition.label, // Human-readable label (e.g., \"Gemini Vision\")\n params: getDefaultParams(definition),\n } as VisionNodeData;\n } else if (definition.type === \"text\") {\n data = {\n providerName: definition.name,\n providerLabel: definition.label, // Human-readable label (e.g., \"Gemini Text\")\n params: getDefaultParams(definition),\n } as TextNodeData;\n } else {\n // Save node - read provider and destination from definition params\n const props = definition.params?.properties || {};\n const provider = (props.provider?.default as string) || \"filesystem\";\n const destination = (props.destination?.default as string) || \"./output/image.png\";\n data = {\n destination,\n provider,\n } as SaveNodeData;\n }\n\n const newNode: Node<NodeData> = {\n id,\n type: definition.type,\n position,\n data,\n };\n\n set((state) => ({\n nodes: [...state.nodes, newNode],\n }));\n },\n\n updateNodeData: (id, data) => {\n set((state) => ({\n nodes: state.nodes.map((node) =>\n node.id === id ? { ...node, data: { ...node.data, ...data } } : node\n ),\n }));\n },\n\n deleteNode: (id) => {\n set((state) => ({\n nodes: state.nodes.filter((n) => n.id !== id),\n edges: state.edges.filter((e) => e.source !== id && e.target !== id),\n selectedNodeId: state.selectedNodeId === id ? null : state.selectedNodeId,\n }));\n },\n\n duplicateNode: (id) => {\n const state = get();\n const nodeToDuplicate = state.nodes.find((n) => n.id === id);\n if (!nodeToDuplicate) return;\n\n const newId = generateNodeId();\n const newNode: Node<NodeData> = {\n ...nodeToDuplicate,\n id: newId,\n position: {\n x: nodeToDuplicate.position.x + 50,\n y: nodeToDuplicate.position.y + 50,\n },\n data: JSON.parse(JSON.stringify(nodeToDuplicate.data)), // Deep clone\n selected: false,\n };\n\n set({\n nodes: [...state.nodes, newNode],\n selectedNodeId: newId, // Select the new node\n });\n },\n\n setNodes: (nodes) => set({ nodes }),\n\n addEdge: (connection) => {\n if (!connection.source || !connection.target) return;\n\n // Include sourceHandle and targetHandle in edge ID for uniqueness\n const handleSuffix = [connection.sourceHandle, connection.targetHandle]\n .filter(Boolean)\n .join(\"_\");\n const id = handleSuffix\n ? `edge_${connection.source}_${connection.target}_${handleSuffix}`\n : `edge_${connection.source}_${connection.target}`;\n\n const newEdge: Edge = {\n id,\n source: connection.source,\n target: connection.target,\n sourceHandle: connection.sourceHandle ?? undefined,\n targetHandle: connection.targetHandle ?? undefined,\n };\n\n set((state) => ({\n edges: [...state.edges, newEdge],\n }));\n },\n\n deleteEdge: (id) => {\n set((state) => ({\n edges: state.edges.filter((e) => e.id !== id),\n }));\n },\n\n setEdges: (edges) => set({ edges }),\n\n setSelectedNode: (id) => set({ selectedNodeId: id }),\n\n execute: async () => {\n const { nodes, edges } = get();\n\n // Convert React Flow nodes to StudioNodes\n const studioNodes = nodes.map((n) => ({\n id: n.id,\n type: n.type as \"generator\" | \"transform\" | \"save\",\n position: n.position,\n data: n.data,\n }));\n\n const studioEdges = edges.map((e) => ({\n id: e.id,\n source: e.source,\n target: e.target,\n sourceHandle: e.sourceHandle ?? undefined,\n targetHandle: e.targetHandle ?? undefined,\n }));\n\n // Get AI provider settings\n const aiProviders = useSettingsStore.getState().getConfiguredProviders();\n\n // Set all nodes to \"pending\" status (not running yet)\n const initialNodeStatus: Record<string, NodeExecutionStatus> = {};\n for (const node of nodes) {\n initialNodeStatus[node.id] = \"pending\";\n }\n\n set({\n execution: {\n status: \"running\",\n imageIds: [],\n imageUrls: [],\n previews: {},\n dataOutputs: {},\n nodeStatus: initialNodeStatus,\n },\n });\n\n // Use SSE streaming for real-time progress updates\n return new Promise<void>((resolve, reject) => {\n activeExecutionConnection = createSSEConnection<ExecutionSSEEvent>(\n \"/api/execute/stream\",\n { nodes: studioNodes, edges: studioEdges, aiProviders },\n {\n onMessage: (event) => {\n const state = get();\n\n if (event.type === \"execution.started\") {\n // All nodes start as pending, they'll transition to running as they execute\n }\n\n if (event.type === \"execution.step\") {\n const step = event.data;\n\n // Update the specific node's status\n const newNodeStatus = {\n ...state.execution.nodeStatus,\n [step.nodeId]: step.status as NodeExecutionStatus,\n };\n\n // Update previews if this step has one\n const newPreviews = step.preview\n ? { ...state.execution.previews, [step.nodeId]: step.preview }\n : state.execution.previews;\n\n // Update dataOutputs if this is a text/vision node\n const newDataOutputs =\n step.dataType && step.content\n ? {\n ...state.execution.dataOutputs,\n [step.nodeId]: {\n dataType: step.dataType,\n content: step.content,\n parsed: step.parsed,\n },\n }\n : state.execution.dataOutputs;\n\n set({\n execution: {\n ...state.execution,\n nodeStatus: newNodeStatus,\n previews: newPreviews,\n dataOutputs: newDataOutputs,\n },\n });\n }\n\n if (event.type === \"execution.completed\") {\n // Mark any remaining pending nodes as completed\n const finalNodeStatus = { ...state.execution.nodeStatus };\n for (const nodeId of Object.keys(finalNodeStatus)) {\n if (\n finalNodeStatus[nodeId] === \"pending\" ||\n finalNodeStatus[nodeId] === \"running\"\n ) {\n finalNodeStatus[nodeId] = \"completed\";\n }\n }\n\n set({\n execution: {\n ...state.execution,\n status: \"completed\",\n imageIds: event.data.imageIds,\n imageUrls: event.data.imageUrls,\n nodeStatus: finalNodeStatus,\n },\n });\n resolve();\n }\n\n if (event.type === \"execution.error\") {\n // Mark nodes as error\n const errorNodeStatus = { ...state.execution.nodeStatus };\n if (event.data.nodeId) {\n errorNodeStatus[event.data.nodeId] = \"error\";\n }\n\n set({\n execution: {\n ...state.execution,\n status: \"error\",\n nodeStatus: errorNodeStatus,\n error: event.data.error,\n },\n });\n reject(new Error(event.data.error));\n }\n },\n onError: (error) => {\n const state = get();\n const errorNodeStatus: Record<string, NodeExecutionStatus> = {};\n for (const nodeId of Object.keys(state.execution.nodeStatus)) {\n errorNodeStatus[nodeId] = \"error\";\n }\n\n set({\n execution: {\n ...state.execution,\n status: \"error\",\n nodeStatus: errorNodeStatus,\n error: error.message,\n },\n });\n reject(error);\n },\n onClose: () => {\n // Clear the connection reference\n activeExecutionConnection = null;\n\n // Stream closed - check why\n const state = get();\n if (state.execution.status === \"running\") {\n // Check if this was a user cancellation (status would be 'cancelled' if so)\n // Otherwise treat as unexpected closure\n set({\n execution: {\n ...state.execution,\n status: \"error\",\n error: \"Connection closed unexpectedly\",\n },\n });\n reject(new Error(\"Connection closed unexpectedly\"));\n }\n },\n }\n );\n });\n },\n\n cancelExecution: () => {\n // Abort the active connection if any\n if (activeExecutionConnection) {\n activeExecutionConnection.abort();\n activeExecutionConnection = null;\n }\n\n // Reset execution state to idle\n set({\n execution: {\n status: \"idle\",\n imageIds: [],\n imageUrls: [],\n previews: {},\n dataOutputs: {},\n nodeStatus: {},\n },\n });\n },\n\n exportToYaml: async () => {\n const { nodes, edges } = get();\n\n const studioNodes = nodes.map((n) => ({\n id: n.id,\n type: n.type as \"generator\" | \"transform\" | \"save\",\n position: n.position,\n data: n.data,\n }));\n\n const studioEdges = edges.map((e) => ({\n id: e.id,\n source: e.source,\n target: e.target,\n sourceHandle: e.sourceHandle ?? undefined,\n targetHandle: e.targetHandle ?? undefined,\n }));\n\n const result = await exportYaml(studioNodes, studioEdges);\n return result.yaml;\n },\n\n importFromYaml: (studioNodes, studioEdges, name) => {\n // Convert StudioNodes to React Flow nodes with new IDs\n const idMap = new Map<string, string>();\n\n const nodes: Node<NodeData>[] = studioNodes.map((studioNode) => {\n const newId = generateNodeId();\n idMap.set(studioNode.id, newId);\n\n return {\n id: newId,\n type: studioNode.type,\n position: studioNode.position,\n data: studioNode.data as NodeData,\n };\n });\n\n // Convert edges with mapped IDs\n const edges: Edge[] = studioEdges.map((studioEdge) => {\n const newSource = idMap.get(studioEdge.source) || studioEdge.source;\n const newTarget = idMap.get(studioEdge.target) || studioEdge.target;\n\n return {\n id: `edge_${newSource}_${newTarget}`,\n source: newSource,\n target: newTarget,\n };\n });\n\n set({\n nodes,\n edges,\n selectedNodeId: null,\n currentTemplateId: null,\n previewVisible: {},\n activeWorkflowId: null,\n activeWorkflowName: name || \"Imported Workflow\",\n hasUnsavedChanges: true,\n execution: {\n status: \"idle\",\n imageIds: [],\n imageUrls: [],\n previews: {},\n dataOutputs: {},\n nodeStatus: {},\n },\n });\n },\n\n // Workflow persistence methods\n markDirty: () => set({ hasUnsavedChanges: true }),\n\n toggleLibrary: () => set((state) => ({ showLibrary: !state.showLibrary })),\n\n setActiveWorkflowName: (name) => set({ activeWorkflowName: name, hasUnsavedChanges: true }),\n\n newWorkflow: () => {\n set({\n nodes: [],\n edges: [],\n selectedNodeId: null,\n currentTemplateId: null,\n previewVisible: {},\n activeWorkflowId: null,\n activeWorkflowName: \"Untitled Workflow\",\n hasUnsavedChanges: false,\n execution: {\n status: \"idle\",\n imageIds: [],\n imageUrls: [],\n previews: {},\n dataOutputs: {},\n nodeStatus: {},\n },\n });\n },\n\n saveWorkflow: (name) => {\n const {\n nodes,\n edges,\n activeWorkflowId,\n activeWorkflowName,\n savedWorkflows,\n currentTemplateId,\n } = get();\n const now = Date.now();\n\n if (activeWorkflowId) {\n // Update existing workflow\n const updated = savedWorkflows.map((wf) =>\n wf.id === activeWorkflowId\n ? { ...wf, name: name || activeWorkflowName, nodes, edges, updatedAt: now }\n : wf\n );\n set({\n savedWorkflows: updated,\n activeWorkflowName: name || activeWorkflowName,\n hasUnsavedChanges: false,\n });\n return activeWorkflowId;\n } else {\n // Create new workflow\n const id = generateWorkflowId();\n const newWorkflow: SavedWorkflow = {\n id,\n name: name || activeWorkflowName,\n nodes,\n edges,\n createdAt: now,\n updatedAt: now,\n templateId: currentTemplateId || undefined,\n };\n set({\n savedWorkflows: [...savedWorkflows, newWorkflow],\n activeWorkflowId: id,\n activeWorkflowName: name || activeWorkflowName,\n hasUnsavedChanges: false,\n });\n return id;\n }\n },\n\n loadWorkflow: (id) => {\n const { savedWorkflows } = get();\n const workflow = savedWorkflows.find((wf) => wf.id === id);\n if (!workflow) return;\n\n set({\n nodes: workflow.nodes,\n edges: workflow.edges,\n selectedNodeId: null,\n currentTemplateId: workflow.templateId || null,\n previewVisible: {},\n activeWorkflowId: id,\n activeWorkflowName: workflow.name,\n hasUnsavedChanges: false,\n execution: {\n status: \"idle\",\n imageIds: [],\n imageUrls: [],\n previews: {},\n dataOutputs: {},\n nodeStatus: {},\n },\n });\n },\n\n deleteWorkflow: (id) => {\n const { savedWorkflows, activeWorkflowId } = get();\n const filtered = savedWorkflows.filter((wf) => wf.id !== id);\n\n if (activeWorkflowId === id) {\n // If deleting the active workflow, clear the canvas\n set({\n savedWorkflows: filtered,\n nodes: [],\n edges: [],\n selectedNodeId: null,\n currentTemplateId: null,\n previewVisible: {},\n activeWorkflowId: null,\n activeWorkflowName: \"Untitled Workflow\",\n hasUnsavedChanges: false,\n execution: {\n status: \"idle\",\n imageIds: [],\n imageUrls: [],\n previews: {},\n dataOutputs: {},\n nodeStatus: {},\n },\n });\n } else {\n set({ savedWorkflows: filtered });\n }\n },\n\n renameWorkflow: (id, name) => {\n const { savedWorkflows, activeWorkflowId } = get();\n const updated = savedWorkflows.map((wf) =>\n wf.id === id ? { ...wf, name, updatedAt: Date.now() } : wf\n );\n set({\n savedWorkflows: updated,\n ...(activeWorkflowId === id ? { activeWorkflowName: name } : {}),\n });\n },\n\n duplicateWorkflow: (id) => {\n const { savedWorkflows } = get();\n const workflow = savedWorkflows.find((wf) => wf.id === id);\n if (!workflow) return \"\";\n\n const now = Date.now();\n const newId = generateWorkflowId();\n const duplicate: SavedWorkflow = {\n ...workflow,\n id: newId,\n name: `${workflow.name} (Copy)`,\n createdAt: now,\n updatedAt: now,\n };\n set({ savedWorkflows: [...savedWorkflows, duplicate] });\n return newId;\n },\n\n loadGeneratedWorkflow: (workflow: GeneratedWorkflowData) => {\n // Convert AI-generated workflow to React Flow nodes\n const idMap = new Map<string, string>();\n\n // Auto-layout: arrange nodes in a grid\n const GRID_SPACING_X = 250;\n const GRID_SPACING_Y = 150;\n const NODES_PER_ROW = 3;\n\n const nodes: Node<NodeData>[] = workflow.nodes.map((genNode, index) => {\n const newId = generateNodeId();\n idMap.set(genNode.id, newId);\n\n // Parse nodeType to extract type and name\n // Format: \"generator:dalle-3\", \"transform:sharp:resize\", \"input:upload\", etc.\n const parts = genNode.nodeType.split(\":\");\n const nodeType = parts[0] as StudioNodeType;\n\n // Calculate grid position\n const row = Math.floor(index / NODES_PER_ROW);\n const col = index % NODES_PER_ROW;\n const position = {\n x: 100 + col * GRID_SPACING_X,\n y: 100 + row * GRID_SPACING_Y,\n };\n\n // Build node data based on type\n let data: NodeData;\n\n if (nodeType === \"generator\") {\n const generatorName = parts.slice(1).join(\":\");\n data = {\n generatorName,\n params: genNode.parameters,\n isAI: true, // Assume AI since we're generating from AI\n } as GeneratorNodeData;\n } else if (nodeType === \"transform\") {\n const providerName = parts[1];\n const operation = parts.slice(2).join(\":\");\n data = {\n operation,\n providerName,\n params: genNode.parameters,\n } as TransformNodeData;\n } else if (nodeType === \"input\") {\n data = {\n uploadId: undefined,\n filename: undefined,\n mime: undefined,\n } as InputNodeData;\n } else if (nodeType === \"vision\") {\n const providerName = parts.slice(1).join(\":\");\n data = {\n providerName,\n params: genNode.parameters,\n } as VisionNodeData;\n } else if (nodeType === \"text\") {\n const providerName = parts.slice(1).join(\":\");\n // Extract jsonSchema from params and convert to outputSchema for UI\n const jsonSchema = genNode.parameters.jsonSchema as\n | { properties?: Record<string, { type?: string; description?: string }> }\n | undefined;\n const outputSchema = jsonSchema?.properties\n ? {\n type: \"object\" as const,\n properties: Object.fromEntries(\n Object.entries(jsonSchema.properties).map(([key, prop]) => [\n key,\n {\n type:\n (prop.type as \"string\" | \"number\" | \"boolean\" | \"object\" | \"array\") ||\n \"string\",\n description: prop.description,\n },\n ])\n ),\n }\n : undefined;\n data = {\n providerName,\n params: genNode.parameters,\n outputSchema,\n } as TextNodeData;\n } else {\n // Default to save node\n data = {\n destination: (genNode.parameters.destination as string) || \"./output/image.png\",\n provider: (genNode.parameters.provider as string) || \"filesystem\",\n } as SaveNodeData;\n }\n\n return {\n id: newId,\n type: nodeType,\n position,\n data,\n };\n });\n\n // Convert edges with mapped IDs\n const edges: Edge[] = workflow.edges.map((genEdge) => {\n const newSource = idMap.get(genEdge.source) || genEdge.source;\n const newTarget = idMap.get(genEdge.target) || genEdge.target;\n\n // Include handles in edge ID for uniqueness (multiple edges from same source)\n const handleSuffix = [genEdge.sourceHandle, genEdge.targetHandle]\n .filter(Boolean)\n .join(\"_\");\n const edgeId = handleSuffix\n ? `edge_${newSource}_${newTarget}_${handleSuffix}`\n : `edge_${newSource}_${newTarget}`;\n\n return {\n id: edgeId,\n source: newSource,\n target: newTarget,\n sourceHandle: genEdge.sourceHandle ?? undefined,\n targetHandle: genEdge.targetHandle ?? undefined,\n };\n });\n\n set({\n nodes,\n edges,\n selectedNodeId: null,\n currentTemplateId: null,\n previewVisible: {},\n activeWorkflowId: null,\n activeWorkflowName: \"AI Generated Workflow\",\n hasUnsavedChanges: true,\n execution: {\n status: \"idle\",\n imageIds: [],\n imageUrls: [],\n previews: {},\n dataOutputs: {},\n nodeStatus: {},\n },\n });\n },\n }),\n {\n name: \"floimg-studio-workflows\",\n // Only persist savedWorkflows - current canvas state is ephemeral\n partialize: (state) => ({\n savedWorkflows: state.savedWorkflows,\n }),\n }\n )\n);\n\n// Helper to extract default values from schema\nfunction getDefaultParams(definition: NodeDefinition): Record<string, unknown> {\n const params: Record<string, unknown> = {};\n\n if (definition.params?.properties) {\n for (const [key, field] of Object.entries(definition.params.properties)) {\n if (field.default !== undefined) {\n params[key] = field.default;\n }\n }\n }\n\n return params;\n}\n","import { memo, useCallback, useRef } from \"react\";\nimport { Handle, Position, type NodeProps } from \"reactflow\";\nimport type {\n GeneratorNodeData,\n TransformNodeData,\n SaveNodeData,\n InputNodeData,\n VisionNodeData,\n TextNodeData,\n} from \"@teamflojo/floimg-studio-shared\";\nimport { useWorkflowStore } from \"../stores/workflowStore\";\nimport { uploadImage, getUploadBlobUrl } from \"../api/client\";\n\n// Helper to get execution status class for node border\nfunction getExecutionClass(nodeStatus: string | undefined): string {\n if (nodeStatus === \"pending\") {\n return \"border-gray-400 dark:border-zinc-500\";\n }\n if (nodeStatus === \"running\") {\n return \"border-yellow-400 animate-pulse\";\n }\n if (nodeStatus === \"completed\") {\n return \"border-green-500\";\n }\n if (nodeStatus === \"error\") {\n return \"border-red-500\";\n }\n return \"\";\n}\n\n// Eye icon for preview toggle\nfunction PreviewToggle({ nodeId, color }: { nodeId: string; color: string }) {\n const previewVisible = useWorkflowStore((s) => s.previewVisible[nodeId] !== false);\n const togglePreview = useWorkflowStore((s) => s.togglePreview);\n\n return (\n <button\n onClick={(e) => {\n e.stopPropagation();\n togglePreview(nodeId);\n }}\n className={`ml-auto p-1 rounded hover:bg-gray-200 dark:hover:bg-zinc-600 transition-colors ${previewVisible ? \"opacity-100\" : \"opacity-40\"}`}\n title={previewVisible ? \"Hide preview\" : \"Show preview\"}\n >\n <svg className={`w-3.5 h-3.5 ${color}`} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n {previewVisible ? (\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M15 12a3 3 0 11-6 0 3 3 0 016 0z M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z\"\n />\n ) : (\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21\"\n />\n )}\n </svg>\n </button>\n );\n}\n\n// Generator Node (source nodes - have output only)\n// AI generators may also have a text input handle and/or references input handle\nexport const GeneratorNode = memo(function GeneratorNode({\n id,\n data,\n selected,\n}: NodeProps<GeneratorNodeData>) {\n const preview = useWorkflowStore((s) => s.execution.previews[id]);\n const nodeStatus = useWorkflowStore((s) => s.execution.nodeStatus[id]);\n const previewVisible = useWorkflowStore((s) => s.previewVisible[id] !== false);\n\n const executionClass = getExecutionClass(nodeStatus);\n const borderClass = executionClass || (selected ? \"border-blue-500\" : \"border-blue-200\");\n\n // AI generators get a text input handle for dynamic prompts\n const isAI = data.isAI;\n // Check if this generator accepts reference images\n const acceptsReferences = data.acceptsReferenceImages;\n\n return (\n <div\n className={`rounded-lg border-2 bg-white dark:bg-zinc-800 shadow-md min-w-[180px] overflow-hidden ${borderClass}`}\n >\n {/* Text input handle for AI generators (optional - for dynamic prompts) */}\n {isAI && (\n <Handle\n type=\"target\"\n position={Position.Top}\n id=\"text\"\n className=\"w-3 h-3 !bg-pink-500\"\n title=\"Text input (optional prompt from text/vision node)\"\n />\n )}\n {/* Reference images input handle (for AI generators) */}\n {acceptsReferences && (\n <Handle\n type=\"target\"\n position={Position.Left}\n id=\"references\"\n className=\"w-3 h-3 !bg-violet-500\"\n style={{ top: \"50%\" }}\n title={`Reference images (up to ${data.maxReferenceImages || 14})`}\n />\n )}\n {preview && previewVisible && (\n <div className=\"bg-gray-100 dark:bg-zinc-900 border-b border-gray-200 dark:border-zinc-700\">\n <img src={preview} alt=\"Preview\" className=\"w-full h-24 object-contain\" />\n </div>\n )}\n <div className=\"px-4 py-3\">\n <div className=\"flex items-center gap-2 mb-2\">\n <div className=\"w-3 h-3 rounded-full bg-blue-500\" />\n <span className=\"font-semibold text-sm text-blue-700 dark:text-blue-400\">\n {data.generatorName}\n </span>\n <PreviewToggle nodeId={id} color=\"text-blue-500 dark:text-blue-400\" />\n </div>\n {isAI && (\n <div className=\"text-[10px] text-pink-500 dark:text-pink-400 mb-1\">\n ↑ Connect text node for dynamic prompt\n </div>\n )}\n {acceptsReferences && (\n <div className=\"text-[10px] text-violet-500 dark:text-violet-400 mb-1\">\n ← Connect reference images\n </div>\n )}\n <div className=\"text-xs text-gray-500 dark:text-zinc-400\">\n {Object.entries(data.params)\n .filter(([, value]) => typeof value !== \"object\" || value === null)\n .slice(0, 2)\n .map(([key, value]) => (\n <div key={key} className=\"truncate\">\n {key}: {String(value).slice(0, 20)}\n </div>\n ))}\n </div>\n </div>\n <Handle type=\"source\" position={Position.Right} className=\"w-3 h-3 !bg-blue-500\" />\n </div>\n );\n});\n\n// Transform Node (have both input and output)\n// AI transforms also have an optional text input at the top\n// AI transforms that accept references have a references input at the bottom\nexport const TransformNode = memo(function TransformNode({\n id,\n data,\n selected,\n}: NodeProps<TransformNodeData>) {\n const preview = useWorkflowStore((s) => s.execution.previews[id]);\n const nodeStatus = useWorkflowStore((s) => s.execution.nodeStatus[id]);\n const previewVisible = useWorkflowStore((s) => s.previewVisible[id] !== false);\n\n const executionClass = getExecutionClass(nodeStatus);\n const borderClass = executionClass || (selected ? \"border-teal-500\" : \"border-teal-200\");\n\n // AI transforms get a purple accent to indicate AI-powered\n const isAI = data.isAI;\n // Check if this transform accepts reference images\n const acceptsReferences = data.acceptsReferenceImages;\n\n return (\n <div\n className={`rounded-lg border-2 bg-white dark:bg-zinc-800 shadow-md min-w-[180px] overflow-hidden ${borderClass}`}\n >\n {/* Text input handle for AI transforms (optional - for dynamic prompts) */}\n {isAI && (\n <Handle\n type=\"target\"\n position={Position.Top}\n id=\"text\"\n className=\"w-3 h-3 !bg-pink-500\"\n title=\"Text input (optional prompt from text/vision node)\"\n />\n )}\n {/* Image input handle */}\n <Handle type=\"target\" position={Position.Left} id=\"image\" className=\"w-3 h-3 !bg-teal-500\" />\n {/* Reference images input handle (for AI transforms that accept additional references) */}\n {acceptsReferences && (\n <Handle\n type=\"target\"\n position={Position.Bottom}\n id=\"references\"\n className=\"w-3 h-3 !bg-violet-500\"\n title={`Reference images (up to ${data.maxReferenceImages || 13})`}\n />\n )}\n {preview && previewVisible && (\n <div className=\"bg-gray-100 dark:bg-zinc-900 border-b border-gray-200 dark:border-zinc-700\">\n <img src={preview} alt=\"Preview\" className=\"w-full h-24 object-contain\" />\n </div>\n )}\n <div className=\"px-4 py-3\">\n <div className=\"flex items-center gap-2 mb-2\">\n {isAI ? (\n <svg className=\"w-3 h-3 text-purple-500\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path d=\"M13 7H7v6h6V7z\" />\n <path\n fillRule=\"evenodd\"\n d=\"M7 2a1 1 0 012 0v1h2V2a1 1 0 112 0v1h2a2 2 0 012 2v2h1a1 1 0 110 2h-1v2h1a1 1 0 110 2h-1v2a2 2 0 01-2 2h-2v1a1 1 0 11-2 0v-1H9v1a1 1 0 11-2 0v-1H5a2 2 0 01-2-2v-2H2a1 1 0 110-2h1V9H2a1 1 0 010-2h1V5a2 2 0 012-2h2V2zM5 5h10v10H5V5z\"\n clipRule=\"evenodd\"\n />\n </svg>\n ) : (\n <div className=\"w-3 h-3 rounded-full bg-teal-500\" />\n )}\n <span\n className={`font-semibold text-sm ${isAI ? \"text-purple-700 dark:text-purple-400\" : \"text-teal-700 dark:text-teal-400\"}`}\n >\n {data.operation}\n </span>\n <PreviewToggle\n nodeId={id}\n color={\n isAI ? \"text-purple-500 dark:text-purple-400\" : \"text-teal-500 dark:text-teal-400\"\n }\n />\n </div>\n {isAI && (\n <div className=\"text-[10px] text-pink-500 dark:text-pink-400 mb-1\">\n ↑ Connect text node for dynamic prompt\n </div>\n )}\n {acceptsReferences && (\n <div className=\"text-[10px] text-violet-500 dark:text-violet-400 mb-1\">\n ↓ Connect reference images\n </div>\n )}\n <div className=\"text-xs text-gray-500 dark:text-zinc-400\">\n {Object.entries(data.params)\n .filter(([, value]) => typeof value !== \"object\" || value === null)\n .slice(0, 2)\n .map(([key, value]) => (\n <div key={key} className=\"truncate\">\n {key}: {String(value).slice(0, 20)}\n </div>\n ))}\n </div>\n </div>\n <Handle type=\"source\" position={Position.Right} className=\"w-3 h-3 !bg-teal-500\" />\n </div>\n );\n});\n\n// Save Node (sink nodes - have input only)\nexport const SaveNode = memo(function SaveNode({ id, data, selected }: NodeProps<SaveNodeData>) {\n const nodeStatus = useWorkflowStore((s) => s.execution.nodeStatus[id]);\n\n const executionClass = getExecutionClass(nodeStatus);\n const borderClass = executionClass || (selected ? \"border-green-500\" : \"border-green-200\");\n\n return (\n <div\n className={`px-4 py-3 rounded-lg border-2 bg-white dark:bg-zinc-800 shadow-md min-w-[180px] ${borderClass}`}\n >\n <Handle type=\"target\" position={Position.Left} className=\"w-3 h-3 !bg-green-500\" />\n <div className=\"flex items-center gap-2 mb-2\">\n <div className=\"w-3 h-3 rounded-full bg-green-500\" />\n <span className=\"font-semibold text-sm text-green-700 dark:text-green-400\">Save</span>\n </div>\n <div className=\"text-xs text-gray-500 dark:text-zinc-400 truncate\">{data.destination}</div>\n </div>\n );\n});\n\n// Input Node (source nodes with uploaded images - have output only)\nexport const InputNode = memo(function InputNode({ id, data, selected }: NodeProps<InputNodeData>) {\n const preview = useWorkflowStore((s) => s.execution.previews[id]);\n const nodeStatus = useWorkflowStore((s) => s.execution.nodeStatus[id]);\n const previewVisible = useWorkflowStore((s) => s.previewVisible[id] !== false);\n const updateNodeData = useWorkflowStore((s) => s.updateNodeData);\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const executionClass = getExecutionClass(nodeStatus);\n const borderClass = executionClass || (selected ? \"border-amber-500\" : \"border-amber-200\");\n\n // Handle file selection\n const handleFileSelect = useCallback(\n async (file: File) => {\n try {\n const result = await uploadImage(file);\n updateNodeData(id, {\n uploadId: result.id,\n filename: result.filename,\n mime: result.mime,\n });\n } catch (error) {\n console.error(\"Upload failed:\", error);\n }\n },\n [id, updateNodeData]\n );\n\n // Handle drag and drop\n const handleDrop = useCallback(\n (e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n const file = e.dataTransfer.files[0];\n if (file && file.type.startsWith(\"image/\")) {\n handleFileSelect(file);\n }\n },\n [handleFileSelect]\n );\n\n const handleDragOver = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n }, []);\n\n // Handle file input change\n const handleInputChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (file) {\n handleFileSelect(file);\n }\n },\n [handleFileSelect]\n );\n\n // Get preview URL - either execution preview or static upload URL\n const previewUrl = preview || (data.uploadId ? getUploadBlobUrl(data.uploadId) : null);\n\n return (\n <div\n className={`rounded-lg border-2 bg-white dark:bg-zinc-800 shadow-md min-w-[180px] overflow-hidden ${borderClass}`}\n onDrop={handleDrop}\n onDragOver={handleDragOver}\n >\n {previewUrl && previewVisible ? (\n <div className=\"bg-gray-100 dark:bg-zinc-900 border-b border-gray-200 dark:border-zinc-700\">\n <img src={previewUrl} alt=\"Uploaded\" className=\"w-full h-24 object-contain\" />\n </div>\n ) : !previewUrl ? (\n <div\n className=\"bg-amber-50 dark:bg-amber-900/30 border-b border-amber-100 dark:border-amber-800 h-24 flex items-center justify-center cursor-pointer hover:bg-amber-100 dark:hover:bg-amber-900/50 transition-colors\"\n onClick={() => fileInputRef.current?.click()}\n >\n <div className=\"text-center text-amber-600 dark:text-amber-400\">\n <div className=\"text-2xl mb-1\">+</div>\n <div className=\"text-xs\">Drop image or click</div>\n </div>\n </div>\n ) : null}\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/*\"\n className=\"hidden\"\n onChange={handleInputChange}\n />\n <div className=\"px-4 py-3\">\n <div className=\"flex items-center gap-2 mb-2\">\n <div className=\"w-3 h-3 rounded-full bg-amber-500\" />\n <span className=\"font-semibold text-sm text-amber-700 dark:text-amber-400\">Input</span>\n <PreviewToggle nodeId={id} color=\"text-amber-500 dark:text-amber-400\" />\n </div>\n <div className=\"text-xs text-gray-500 dark:text-zinc-400 truncate\">\n {data.filename || \"No image selected\"}\n </div>\n </div>\n <Handle type=\"source\" position={Position.Right} className=\"w-3 h-3 !bg-amber-500\" />\n </div>\n );\n});\n\n// Vision Node (AI image analysis - has input and output)\n// Supports multiple output handles when outputSchema is defined\nexport const VisionNode = memo(function VisionNode({\n id,\n data,\n selected,\n}: NodeProps<VisionNodeData>) {\n const nodeStatus = useWorkflowStore((s) => s.execution.nodeStatus[id]);\n const dataOutput = useWorkflowStore((s) => s.execution.dataOutputs?.[id]);\n const openOutputInspector = useWorkflowStore((s) => s.openOutputInspector);\n\n const executionClass = getExecutionClass(nodeStatus);\n const borderClass = executionClass || (selected ? \"border-cyan-500\" : \"border-cyan-200\");\n\n // Get output schema properties for multi-output handles\n const outputProperties = data.outputSchema?.properties\n ? Object.entries(data.outputSchema.properties)\n : [];\n const hasMultiOutput = outputProperties.length > 0;\n\n return (\n <div\n className={`rounded-lg border-2 bg-white dark:bg-zinc-800 shadow-md min-w-[180px] overflow-hidden ${borderClass}`}\n >\n <Handle type=\"target\" position={Position.Left} className=\"w-3 h-3 !bg-cyan-500\" />\n {dataOutput && (\n <div className=\"bg-cyan-50 dark:bg-cyan-900/30 border-b border-cyan-100 dark:border-cyan-800 p-2 max-h-24 overflow-auto\">\n <pre className=\"text-xs text-cyan-800 dark:text-cyan-200 whitespace-pre-wrap\">\n {dataOutput.content?.slice(0, 200)}\n {(dataOutput.content?.length || 0) > 200 && \"...\"}\n </pre>\n {dataOutput.content && dataOutput.content.length > 100 && (\n <button\n onClick={(e) => {\n e.stopPropagation();\n openOutputInspector(id);\n }}\n className=\"mt-1 text-xs text-cyan-600 dark:text-cyan-400 hover:text-cyan-800 dark:hover:text-cyan-300 hover:underline\"\n >\n View Full Output\n </button>\n )}\n </div>\n )}\n <div className=\"px-4 py-3\">\n <div className=\"flex items-center gap-2 mb-2\">\n <svg className=\"w-3 h-3 text-cyan-500\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path d=\"M10 12a2 2 0 100-4 2 2 0 000 4z\" />\n <path\n fillRule=\"evenodd\"\n d=\"M.458 10C1.732 5.943 5.522 3 10 3s8.268 2.943 9.542 7c-1.274 4.057-5.064 7-9.542 7S1.732 14.057.458 10zM14 10a4 4 0 11-8 0 4 4 0 018 0z\"\n clipRule=\"evenodd\"\n />\n </svg>\n <span className=\"font-semibold text-sm text-cyan-700 dark:text-cyan-400\">\n {data.providerLabel || data.providerName}\n </span>\n </div>\n <div className=\"text-xs text-gray-500 dark:text-zinc-400\">\n {data.params.prompt ? (\n <div className=\"truncate\">{String(data.params.prompt).slice(0, 30)}...</div>\n ) : null}\n </div>\n {/* Show output schema info if defined */}\n {hasMultiOutput && (\n <div className=\"mt-2 pt-2 border-t border-cyan-200 dark:border-cyan-800\">\n <div className=\"text-[10px] text-cyan-500 dark:text-cyan-400 font-medium mb-1\">\n Outputs:\n </div>\n {outputProperties.map(([key]) => (\n <div\n key={key}\n className=\"text-[10px] text-gray-500 dark:text-zinc-400 flex items-center gap-1\"\n >\n <span className=\"w-1.5 h-1.5 rounded-full bg-cyan-400\"></span>\n {key}\n </div>\n ))}\n </div>\n )}\n </div>\n {/* Multi-output handles: one for each schema property */}\n {hasMultiOutput ? (\n <>\n {/* Full output handle (backward compat) */}\n <Handle\n type=\"source\"\n position={Position.Right}\n id=\"output\"\n className=\"w-3 h-3 !bg-cyan-500\"\n style={{ top: \"50%\" }}\n title=\"Full JSON output\"\n />\n {/* Individual property handles */}\n {outputProperties.map(([key, prop], index) => (\n <Handle\n key={key}\n type=\"source\"\n position={Position.Right}\n id={`output.${key}`}\n className=\"w-2.5 h-2.5 !bg-cyan-400\"\n style={{\n top: `${70 + index * 14}%`,\n }}\n title={`${key}: ${prop.description || prop.type}`}\n />\n ))}\n </>\n ) : (\n <Handle type=\"source\" position={Position.Right} className=\"w-3 h-3 !bg-cyan-500\" />\n )}\n </div>\n );\n});\n\n// Text Node (AI text generation - has optional input and output)\n// Supports multiple output handles when outputSchema is defined\nexport const TextNode = memo(function TextNode({ id, data, selected }: NodeProps<TextNodeData>) {\n const nodeStatus = useWorkflowStore((s) => s.execution.nodeStatus[id]);\n const dataOutput = useWorkflowStore((s) => s.execution.dataOutputs?.[id]);\n const openOutputInspector = useWorkflowStore((s) => s.openOutputInspector);\n\n const executionClass = getExecutionClass(nodeStatus);\n const borderClass = executionClass || (selected ? \"border-pink-500\" : \"border-pink-200\");\n\n // Get output schema properties for multi-output handles\n const outputProperties = data.outputSchema?.properties\n ? Object.entries(data.outputSchema.properties)\n : [];\n const hasMultiOutput = outputProperties.length > 0;\n\n return (\n <div\n className={`rounded-lg border-2 bg-white dark:bg-zinc-800 shadow-md min-w-[180px] overflow-hidden ${borderClass}`}\n >\n <Handle type=\"target\" position={Position.Left} className=\"w-3 h-3 !bg-pink-500\" />\n {dataOutput && (\n <div className=\"bg-pink-50 dark:bg-pink-900/30 border-b border-pink-100 dark:border-pink-800 p-2 max-h-24 overflow-auto\">\n <pre className=\"text-xs text-pink-800 dark:text-pink-200 whitespace-pre-wrap\">\n {dataOutput.content?.slice(0, 200)}\n {(dataOutput.content?.length || 0) > 200 && \"...\"}\n </pre>\n {dataOutput.content && dataOutput.content.length > 100 && (\n <button\n onClick={(e) => {\n e.stopPropagation();\n openOutputInspector(id);\n }}\n className=\"mt-1 text-xs text-pink-600 dark:text-pink-400 hover:text-pink-800 dark:hover:text-pink-300 hover:underline\"\n >\n View Full Output\n </button>\n )}\n </div>\n )}\n <div className=\"px-4 py-3\">\n <div className=\"flex items-center gap-2 mb-2\">\n <svg className=\"w-3 h-3 text-pink-500\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path\n fillRule=\"evenodd\"\n d=\"M18 13V5a2 2 0 00-2-2H4a2 2 0 00-2 2v8a2 2 0 002 2h3l3 3 3-3h3a2 2 0 002-2zM5 7a1 1 0 011-1h8a1 1 0 110 2H6a1 1 0 01-1-1zm1 3a1 1 0 100 2h3a1 1 0 100-2H6z\"\n clipRule=\"evenodd\"\n />\n </svg>\n <span className=\"font-semibold text-sm text-pink-700 dark:text-pink-400\">\n {data.providerLabel || data.providerName}\n </span>\n </div>\n <div className=\"text-xs text-gray-500 dark:text-zinc-400\">\n {data.params.prompt ? (\n <div className=\"truncate\">{String(data.params.prompt).slice(0, 30)}...</div>\n ) : null}\n </div>\n {/* Show output schema info if defined */}\n {hasMultiOutput && (\n <div className=\"mt-2 pt-2 border-t border-pink-200 dark:border-pink-800\">\n <div className=\"text-[10px] text-pink-500 dark:text-pink-400 font-medium mb-1\">\n Outputs:\n </div>\n {outputProperties.map(([key]) => (\n <div\n key={key}\n className=\"text-[10px] text-gray-500 dark:text-zinc-400 flex items-center gap-1\"\n >\n <span className=\"w-1.5 h-1.5 rounded-full bg-pink-400\"></span>\n {key}\n </div>\n ))}\n </div>\n )}\n </div>\n {/* Multi-output handles: one for each schema property */}\n {hasMultiOutput ? (\n <>\n {/* Full output handle (backward compat) */}\n <Handle\n type=\"source\"\n position={Position.Right}\n id=\"output\"\n className=\"w-3 h-3 !bg-pink-500\"\n style={{ top: \"50%\" }}\n title=\"Full JSON output\"\n />\n {/* Individual property handles */}\n {outputProperties.map(([key, prop], index) => (\n <Handle\n key={key}\n type=\"source\"\n position={Position.Right}\n id={`output.${key}`}\n className=\"w-2.5 h-2.5 !bg-pink-400\"\n style={{\n top: `${70 + index * 14}%`,\n }}\n title={`${key}: ${prop.description || prop.type}`}\n />\n ))}\n </>\n ) : (\n <Handle type=\"source\" position={Position.Right} className=\"w-3 h-3 !bg-pink-500\" />\n )}\n </div>\n );\n});\n\nexport const nodeTypes = {\n generator: GeneratorNode,\n transform: TransformNode,\n save: SaveNode,\n input: InputNode,\n vision: VisionNode,\n text: TextNode,\n};\n","import { useCallback, useMemo } from \"react\";\nimport ReactFlow, {\n Background,\n Controls,\n MiniMap,\n MarkerType,\n type Connection,\n type NodeMouseHandler,\n type OnNodesChange,\n type OnEdgesChange,\n type DefaultEdgeOptions,\n applyNodeChanges,\n applyEdgeChanges,\n} from \"reactflow\";\nimport \"reactflow/dist/style.css\";\nimport \"./reactflow-dark.css\";\nimport type { GeneratorNodeData } from \"@teamflojo/floimg-studio-shared\";\nimport { useWorkflowStore } from \"../stores/workflowStore\";\nimport { nodeTypes } from \"./nodeTypes\";\n\n// Default edge styling with arrows to show direction\nconst defaultEdgeOptions: DefaultEdgeOptions = {\n type: \"smoothstep\",\n animated: false,\n markerEnd: {\n type: MarkerType.ArrowClosed,\n color: \"#64748b\",\n width: 20,\n height: 20,\n },\n style: {\n stroke: \"#64748b\",\n strokeWidth: 2,\n },\n // Make edges easier to select\n interactionWidth: 20,\n};\n\nexport function WorkflowEditor() {\n const nodes = useWorkflowStore((s) => s.nodes);\n const edges = useWorkflowStore((s) => s.edges);\n const setNodes = useWorkflowStore((s) => s.setNodes);\n const setEdges = useWorkflowStore((s) => s.setEdges);\n const addEdge = useWorkflowStore((s) => s.addEdge);\n const setSelectedNode = useWorkflowStore((s) => s.setSelectedNode);\n\n // Memoize nodeTypes to prevent React Flow warning during HMR\n // The nodeTypes object is defined outside, but HMR can cause module re-evaluation\n const memoizedNodeTypes = useMemo(() => nodeTypes, []);\n\n // Validate connections based on node types\n const isValidConnection = useCallback(\n (connection: Connection) => {\n const { source, target, targetHandle } = connection;\n if (!source || !target) return false;\n\n const sourceNode = nodes.find((n) => n.id === source);\n const targetNode = nodes.find((n) => n.id === target);\n\n if (!sourceNode || !targetNode) return false;\n\n // Rule 1: Cannot connect FROM a save node (no output)\n if (sourceNode.type === \"save\") return false;\n\n // Rule 2: Cannot connect TO a generator UNLESS it has specific input handles\n // AI generators have \"text\" (for prompts) and \"references\" (for reference images) handles\n if (targetNode.type === \"generator\") {\n const data = targetNode.data as GeneratorNodeData;\n // Allow connections to text handle if it's an AI generator\n if (targetHandle === \"text\" && data.isAI) return true;\n // Allow connections to references handle if it accepts reference images\n if (targetHandle === \"references\" && data.acceptsReferenceImages) return true;\n // Block all other connections to generators\n return false;\n }\n\n // Rule 3: Cannot connect TO an input node (no input port)\n if (targetNode.type === \"input\") return false;\n\n // Rule 4: No self-connections\n if (source === target) return false;\n\n // Note: We allow replacing existing connections - handled in onConnect\n return true;\n },\n [nodes]\n );\n\n const onNodesChange: OnNodesChange = useCallback(\n (changes) => {\n setNodes(applyNodeChanges(changes, nodes));\n },\n [nodes, setNodes]\n );\n\n const onEdgesChange: OnEdgesChange = useCallback(\n (changes) => {\n setEdges(applyEdgeChanges(changes, edges));\n },\n [edges, setEdges]\n );\n\n const onConnect = useCallback(\n (connection: Connection) => {\n // \"references\" handles accept multiple connections (for reference images)\n // All other handles (text, image, default) are single-connection and auto-replace\n const isMultiConnectionHandle = connection.targetHandle === \"references\";\n\n if (!isMultiConnectionHandle) {\n // Remove any existing connection to the same target handle before adding new one\n // Handle edge creation inconsistencies from AI generation or YAML import\n const edgesToRemove = edges.filter((e) => {\n if (e.target !== connection.target) return false;\n\n // Exact handle match (including both being null/undefined)\n const existingHandle = e.targetHandle || null;\n const newHandle = connection.targetHandle || null;\n if (existingHandle === newHandle) return true;\n\n // For \"text\" or \"image\" handle connections, also remove edges with no targetHandle\n // These are the primary single-input handles that should auto-replace\n if (\n (connection.targetHandle === \"text\" || connection.targetHandle === \"image\") &&\n !e.targetHandle\n ) {\n return true;\n }\n\n // If connecting to default handle (no targetHandle), remove edges to \"image\" handle\n // since that's the main input for transforms\n if (!connection.targetHandle && e.targetHandle === \"image\") {\n return true;\n }\n\n return false;\n });\n\n if (edgesToRemove.length > 0) {\n const removeIds = new Set(edgesToRemove.map((e) => e.id));\n setEdges(edges.filter((e) => !removeIds.has(e.id)));\n }\n }\n addEdge(connection);\n },\n [addEdge, edges, setEdges]\n );\n\n const onNodeClick: NodeMouseHandler = useCallback(\n (_event, node) => {\n setSelectedNode(node.id);\n },\n [setSelectedNode]\n );\n\n const onPaneClick = useCallback(() => {\n setSelectedNode(null);\n }, [setSelectedNode]);\n\n return (\n <div className=\"h-full w-full\">\n <ReactFlow\n nodes={nodes}\n edges={edges}\n onNodesChange={onNodesChange}\n onEdgesChange={onEdgesChange}\n onConnect={onConnect}\n onNodeClick={onNodeClick}\n onPaneClick={onPaneClick}\n nodeTypes={memoizedNodeTypes}\n defaultEdgeOptions={defaultEdgeOptions}\n isValidConnection={isValidConnection}\n nodesDraggable={true}\n nodesConnectable={true}\n elementsSelectable={true}\n edgesFocusable={true}\n deleteKeyCode={[\"Backspace\", \"Delete\"]}\n proOptions={{ hideAttribution: true }}\n fitView\n snapToGrid\n snapGrid={[15, 15]}\n >\n <Background />\n <Controls />\n <MiniMap nodeStrokeWidth={3} zoomable pannable />\n </ReactFlow>\n </div>\n );\n}\n","import { useState, useEffect } from \"react\";\nimport { listUploads, deleteUpload, getUploadBlobUrl, type UploadInfo } from \"../api/client\";\n\ninterface UploadGalleryProps {\n onSelect?: (upload: UploadInfo) => void;\n}\n\nexport function UploadGallery({ onSelect }: UploadGalleryProps) {\n const [uploads, setUploads] = useState<UploadInfo[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n const fetchUploads = async () => {\n try {\n setLoading(true);\n const data = await listUploads();\n setUploads(data);\n setError(null);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to load uploads\");\n } finally {\n setLoading(false);\n }\n };\n\n useEffect(() => {\n fetchUploads();\n }, []);\n\n const handleDelete = async (id: string, e: React.MouseEvent) => {\n e.stopPropagation();\n if (!confirm(\"Delete this upload?\")) return;\n\n try {\n await deleteUpload(id);\n setUploads((prev) => prev.filter((u) => u.id !== id));\n } catch (err) {\n console.error(\"Failed to delete:\", err);\n }\n };\n\n const formatSize = (bytes: number) => {\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\n if (loading) {\n return (\n <div className=\"p-4 text-center text-gray-500 dark:text-zinc-400\">Loading uploads...</div>\n );\n }\n\n if (error) {\n return (\n <div className=\"p-4 text-center text-red-500 dark:text-red-400\">\n {error}\n <button\n onClick={fetchUploads}\n className=\"ml-2 text-teal-500 dark:text-teal-400 hover:underline\"\n >\n Retry\n </button>\n </div>\n );\n }\n\n if (uploads.length === 0) {\n return (\n <div className=\"p-4 text-center text-gray-500 dark:text-zinc-400\">\n No uploads yet. Drag an image onto an Input node to upload.\n </div>\n );\n }\n\n return (\n <div className=\"p-2\">\n <div className=\"grid grid-cols-2 gap-2\">\n {uploads.map((upload) => (\n <div\n key={upload.id}\n className=\"relative group rounded border border-gray-200 dark:border-zinc-700 overflow-hidden cursor-pointer hover:border-amber-400 dark:hover:border-amber-500 transition-colors\"\n onClick={() => onSelect?.(upload)}\n >\n <img\n src={getUploadBlobUrl(upload.id)}\n alt={upload.filename}\n className=\"w-full h-20 object-cover\"\n />\n <div className=\"absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center\">\n <button\n onClick={(e) => handleDelete(upload.id, e)}\n className=\"p-1 bg-red-500 rounded text-white text-xs hover:bg-red-600\"\n >\n Delete\n </button>\n </div>\n <div className=\"p-1 text-xs truncate bg-white dark:bg-zinc-800 text-gray-800 dark:text-zinc-200\">\n {upload.filename}\n </div>\n <div className=\"px-1 pb-1 text-xs text-gray-400 dark:text-zinc-500 bg-white dark:bg-zinc-800\">\n {formatSize(upload.size)}\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n}\n","import { useEffect, useState } from \"react\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport type { NodeDefinition } from \"@teamflojo/floimg-studio-shared\";\nimport { getGenerators, getTransforms, getTextProviders, getVisionProviders } from \"../api/client\";\nimport { useWorkflowStore } from \"../stores/workflowStore\";\nimport { UploadGallery } from \"./UploadGallery\";\n\nexport function NodePalette() {\n const setGenerators = useWorkflowStore((s) => s.setGenerators);\n const setTransforms = useWorkflowStore((s) => s.setTransforms);\n const setTextProviders = useWorkflowStore((s) => s.setTextProviders);\n const setVisionProviders = useWorkflowStore((s) => s.setVisionProviders);\n const generators = useWorkflowStore((s) => s.generators);\n const transforms = useWorkflowStore((s) => s.transforms);\n const textProviders = useWorkflowStore((s) => s.textProviders);\n const visionProviders = useWorkflowStore((s) => s.visionProviders);\n const addNode = useWorkflowStore((s) => s.addNode);\n const [showUploads, setShowUploads] = useState(false);\n\n // Fetch node definitions\n const { data: fetchedGenerators } = useQuery({\n queryKey: [\"generators\"],\n queryFn: getGenerators,\n });\n\n const { data: fetchedTransforms } = useQuery({\n queryKey: [\"transforms\"],\n queryFn: getTransforms,\n });\n\n const { data: fetchedTextProviders } = useQuery({\n queryKey: [\"textProviders\"],\n queryFn: getTextProviders,\n });\n\n const { data: fetchedVisionProviders } = useQuery({\n queryKey: [\"visionProviders\"],\n queryFn: getVisionProviders,\n });\n\n useEffect(() => {\n if (fetchedGenerators) setGenerators(fetchedGenerators);\n }, [fetchedGenerators, setGenerators]);\n\n useEffect(() => {\n if (fetchedTransforms) setTransforms(fetchedTransforms);\n }, [fetchedTransforms, setTransforms]);\n\n useEffect(() => {\n if (fetchedTextProviders) setTextProviders(fetchedTextProviders);\n }, [fetchedTextProviders, setTextProviders]);\n\n useEffect(() => {\n if (fetchedVisionProviders) setVisionProviders(fetchedVisionProviders);\n }, [fetchedVisionProviders, setVisionProviders]);\n\n const handleDragStart = (e: React.DragEvent, definition: NodeDefinition) => {\n e.dataTransfer.setData(\"application/json\", JSON.stringify(definition));\n e.dataTransfer.effectAllowed = \"move\";\n };\n\n const handleDoubleClick = (definition: NodeDefinition) => {\n // Add node at center of canvas\n addNode(definition, { x: 250, y: 150 + Math.random() * 100 });\n };\n\n // Input node definition (special case - for uploaded images)\n const inputDefinition: NodeDefinition = {\n id: \"input:upload\",\n type: \"input\",\n name: \"upload\",\n label: \"Upload Image\",\n description: \"Use an uploaded image\",\n category: \"Input\",\n params: {\n type: \"object\",\n properties: {},\n },\n };\n\n // Save node definition (special case)\n const saveDefinition: NodeDefinition = {\n id: \"save:filesystem\",\n type: \"save\",\n name: \"save\",\n label: \"Save\",\n description: \"Save image to file\",\n category: \"Output\",\n params: {\n type: \"object\",\n properties: {\n destination: {\n type: \"string\",\n title: \"Destination\",\n default: \"./output/image.png\",\n },\n provider: {\n type: \"string\",\n default: \"filesystem\",\n },\n },\n },\n };\n\n // Group generators by category\n const generatorsByCategory = generators.reduce(\n (acc, g) => {\n const cat = g.category || \"Other\";\n if (!acc[cat]) acc[cat] = [];\n acc[cat].push(g);\n return acc;\n },\n {} as Record<string, NodeDefinition[]>\n );\n\n // Group transforms by category\n const transformsByCategory = transforms.reduce(\n (acc, t) => {\n const cat = t.category || \"Other\";\n if (!acc[cat]) acc[cat] = [];\n acc[cat].push(t);\n return acc;\n },\n {} as Record<string, NodeDefinition[]>\n );\n\n return (\n <div className=\"w-64 bg-gray-50 dark:bg-zinc-800 border-r border-gray-200 dark:border-zinc-700 overflow-y-auto\">\n <div className=\"p-4\">\n <h2 className=\"text-lg font-semibold text-gray-800 dark:text-white mb-4\">Nodes</h2>\n\n {/* Input */}\n <div className=\"mb-6\">\n <div className=\"flex items-center justify-between mb-2\">\n <h3 className=\"text-sm font-medium text-amber-600 dark:text-amber-400 uppercase tracking-wide\">\n Input\n </h3>\n <button\n onClick={() => setShowUploads(!showUploads)}\n className=\"text-xs text-amber-600 dark:text-amber-400 hover:text-amber-700 dark:hover:text-amber-300\"\n >\n {showUploads ? \"Hide\" : \"Browse\"} Uploads\n </button>\n </div>\n <div\n draggable\n onDragStart={(e) => handleDragStart(e, inputDefinition)}\n onDoubleClick={() => handleDoubleClick(inputDefinition)}\n className=\"px-3 py-2 bg-amber-50 dark:bg-amber-900/30 border border-amber-200 dark:border-amber-700 rounded cursor-grab active:cursor-grabbing hover:bg-amber-100 dark:hover:bg-amber-900/50 transition-colors\"\n >\n <div className=\"text-sm font-medium text-amber-700 dark:text-amber-300\">\n Upload Image\n </div>\n <div className=\"text-xs text-gray-500 dark:text-zinc-400\">Start with your image</div>\n </div>\n {showUploads && (\n <div className=\"mt-2 border border-amber-200 dark:border-amber-700 rounded bg-white dark:bg-zinc-900 max-h-64 overflow-y-auto\">\n <UploadGallery />\n </div>\n )}\n </div>\n\n {/* Generators */}\n <div className=\"mb-6\">\n <h3 className=\"text-sm font-medium text-blue-600 dark:text-blue-400 uppercase tracking-wide mb-2\">\n Generators\n </h3>\n {Object.entries(generatorsByCategory).map(([category, nodes]) => (\n <div key={category} className=\"mb-3\">\n <div className=\"text-xs text-gray-500 dark:text-zinc-400 mb-1\">{category}</div>\n {nodes.map((def) => (\n <div\n key={def.id}\n draggable\n onDragStart={(e) => handleDragStart(e, def)}\n onDoubleClick={() => handleDoubleClick(def)}\n className=\"px-3 py-2 bg-blue-50 dark:bg-blue-900/30 border border-blue-200 dark:border-blue-700 rounded mb-1 cursor-grab active:cursor-grabbing hover:bg-blue-100 dark:hover:bg-blue-900/50 transition-colors\"\n >\n <div className=\"text-sm font-medium text-blue-700 dark:text-blue-300\">\n {def.label}\n </div>\n {def.description && (\n <div className=\"text-xs text-gray-500 dark:text-zinc-400 truncate\">\n {def.description}\n </div>\n )}\n </div>\n ))}\n </div>\n ))}\n </div>\n\n {/* Transforms */}\n <div className=\"mb-6\">\n <h3 className=\"text-sm font-medium text-teal-600 dark:text-teal-400 uppercase tracking-wide mb-2\">\n Transforms\n </h3>\n {Object.entries(transformsByCategory).map(([category, nodes]) => (\n <div key={category} className=\"mb-3\">\n <div className=\"text-xs text-gray-500 dark:text-zinc-400 mb-1\">{category}</div>\n {nodes.map((def) => (\n <div\n key={def.id}\n draggable\n onDragStart={(e) => handleDragStart(e, def)}\n onDoubleClick={() => handleDoubleClick(def)}\n className=\"px-3 py-2 bg-teal-50 dark:bg-teal-900/30 border border-teal-200 dark:border-teal-700 rounded mb-1 cursor-grab active:cursor-grabbing hover:bg-teal-100 dark:hover:bg-teal-900/50 transition-colors\"\n >\n <div className=\"text-sm font-medium text-teal-700 dark:text-teal-300\">\n {def.label}\n </div>\n {def.description && (\n <div className=\"text-xs text-gray-500 dark:text-zinc-400 truncate\">\n {def.description}\n </div>\n )}\n </div>\n ))}\n </div>\n ))}\n </div>\n\n {/* AI Text */}\n {textProviders.length > 0 && (\n <div className=\"mb-6\">\n <h3 className=\"text-sm font-medium text-pink-600 dark:text-pink-400 uppercase tracking-wide mb-2\">\n AI Text\n </h3>\n {textProviders.map((def) => (\n <div\n key={def.id}\n draggable\n onDragStart={(e) => handleDragStart(e, def)}\n onDoubleClick={() => handleDoubleClick(def)}\n className=\"px-3 py-2 bg-pink-50 dark:bg-pink-900/30 border border-pink-200 dark:border-pink-700 rounded mb-1 cursor-grab active:cursor-grabbing hover:bg-pink-100 dark:hover:bg-pink-900/50 transition-colors\"\n >\n <div className=\"text-sm font-medium text-pink-700 dark:text-pink-300\">\n {def.label}\n </div>\n {def.description && (\n <div className=\"text-xs text-gray-500 dark:text-zinc-400 truncate\">\n {def.description}\n </div>\n )}\n </div>\n ))}\n </div>\n )}\n\n {/* AI Vision */}\n {visionProviders.length > 0 && (\n <div className=\"mb-6\">\n <h3 className=\"text-sm font-medium text-cyan-600 dark:text-cyan-400 uppercase tracking-wide mb-2\">\n AI Vision\n </h3>\n {visionProviders.map((def) => (\n <div\n key={def.id}\n draggable\n onDragStart={(e) => handleDragStart(e, def)}\n onDoubleClick={() => handleDoubleClick(def)}\n className=\"px-3 py-2 bg-cyan-50 dark:bg-cyan-900/30 border border-cyan-200 dark:border-cyan-700 rounded mb-1 cursor-grab active:cursor-grabbing hover:bg-cyan-100 dark:hover:bg-cyan-900/50 transition-colors\"\n >\n <div className=\"text-sm font-medium text-cyan-700 dark:text-cyan-300\">\n {def.label}\n </div>\n {def.description && (\n <div className=\"text-xs text-gray-500 dark:text-zinc-400 truncate\">\n {def.description}\n </div>\n )}\n </div>\n ))}\n </div>\n )}\n\n {/* Output */}\n <div className=\"mb-6\">\n <h3 className=\"text-sm font-medium text-green-600 dark:text-green-400 uppercase tracking-wide mb-2\">\n Output\n </h3>\n <div\n draggable\n onDragStart={(e) => handleDragStart(e, saveDefinition)}\n onDoubleClick={() => handleDoubleClick(saveDefinition)}\n className=\"px-3 py-2 bg-green-50 dark:bg-green-900/30 border border-green-200 dark:border-green-700 rounded cursor-grab active:cursor-grabbing hover:bg-green-100 dark:hover:bg-green-900/50 transition-colors\"\n >\n <div className=\"text-sm font-medium text-green-700 dark:text-green-300\">Save</div>\n <div className=\"text-xs text-gray-500 dark:text-zinc-400\">Save to file</div>\n </div>\n </div>\n </div>\n </div>\n );\n}\n","import { useState } from \"react\";\nimport type {\n GeneratorNodeData,\n TransformNodeData,\n SaveNodeData,\n TextNodeData,\n VisionNodeData,\n ParamField,\n OutputSchema,\n OutputProperty,\n} from \"@teamflojo/floimg-studio-shared\";\nimport { useWorkflowStore } from \"../stores/workflowStore\";\n\nexport function NodeInspector() {\n const selectedNodeId = useWorkflowStore((s) => s.selectedNodeId);\n const nodes = useWorkflowStore((s) => s.nodes);\n const generators = useWorkflowStore((s) => s.generators);\n const transforms = useWorkflowStore((s) => s.transforms);\n const textProviders = useWorkflowStore((s) => s.textProviders);\n const visionProviders = useWorkflowStore((s) => s.visionProviders);\n const updateNodeData = useWorkflowStore((s) => s.updateNodeData);\n const deleteNode = useWorkflowStore((s) => s.deleteNode);\n\n const selectedNode = nodes.find((n) => n.id === selectedNodeId);\n\n if (!selectedNode) {\n return (\n <div className=\"w-80 bg-gray-50 dark:bg-zinc-800 border-l border-gray-200 dark:border-zinc-700 p-4\">\n <div className=\"text-gray-500 dark:text-zinc-400 text-sm\">\n Select a node to edit its properties\n </div>\n </div>\n );\n }\n\n // Get schema for the selected node\n let schema: Record<string, ParamField> | undefined;\n let nodeLabel = \"\";\n\n if (selectedNode.type === \"generator\") {\n const data = selectedNode.data as GeneratorNodeData;\n const def = generators.find((g) => g.name === data.generatorName);\n schema = def?.params?.properties;\n nodeLabel = def?.label || data.generatorName;\n } else if (selectedNode.type === \"transform\") {\n const data = selectedNode.data as TransformNodeData;\n const def = transforms.find((t) => t.name === data.operation);\n schema = def?.params?.properties;\n nodeLabel = def?.label || data.operation;\n } else if (selectedNode.type === \"save\") {\n const data = selectedNode.data as SaveNodeData;\n const isCloudSave = data.provider === \"floimg-cloud\";\n\n nodeLabel = isCloudSave ? \"Save to FloImg Cloud\" : \"Save\";\n schema = {\n destination: {\n type: \"string\",\n title: isCloudSave ? \"Filename\" : \"Destination\",\n description: isCloudSave ? \"Filename for cloud storage\" : \"File path to save the image\",\n },\n };\n } else if (selectedNode.type === \"text\") {\n const data = selectedNode.data as TextNodeData;\n const def = textProviders.find((t) => t.name === data.providerName);\n schema = def?.params?.properties;\n nodeLabel = def?.label || data.providerName;\n } else if (selectedNode.type === \"vision\") {\n const data = selectedNode.data as VisionNodeData;\n const def = visionProviders.find((v) => v.name === data.providerName);\n schema = def?.params?.properties;\n nodeLabel = def?.label || data.providerName;\n }\n\n const handleParamChange = (key: string, value: unknown) => {\n if (selectedNode.type === \"generator\") {\n const data = selectedNode.data as GeneratorNodeData;\n updateNodeData(selectedNode.id, {\n params: { ...data.params, [key]: value },\n });\n } else if (selectedNode.type === \"transform\") {\n const data = selectedNode.data as TransformNodeData;\n updateNodeData(selectedNode.id, {\n params: { ...data.params, [key]: value },\n });\n } else if (selectedNode.type === \"save\") {\n updateNodeData(selectedNode.id, { [key]: value });\n } else if (selectedNode.type === \"text\") {\n const data = selectedNode.data as TextNodeData;\n updateNodeData(selectedNode.id, {\n params: { ...data.params, [key]: value },\n });\n } else if (selectedNode.type === \"vision\") {\n const data = selectedNode.data as VisionNodeData;\n updateNodeData(selectedNode.id, {\n params: { ...data.params, [key]: value },\n });\n }\n };\n\n const getParamValue = (key: string): unknown => {\n if (selectedNode.type === \"generator\") {\n return (selectedNode.data as GeneratorNodeData).params[key];\n } else if (selectedNode.type === \"transform\") {\n return (selectedNode.data as TransformNodeData).params[key];\n } else if (selectedNode.type === \"save\") {\n return (selectedNode.data as SaveNodeData)[key as keyof SaveNodeData];\n } else if (selectedNode.type === \"text\") {\n return (selectedNode.data as TextNodeData).params[key];\n } else if (selectedNode.type === \"vision\") {\n return (selectedNode.data as VisionNodeData).params[key];\n }\n return undefined;\n };\n\n // Determine which fields should be visible based on current parameter values\n const isFieldVisible = (key: string, _field: ParamField): boolean => {\n // For shapes generator, apply conditional visibility\n if (\n selectedNode.type === \"generator\" &&\n (selectedNode.data as GeneratorNodeData).generatorName === \"shapes\"\n ) {\n const shapeType = getParamValue(\"shapeType\") || \"rectangle\";\n const fillType = getParamValue(\"fillType\") || \"solid\";\n\n // Shape-specific parameters\n if (key === \"sides\") return shapeType === \"polygon\";\n if (key === \"points\" || key === \"innerRadius\") return shapeType === \"star\";\n if (key === \"cornerRadius\") return shapeType === \"rectangle\";\n\n // Fill-specific parameters\n if (key === \"fillColor\") return fillType === \"solid\";\n if (\n key === \"gradientType\" ||\n key === \"gradientColor1\" ||\n key === \"gradientColor2\" ||\n key === \"gradientAngle\"\n ) {\n return fillType === \"gradient\";\n }\n if (\n key === \"patternType\" ||\n key === \"patternColor\" ||\n key === \"patternBackground\" ||\n key === \"patternScale\"\n ) {\n return fillType === \"pattern\";\n }\n }\n\n return true;\n };\n\n return (\n <div className=\"w-80 bg-gray-50 dark:bg-zinc-800 border-l border-gray-200 dark:border-zinc-700 overflow-y-auto\">\n <div className=\"p-4\">\n <div className=\"flex items-center justify-between mb-4\">\n <h2 className=\"text-lg font-semibold text-gray-800 dark:text-white\">{nodeLabel}</h2>\n <button\n onClick={() => deleteNode(selectedNode.id)}\n className=\"text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300 text-sm\"\n >\n Delete\n </button>\n </div>\n\n <div className=\"space-y-4\">\n {schema &&\n Object.entries(schema)\n .filter(([key, field]) => isFieldVisible(key, field))\n .map(([key, field]) => (\n <FieldEditor\n key={key}\n name={key}\n field={field}\n value={getParamValue(key)}\n onChange={(value) => handleParamChange(key, value)}\n />\n ))}\n </div>\n\n {/* Output Schema Editor for text/vision nodes */}\n {(selectedNode.type === \"text\" || selectedNode.type === \"vision\") && (\n <OutputSchemaEditor\n nodeId={selectedNode.id}\n outputSchema={(selectedNode.data as TextNodeData | VisionNodeData).outputSchema}\n updateNodeData={updateNodeData}\n />\n )}\n </div>\n </div>\n );\n}\n\ninterface FieldEditorProps {\n name: string;\n field: ParamField;\n value: unknown;\n onChange: (value: unknown) => void;\n}\n\nfunction FieldEditor({ name, field, value, onChange }: FieldEditorProps) {\n const label = field.title || name;\n const inputClasses =\n \"w-full px-3 py-2 border border-gray-300 dark:border-zinc-600 rounded-md shadow-sm focus:ring-teal-500 focus:border-teal-500 bg-white dark:bg-zinc-900 text-gray-900 dark:text-zinc-100\";\n\n // Enum -> select dropdown\n if (field.enum) {\n return (\n <div>\n <label className=\"block text-sm font-medium text-gray-700 dark:text-zinc-300 mb-1\">\n {label}\n </label>\n <select\n value={String(value || \"\")}\n onChange={(e) => onChange(e.target.value)}\n className={inputClasses}\n >\n <option value=\"\">Select...</option>\n {field.enum.map((opt) => (\n <option key={opt} value={opt}>\n {opt}\n </option>\n ))}\n </select>\n {field.description && (\n <p className=\"mt-1 text-xs text-gray-500 dark:text-zinc-400\">{field.description}</p>\n )}\n </div>\n );\n }\n\n // Number input\n if (field.type === \"number\") {\n return (\n <div>\n <label className=\"block text-sm font-medium text-gray-700 dark:text-zinc-300 mb-1\">\n {label}\n </label>\n <input\n type=\"number\"\n value={value !== undefined ? Number(value) : \"\"}\n onChange={(e) => onChange(Number(e.target.value))}\n min={field.minimum}\n max={field.maximum}\n className={inputClasses}\n />\n {field.description && (\n <p className=\"mt-1 text-xs text-gray-500 dark:text-zinc-400\">{field.description}</p>\n )}\n </div>\n );\n }\n\n // Boolean -> checkbox\n if (field.type === \"boolean\") {\n return (\n <div className=\"flex items-center gap-2\">\n <input\n type=\"checkbox\"\n checked={Boolean(value)}\n onChange={(e) => onChange(e.target.checked)}\n className=\"h-4 w-4 text-teal-600 focus:ring-teal-500 border-gray-300 dark:border-zinc-600 rounded bg-white dark:bg-zinc-900\"\n />\n <label className=\"text-sm font-medium text-gray-700 dark:text-zinc-300\">{label}</label>\n </div>\n );\n }\n\n // Color picker for color-related fields\n if (name.toLowerCase().includes(\"color\") && typeof value === \"string\" && value.startsWith(\"#\")) {\n return (\n <div>\n <label className=\"block text-sm font-medium text-gray-700 dark:text-zinc-300 mb-1\">\n {label}\n </label>\n <div className=\"flex gap-2\">\n <input\n type=\"color\"\n value={String(value || \"#000000\")}\n onChange={(e) => onChange(e.target.value)}\n className=\"h-10 w-14 p-1 border border-gray-300 dark:border-zinc-600 rounded\"\n />\n <input\n type=\"text\"\n value={String(value || \"\")}\n onChange={(e) => onChange(e.target.value)}\n className={inputClasses + \" flex-1\"}\n />\n </div>\n </div>\n );\n }\n\n // Default: text input (also for objects as JSON)\n if (field.type === \"object\") {\n return (\n <div>\n <label className=\"block text-sm font-medium text-gray-700 dark:text-zinc-300 mb-1\">\n {label}\n </label>\n <textarea\n value={value ? JSON.stringify(value, null, 2) : \"{}\"}\n onChange={(e) => {\n try {\n onChange(JSON.parse(e.target.value));\n } catch {\n // Invalid JSON, ignore\n }\n }}\n rows={4}\n className={inputClasses + \" font-mono text-xs\"}\n />\n {field.description && (\n <p className=\"mt-1 text-xs text-gray-500 dark:text-zinc-400\">{field.description}</p>\n )}\n </div>\n );\n }\n\n // String input (default)\n return (\n <div>\n <label className=\"block text-sm font-medium text-gray-700 dark:text-zinc-300 mb-1\">\n {label}\n </label>\n {name === \"prompt\" || name === \"code\" || name === \"text\" ? (\n <textarea\n value={String(value || \"\")}\n onChange={(e) => onChange(e.target.value)}\n rows={3}\n className={inputClasses}\n />\n ) : (\n <input\n type=\"text\"\n value={String(value || \"\")}\n onChange={(e) => onChange(e.target.value)}\n className={inputClasses}\n />\n )}\n {field.description && (\n <p className=\"mt-1 text-xs text-gray-500 dark:text-zinc-400\">{field.description}</p>\n )}\n </div>\n );\n}\n\n// ============================================================================\n// Output Schema Editor for text/vision nodes\n// ============================================================================\n\ninterface OutputSchemaEditorProps {\n nodeId: string;\n outputSchema?: OutputSchema;\n updateNodeData: (id: string, data: Partial<TextNodeData | VisionNodeData>) => void;\n}\n\nfunction OutputSchemaEditor({ nodeId, outputSchema, updateNodeData }: OutputSchemaEditorProps) {\n const [newPropertyName, setNewPropertyName] = useState(\"\");\n\n const properties = outputSchema?.properties || {};\n const propertyEntries = Object.entries(properties);\n\n const handleAddProperty = () => {\n if (!newPropertyName.trim()) return;\n\n const newSchema: OutputSchema = {\n type: \"object\",\n properties: {\n ...properties,\n [newPropertyName.trim()]: { type: \"string\" },\n },\n };\n\n updateNodeData(nodeId, { outputSchema: newSchema });\n setNewPropertyName(\"\");\n };\n\n const handleRemoveProperty = (key: string) => {\n const newProperties = { ...properties };\n delete newProperties[key];\n\n if (Object.keys(newProperties).length === 0) {\n updateNodeData(nodeId, { outputSchema: undefined });\n } else {\n updateNodeData(nodeId, {\n outputSchema: { type: \"object\", properties: newProperties },\n });\n }\n };\n\n const handleTypeChange = (key: string, type: OutputProperty[\"type\"]) => {\n updateNodeData(nodeId, {\n outputSchema: {\n type: \"object\",\n properties: {\n ...properties,\n [key]: { ...properties[key], type },\n },\n },\n });\n };\n\n const handleDescriptionChange = (key: string, description: string) => {\n updateNodeData(nodeId, {\n outputSchema: {\n type: \"object\",\n properties: {\n ...properties,\n [key]: { ...properties[key], description: description || undefined },\n },\n },\n });\n };\n\n return (\n <div className=\"mt-6 pt-4 border-t border-gray-200 dark:border-zinc-700\">\n <div className=\"flex items-center justify-between mb-3\">\n <h3 className=\"text-sm font-medium text-gray-700 dark:text-zinc-300\">Output Schema</h3>\n <span className=\"text-xs text-gray-500 dark:text-zinc-500\">\n {propertyEntries.length > 0\n ? `${propertyEntries.length} output${propertyEntries.length > 1 ? \"s\" : \"\"}`\n : \"No outputs defined\"}\n </span>\n </div>\n\n <p className=\"text-xs text-gray-500 dark:text-zinc-400 mb-3\">\n Define output properties to enable connecting individual JSON fields to other nodes.\n </p>\n\n {/* Existing properties */}\n {propertyEntries.length > 0 && (\n <div className=\"space-y-2 mb-3\">\n {propertyEntries.map(([key, prop]) => (\n <div\n key={key}\n className=\"flex items-center gap-2 p-2 bg-pink-50 dark:bg-pink-900/20 rounded border border-pink-200 dark:border-pink-800\"\n >\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-medium text-pink-700 dark:text-pink-300 truncate\">\n {key}\n </span>\n <select\n value={prop.type}\n onChange={(e) =>\n handleTypeChange(key, e.target.value as OutputProperty[\"type\"])\n }\n className=\"text-xs px-1.5 py-0.5 rounded border border-pink-300 dark:border-pink-700 bg-white dark:bg-zinc-800 text-gray-700 dark:text-zinc-300\"\n >\n <option value=\"string\">string</option>\n <option value=\"number\">number</option>\n <option value=\"boolean\">boolean</option>\n <option value=\"object\">object</option>\n <option value=\"array\">array</option>\n </select>\n </div>\n <input\n type=\"text\"\n value={prop.description || \"\"}\n onChange={(e) => handleDescriptionChange(key, e.target.value)}\n placeholder=\"Description (optional)\"\n className=\"mt-1 w-full text-xs px-2 py-1 rounded border border-pink-200 dark:border-pink-700 bg-white dark:bg-zinc-800 text-gray-600 dark:text-zinc-400 placeholder-gray-400 dark:placeholder-zinc-500\"\n />\n </div>\n <button\n onClick={() => handleRemoveProperty(key)}\n className=\"text-pink-500 hover:text-pink-700 dark:text-pink-400 dark:hover:text-pink-300 p-1\"\n title=\"Remove property\"\n >\n <svg className=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </button>\n </div>\n ))}\n </div>\n )}\n\n {/* Add new property */}\n <div className=\"flex gap-2\">\n <input\n type=\"text\"\n value={newPropertyName}\n onChange={(e) => setNewPropertyName(e.target.value)}\n onKeyDown={(e) => e.key === \"Enter\" && handleAddProperty()}\n placeholder=\"Property name...\"\n className=\"flex-1 px-2 py-1.5 text-sm border border-gray-300 dark:border-zinc-600 rounded bg-white dark:bg-zinc-900 text-gray-900 dark:text-zinc-100 placeholder-gray-400 dark:placeholder-zinc-500\"\n />\n <button\n onClick={handleAddProperty}\n disabled={!newPropertyName.trim()}\n className=\"px-3 py-1.5 text-sm font-medium text-white bg-pink-500 rounded hover:bg-pink-600 disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n Add\n </button>\n </div>\n\n {/* Hint about usage */}\n {propertyEntries.length > 0 && (\n <p className=\"mt-3 text-xs text-gray-500 dark:text-zinc-500\">\n Connect from the small pink handles on the right of the node to route individual\n properties.\n </p>\n )}\n </div>\n );\n}\n","import type { Node, Edge } from \"reactflow\";\nimport type {\n GeneratorNodeData,\n TransformNodeData,\n SaveNodeData,\n InputNodeData,\n VisionNodeData,\n TextNodeData,\n} from \"@teamflojo/floimg-studio-shared\";\n\ntype NodeData =\n | GeneratorNodeData\n | TransformNodeData\n | SaveNodeData\n | InputNodeData\n | VisionNodeData\n | TextNodeData;\n\n/**\n * Topologically sort nodes based on edges (dependencies)\n * Returns nodes in execution order\n */\nfunction topologicalSort(nodes: Node<NodeData>[], edges: Edge[]): Node<NodeData>[] {\n const nodeMap = new Map(nodes.map((n) => [n.id, n]));\n const inDegree = new Map<string, number>();\n const adjacency = new Map<string, string[]>();\n\n // Initialize\n for (const node of nodes) {\n inDegree.set(node.id, 0);\n adjacency.set(node.id, []);\n }\n\n // Build graph\n for (const edge of edges) {\n const targets = adjacency.get(edge.source) || [];\n targets.push(edge.target);\n adjacency.set(edge.source, targets);\n inDegree.set(edge.target, (inDegree.get(edge.target) || 0) + 1);\n }\n\n // Find nodes with no incoming edges (sources)\n const queue: string[] = [];\n for (const [id, degree] of inDegree) {\n if (degree === 0) {\n queue.push(id);\n }\n }\n\n // Process in order\n const sorted: Node<NodeData>[] = [];\n while (queue.length > 0) {\n const id = queue.shift()!;\n const node = nodeMap.get(id);\n if (node) {\n sorted.push(node);\n }\n\n const neighbors = adjacency.get(id) || [];\n for (const neighbor of neighbors) {\n const newDegree = (inDegree.get(neighbor) || 1) - 1;\n inDegree.set(neighbor, newDegree);\n if (newDegree === 0) {\n queue.push(neighbor);\n }\n }\n }\n\n return sorted;\n}\n\n/**\n * Get the variable name for a node\n */\nfunction getNodeVarName(node: Node<NodeData>): string {\n const type = node.type || \"node\";\n const suffix = node.id.replace(/[^a-zA-Z0-9]/g, \"_\");\n return `${type}_${suffix}`;\n}\n\n/**\n * Stringify a value for code generation\n */\nfunction stringify(value: unknown): string {\n if (typeof value === \"string\") {\n // Escape special characters and use template literal if multiline\n if (value.includes(\"\\n\")) {\n return \"`\" + value.replace(/`/g, \"\\\\`\").replace(/\\$/g, \"\\\\$\") + \"`\";\n }\n return JSON.stringify(value);\n }\n return JSON.stringify(value, null, 2);\n}\n\n/**\n * Generate JavaScript code for a single node\n */\nfunction generateNodeCode(\n node: Node<NodeData>,\n edges: Edge[],\n nodeVarNames: Map<string, string>\n): { code: string; imports: string[] } {\n const varName = nodeVarNames.get(node.id)!;\n const imports: string[] = [];\n\n // Find input node (source of edge pointing to this node)\n const inputEdge = edges.find((e) => e.target === node.id);\n const inputVarName = inputEdge ? nodeVarNames.get(inputEdge.source) : null;\n\n switch (node.type) {\n case \"generator\": {\n const data = node.data as GeneratorNodeData;\n imports.push(data.generatorName);\n\n const params = data.params || {};\n const paramStr = Object.entries(params)\n .filter(([, v]) => v !== undefined && v !== \"\")\n .map(([k, v]) => ` ${k}: ${stringify(v)}`)\n .join(\",\\n\");\n\n return {\n code: `// Generate image using ${data.generatorName}\nconst ${varName} = await ${data.generatorName}({\n${paramStr}\n});`,\n imports,\n };\n }\n\n case \"input\": {\n return {\n code: `// Load input image\nconst ${varName} = await flo.loadImage(\"./input.png\");`,\n imports: [],\n };\n }\n\n case \"transform\": {\n const data = node.data as TransformNodeData;\n const params = data.params || {};\n const paramStr = Object.entries(params)\n .filter(([, v]) => v !== undefined && v !== \"\")\n .map(([k, v]) => `${k}: ${stringify(v)}`)\n .join(\", \");\n\n const input = inputVarName || \"image\";\n return {\n code: `// Apply ${data.operation} transform\nconst ${varName} = await flo.transform(${input}, \"${data.operation}\"${paramStr ? `, { ${paramStr} }` : \"\"});`,\n imports: [],\n };\n }\n\n case \"vision\": {\n const data = node.data as VisionNodeData;\n imports.push(data.providerName);\n\n const params = data.params || {};\n const input = inputVarName || \"image\";\n const paramStr = Object.entries(params)\n .filter(([, v]) => v !== undefined && v !== \"\")\n .map(([k, v]) => ` ${k}: ${stringify(v)}`)\n .join(\",\\n\");\n\n return {\n code: `// Analyze image with ${data.providerName}\nconst ${varName} = await ${data.providerName}.analyze(${input}, {\n${paramStr}\n});`,\n imports,\n };\n }\n\n case \"text\": {\n const data = node.data as TextNodeData;\n imports.push(data.providerName);\n\n const params = data.params || {};\n const paramStr = Object.entries(params)\n .filter(([, v]) => v !== undefined && v !== \"\")\n .map(([k, v]) => ` ${k}: ${stringify(v)}`)\n .join(\",\\n\");\n\n return {\n code: `// Generate text with ${data.providerName}\nconst ${varName} = await ${data.providerName}.generate({\n${paramStr}\n});`,\n imports,\n };\n }\n\n case \"save\": {\n const data = node.data as SaveNodeData;\n const input = inputVarName || \"result\";\n return {\n code: `// Save result\nawait flo.save(${input}, ${stringify(data.destination)});`,\n imports: [],\n };\n }\n\n default:\n return {\n code: `// Unknown node type: ${node.type}`,\n imports: [],\n };\n }\n}\n\n/**\n * Generate JavaScript code from workflow nodes and edges\n */\nexport function generateJavaScript(nodes: Node<NodeData>[], edges: Edge[]): string {\n if (nodes.length === 0) {\n return `// Empty workflow\n// Add nodes to your canvas to generate code`;\n }\n\n // Sort nodes topologically\n const sortedNodes = topologicalSort(nodes, edges);\n\n // Generate variable names\n const nodeVarNames = new Map<string, string>();\n for (const node of sortedNodes) {\n nodeVarNames.set(node.id, getNodeVarName(node));\n }\n\n // Generate code for each node\n const allImports = new Set<string>();\n const codeBlocks: string[] = [];\n\n for (const node of sortedNodes) {\n const { code, imports } = generateNodeCode(node, edges, nodeVarNames);\n codeBlocks.push(code);\n for (const imp of imports) {\n allImports.add(imp);\n }\n }\n\n // Build final code\n const importLines: string[] = [];\n if (allImports.size > 0) {\n importLines.push(`import { ${Array.from(allImports).join(\", \")} } from \"@teamflojo/floimg\";`);\n }\n importLines.push(`import * as flo from \"@teamflojo/floimg\";`);\n\n const header = `/**\n * FloImg Workflow\n * Generated by FloImg Studio\n * https://floimg.com\n */\n\n`;\n\n const mainCode = `\nasync function runWorkflow() {\n${codeBlocks\n .map((block) =>\n block\n .split(\"\\n\")\n .map((line) => \" \" + line)\n .join(\"\\n\")\n )\n .join(\"\\n\\n\")}\n}\n\n// Run the workflow\nrunWorkflow().catch(console.error);\n`;\n\n return header + importLines.join(\"\\n\") + \"\\n\" + mainCode;\n}\n","import { useState, useCallback, type DragEvent } from \"react\";\nimport { importYaml, validateYaml } from \"../api/client\";\nimport type { StudioNode, StudioEdge } from \"@teamflojo/floimg-studio-shared\";\n\ninterface ImportModalProps {\n isOpen: boolean;\n onClose: () => void;\n onImport: (nodes: StudioNode[], edges: StudioEdge[], name?: string) => void;\n}\n\ninterface ValidationError {\n message: string;\n line?: number;\n column?: number;\n}\n\nexport function ImportModal({ isOpen, onClose, onImport }: ImportModalProps) {\n const [yamlContent, setYamlContent] = useState(\"\");\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<ValidationError | null>(null);\n const [isDragging, setIsDragging] = useState(false);\n\n const handleImport = useCallback(async () => {\n if (!yamlContent.trim()) {\n setError({ message: \"Please enter or paste YAML content\" });\n return;\n }\n\n setIsLoading(true);\n setError(null);\n\n try {\n const result = await importYaml(yamlContent);\n\n if (result.success) {\n onImport(result.nodes, result.edges, result.name);\n setYamlContent(\"\");\n onClose();\n } else {\n setError({\n message: result.error || \"Import failed\",\n line: result.line,\n column: result.column,\n });\n }\n } catch (err) {\n setError({ message: err instanceof Error ? err.message : \"Import failed\" });\n } finally {\n setIsLoading(false);\n }\n }, [yamlContent, onImport, onClose]);\n\n const handleValidate = useCallback(async () => {\n if (!yamlContent.trim()) {\n setError({ message: \"Please enter or paste YAML content\" });\n return;\n }\n\n setIsLoading(true);\n setError(null);\n\n try {\n const result = await validateYaml(yamlContent);\n\n if (result.valid) {\n setError(null);\n // Show success briefly\n setError({ message: \"Valid YAML!\" });\n setTimeout(() => setError(null), 2000);\n } else if (result.errors.length > 0) {\n setError(result.errors[0]);\n }\n } catch (err) {\n setError({ message: err instanceof Error ? err.message : \"Validation failed\" });\n } finally {\n setIsLoading(false);\n }\n }, [yamlContent]);\n\n const handleFileUpload = useCallback(async (file: File) => {\n if (!file.name.endsWith(\".yaml\") && !file.name.endsWith(\".yml\")) {\n setError({ message: \"Please upload a .yaml or .yml file\" });\n return;\n }\n\n try {\n const text = await file.text();\n setYamlContent(text);\n setError(null);\n } catch {\n setError({ message: \"Failed to read file\" });\n }\n }, []);\n\n const handleDragOver = useCallback((e: DragEvent) => {\n e.preventDefault();\n setIsDragging(true);\n }, []);\n\n const handleDragLeave = useCallback((e: DragEvent) => {\n e.preventDefault();\n setIsDragging(false);\n }, []);\n\n const handleDrop = useCallback(\n (e: DragEvent) => {\n e.preventDefault();\n setIsDragging(false);\n\n const file = e.dataTransfer.files[0];\n if (file) {\n handleFileUpload(file);\n }\n },\n [handleFileUpload]\n );\n\n const handleFileInputChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (file) {\n handleFileUpload(file);\n }\n },\n [handleFileUpload]\n );\n\n if (!isOpen) return null;\n\n return (\n <div className=\"fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50\">\n <div className=\"bg-white dark:bg-zinc-800 rounded-lg shadow-xl max-w-2xl w-full mx-4 max-h-[80vh] flex flex-col\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-gray-200 dark:border-zinc-700\">\n <h3 className=\"text-lg font-semibold text-gray-900 dark:text-white\">Import Workflow</h3>\n <button\n onClick={onClose}\n className=\"text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200\"\n >\n <svg className=\"h-6 w-6\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </button>\n </div>\n\n {/* Content */}\n <div className=\"p-4 flex-1 overflow-auto\">\n <p className=\"text-sm text-gray-600 dark:text-zinc-400 mb-4\">\n Paste YAML content or drag and drop a .yaml file to import a workflow.\n </p>\n\n {/* File drop zone */}\n <div\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n className={`border-2 border-dashed rounded-lg p-4 mb-4 text-center transition-colors ${\n isDragging\n ? \"border-teal-500 bg-teal-50 dark:bg-teal-900/20\"\n : \"border-gray-300 dark:border-zinc-600\"\n }`}\n >\n <input\n type=\"file\"\n accept=\".yaml,.yml\"\n onChange={handleFileInputChange}\n className=\"hidden\"\n id=\"yaml-file-input\"\n />\n <label\n htmlFor=\"yaml-file-input\"\n className=\"cursor-pointer text-sm text-gray-600 dark:text-zinc-400\"\n >\n <svg\n className=\"h-8 w-8 mx-auto mb-2 text-gray-400 dark:text-zinc-500\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n 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 />\n </svg>\n <span className=\"text-teal-600 dark:text-teal-400 hover:underline\">\n Click to upload\n </span>{\" \"}\n or drag and drop\n <br />\n <span className=\"text-xs\">.yaml or .yml files</span>\n </label>\n </div>\n\n {/* YAML textarea */}\n <textarea\n value={yamlContent}\n onChange={(e) => {\n setYamlContent(e.target.value);\n setError(null);\n }}\n placeholder={`name: My Workflow\nsteps:\n - kind: generate\n generator: quickchart\n params:\n type: bar\n data:\n labels: [Q1, Q2, Q3, Q4]\n datasets:\n - label: Revenue\n data: [12, 19, 8, 15]\n out: v0\n\n - kind: transform\n op: resize\n in: v0\n params:\n width: 800\n out: v1`}\n className=\"w-full h-64 p-3 font-mono text-sm bg-gray-100 dark:bg-zinc-900 border border-gray-300 dark:border-zinc-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-teal-500 text-gray-800 dark:text-zinc-200\"\n />\n\n {/* Error/Success message */}\n {error && (\n <div\n className={`mt-4 p-3 rounded-lg text-sm ${\n error.message === \"Valid YAML!\"\n ? \"bg-green-50 dark:bg-green-900/30 text-green-700 dark:text-green-400\"\n : \"bg-red-50 dark:bg-red-900/30 text-red-700 dark:text-red-400\"\n }`}\n >\n <span className=\"font-medium\">{error.message}</span>\n {error.line && (\n <span className=\"ml-2 text-xs\">\n (line {error.line}\n {error.column ? `, column ${error.column}` : \"\"})\n </span>\n )}\n </div>\n )}\n </div>\n\n {/* Footer */}\n <div className=\"flex justify-between items-center px-4 py-3 border-t border-gray-200 dark:border-zinc-700\">\n <span className=\"text-xs text-gray-500 dark:text-zinc-400\">\n Use with floimg CLI: floimg run workflow.yaml\n </span>\n <div className=\"flex gap-2\">\n <button\n onClick={handleValidate}\n disabled={isLoading || !yamlContent.trim()}\n className=\"px-4 py-2 text-sm font-medium text-gray-700 dark:text-zinc-200 bg-white dark:bg-zinc-700 border border-gray-300 dark:border-zinc-600 rounded-md hover:bg-gray-50 dark:hover:bg-zinc-600 disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n Validate\n </button>\n <button\n onClick={handleImport}\n disabled={isLoading || !yamlContent.trim()}\n className=\"px-4 py-2 text-sm font-medium text-white bg-teal-600 rounded-md hover:bg-teal-700 disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2\"\n >\n {isLoading && (\n <svg className=\"animate-spin h-4 w-4\" viewBox=\"0 0 24 24\" fill=\"none\">\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z\"\n />\n </svg>\n )}\n Import\n </button>\n </div>\n </div>\n </div>\n </div>\n );\n}\n","import { useState, useEffect, useCallback, type ReactNode } from \"react\";\nimport { useWorkflowStore } from \"../stores/workflowStore\";\nimport { useSettingsStore } from \"../stores/settingsStore\";\nimport { generateJavaScript } from \"../utils/codeGenerator\";\nimport { ImportModal } from \"./ImportModal\";\nimport type { StudioNode, StudioEdge } from \"@teamflojo/floimg-studio-shared\";\n\ntype ExportTab = \"yaml\" | \"javascript\";\n\n/**\n * Props for the Toolbar component.\n * All props are optional to maintain backward compatibility.\n */\nexport interface ToolbarProps {\n /** Slot rendered after the branding text (e.g., \"Cloud\" badge) */\n brandingSlot?: ReactNode;\n /** Slot rendered before the action buttons (e.g., usage counter) */\n beforeActionsSlot?: ReactNode;\n /** Slot rendered after all action buttons (e.g., auth/user menu) */\n afterActionsSlot?: ReactNode;\n /** Hide the \"by Flojo\" attribution link */\n hideAttribution?: boolean;\n /** Hide the \"My Workflows\" library toggle button (for wrappers providing custom workflow management) */\n hideWorkflowLibrary?: boolean;\n}\n\nexport function Toolbar({\n brandingSlot,\n beforeActionsSlot,\n afterActionsSlot,\n hideAttribution = false,\n hideWorkflowLibrary = false,\n}: ToolbarProps = {}) {\n const execution = useWorkflowStore((s) => s.execution);\n const execute = useWorkflowStore((s) => s.execute);\n const cancelExecution = useWorkflowStore((s) => s.cancelExecution);\n const exportToYaml = useWorkflowStore((s) => s.exportToYaml);\n const importFromYaml = useWorkflowStore((s) => s.importFromYaml);\n const nodes = useWorkflowStore((s) => s.nodes);\n const edges = useWorkflowStore((s) => s.edges);\n const openSettings = useSettingsStore((s) => s.openSettings);\n\n // Workflow persistence state\n const activeWorkflowName = useWorkflowStore((s) => s.activeWorkflowName);\n const hasUnsavedChanges = useWorkflowStore((s) => s.hasUnsavedChanges);\n const saveWorkflow = useWorkflowStore((s) => s.saveWorkflow);\n const toggleLibrary = useWorkflowStore((s) => s.toggleLibrary);\n const setActiveWorkflowName = useWorkflowStore((s) => s.setActiveWorkflowName);\n\n // Node operations\n const selectedNodeId = useWorkflowStore((s) => s.selectedNodeId);\n const duplicateNode = useWorkflowStore((s) => s.duplicateNode);\n\n const [showExport, setShowExport] = useState(false);\n const [showImport, setShowImport] = useState(false);\n const [exportTab, setExportTab] = useState<ExportTab>(\"yaml\");\n const [yamlContent, setYamlContent] = useState(\"\");\n const [jsContent, setJsContent] = useState(\"\");\n const [notification, setNotification] = useState<string | null>(null);\n const [isEditingName, setIsEditingName] = useState(false);\n const [editingName, setEditingName] = useState(\"\");\n\n // Listen for new workflow event\n useEffect(() => {\n const handleNewWorkflow = () => {\n setNotification(\"New workflow created\");\n setTimeout(() => setNotification(null), 2000);\n };\n window.addEventListener(\"new-workflow-created\", handleNewWorkflow);\n return () => window.removeEventListener(\"new-workflow-created\", handleNewWorkflow);\n }, []);\n\n // Handle save with Cmd+S / Ctrl+S\n const handleSave = useCallback(() => {\n if (nodes.length === 0) return;\n saveWorkflow();\n setNotification(\"Saved!\");\n setTimeout(() => setNotification(null), 2000);\n }, [nodes.length, saveWorkflow]);\n\n // Handle inline rename\n const handleStartRename = () => {\n setEditingName(activeWorkflowName);\n setIsEditingName(true);\n };\n\n const handleSaveRename = () => {\n const trimmed = editingName.trim();\n if (trimmed && trimmed !== activeWorkflowName) {\n setActiveWorkflowName(trimmed);\n }\n setIsEditingName(false);\n };\n\n // Handle duplicate with Cmd+D / Ctrl+D\n const handleDuplicate = useCallback(() => {\n if (selectedNodeId) {\n duplicateNode(selectedNodeId);\n }\n }, [selectedNodeId, duplicateNode]);\n\n // Keyboard shortcuts\n useEffect(() => {\n function handleKeyDown(e: KeyboardEvent) {\n if ((e.metaKey || e.ctrlKey) && e.key === \"s\") {\n e.preventDefault();\n handleSave();\n }\n if ((e.metaKey || e.ctrlKey) && e.key === \"d\") {\n e.preventDefault();\n handleDuplicate();\n }\n }\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [handleSave, handleDuplicate]);\n\n const handleExecute = async () => {\n await execute();\n };\n\n const handleExport = async () => {\n const yaml = await exportToYaml();\n setYamlContent(yaml);\n const js = generateJavaScript(nodes, edges);\n setJsContent(js);\n setShowExport(true);\n };\n\n const handleCopy = () => {\n const content = exportTab === \"yaml\" ? yamlContent : jsContent;\n navigator.clipboard.writeText(content);\n };\n\n const handleImport = useCallback(\n (importedNodes: StudioNode[], importedEdges: StudioEdge[], name?: string) => {\n importFromYaml(importedNodes, importedEdges, name);\n setNotification(\"Workflow imported!\");\n setTimeout(() => setNotification(null), 2000);\n },\n [importFromYaml]\n );\n\n return (\n <>\n <div className=\"h-14 bg-white dark:bg-zinc-800 border-b border-gray-200 dark:border-zinc-700 flex items-center justify-between px-4\">\n <div className=\"flex items-center gap-4\">\n {/* My Workflows button - can be hidden when custom workflow management is provided */}\n {!hideWorkflowLibrary && (\n <button\n onClick={toggleLibrary}\n className=\"p-2 text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200 hover:bg-gray-100 dark:hover:bg-zinc-700 rounded-md\"\n title=\"My Workflows\"\n >\n <svg className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 6h16M4 12h16M4 18h7\"\n />\n </svg>\n </button>\n )}\n\n <div className=\"flex items-baseline gap-2\">\n <h1 className=\"text-xl font-bold text-gray-800 dark:text-white\">FloImg Studio</h1>\n {brandingSlot}\n {!hideAttribution && (\n <a\n href=\"https://flojo.io\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-xs text-gray-400 dark:text-zinc-500 hover:text-gray-600 dark:hover:text-zinc-300\"\n >\n by Flojo\n </a>\n )}\n </div>\n\n {/* Workflow name and status - click to rename */}\n <div className=\"flex items-center gap-2\">\n {isEditingName ? (\n <input\n type=\"text\"\n value={editingName}\n onChange={(e) => setEditingName(e.target.value)}\n onBlur={handleSaveRename}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") handleSaveRename();\n if (e.key === \"Escape\") {\n setEditingName(activeWorkflowName);\n setIsEditingName(false);\n }\n }}\n className=\"w-48 px-2 py-1 text-sm font-medium bg-white dark:bg-zinc-900 border border-teal-500 rounded focus:outline-none focus:ring-1 focus:ring-teal-500 text-gray-900 dark:text-zinc-100\"\n autoFocus\n />\n ) : (\n <button\n onClick={handleStartRename}\n className=\"text-sm text-gray-700 dark:text-zinc-300 font-medium hover:text-gray-900 dark:hover:text-zinc-100 rounded px-2 py-1 -mx-2 hover:bg-gray-100 dark:hover:bg-zinc-700 transition-colors\"\n title=\"Click to rename\"\n >\n {activeWorkflowName}\n </button>\n )}\n {hasUnsavedChanges && (\n <span className=\"text-xs text-amber-600 dark:text-amber-400\">(unsaved)</span>\n )}\n {notification && (\n <span className=\"text-xs text-green-600 dark:text-green-400\">{notification}</span>\n )}\n </div>\n\n <span className=\"text-sm text-gray-500 dark:text-zinc-400\">\n {nodes.length} node{nodes.length !== 1 ? \"s\" : \"\"}\n </span>\n </div>\n\n <div className=\"flex items-center gap-3\">\n {beforeActionsSlot}\n <button\n onClick={openSettings}\n className=\"p-2 text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200 hover:bg-gray-100 dark:hover:bg-zinc-700 rounded-md\"\n title=\"AI Settings\"\n >\n <svg className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z\"\n />\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M15 12a3 3 0 11-6 0 3 3 0 016 0z\"\n />\n </svg>\n </button>\n\n {/* Save button */}\n <button\n onClick={handleSave}\n disabled={nodes.length === 0}\n className=\"p-2 text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200 hover:bg-gray-100 dark:hover:bg-zinc-700 rounded-md disabled:opacity-50 disabled:cursor-not-allowed\"\n title=\"Save Workflow (Cmd+S)\"\n >\n <svg className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M8 7H5a2 2 0 00-2 2v9a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-3m-1 4l-3 3m0 0l-3-3m3 3V4\"\n />\n </svg>\n </button>\n\n <button\n onClick={() => setShowImport(true)}\n className=\"px-4 py-2 text-sm font-medium text-gray-700 dark:text-zinc-200 bg-white dark:bg-zinc-700 border border-gray-300 dark:border-zinc-600 rounded-md hover:bg-gray-50 dark:hover:bg-zinc-600\"\n >\n Import\n </button>\n\n <button\n onClick={handleExport}\n disabled={nodes.length === 0}\n className=\"px-4 py-2 text-sm font-medium text-gray-700 dark:text-zinc-200 bg-white dark:bg-zinc-700 border border-gray-300 dark:border-zinc-600 rounded-md hover:bg-gray-50 dark:hover:bg-zinc-600 disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n Export\n </button>\n\n {execution.status === \"running\" ? (\n <button\n onClick={cancelExecution}\n className=\"px-4 py-2 text-sm font-medium text-white bg-red-600 rounded-md hover:bg-red-700 flex items-center gap-2\"\n >\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n Cancel\n </button>\n ) : (\n <button\n onClick={handleExecute}\n disabled={nodes.length === 0}\n className=\"px-4 py-2 text-sm font-medium text-white bg-teal-600 rounded-md hover:bg-teal-700 disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2\"\n >\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z\"\n />\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"\n />\n </svg>\n Execute\n </button>\n )}\n {afterActionsSlot}\n </div>\n </div>\n\n {/* Execution result banner */}\n {execution.status === \"completed\" && execution.imageIds.length > 0 && (\n <div className=\"bg-green-50 dark:bg-green-900/30 border-b border-green-200 dark:border-green-800 px-4 py-3\">\n <div className=\"flex items-center gap-4\">\n <span className=\"text-green-700 dark:text-green-400 font-medium\">\n Generated {execution.imageIds.length} image\n {execution.imageIds.length !== 1 ? \"s\" : \"\"}\n </span>\n <div className=\"flex gap-2\">\n {execution.imageUrls.slice(0, 4).map((url, idx) => (\n <a key={idx} href={url} target=\"_blank\" rel=\"noopener noreferrer\" className=\"block\">\n <img\n src={url}\n alt=\"Generated\"\n className=\"h-12 w-12 object-cover rounded border border-green-300 dark:border-green-700\"\n />\n </a>\n ))}\n </div>\n </div>\n </div>\n )}\n\n {execution.status === \"error\" && (\n <div className=\"bg-red-50 dark:bg-red-900/30 border-b border-red-200 dark:border-red-800 px-4 py-3\">\n <span className=\"text-red-700 dark:text-red-400\">Error: {execution.error}</span>\n </div>\n )}\n\n {/* Export modal with tabs */}\n {showExport && (\n <div className=\"fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50\">\n <div className=\"bg-white dark:bg-zinc-800 rounded-lg shadow-xl max-w-2xl w-full mx-4 max-h-[80vh] flex flex-col\">\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-gray-200 dark:border-zinc-700\">\n <div className=\"flex items-center gap-4\">\n <h3 className=\"text-lg font-semibold text-gray-900 dark:text-white\">\n Export Workflow\n </h3>\n {/* Tabs */}\n <div className=\"flex gap-1 bg-gray-100 dark:bg-zinc-700 rounded-lg p-1\">\n <button\n onClick={() => setExportTab(\"yaml\")}\n className={`px-3 py-1 text-sm font-medium rounded-md transition-colors ${\n exportTab === \"yaml\"\n ? \"bg-white dark:bg-zinc-600 text-gray-900 dark:text-white shadow-sm\"\n : \"text-gray-600 dark:text-zinc-400 hover:text-gray-900 dark:hover:text-white\"\n }`}\n >\n YAML\n </button>\n <button\n onClick={() => setExportTab(\"javascript\")}\n className={`px-3 py-1 text-sm font-medium rounded-md transition-colors ${\n exportTab === \"javascript\"\n ? \"bg-white dark:bg-zinc-600 text-gray-900 dark:text-white shadow-sm\"\n : \"text-gray-600 dark:text-zinc-400 hover:text-gray-900 dark:hover:text-white\"\n }`}\n >\n JavaScript\n </button>\n </div>\n </div>\n <button\n onClick={() => setShowExport(false)}\n className=\"text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200\"\n >\n <svg className=\"h-6 w-6\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </button>\n </div>\n <div className=\"p-4 overflow-auto flex-1\">\n <pre className=\"bg-gray-100 dark:bg-zinc-900 p-4 rounded text-sm font-mono whitespace-pre-wrap text-gray-800 dark:text-zinc-200\">\n {exportTab === \"yaml\" ? yamlContent : jsContent}\n </pre>\n </div>\n <div className=\"flex justify-between items-center px-4 py-3 border-t border-gray-200 dark:border-zinc-700\">\n <span className=\"text-xs text-gray-500 dark:text-zinc-400\">\n {exportTab === \"yaml\"\n ? \"Use with floimg CLI: floimg run workflow.yaml\"\n : \"Run with Node.js or Bun\"}\n </span>\n <div className=\"flex gap-2\">\n <button\n onClick={handleCopy}\n className=\"px-4 py-2 text-sm font-medium text-gray-700 dark:text-zinc-200 bg-white dark:bg-zinc-700 border border-gray-300 dark:border-zinc-600 rounded-md hover:bg-gray-50 dark:hover:bg-zinc-600\"\n >\n Copy to Clipboard\n </button>\n <button\n onClick={() => setShowExport(false)}\n className=\"px-4 py-2 text-sm font-medium text-white bg-teal-600 rounded-md hover:bg-teal-700\"\n >\n Close\n </button>\n </div>\n </div>\n </div>\n </div>\n )}\n\n {/* Import modal */}\n <ImportModal\n isOpen={showImport}\n onClose={() => setShowImport(false)}\n onImport={handleImport}\n />\n </>\n );\n}\n","import { useState } from \"react\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { listImages, getImageUrl, getImageWorkflow, type ImageInfo } from \"../api/client\";\nimport { useWorkflowStore } from \"../stores/workflowStore\";\nimport type { Template } from \"@teamflojo/floimg-templates\";\n\nexport function Gallery() {\n const loadTemplate = useWorkflowStore((s) => s.loadTemplate);\n const [loadingWorkflow, setLoadingWorkflow] = useState<string | null>(null);\n\n const {\n data: images,\n isLoading,\n error,\n refetch,\n } = useQuery({\n queryKey: [\"images\"],\n queryFn: listImages,\n refetchInterval: 5000, // Auto-refresh every 5 seconds\n });\n\n const handleLoadWorkflow = async (imageId: string) => {\n setLoadingWorkflow(imageId);\n try {\n const metadata = await getImageWorkflow(imageId);\n if (metadata?.workflow) {\n // Convert to Template format for loading\n const template: Template = {\n id: `image-${imageId}`,\n name: `Workflow from ${imageId}`,\n description: \"Loaded from gallery image\",\n category: \"Utilities\",\n generator: \"unknown\",\n workflow: {\n nodes: metadata.workflow.nodes,\n edges: metadata.workflow.edges,\n },\n };\n loadTemplate(template);\n // Navigate to editor tab (parent handles this via URL or state)\n window.dispatchEvent(new CustomEvent(\"workflow-loaded\"));\n } else {\n alert(\"No workflow metadata available for this image\");\n }\n } catch (err) {\n console.error(\"Failed to load workflow:\", err);\n alert(\"Failed to load workflow\");\n } finally {\n setLoadingWorkflow(null);\n }\n };\n\n if (isLoading) {\n return (\n <div className=\"p-8 text-center text-gray-500 dark:text-zinc-400\">Loading images...</div>\n );\n }\n\n if (error) {\n return (\n <div className=\"p-8 text-center text-red-500 dark:text-red-400\">\n Error loading images: {error instanceof Error ? error.message : \"Unknown error\"}\n </div>\n );\n }\n\n if (!images || images.length === 0) {\n return (\n <div className=\"p-8 text-center text-gray-500 dark:text-zinc-400\">\n <div className=\"text-lg mb-2\">No images yet</div>\n <div className=\"text-sm\">Create a workflow and click Execute to generate images</div>\n </div>\n );\n }\n\n return (\n <div className=\"p-4 bg-gray-100 dark:bg-zinc-900 min-h-full\">\n <div className=\"flex items-center justify-between mb-4\">\n <div>\n <h2 className=\"text-lg font-semibold text-gray-800 dark:text-white\">\n Images ({images.length})\n </h2>\n <p className=\"text-xs text-gray-500 dark:text-zinc-500\">Your generated images</p>\n </div>\n <button\n onClick={() => refetch()}\n className=\"text-sm text-teal-600 dark:text-teal-400 hover:text-teal-700 dark:hover:text-violet-300\"\n >\n Refresh\n </button>\n </div>\n\n <div className=\"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4\">\n {images.map((image) => (\n <ImageCard\n key={image.id}\n image={image}\n onLoadWorkflow={() => handleLoadWorkflow(image.id)}\n isLoading={loadingWorkflow === image.id}\n />\n ))}\n </div>\n </div>\n );\n}\n\ninterface ImageCardProps {\n image: ImageInfo;\n onLoadWorkflow: () => void;\n isLoading: boolean;\n}\n\nfunction ImageCard({ image, onLoadWorkflow, isLoading }: ImageCardProps) {\n const formatDate = (timestamp: number) => {\n return new Date(timestamp).toLocaleString();\n };\n\n const formatSize = (bytes: number) => {\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\n return (\n <div className=\"bg-white dark:bg-zinc-800 rounded-lg border border-gray-200 dark:border-zinc-700 overflow-hidden shadow-sm hover:shadow-md transition-shadow group\">\n <div className=\"relative\">\n <a\n href={getImageUrl(image.id)}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"block aspect-square bg-gray-100 dark:bg-zinc-900\"\n >\n <img\n src={getImageUrl(image.id)}\n alt={image.filename}\n className=\"w-full h-full object-cover\"\n loading=\"lazy\"\n />\n </a>\n {/* Hover overlay with action buttons */}\n <div className=\"absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center gap-2\">\n <button\n onClick={(e) => {\n e.preventDefault();\n onLoadWorkflow();\n }}\n disabled={isLoading}\n className=\"px-3 py-1.5 bg-teal-600 text-white text-sm rounded-lg hover:bg-teal-700 disabled:opacity-50\"\n >\n {isLoading ? \"Loading...\" : \"Load Workflow\"}\n </button>\n <a\n href={getImageUrl(image.id)}\n download={image.filename}\n onClick={(e) => e.stopPropagation()}\n className=\"p-1.5 bg-zinc-700 text-white rounded-lg hover:bg-zinc-600\"\n title=\"Download image\"\n >\n <svg className=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4\"\n />\n </svg>\n </a>\n </div>\n </div>\n <div className=\"p-3\">\n <div className=\"text-sm font-medium text-gray-800 dark:text-white truncate\">\n {image.filename}\n </div>\n <div className=\"text-xs text-gray-500 dark:text-zinc-400 mt-1\">\n {image.mime} • {formatSize(image.size)}\n </div>\n <div className=\"text-xs text-gray-400 dark:text-zinc-500 mt-1\">\n {formatDate(image.createdAt)}\n </div>\n </div>\n </div>\n );\n}\n","/**\n * Data Visualization Templates\n *\n * Charts, graphs, and diagrams using QuickChart and Mermaid generators.\n * All templates in this category work offline (OSS-compatible).\n */\n/**\n * Revenue Dashboard Pipeline\n * Canonical ID: revenue-chart\n *\n * Multi-step workflow: Generate chart → Resize → Add caption → WebP export\n * Demonstrates: chart generation with professional output formatting\n */\nexport const revenueChart = {\n id: \"revenue-chart\",\n name: \"Revenue Dashboard\",\n description: \"Quarterly revenue chart with caption and web-optimized export\",\n category: \"Data Viz\",\n generator: \"quickchart\",\n tags: [\"bar\", \"revenue\", \"quarterly\", \"dashboard\", \"sales\", \"pipeline\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"chart\",\n preview: {\n imageUrl: \"/showcase/data-viz/quarterly-revenue.png\",\n },\n codeExample: `const chart = await floimg\n .generate('quickchart', {\n chart: {\n type: 'bar',\n data: {\n labels: ['Q1', 'Q2', 'Q3', 'Q4'],\n datasets: [{ label: 'Revenue ($K)', data: [120, 190, 175, 240] }]\n }\n }\n })\n .transform('resize', { width: 800, height: 500, fit: 'inside' })\n .transform('addCaption', {\n text: 'Source: Finance Dashboard',\n position: 'bottom-right',\n fontSize: 12\n })\n .transform('convert', { to: 'image/webp', quality: 90 })\n .toBlob();`,\n seo: {\n title: \"Revenue Dashboard Chart Template\",\n description: \"Generate professional quarterly revenue bar charts with caption and optimization\",\n keywords: [\"revenue chart\", \"bar chart\", \"quarterly report\", \"dashboard\"],\n },\n workflow: {\n nodes: [\n {\n id: \"gen-1\",\n type: \"generator\",\n position: { x: 100, y: 150 },\n data: {\n generatorName: \"quickchart\",\n params: {\n chart: {\n type: \"bar\",\n data: {\n labels: [\"Q1\", \"Q2\", \"Q3\", \"Q4\"],\n datasets: [\n {\n label: \"Revenue ($K)\",\n data: [120, 190, 175, 240],\n backgroundColor: [\n \"rgba(99, 102, 241, 0.8)\",\n \"rgba(139, 92, 246, 0.8)\",\n \"rgba(168, 85, 247, 0.8)\",\n \"rgba(192, 132, 252, 0.8)\",\n ],\n },\n ],\n },\n options: {\n plugins: {\n title: {\n display: true,\n text: \"Quarterly Revenue 2024\",\n },\n },\n },\n },\n width: 600,\n height: 400,\n },\n },\n },\n {\n id: \"transform-resize\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 800,\n height: 500,\n fit: \"inside\",\n },\n },\n },\n {\n id: \"transform-caption\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"addCaption\",\n params: {\n text: \"Source: Finance Dashboard\",\n position: \"bottom-right\",\n fontSize: 12,\n color: \"#6B7280\",\n padding: 8,\n },\n },\n },\n {\n id: \"transform-webp\",\n type: \"transform\",\n position: { x: 1000, y: 150 },\n data: {\n operation: \"convert\",\n params: {\n to: \"image/webp\",\n quality: 90,\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"gen-1\", target: \"transform-resize\" },\n { id: \"e2\", source: \"transform-resize\", target: \"transform-caption\" },\n { id: \"e3\", source: \"transform-caption\", target: \"transform-webp\" },\n ],\n },\n};\n/**\n * User Growth Chart for Investor Updates\n * Canonical ID: monthly-users\n *\n * Multi-step workflow: Generate chart → Resize for slides → Round corners for modern look → PNG export\n * JTBD: Create polished growth charts for investor decks and board presentations\n */\nexport const monthlyUsers = {\n id: \"monthly-users\",\n name: \"User Growth Chart\",\n description: \"Polished user growth chart ready for investor decks and presentations\",\n category: \"Data Viz\",\n generator: \"quickchart\",\n tags: [\"line\", \"growth\", \"users\", \"monthly\", \"analytics\", \"pipeline\", \"investor\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"chart\",\n preview: {\n imageUrl: \"/showcase/data-viz/monthly-users.png\",\n },\n codeExample: `const chart = await floimg\n .generate('quickchart', {\n chart: {\n type: 'line',\n data: {\n labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],\n datasets: [{ label: 'Active Users', data: [1200, 1900, 3000, 5000, 6200, 8100] }]\n }\n }\n })\n .transform('resize', { width: 1200, height: 675 }) // 16:9 for slides\n .transform('roundCorners', { radius: 16 })\n .transform('convert', { to: 'image/png' })\n .toBlob();`,\n seo: {\n title: \"User Growth Chart Template\",\n description: \"Visualize monthly user growth with smooth bezier curves for investor presentations\",\n keywords: [\"user growth\", \"line chart\", \"analytics\", \"investor deck\"],\n },\n workflow: {\n nodes: [\n {\n id: \"gen-1\",\n type: \"generator\",\n position: { x: 100, y: 150 },\n data: {\n generatorName: \"quickchart\",\n params: {\n chart: {\n type: \"line\",\n data: {\n labels: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\"],\n datasets: [\n {\n label: \"Active Users\",\n data: [1200, 1900, 3000, 5000, 6200, 8100],\n borderColor: \"rgb(99, 102, 241)\",\n backgroundColor: \"rgba(99, 102, 241, 0.1)\",\n fill: true,\n tension: 0.4,\n },\n ],\n },\n options: {\n plugins: {\n title: {\n display: true,\n text: \"User Growth 2024\",\n },\n },\n },\n },\n width: 600,\n height: 400,\n },\n },\n },\n {\n id: \"transform-resize\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 1200,\n height: 675,\n fit: \"contain\",\n background: \"#ffffff\",\n },\n },\n },\n {\n id: \"transform-corners\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"roundCorners\",\n params: {\n radius: 16,\n },\n },\n },\n {\n id: \"transform-png\",\n type: \"transform\",\n position: { x: 1000, y: 150 },\n data: {\n operation: \"convert\",\n params: {\n to: \"image/png\",\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"gen-1\", target: \"transform-resize\" },\n { id: \"e2\", source: \"transform-resize\", target: \"transform-corners\" },\n { id: \"e3\", source: \"transform-corners\", target: \"transform-png\" },\n ],\n },\n};\n/**\n * Framework Comparison for Blog Posts\n * Canonical ID: framework-usage\n *\n * Multi-step workflow: Generate chart → Resize for blog → Add padding → WebP for fast loading\n * JTBD: Create comparison charts for technical blog posts and documentation\n */\nexport const frameworkUsage = {\n id: \"framework-usage\",\n name: \"Framework Usage Stats\",\n description: \"Blog-ready comparison chart with optimized sizing and fast web loading\",\n category: \"Data Viz\",\n generator: \"quickchart\",\n tags: [\"bar\", \"comparison\", \"stats\", \"horizontal\", \"frameworks\", \"pipeline\", \"blog\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"chart\",\n preview: {\n imageUrl: \"/showcase/data-viz/framework-usage.png\",\n },\n codeExample: `const chart = await floimg\n .generate('quickchart', {\n chart: {\n type: 'horizontalBar',\n data: {\n labels: ['React', 'Vue', 'Angular', 'Svelte', 'Solid'],\n datasets: [{ label: 'Usage %', data: [42, 18, 15, 8, 4] }]\n }\n }\n })\n .transform('resize', { width: 800, height: 450 }) // Blog content width\n .transform('extend', { top: 16, bottom: 16, left: 16, right: 16, background: '#ffffff' })\n .transform('convert', { to: 'image/webp', quality: 85 })\n .toBlob();`,\n seo: {\n title: \"Framework Comparison Chart Template\",\n description: \"Generate comparison charts for technical blog posts with optimized web delivery\",\n keywords: [\"framework comparison\", \"bar chart\", \"tech blog\", \"documentation\"],\n },\n workflow: {\n nodes: [\n {\n id: \"gen-1\",\n type: \"generator\",\n position: { x: 100, y: 150 },\n data: {\n generatorName: \"quickchart\",\n params: {\n chart: {\n type: \"horizontalBar\",\n data: {\n labels: [\"React\", \"Vue\", \"Angular\", \"Svelte\", \"Solid\"],\n datasets: [\n {\n label: \"Usage %\",\n data: [42, 18, 15, 8, 4],\n backgroundColor: [\n \"rgba(97, 218, 251, 0.8)\",\n \"rgba(65, 184, 131, 0.8)\",\n \"rgba(221, 0, 49, 0.8)\",\n \"rgba(255, 62, 0, 0.8)\",\n \"rgba(68, 107, 158, 0.8)\",\n ],\n },\n ],\n },\n options: {\n plugins: {\n title: {\n display: true,\n text: \"Frontend Framework Usage 2024\",\n },\n },\n },\n },\n width: 600,\n height: 400,\n },\n },\n },\n {\n id: \"transform-resize\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 800,\n height: 450,\n fit: \"inside\",\n },\n },\n },\n {\n id: \"transform-padding\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"extend\",\n params: {\n top: 16,\n bottom: 16,\n left: 16,\n right: 16,\n background: \"#ffffff\",\n },\n },\n },\n {\n id: \"transform-webp\",\n type: \"transform\",\n position: { x: 1000, y: 150 },\n data: {\n operation: \"convert\",\n params: {\n to: \"image/webp\",\n quality: 85,\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"gen-1\", target: \"transform-resize\" },\n { id: \"e2\", source: \"transform-resize\", target: \"transform-padding\" },\n { id: \"e3\", source: \"transform-padding\", target: \"transform-webp\" },\n ],\n },\n};\n/**\n * Traffic Breakdown for Slack/Reports\n * Canonical ID: traffic-breakdown\n *\n * Multi-step workflow: Generate chart → Square format for Slack → Add date annotation → PNG\n * JTBD: Share analytics breakdowns in Slack channels and weekly reports\n */\nexport const trafficBreakdown = {\n id: \"traffic-breakdown\",\n name: \"Traffic by Device\",\n description: \"Analytics breakdown optimized for Slack sharing and weekly reports\",\n category: \"Data Viz\",\n generator: \"quickchart\",\n tags: [\"doughnut\", \"traffic\", \"analytics\", \"pie\", \"devices\", \"pipeline\", \"slack\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"chart\",\n preview: {\n imageUrl: \"/showcase/data-viz/traffic-by-device.png\",\n },\n codeExample: `const chart = await floimg\n .generate('quickchart', {\n chart: {\n type: 'doughnut',\n data: {\n labels: ['Desktop', 'Mobile', 'Tablet'],\n datasets: [{ data: [55, 35, 10] }]\n }\n }\n })\n .transform('resize', { width: 500, height: 500 }) // Square for Slack preview\n .transform('addCaption', {\n text: 'Week of Jan 1, 2026',\n position: 'bottom-center',\n fontSize: 14,\n color: '#6B7280'\n })\n .transform('convert', { to: 'image/png' })\n .toBlob();`,\n seo: {\n title: \"Traffic Breakdown Chart Template\",\n description: \"Generate analytics breakdown charts optimized for Slack sharing and reports\",\n keywords: [\"traffic analytics\", \"doughnut chart\", \"slack\", \"weekly report\"],\n },\n workflow: {\n nodes: [\n {\n id: \"gen-1\",\n type: \"generator\",\n position: { x: 100, y: 150 },\n data: {\n generatorName: \"quickchart\",\n params: {\n chart: {\n type: \"doughnut\",\n data: {\n labels: [\"Desktop\", \"Mobile\", \"Tablet\"],\n datasets: [\n {\n data: [55, 35, 10],\n backgroundColor: [\n \"rgba(99, 102, 241, 0.8)\",\n \"rgba(34, 197, 94, 0.8)\",\n \"rgba(249, 115, 22, 0.8)\",\n ],\n },\n ],\n },\n options: {\n plugins: {\n title: {\n display: true,\n text: \"Traffic by Device Type\",\n },\n },\n },\n },\n width: 400,\n height: 400,\n },\n },\n },\n {\n id: \"transform-resize\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 500,\n height: 500,\n fit: \"contain\",\n background: \"#ffffff\",\n },\n },\n },\n {\n id: \"transform-caption\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"addCaption\",\n params: {\n text: \"Week of Jan 1, 2026\",\n position: \"bottom-center\",\n fontSize: 14,\n color: \"#6B7280\",\n padding: 12,\n },\n },\n },\n {\n id: \"transform-png\",\n type: \"transform\",\n position: { x: 1000, y: 150 },\n data: {\n operation: \"convert\",\n params: {\n to: \"image/png\",\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"gen-1\", target: \"transform-resize\" },\n { id: \"e2\", source: \"transform-resize\", target: \"transform-caption\" },\n { id: \"e3\", source: \"transform-caption\", target: \"transform-png\" },\n ],\n },\n};\n/**\n * API Documentation Sequence Diagram\n * Canonical ID: api-flow\n *\n * Multi-step workflow: Generate diagram → Resize for docs → Add padding → PNG for docs\n * JTBD: Create API flow diagrams for technical documentation and README files\n */\nexport const apiFlow = {\n id: \"api-flow\",\n name: \"API Request Flow\",\n description: \"Sequence diagram ready for API documentation and README files\",\n category: \"Data Viz\",\n generator: \"mermaid\",\n tags: [\"sequence\", \"api\", \"authentication\", \"diagram\", \"flow\", \"pipeline\", \"docs\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"diagram\",\n preview: {\n imageUrl: \"/showcase/diagrams/api-flow.png\",\n },\n codeExample: `const diagram = await floimg\n .generate('mermaid', {\n code: \\`sequenceDiagram\n participant Client\n participant API\n participant Auth\n Client->>API: POST /login\n API->>Auth: Validate\n Auth-->>API: JWT token\n API-->>Client: 200 OK\\`\n })\n .transform('resize', { width: 800, fit: 'inside' })\n .transform('extend', { top: 24, bottom: 24, left: 24, right: 24, background: '#ffffff' })\n .transform('convert', { to: 'image/png' })\n .toBlob();`,\n seo: {\n title: \"API Flow Diagram Template\",\n description: \"Generate sequence diagrams for API documentation and README files\",\n keywords: [\"api diagram\", \"sequence diagram\", \"documentation\", \"readme\"],\n },\n workflow: {\n nodes: [\n {\n id: \"gen-1\",\n type: \"generator\",\n position: { x: 100, y: 150 },\n data: {\n generatorName: \"mermaid\",\n params: {\n code: `sequenceDiagram\n participant Client\n participant API\n participant Auth\n participant DB\n\n Client->>API: POST /login\n API->>Auth: Validate credentials\n Auth->>DB: Query user\n DB-->>Auth: User data\n Auth-->>API: JWT token\n API-->>Client: 200 OK + token\n\n Client->>API: GET /data (+ JWT)\n API->>Auth: Verify token\n Auth-->>API: Valid\n API->>DB: Fetch data\n DB-->>API: Data\n API-->>Client: 200 OK + data`,\n theme: \"default\",\n },\n },\n },\n {\n id: \"transform-resize\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 800,\n fit: \"inside\",\n },\n },\n },\n {\n id: \"transform-padding\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"extend\",\n params: {\n top: 24,\n bottom: 24,\n left: 24,\n right: 24,\n background: \"#ffffff\",\n },\n },\n },\n {\n id: \"transform-png\",\n type: \"transform\",\n position: { x: 1000, y: 150 },\n data: {\n operation: \"convert\",\n params: {\n to: \"image/png\",\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"gen-1\", target: \"transform-resize\" },\n { id: \"e2\", source: \"transform-resize\", target: \"transform-padding\" },\n { id: \"e3\", source: \"transform-padding\", target: \"transform-png\" },\n ],\n },\n};\n/**\n * System Architecture for Technical Docs\n * Canonical ID: system-architecture\n *\n * Multi-step workflow: Generate diagram → Resize for wiki → Add padding → WebP for fast loading\n * JTBD: Create architecture diagrams for Confluence/Notion/README documentation\n */\nexport const systemArchitecture = {\n id: \"system-architecture\",\n name: \"System Architecture\",\n description: \"Architecture diagram optimized for Confluence, Notion, and technical documentation\",\n category: \"Data Viz\",\n generator: \"mermaid\",\n tags: [\n \"architecture\",\n \"microservices\",\n \"flowchart\",\n \"system\",\n \"infrastructure\",\n \"pipeline\",\n \"confluence\",\n ],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"diagram\",\n preview: {\n imageUrl: \"/showcase/diagrams/system-architecture.png\",\n },\n codeExample: `const diagram = await floimg\n .generate('mermaid', {\n code: \\`flowchart TB\n subgraph Gateway\n LB[Load Balancer]\n API[API Gateway]\n end\n subgraph Services\n Auth[Auth]\n Users[Users]\n end\n LB --> API --> Auth & Users\\`\n })\n .transform('resize', { width: 1000, fit: 'inside' })\n .transform('extend', { top: 32, bottom: 32, left: 32, right: 32, background: '#ffffff' })\n .transform('convert', { to: 'image/webp', quality: 90 })\n .toBlob();`,\n seo: {\n title: \"System Architecture Diagram Template\",\n description: \"Generate architecture diagrams for Confluence, Notion, and technical documentation\",\n keywords: [\"architecture diagram\", \"microservices\", \"confluence\", \"notion\"],\n },\n workflow: {\n nodes: [\n {\n id: \"gen-1\",\n type: \"generator\",\n position: { x: 100, y: 150 },\n data: {\n generatorName: \"mermaid\",\n params: {\n code: `flowchart TB\n subgraph Client\n Web[Web App]\n Mobile[Mobile App]\n end\n\n subgraph Gateway\n LB[Load Balancer]\n API[API Gateway]\n end\n\n subgraph Services\n Auth[Auth Service]\n Users[User Service]\n Orders[Order Service]\n Notify[Notification Service]\n end\n\n subgraph Data\n PG[(PostgreSQL)]\n Redis[(Redis Cache)]\n S3[(S3 Storage)]\n end\n\n Web --> LB\n Mobile --> LB\n LB --> API\n API --> Auth\n API --> Users\n API --> Orders\n API --> Notify\n Auth --> Redis\n Users --> PG\n Orders --> PG\n Notify --> Redis`,\n theme: \"default\",\n },\n },\n },\n {\n id: \"transform-resize\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 1000,\n fit: \"inside\",\n },\n },\n },\n {\n id: \"transform-padding\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"extend\",\n params: {\n top: 32,\n bottom: 32,\n left: 32,\n right: 32,\n background: \"#ffffff\",\n },\n },\n },\n {\n id: \"transform-webp\",\n type: \"transform\",\n position: { x: 1000, y: 150 },\n data: {\n operation: \"convert\",\n params: {\n to: \"image/webp\",\n quality: 90,\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"gen-1\", target: \"transform-resize\" },\n { id: \"e2\", source: \"transform-resize\", target: \"transform-padding\" },\n { id: \"e3\", source: \"transform-padding\", target: \"transform-webp\" },\n ],\n },\n};\n/**\n * Git Workflow for Team Onboarding\n * Canonical ID: git-workflow\n *\n * Multi-step workflow: Generate diagram → Resize for wiki → Add caption → PNG for docs\n * JTBD: Create git workflow diagrams for team onboarding and CONTRIBUTING.md files\n */\nexport const gitWorkflow = {\n id: \"git-workflow\",\n name: \"Git Branch Workflow\",\n description: \"Git branching diagram for team onboarding and CONTRIBUTING.md\",\n category: \"Data Viz\",\n generator: \"mermaid\",\n tags: [\n \"git\",\n \"branching\",\n \"workflow\",\n \"development\",\n \"version-control\",\n \"pipeline\",\n \"onboarding\",\n ],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"diagram\",\n preview: {\n imageUrl: \"/showcase/diagrams/git-workflow.png\",\n },\n codeExample: `const diagram = await floimg\n .generate('mermaid', {\n code: \\`gitGraph\n commit id: \"Initial\"\n branch develop\n commit id: \"Setup\"\n branch feature/auth\n commit id: \"Add login\"\n checkout develop\n merge feature/auth tag: \"v1.0.0\"\\`\n })\n .transform('resize', { width: 900, fit: 'inside' })\n .transform('addCaption', {\n text: 'Our Git Branching Strategy',\n position: 'top-center',\n fontSize: 16\n })\n .transform('convert', { to: 'image/png' })\n .toBlob();`,\n seo: {\n title: \"Git Workflow Diagram Template\",\n description: \"Generate git branching diagrams for team onboarding and CONTRIBUTING.md\",\n keywords: [\"git workflow\", \"branching strategy\", \"team onboarding\", \"contributing\"],\n },\n workflow: {\n nodes: [\n {\n id: \"gen-1\",\n type: \"generator\",\n position: { x: 100, y: 150 },\n data: {\n generatorName: \"mermaid\",\n params: {\n code: `gitGraph\n commit id: \"Initial\"\n branch develop\n checkout develop\n commit id: \"Setup\"\n branch feature/auth\n checkout feature/auth\n commit id: \"Add login\"\n commit id: \"Add signup\"\n checkout develop\n merge feature/auth\n branch feature/dashboard\n checkout feature/dashboard\n commit id: \"Add charts\"\n checkout develop\n merge feature/dashboard\n checkout main\n merge develop tag: \"v1.0.0\"\n checkout develop\n commit id: \"Post-release\"`,\n theme: \"default\",\n },\n },\n },\n {\n id: \"transform-resize\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 900,\n fit: \"inside\",\n },\n },\n },\n {\n id: \"transform-caption\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"addCaption\",\n params: {\n text: \"Our Git Branching Strategy\",\n position: \"top-center\",\n fontSize: 16,\n color: \"#374151\",\n padding: 16,\n },\n },\n },\n {\n id: \"transform-png\",\n type: \"transform\",\n position: { x: 1000, y: 150 },\n data: {\n operation: \"convert\",\n params: {\n to: \"image/png\",\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"gen-1\", target: \"transform-resize\" },\n { id: \"e2\", source: \"transform-resize\", target: \"transform-caption\" },\n { id: \"e3\", source: \"transform-caption\", target: \"transform-png\" },\n ],\n },\n};\n/**\n * All data visualization templates\n */\nexport const dataVizTemplates = [\n revenueChart,\n monthlyUsers,\n frameworkUsage,\n trafficBreakdown,\n apiFlow,\n systemArchitecture,\n gitWorkflow,\n];\n//# sourceMappingURL=data-viz.js.map","/**\n * AI Workflow Templates\n *\n * Templates that use AI image generation (OpenAI DALL-E, etc.)\n * These require API keys (cloud deployment) to execute.\n */\n/**\n * AI Product Photography for E-commerce\n * Canonical ID: ai-product-shot\n *\n * Multi-step workflow: AI generate → Remove background → Resize for listing → Add watermark\n * JTBD: Create e-commerce-ready product photos with transparent backgrounds and consistent sizing\n */\nexport const aiProductShot = {\n id: \"ai-product-shot\",\n name: \"AI Product Photography\",\n description: \"Generate AI product photos with background removal and e-commerce-ready sizing\",\n category: \"AI Workflows\",\n generator: \"openai\",\n tags: [\"product\", \"ecommerce\", \"photography\", \"dall-e\", \"ai\", \"pipeline\", \"background-removal\"],\n requiresCloud: true,\n requiresAuth: true,\n usesAI: true,\n aiCreditsNeeded: 1,\n capabilities: {\n pipeline: true,\n },\n icon: \"sparkles\",\n valueProp: \"E-commerce-ready product photos in seconds\",\n preview: {\n imageUrl: \"/showcase/ai-generation/product-headphones.png\",\n },\n codeExample: `const product = await floimg\n .generate('openai', {\n prompt: 'Professional product photo of headphones on white background',\n model: 'dall-e-3',\n size: '1024x1024'\n })\n .transform('removeBackground')\n .transform('resize', { width: 800, height: 800, fit: 'contain', background: '#ffffff' })\n .transform('addCaption', { text: 'SKU-12345', position: 'bottom-right', fontSize: 12 })\n .toBlob();`,\n seo: {\n title: \"AI Product Photography Template\",\n description: \"Generate e-commerce-ready product photos with AI and background removal\",\n keywords: [\"product photography\", \"ai generation\", \"ecommerce\", \"background removal\"],\n },\n workflow: {\n nodes: [\n {\n id: \"gen-ai\",\n type: \"generator\",\n position: { x: 100, y: 150 },\n data: {\n generatorName: \"openai\",\n params: {\n prompt: \"Professional product photo of modern wireless headphones on a clean white background, studio lighting, high-end commercial photography style\",\n model: \"dall-e-3\",\n size: \"1024x1024\",\n quality: \"hd\",\n },\n },\n },\n {\n id: \"transform-bg\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"removeBackground\",\n params: {},\n },\n },\n {\n id: \"transform-resize\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 800,\n height: 800,\n fit: \"contain\",\n background: \"#ffffff\",\n },\n },\n },\n {\n id: \"transform-caption\",\n type: \"transform\",\n position: { x: 1000, y: 150 },\n data: {\n operation: \"addCaption\",\n params: {\n text: \"SKU-12345\",\n position: \"bottom-right\",\n fontSize: 12,\n color: \"#9CA3AF\",\n padding: 8,\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"gen-ai\", target: \"transform-bg\" },\n { id: \"e2\", source: \"transform-bg\", target: \"transform-resize\" },\n { id: \"e3\", source: \"transform-resize\", target: \"transform-caption\" },\n ],\n },\n};\n/**\n * AI Hero Image for Landing Pages\n * Canonical ID: ai-hero-image\n *\n * Multi-step workflow: AI generate → Resize to OG dimensions → Round corners → WebP for fast loading\n * JTBD: Create landing page hero images optimized for web performance and social sharing\n */\nexport const aiHeroImage = {\n id: \"ai-hero-image\",\n name: \"AI Hero Image\",\n description: \"Generate landing page hero images optimized for web and social sharing\",\n category: \"AI Workflows\",\n generator: \"openai\",\n tags: [\"hero\", \"landing-page\", \"marketing\", \"dall-e\", \"ai\", \"pipeline\", \"og-image\"],\n requiresCloud: true,\n requiresAuth: true,\n usesAI: true,\n aiCreditsNeeded: 1,\n capabilities: {\n pipeline: true,\n },\n icon: \"sparkles\",\n valueProp: \"Landing page hero images in seconds\",\n preview: {\n imageUrl: \"/showcase/ai-generation/futuristic-city.png\",\n },\n codeExample: `const hero = await floimg\n .generate('openai', {\n prompt: 'Futuristic city skyline at sunset, cinematic lighting',\n model: 'dall-e-3',\n size: '1792x1024'\n })\n .transform('resize', { width: 1200, height: 630 }) // OG image dimensions\n .transform('roundCorners', { radius: 8 })\n .transform('convert', { to: 'image/webp', quality: 85 })\n .toBlob();`,\n seo: {\n title: \"AI Hero Image Generator\",\n description: \"Generate landing page hero images optimized for web and social sharing\",\n keywords: [\"hero image\", \"landing page\", \"og image\", \"social sharing\"],\n },\n workflow: {\n nodes: [\n {\n id: \"gen-ai\",\n type: \"generator\",\n position: { x: 100, y: 150 },\n data: {\n generatorName: \"openai\",\n params: {\n prompt: \"Futuristic city skyline at golden hour sunset, cinematic wide angle, volumetric lighting, sci-fi architecture, dramatic clouds, professional photography\",\n model: \"dall-e-3\",\n size: \"1792x1024\",\n quality: \"hd\",\n },\n },\n },\n {\n id: \"transform-resize\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 1200,\n height: 630,\n fit: \"cover\",\n },\n },\n },\n {\n id: \"transform-corners\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"roundCorners\",\n params: {\n radius: 8,\n },\n },\n },\n {\n id: \"transform-webp\",\n type: \"transform\",\n position: { x: 1000, y: 150 },\n data: {\n operation: \"convert\",\n params: {\n to: \"image/webp\",\n quality: 85,\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"gen-ai\", target: \"transform-resize\" },\n { id: \"e2\", source: \"transform-resize\", target: \"transform-corners\" },\n { id: \"e3\", source: \"transform-corners\", target: \"transform-webp\" },\n ],\n },\n};\n/**\n * AI Mascot with Brand Kit Export\n * Canonical ID: ai-mascot\n *\n * Multi-step workflow: AI generate → Remove background → Export multiple sizes for different uses\n * JTBD: Create mascot assets ready for favicon, social avatars, and website use\n */\nexport const aiMascot = {\n id: \"ai-mascot\",\n name: \"AI Mascot Generator\",\n description: \"Generate mascot with transparent background and multiple export sizes\",\n category: \"AI Workflows\",\n generator: \"openai\",\n tags: [\"mascot\", \"character\", \"branding\", \"dall-e\", \"ai\", \"pipeline\", \"favicon\", \"avatar\"],\n requiresCloud: true,\n requiresAuth: true,\n usesAI: true,\n aiCreditsNeeded: 1,\n capabilities: {\n pipeline: true,\n },\n icon: \"sparkles\",\n valueProp: \"Brand-ready mascot assets in seconds\",\n preview: {\n imageUrl: \"/showcase/ai-generation/robot-mascot.png\",\n },\n codeExample: `const mascot = await floimg\n .generate('openai', {\n prompt: 'Friendly robot mascot, modern flat design, teal colors, white background',\n model: 'dall-e-3',\n size: '1024x1024'\n })\n .transform('removeBackground')\n .transform('resize', { width: 512, height: 512, fit: 'contain' })\n .transform('convert', { to: 'image/png' })\n .toBlob();`,\n seo: {\n title: \"AI Mascot Generator\",\n description: \"Create brand mascots with transparent backgrounds ready for any use\",\n keywords: [\"mascot design\", \"character design\", \"branding\", \"favicon\"],\n },\n workflow: {\n nodes: [\n {\n id: \"gen-ai\",\n type: \"generator\",\n position: { x: 100, y: 150 },\n data: {\n generatorName: \"openai\",\n params: {\n prompt: \"Friendly robot mascot character, modern flat design style, vibrant teal and purple colors, simple geometric shapes, suitable for tech company branding, white background\",\n model: \"dall-e-3\",\n size: \"1024x1024\",\n quality: \"hd\",\n },\n },\n },\n {\n id: \"transform-bg\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"removeBackground\",\n params: {},\n },\n },\n {\n id: \"transform-resize\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 512,\n height: 512,\n fit: \"contain\",\n },\n },\n },\n {\n id: \"transform-png\",\n type: \"transform\",\n position: { x: 1000, y: 150 },\n data: {\n operation: \"convert\",\n params: {\n to: \"image/png\",\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"gen-ai\", target: \"transform-bg\" },\n { id: \"e2\", source: \"transform-bg\", target: \"transform-resize\" },\n { id: \"e3\", source: \"transform-resize\", target: \"transform-png\" },\n ],\n },\n};\n/**\n * AI Logo to Brand Kit (Cloud Onboarding)\n * Canonical ID: cloud-ai-logo-brand\n */\nexport const aiLogoBrandKit = {\n id: \"cloud-ai-logo-brand\",\n name: \"AI Logo to Brand Kit\",\n description: \"Generate a logo with AI, then create production-ready brand assets\",\n category: \"AI Workflows\",\n generator: \"openai\",\n tags: [\"ai\", \"logo\", \"branding\", \"dall-e\", \"pipeline\"],\n requiresCloud: true,\n requiresAuth: true,\n usesAI: true,\n aiCreditsNeeded: 1,\n capabilities: {\n pipeline: true,\n },\n icon: \"sparkles\",\n valueProp: \"From idea to brand kit in seconds\",\n seo: {\n title: \"AI Logo to Brand Kit\",\n description: \"Generate a logo with AI and create production-ready brand assets\",\n keywords: [\"logo design\", \"brand kit\", \"ai generation\", \"branding\"],\n },\n workflow: {\n nodes: [\n {\n id: \"gen-ai\",\n type: \"generator\",\n position: { x: 100, y: 150 },\n data: {\n generatorName: \"openai\",\n params: {\n prompt: \"A modern minimalist logo for a tech startup called 'Nexus', clean geometric lines, professional, suitable for business cards and websites, white background\",\n model: \"dall-e-3\",\n size: \"1024x1024\",\n quality: \"standard\",\n },\n },\n },\n {\n id: \"transform-bg\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"removeBackground\",\n params: {},\n },\n },\n {\n id: \"transform-watermark\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"addCaption\",\n params: {\n text: \"Nexus Inc.\",\n position: \"bottom-right\",\n fontSize: 14,\n color: \"#6B7280\",\n padding: 16,\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"gen-ai\", target: \"transform-bg\" },\n { id: \"e2\", source: \"transform-bg\", target: \"transform-watermark\" },\n ],\n },\n};\n/**\n * Product Photo Enhancement (Cloud Onboarding)\n * Canonical ID: cloud-product-enhance\n */\nexport const productPhotoEnhancement = {\n id: \"cloud-product-enhance\",\n name: \"Product Photo Enhancement\",\n description: \"Remove background and add professional product labeling\",\n category: \"AI Workflows\",\n generator: \"input\",\n tags: [\"product\", \"ecommerce\", \"background-removal\", \"pipeline\"],\n requiresCloud: true,\n requiresAuth: true,\n usesAI: false, // Uses AI transforms but not AI generation\n aiCreditsNeeded: 0,\n capabilities: {\n pipeline: true,\n },\n icon: \"image\",\n valueProp: \"E-commerce ready in one click\",\n workflow: {\n nodes: [\n {\n id: \"input-1\",\n type: \"input\",\n position: { x: 100, y: 150 },\n data: {},\n },\n {\n id: \"transform-bg\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"removeBackground\",\n params: {},\n },\n },\n {\n id: \"transform-caption\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"addCaption\",\n params: {\n text: \"Premium Quality\",\n position: \"bottom-center\",\n fontSize: 24,\n color: \"#18181B\",\n padding: 20,\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"input-1\", target: \"transform-bg\" },\n { id: \"e2\", source: \"transform-bg\", target: \"transform-caption\" },\n ],\n },\n};\n/**\n * AI Art to Social Post (Cloud Onboarding)\n * Canonical ID: cloud-ai-social\n */\nexport const aiArtSocialPost = {\n id: \"cloud-ai-social\",\n name: \"AI Art to Social Post\",\n description: \"Generate creative AI art, optimize for social media\",\n category: \"AI Workflows\",\n generator: \"openai\",\n tags: [\"ai\", \"art\", \"social-media\", \"dall-e\", \"pipeline\"],\n requiresCloud: true,\n requiresAuth: true,\n usesAI: true,\n aiCreditsNeeded: 1,\n capabilities: {\n pipeline: true,\n },\n icon: \"share\",\n valueProp: \"Creative content for your feed\",\n workflow: {\n nodes: [\n {\n id: \"gen-ai\",\n type: \"generator\",\n position: { x: 100, y: 150 },\n data: {\n generatorName: \"openai\",\n params: {\n prompt: \"Abstract colorful digital art with flowing gradients, trending on artstation, vibrant neon colors, perfect for social media\",\n model: \"dall-e-3\",\n size: \"1024x1024\",\n style: \"vivid\",\n },\n },\n },\n {\n id: \"transform-corners\",\n type: \"transform\",\n position: { x: 400, y: 100 },\n data: {\n operation: \"roundCorners\",\n params: {\n radius: 24,\n },\n },\n },\n {\n id: \"transform-caption\",\n type: \"transform\",\n position: { x: 700, y: 100 },\n data: {\n operation: \"addCaption\",\n params: {\n text: \"@floimg\",\n position: \"bottom-right\",\n fontSize: 18,\n color: \"#FFFFFF\",\n padding: 16,\n },\n },\n },\n {\n id: \"transform-webp\",\n type: \"transform\",\n position: { x: 1000, y: 100 },\n data: {\n operation: \"convert\",\n params: {\n to: \"image/webp\",\n quality: 85,\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"gen-ai\", target: \"transform-corners\" },\n { id: \"e2\", source: \"transform-corners\", target: \"transform-caption\" },\n { id: \"e3\", source: \"transform-caption\", target: \"transform-webp\" },\n ],\n },\n};\n/**\n * All AI workflow templates\n */\nexport const aiWorkflowTemplates = [\n aiProductShot,\n aiHeroImage,\n aiMascot,\n aiLogoBrandKit,\n productPhotoEnhancement,\n aiArtSocialPost,\n];\n//# sourceMappingURL=ai-workflows.js.map","/**\n * Marketing Templates\n *\n * Social media kits, branding, and promotional asset workflows.\n * Most are pipeline templates that work offline (OSS-compatible).\n */\n/**\n * Social Media Kit\n * Canonical ID: social-media-kit\n */\nexport const socialMediaKit = {\n id: \"social-media-kit\",\n name: \"Social Media Kit\",\n description: \"Generate optimized images for all social platforms from one source\",\n category: \"Marketing\",\n generator: \"pipeline\",\n tags: [\"social\", \"og-image\", \"twitter\", \"instagram\", \"resize\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"share\",\n preview: {\n imageUrl: \"/showcase/pipelines/output/og-image.png\",\n },\n codeExample: `// One source -> all platforms\nconst socialKit = await floimg.pipeline(heroImage, [\n { op: 'resize', params: { width: 1200, height: 630 }, save: 'og-image.png' },\n { op: 'resize', params: { width: 800, height: 418 }, save: 'twitter-card.png' },\n { op: 'resize', params: { width: 1080, height: 1080 }, save: 'instagram.png' },\n]);`,\n seo: {\n title: \"Social Media Kit Generator\",\n description: \"Generate optimized images for all social platforms from one source image\",\n keywords: [\"social media\", \"og image\", \"twitter card\", \"instagram\", \"image resize\"],\n },\n workflow: {\n nodes: [\n {\n id: \"input-1\",\n type: \"input\",\n position: { x: 100, y: 200 },\n data: {},\n },\n {\n id: \"transform-og\",\n type: \"transform\",\n position: { x: 400, y: 100 },\n data: {\n operation: \"resize\",\n params: {\n width: 1200,\n height: 630,\n fit: \"cover\",\n },\n },\n },\n {\n id: \"transform-twitter\",\n type: \"transform\",\n position: { x: 400, y: 200 },\n data: {\n operation: \"resize\",\n params: {\n width: 800,\n height: 418,\n fit: \"cover\",\n },\n },\n },\n {\n id: \"transform-instagram\",\n type: \"transform\",\n position: { x: 400, y: 300 },\n data: {\n operation: \"resize\",\n params: {\n width: 1080,\n height: 1080,\n fit: \"cover\",\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"input-1\", target: \"transform-og\" },\n { id: \"e2\", source: \"input-1\", target: \"transform-twitter\" },\n { id: \"e3\", source: \"input-1\", target: \"transform-instagram\" },\n ],\n },\n};\n/**\n * Avatar Processing Pipeline\n * Canonical ID: avatar-pipeline\n */\nexport const avatarPipeline = {\n id: \"avatar-pipeline\",\n name: \"Avatar Processing\",\n description: \"Generate consistent avatar sizes with circular crop and optimization\",\n category: \"Marketing\",\n generator: \"pipeline\",\n tags: [\"avatar\", \"profile\", \"resize\", \"crop\", \"user\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"image\",\n preview: {\n imageUrl: \"/showcase/pipelines/output/avatar-128.png\",\n },\n codeExample: `const avatars = await floimg.pipeline(photo, [\n { op: 'crop', params: { shape: 'circle' } },\n { op: 'resize', params: { width: 256 }, save: 'avatar-256.png' },\n { op: 'resize', params: { width: 128 }, save: 'avatar-128.png' },\n { op: 'resize', params: { width: 64 }, save: 'avatar-64.png' },\n]);`,\n seo: {\n title: \"Avatar Processing Pipeline\",\n description: \"Generate consistent avatar sizes with circular crop and optimization\",\n keywords: [\"avatar\", \"profile picture\", \"image resize\", \"circular crop\"],\n },\n workflow: {\n nodes: [\n {\n id: \"input-1\",\n type: \"input\",\n position: { x: 100, y: 200 },\n data: {},\n },\n {\n id: \"transform-crop\",\n type: \"transform\",\n position: { x: 350, y: 200 },\n data: {\n operation: \"crop\",\n params: {\n shape: \"circle\",\n },\n },\n },\n {\n id: \"transform-256\",\n type: \"transform\",\n position: { x: 600, y: 100 },\n data: {\n operation: \"resize\",\n params: {\n width: 256,\n height: 256,\n },\n },\n },\n {\n id: \"transform-128\",\n type: \"transform\",\n position: { x: 600, y: 200 },\n data: {\n operation: \"resize\",\n params: {\n width: 128,\n height: 128,\n },\n },\n },\n {\n id: \"transform-64\",\n type: \"transform\",\n position: { x: 600, y: 300 },\n data: {\n operation: \"resize\",\n params: {\n width: 64,\n height: 64,\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"input-1\", target: \"transform-crop\" },\n { id: \"e2\", source: \"transform-crop\", target: \"transform-256\" },\n { id: \"e3\", source: \"transform-crop\", target: \"transform-128\" },\n { id: \"e4\", source: \"transform-crop\", target: \"transform-64\" },\n ],\n },\n};\n/**\n * Branded Watermark\n * Canonical ID: watermark-branding\n */\nexport const watermarkBranding = {\n id: \"watermark-branding\",\n name: \"Branded Watermark\",\n description: \"Add your logo watermark to images automatically\",\n category: \"Marketing\",\n generator: \"pipeline\",\n tags: [\"watermark\", \"branding\", \"logo\", \"protection\", \"copyright\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"image\",\n preview: {\n imageUrl: \"/showcase/pipelines/output/watermark-branded.png\",\n },\n seo: {\n title: \"Branded Watermark Template\",\n description: \"Add professional watermarks to protect and brand your images\",\n keywords: [\"watermark\", \"branding\", \"image protection\", \"logo overlay\"],\n },\n workflow: {\n nodes: [\n {\n id: \"gen-1\",\n type: \"generator\",\n position: { x: 100, y: 100 },\n data: {\n generatorName: \"quickchart\",\n params: {\n chart: {\n type: \"bar\",\n data: {\n labels: [\"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\"],\n datasets: [\n {\n label: \"Sales\",\n data: [45, 62, 38, 71, 55],\n backgroundColor: \"rgba(99, 102, 241, 0.8)\",\n },\n ],\n },\n },\n width: 600,\n height: 400,\n },\n },\n },\n {\n id: \"transform-1\",\n type: \"transform\",\n position: { x: 400, y: 100 },\n data: {\n operation: \"addCaption\",\n params: {\n text: \"floimg.com\",\n position: \"bottom-right\",\n fontSize: 14,\n color: \"#9ca3af\",\n padding: 10,\n },\n },\n },\n {\n id: \"transform-2\",\n type: \"transform\",\n position: { x: 700, y: 100 },\n data: {\n operation: \"roundCorners\",\n params: {\n radius: 16,\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"gen-1\", target: \"transform-1\" },\n { id: \"e2\", source: \"transform-1\", target: \"transform-2\" },\n ],\n },\n};\n/**\n * Image Filters\n * Canonical ID: filter-showcase\n */\nexport const filterShowcase = {\n id: \"filter-showcase\",\n name: \"Image Filters\",\n description: \"Apply artistic filters: vintage, dramatic, vibrant, and more\",\n category: \"Marketing\",\n generator: \"pipeline\",\n tags: [\"filter\", \"vintage\", \"effects\", \"artistic\", \"photo\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"image\",\n preview: {\n imageUrl: \"/showcase/pipelines/output/filter-vintage.png\",\n },\n seo: {\n title: \"Image Filter Effects\",\n description: \"Apply artistic filters like vintage, dramatic, and vibrant effects\",\n keywords: [\"image filter\", \"photo effects\", \"vintage filter\", \"artistic\"],\n },\n workflow: {\n nodes: [\n {\n id: \"input-1\",\n type: \"input\",\n position: { x: 100, y: 200 },\n data: {},\n },\n {\n id: \"transform-vintage\",\n type: \"transform\",\n position: { x: 400, y: 100 },\n data: {\n operation: \"adjustColors\",\n params: {\n saturation: 0.7,\n brightness: 0.9,\n sepia: 0.3,\n },\n },\n },\n {\n id: \"transform-vibrant\",\n type: \"transform\",\n position: { x: 400, y: 200 },\n data: {\n operation: \"adjustColors\",\n params: {\n saturation: 1.4,\n contrast: 1.2,\n },\n },\n },\n {\n id: \"transform-dramatic\",\n type: \"transform\",\n position: { x: 400, y: 300 },\n data: {\n operation: \"adjustColors\",\n params: {\n contrast: 1.5,\n brightness: 0.8,\n saturation: 0.9,\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"input-1\", target: \"transform-vintage\" },\n { id: \"e2\", source: \"input-1\", target: \"transform-vibrant\" },\n { id: \"e3\", source: \"input-1\", target: \"transform-dramatic\" },\n ],\n },\n};\n/**\n * Responsive Image Pipeline\n * Canonical ID: responsive-images\n *\n * Multi-step workflow: Input → 5 parallel resize branches for responsive web\n * JTBD: Generate all responsive image sizes from one source for web performance\n */\nexport const responsiveImages = {\n id: \"responsive-images\",\n name: \"Responsive Image Pipeline\",\n description: \"Generate thumbnail, mobile, tablet, desktop, and retina sizes from one source\",\n category: \"Marketing\",\n generator: \"pipeline\",\n tags: [\"responsive\", \"web\", \"performance\", \"srcset\", \"resize\", \"pipeline\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"image\",\n preview: {\n imageUrl: \"/showcase/pipelines/output/responsive-desktop.png\",\n },\n codeExample: `// One source → all responsive sizes\nconst responsive = await floimg.from(source)\n .transform('resize', { width: 320 }) // Mobile\n .transform('resize', { width: 768 }) // Tablet\n .transform('resize', { width: 1024 }) // Desktop\n .transform('resize', { width: 2048 }) // Retina\n .toBlob();`,\n seo: {\n title: \"Responsive Image Pipeline\",\n description: \"Generate all responsive image sizes for web srcset from one source\",\n keywords: [\"responsive images\", \"srcset\", \"web performance\", \"image optimization\"],\n },\n workflow: {\n nodes: [\n {\n id: \"input-1\",\n type: \"input\",\n position: { x: 100, y: 250 },\n data: {},\n },\n {\n id: \"transform-thumb\",\n type: \"transform\",\n position: { x: 400, y: 50 },\n data: {\n operation: \"resize\",\n params: {\n width: 150,\n fit: \"inside\",\n },\n },\n },\n {\n id: \"transform-mobile\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 320,\n fit: \"inside\",\n },\n },\n },\n {\n id: \"transform-tablet\",\n type: \"transform\",\n position: { x: 400, y: 250 },\n data: {\n operation: \"resize\",\n params: {\n width: 768,\n fit: \"inside\",\n },\n },\n },\n {\n id: \"transform-desktop\",\n type: \"transform\",\n position: { x: 400, y: 350 },\n data: {\n operation: \"resize\",\n params: {\n width: 1024,\n fit: \"inside\",\n },\n },\n },\n {\n id: \"transform-retina\",\n type: \"transform\",\n position: { x: 400, y: 450 },\n data: {\n operation: \"resize\",\n params: {\n width: 2048,\n fit: \"inside\",\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"input-1\", target: \"transform-thumb\" },\n { id: \"e2\", source: \"input-1\", target: \"transform-mobile\" },\n { id: \"e3\", source: \"input-1\", target: \"transform-tablet\" },\n { id: \"e4\", source: \"input-1\", target: \"transform-desktop\" },\n { id: \"e5\", source: \"input-1\", target: \"transform-retina\" },\n ],\n },\n};\n/**\n * Team Headshot Standardizer\n * Canonical ID: team-headshots\n *\n * Multi-step workflow: Input → Crop square → Resize → Grayscale → PNG export\n * JTBD: Standardize team photos for about pages and directories\n */\nexport const teamHeadshots = {\n id: \"team-headshots\",\n name: \"Team Headshot Standardizer\",\n description: \"Standardize team photos with consistent sizing and professional styling\",\n category: \"Marketing\",\n generator: \"pipeline\",\n tags: [\"headshot\", \"team\", \"about-page\", \"profile\", \"standardize\", \"pipeline\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"image\",\n preview: {\n imageUrl: \"/showcase/pipelines/output/headshot-standard.png\",\n },\n codeExample: `const headshot = await floimg.from(photo)\n .transform('extract', { width: 400, height: 400, gravity: 'face' })\n .transform('resize', { width: 300, height: 300 })\n .transform('grayscale')\n .transform('convert', { to: 'image/png' })\n .toBlob();`,\n seo: {\n title: \"Team Headshot Standardizer\",\n description: \"Standardize team photos with consistent sizing for about pages\",\n keywords: [\"headshot\", \"team photo\", \"about page\", \"profile picture\"],\n },\n workflow: {\n nodes: [\n {\n id: \"input-1\",\n type: \"input\",\n position: { x: 100, y: 150 },\n data: {},\n },\n {\n id: \"transform-crop\",\n type: \"transform\",\n position: { x: 350, y: 150 },\n data: {\n operation: \"extract\",\n params: {\n width: 400,\n height: 400,\n gravity: \"center\",\n },\n },\n },\n {\n id: \"transform-resize\",\n type: \"transform\",\n position: { x: 600, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 300,\n height: 300,\n fit: \"cover\",\n },\n },\n },\n {\n id: \"transform-grayscale\",\n type: \"transform\",\n position: { x: 850, y: 150 },\n data: {\n operation: \"grayscale\",\n params: {},\n },\n },\n {\n id: \"transform-png\",\n type: \"transform\",\n position: { x: 1100, y: 150 },\n data: {\n operation: \"convert\",\n params: {\n to: \"image/png\",\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"input-1\", target: \"transform-crop\" },\n { id: \"e2\", source: \"transform-crop\", target: \"transform-resize\" },\n { id: \"e3\", source: \"transform-resize\", target: \"transform-grayscale\" },\n { id: \"e4\", source: \"transform-grayscale\", target: \"transform-png\" },\n ],\n },\n};\n/**\n * Screenshot to Documentation Asset\n * Canonical ID: screenshot-docs\n *\n * Multi-step workflow: Screenshot URL → Resize → Add border/shadow → Optimize\n * JTBD: Prepare screenshots for documentation and README files\n */\nexport const screenshotDocs = {\n id: \"screenshot-docs\",\n name: \"Screenshot to Docs\",\n description: \"Prepare screenshots for documentation with borders and optimization\",\n category: \"Marketing\",\n generator: \"screenshot\",\n tags: [\"screenshot\", \"documentation\", \"readme\", \"border\", \"pipeline\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"image\",\n preview: {\n imageUrl: \"/showcase/pipelines/output/screenshot-docs.png\",\n },\n codeExample: `const docImage = await floimg\n .generate('screenshot', { url: 'https://example.com', width: 1280 })\n .transform('resize', { width: 800, fit: 'inside' })\n .transform('extend', { top: 16, bottom: 16, left: 16, right: 16, background: '#f3f4f6' })\n .transform('roundCorners', { radius: 8 })\n .transform('convert', { to: 'image/png' })\n .toBlob();`,\n seo: {\n title: \"Screenshot to Documentation Asset\",\n description: \"Prepare screenshots for documentation with professional styling\",\n keywords: [\"screenshot\", \"documentation\", \"readme\", \"developer tools\"],\n },\n workflow: {\n nodes: [\n {\n id: \"gen-1\",\n type: \"generator\",\n position: { x: 100, y: 150 },\n data: {\n generatorName: \"screenshot\",\n params: {\n url: \"https://floimg.com\",\n width: 1280,\n height: 800,\n },\n },\n },\n {\n id: \"transform-resize\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 800,\n fit: \"inside\",\n },\n },\n },\n {\n id: \"transform-border\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"extend\",\n params: {\n top: 16,\n bottom: 16,\n left: 16,\n right: 16,\n background: \"#f3f4f6\",\n },\n },\n },\n {\n id: \"transform-corners\",\n type: \"transform\",\n position: { x: 1000, y: 150 },\n data: {\n operation: \"roundCorners\",\n params: {\n radius: 8,\n },\n },\n },\n {\n id: \"transform-png\",\n type: \"transform\",\n position: { x: 1300, y: 150 },\n data: {\n operation: \"convert\",\n params: {\n to: \"image/png\",\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"gen-1\", target: \"transform-resize\" },\n { id: \"e2\", source: \"transform-resize\", target: \"transform-border\" },\n { id: \"e3\", source: \"transform-border\", target: \"transform-corners\" },\n { id: \"e4\", source: \"transform-corners\", target: \"transform-png\" },\n ],\n },\n};\n/**\n * Blog Post OG Image\n * Canonical ID: blog-og-image\n *\n * Multi-step workflow: Input → Resize to OG → Add title overlay → WebP export\n * JTBD: Create social sharing images for blog posts with title overlay\n */\nexport const blogOgImage = {\n id: \"blog-og-image\",\n name: \"Blog Post OG Image\",\n description: \"Create social sharing images for blog posts with title overlay\",\n category: \"Marketing\",\n generator: \"pipeline\",\n tags: [\"blog\", \"og-image\", \"social\", \"title\", \"overlay\", \"pipeline\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"share\",\n preview: {\n imageUrl: \"/showcase/pipelines/output/blog-og.png\",\n },\n codeExample: `const ogImage = await floimg.from(heroImage)\n .transform('resize', { width: 1200, height: 630, fit: 'cover' })\n .transform('addCaption', {\n text: 'How to Build Image Pipelines',\n position: 'center',\n fontSize: 48,\n color: '#ffffff'\n })\n .transform('convert', { to: 'image/webp', quality: 85 })\n .toBlob();`,\n seo: {\n title: \"Blog Post OG Image Generator\",\n description: \"Create social sharing images for blog posts with title overlay\",\n keywords: [\"og image\", \"blog\", \"social sharing\", \"title overlay\"],\n },\n workflow: {\n nodes: [\n {\n id: \"input-1\",\n type: \"input\",\n position: { x: 100, y: 150 },\n data: {},\n },\n {\n id: \"transform-resize\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 1200,\n height: 630,\n fit: \"cover\",\n },\n },\n },\n {\n id: \"transform-caption\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"addCaption\",\n params: {\n text: \"Your Blog Post Title\",\n position: \"center\",\n fontSize: 48,\n color: \"#ffffff\",\n padding: 32,\n },\n },\n },\n {\n id: \"transform-webp\",\n type: \"transform\",\n position: { x: 1000, y: 150 },\n data: {\n operation: \"convert\",\n params: {\n to: \"image/webp\",\n quality: 85,\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"input-1\", target: \"transform-resize\" },\n { id: \"e2\", source: \"transform-resize\", target: \"transform-caption\" },\n { id: \"e3\", source: \"transform-caption\", target: \"transform-webp\" },\n ],\n },\n};\n/**\n * Email Banner\n * Canonical ID: email-banner\n *\n * Multi-step workflow: Input → Resize 600x200 → Add CTA text → PNG export\n * JTBD: Create email header banners with consistent dimensions for newsletters\n */\nexport const emailBanner = {\n id: \"email-banner\",\n name: \"Email Banner\",\n description: \"Create email header banners with consistent dimensions for newsletters\",\n category: \"Marketing\",\n generator: \"pipeline\",\n tags: [\"email\", \"banner\", \"newsletter\", \"header\", \"marketing\", \"pipeline\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"share\",\n preview: {\n imageUrl: \"/showcase/pipelines/output/email-banner.png\",\n },\n codeExample: `const banner = await floimg.from(image)\n .transform('resize', { width: 600, height: 200, fit: 'cover' })\n .transform('addCaption', {\n text: 'Weekly Newsletter',\n position: 'center',\n fontSize: 32,\n color: '#ffffff'\n })\n .transform('convert', { to: 'image/png' })\n .toBlob();`,\n seo: {\n title: \"Email Banner Generator\",\n description: \"Create email header banners with consistent dimensions\",\n keywords: [\"email banner\", \"newsletter\", \"email marketing\", \"header image\"],\n },\n workflow: {\n nodes: [\n {\n id: \"input-1\",\n type: \"input\",\n position: { x: 100, y: 150 },\n data: {},\n },\n {\n id: \"transform-resize\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 600,\n height: 200,\n fit: \"cover\",\n },\n },\n },\n {\n id: \"transform-caption\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"addCaption\",\n params: {\n text: \"Weekly Newsletter\",\n position: \"center\",\n fontSize: 32,\n color: \"#ffffff\",\n padding: 16,\n },\n },\n },\n {\n id: \"transform-png\",\n type: \"transform\",\n position: { x: 1000, y: 150 },\n data: {\n operation: \"convert\",\n params: {\n to: \"image/png\",\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"input-1\", target: \"transform-resize\" },\n { id: \"e2\", source: \"transform-resize\", target: \"transform-caption\" },\n { id: \"e3\", source: \"transform-caption\", target: \"transform-png\" },\n ],\n },\n};\n/**\n * App Icon Generator\n * Canonical ID: app-icons\n *\n * Multi-step workflow: Input → Remove background → Multiple iOS/Android sizes\n * JTBD: Generate all required app icon sizes for iOS and Android from one source\n */\nexport const appIcons = {\n id: \"app-icons\",\n name: \"App Icon Generator\",\n description: \"Generate iOS and Android app icon sizes from one source image\",\n category: \"Marketing\",\n generator: \"pipeline\",\n tags: [\"app-icon\", \"ios\", \"android\", \"mobile\", \"resize\", \"pipeline\"],\n requiresCloud: true,\n requiresAuth: true,\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"image\",\n preview: {\n imageUrl: \"/showcase/pipelines/output/app-icon-180.png\",\n },\n codeExample: `const icons = await floimg.from(logo)\n .transform('removeBackground')\n .transform('resize', { width: 180, height: 180 }) // iOS\n .transform('resize', { width: 192, height: 192 }) // Android\n .transform('resize', { width: 512, height: 512 }) // Store\n .toBlob();`,\n seo: {\n title: \"App Icon Generator\",\n description: \"Generate all required iOS and Android app icon sizes\",\n keywords: [\"app icon\", \"ios icon\", \"android icon\", \"mobile app\"],\n },\n workflow: {\n nodes: [\n {\n id: \"input-1\",\n type: \"input\",\n position: { x: 100, y: 200 },\n data: {},\n },\n {\n id: \"transform-bg\",\n type: \"transform\",\n position: { x: 350, y: 200 },\n data: {\n operation: \"removeBackground\",\n params: {},\n },\n },\n {\n id: \"transform-ios-60\",\n type: \"transform\",\n position: { x: 600, y: 50 },\n data: {\n operation: \"resize\",\n params: {\n width: 60,\n height: 60,\n fit: \"contain\",\n },\n },\n },\n {\n id: \"transform-ios-180\",\n type: \"transform\",\n position: { x: 600, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 180,\n height: 180,\n fit: \"contain\",\n },\n },\n },\n {\n id: \"transform-android-192\",\n type: \"transform\",\n position: { x: 600, y: 250 },\n data: {\n operation: \"resize\",\n params: {\n width: 192,\n height: 192,\n fit: \"contain\",\n },\n },\n },\n {\n id: \"transform-store-512\",\n type: \"transform\",\n position: { x: 600, y: 350 },\n data: {\n operation: \"resize\",\n params: {\n width: 512,\n height: 512,\n fit: \"contain\",\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"input-1\", target: \"transform-bg\" },\n { id: \"e2\", source: \"transform-bg\", target: \"transform-ios-60\" },\n { id: \"e3\", source: \"transform-bg\", target: \"transform-ios-180\" },\n { id: \"e4\", source: \"transform-bg\", target: \"transform-android-192\" },\n { id: \"e5\", source: \"transform-bg\", target: \"transform-store-512\" },\n ],\n },\n};\n/**\n * All marketing templates\n */\nexport const marketingTemplates = [\n socialMediaKit,\n avatarPipeline,\n watermarkBranding,\n filterShowcase,\n responsiveImages,\n teamHeadshots,\n screenshotDocs,\n blogOgImage,\n emailBanner,\n appIcons,\n];\n//# sourceMappingURL=marketing.js.map","/**\n * Utility Templates\n *\n * QR codes, format conversion, and general-purpose utilities.\n * All templates in this category work offline (OSS-compatible).\n */\n/**\n * Branded QR Code Pipeline\n * Canonical ID: branded-qr\n *\n * Multi-step workflow: Generate QR → Resize → Add rounded corners → Convert to PNG\n * Demonstrates: composable transforms on generated content\n */\nexport const brandedQR = {\n id: \"branded-qr\",\n name: \"Branded QR Code\",\n description: \"QR code with custom colors, rounded corners, and optimized for print or digital\",\n category: \"Utilities\",\n generator: \"qr\",\n tags: [\"qr\", \"branded\", \"link\", \"custom\", \"url\", \"pipeline\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"qr\",\n preview: {\n imageUrl: \"/showcase/qr-codes/qr-brand.png\",\n },\n codeExample: `const qr = await floimg\n .generate('qr', {\n data: 'https://floimg.com',\n dark: '#0d9488',\n light: '#ffffff'\n })\n .transform('resize', { width: 300, height: 300 })\n .transform('roundCorners', { radius: 16 })\n .transform('convert', { to: 'image/png' })\n .toBlob();`,\n seo: {\n title: \"Branded QR Code Generator\",\n description: \"Generate QR codes with custom colors, rounded corners, and professional styling\",\n keywords: [\"qr code\", \"branded qr\", \"custom qr\", \"marketing\"],\n },\n workflow: {\n nodes: [\n {\n id: \"gen-1\",\n type: \"generator\",\n position: { x: 100, y: 150 },\n data: {\n generatorName: \"qr\",\n params: {\n data: \"https://floimg.com\",\n size: 400,\n margin: 2,\n dark: \"#0d9488\",\n light: \"#ffffff\",\n errorCorrectionLevel: \"M\",\n },\n },\n },\n {\n id: \"transform-resize\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 300,\n height: 300,\n fit: \"contain\",\n },\n },\n },\n {\n id: \"transform-corners\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"roundCorners\",\n params: {\n radius: 16,\n },\n },\n },\n {\n id: \"transform-convert\",\n type: \"transform\",\n position: { x: 1000, y: 150 },\n data: {\n operation: \"convert\",\n params: {\n to: \"image/png\",\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"gen-1\", target: \"transform-resize\" },\n { id: \"e2\", source: \"transform-resize\", target: \"transform-corners\" },\n { id: \"e3\", source: \"transform-corners\", target: \"transform-convert\" },\n ],\n },\n};\n/**\n * Dark Mode QR Code Pipeline\n * Canonical ID: dark-qr\n *\n * Multi-step workflow: Generate inverted QR → Resize → Add subtle border → WebP export\n * Demonstrates: transforms for dark UI integration\n */\nexport const darkQR = {\n id: \"dark-qr\",\n name: \"Dark Mode QR\",\n description: \"QR code optimized for dark backgrounds with subtle border and web-optimized export\",\n category: \"Utilities\",\n generator: \"qr\",\n tags: [\"qr\", \"dark-mode\", \"link\", \"inverted\", \"pipeline\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"qr\",\n preview: {\n imageUrl: \"/showcase/qr-codes/qr-dark.png\",\n },\n codeExample: `const qr = await floimg\n .generate('qr', {\n data: 'https://floimg.com',\n dark: '#ffffff',\n light: '#18181b'\n })\n .transform('resize', { width: 300, height: 300 })\n .transform('extend', {\n top: 8, bottom: 8, left: 8, right: 8,\n background: '#27272a'\n })\n .transform('convert', { to: 'image/webp', quality: 90 })\n .toBlob();`,\n seo: {\n title: \"Dark Mode QR Code\",\n description: \"QR codes optimized for dark backgrounds and dark mode UIs\",\n keywords: [\"qr code\", \"dark mode\", \"inverted qr\", \"night mode\"],\n },\n workflow: {\n nodes: [\n {\n id: \"gen-1\",\n type: \"generator\",\n position: { x: 100, y: 150 },\n data: {\n generatorName: \"qr\",\n params: {\n data: \"https://floimg.com\",\n size: 400,\n margin: 2,\n dark: \"#ffffff\",\n light: \"#18181b\",\n errorCorrectionLevel: \"M\",\n },\n },\n },\n {\n id: \"transform-resize\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 300,\n height: 300,\n fit: \"contain\",\n },\n },\n },\n {\n id: \"transform-border\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"extend\",\n params: {\n top: 8,\n bottom: 8,\n left: 8,\n right: 8,\n background: \"#27272a\",\n },\n },\n },\n {\n id: \"transform-webp\",\n type: \"transform\",\n position: { x: 1000, y: 150 },\n data: {\n operation: \"convert\",\n params: {\n to: \"image/webp\",\n quality: 90,\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"gen-1\", target: \"transform-resize\" },\n { id: \"e2\", source: \"transform-resize\", target: \"transform-border\" },\n { id: \"e3\", source: \"transform-border\", target: \"transform-webp\" },\n ],\n },\n};\n/**\n * WiFi QR Code Pipeline\n * Canonical ID: wifi-qr\n *\n * Multi-step workflow: Generate WiFi QR → Resize → Add caption label → Rounded corners\n * Demonstrates: adding context/labels to generated content\n */\nexport const wifiQR = {\n id: \"wifi-qr\",\n name: \"WiFi QR Code\",\n description: \"Scannable WiFi QR code with network name label and professional styling\",\n category: \"Utilities\",\n generator: \"qr\",\n tags: [\"qr\", \"wifi\", \"network\", \"guest\", \"access\", \"pipeline\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"qr\",\n preview: {\n imageUrl: \"/showcase/qr-codes/qr-wifi.png\",\n },\n codeExample: `const qr = await floimg\n .generate('qr', {\n data: 'WIFI:T:WPA;S:GuestNetwork;P:welcome123;;',\n dark: '#059669',\n light: '#ffffff'\n })\n .transform('resize', { width: 300, height: 300 })\n .transform('addCaption', {\n text: 'Scan for WiFi',\n position: 'bottom-center',\n fontSize: 18,\n color: '#059669'\n })\n .transform('roundCorners', { radius: 12 })\n .toBlob();`,\n seo: {\n title: \"WiFi QR Code Generator\",\n description: \"Generate scannable QR codes for easy WiFi network access sharing\",\n keywords: [\"wifi qr\", \"network access\", \"guest wifi\", \"qr code\"],\n },\n workflow: {\n nodes: [\n {\n id: \"gen-1\",\n type: \"generator\",\n position: { x: 100, y: 150 },\n data: {\n generatorName: \"qr\",\n params: {\n data: \"WIFI:T:WPA;S:GuestNetwork;P:welcome123;;\",\n size: 400,\n margin: 2,\n dark: \"#059669\",\n light: \"#ffffff\",\n errorCorrectionLevel: \"H\",\n },\n },\n },\n {\n id: \"transform-resize\",\n type: \"transform\",\n position: { x: 400, y: 150 },\n data: {\n operation: \"resize\",\n params: {\n width: 300,\n height: 300,\n fit: \"contain\",\n },\n },\n },\n {\n id: \"transform-caption\",\n type: \"transform\",\n position: { x: 700, y: 150 },\n data: {\n operation: \"addCaption\",\n params: {\n text: \"Scan for WiFi\",\n position: \"bottom-center\",\n fontSize: 18,\n color: \"#059669\",\n padding: 16,\n },\n },\n },\n {\n id: \"transform-corners\",\n type: \"transform\",\n position: { x: 1000, y: 150 },\n data: {\n operation: \"roundCorners\",\n params: {\n radius: 12,\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"gen-1\", target: \"transform-resize\" },\n { id: \"e2\", source: \"transform-resize\", target: \"transform-caption\" },\n { id: \"e3\", source: \"transform-caption\", target: \"transform-corners\" },\n ],\n },\n};\n/**\n * Thumbnail Generator\n * Canonical ID: thumbnail-generator\n */\nexport const thumbnailGenerator = {\n id: \"thumbnail-generator\",\n name: \"Thumbnail Generator\",\n description: \"Create multiple thumbnail sizes with automatic optimization\",\n category: \"Utilities\",\n generator: \"pipeline\",\n tags: [\"thumbnail\", \"resize\", \"optimize\", \"batch\", \"responsive\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"image\",\n preview: {\n imageUrl: \"/showcase/pipelines/output/thumb-200.png\",\n },\n seo: {\n title: \"Thumbnail Generator\",\n description: \"Generate multiple thumbnail sizes with automatic optimization\",\n keywords: [\"thumbnail\", \"image resize\", \"responsive images\", \"optimization\"],\n },\n workflow: {\n nodes: [\n {\n id: \"input-1\",\n type: \"input\",\n position: { x: 100, y: 200 },\n data: {},\n },\n {\n id: \"transform-800\",\n type: \"transform\",\n position: { x: 400, y: 100 },\n data: {\n operation: \"resize\",\n params: {\n width: 800,\n fit: \"inside\",\n },\n },\n },\n {\n id: \"transform-400\",\n type: \"transform\",\n position: { x: 400, y: 200 },\n data: {\n operation: \"resize\",\n params: {\n width: 400,\n fit: \"inside\",\n },\n },\n },\n {\n id: \"transform-200\",\n type: \"transform\",\n position: { x: 400, y: 300 },\n data: {\n operation: \"resize\",\n params: {\n width: 200,\n fit: \"inside\",\n },\n },\n },\n ],\n edges: [\n { id: \"e1\", source: \"input-1\", target: \"transform-800\" },\n { id: \"e2\", source: \"input-1\", target: \"transform-400\" },\n { id: \"e3\", source: \"input-1\", target: \"transform-200\" },\n ],\n },\n};\n/**\n * Diagram to WebP Conversion\n * Canonical ID: diagram-webp\n */\nexport const diagramWebp = {\n id: \"diagram-webp\",\n name: \"Diagram to WebP\",\n description: \"Mermaid diagram converted to optimized WebP format\",\n category: \"Utilities\",\n generator: \"mermaid\",\n tags: [\"mermaid\", \"webp\", \"optimize\", \"pipeline\", \"conversion\"],\n capabilities: {\n claudeCodeReady: true,\n pipeline: true,\n },\n icon: \"diagram\",\n seo: {\n title: \"Diagram to WebP Converter\",\n description: \"Convert Mermaid diagrams to optimized WebP format\",\n keywords: [\"mermaid diagram\", \"webp conversion\", \"image optimization\"],\n },\n workflow: {\n nodes: [\n {\n id: \"gen-1\",\n type: \"generator\",\n position: { x: 100, y: 100 },\n data: {\n generatorName: \"mermaid\",\n params: {\n code: `graph LR\n A[Start] --> B{Decision}\n B -->|Yes| C[Action 1]\n B -->|No| D[Action 2]\n C --> E[End]\n D --> E`,\n theme: \"neutral\",\n },\n },\n },\n {\n id: \"transform-1\",\n type: \"transform\",\n position: { x: 400, y: 100 },\n data: {\n operation: \"convert\",\n params: {\n to: \"image/webp\",\n quality: 90,\n },\n },\n },\n ],\n edges: [{ id: \"e1\", source: \"gen-1\", target: \"transform-1\" }],\n },\n};\n/**\n * All utility templates\n */\nexport const utilityTemplates = [\n brandedQR,\n darkQR,\n wifiQR,\n thumbnailGenerator,\n diagramWebp,\n];\n//# sourceMappingURL=utilities.js.map","/**\n * @teamflojo/floimg-templates\n *\n * Official workflow templates for FloImg Studio.\n * Single source of truth for template definitions.\n *\n * @example\n * ```typescript\n * // Self-hosted: Get only templates that work offline\n * import { getCoreTemplates } from '@teamflojo/floimg-templates';\n * const templates = getCoreTemplates();\n *\n * // Cloud/full: Get all templates including those requiring API keys\n * import { getAllTemplates } from '@teamflojo/floimg-templates';\n * const templates = getAllTemplates();\n *\n * // Get specific template with metadata\n * import { getTemplateById } from '@teamflojo/floimg-templates';\n * const template = getTemplateById('revenue-chart');\n * ```\n */\n// Import all template categories\nimport { dataVizTemplates } from \"./templates/data-viz.js\";\nimport { aiWorkflowTemplates } from \"./templates/ai-workflows.js\";\nimport { marketingTemplates } from \"./templates/marketing.js\";\nimport { utilityTemplates } from \"./templates/utilities.js\";\n// Re-export individual templates for direct imports\nexport * from \"./templates/data-viz.js\";\nexport * from \"./templates/ai-workflows.js\";\nexport * from \"./templates/marketing.js\";\nexport * from \"./templates/utilities.js\";\n// ============================================\n// Template Registry\n// ============================================\n/**\n * All templates combined\n */\nexport const allTemplates = [\n ...dataVizTemplates,\n ...aiWorkflowTemplates,\n ...marketingTemplates,\n ...utilityTemplates,\n];\n/**\n * Core templates that work offline (no cloud required)\n * For FloImg Studio OSS and self-hosted deployments\n */\nexport const coreTemplates = allTemplates.filter((t) => !t.requiresCloud);\n/**\n * Cloud-only templates (require API keys like OpenAI, etc.)\n */\nexport const cloudTemplates = allTemplates.filter((t) => t.requiresCloud);\n// ============================================\n// Query Functions\n// ============================================\n/**\n * Get all templates (includes cloud-only templates)\n */\nexport function getAllTemplates() {\n return allTemplates;\n}\n/**\n * Get only core templates that work offline (for OSS Studio)\n */\nexport function getCoreTemplates() {\n return coreTemplates;\n}\n/**\n * Get cloud-only templates (require API keys)\n */\nexport function getCloudTemplates() {\n return cloudTemplates;\n}\n/**\n * Get a template by ID (searches all templates)\n */\nexport function getTemplateById(id) {\n return allTemplates.find((t) => t.id === id);\n}\n/**\n * Get a core template by ID (OSS-compatible only)\n */\nexport function getCoreTemplateById(id) {\n return coreTemplates.find((t) => t.id === id);\n}\n/**\n * Get all unique categories (from all templates)\n */\nexport function getCategories() {\n const categories = new Set(allTemplates.map((t) => t.category));\n return Array.from(categories);\n}\n/**\n * Get categories available in core templates (OSS-compatible)\n */\nexport function getCoreCategories() {\n const categories = new Set(coreTemplates.map((t) => t.category));\n return Array.from(categories);\n}\n/**\n * Get templates by category (from all templates)\n */\nexport function getTemplatesByCategory(category) {\n return allTemplates.filter((t) => t.category === category);\n}\n/**\n * Get core templates by category (OSS-compatible)\n */\nexport function getCoreTemplatesByCategory(category) {\n return coreTemplates.filter((t) => t.category === category);\n}\n/**\n * Get templates by generator type\n */\nexport function getTemplatesByGenerator(generator) {\n return allTemplates.filter((t) => t.generator === generator);\n}\n/**\n * Search templates by query (searches name, description, tags)\n */\nexport function searchTemplates(query) {\n const q = query.toLowerCase();\n return allTemplates.filter((t) => t.name.toLowerCase().includes(q) ||\n t.description.toLowerCase().includes(q) ||\n t.category.toLowerCase().includes(q) ||\n t.generator.toLowerCase().includes(q) ||\n t.tags?.some((tag) => tag.toLowerCase().includes(q)));\n}\n/**\n * Search core templates by query (OSS-compatible)\n */\nexport function searchCoreTemplates(query) {\n const q = query.toLowerCase();\n return coreTemplates.filter((t) => t.name.toLowerCase().includes(q) ||\n t.description.toLowerCase().includes(q) ||\n t.category.toLowerCase().includes(q) ||\n t.generator.toLowerCase().includes(q) ||\n t.tags?.some((tag) => tag.toLowerCase().includes(q)));\n}\n/**\n * Get templates that require authentication\n */\nexport function getAuthRequiredTemplates() {\n return allTemplates.filter((t) => t.requiresAuth);\n}\n/**\n * Get templates by capability\n */\nexport function getTemplatesByCapability(capability) {\n return allTemplates.filter((t) => t.capabilities?.[capability]);\n}\n// ============================================\n// Studio URL Helpers\n// ============================================\n/**\n * Get the Studio URL for a template\n * @param templateId - The template ID\n * @param baseUrl - Base URL (defaults to studio.floimg.com for cloud, or can be overridden for self-hosted)\n */\nexport function getStudioUrl(templateId, baseUrl = \"https://studio.floimg.com\") {\n return `${baseUrl}/?template=${templateId}`;\n}\n/**\n * Get the OSS Studio URL for a template (localhost default)\n * @param templateId - The template ID\n * @param port - Port number (defaults to 5173)\n */\nexport function getOSSStudioUrl(templateId, port = 5173) {\n return `http://localhost:${port}/?template=${templateId}`;\n}\n/**\n * Resolve a template by ID\n * @param id - Template ID\n * @returns The template or undefined\n */\nexport function resolveTemplate(id) {\n return getTemplateById(id);\n}\n// ============================================\n// Computed Metadata Helpers\n// ============================================\n/**\n * Get the node count for a template\n * Uses explicit nodeCount if set, otherwise computes from workflow.nodes.length\n */\nexport function getNodeCount(template) {\n if (template.nodeCount !== undefined) {\n return template.nodeCount;\n }\n return template.workflow.nodes.length;\n}\n/**\n * Get all templates with computed nodeCount added\n * Useful for consumers that want to display node count\n */\nexport function getAllTemplatesWithNodeCount() {\n return allTemplates.map((t) => ({\n ...t,\n nodeCount: getNodeCount(t),\n }));\n}\n/**\n * Get templates that are true pipelines (2+ nodes)\n */\nexport function getPipelineTemplates() {\n return allTemplates.filter((t) => getNodeCount(t) >= 2);\n}\n/**\n * Get templates sorted by complexity (node count, descending)\n */\nexport function getTemplatesByComplexity() {\n return [...allTemplates].sort((a, b) => getNodeCount(b) - getNodeCount(a));\n}\n//# sourceMappingURL=index.js.map","import { useState, useMemo } from \"react\";\nimport {\n coreTemplates as templates,\n getCoreCategories as getCategories,\n type Template,\n} from \"@teamflojo/floimg-templates\";\n\ninterface TemplateGalleryProps {\n onSelect: (templateId: string) => void;\n}\n\nexport function TemplateGallery({ onSelect }: TemplateGalleryProps) {\n const [selectedCategory, setSelectedCategory] = useState<string | null>(null);\n const [searchQuery, setSearchQuery] = useState(\"\");\n\n const categories = useMemo(() => getCategories(), []);\n\n const filteredTemplates = useMemo(() => {\n let result = templates;\n\n // Filter by category\n if (selectedCategory) {\n result = result.filter((t) => t.category === selectedCategory);\n }\n\n // Filter by search query\n if (searchQuery) {\n const q = searchQuery.toLowerCase();\n result = result.filter(\n (t) =>\n t.name.toLowerCase().includes(q) ||\n t.description.toLowerCase().includes(q) ||\n t.generator.toLowerCase().includes(q) ||\n t.tags?.some((tag) => tag.toLowerCase().includes(q))\n );\n }\n\n return result;\n }, [selectedCategory, searchQuery]);\n\n return (\n <div className=\"p-6\">\n <div className=\"mb-6\">\n <h2 className=\"text-2xl font-bold text-gray-900 dark:text-white mb-2\">Templates</h2>\n <p className=\"text-gray-600 dark:text-zinc-400\">\n Start with a pre-built workflow. Click any template to load it into the editor.\n </p>\n </div>\n\n {/* Search and filters */}\n <div className=\"flex flex-wrap gap-4 mb-6\">\n <input\n type=\"text\"\n placeholder=\"Search templates...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"px-4 py-2 border border-gray-300 dark:border-zinc-600 rounded-lg bg-white dark:bg-zinc-800 text-gray-900 dark:text-white focus:ring-2 focus:ring-teal-500 focus:border-transparent w-64\"\n />\n\n <div className=\"flex gap-2 flex-wrap\">\n <button\n onClick={() => setSelectedCategory(null)}\n className={`px-3 py-1.5 rounded-full text-sm font-medium transition-colors ${\n selectedCategory === null\n ? \"bg-teal-600 text-white\"\n : \"bg-gray-200 dark:bg-zinc-700 text-gray-700 dark:text-zinc-300 hover:bg-gray-300 dark:hover:bg-zinc-600\"\n }`}\n >\n All\n </button>\n {categories.map((category) => (\n <button\n key={category}\n onClick={() => setSelectedCategory(category)}\n className={`px-3 py-1.5 rounded-full text-sm font-medium transition-colors ${\n selectedCategory === category\n ? \"bg-teal-600 text-white\"\n : \"bg-gray-200 dark:bg-zinc-700 text-gray-700 dark:text-zinc-300 hover:bg-gray-300 dark:hover:bg-zinc-600\"\n }`}\n >\n {category}\n </button>\n ))}\n </div>\n </div>\n\n {/* Template grid */}\n {filteredTemplates.length === 0 ? (\n <div className=\"text-center py-12 text-gray-500 dark:text-zinc-400\">\n No templates found matching your criteria.\n </div>\n ) : (\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6\">\n {filteredTemplates.map((template) => (\n <TemplateCard\n key={template.id}\n template={template}\n onSelect={() => onSelect(template.id)}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n\ninterface TemplateCardProps {\n template: Template;\n onSelect: () => void;\n}\n\nfunction TemplateCard({ template, onSelect }: TemplateCardProps) {\n const nodeCount = template.workflow.nodes.length;\n const edgeCount = template.workflow.edges.length;\n\n // Generator badge colors\n const generatorColors: Record<string, string> = {\n quickchart: \"bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-300\",\n mermaid: \"bg-pink-100 text-pink-800 dark:bg-pink-900/30 dark:text-pink-300\",\n qr: \"bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-300\",\n d3: \"bg-orange-100 text-orange-800 dark:bg-orange-900/30 dark:text-orange-300\",\n };\n\n return (\n <div className=\"bg-white dark:bg-zinc-800 rounded-lg border border-gray-200 dark:border-zinc-700 overflow-hidden hover:shadow-lg transition-shadow\">\n {/* Preview area */}\n <div className=\"aspect-video bg-gray-100 dark:bg-zinc-900 flex items-center justify-center p-4\">\n {template.preview ? (\n <img\n src={template.preview.imageUrl}\n alt={template.name}\n className=\"max-w-full max-h-full object-contain\"\n />\n ) : (\n <div className=\"text-center text-gray-400 dark:text-zinc-500\">\n <svg\n className=\"w-12 h-12 mx-auto mb-2\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n 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 />\n </svg>\n <span className=\"text-sm\">No preview</span>\n </div>\n )}\n </div>\n\n {/* Content */}\n <div className=\"p-4\">\n <div className=\"flex items-start justify-between mb-2\">\n <h3 className=\"text-lg font-semibold text-gray-900 dark:text-white\">{template.name}</h3>\n <span\n className={`px-2 py-0.5 rounded text-xs font-medium ${\n generatorColors[template.generator] ||\n \"bg-gray-100 text-gray-800 dark:bg-zinc-700 dark:text-zinc-300\"\n }`}\n >\n {template.generator}\n </span>\n </div>\n\n <p className=\"text-sm text-gray-600 dark:text-zinc-400 mb-3\">{template.description}</p>\n\n {/* Metadata */}\n <div className=\"flex items-center gap-4 text-xs text-gray-500 dark:text-zinc-500 mb-4\">\n <span className=\"flex items-center gap-1\">\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 6h16M4 12h16M4 18h7\"\n />\n </svg>\n {nodeCount} node{nodeCount !== 1 ? \"s\" : \"\"}\n </span>\n {edgeCount > 0 && (\n <span className=\"flex items-center gap-1\">\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M13 7l5 5m0 0l-5 5m5-5H6\"\n />\n </svg>\n {edgeCount} edge{edgeCount !== 1 ? \"s\" : \"\"}\n </span>\n )}\n </div>\n\n {/* Tags */}\n {template.tags && template.tags.length > 0 && (\n <div className=\"flex flex-wrap gap-1 mb-4\">\n {template.tags.slice(0, 4).map((tag) => (\n <span\n key={tag}\n className=\"px-2 py-0.5 bg-gray-100 dark:bg-zinc-700 text-gray-600 dark:text-zinc-400 rounded text-xs\"\n >\n {tag}\n </span>\n ))}\n </div>\n )}\n\n {/* Action button */}\n <button\n onClick={onSelect}\n className=\"w-full py-2 px-4 bg-teal-600 hover:bg-teal-700 text-white rounded-lg font-medium transition-colors\"\n >\n Use Template\n </button>\n </div>\n </div>\n );\n}\n","import { useState } from \"react\";\nimport { useWorkflowStore, type SavedWorkflow } from \"../stores/workflowStore\";\n\ninterface WorkflowItemProps {\n workflow: SavedWorkflow;\n isActive: boolean;\n onLoad: () => void;\n onDelete: () => void;\n onRename: (name: string) => void;\n onDuplicate: () => void;\n}\n\nfunction WorkflowItem({\n workflow,\n isActive,\n onLoad,\n onDelete,\n onRename,\n onDuplicate,\n}: WorkflowItemProps) {\n const [isEditing, setIsEditing] = useState(false);\n const [editName, setEditName] = useState(workflow.name);\n const [showMenu, setShowMenu] = useState(false);\n\n const handleRename = () => {\n if (editName.trim() && editName !== workflow.name) {\n onRename(editName.trim());\n }\n setIsEditing(false);\n };\n\n const formatDate = (timestamp: number) => {\n const date = new Date(timestamp);\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMs / 3600000);\n const diffDays = Math.floor(diffMs / 86400000);\n\n if (diffMins < 1) return \"Just now\";\n if (diffMins < 60) return `${diffMins}m ago`;\n if (diffHours < 24) return `${diffHours}h ago`;\n if (diffDays < 7) return `${diffDays}d ago`;\n return date.toLocaleDateString();\n };\n\n return (\n <div\n className={`group relative p-3 rounded-lg border transition-colors ${\n isActive\n ? \"bg-teal-50 dark:bg-teal-900/20 border-teal-200 dark:border-teal-800\"\n : \"bg-white dark:bg-zinc-800 border-zinc-200 dark:border-zinc-700 hover:border-zinc-300 dark:hover:border-zinc-600\"\n }`}\n >\n <div className=\"flex items-start justify-between gap-2\">\n <button onClick={onLoad} className=\"flex-1 text-left min-w-0\">\n {isEditing ? (\n <input\n type=\"text\"\n value={editName}\n onChange={(e) => setEditName(e.target.value)}\n onBlur={handleRename}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") handleRename();\n if (e.key === \"Escape\") {\n setEditName(workflow.name);\n setIsEditing(false);\n }\n }}\n className=\"w-full px-1 py-0.5 text-sm font-medium bg-white dark:bg-zinc-900 border border-teal-500 rounded focus:outline-none focus:ring-1 focus:ring-teal-500\"\n autoFocus\n onClick={(e) => e.stopPropagation()}\n />\n ) : (\n <span className=\"block text-sm font-medium text-zinc-900 dark:text-zinc-100 truncate\">\n {workflow.name}\n </span>\n )}\n <span className=\"block text-xs text-zinc-500 dark:text-zinc-400 mt-0.5\">\n {workflow.nodes.length} nodes · Updated {formatDate(workflow.updatedAt)}\n </span>\n </button>\n\n <div className=\"relative\">\n <button\n onClick={(e) => {\n e.stopPropagation();\n setShowMenu(!showMenu);\n }}\n className=\"p-1 text-zinc-400 hover:text-zinc-600 dark:hover:text-zinc-300 rounded opacity-0 group-hover:opacity-100 transition-opacity\"\n >\n <svg className=\"w-4 h-4\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path d=\"M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z\" />\n </svg>\n </button>\n\n {showMenu && (\n <>\n <div className=\"fixed inset-0 z-10\" onClick={() => setShowMenu(false)} />\n <div className=\"absolute right-0 top-full mt-1 w-36 bg-white dark:bg-zinc-800 rounded-lg shadow-lg border border-zinc-200 dark:border-zinc-700 py-1 z-20\">\n <button\n onClick={(e) => {\n e.stopPropagation();\n setIsEditing(true);\n setShowMenu(false);\n }}\n className=\"w-full px-3 py-1.5 text-left text-sm text-zinc-700 dark:text-zinc-300 hover:bg-zinc-100 dark:hover:bg-zinc-700\"\n >\n Rename\n </button>\n <button\n onClick={(e) => {\n e.stopPropagation();\n onDuplicate();\n setShowMenu(false);\n }}\n className=\"w-full px-3 py-1.5 text-left text-sm text-zinc-700 dark:text-zinc-300 hover:bg-zinc-100 dark:hover:bg-zinc-700\"\n >\n Duplicate\n </button>\n <button\n onClick={(e) => {\n e.stopPropagation();\n if (window.confirm(\"Delete this workflow?\")) {\n onDelete();\n }\n setShowMenu(false);\n }}\n className=\"w-full px-3 py-1.5 text-left text-sm text-red-600 dark:text-red-400 hover:bg-zinc-100 dark:hover:bg-zinc-700\"\n >\n Delete\n </button>\n </div>\n </>\n )}\n </div>\n </div>\n\n {isActive && <span className=\"absolute top-2 right-2 w-2 h-2 bg-teal-500 rounded-full\" />}\n </div>\n );\n}\n\nexport function WorkflowLibrary() {\n const showLibrary = useWorkflowStore((s) => s.showLibrary);\n const toggleLibrary = useWorkflowStore((s) => s.toggleLibrary);\n const savedWorkflows = useWorkflowStore((s) => s.savedWorkflows);\n const activeWorkflowId = useWorkflowStore((s) => s.activeWorkflowId);\n const loadWorkflow = useWorkflowStore((s) => s.loadWorkflow);\n const deleteWorkflow = useWorkflowStore((s) => s.deleteWorkflow);\n const renameWorkflow = useWorkflowStore((s) => s.renameWorkflow);\n const duplicateWorkflow = useWorkflowStore((s) => s.duplicateWorkflow);\n const newWorkflow = useWorkflowStore((s) => s.newWorkflow);\n\n if (!showLibrary) return null;\n\n // Sort by most recently updated\n const sortedWorkflows = [...savedWorkflows].sort((a, b) => b.updatedAt - a.updatedAt);\n\n return (\n <>\n {/* Backdrop */}\n <div className=\"fixed inset-0 bg-black/20 dark:bg-black/40 z-40\" onClick={toggleLibrary} />\n\n {/* Panel */}\n <div className=\"fixed left-0 top-0 bottom-0 w-80 bg-zinc-50 dark:bg-zinc-900 border-r border-zinc-200 dark:border-zinc-700 z-50 flex flex-col shadow-xl\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-zinc-200 dark:border-zinc-700\">\n <h2 className=\"text-lg font-semibold text-zinc-900 dark:text-zinc-100\">My Workflows</h2>\n <button\n onClick={toggleLibrary}\n className=\"p-1 text-zinc-500 hover:text-zinc-700 dark:hover:text-zinc-300 rounded\"\n >\n <svg className=\"w-5 h-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </button>\n </div>\n\n {/* New Workflow Button */}\n <div className=\"p-4 border-b border-zinc-200 dark:border-zinc-700\">\n <button\n onClick={() => {\n newWorkflow();\n toggleLibrary();\n window.dispatchEvent(new window.CustomEvent(\"new-workflow-created\"));\n }}\n className=\"w-full flex items-center justify-center gap-2 px-4 py-2 text-sm font-medium text-white bg-teal-600 rounded-lg hover:bg-teal-700 transition-colors\"\n >\n <svg className=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 4v16m8-8H4\"\n />\n </svg>\n New Workflow\n </button>\n </div>\n\n {/* Workflow List */}\n <div className=\"flex-1 overflow-y-auto p-4\">\n {sortedWorkflows.length === 0 ? (\n <div className=\"text-center py-8\">\n <div className=\"w-12 h-12 mx-auto mb-3 rounded-full bg-zinc-200 dark:bg-zinc-700 flex items-center justify-center\">\n <svg\n className=\"w-6 h-6 text-zinc-400\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10\"\n />\n </svg>\n </div>\n <p className=\"text-sm text-zinc-500 dark:text-zinc-400\">No saved workflows yet</p>\n <p className=\"text-xs text-zinc-400 dark:text-zinc-500 mt-1\">\n Build a workflow and save it to see it here\n </p>\n </div>\n ) : (\n <div className=\"space-y-2\">\n {sortedWorkflows.map((workflow) => (\n <WorkflowItem\n key={workflow.id}\n workflow={workflow}\n isActive={workflow.id === activeWorkflowId}\n onLoad={() => {\n loadWorkflow(workflow.id);\n toggleLibrary();\n }}\n onDelete={() => deleteWorkflow(workflow.id)}\n onRename={(name) => renameWorkflow(workflow.id, name)}\n onDuplicate={() => duplicateWorkflow(workflow.id)}\n />\n ))}\n </div>\n )}\n </div>\n\n {/* Footer */}\n <div className=\"px-4 py-3 border-t border-zinc-200 dark:border-zinc-700 text-xs text-zinc-500 dark:text-zinc-400\">\n {savedWorkflows.length} workflow{savedWorkflows.length !== 1 ? \"s\" : \"\"} saved locally\n </div>\n </div>\n </>\n );\n}\n","import { useState } from \"react\";\nimport { useSettingsStore } from \"../stores/settingsStore\";\n\n// Provider metadata\nconst CLOUD_PROVIDERS = [\n {\n id: \"openai\" as const,\n name: \"OpenAI\",\n description: \"GPT-4 Vision, GPT-4 Text, DALL-E 3\",\n placeholder: \"sk-...\",\n docsUrl: \"https://platform.openai.com/api-keys\",\n },\n {\n id: \"anthropic\" as const,\n name: \"Anthropic\",\n description: \"Claude Vision, Claude Text\",\n placeholder: \"sk-ant-...\",\n docsUrl: \"https://console.anthropic.com/settings/keys\",\n },\n {\n id: \"gemini\" as const,\n name: \"Google AI\",\n description: \"Gemini Vision, Gemini Text, Gemini Edit\",\n placeholder: \"AIza...\",\n docsUrl: \"https://aistudio.google.com/apikey\",\n },\n {\n id: \"grok\" as const,\n name: \"xAI (Grok)\",\n description: \"Grok Vision, Grok Text\",\n placeholder: \"xai-...\",\n docsUrl: \"https://console.x.ai/\",\n },\n {\n id: \"openrouter\" as const,\n name: \"OpenRouter\",\n description: \"Access multiple models with one API key\",\n placeholder: \"sk-or-...\",\n docsUrl: \"https://openrouter.ai/keys\",\n },\n];\n\nconst LOCAL_PROVIDERS = [\n {\n id: \"ollama\" as const,\n name: \"Ollama\",\n description: \"Local LLaVA Vision, Llama/Mistral Text\",\n defaultUrl: \"http://localhost:11434\",\n docsUrl: \"https://ollama.ai\",\n },\n {\n id: \"lmstudio\" as const,\n name: \"LM Studio\",\n description: \"Local models via OpenAI-compatible API\",\n defaultUrl: \"http://localhost:1234\",\n docsUrl: \"https://lmstudio.ai\",\n },\n];\n\nfunction CloudProviderRow({ provider }: { provider: (typeof CLOUD_PROVIDERS)[number] }) {\n const ai = useSettingsStore((s) => s.ai);\n const setAIProvider = useSettingsStore((s) => s.setAIProvider);\n\n const config = ai[provider.id];\n const isEnabled = config?.enabled ?? false;\n const apiKey = (config as { apiKey?: string })?.apiKey ?? \"\";\n\n const [localKey, setLocalKey] = useState(apiKey);\n const [showKey, setShowKey] = useState(false);\n\n const handleToggle = () => {\n setAIProvider(provider.id, {\n apiKey: localKey,\n enabled: !isEnabled,\n });\n };\n\n const handleKeyChange = (value: string) => {\n setLocalKey(value);\n setAIProvider(provider.id, {\n apiKey: value,\n enabled: isEnabled,\n });\n };\n\n return (\n <div className=\"flex items-start gap-4 p-4 border border-gray-200 dark:border-zinc-700 rounded-lg\">\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium text-gray-900 dark:text-white\">{provider.name}</span>\n <a\n href={provider.docsUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-xs text-teal-600 dark:text-teal-400 hover:underline\"\n >\n Get API key\n </a>\n </div>\n <p className=\"text-sm text-gray-500 dark:text-zinc-400 mt-0.5\">{provider.description}</p>\n <div className=\"mt-2 flex items-center gap-2\">\n <div className=\"relative flex-1\">\n <input\n type={showKey ? \"text\" : \"password\"}\n value={localKey}\n onChange={(e) => handleKeyChange(e.target.value)}\n placeholder={provider.placeholder}\n className=\"w-full px-3 py-1.5 text-sm border border-gray-300 dark:border-zinc-600 rounded bg-white dark:bg-zinc-800 text-gray-900 dark:text-white placeholder-gray-400 dark:placeholder-zinc-500\"\n />\n <button\n type=\"button\"\n onClick={() => setShowKey(!showKey)}\n className=\"absolute right-2 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 dark:hover:text-zinc-300\"\n >\n <svg className=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n {showKey ? (\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21\"\n />\n ) : (\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M15 12a3 3 0 11-6 0 3 3 0 016 0z M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z\"\n />\n )}\n </svg>\n </button>\n </div>\n </div>\n </div>\n <div className=\"flex items-center\">\n <button\n onClick={handleToggle}\n className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${\n isEnabled ? \"bg-teal-600\" : \"bg-gray-300 dark:bg-zinc-600\"\n }`}\n >\n <span\n className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${\n isEnabled ? \"translate-x-6\" : \"translate-x-1\"\n }`}\n />\n </button>\n </div>\n </div>\n );\n}\n\nfunction LocalProviderRow({ provider }: { provider: (typeof LOCAL_PROVIDERS)[number] }) {\n const ai = useSettingsStore((s) => s.ai);\n const setAIProvider = useSettingsStore((s) => s.setAIProvider);\n\n const config = ai[provider.id];\n const isEnabled = config?.enabled ?? false;\n const baseUrl = (config as { baseUrl?: string })?.baseUrl ?? provider.defaultUrl;\n\n const [localUrl, setLocalUrl] = useState(baseUrl);\n\n const handleToggle = () => {\n setAIProvider(provider.id, {\n baseUrl: localUrl,\n enabled: !isEnabled,\n });\n };\n\n const handleUrlChange = (value: string) => {\n setLocalUrl(value);\n setAIProvider(provider.id, {\n baseUrl: value,\n enabled: isEnabled,\n });\n };\n\n return (\n <div className=\"flex items-start gap-4 p-4 border border-gray-200 dark:border-zinc-700 rounded-lg\">\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium text-gray-900 dark:text-white\">{provider.name}</span>\n <a\n href={provider.docsUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-xs text-teal-600 dark:text-teal-400 hover:underline\"\n >\n Docs\n </a>\n <span className=\"text-xs bg-green-100 dark:bg-green-900/50 text-green-700 dark:text-green-400 px-1.5 py-0.5 rounded\">\n Local\n </span>\n </div>\n <p className=\"text-sm text-gray-500 dark:text-zinc-400 mt-0.5\">{provider.description}</p>\n <div className=\"mt-2\">\n <input\n type=\"text\"\n value={localUrl}\n onChange={(e) => handleUrlChange(e.target.value)}\n placeholder={provider.defaultUrl}\n className=\"w-full px-3 py-1.5 text-sm border border-gray-300 dark:border-zinc-600 rounded bg-white dark:bg-zinc-800 text-gray-900 dark:text-white placeholder-gray-400 dark:placeholder-zinc-500\"\n />\n </div>\n </div>\n <div className=\"flex items-center\">\n <button\n onClick={handleToggle}\n className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${\n isEnabled ? \"bg-teal-600\" : \"bg-gray-300 dark:bg-zinc-600\"\n }`}\n >\n <span\n className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${\n isEnabled ? \"translate-x-6\" : \"translate-x-1\"\n }`}\n />\n </button>\n </div>\n </div>\n );\n}\n\nexport function AISettings() {\n const showSettings = useSettingsStore((s) => s.showSettings);\n const closeSettings = useSettingsStore((s) => s.closeSettings);\n\n if (!showSettings) return null;\n\n return (\n <div className=\"fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50\">\n <div className=\"bg-white dark:bg-zinc-800 rounded-lg shadow-xl max-w-xl w-full mx-4 max-h-[85vh] flex flex-col\">\n <div className=\"flex items-center justify-between px-6 py-4 border-b border-gray-200 dark:border-zinc-700\">\n <div>\n <h2 className=\"text-lg font-semibold text-gray-900 dark:text-white\">\n AI Provider Settings\n </h2>\n <p className=\"text-sm text-gray-500 dark:text-zinc-400 mt-0.5\">\n Configure your AI providers for vision and text generation\n </p>\n </div>\n <button\n onClick={closeSettings}\n className=\"text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200\"\n >\n <svg className=\"h-6 w-6\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </button>\n </div>\n\n <div className=\"flex-1 overflow-y-auto p-6 space-y-6\">\n {/* Cloud Providers */}\n <section>\n <h3 className=\"text-sm font-medium text-gray-700 dark:text-zinc-300 mb-3\">\n Cloud Providers\n </h3>\n <div className=\"space-y-3\">\n {CLOUD_PROVIDERS.map((provider) => (\n <CloudProviderRow key={provider.id} provider={provider} />\n ))}\n </div>\n </section>\n\n {/* Local Providers */}\n <section>\n <h3 className=\"text-sm font-medium text-gray-700 dark:text-zinc-300 mb-3\">\n Local Providers\n </h3>\n <div className=\"space-y-3\">\n {LOCAL_PROVIDERS.map((provider) => (\n <LocalProviderRow key={provider.id} provider={provider} />\n ))}\n </div>\n </section>\n\n {/* Privacy Notice */}\n <div className=\"bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg p-4\">\n <div className=\"flex items-start gap-3\">\n <svg\n className=\"w-5 h-5 text-blue-600 dark:text-blue-400 mt-0.5\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z\"\n />\n </svg>\n <div>\n <p className=\"text-sm font-medium text-blue-900 dark:text-blue-300\">\n Your keys stay local\n </p>\n <p className=\"text-sm text-blue-700 dark:text-blue-400 mt-1\">\n API keys are stored in your browser only and sent directly to providers. They\n never pass through our servers.\n </p>\n </div>\n </div>\n </div>\n </div>\n\n <div className=\"flex justify-end px-6 py-4 border-t border-gray-200 dark:border-zinc-700\">\n <button\n onClick={closeSettings}\n className=\"px-4 py-2 text-sm font-medium text-white bg-teal-600 rounded-md hover:bg-teal-700\"\n >\n Done\n </button>\n </div>\n </div>\n </div>\n );\n}\n","import { useState, useRef, useEffect, useCallback } from \"react\";\nimport type {\n GenerateWorkflowMessage,\n GeneratedWorkflowData,\n GenerateStatusReason,\n GenerationPhase,\n GenerationSSEEvent,\n} from \"@teamflojo/floimg-studio-shared\";\nimport { getGenerateStatus } from \"../api/client\";\nimport { createSSEConnection, type SSEConnection } from \"../api/sse\";\n\n// Module-level connection reference for cancellation\n// (Not in component state because SSEConnection is not serializable)\nlet activeGenerationConnection: SSEConnection | null = null;\n\ninterface AIChatProps {\n isOpen: boolean;\n onClose: () => void;\n onApplyWorkflow: (workflow: GeneratedWorkflowData) => void;\n}\n\nexport function AIChat({ isOpen, onClose, onApplyWorkflow }: AIChatProps) {\n const [messages, setMessages] = useState<GenerateWorkflowMessage[]>([]);\n const [input, setInput] = useState(\"\");\n const [isLoading, setIsLoading] = useState(false);\n const [generationPhase, setGenerationPhase] = useState<GenerationPhase | null>(null);\n const [generationMessage, setGenerationMessage] = useState(\"\");\n const [error, setError] = useState<string | null>(null);\n const [isAvailable, setIsAvailable] = useState<boolean | null>(null);\n const [statusMessage, setStatusMessage] = useState(\"\");\n const [statusReason, setStatusReason] = useState<GenerateStatusReason | undefined>();\n const [isCloudDeployment, setIsCloudDeployment] = useState(false);\n const [supportUrl, setSupportUrl] = useState<string | undefined>();\n const messagesEndRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLTextAreaElement>(null);\n\n // Check if generation is available on mount\n useEffect(() => {\n if (isOpen && isAvailable === null) {\n getGenerateStatus()\n .then((status) => {\n setIsAvailable(status.available);\n setStatusMessage(status.message);\n setStatusReason(status.reason);\n setIsCloudDeployment(status.isCloudDeployment ?? false);\n setSupportUrl(status.supportUrl);\n })\n .catch(() => {\n setIsAvailable(false);\n setStatusMessage(\"Failed to check AI availability\");\n setStatusReason(\"service_unavailable\");\n });\n }\n }, [isOpen, isAvailable]);\n\n // Focus input when opened\n useEffect(() => {\n if (isOpen && inputRef.current) {\n inputRef.current.focus();\n }\n }, [isOpen]);\n\n // Scroll to bottom on new messages\n useEffect(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: \"smooth\" });\n }, [messages]);\n\n const handleSubmit = useCallback(() => {\n if (!input.trim() || isLoading) return;\n\n const userMessage: GenerateWorkflowMessage = {\n role: \"user\",\n content: input.trim(),\n timestamp: Date.now(),\n };\n\n setMessages((prev) => [...prev, userMessage]);\n setInput(\"\");\n setIsLoading(true);\n setError(null);\n setGenerationPhase(null);\n setGenerationMessage(\"\");\n\n let receivedWorkflow: GeneratedWorkflowData | undefined;\n\n activeGenerationConnection = createSSEConnection<GenerationSSEEvent>(\n \"/api/generate/workflow/stream\",\n { prompt: userMessage.content, history: messages },\n {\n onMessage: (event) => {\n if (event.type === \"generation.started\") {\n // Started - no visible change needed\n }\n\n if (event.type === \"generation.progress\") {\n setGenerationPhase(event.data.phase);\n setGenerationMessage(event.data.message);\n }\n\n if (event.type === \"generation.completed\") {\n receivedWorkflow = event.data;\n }\n\n if (event.type === \"generation.error\") {\n setError(event.data.error);\n }\n },\n onError: (err) => {\n activeGenerationConnection = null;\n setError(err.message || \"Failed to generate workflow\");\n setIsLoading(false);\n setGenerationPhase(null);\n },\n onClose: () => {\n activeGenerationConnection = null;\n // Stream completed - add the assistant message\n const assistantMessage: GenerateWorkflowMessage = {\n role: \"assistant\",\n content: receivedWorkflow\n ? \"I've created a workflow based on your description. Click 'Apply to Canvas' to use it.\"\n : \"I couldn't generate a workflow. Please try a different description.\",\n workflow: receivedWorkflow,\n timestamp: Date.now(),\n };\n\n setMessages((prev) => [...prev, assistantMessage]);\n setIsLoading(false);\n setGenerationPhase(null);\n setGenerationMessage(\"\");\n },\n }\n );\n }, [input, isLoading, messages]);\n\n const handleCancelGeneration = useCallback(() => {\n if (activeGenerationConnection) {\n activeGenerationConnection.abort();\n activeGenerationConnection = null;\n }\n setIsLoading(false);\n setGenerationPhase(null);\n setGenerationMessage(\"\");\n }, []);\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n handleSubmit();\n }\n };\n\n const handleApply = (workflow: GeneratedWorkflowData) => {\n onApplyWorkflow(workflow);\n onClose();\n };\n\n const handleNewChat = () => {\n setMessages([]);\n setError(null);\n };\n\n if (!isOpen) return null;\n\n return (\n <div className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50\">\n <div className=\"bg-white dark:bg-zinc-800 rounded-lg shadow-xl w-full max-w-2xl mx-4 h-[80vh] flex flex-col\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-gray-200 dark:border-zinc-700\">\n <div className=\"flex items-center gap-3\">\n <div className=\"flex items-center gap-2\">\n <svg\n className=\"h-5 w-5 text-teal-600\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z\"\n />\n </svg>\n <h3 className=\"text-lg font-semibold text-gray-900 dark:text-white\">\n AI Workflow Generator\n </h3>\n </div>\n <span className=\"text-xs bg-teal-100 dark:bg-teal-900 text-teal-700 dark:text-teal-300 px-2 py-0.5 rounded\">\n Gemini 3 Pro\n </span>\n </div>\n <div className=\"flex items-center gap-2\">\n {messages.length > 0 && (\n <button\n onClick={handleNewChat}\n className=\"p-2 text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200 hover:bg-gray-100 dark:hover:bg-zinc-700 rounded\"\n title=\"New Chat\"\n >\n <svg className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 4v16m8-8H4\"\n />\n </svg>\n </button>\n )}\n <button\n onClick={onClose}\n className=\"p-2 text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200 hover:bg-gray-100 dark:hover:bg-zinc-700 rounded\"\n >\n <svg className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </button>\n </div>\n </div>\n\n {/* Messages */}\n <div className=\"flex-1 overflow-auto p-4 space-y-4\">\n {isAvailable === false && (\n <div className=\"bg-amber-50 dark:bg-amber-900/30 border border-amber-200 dark:border-amber-800 rounded-lg p-4\">\n <div className=\"flex items-start gap-3\">\n {/* Icon varies by reason */}\n {statusReason === \"tier_limit\" ? (\n <svg\n className=\"h-5 w-5 text-amber-600 dark:text-amber-400 mt-0.5\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z\"\n />\n </svg>\n ) : (\n <svg\n className=\"h-5 w-5 text-amber-600 dark:text-amber-400 mt-0.5\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\n />\n </svg>\n )}\n <div>\n <p className=\"font-medium text-amber-800 dark:text-amber-200\">\n {statusReason === \"tier_limit\"\n ? \"AI Workflow Generation Not Available\"\n : \"AI Generation Not Available\"}\n </p>\n <p className=\"text-sm text-amber-700 dark:text-amber-300 mt-1\">{statusMessage}</p>\n\n {/* Context-aware actions */}\n <div className=\"flex flex-col sm:flex-row gap-2 mt-3\">\n {statusReason === \"tier_limit\" && (\n <a\n href=\"/pricing\"\n className=\"text-sm font-medium text-teal-600 hover:text-teal-700 dark:text-teal-400 dark:hover:text-teal-300\"\n >\n View Plans\n </a>\n )}\n {statusReason === \"service_unavailable\" && supportUrl && (\n <a\n href={supportUrl}\n className=\"text-sm font-medium text-amber-700 hover:text-amber-800 dark:text-amber-400 dark:hover:text-amber-300\"\n >\n Contact Support\n </a>\n )}\n {statusReason === \"not_configured\" && !isCloudDeployment && (\n <a\n href=\"https://floimg.com/docs/studio/ai-workflows\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-sm font-medium text-teal-600 hover:text-teal-700 dark:text-teal-400 dark:hover:text-teal-300\"\n >\n View Setup Guide\n </a>\n )}\n </div>\n </div>\n </div>\n </div>\n )}\n\n {messages.length === 0 && isAvailable !== false && (\n <div className=\"text-center py-8\">\n <div className=\"inline-flex items-center justify-center w-16 h-16 bg-teal-100 dark:bg-teal-900/50 rounded-full mb-4\">\n <svg\n className=\"h-8 w-8 text-teal-600 dark:text-teal-400\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z\"\n />\n </svg>\n </div>\n <h4 className=\"text-lg font-medium text-gray-900 dark:text-white mb-2\">\n Describe your workflow\n </h4>\n <p className=\"text-sm text-gray-500 dark:text-zinc-400 max-w-md mx-auto\">\n Tell me what you want to create and I'll generate a workflow for you. For\n example:\n </p>\n <div className=\"mt-4 space-y-2\">\n {[\n \"Generate an image of a sunset and resize it to 800x600\",\n \"Use Gemini text to generate 3 creative image prompts about space exploration, then generate images from each prompt\",\n \"Generate an image with Gemini, then use it as a reference to create a variation with different lighting\",\n \"Create a product mockup: generate a minimalist logo, then composite it onto a t-shirt image\",\n \"Build an AI art pipeline: generate a base image, apply artistic style transfer, then upscale to 4K\",\n ].map((example, i) => (\n <button\n key={i}\n onClick={() => setInput(example)}\n className=\"block w-full text-left text-sm px-4 py-2 bg-gray-100 dark:bg-zinc-700 hover:bg-gray-200 dark:hover:bg-zinc-600 rounded-lg text-gray-700 dark:text-zinc-300 transition-colors\"\n >\n "{example}"\n </button>\n ))}\n </div>\n </div>\n )}\n\n {messages.map((msg, idx) => (\n <div\n key={idx}\n className={`flex ${msg.role === \"user\" ? \"justify-end\" : \"justify-start\"}`}\n >\n <div\n className={`max-w-[80%] rounded-lg px-4 py-3 ${\n msg.role === \"user\"\n ? \"bg-teal-600 text-white\"\n : \"bg-gray-100 dark:bg-zinc-700 text-gray-900 dark:text-white\"\n }`}\n >\n <p className=\"text-sm whitespace-pre-wrap\">{msg.content}</p>\n\n {/* Workflow preview for assistant messages */}\n {msg.role === \"assistant\" && msg.workflow && (\n <div className=\"mt-3 pt-3 border-t border-gray-200 dark:border-zinc-600\">\n <div className=\"flex items-center justify-between mb-2\">\n <span className=\"text-xs font-medium text-gray-500 dark:text-zinc-400\">\n Generated Workflow\n </span>\n <button\n onClick={() => handleApply(msg.workflow!)}\n className=\"text-xs px-3 py-1 bg-teal-600 hover:bg-teal-700 text-white rounded transition-colors\"\n >\n Apply to Canvas\n </button>\n </div>\n <div className=\"bg-white dark:bg-zinc-800 rounded p-2 text-xs\">\n <div className=\"space-y-1\">\n {msg.workflow.nodes.map((node, nodeIdx) => (\n <div\n key={nodeIdx}\n className=\"flex items-center gap-2 text-gray-600 dark:text-zinc-300\"\n >\n <span className=\"font-mono bg-gray-100 dark:bg-zinc-700 px-1.5 py-0.5 rounded\">\n {node.nodeType.split(\":\").pop()}\n </span>\n {node.label && <span className=\"text-gray-400\">({node.label})</span>}\n </div>\n ))}\n {msg.workflow.edges.length > 0 && (\n <div className=\"text-gray-400 dark:text-zinc-500 pt-1\">\n {msg.workflow.edges.length} connection\n {msg.workflow.edges.length !== 1 ? \"s\" : \"\"}\n </div>\n )}\n </div>\n </div>\n </div>\n )}\n </div>\n </div>\n ))}\n\n {isLoading && (\n <div className=\"flex justify-start\">\n <div className=\"bg-gray-100 dark:bg-zinc-700 rounded-lg px-4 py-3\">\n <div className=\"flex items-center gap-3\">\n {/* Phase indicator */}\n <div className=\"flex items-center gap-2\">\n {generationPhase === \"analyzing\" && (\n <svg\n className=\"h-4 w-4 text-teal-500 animate-pulse\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\"\n />\n </svg>\n )}\n {generationPhase === \"selecting_nodes\" && (\n <svg\n className=\"h-4 w-4 text-teal-500 animate-pulse\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n 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 />\n </svg>\n )}\n {generationPhase === \"generating\" && (\n <svg\n className=\"h-4 w-4 text-teal-500 animate-spin\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n 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 />\n </svg>\n )}\n {generationPhase === \"validating\" && (\n <svg\n className=\"h-4 w-4 text-teal-500 animate-pulse\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z\"\n />\n </svg>\n )}\n {!generationPhase && (\n <div className=\"flex space-x-1\">\n <div className=\"w-2 h-2 bg-teal-400 rounded-full animate-bounce\" />\n <div\n className=\"w-2 h-2 bg-teal-400 rounded-full animate-bounce\"\n style={{ animationDelay: \"0.1s\" }}\n />\n <div\n className=\"w-2 h-2 bg-teal-400 rounded-full animate-bounce\"\n style={{ animationDelay: \"0.2s\" }}\n />\n </div>\n )}\n </div>\n <span className=\"text-sm text-gray-600 dark:text-zinc-300\">\n {generationMessage || \"Connecting...\"}\n </span>\n {/* Cancel button */}\n <button\n onClick={handleCancelGeneration}\n className=\"ml-2 px-2 py-1 text-xs font-medium text-red-600 dark:text-red-400 hover:bg-red-50 dark:hover:bg-red-900/30 rounded transition-colors\"\n title=\"Cancel generation\"\n >\n Cancel\n </button>\n </div>\n {/* Progress steps */}\n {generationPhase && (\n <div className=\"flex items-center gap-1 mt-2\">\n <div\n className={`h-1 w-8 rounded-full ${generationPhase === \"analyzing\" || generationPhase === \"selecting_nodes\" || generationPhase === \"generating\" || generationPhase === \"validating\" ? \"bg-teal-500\" : \"bg-gray-300 dark:bg-zinc-600\"}`}\n />\n <div\n className={`h-1 w-8 rounded-full ${generationPhase === \"selecting_nodes\" || generationPhase === \"generating\" || generationPhase === \"validating\" ? \"bg-teal-500\" : \"bg-gray-300 dark:bg-zinc-600\"}`}\n />\n <div\n className={`h-1 w-8 rounded-full ${generationPhase === \"generating\" || generationPhase === \"validating\" ? \"bg-teal-500\" : \"bg-gray-300 dark:bg-zinc-600\"}`}\n />\n <div\n className={`h-1 w-8 rounded-full ${generationPhase === \"validating\" ? \"bg-teal-500\" : \"bg-gray-300 dark:bg-zinc-600\"}`}\n />\n </div>\n )}\n </div>\n </div>\n )}\n\n {error && (\n <div className=\"bg-red-50 dark:bg-red-900/30 border border-red-200 dark:border-red-800 rounded-lg p-3\">\n <p className=\"text-sm text-red-700 dark:text-red-300\">{error}</p>\n </div>\n )}\n\n <div ref={messagesEndRef} />\n </div>\n\n {/* Input */}\n <div className=\"border-t border-gray-200 dark:border-zinc-700 p-4\">\n <div className=\"flex gap-2\">\n <textarea\n ref={inputRef}\n value={input}\n onChange={(e) => setInput(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={\n isAvailable === false\n ? \"AI generation not available\"\n : \"Describe what workflow you want to create...\"\n }\n disabled={isLoading || isAvailable === false}\n rows={2}\n className=\"flex-1 resize-none rounded-lg border border-gray-300 dark:border-zinc-600 bg-white dark:bg-zinc-900 px-4 py-2 text-sm text-gray-900 dark:text-white placeholder-gray-400 dark:placeholder-zinc-500 focus:border-teal-500 focus:outline-none focus:ring-1 focus:ring-teal-500 disabled:opacity-50 disabled:cursor-not-allowed\"\n />\n <button\n onClick={handleSubmit}\n disabled={!input.trim() || isLoading || isAvailable === false}\n className=\"self-end px-4 py-2 bg-teal-600 hover:bg-teal-700 disabled:opacity-50 disabled:cursor-not-allowed text-white rounded-lg transition-colors\"\n >\n <svg className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 19l9 2-9-18-9 18 9-2zm0 0v-8\"\n />\n </svg>\n </button>\n </div>\n <p className=\"text-xs text-gray-400 dark:text-zinc-500 mt-2\">\n Press Enter to send, Shift+Enter for new line\n </p>\n </div>\n </div>\n </div>\n );\n}\n","import { useState, useCallback } from \"react\";\n\n// Size/depth limits to prevent browser freeze on large outputs\nconst MAX_JSON_DEPTH = 20;\nconst MAX_ARRAY_ITEMS = 500;\nconst LARGE_OUTPUT_THRESHOLD = 100_000; // 100KB\n\ninterface DataOutput {\n dataType: \"text\" | \"json\";\n content: string;\n parsed?: Record<string, unknown>;\n}\n\ninterface OutputInspectorProps {\n isOpen: boolean;\n onClose: () => void;\n nodeId: string;\n nodeLabel: string;\n output: DataOutput;\n}\n\nexport function OutputInspector({ isOpen, onClose, nodeLabel, output }: OutputInspectorProps) {\n const [viewMode, setViewMode] = useState<\"formatted\" | \"raw\">(\"formatted\");\n const [copied, setCopied] = useState(false);\n\n const handleCopy = useCallback(() => {\n const textToCopy =\n viewMode === \"formatted\" && output.parsed\n ? JSON.stringify(output.parsed, null, 2)\n : output.content;\n\n navigator.clipboard.writeText(textToCopy).then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n });\n }, [viewMode, output]);\n\n if (!isOpen) return null;\n\n const hasFormattedView = output.dataType === \"json\" && output.parsed;\n\n return (\n <div className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50\">\n <div className=\"bg-white dark:bg-zinc-800 rounded-lg shadow-xl w-full max-w-3xl mx-4 max-h-[85vh] flex flex-col\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-gray-200 dark:border-zinc-700\">\n <div className=\"flex items-center gap-3\">\n <svg\n className=\"h-5 w-5 text-pink-500\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\"\n />\n </svg>\n <div>\n <h3 className=\"text-lg font-semibold text-gray-900 dark:text-white\">\n {nodeLabel} Output\n </h3>\n <span className=\"text-xs text-gray-500 dark:text-zinc-400\">\n {output.dataType === \"json\" ? \"Structured JSON\" : \"Text\"}\n </span>\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n {/* View mode toggle */}\n {hasFormattedView && (\n <div className=\"flex bg-gray-100 dark:bg-zinc-700 rounded-lg p-0.5\">\n <button\n onClick={() => setViewMode(\"formatted\")}\n className={`px-3 py-1 text-sm rounded-md transition-colors ${\n viewMode === \"formatted\"\n ? \"bg-white dark:bg-zinc-600 text-gray-900 dark:text-white shadow-sm\"\n : \"text-gray-600 dark:text-zinc-400 hover:text-gray-900 dark:hover:text-white\"\n }`}\n >\n Formatted\n </button>\n <button\n onClick={() => setViewMode(\"raw\")}\n className={`px-3 py-1 text-sm rounded-md transition-colors ${\n viewMode === \"raw\"\n ? \"bg-white dark:bg-zinc-600 text-gray-900 dark:text-white shadow-sm\"\n : \"text-gray-600 dark:text-zinc-400 hover:text-gray-900 dark:hover:text-white\"\n }`}\n >\n Raw\n </button>\n </div>\n )}\n {/* Close button */}\n <button\n onClick={onClose}\n className=\"p-2 text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200 hover:bg-gray-100 dark:hover:bg-zinc-700 rounded\"\n >\n <svg className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </button>\n </div>\n </div>\n\n {/* Large output warning */}\n {output.content.length > LARGE_OUTPUT_THRESHOLD && (\n <div className=\"px-4 py-2 bg-amber-50 dark:bg-amber-900/20 border-b border-amber-200 dark:border-amber-800 flex items-center gap-2\">\n <svg\n className=\"h-4 w-4 text-amber-600 dark:text-amber-400\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\n />\n </svg>\n <span className=\"text-sm text-amber-700 dark:text-amber-300\">\n Large output ({Math.round(output.content.length / 1024)}KB) - rendering may be slow\n </span>\n </div>\n )}\n\n {/* Content */}\n <div className=\"flex-1 overflow-auto p-4\">\n {viewMode === \"formatted\" && hasFormattedView ? (\n <JsonTree data={output.parsed!} />\n ) : (\n <pre className=\"whitespace-pre-wrap font-mono text-sm text-gray-800 dark:text-zinc-200 bg-gray-50 dark:bg-zinc-900 rounded-lg p-4 overflow-auto\">\n {output.content}\n </pre>\n )}\n </div>\n\n {/* Footer */}\n <div className=\"flex items-center justify-between px-4 py-3 border-t border-gray-200 dark:border-zinc-700\">\n <span className=\"text-xs text-gray-500 dark:text-zinc-400\">\n {output.content.length.toLocaleString()} characters\n </span>\n <button\n onClick={handleCopy}\n className=\"flex items-center gap-2 px-3 py-1.5 text-sm font-medium text-teal-600 dark:text-teal-400 hover:bg-teal-50 dark:hover:bg-teal-900/30 rounded-lg transition-colors\"\n >\n {copied ? (\n <>\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M5 13l4 4L19 7\"\n />\n </svg>\n Copied!\n </>\n ) : (\n <>\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"\n />\n </svg>\n Copy to Clipboard\n </>\n )}\n </button>\n </div>\n </div>\n </div>\n );\n}\n\n// Simple JSON tree viewer component with depth/size limits\nfunction JsonTree({ data }: { data: Record<string, unknown> }) {\n return (\n <div className=\"font-mono text-sm\">\n <JsonNode value={data} depth={0} maxDepth={MAX_JSON_DEPTH} />\n </div>\n );\n}\n\ninterface JsonNodeProps {\n value: unknown;\n depth: number;\n keyName?: string;\n maxDepth: number;\n}\n\nfunction JsonNode({ value, depth, keyName, maxDepth }: JsonNodeProps) {\n const indent = depth * 16;\n\n // Check depth limit\n if (depth >= maxDepth) {\n return (\n <div style={{ marginLeft: indent }} className=\"py-0.5\">\n {keyName && <span className=\"text-pink-600 dark:text-pink-400\">"{keyName}"</span>}\n {keyName && <span className=\"text-gray-600 dark:text-zinc-400\">: </span>}\n <span className=\"text-zinc-500 italic\">[max depth reached]</span>\n </div>\n );\n }\n\n if (value === null) {\n return (\n <div style={{ marginLeft: indent }} className=\"py-0.5\">\n {keyName && <span className=\"text-pink-600 dark:text-pink-400\">"{keyName}"</span>}\n {keyName && <span className=\"text-gray-600 dark:text-zinc-400\">: </span>}\n <span className=\"text-gray-500 dark:text-zinc-500\">null</span>\n </div>\n );\n }\n\n if (typeof value === \"boolean\") {\n return (\n <div style={{ marginLeft: indent }} className=\"py-0.5\">\n {keyName && <span className=\"text-pink-600 dark:text-pink-400\">"{keyName}"</span>}\n {keyName && <span className=\"text-gray-600 dark:text-zinc-400\">: </span>}\n <span className=\"text-blue-600 dark:text-blue-400\">{value.toString()}</span>\n </div>\n );\n }\n\n if (typeof value === \"number\") {\n return (\n <div style={{ marginLeft: indent }} className=\"py-0.5\">\n {keyName && <span className=\"text-pink-600 dark:text-pink-400\">"{keyName}"</span>}\n {keyName && <span className=\"text-gray-600 dark:text-zinc-400\">: </span>}\n <span className=\"text-green-600 dark:text-green-400\">{value}</span>\n </div>\n );\n }\n\n if (typeof value === \"string\") {\n // Truncate long strings in the tree view\n const displayValue = value.length > 100 ? value.slice(0, 100) + \"...\" : value;\n return (\n <div style={{ marginLeft: indent }} className=\"py-0.5\">\n {keyName && <span className=\"text-pink-600 dark:text-pink-400\">"{keyName}"</span>}\n {keyName && <span className=\"text-gray-600 dark:text-zinc-400\">: </span>}\n <span className=\"text-amber-600 dark:text-amber-400\">"{displayValue}"</span>\n </div>\n );\n }\n\n if (Array.isArray(value)) {\n const itemsToRender = value.slice(0, MAX_ARRAY_ITEMS);\n const hiddenCount = value.length - itemsToRender.length;\n\n return (\n <div style={{ marginLeft: indent }}>\n {keyName && (\n <div className=\"py-0.5\">\n <span className=\"text-pink-600 dark:text-pink-400\">"{keyName}"</span>\n <span className=\"text-gray-600 dark:text-zinc-400\">: </span>\n <span className=\"text-gray-500 dark:text-zinc-500\">[{value.length} items]</span>\n </div>\n )}\n {!keyName && <span className=\"text-gray-500 dark:text-zinc-500 py-0.5 block\">[</span>}\n {itemsToRender.map((item, index) => (\n <JsonNode key={index} value={item} depth={depth + 1} maxDepth={maxDepth} />\n ))}\n {hiddenCount > 0 && (\n <div style={{ marginLeft: (depth + 1) * 16 }} className=\"py-0.5 text-zinc-500 italic\">\n ...and {hiddenCount} more items\n </div>\n )}\n {!keyName && <span className=\"text-gray-500 dark:text-zinc-500 py-0.5 block\">]</span>}\n </div>\n );\n }\n\n if (typeof value === \"object\") {\n const entries = Object.entries(value);\n return (\n <div style={{ marginLeft: indent }}>\n {keyName && (\n <div className=\"py-0.5\">\n <span className=\"text-pink-600 dark:text-pink-400\">"{keyName}"</span>\n <span className=\"text-gray-600 dark:text-zinc-400\">: </span>\n <span className=\"text-gray-500 dark:text-zinc-500\">{\"{\"}</span>\n </div>\n )}\n {!keyName && <span className=\"text-gray-500 dark:text-zinc-500 py-0.5 block\">{\"{\"}</span>}\n {entries.map(([key, val]) => (\n <JsonNode key={key} value={val} depth={depth + 1} keyName={key} maxDepth={maxDepth} />\n ))}\n <div style={{ marginLeft: keyName ? 0 : indent }} className=\"py-0.5\">\n <span className=\"text-gray-500 dark:text-zinc-500\">{\"}\"}</span>\n </div>\n </div>\n );\n }\n\n return null;\n}\n","import { useState, useCallback, useEffect, DragEvent } from \"react\";\nimport { ReactFlowProvider, useReactFlow } from \"reactflow\";\nimport { WorkflowEditor } from \"./editor/WorkflowEditor\";\nimport { NodePalette } from \"./components/NodePalette\";\nimport { NodeInspector } from \"./components/NodeInspector\";\nimport { Toolbar } from \"./components/Toolbar\";\nimport { Gallery } from \"./components/Gallery\";\nimport { TemplateGallery } from \"./components/TemplateGallery\";\nimport { WorkflowLibrary } from \"./components/WorkflowLibrary\";\nimport { AISettings } from \"./components/AISettings\";\nimport { AIChat } from \"./components/AIChat\";\nimport { OutputInspector } from \"./components/OutputInspector\";\nimport { useWorkflowStore } from \"./stores/workflowStore\";\nimport { resolveTemplate } from \"@teamflojo/floimg-templates\";\nimport type { NodeDefinition, GeneratedWorkflowData } from \"@teamflojo/floimg-studio-shared\";\n\n// EditorDropZone - handles node drops with correct coordinate conversion\n// Must be inside ReactFlowProvider to access useReactFlow hook\nfunction EditorDropZone() {\n const { screenToFlowPosition } = useReactFlow();\n const addNode = useWorkflowStore((s) => s.addNode);\n\n const handleDrop = useCallback(\n (event: DragEvent<HTMLDivElement>) => {\n event.preventDefault();\n\n const data = event.dataTransfer.getData(\"application/json\");\n if (!data) return;\n\n try {\n const definition: NodeDefinition = JSON.parse(data);\n\n // Use screenToFlowPosition to correctly convert screen coordinates\n // to flow coordinates, accounting for zoom and pan\n const position = screenToFlowPosition({\n x: event.clientX,\n y: event.clientY,\n });\n\n addNode(definition, position);\n } catch (e) {\n console.error(\"Failed to parse dropped node:\", e);\n }\n },\n [addNode, screenToFlowPosition]\n );\n\n const handleDragOver = useCallback((event: DragEvent<HTMLDivElement>) => {\n event.preventDefault();\n event.dataTransfer.dropEffect = \"move\";\n }, []);\n\n return (\n <div className=\"flex-1\" onDrop={handleDrop} onDragOver={handleDragOver}>\n <WorkflowEditor />\n </div>\n );\n}\n\ntype TabType = \"editor\" | \"gallery\" | \"templates\";\n\nfunction App() {\n const [activeTab, setActiveTab] = useState<TabType>(\"editor\");\n const [showAIChat, setShowAIChat] = useState(false);\n const loadTemplate = useWorkflowStore((s) => s.loadTemplate);\n const loadGeneratedWorkflow = useWorkflowStore((s) => s.loadGeneratedWorkflow);\n\n // Output inspector state\n const inspectedNodeId = useWorkflowStore((s) => s.inspectedNodeId);\n const executionDataOutputs = useWorkflowStore((s) => s.execution.dataOutputs);\n const closeOutputInspector = useWorkflowStore((s) => s.closeOutputInspector);\n const nodes = useWorkflowStore((s) => s.nodes);\n\n // Get inspected node info\n const inspectedNode = inspectedNodeId ? nodes.find((n) => n.id === inspectedNodeId) : null;\n const inspectedOutput = inspectedNodeId ? executionDataOutputs[inspectedNodeId] : null;\n\n // Handle ?template=<id> URL parameter\n useEffect(() => {\n const params = new URLSearchParams(window.location.search);\n const templateId = params.get(\"template\");\n\n if (templateId) {\n // resolveTemplate handles both canonical IDs and legacy IDs\n const template = resolveTemplate(templateId);\n if (template) {\n loadTemplate(template);\n // Clean up URL without reload\n window.history.replaceState({}, \"\", window.location.pathname);\n }\n }\n }, [loadTemplate]);\n\n // Listen for workflow-loaded event (from Gallery)\n useEffect(() => {\n const handleWorkflowLoaded = () => {\n setActiveTab(\"editor\");\n };\n window.addEventListener(\"workflow-loaded\", handleWorkflowLoaded);\n return () => {\n window.removeEventListener(\"workflow-loaded\", handleWorkflowLoaded);\n };\n }, []);\n\n // Handler for template selection (from TemplateGallery)\n const handleTemplateSelect = useCallback(\n (templateId: string) => {\n const template = resolveTemplate(templateId);\n if (template) {\n loadTemplate(template);\n setActiveTab(\"editor\");\n }\n },\n [loadTemplate]\n );\n\n // Handler for AI-generated workflow\n const handleApplyWorkflow = useCallback(\n (workflow: GeneratedWorkflowData) => {\n loadGeneratedWorkflow(workflow);\n setActiveTab(\"editor\");\n },\n [loadGeneratedWorkflow]\n );\n\n return (\n <ReactFlowProvider>\n {/* AI Settings Modal */}\n <AISettings />\n\n {/* AI Chat Modal */}\n <AIChat\n isOpen={showAIChat}\n onClose={() => setShowAIChat(false)}\n onApplyWorkflow={handleApplyWorkflow}\n />\n\n {/* Output Inspector Modal */}\n {inspectedNode && inspectedOutput && (\n <OutputInspector\n isOpen={true}\n onClose={closeOutputInspector}\n nodeId={inspectedNodeId!}\n nodeLabel={\n (inspectedNode.data as { providerLabel?: string }).providerLabel ||\n inspectedNode.type ||\n \"Node\"\n }\n output={inspectedOutput}\n />\n )}\n\n {/* Workflow Library slide-out panel */}\n <WorkflowLibrary />\n\n <div className=\"h-screen flex flex-col bg-gray-100 dark:bg-zinc-900\">\n <Toolbar />\n\n {/* Tab navigation */}\n <div className=\"bg-white dark:bg-zinc-800 border-b border-gray-200 dark:border-zinc-700\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex\">\n <button\n onClick={() => setActiveTab(\"editor\")}\n className={`px-6 py-3 text-sm font-medium border-b-2 transition-colors ${\n activeTab === \"editor\"\n ? \"border-teal-500 text-teal-600 dark:text-teal-400\"\n : \"border-transparent text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200\"\n }`}\n >\n Editor\n </button>\n <button\n onClick={() => setActiveTab(\"gallery\")}\n className={`px-6 py-3 text-sm font-medium border-b-2 transition-colors ${\n activeTab === \"gallery\"\n ? \"border-teal-500 text-teal-600 dark:text-teal-400\"\n : \"border-transparent text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200\"\n }`}\n >\n Images\n </button>\n <button\n onClick={() => setActiveTab(\"templates\")}\n className={`px-6 py-3 text-sm font-medium border-b-2 transition-colors ${\n activeTab === \"templates\"\n ? \"border-teal-500 text-teal-600 dark:text-teal-400\"\n : \"border-transparent text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200\"\n }`}\n >\n Templates\n </button>\n </div>\n\n {/* AI Generate button */}\n <button\n onClick={() => setShowAIChat(true)}\n className=\"mr-4 px-4 py-1.5 text-sm font-medium text-white bg-gradient-to-r from-teal-500 to-cyan-500 hover:from-teal-600 hover:to-cyan-600 rounded-full flex items-center gap-2 transition-all shadow-sm hover:shadow\"\n >\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z\"\n />\n </svg>\n AI Generate\n </button>\n </div>\n </div>\n\n {/* Main content */}\n <div className=\"flex-1 flex overflow-hidden\">\n {activeTab === \"editor\" && (\n <>\n <NodePalette />\n <EditorDropZone />\n <NodeInspector />\n </>\n )}\n {activeTab === \"gallery\" && (\n <div className=\"flex-1 overflow-auto\">\n <Gallery />\n </div>\n )}\n {activeTab === \"templates\" && (\n <div className=\"flex-1 overflow-auto\">\n <TemplateGallery onSelect={handleTemplateSelect} />\n </div>\n )}\n </div>\n </div>\n </ReactFlowProvider>\n );\n}\n\nexport default App;\n"],"names":["createJSONStorage","getStorage","options","storage","name","_a","parse","str2","str","newValue","toThenable","fn","input","result","onFulfilled","_onRejected","e","_onFulfilled","onRejected","persistImpl","config","baseOptions","set","get","api","state","persistedState","currentState","hasHydrated","hydrationListeners","finishHydrationListeners","args","setItem","savedSetState","replace","configResult","stateFromStorage","hydrate","_b","cb","_a2","postRehydrationCallback","deserializedStorageValue","migration","migrationResult","migrated","migratedState","newOptions","persist","API_BASE","fetchJson","url","response","error","getGenerators","getTransforms","getTextProviders","getVisionProviders","exportYaml","nodes","edges","listImages","getImageUrl","id","getImageWorkflow","uploadImage","file","formData","listUploads","deleteUpload","getUploadBlobUrl","importYaml","yaml","validateYaml","getGenerateStatus","createSSEConnection","body","handlers","controller","errorBody","reader","decoder","buffer","done","value","processBuffer","messages","message","processSSEMessage","lines","data","line","parsed","DEFAULT_OLLAMA_URL","DEFAULT_LMSTUDIO_URL","useSettingsStore","create","provider","newAI","ai","_c","_d","_e","_f","_g","activeExecutionConnection","nodeIdCounter","generateNodeId","generateWorkflowId","timestamp","random","useWorkflowStore","nodeId","template","idMap","studioNode","newId","studioEdge","newSource","newTarget","generators","transforms","textProviders","visionProviders","definition","position","getDefaultParams","props","newNode","node","nodeToDuplicate","n","connection","handleSuffix","newEdge","studioNodes","studioEdges","aiProviders","initialNodeStatus","resolve","reject","event","step","newNodeStatus","newPreviews","newDataOutputs","finalNodeStatus","errorNodeStatus","activeWorkflowId","activeWorkflowName","savedWorkflows","currentTemplateId","now","updated","wf","newWorkflow","workflow","filtered","duplicate","GRID_SPACING_X","GRID_SPACING_Y","NODES_PER_ROW","genNode","index","parts","nodeType","row","providerName","jsonSchema","outputSchema","key","prop","genEdge","params","field","getExecutionClass","nodeStatus","PreviewToggle","color","previewVisible","s","togglePreview","jsx","GeneratorNode","memo","selected","preview","borderClass","isAI","acceptsReferences","jsxs","Handle","Position","TransformNode","SaveNode","InputNode","updateNodeData","fileInputRef","useRef","handleFileSelect","useCallback","handleDrop","handleDragOver","handleInputChange","previewUrl","VisionNode","dataOutput","openOutputInspector","outputProperties","hasMultiOutput","Fragment","TextNode","nodeTypes","defaultEdgeOptions","MarkerType","WorkflowEditor","setNodes","setEdges","addEdge","setSelectedNode","memoizedNodeTypes","useMemo","isValidConnection","source","target","targetHandle","sourceNode","targetNode","onNodesChange","changes","applyNodeChanges","onEdgesChange","applyEdgeChanges","onConnect","edgesToRemove","existingHandle","newHandle","removeIds","onNodeClick","_event","onPaneClick","ReactFlow","Background","Controls","MiniMap","UploadGallery","onSelect","uploads","setUploads","useState","loading","setLoading","setError","fetchUploads","err","useEffect","handleDelete","prev","u","formatSize","bytes","upload","NodePalette","setGenerators","setTransforms","setTextProviders","setVisionProviders","addNode","showUploads","setShowUploads","fetchedGenerators","useQuery","fetchedTransforms","fetchedTextProviders","fetchedVisionProviders","handleDragStart","handleDoubleClick","inputDefinition","saveDefinition","generatorsByCategory","acc","g","cat","transformsByCategory","t","category","def","NodeInspector","selectedNodeId","deleteNode","selectedNode","schema","nodeLabel","isCloudSave","v","handleParamChange","getParamValue","isFieldVisible","_field","shapeType","fillType","FieldEditor","OutputSchemaEditor","onChange","label","inputClasses","opt","newPropertyName","setNewPropertyName","properties","propertyEntries","handleAddProperty","newSchema","handleRemoveProperty","newProperties","handleTypeChange","type","handleDescriptionChange","description","topologicalSort","nodeMap","inDegree","adjacency","edge","targets","queue","degree","sorted","neighbors","neighbor","newDegree","getNodeVarName","suffix","stringify","generateNodeCode","nodeVarNames","varName","imports","inputEdge","inputVarName","paramStr","k","generateJavaScript","sortedNodes","allImports","codeBlocks","code","imp","importLines","header","mainCode","block","ImportModal","isOpen","onClose","onImport","yamlContent","setYamlContent","isLoading","setIsLoading","isDragging","setIsDragging","handleImport","handleValidate","handleFileUpload","text","handleDragLeave","handleFileInputChange","Toolbar","brandingSlot","beforeActionsSlot","afterActionsSlot","hideAttribution","hideWorkflowLibrary","execution","execute","cancelExecution","exportToYaml","importFromYaml","openSettings","hasUnsavedChanges","saveWorkflow","toggleLibrary","setActiveWorkflowName","duplicateNode","showExport","setShowExport","showImport","setShowImport","exportTab","setExportTab","jsContent","setJsContent","notification","setNotification","isEditingName","setIsEditingName","editingName","setEditingName","handleNewWorkflow","handleSave","handleStartRename","handleSaveRename","trimmed","handleDuplicate","handleKeyDown","handleExecute","handleExport","js","handleCopy","content","importedNodes","importedEdges","idx","Gallery","loadTemplate","loadingWorkflow","setLoadingWorkflow","images","refetch","handleLoadWorkflow","imageId","metadata","image","ImageCard","onLoadWorkflow","formatDate","revenueChart","monthlyUsers","frameworkUsage","trafficBreakdown","apiFlow","systemArchitecture","gitWorkflow","dataVizTemplates","aiProductShot","aiHeroImage","aiMascot","aiLogoBrandKit","productPhotoEnhancement","aiArtSocialPost","aiWorkflowTemplates","socialMediaKit","avatarPipeline","watermarkBranding","filterShowcase","responsiveImages","teamHeadshots","screenshotDocs","blogOgImage","emailBanner","appIcons","marketingTemplates","brandedQR","darkQR","wifiQR","thumbnailGenerator","diagramWebp","utilityTemplates","allTemplates","coreTemplates","getTemplateById","getCoreTemplateById","getCoreCategories","categories","getCoreTemplatesByCategory","searchCoreTemplates","query","q","tag","resolveTemplate","TemplateGallery","selectedCategory","setSelectedCategory","searchQuery","setSearchQuery","getCategories","filteredTemplates","templates","TemplateCard","nodeCount","edgeCount","generatorColors","WorkflowItem","isActive","onLoad","onDelete","onRename","onDuplicate","isEditing","setIsEditing","editName","setEditName","showMenu","setShowMenu","handleRename","date","diffMs","diffMins","diffHours","diffDays","WorkflowLibrary","showLibrary","loadWorkflow","deleteWorkflow","renameWorkflow","duplicateWorkflow","sortedWorkflows","a","b","CLOUD_PROVIDERS","LOCAL_PROVIDERS","CloudProviderRow","setAIProvider","isEnabled","apiKey","localKey","setLocalKey","showKey","setShowKey","handleToggle","handleKeyChange","LocalProviderRow","baseUrl","localUrl","setLocalUrl","handleUrlChange","AISettings","showSettings","closeSettings","activeGenerationConnection","AIChat","onApplyWorkflow","setMessages","setInput","generationPhase","setGenerationPhase","generationMessage","setGenerationMessage","isAvailable","setIsAvailable","statusMessage","setStatusMessage","statusReason","setStatusReason","isCloudDeployment","setIsCloudDeployment","supportUrl","setSupportUrl","messagesEndRef","inputRef","status","handleSubmit","userMessage","receivedWorkflow","assistantMessage","handleCancelGeneration","handleApply","handleNewChat","example","i","msg","nodeIdx","MAX_JSON_DEPTH","MAX_ARRAY_ITEMS","LARGE_OUTPUT_THRESHOLD","OutputInspector","output","viewMode","setViewMode","copied","setCopied","textToCopy","hasFormattedView","JsonTree","JsonNode","depth","keyName","maxDepth","indent","displayValue","itemsToRender","hiddenCount","item","entries","val","EditorDropZone","screenToFlowPosition","useReactFlow","App","activeTab","setActiveTab","showAIChat","setShowAIChat","loadGeneratedWorkflow","inspectedNodeId","executionDataOutputs","closeOutputInspector","inspectedNode","inspectedOutput","templateId","handleWorkflowLoaded","handleTemplateSelect","handleApplyWorkflow","ReactFlowProvider"],"mappings":"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","x_google_ignoreList":[0]}
|