{#if treeData.nodes.length > 0} {@const nodeSize = TREE_CONFIG.nodeSize} {@const iconSize = TREE_CONFIG.iconSize} {@const svgWidth = Math.max(treeData.width, TREE_CONFIG.minWidth)} {@const svgHeight = Math.max(treeData.height, TREE_CONFIG.minHeight)}
{#each treeData.nodes as node} {#if node.parentX !== undefined && node.parentY !== undefined} {@const parentNode = treeData.nodes.find(n => n.x === node.parentX && n.y === node.parentY)} {@const isMultiPersonaResponse = node.message.from === MessageRole.Assistant && node.message.personaResponses && node.message.personaResponses.length > 1} {@const parentIsUser = parentNode?.message.from === MessageRole.User} {#if parentIsUser && isMultiPersonaResponse && node.message.personaResponses} {@const personaCount = node.message.personaResponses.length} {@const spacing = TREE_CONFIG.spacing} {@const totalWidth = personaCount * iconSize + (personaCount - 1) * spacing} {@const startOffset = (node.width - totalWidth) / 2} {@const leftmostX = node.x + startOffset + iconSize / 2} {@const rightmostX = leftmostX + (personaCount - 1) * (iconSize + spacing)} {@const childCenterX = node.x + node.width / 2} {@const parentBottom = node.parentY + nodeSize} {@const gap = node.y - parentBottom} {@const junctionY = parentBottom + gap * 0.5} {@const parentWidth = parentNode?.width || nodeSize} {@const parentCenterX = node.parentX + parentWidth / 2} {#each node.message.personaResponses as persona, personaIndex} {@const dropX = leftmostX + personaIndex * (iconSize + spacing)} {/each} {:else} {@const parentWidth = parentNode?.width || nodeSize} {@const parentCenterX = node.parentX + parentWidth / 2} {@const spacing = TREE_CONFIG.spacing} {@const parentIsMultiPersona = parentNode?.message.from === MessageRole.Assistant && parentNode?.message.personaResponses && parentNode.message.personaResponses.length > 1} {@const branchedFromPersonaId = node.message.branchedFrom?.personaId} {@const targetPersonaIndex = (parentIsMultiPersona && branchedFromPersonaId && parentNode?.message.personaResponses) ? parentNode.message.personaResponses.findIndex(p => p.personaId === branchedFromPersonaId) : -1} {@const parentPersonaCount = parentNode?.message.personaResponses?.length || 0} {@const parentTotalWidth = (parentPersonaCount > 0) ? parentPersonaCount * iconSize + (parentPersonaCount - 1) * spacing : 0} {@const parentStartOffset = (parentWidth - parentTotalWidth) / 2} {@const x1 = (targetPersonaIndex !== -1) ? (node.parentX + parentStartOffset + iconSize / 2) + targetPersonaIndex * (iconSize + spacing) : parentCenterX} {@const y1 = node.parentY + nodeSize} {@const x2 = node.x + nodeSize / 2} {@const y2 = node.y} {@const controlOffset = Math.abs(y2 - y1) * 0.3} {/if} {/if} {/each} {#each treeData.nodes as node} {@const cx = node.x + node.width / 2} {@const cy = node.y + nodeSize / 2} {#if node.message.from === MessageRole.User} onNodeClick(node.message.id)} onkeydown={(e) => e.key === 'Enter' && onNodeClick(node.message.id)} >
{:else if node.message.personaResponses && node.message.personaResponses.length > 0} {@const personaCount = node.message.personaResponses.length} {@const spacing = TREE_CONFIG.spacing} {#if personaCount === 1} onNodeClick(node.message.id, node.message.personaResponses![0].personaId)} onkeydown={(e) => e.key === 'Enter' && onNodeClick(node.message.id, node.message.personaResponses![0].personaId)} >
{:else} {@const totalWidth = personaCount * iconSize + (personaCount - 1) * spacing} {@const startOffset = (node.width - totalWidth) / 2} {@const startX = node.x + startOffset + iconSize / 2} {#each node.message.personaResponses as response, i} {@const iconX = startX + i * (iconSize + spacing)} onNodeClick(node.message.id, response.personaId)} onkeydown={(e) => e.key === 'Enter' && onNodeClick(node.message.id, response.personaId)} >
{/each} {/if} {:else} onNodeClick(node.message.id)} onkeydown={(e) => e.key === 'Enter' && onNodeClick(node.message.id)} >
{/if} {/each}
{/if}