feat: enhance canvas functionality with new asset node type and improved image handling

- Introduced a new "asset" node type in the canvas sidebar for better resource management.
- Updated image node components to support dynamic image dimensions and improved resizing logic.
- Enhanced prompt and AI image nodes to utilize reference images from asset nodes, improving integration and functionality.
- Refactored canvas utilities to accommodate new asset configurations and maintain consistent media handling.
This commit is contained in:
Matthias
2026-03-27 20:33:20 +01:00
parent 6e38e2d270
commit bc3bbf9d69
14 changed files with 1059 additions and 189 deletions

View File

@@ -1,154 +0,0 @@
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7axgmhqz0gkt6sndpq6ersch83nysx","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606648051}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H2","location":"canvas.tsx:edgeSyncEffect","message":"edges passed to ReactFlow","data":{"edgeCount":6,"edges":[{"id":"jn7axgmhqz0gkt6sndpq6ersch83nysx","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7242a6vnazmg729y2nwfb4vx83nqgf","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7b8ee3z6p073bdecght4ba5d83m5mv","source":"js7ak7hkab3rpnxqc6xdzjphx583m665","target":"js7fr15mb7ds98dvw9w2wjj89983naj6","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","source":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","target":"js79syh9wc7n20m6fg9r1191q183msb2","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","source":"js7fr15mb7ds98dvw9w2wjj89983naj6","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"left","typeofTH":"string","isNullTH":false},{"id":"jn72b68knm8y5tvjj6a6fj6h8n83n9a7","source":"js79syh9wc7n20m6fg9r1191q183msb2","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"right","typeofTH":"string","isNullTH":false}]},"timestamp":1774606648051}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7242a6vnazmg729y2nwfb4vx83nqgf","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606648051}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7axgmhqz0gkt6sndpq6ersch83nysx","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606648052}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7b8ee3z6p073bdecght4ba5d83m5mv","sourceNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606648051}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7b8ee3z6p073bdecght4ba5d83m5mv","sourceNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606648052}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","sourceNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetNodeId":"js79syh9wc7n20m6fg9r1191q183msb2","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606648052}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","sourceNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"left","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"left"},"timestamp":1774606648052}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","sourceNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"left","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"left"},"timestamp":1774606648051}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H2","location":"canvas.tsx:edgeSyncEffect","message":"edges passed to ReactFlow","data":{"edgeCount":6,"edges":[{"id":"jn7axgmhqz0gkt6sndpq6ersch83nysx","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7242a6vnazmg729y2nwfb4vx83nqgf","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7b8ee3z6p073bdecght4ba5d83m5mv","source":"js7ak7hkab3rpnxqc6xdzjphx583m665","target":"js7fr15mb7ds98dvw9w2wjj89983naj6","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","source":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","target":"js79syh9wc7n20m6fg9r1191q183msb2","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","source":"js7fr15mb7ds98dvw9w2wjj89983naj6","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"left","typeofTH":"string","isNullTH":false},{"id":"jn72b68knm8y5tvjj6a6fj6h8n83n9a7","source":"js79syh9wc7n20m6fg9r1191q183msb2","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"right","typeofTH":"string","isNullTH":false}]},"timestamp":1774606648052}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn72b68knm8y5tvjj6a6fj6h8n83n9a7","sourceNodeId":"js79syh9wc7n20m6fg9r1191q183msb2","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"right","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"right"},"timestamp":1774606648052}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7242a6vnazmg729y2nwfb4vx83nqgf","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606648052}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","sourceNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetNodeId":"js79syh9wc7n20m6fg9r1191q183msb2","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606648051}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn72b68knm8y5tvjj6a6fj6h8n83n9a7","sourceNodeId":"js79syh9wc7n20m6fg9r1191q183msb2","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"right","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"right"},"timestamp":1774606648051}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7242a6vnazmg729y2nwfb4vx83nqgf","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606657711}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn78rknrhj507t3e123ba7ebqn83pnx4","sourceNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetNodeId":"js7df78fpx4gpt1n50fj6hwyjs83pzxf","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606657711}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7axgmhqz0gkt6sndpq6ersch83nysx","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606657711}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7b8ee3z6p073bdecght4ba5d83m5mv","sourceNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606657711}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H2","location":"canvas.tsx:edgeSyncEffect","message":"edges passed to ReactFlow","data":{"edgeCount":7,"edges":[{"id":"jn7axgmhqz0gkt6sndpq6ersch83nysx","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7242a6vnazmg729y2nwfb4vx83nqgf","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7b8ee3z6p073bdecght4ba5d83m5mv","source":"js7ak7hkab3rpnxqc6xdzjphx583m665","target":"js7fr15mb7ds98dvw9w2wjj89983naj6","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","source":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","target":"js79syh9wc7n20m6fg9r1191q183msb2","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","source":"js7fr15mb7ds98dvw9w2wjj89983naj6","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"left","typeofTH":"string","isNullTH":false},{"id":"jn72b68knm8y5tvjj6a6fj6h8n83n9a7","source":"js79syh9wc7n20m6fg9r1191q183msb2","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"right","typeofTH":"string","isNullTH":false},{"id":"jn78rknrhj507t3e123ba7ebqn83pnx4","source":"js7ak7hkab3rpnxqc6xdzjphx583m665","target":"js7df78fpx4gpt1n50fj6hwyjs83pzxf","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false}]},"timestamp":1774606657711}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","sourceNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetNodeId":"js79syh9wc7n20m6fg9r1191q183msb2","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606657711}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7b8ee3z6p073bdecght4ba5d83m5mv","sourceNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606657712}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7axgmhqz0gkt6sndpq6ersch83nysx","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606657712}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","sourceNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetNodeId":"js79syh9wc7n20m6fg9r1191q183msb2","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606657712}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7242a6vnazmg729y2nwfb4vx83nqgf","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606657712}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","sourceNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"left","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"left"},"timestamp":1774606657712}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","sourceNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"left","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"left"},"timestamp":1774606657711}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn72b68knm8y5tvjj6a6fj6h8n83n9a7","sourceNodeId":"js79syh9wc7n20m6fg9r1191q183msb2","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"right","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"right"},"timestamp":1774606657712}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn78rknrhj507t3e123ba7ebqn83pnx4","sourceNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetNodeId":"js7df78fpx4gpt1n50fj6hwyjs83pzxf","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606657712}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn72b68knm8y5tvjj6a6fj6h8n83n9a7","sourceNodeId":"js79syh9wc7n20m6fg9r1191q183msb2","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"right","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"right"},"timestamp":1774606657711}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H2","location":"canvas.tsx:edgeSyncEffect","message":"edges passed to ReactFlow","data":{"edgeCount":7,"edges":[{"id":"jn7axgmhqz0gkt6sndpq6ersch83nysx","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7242a6vnazmg729y2nwfb4vx83nqgf","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7b8ee3z6p073bdecght4ba5d83m5mv","source":"js7ak7hkab3rpnxqc6xdzjphx583m665","target":"js7fr15mb7ds98dvw9w2wjj89983naj6","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","source":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","target":"js79syh9wc7n20m6fg9r1191q183msb2","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","source":"js7fr15mb7ds98dvw9w2wjj89983naj6","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"left","typeofTH":"string","isNullTH":false},{"id":"jn72b68knm8y5tvjj6a6fj6h8n83n9a7","source":"js79syh9wc7n20m6fg9r1191q183msb2","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"right","typeofTH":"string","isNullTH":false},{"id":"jn78rknrhj507t3e123ba7ebqn83pnx4","source":"js7ak7hkab3rpnxqc6xdzjphx583m665","target":"js7df78fpx4gpt1n50fj6hwyjs83pzxf","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false}]},"timestamp":1774606657712}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7axgmhqz0gkt6sndpq6ersch83nysx","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606661452}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7242a6vnazmg729y2nwfb4vx83nqgf","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606661452}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7b8ee3z6p073bdecght4ba5d83m5mv","sourceNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606661452}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","sourceNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetNodeId":"js79syh9wc7n20m6fg9r1191q183msb2","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606661452}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","sourceNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"left","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"left"},"timestamp":1774606661452}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn72b68knm8y5tvjj6a6fj6h8n83n9a7","sourceNodeId":"js79syh9wc7n20m6fg9r1191q183msb2","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"right","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"right"},"timestamp":1774606661452}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn78rknrhj507t3e123ba7ebqn83pnx4","sourceNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetNodeId":"js7df78fpx4gpt1n50fj6hwyjs83pzxf","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606661452}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn76zkdqqkxnpkghrwaevm3j3x83qyyx","sourceNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetNodeId":"js7380wns03f3m9zr10qfev0wn83q0nv","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606661452}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H2","location":"canvas.tsx:edgeSyncEffect","message":"edges passed to ReactFlow","data":{"edgeCount":8,"edges":[{"id":"jn7axgmhqz0gkt6sndpq6ersch83nysx","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7242a6vnazmg729y2nwfb4vx83nqgf","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7b8ee3z6p073bdecght4ba5d83m5mv","source":"js7ak7hkab3rpnxqc6xdzjphx583m665","target":"js7fr15mb7ds98dvw9w2wjj89983naj6","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","source":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","target":"js79syh9wc7n20m6fg9r1191q183msb2","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","source":"js7fr15mb7ds98dvw9w2wjj89983naj6","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"left","typeofTH":"string","isNullTH":false},{"id":"jn72b68knm8y5tvjj6a6fj6h8n83n9a7","source":"js79syh9wc7n20m6fg9r1191q183msb2","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"right","typeofTH":"string","isNullTH":false},{"id":"jn78rknrhj507t3e123ba7ebqn83pnx4","source":"js7ak7hkab3rpnxqc6xdzjphx583m665","target":"js7df78fpx4gpt1n50fj6hwyjs83pzxf","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn76zkdqqkxnpkghrwaevm3j3x83qyyx","source":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","target":"js7380wns03f3m9zr10qfev0wn83q0nv","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false}]},"timestamp":1774606661452}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7axgmhqz0gkt6sndpq6ersch83nysx","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606661452}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7b8ee3z6p073bdecght4ba5d83m5mv","sourceNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606661452}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn78rknrhj507t3e123ba7ebqn83pnx4","sourceNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetNodeId":"js7df78fpx4gpt1n50fj6hwyjs83pzxf","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606661452}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7242a6vnazmg729y2nwfb4vx83nqgf","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606661452}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","sourceNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetNodeId":"js79syh9wc7n20m6fg9r1191q183msb2","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606661452}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","sourceNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"left","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"left"},"timestamp":1774606661452}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn76zkdqqkxnpkghrwaevm3j3x83qyyx","sourceNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetNodeId":"js7380wns03f3m9zr10qfev0wn83q0nv","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606661453}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn72b68knm8y5tvjj6a6fj6h8n83n9a7","sourceNodeId":"js79syh9wc7n20m6fg9r1191q183msb2","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"right","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"right"},"timestamp":1774606661452}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H2","location":"canvas.tsx:edgeSyncEffect","message":"edges passed to ReactFlow","data":{"edgeCount":8,"edges":[{"id":"jn7axgmhqz0gkt6sndpq6ersch83nysx","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7242a6vnazmg729y2nwfb4vx83nqgf","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7b8ee3z6p073bdecght4ba5d83m5mv","source":"js7ak7hkab3rpnxqc6xdzjphx583m665","target":"js7fr15mb7ds98dvw9w2wjj89983naj6","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","source":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","target":"js79syh9wc7n20m6fg9r1191q183msb2","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","source":"js7fr15mb7ds98dvw9w2wjj89983naj6","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"left","typeofTH":"string","isNullTH":false},{"id":"jn72b68knm8y5tvjj6a6fj6h8n83n9a7","source":"js79syh9wc7n20m6fg9r1191q183msb2","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"right","typeofTH":"string","isNullTH":false},{"id":"jn78rknrhj507t3e123ba7ebqn83pnx4","source":"js7ak7hkab3rpnxqc6xdzjphx583m665","target":"js7df78fpx4gpt1n50fj6hwyjs83pzxf","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn76zkdqqkxnpkghrwaevm3j3x83qyyx","source":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","target":"js7380wns03f3m9zr10qfev0wn83q0nv","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false}]},"timestamp":1774606661453}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7axgmhqz0gkt6sndpq6ersch83nysx","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606680465}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7242a6vnazmg729y2nwfb4vx83nqgf","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606680466}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","sourceNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetNodeId":"js79syh9wc7n20m6fg9r1191q183msb2","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606680466}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn78rknrhj507t3e123ba7ebqn83pnx4","sourceNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetNodeId":"js7df78fpx4gpt1n50fj6hwyjs83pzxf","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606680466}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7b8ee3z6p073bdecght4ba5d83m5mv","sourceNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606680466}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7242a6vnazmg729y2nwfb4vx83nqgf","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606680466}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H2","location":"canvas.tsx:edgeSyncEffect","message":"edges passed to ReactFlow","data":{"edgeCount":7,"edges":[{"id":"jn7axgmhqz0gkt6sndpq6ersch83nysx","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7242a6vnazmg729y2nwfb4vx83nqgf","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7b8ee3z6p073bdecght4ba5d83m5mv","source":"js7ak7hkab3rpnxqc6xdzjphx583m665","target":"js7fr15mb7ds98dvw9w2wjj89983naj6","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","source":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","target":"js79syh9wc7n20m6fg9r1191q183msb2","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","source":"js7fr15mb7ds98dvw9w2wjj89983naj6","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"left","typeofTH":"string","isNullTH":false},{"id":"jn72b68knm8y5tvjj6a6fj6h8n83n9a7","source":"js79syh9wc7n20m6fg9r1191q183msb2","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"right","typeofTH":"string","isNullTH":false},{"id":"jn78rknrhj507t3e123ba7ebqn83pnx4","source":"js7ak7hkab3rpnxqc6xdzjphx583m665","target":"js7df78fpx4gpt1n50fj6hwyjs83pzxf","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false}]},"timestamp":1774606680466}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","sourceNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetNodeId":"js79syh9wc7n20m6fg9r1191q183msb2","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606680466}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn72b68knm8y5tvjj6a6fj6h8n83n9a7","sourceNodeId":"js79syh9wc7n20m6fg9r1191q183msb2","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"right","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"right"},"timestamp":1774606680466}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn72b68knm8y5tvjj6a6fj6h8n83n9a7","sourceNodeId":"js79syh9wc7n20m6fg9r1191q183msb2","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"right","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"right"},"timestamp":1774606680466}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","sourceNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"left","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"left"},"timestamp":1774606680466}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H2","location":"canvas.tsx:edgeSyncEffect","message":"edges passed to ReactFlow","data":{"edgeCount":7,"edges":[{"id":"jn7axgmhqz0gkt6sndpq6ersch83nysx","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7242a6vnazmg729y2nwfb4vx83nqgf","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7b8ee3z6p073bdecght4ba5d83m5mv","source":"js7ak7hkab3rpnxqc6xdzjphx583m665","target":"js7fr15mb7ds98dvw9w2wjj89983naj6","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","source":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","target":"js79syh9wc7n20m6fg9r1191q183msb2","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","source":"js7fr15mb7ds98dvw9w2wjj89983naj6","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"left","typeofTH":"string","isNullTH":false},{"id":"jn72b68knm8y5tvjj6a6fj6h8n83n9a7","source":"js79syh9wc7n20m6fg9r1191q183msb2","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"right","typeofTH":"string","isNullTH":false},{"id":"jn78rknrhj507t3e123ba7ebqn83pnx4","source":"js7ak7hkab3rpnxqc6xdzjphx583m665","target":"js7df78fpx4gpt1n50fj6hwyjs83pzxf","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false}]},"timestamp":1774606680466}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7b8ee3z6p073bdecght4ba5d83m5mv","sourceNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606680466}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn78rknrhj507t3e123ba7ebqn83pnx4","sourceNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetNodeId":"js7df78fpx4gpt1n50fj6hwyjs83pzxf","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606680466}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7axgmhqz0gkt6sndpq6ersch83nysx","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606680466}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","sourceNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"left","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"left"},"timestamp":1774606680466}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7axgmhqz0gkt6sndpq6ersch83nysx","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606684760}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7242a6vnazmg729y2nwfb4vx83nqgf","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606684760}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7b8ee3z6p073bdecght4ba5d83m5mv","sourceNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606684760}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","sourceNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetNodeId":"js79syh9wc7n20m6fg9r1191q183msb2","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606684760}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","sourceNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"left","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"left"},"timestamp":1774606684760}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn72b68knm8y5tvjj6a6fj6h8n83n9a7","sourceNodeId":"js79syh9wc7n20m6fg9r1191q183msb2","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"right","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"right"},"timestamp":1774606684760}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn78rknrhj507t3e123ba7ebqn83pnx4","sourceNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetNodeId":"js7df78fpx4gpt1n50fj6hwyjs83pzxf","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606684760}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn741xv0z6ttznkfncsaansnz983qbse","sourceNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetNodeId":"js79vt1be2c1zab58j94ydfzp183pqdg","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606684760}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H2","location":"canvas.tsx:edgeSyncEffect","message":"edges passed to ReactFlow","data":{"edgeCount":8,"edges":[{"id":"jn7axgmhqz0gkt6sndpq6ersch83nysx","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7242a6vnazmg729y2nwfb4vx83nqgf","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7b8ee3z6p073bdecght4ba5d83m5mv","source":"js7ak7hkab3rpnxqc6xdzjphx583m665","target":"js7fr15mb7ds98dvw9w2wjj89983naj6","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","source":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","target":"js79syh9wc7n20m6fg9r1191q183msb2","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","source":"js7fr15mb7ds98dvw9w2wjj89983naj6","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"left","typeofTH":"string","isNullTH":false},{"id":"jn72b68knm8y5tvjj6a6fj6h8n83n9a7","source":"js79syh9wc7n20m6fg9r1191q183msb2","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"right","typeofTH":"string","isNullTH":false},{"id":"jn78rknrhj507t3e123ba7ebqn83pnx4","source":"js7ak7hkab3rpnxqc6xdzjphx583m665","target":"js7df78fpx4gpt1n50fj6hwyjs83pzxf","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn741xv0z6ttznkfncsaansnz983qbse","source":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","target":"js79vt1be2c1zab58j94ydfzp183pqdg","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false}]},"timestamp":1774606684760}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7axgmhqz0gkt6sndpq6ersch83nysx","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606684760}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7242a6vnazmg729y2nwfb4vx83nqgf","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606684760}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7b8ee3z6p073bdecght4ba5d83m5mv","sourceNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606684760}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn78rknrhj507t3e123ba7ebqn83pnx4","sourceNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetNodeId":"js7df78fpx4gpt1n50fj6hwyjs83pzxf","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606684761}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn72b68knm8y5tvjj6a6fj6h8n83n9a7","sourceNodeId":"js79syh9wc7n20m6fg9r1191q183msb2","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"right","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"right"},"timestamp":1774606684761}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn741xv0z6ttznkfncsaansnz983qbse","sourceNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetNodeId":"js79vt1be2c1zab58j94ydfzp183pqdg","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606684761}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","sourceNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetNodeId":"js79syh9wc7n20m6fg9r1191q183msb2","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606684761}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","sourceNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"left","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"left"},"timestamp":1774606684761}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H2","location":"canvas.tsx:edgeSyncEffect","message":"edges passed to ReactFlow","data":{"edgeCount":8,"edges":[{"id":"jn7axgmhqz0gkt6sndpq6ersch83nysx","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7242a6vnazmg729y2nwfb4vx83nqgf","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7b8ee3z6p073bdecght4ba5d83m5mv","source":"js7ak7hkab3rpnxqc6xdzjphx583m665","target":"js7fr15mb7ds98dvw9w2wjj89983naj6","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","source":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","target":"js79syh9wc7n20m6fg9r1191q183msb2","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","source":"js7fr15mb7ds98dvw9w2wjj89983naj6","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"left","typeofTH":"string","isNullTH":false},{"id":"jn72b68knm8y5tvjj6a6fj6h8n83n9a7","source":"js79syh9wc7n20m6fg9r1191q183msb2","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"right","typeofTH":"string","isNullTH":false},{"id":"jn78rknrhj507t3e123ba7ebqn83pnx4","source":"js7ak7hkab3rpnxqc6xdzjphx583m665","target":"js7df78fpx4gpt1n50fj6hwyjs83pzxf","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn741xv0z6ttznkfncsaansnz983qbse","source":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","target":"js79vt1be2c1zab58j94ydfzp183pqdg","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false}]},"timestamp":1774606684761}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7242a6vnazmg729y2nwfb4vx83nqgf","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606811016}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7a560btkzv97yv0qvk8ep1yd83qmn2","sourceNodeId":"js79vt1be2c1zab58j94ydfzp183pqdg","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"right","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"right"},"timestamp":1774606811016}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","sourceNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"left","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"left"},"timestamp":1774606811016}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7242a6vnazmg729y2nwfb4vx83nqgf","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606811016}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7axgmhqz0gkt6sndpq6ersch83nysx","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606811015}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7a560btkzv97yv0qvk8ep1yd83qmn2","sourceNodeId":"js79vt1be2c1zab58j94ydfzp183pqdg","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"right","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"right"},"timestamp":1774606811016}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7axgmhqz0gkt6sndpq6ersch83nysx","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606811016}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","sourceNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetNodeId":"js79syh9wc7n20m6fg9r1191q183msb2","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606811016}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn72b68knm8y5tvjj6a6fj6h8n83n9a7","sourceNodeId":"js79syh9wc7n20m6fg9r1191q183msb2","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"right","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"right"},"timestamp":1774606811016}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn741xv0z6ttznkfncsaansnz983qbse","sourceNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetNodeId":"js79vt1be2c1zab58j94ydfzp183pqdg","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606811016}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn78rknrhj507t3e123ba7ebqn83pnx4","sourceNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetNodeId":"js7df78fpx4gpt1n50fj6hwyjs83pzxf","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606811016}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn78rknrhj507t3e123ba7ebqn83pnx4","sourceNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetNodeId":"js7df78fpx4gpt1n50fj6hwyjs83pzxf","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606811016}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","sourceNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetNodeId":"js79syh9wc7n20m6fg9r1191q183msb2","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606811016}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn72b68knm8y5tvjj6a6fj6h8n83n9a7","sourceNodeId":"js79syh9wc7n20m6fg9r1191q183msb2","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"right","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"right"},"timestamp":1774606811016}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7b8ee3z6p073bdecght4ba5d83m5mv","sourceNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606811016}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn741xv0z6ttznkfncsaansnz983qbse","sourceNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetNodeId":"js79vt1be2c1zab58j94ydfzp183pqdg","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606811016}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H2","location":"canvas.tsx:edgeSyncEffect","message":"edges passed to ReactFlow","data":{"edgeCount":9,"edges":[{"id":"jn7axgmhqz0gkt6sndpq6ersch83nysx","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7242a6vnazmg729y2nwfb4vx83nqgf","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7b8ee3z6p073bdecght4ba5d83m5mv","source":"js7ak7hkab3rpnxqc6xdzjphx583m665","target":"js7fr15mb7ds98dvw9w2wjj89983naj6","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","source":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","target":"js79syh9wc7n20m6fg9r1191q183msb2","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","source":"js7fr15mb7ds98dvw9w2wjj89983naj6","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"left","typeofTH":"string","isNullTH":false},{"id":"jn72b68knm8y5tvjj6a6fj6h8n83n9a7","source":"js79syh9wc7n20m6fg9r1191q183msb2","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"right","typeofTH":"string","isNullTH":false},{"id":"jn78rknrhj507t3e123ba7ebqn83pnx4","source":"js7ak7hkab3rpnxqc6xdzjphx583m665","target":"js7df78fpx4gpt1n50fj6hwyjs83pzxf","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn741xv0z6ttznkfncsaansnz983qbse","source":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","target":"js79vt1be2c1zab58j94ydfzp183pqdg","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn7a560btkzv97yv0qvk8ep1yd83qmn2","source":"js79vt1be2c1zab58j94ydfzp183pqdg","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"right","typeofTH":"string","isNullTH":false}]},"timestamp":1774606811016}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H2","location":"canvas.tsx:edgeSyncEffect","message":"edges passed to ReactFlow","data":{"edgeCount":9,"edges":[{"id":"jn7axgmhqz0gkt6sndpq6ersch83nysx","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7242a6vnazmg729y2nwfb4vx83nqgf","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7b8ee3z6p073bdecght4ba5d83m5mv","source":"js7ak7hkab3rpnxqc6xdzjphx583m665","target":"js7fr15mb7ds98dvw9w2wjj89983naj6","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","source":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","target":"js79syh9wc7n20m6fg9r1191q183msb2","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","source":"js7fr15mb7ds98dvw9w2wjj89983naj6","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"left","typeofTH":"string","isNullTH":false},{"id":"jn72b68knm8y5tvjj6a6fj6h8n83n9a7","source":"js79syh9wc7n20m6fg9r1191q183msb2","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"right","typeofTH":"string","isNullTH":false},{"id":"jn78rknrhj507t3e123ba7ebqn83pnx4","source":"js7ak7hkab3rpnxqc6xdzjphx583m665","target":"js7df78fpx4gpt1n50fj6hwyjs83pzxf","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn741xv0z6ttznkfncsaansnz983qbse","source":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","target":"js79vt1be2c1zab58j94ydfzp183pqdg","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn7a560btkzv97yv0qvk8ep1yd83qmn2","source":"js79vt1be2c1zab58j94ydfzp183pqdg","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"right","typeofTH":"string","isNullTH":false}]},"timestamp":1774606811016}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7b8ee3z6p073bdecght4ba5d83m5mv","sourceNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606811016}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","sourceNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"left","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"left"},"timestamp":1774606811016}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H2","location":"canvas.tsx:edgeSyncEffect","message":"edges passed to ReactFlow","data":{"edgeCount":8,"edges":[{"id":"jn7axgmhqz0gkt6sndpq6ersch83nysx","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7242a6vnazmg729y2nwfb4vx83nqgf","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7b8ee3z6p073bdecght4ba5d83m5mv","source":"js7ak7hkab3rpnxqc6xdzjphx583m665","target":"js7fr15mb7ds98dvw9w2wjj89983naj6","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","source":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","target":"js79syh9wc7n20m6fg9r1191q183msb2","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","source":"js7fr15mb7ds98dvw9w2wjj89983naj6","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"left","typeofTH":"string","isNullTH":false},{"id":"jn78rknrhj507t3e123ba7ebqn83pnx4","source":"js7ak7hkab3rpnxqc6xdzjphx583m665","target":"js7df78fpx4gpt1n50fj6hwyjs83pzxf","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn741xv0z6ttznkfncsaansnz983qbse","source":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","target":"js79vt1be2c1zab58j94ydfzp183pqdg","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn7a560btkzv97yv0qvk8ep1yd83qmn2","source":"js79vt1be2c1zab58j94ydfzp183pqdg","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"right","typeofTH":"string","isNullTH":false}]},"timestamp":1774606822672}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7242a6vnazmg729y2nwfb4vx83nqgf","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606822672}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7b8ee3z6p073bdecght4ba5d83m5mv","sourceNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606822671}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H2","location":"canvas.tsx:edgeSyncEffect","message":"edges passed to ReactFlow","data":{"edgeCount":8,"edges":[{"id":"jn7axgmhqz0gkt6sndpq6ersch83nysx","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7242a6vnazmg729y2nwfb4vx83nqgf","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7b8ee3z6p073bdecght4ba5d83m5mv","source":"js7ak7hkab3rpnxqc6xdzjphx583m665","target":"js7fr15mb7ds98dvw9w2wjj89983naj6","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","source":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","target":"js79syh9wc7n20m6fg9r1191q183msb2","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","source":"js7fr15mb7ds98dvw9w2wjj89983naj6","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"left","typeofTH":"string","isNullTH":false},{"id":"jn78rknrhj507t3e123ba7ebqn83pnx4","source":"js7ak7hkab3rpnxqc6xdzjphx583m665","target":"js7df78fpx4gpt1n50fj6hwyjs83pzxf","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn741xv0z6ttznkfncsaansnz983qbse","source":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","target":"js79vt1be2c1zab58j94ydfzp183pqdg","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn7a560btkzv97yv0qvk8ep1yd83qmn2","source":"js79vt1be2c1zab58j94ydfzp183pqdg","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"right","typeofTH":"string","isNullTH":false}]},"timestamp":1774606822672}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7a560btkzv97yv0qvk8ep1yd83qmn2","sourceNodeId":"js79vt1be2c1zab58j94ydfzp183pqdg","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"right","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"right"},"timestamp":1774606822672}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn78rknrhj507t3e123ba7ebqn83pnx4","sourceNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetNodeId":"js7df78fpx4gpt1n50fj6hwyjs83pzxf","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606822672}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","sourceNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetNodeId":"js79syh9wc7n20m6fg9r1191q183msb2","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606822671}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7axgmhqz0gkt6sndpq6ersch83nysx","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606822671}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7242a6vnazmg729y2nwfb4vx83nqgf","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606822671}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn741xv0z6ttznkfncsaansnz983qbse","sourceNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetNodeId":"js79vt1be2c1zab58j94ydfzp183pqdg","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606822672}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","sourceNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"left","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"left"},"timestamp":1774606822672}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7axgmhqz0gkt6sndpq6ersch83nysx","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606822672}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7b8ee3z6p073bdecght4ba5d83m5mv","sourceNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606822672}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","sourceNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"left","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"left"},"timestamp":1774606822672}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","sourceNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetNodeId":"js79syh9wc7n20m6fg9r1191q183msb2","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606822672}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn78rknrhj507t3e123ba7ebqn83pnx4","sourceNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetNodeId":"js7df78fpx4gpt1n50fj6hwyjs83pzxf","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606822672}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7a560btkzv97yv0qvk8ep1yd83qmn2","sourceNodeId":"js79vt1be2c1zab58j94ydfzp183pqdg","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"right","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"right"},"timestamp":1774606822672}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn741xv0z6ttznkfncsaansnz983qbse","sourceNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetNodeId":"js79vt1be2c1zab58j94ydfzp183pqdg","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606822672}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7axgmhqz0gkt6sndpq6ersch83nysx","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606827178}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7242a6vnazmg729y2nwfb4vx83nqgf","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606827179}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7b8ee3z6p073bdecght4ba5d83m5mv","sourceNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606827179}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","sourceNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetNodeId":"js79syh9wc7n20m6fg9r1191q183msb2","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606827179}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","sourceNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"left","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"left"},"timestamp":1774606827179}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn78rknrhj507t3e123ba7ebqn83pnx4","sourceNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetNodeId":"js7df78fpx4gpt1n50fj6hwyjs83pzxf","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606827179}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn741xv0z6ttznkfncsaansnz983qbse","sourceNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetNodeId":"js79vt1be2c1zab58j94ydfzp183pqdg","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606827179}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H2","location":"canvas.tsx:edgeSyncEffect","message":"edges passed to ReactFlow","data":{"edgeCount":7,"edges":[{"id":"jn7axgmhqz0gkt6sndpq6ersch83nysx","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7242a6vnazmg729y2nwfb4vx83nqgf","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7b8ee3z6p073bdecght4ba5d83m5mv","source":"js7ak7hkab3rpnxqc6xdzjphx583m665","target":"js7fr15mb7ds98dvw9w2wjj89983naj6","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","source":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","target":"js79syh9wc7n20m6fg9r1191q183msb2","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","source":"js7fr15mb7ds98dvw9w2wjj89983naj6","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"left","typeofTH":"string","isNullTH":false},{"id":"jn78rknrhj507t3e123ba7ebqn83pnx4","source":"js7ak7hkab3rpnxqc6xdzjphx583m665","target":"js7df78fpx4gpt1n50fj6hwyjs83pzxf","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn741xv0z6ttznkfncsaansnz983qbse","source":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","target":"js79vt1be2c1zab58j94ydfzp183pqdg","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false}]},"timestamp":1774606827179}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7axgmhqz0gkt6sndpq6ersch83nysx","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606827179}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7242a6vnazmg729y2nwfb4vx83nqgf","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606827179}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7b8ee3z6p073bdecght4ba5d83m5mv","sourceNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606827179}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","sourceNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetNodeId":"js79syh9wc7n20m6fg9r1191q183msb2","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606827179}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H2","location":"canvas.tsx:edgeSyncEffect","message":"edges passed to ReactFlow","data":{"edgeCount":7,"edges":[{"id":"jn7axgmhqz0gkt6sndpq6ersch83nysx","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7242a6vnazmg729y2nwfb4vx83nqgf","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7b8ee3z6p073bdecght4ba5d83m5mv","source":"js7ak7hkab3rpnxqc6xdzjphx583m665","target":"js7fr15mb7ds98dvw9w2wjj89983naj6","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","source":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","target":"js79syh9wc7n20m6fg9r1191q183msb2","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","source":"js7fr15mb7ds98dvw9w2wjj89983naj6","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"left","typeofTH":"string","isNullTH":false},{"id":"jn78rknrhj507t3e123ba7ebqn83pnx4","source":"js7ak7hkab3rpnxqc6xdzjphx583m665","target":"js7df78fpx4gpt1n50fj6hwyjs83pzxf","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn741xv0z6ttznkfncsaansnz983qbse","source":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","target":"js79vt1be2c1zab58j94ydfzp183pqdg","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false}]},"timestamp":1774606827180}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","sourceNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"left","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"left"},"timestamp":1774606827179}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn741xv0z6ttznkfncsaansnz983qbse","sourceNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetNodeId":"js79vt1be2c1zab58j94ydfzp183pqdg","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606827180}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn78rknrhj507t3e123ba7ebqn83pnx4","sourceNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetNodeId":"js7df78fpx4gpt1n50fj6hwyjs83pzxf","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606827179}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7242a6vnazmg729y2nwfb4vx83nqgf","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606828375}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7axgmhqz0gkt6sndpq6ersch83nysx","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606828374}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn741xv0z6ttznkfncsaansnz983qbse","sourceNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetNodeId":"js79vt1be2c1zab58j94ydfzp183pqdg","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606828375}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H2","location":"canvas.tsx:edgeSyncEffect","message":"edges passed to ReactFlow","data":{"edgeCount":8,"edges":[{"id":"jn7axgmhqz0gkt6sndpq6ersch83nysx","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7242a6vnazmg729y2nwfb4vx83nqgf","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7b8ee3z6p073bdecght4ba5d83m5mv","source":"js7ak7hkab3rpnxqc6xdzjphx583m665","target":"js7fr15mb7ds98dvw9w2wjj89983naj6","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","source":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","target":"js79syh9wc7n20m6fg9r1191q183msb2","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","source":"js7fr15mb7ds98dvw9w2wjj89983naj6","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"left","typeofTH":"string","isNullTH":false},{"id":"jn78rknrhj507t3e123ba7ebqn83pnx4","source":"js7ak7hkab3rpnxqc6xdzjphx583m665","target":"js7df78fpx4gpt1n50fj6hwyjs83pzxf","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn741xv0z6ttznkfncsaansnz983qbse","source":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","target":"js79vt1be2c1zab58j94ydfzp183pqdg","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn7cx57f8hss73bxy5qxbc4v7183qjt4","source":"js79syh9wc7n20m6fg9r1191q183msb2","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"right","typeofTH":"string","isNullTH":false}]},"timestamp":1774606828375}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn78rknrhj507t3e123ba7ebqn83pnx4","sourceNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetNodeId":"js7df78fpx4gpt1n50fj6hwyjs83pzxf","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606828375}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7b8ee3z6p073bdecght4ba5d83m5mv","sourceNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606828376}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","sourceNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetNodeId":"js79syh9wc7n20m6fg9r1191q183msb2","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606828375}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7axgmhqz0gkt6sndpq6ersch83nysx","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606828375}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn78rknrhj507t3e123ba7ebqn83pnx4","sourceNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetNodeId":"js7df78fpx4gpt1n50fj6hwyjs83pzxf","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606828376}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","sourceNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"left","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"left"},"timestamp":1774606828375}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","sourceNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"left","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"left"},"timestamp":1774606828376}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H2","location":"canvas.tsx:edgeSyncEffect","message":"edges passed to ReactFlow","data":{"edgeCount":8,"edges":[{"id":"jn7axgmhqz0gkt6sndpq6ersch83nysx","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7242a6vnazmg729y2nwfb4vx83nqgf","source":"js7bbr471t9fqerb27eh3p0ksd83n82c","target":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetHandle":"image-in","typeofTH":"string","isNullTH":false},{"id":"jn7b8ee3z6p073bdecght4ba5d83m5mv","source":"js7ak7hkab3rpnxqc6xdzjphx583m665","target":"js7fr15mb7ds98dvw9w2wjj89983naj6","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","source":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","target":"js79syh9wc7n20m6fg9r1191q183msb2","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn79n3spvbdrqfgf9wd7h1rvgx83nrtv","source":"js7fr15mb7ds98dvw9w2wjj89983naj6","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"left","typeofTH":"string","isNullTH":false},{"id":"jn78rknrhj507t3e123ba7ebqn83pnx4","source":"js7ak7hkab3rpnxqc6xdzjphx583m665","target":"js7df78fpx4gpt1n50fj6hwyjs83pzxf","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn741xv0z6ttznkfncsaansnz983qbse","source":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","target":"js79vt1be2c1zab58j94ydfzp183pqdg","sourceHandle":"prompt-out","targetHandle":"prompt-in","typeofTH":"string","isNullTH":false},{"id":"jn7cx57f8hss73bxy5qxbc4v7183qjt4","source":"js79syh9wc7n20m6fg9r1191q183msb2","target":"js7cpdwr5v40hw20w55f2cet5583n1g7","sourceHandle":"image-out","targetHandle":"right","typeofTH":"string","isNullTH":false}]},"timestamp":1774606828376}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7cx57f8hss73bxy5qxbc4v7183qjt4","sourceNodeId":"js79syh9wc7n20m6fg9r1191q183msb2","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"right","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"right"},"timestamp":1774606828376}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7b8ee3z6p073bdecght4ba5d83m5mv","sourceNodeId":"js7ak7hkab3rpnxqc6xdzjphx583m665","targetNodeId":"js7fr15mb7ds98dvw9w2wjj89983naj6","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606828375}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7242a6vnazmg729y2nwfb4vx83nqgf","sourceNodeId":"js7bbr471t9fqerb27eh3p0ksd83n82c","targetNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","rawTargetHandle":"image-in","typeofSourceHandle":"undefined","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":true,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedTH":"image-in"},"timestamp":1774606828375}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn741xv0z6ttznkfncsaansnz983qbse","sourceNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetNodeId":"js79vt1be2c1zab58j94ydfzp183pqdg","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606828376}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7cx57f8hss73bxy5qxbc4v7183qjt4","sourceNodeId":"js79syh9wc7n20m6fg9r1191q183msb2","targetNodeId":"js7cpdwr5v40hw20w55f2cet5583n1g7","rawSourceHandle":"image-out","rawTargetHandle":"right","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"image-out","sanitizedTH":"right"},"timestamp":1774606828375}
{"sessionId":"594b9f","runId":"run1","hypothesisId":"H1-H3-H4","location":"canvas-utils.ts:convexEdgeToRF","message":"raw edge from convex","data":{"edgeId":"jn7frrkcn95k984f9w1b7vcv4x83mgpb","sourceNodeId":"js7dt20y2wyrt6mk1e1aee2pgd83mh4e","targetNodeId":"js79syh9wc7n20m6fg9r1191q183msb2","rawSourceHandle":"prompt-out","rawTargetHandle":"prompt-in","typeofSourceHandle":"string","typeofTargetHandle":"string","isNullSH":false,"isNullTH":false,"isUndefinedSH":false,"isUndefinedTH":false,"isStringNullSH":false,"isStringNullTH":false,"sanitizedSH":"prompt-out","sanitizedTH":"prompt-in"},"timestamp":1774606828376}

View File

@@ -4,7 +4,7 @@ import Image from "next/image";
import { useRouter } from "next/navigation";
import { useEffect, useRef, useState } from "react";
import { useTheme } from "next-themes";
import { useMutation, useQuery } from "convex/react";
import { useMutation } from "convex/react";
import {
ChevronDown,
Coins,
@@ -35,6 +35,7 @@ import { RecentTransactions } from "@/components/dashboard/recent-transactions";
import CanvasCard from "@/components/dashboard/canvas-card";
import { toast } from "@/lib/toast";
import { msg } from "@/lib/toast-messages";
import { useAuthQuery } from "@/hooks/use-auth-query";
function getInitials(nameOrEmail: string) {
@@ -54,7 +55,7 @@ export default function DashboardPage() {
const welcomeToastSentRef = useRef(false);
const { theme = "system", setTheme } = useTheme();
const { data: session, isPending: isSessionPending } = authClient.useSession();
const canvases = useQuery(
const canvases = useAuthQuery(
api.canvases.list,
session?.user && !isSessionPending ? {} : "skip",
);

View File

@@ -0,0 +1,380 @@
"use client";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { createPortal } from "react-dom";
import { useAction, useMutation } from "convex/react";
import { X, Search, Loader2, AlertCircle } from "lucide-react";
import { api } from "@/convex/_generated/api";
import type { Id } from "@/convex/_generated/dataModel";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Badge } from "@/components/ui/badge";
import { computeMediaNodeSize } from "@/lib/canvas-utils";
type AssetType = "photo" | "vector" | "icon";
interface FreepikResult {
id: number;
title: string;
assetType: AssetType;
previewUrl: string;
intrinsicWidth?: number;
intrinsicHeight?: number;
sourceUrl: string;
license: "freemium" | "premium";
authorName: string;
orientation?: string;
}
export interface AssetBrowserSessionState {
term: string;
assetType: AssetType;
results: FreepikResult[];
page: number;
totalPages: number;
}
interface Props {
nodeId: string;
canvasId: string;
onClose: () => void;
initialState?: AssetBrowserSessionState;
onStateChange?: (state: AssetBrowserSessionState) => void;
}
export function AssetBrowserPanel({
nodeId,
canvasId,
onClose,
initialState,
onStateChange,
}: Props) {
const [isMounted, setIsMounted] = useState(false);
const [term, setTerm] = useState(initialState?.term ?? "");
const [debouncedTerm, setDebouncedTerm] = useState(initialState?.term ?? "");
const [assetType, setAssetType] = useState<AssetType>(initialState?.assetType ?? "photo");
const [results, setResults] = useState<FreepikResult[]>(initialState?.results ?? []);
const [page, setPage] = useState(initialState?.page ?? 1);
const [totalPages, setTotalPages] = useState(initialState?.totalPages ?? 1);
const [isLoading, setIsLoading] = useState(false);
const [errorMessage, setErrorMessage] = useState<string | null>(null);
const searchFreepik = useAction(api.freepik.search);
const updateData = useMutation(api.nodes.updateData);
const resizeNode = useMutation(api.nodes.resize);
const shouldSkipInitialSearchRef = useRef(Boolean(initialState?.results?.length));
useEffect(() => {
setIsMounted(true);
return () => setIsMounted(false);
}, []);
useEffect(() => {
const timeout = setTimeout(() => {
setDebouncedTerm(term);
}, 500);
return () => clearTimeout(timeout);
}, [term]);
useEffect(() => {
const onKeyDown = (event: KeyboardEvent) => {
if (event.key === "Escape") {
onClose();
}
};
window.addEventListener("keydown", onKeyDown);
return () => window.removeEventListener("keydown", onKeyDown);
}, [onClose]);
useEffect(() => {
if (!onStateChange) return;
onStateChange({
term,
assetType,
results,
page,
totalPages,
});
}, [assetType, onStateChange, page, results, term, totalPages]);
const runSearch = useCallback(
async (searchTerm: string, type: AssetType, requestedPage: number) => {
const cleanedTerm = searchTerm.trim();
if (!cleanedTerm) {
setResults([]);
setErrorMessage(null);
setTotalPages(1);
setPage(1);
return;
}
setIsLoading(true);
setErrorMessage(null);
try {
const response = await searchFreepik({
term: cleanedTerm,
assetType: type,
page: requestedPage,
limit: 20,
});
setResults(response.results);
setTotalPages(response.totalPages);
setPage(response.currentPage);
} catch (error) {
console.error("Freepik search error", error);
setErrorMessage(
error instanceof Error ? error.message : "Freepik search failed",
);
} finally {
setIsLoading(false);
}
},
[searchFreepik],
);
useEffect(() => {
if (shouldSkipInitialSearchRef.current) {
shouldSkipInitialSearchRef.current = false;
return;
}
setPage(1);
void runSearch(debouncedTerm, assetType, 1);
}, [assetType, debouncedTerm, runSearch]);
const handleSelect = useCallback(
async (asset: FreepikResult) => {
await updateData({
nodeId: nodeId as Id<"nodes">,
data: {
assetId: asset.id,
assetType: asset.assetType,
title: asset.title,
previewUrl: asset.previewUrl,
intrinsicWidth: asset.intrinsicWidth,
intrinsicHeight: asset.intrinsicHeight,
url: asset.previewUrl,
sourceUrl: asset.sourceUrl,
license: asset.license,
authorName: asset.authorName,
orientation: asset.orientation,
canvasId,
},
});
const targetSize = computeMediaNodeSize("asset", {
intrinsicWidth: asset.intrinsicWidth,
intrinsicHeight: asset.intrinsicHeight,
orientation: asset.orientation,
});
await resizeNode({
nodeId: nodeId as Id<"nodes">,
width: targetSize.width,
height: targetSize.height,
});
onClose();
},
[canvasId, nodeId, onClose, resizeNode, updateData],
);
const handlePreviousPage = useCallback(() => {
if (isLoading || page <= 1) return;
void runSearch(debouncedTerm, assetType, page - 1);
}, [assetType, debouncedTerm, isLoading, page, runSearch]);
const handleNextPage = useCallback(() => {
if (isLoading || page >= totalPages) return;
void runSearch(debouncedTerm, assetType, page + 1);
}, [assetType, debouncedTerm, isLoading, page, runSearch, totalPages]);
const modal = useMemo(
() => (
<div
className="nowheel nodrag nopan fixed inset-0 z-50 flex items-center justify-center bg-black/40 backdrop-blur-sm"
onClick={onClose}
onWheelCapture={(event) => event.stopPropagation()}
onPointerDownCapture={(event) => event.stopPropagation()}
>
<div
className="nowheel nodrag nopan relative flex max-h-[80vh] w-[720px] flex-col overflow-hidden rounded-xl border bg-background shadow-2xl"
onClick={(event) => event.stopPropagation()}
onWheelCapture={(event) => event.stopPropagation()}
onPointerDownCapture={(event) => event.stopPropagation()}
>
<div className="flex shrink-0 items-center justify-between border-b px-5 py-4">
<h2 className="text-sm font-semibold">Browse Freepik Assets</h2>
<button
onClick={onClose}
className="text-muted-foreground transition-colors hover:text-foreground"
aria-label="Close asset browser"
>
<X className="h-4 w-4" />
</button>
</div>
<div className="flex shrink-0 flex-col gap-3 border-b px-5 py-3">
<div className="relative">
<Search className="absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
<Input
placeholder="Search photos, vectors, icons..."
value={term}
onChange={(event) => setTerm(event.target.value)}
className="pl-9"
autoFocus
/>
</div>
<Tabs value={assetType} onValueChange={(value) => setAssetType(value as AssetType)}>
<TabsList className="h-8">
<TabsTrigger value="photo" className="text-xs">
Photos
</TabsTrigger>
<TabsTrigger value="vector" className="text-xs">
Vectors
</TabsTrigger>
<TabsTrigger value="icon" className="text-xs">
Icons
</TabsTrigger>
</TabsList>
</Tabs>
</div>
<div
className="nowheel nodrag nopan flex-1 overflow-y-auto p-5"
onWheelCapture={(event) => event.stopPropagation()}
>
{isLoading ? (
<div className="grid grid-cols-4 gap-3">
{Array.from({ length: 16 }).map((_, index) => (
<div key={index} className="aspect-square animate-pulse rounded-lg bg-muted" />
))}
</div>
) : errorMessage ? (
<div className="flex flex-col items-center justify-center gap-2 py-16 text-center text-muted-foreground">
<AlertCircle className="h-8 w-8 text-destructive" />
<p className="text-sm text-foreground">Search failed</p>
<p className="max-w-md text-xs">{errorMessage}</p>
</div>
) : results.length === 0 ? (
<div className="flex flex-col items-center justify-center gap-2 py-16 text-center text-muted-foreground">
<Search className="h-8 w-8" />
<p className="text-sm">
{term.trim() ? "No results found" : "Type to search Freepik assets"}
</p>
</div>
) : (
<>
<div className="grid grid-cols-4 gap-3">
{results.map((asset) => (
<button
key={`${asset.assetType}-${asset.id}`}
onClick={() => void handleSelect(asset)}
className="group relative aspect-square overflow-hidden rounded-lg border-2 border-transparent bg-muted transition-all hover:border-primary focus:border-primary focus:outline-none"
title={asset.title}
type="button"
>
{/* eslint-disable-next-line @next/next/no-img-element */}
<img
src={asset.previewUrl}
alt={asset.title}
className="h-full w-full object-cover transition-transform duration-200 group-hover:scale-105"
loading="lazy"
/>
<div className="absolute inset-x-1 top-1 flex items-start justify-between gap-1 opacity-0 transition-opacity group-hover:opacity-100">
<Badge variant="secondary" className="h-4 px-1.5 py-0 text-[10px]">
{asset.assetType}
</Badge>
<Badge
variant={asset.license === "freemium" ? "outline" : "destructive"}
className="h-4 px-1.5 py-0 text-[10px]"
>
{asset.license}
</Badge>
</div>
<div className="absolute inset-0 bg-black/0 transition-colors group-hover:bg-black/20" />
</button>
))}
</div>
</>
)}
</div>
<div className="flex shrink-0 flex-col gap-3 border-t px-5 py-3">
{results.length > 0 ? (
<div className="flex items-center justify-center gap-2">
<Button
variant="outline"
size="sm"
onClick={handlePreviousPage}
disabled={isLoading || page <= 1}
>
Previous
</Button>
<span className="text-xs text-muted-foreground">
Page {page} of {totalPages}
</span>
<Button
variant="outline"
size="sm"
onClick={handleNextPage}
disabled={isLoading || page >= totalPages}
>
{isLoading ? (
<>
<Loader2 className="mr-2 h-3 w-3 animate-spin" />
Loading...
</>
) : (
"Next"
)}
</Button>
</div>
) : null}
<div className="flex items-center justify-between gap-3">
<p className="text-[11px] text-muted-foreground">
Assets by{" "}
<a
href="https://www.freepik.com"
target="_blank"
rel="noopener noreferrer"
className="underline transition-colors hover:text-foreground"
>
Freepik
</a>
. Freemium assets require attribution.
</p>
<span className="text-[11px] text-muted-foreground">
{results.length > 0 ? `${results.length} results on this page` : ""}
</span>
</div>
</div>
</div>
</div>
),
[
assetType,
errorMessage,
handleNextPage,
handlePreviousPage,
handleSelect,
isLoading,
onClose,
page,
results,
term,
totalPages,
],
);
if (!isMounted) {
return null;
}
return createPortal(modal, document.body);
}

View File

@@ -2,6 +2,7 @@
const nodeTemplates = [
{ type: "image", label: "Bild", icon: "🖼️", category: "Quelle" },
{ type: "asset", label: "Asset", icon: "🛍️", category: "Quelle" },
{ type: "text", label: "Text", icon: "📝", category: "Quelle" },
{ type: "prompt", label: "Prompt", icon: "✨", category: "Quelle" },
{ type: "note", label: "Notiz", icon: "📌", category: "Layout" },

View File

@@ -6,6 +6,7 @@ import GroupNode from "./nodes/group-node";
import FrameNode from "./nodes/frame-node";
import NoteNode from "./nodes/note-node";
import CompareNode from "./nodes/compare-node";
import AssetNode from "./nodes/asset-node";
/**
* Node-Type-Map für React Flow.
@@ -23,4 +24,5 @@ export const nodeTypes = {
frame: FrameNode,
note: NoteNode,
compare: CompareNode,
asset: AssetNode,
} as const;

View File

@@ -97,6 +97,7 @@ export default function AiImageNode({
const edges = getEdges();
const incomingEdges = edges.filter((e) => e.target === id);
let referenceStorageId: Id<"_storage"> | undefined;
let referenceImageUrl: string | undefined;
for (const edge of incomingEdges) {
const src = getNode(edge.source);
if (src?.type === "image") {
@@ -106,6 +107,10 @@ export default function AiImageNode({
break;
}
}
if (src?.type === "asset") {
const srcData = src.data as { previewUrl?: string; url?: string };
referenceImageUrl = srcData.url ?? srcData.previewUrl;
}
}
const modelId = nodeData.model ?? DEFAULT_MODEL_ID;
@@ -117,6 +122,7 @@ export default function AiImageNode({
nodeId: id as Id<"nodes">,
prompt,
referenceStorageId,
referenceImageUrl,
model: modelId,
aspectRatio: nodeData.aspectRatio ?? DEFAULT_ASPECT_RATIO,
}),

View File

@@ -0,0 +1,245 @@
"use client";
import {
useEffect,
useLayoutEffect,
useRef,
useState,
type MouseEvent,
} from "react";
import { Handle, Position, type Node, type NodeProps } from "@xyflow/react";
import { useMutation } from "convex/react";
import { ExternalLink, ImageIcon } from "lucide-react";
import BaseNodeWrapper from "./base-node-wrapper";
import {
AssetBrowserPanel,
type AssetBrowserSessionState,
} from "@/components/canvas/asset-browser-panel";
import { api } from "@/convex/_generated/api";
import type { Id } from "@/convex/_generated/dataModel";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { computeMediaNodeSize, resolveMediaAspectRatio } from "@/lib/canvas-utils";
type AssetNodeData = {
assetId?: number;
assetType?: "photo" | "vector" | "icon";
title?: string;
previewUrl?: string;
intrinsicWidth?: number;
intrinsicHeight?: number;
url?: string;
sourceUrl?: string;
license?: "freemium" | "premium";
authorName?: string;
orientation?: string;
canvasId?: string;
_status?: string;
_statusMessage?: string;
};
export type AssetNodeType = Node<AssetNodeData, "asset">;
export default function AssetNode({ id, data, selected, width, height }: NodeProps<AssetNodeType>) {
const [panelOpen, setPanelOpen] = useState(false);
const [handleTop, setHandleTop] = useState<number | undefined>(undefined);
const [browserState, setBrowserState] = useState<AssetBrowserSessionState>({
term: "",
assetType: "photo",
results: [],
page: 1,
totalPages: 1,
});
const resizeNode = useMutation(api.nodes.resize);
const contentRef = useRef<HTMLDivElement | null>(null);
const mediaRef = useRef<HTMLDivElement | null>(null);
const hasAsset = typeof data.assetId === "number";
const previewUrl = data.url ?? data.previewUrl;
const aspectRatio = resolveMediaAspectRatio(
data.intrinsicWidth,
data.intrinsicHeight,
data.orientation,
);
useEffect(() => {
if (!hasAsset) return;
const targetSize = computeMediaNodeSize("asset", {
intrinsicWidth: data.intrinsicWidth,
intrinsicHeight: data.intrinsicHeight,
orientation: data.orientation,
});
if (width === targetSize.width && height === targetSize.height) {
return;
}
void resizeNode({
nodeId: id as Id<"nodes">,
width: targetSize.width,
height: targetSize.height,
});
}, [
data.intrinsicHeight,
data.intrinsicWidth,
data.orientation,
hasAsset,
height,
id,
resizeNode,
width,
]);
useLayoutEffect(() => {
if (!hasAsset || !contentRef.current || !mediaRef.current) return;
const contentEl = contentRef.current;
const mediaEl = mediaRef.current;
let frameId: number | undefined;
const updateHandleTop = () => {
if (frameId !== undefined) {
cancelAnimationFrame(frameId);
}
frameId = requestAnimationFrame(() => {
const contentRect = contentEl.getBoundingClientRect();
const mediaRect = mediaEl.getBoundingClientRect();
const nextTop = mediaRect.top - contentRect.top + mediaRect.height / 2;
setHandleTop(nextTop);
});
};
updateHandleTop();
const observer = new ResizeObserver(updateHandleTop);
observer.observe(contentEl);
observer.observe(mediaEl);
return () => {
observer.disconnect();
if (frameId !== undefined) {
cancelAnimationFrame(frameId);
}
};
}, [aspectRatio, hasAsset]);
const stopNodeClickPropagation = (event: MouseEvent<HTMLAnchorElement>) => {
event.stopPropagation();
};
return (
<BaseNodeWrapper
nodeType="asset"
selected={selected}
status={data._status}
statusMessage={data._statusMessage}
className="overflow-hidden"
>
<Handle
type="target"
position={Position.Left}
className="h-3! w-3! border-2! border-background! bg-primary!"
style={{ top: hasAsset && handleTop ? `${handleTop}px` : "50%" }}
/>
<div ref={contentRef} className="w-full">
<div className="flex items-center justify-between border-b px-3 py-2">
<span className="text-xs font-medium tracking-wide text-muted-foreground uppercase">
Asset
</span>
<Button
size="sm"
variant={hasAsset ? "ghost" : "default"}
className="h-6 px-2 text-xs"
onClick={() => setPanelOpen(true)}
type="button"
>
{hasAsset ? "Change" : "Browse Assets"}
</Button>
</div>
{hasAsset && previewUrl ? (
<div className="flex flex-col gap-0">
<div
ref={mediaRef}
className="relative overflow-hidden bg-muted/30"
style={{ aspectRatio }}
>
{/* eslint-disable-next-line @next/next/no-img-element */}
<img
src={previewUrl}
alt={data.title ?? "Asset preview"}
className="h-full w-full object-contain"
draggable={false}
/>
<Badge variant="secondary" className="absolute top-2 left-2 h-4 py-0 text-[10px]">
{data.assetType ?? "asset"}
</Badge>
{data.license ? (
<Badge
variant={data.license === "freemium" ? "outline" : "destructive"}
className="absolute top-2 right-2 h-4 py-0 text-[10px]"
>
{data.license}
</Badge>
) : null}
</div>
<div className="flex flex-col gap-1 px-3 py-2">
<p className="truncate text-xs font-medium" title={data.title ?? "Untitled"}>
{data.title ?? "Untitled"}
</p>
<div className="flex items-center justify-between gap-2">
<span className="truncate text-[10px] text-muted-foreground">
by {data.authorName ?? "Freepik"}
</span>
{data.sourceUrl ? (
<a
href={data.sourceUrl}
target="_blank"
rel="noopener noreferrer"
className="flex shrink-0 items-center gap-0.5 text-[10px] text-muted-foreground transition-colors hover:text-foreground"
onClick={stopNodeClickPropagation}
>
freepik.com
<ExternalLink className="h-2.5 w-2.5" />
</a>
) : null}
</div>
</div>
</div>
) : (
<div className="flex flex-col items-center justify-center gap-3 px-4 py-8 text-center">
<div className="flex h-10 w-10 items-center justify-center rounded-lg bg-muted">
<ImageIcon className="h-5 w-5 text-muted-foreground" />
</div>
<div>
<p className="text-xs font-medium">No asset selected</p>
<p className="mt-0.5 text-[11px] text-muted-foreground">
Browse millions of Freepik resources
</p>
</div>
</div>
)}
</div>
{panelOpen && data.canvasId ? (
<AssetBrowserPanel
nodeId={id}
canvasId={data.canvasId}
initialState={browserState}
onStateChange={setBrowserState}
onClose={() => setPanelOpen(false)}
/>
) : null}
<Handle
type="source"
position={Position.Right}
className="h-3! w-3! border-2! border-background! bg-primary!"
style={{ top: hasAsset && handleTop ? `${handleTop}px` : "50%" }}
/>
</BaseNodeWrapper>
);
}

View File

@@ -3,6 +3,8 @@
import {
useState,
useCallback,
useEffect,
useLayoutEffect,
useRef,
type ChangeEvent,
type DragEvent,
@@ -11,10 +13,11 @@ import { Handle, Position, type NodeProps, type Node } from "@xyflow/react";
import { useMutation } from "convex/react";
import { api } from "@/convex/_generated/api";
import type { Id } from "@/convex/_generated/dataModel";
import Image from "next/image";
import NextImage from "next/image";
import BaseNodeWrapper from "./base-node-wrapper";
import { toast } from "@/lib/toast";
import { msg } from "@/lib/toast-messages";
import { computeMediaNodeSize, resolveMediaAspectRatio } from "@/lib/canvas-utils";
const ALLOWED_IMAGE_TYPES = new Set([
"image/png",
@@ -28,18 +31,113 @@ type ImageNodeData = {
url?: string;
filename?: string;
mimeType?: string;
width?: number;
height?: number;
_status?: string;
_statusMessage?: string;
};
export type ImageNode = Node<ImageNodeData, "image">;
export default function ImageNode({ id, data, selected }: NodeProps<ImageNode>) {
async function getImageDimensions(file: File): Promise<{ width: number; height: number }> {
return await new Promise((resolve, reject) => {
const objectUrl = URL.createObjectURL(file);
const image = new window.Image();
image.onload = () => {
const width = image.naturalWidth;
const height = image.naturalHeight;
URL.revokeObjectURL(objectUrl);
if (!width || !height) {
reject(new Error("Could not read image dimensions"));
return;
}
resolve({ width, height });
};
image.onerror = () => {
URL.revokeObjectURL(objectUrl);
reject(new Error("Could not decode image"));
};
image.src = objectUrl;
});
}
export default function ImageNode({
id,
data,
selected,
width,
height,
}: NodeProps<ImageNode>) {
const generateUploadUrl = useMutation(api.storage.generateUploadUrl);
const updateData = useMutation(api.nodes.updateData);
const resizeNode = useMutation(api.nodes.resize);
const fileInputRef = useRef<HTMLInputElement>(null);
const contentRef = useRef<HTMLDivElement | null>(null);
const mediaRef = useRef<HTMLDivElement | null>(null);
const [isUploading, setIsUploading] = useState(false);
const [isDragOver, setIsDragOver] = useState(false);
const [handleTop, setHandleTop] = useState<number | undefined>(undefined);
const aspectRatio = resolveMediaAspectRatio(data.width, data.height);
useEffect(() => {
if (typeof data.width !== "number" || typeof data.height !== "number") {
return;
}
const targetSize = computeMediaNodeSize("image", {
intrinsicWidth: data.width,
intrinsicHeight: data.height,
});
if (width === targetSize.width && height === targetSize.height) {
return;
}
void resizeNode({
nodeId: id as Id<"nodes">,
width: targetSize.width,
height: targetSize.height,
});
}, [data.height, data.width, height, id, resizeNode, width]);
useLayoutEffect(() => {
if (!contentRef.current || !mediaRef.current) return;
const contentEl = contentRef.current;
const mediaEl = mediaRef.current;
let frameId: number | undefined;
const updateHandleTop = () => {
if (frameId !== undefined) {
cancelAnimationFrame(frameId);
}
frameId = requestAnimationFrame(() => {
const contentRect = contentEl.getBoundingClientRect();
const mediaRect = mediaEl.getBoundingClientRect();
const nextTop = mediaRect.top - contentRect.top + mediaRect.height / 2;
setHandleTop(nextTop);
});
};
updateHandleTop();
const observer = new ResizeObserver(updateHandleTop);
observer.observe(contentEl);
observer.observe(mediaEl);
return () => {
observer.disconnect();
if (frameId !== undefined) {
cancelAnimationFrame(frameId);
}
};
}, [aspectRatio, data.filename, data.url, isDragOver, isUploading]);
const uploadFile = useCallback(
async (file: File) => {
@@ -61,6 +159,13 @@ export default function ImageNode({ id, data, selected }: NodeProps<ImageNode>)
setIsUploading(true);
try {
let dimensions: { width: number; height: number } | undefined;
try {
dimensions = await getImageDimensions(file);
} catch {
dimensions = undefined;
}
const uploadUrl = await generateUploadUrl();
const result = await fetch(uploadUrl, {
method: "POST",
@@ -80,8 +185,23 @@ export default function ImageNode({ id, data, selected }: NodeProps<ImageNode>)
storageId,
filename: file.name,
mimeType: file.type,
...(dimensions ? { width: dimensions.width, height: dimensions.height } : {}),
},
});
if (dimensions) {
const targetSize = computeMediaNodeSize("image", {
intrinsicWidth: dimensions.width,
intrinsicHeight: dimensions.height,
});
await resizeNode({
nodeId: id as Id<"nodes">,
width: targetSize.width,
height: targetSize.height,
});
}
toast.success(msg.canvas.imageUploaded.title);
} catch (err) {
console.error("Upload failed:", err);
@@ -93,7 +213,7 @@ export default function ImageNode({ id, data, selected }: NodeProps<ImageNode>)
setIsUploading(false);
}
},
[id, generateUploadUrl, updateData]
[id, generateUploadUrl, resizeNode, updateData]
);
const handleClick = useCallback(() => {
@@ -144,14 +264,20 @@ export default function ImageNode({ id, data, selected }: NodeProps<ImageNode>)
}, []);
return (
<BaseNodeWrapper nodeType="image" selected={selected} status={data._status}>
<BaseNodeWrapper
nodeType="image"
selected={selected}
status={data._status}
className="overflow-hidden"
>
<Handle
type="target"
position={Position.Left}
className="h-3! w-3! bg-primary! border-2! border-background!"
style={{ top: handleTop ? `${handleTop}px` : "50%" }}
/>
<div className="p-2">
<div ref={contentRef} className="p-2">
<div className="mb-1 flex items-center justify-between">
<div className="text-xs font-medium text-muted-foreground">🖼 Bild</div>
{data.url && (
@@ -164,48 +290,48 @@ export default function ImageNode({ id, data, selected }: NodeProps<ImageNode>)
)}
</div>
{isUploading ? (
<div className="flex h-36 w-56 items-center justify-center rounded-lg bg-muted">
<div className="flex flex-col items-center gap-2">
<div className="h-5 w-5 animate-spin rounded-full border-2 border-primary border-t-transparent" />
<span className="text-xs text-muted-foreground">Wird hochgeladen...</span>
<div ref={mediaRef} className="relative w-full overflow-hidden rounded-lg" style={{ aspectRatio }}>
{isUploading ? (
<div className="flex h-full w-full items-center justify-center bg-muted">
<div className="flex flex-col items-center gap-2">
<div className="h-5 w-5 animate-spin rounded-full border-2 border-primary border-t-transparent" />
<span className="text-xs text-muted-foreground">Wird hochgeladen...</span>
</div>
</div>
</div>
) : data.url ? (
<div className="relative h-36 w-56 overflow-hidden rounded-lg">
<Image
) : data.url ? (
<NextImage
src={data.url}
alt={data.filename ?? "Bild"}
fill
className="object-cover"
sizes="224px"
sizes="(max-width: 640px) 100vw, 260px"
draggable={false}
/>
</div>
) : (
<div
onClick={handleClick}
onDragOver={handleDragOver}
onDragLeave={handleDragLeave}
onDrop={handleDrop}
className={`
nodrag flex h-36 w-56 cursor-pointer flex-col items-center justify-center
rounded-lg border-2 border-dashed text-sm transition-colors
) : (
<div
onClick={handleClick}
onDragOver={handleDragOver}
onDragLeave={handleDragLeave}
onDrop={handleDrop}
className={`
nodrag flex w-full cursor-pointer flex-col items-center justify-center
h-full border-2 border-dashed text-sm transition-colors
${
isDragOver
? "border-primary bg-primary/5 text-primary"
: "text-muted-foreground hover:border-primary/50 hover:text-foreground"
}
`}
>
<span className="mb-1 text-lg">📁</span>
<span>Klicken oder hierhin ziehen</span>
<span className="mt-0.5 text-xs">PNG, JPG, WebP</span>
</div>
)}
>
<span className="mb-1 text-lg">📁</span>
<span>Klicken oder hierhin ziehen</span>
<span className="mt-0.5 text-xs">PNG, JPG, WebP</span>
</div>
)}
</div>
{data.filename && data.url && (
<p className="mt-1 max-w-[260px] truncate text-xs text-muted-foreground">
<p className="mt-1 truncate text-xs text-muted-foreground">
{data.filename}
</p>
)}
@@ -223,6 +349,7 @@ export default function ImageNode({ id, data, selected }: NodeProps<ImageNode>)
type="source"
position={Position.Right}
className="h-3! w-3! bg-primary! border-2! border-background!"
style={{ top: handleTop ? `${handleTop}px` : "50%" }}
/>
</BaseNodeWrapper>
);

View File

@@ -182,6 +182,7 @@ export default function PromptNode({
const incomingEdges = currentEdges.filter((e) => e.target === id);
let connectedTextPrompt: string | undefined;
let referenceStorageId: Id<"_storage"> | undefined;
let referenceImageUrl: string | undefined;
for (const edge of incomingEdges) {
const sourceNode = getNode(edge.source);
@@ -197,6 +198,10 @@ export default function PromptNode({
referenceStorageId = srcData.storageId as Id<"_storage">;
}
}
if (sourceNode?.type === "asset") {
const srcData = sourceNode.data as { previewUrl?: string; url?: string };
referenceImageUrl = srcData.url ?? srcData.previewUrl;
}
}
const promptToUse = (connectedTextPrompt ?? prompt).trim();
@@ -240,6 +245,7 @@ export default function PromptNode({
nodeId: aiNodeId,
prompt: promptToUse,
referenceStorageId,
referenceImageUrl,
model: DEFAULT_MODEL_ID,
aspectRatio,
}),

View File

@@ -14,6 +14,7 @@ import type * as canvases from "../canvases.js";
import type * as credits from "../credits.js";
import type * as edges from "../edges.js";
import type * as export_ from "../export.js";
import type * as freepik from "../freepik.js";
import type * as helpers from "../helpers.js";
import type * as http from "../http.js";
import type * as nodes from "../nodes.js";
@@ -34,6 +35,7 @@ declare const fullApi: ApiFromModules<{
credits: typeof credits;
edges: typeof edges;
export: typeof export_;
freepik: typeof freepik;
helpers: typeof helpers;
http: typeof http;
nodes: typeof nodes;

View File

@@ -162,6 +162,7 @@ export const generateImage = action({
nodeId: v.id("nodes"),
prompt: v.string(),
referenceStorageId: v.optional(v.id("_storage")),
referenceImageUrl: v.optional(v.string()),
model: v.optional(v.string()),
aspectRatio: v.optional(v.string()),
},
@@ -200,7 +201,7 @@ export const generateImage = action({
let retryCount = 0;
try {
let referenceImageUrl: string | undefined;
let referenceImageUrl = args.referenceImageUrl?.trim() || undefined;
if (args.referenceStorageId) {
referenceImageUrl =
(await ctx.storage.getUrl(args.referenceStorageId)) ?? undefined;

169
convex/freepik.ts Normal file
View File

@@ -0,0 +1,169 @@
"use node";
import { v } from "convex/values";
import { action } from "./_generated/server";
const FREEPIK_BASE = "https://api.freepik.com";
type AssetType = "photo" | "vector" | "icon";
interface FreepikResult {
id: number;
title: string;
assetType: AssetType;
previewUrl: string;
intrinsicWidth?: number;
intrinsicHeight?: number;
sourceUrl: string;
license: "freemium" | "premium";
authorName: string;
orientation?: string;
}
interface FreepikSearchResponse {
results: FreepikResult[];
totalPages: number;
currentPage: number;
total: number;
}
function parseSize(size?: string): { width?: number; height?: number } {
if (!size) return {};
const match = size.match(/^(\d+)x(\d+)$/i);
if (!match) return {};
const width = Number(match[1]);
const height = Number(match[2]);
if (!Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) {
return {};
}
return { width, height };
}
export const search = action({
args: {
term: v.string(),
assetType: v.union(v.literal("photo"), v.literal("vector"), v.literal("icon")),
page: v.optional(v.number()),
limit: v.optional(v.number()),
},
handler: async (_ctx, args): Promise<FreepikSearchResponse> => {
const apiKey = process.env.FREEPIK_API_KEY;
if (!apiKey) {
throw new Error("FREEPIK_API_KEY not set");
}
const page = args.page ?? 1;
const limit = args.limit ?? 20;
const params = new URLSearchParams({
term: args.term,
page: String(page),
order: "relevance",
"filters[license][freemium]": "1",
});
let endpoint = `${FREEPIK_BASE}/v1/resources`;
if (args.assetType === "icon") {
endpoint = `${FREEPIK_BASE}/v1/icons`;
params.set("per_page", String(limit));
} else {
params.set("limit", String(limit));
params.set(`filters[content_type][${args.assetType}]`, "1");
}
const res = await fetch(`${endpoint}?${params.toString()}`, {
headers: {
"x-freepik-api-key": apiKey,
Accept: "application/json",
},
});
if (!res.ok) {
throw new Error(`Freepik API error: ${res.status} ${res.statusText}`);
}
const json = (await res.json()) as {
data?: Array<{
id?: number;
title?: string;
url?: string;
image?: {
orientation?: string;
source?: {
url?: string;
size?: string;
};
};
licenses?: Array<{ type?: string }>;
author?: { name?: string };
}>;
meta?: {
total?: number;
current_page?: number;
last_page?: number;
total_pages?: number;
pagination?: {
total?: number;
current_page?: number;
last_page?: number;
total_pages?: number;
};
};
};
const data = json.data ?? [];
const pagination = json.meta?.pagination;
const results = data
.map((item): FreepikResult | null => {
if (!item.id || !item.image?.source?.url || !item.url) {
return null;
}
const license = item.licenses?.some((entry) => entry.type === "freemium")
? "freemium"
: "premium";
const parsedSize = parseSize(item.image?.source?.size);
return {
id: item.id,
title: item.title ?? "Untitled",
assetType: args.assetType,
previewUrl: item.image.source.url,
intrinsicWidth: parsedSize.width,
intrinsicHeight: parsedSize.height,
sourceUrl: item.url,
license,
authorName: item.author?.name ?? "Freepik",
orientation: item.image.orientation,
};
})
.filter((entry): entry is FreepikResult => entry !== null);
const totalPagesRaw =
pagination?.last_page ??
pagination?.total_pages ??
json.meta?.last_page ??
json.meta?.total_pages ??
1;
const currentPageRaw = pagination?.current_page ?? json.meta?.current_page ?? page;
const totalRaw = pagination?.total ?? json.meta?.total ?? results.length;
const totalPages =
Number.isFinite(totalPagesRaw) && totalPagesRaw > 0
? Math.floor(totalPagesRaw)
: 1;
const currentPage =
Number.isFinite(currentPageRaw) && currentPageRaw > 0
? Math.min(Math.floor(currentPageRaw), totalPages)
: page;
const total = Number.isFinite(totalRaw) && totalRaw >= 0 ? Math.floor(totalRaw) : results.length;
return {
results,
totalPages,
currentPage,
total,
};
},
});

View File

@@ -7,6 +7,9 @@ import type { FunctionReference, FunctionArgs, FunctionReturnType } from "convex
* Wrapper um `useQuery` der automatisch `"skip"` nutzt wenn der
* Convex-Auth-Token noch nicht bereit ist. Verhindert "Unauthenticated"-Fehler
* bei Queries die `requireAuth` nutzen.
* Convex-Queries sind reaktiv: Ergebnisse werden im Client-Cache gehalten und
* nur bei relevanten Datenänderungen aktualisiert (keine manuelle Polling-
* Schleife, z. B. alle 3000ms, notwendig).
*
* Nutzt nur `isAuthenticated` (nicht `isLoading`) als Guard — wenn ein
* `initialToken` vom SSR vorhanden ist, springt `isAuthenticated` sofort

View File

@@ -64,6 +64,7 @@ export const NODE_HANDLE_MAP: Record<
frame: { source: "frame-out", target: "frame-in" },
note: { source: undefined, target: undefined },
compare: { source: "compare-out", target: "left" },
asset: { source: undefined, target: undefined },
};
/**
@@ -86,4 +87,84 @@ export const NODE_DEFAULTS: Record<
},
note: { width: 208, height: 100, data: { content: "" } },
compare: { width: 500, height: 380, data: {} },
asset: { width: 260, height: 240, data: {} },
};
type MediaNodeKind = "asset" | "image";
const MEDIA_NODE_CONFIG: Record<
MediaNodeKind,
{
width: number;
chromeHeight: number;
minPreviewHeight: number;
maxPreviewHeight: number;
}
> = {
asset: {
width: 260,
chromeHeight: 88,
minPreviewHeight: 120,
maxPreviewHeight: 300,
},
image: {
width: 280,
chromeHeight: 52,
minPreviewHeight: 120,
maxPreviewHeight: 320,
},
};
function clamp(value: number, min: number, max: number): number {
return Math.max(min, Math.min(max, value));
}
function fallbackAspectRatio(orientation?: string): number {
if (orientation === "horizontal") return 4 / 3;
if (orientation === "vertical") return 3 / 4;
return 1;
}
export function resolveMediaAspectRatio(
intrinsicWidth?: number,
intrinsicHeight?: number,
orientation?: string,
): number {
if (
typeof intrinsicWidth === "number" &&
typeof intrinsicHeight === "number" &&
intrinsicWidth > 0 &&
intrinsicHeight > 0
) {
return intrinsicWidth / intrinsicHeight;
}
return fallbackAspectRatio(orientation);
}
export function computeMediaNodeSize(
kind: MediaNodeKind,
options?: {
intrinsicWidth?: number;
intrinsicHeight?: number;
orientation?: string;
},
): { width: number; height: number; previewHeight: number; aspectRatio: number } {
const config = MEDIA_NODE_CONFIG[kind];
const aspectRatio = resolveMediaAspectRatio(
options?.intrinsicWidth,
options?.intrinsicHeight,
options?.orientation,
);
const previewHeight = clamp(
Math.round(config.width / aspectRatio),
config.minPreviewHeight,
config.maxPreviewHeight,
);
return {
width: config.width,
height: previewHeight + config.chromeHeight,
previewHeight,
aspectRatio,
};
}