# 엣지와 레이아웃

엣지는 노드 사이의 관계를 설명합니다. 레이아웃 블록은 좌표나 드로잉 원시 요소를 노출하지 않고 소량의 배치 의도를 표현합니다.

## 엣지 방향

엣지는 서로 다른 두 노드를 연결합니다. 전방 참조는 유효하지만 self-edge와 그룹 endpoint는 유효하지 않습니다.

| 연산자 | 의미                                        |
| ------ | ------------------------------------------- |
| `->`   | 왼쪽 노드에서 오른쪽 노드로 향하는 관계     |
| `<->`  | 양방향 대칭인 하나의 관계                   |
| `--`   | 방향이 없거나 의도적으로 지정하지 않은 연관 |

`<->`는 독립적으로 라벨을 붙일 수 있는 두 엣지의 축약형이 아닙니다.

## 엣지 종류와 라벨

선택적 라벨은 프로토콜, 이벤트, 명령, 데이터셋, 목적을 나타내며 1~40 Unicode scalar입니다. 선택적 `kind`는 라벨과 별개로 관계를 설명하고 기본값은 `flow`입니다.

| Kind         | 의도한 의미                       |
| ------------ | --------------------------------- |
| `flow`       | 일반 runtime 또는 conceptual flow |
| `request`    | 동기 요청 또는 호출               |
| `event`      | 비동기 메시지 또는 이벤트 전달    |
| `data`       | 데이터 이동, 복제, 읽기, 쓰기     |
| `dependency` | 빌드, 배포, 운영 의존성           |

```stack
stack 1.0

diagram "Relationships" {
  node web "Web app" {
    kind client
  }

  node api "API"
  node queue "Events" {
    kind queue
  }

  edge web -> api "HTTPS" {
    kind request
  }

  edge api -> queue "OrderPlaced" {
    kind event
  }
}
```

서로 다른 관계를 표현한다면 같은 노드 쌍에 여러 엣지를 둘 수 있습니다. endpoint, 연산자, 라벨, 유효 kind가 모두 같은 정확한 중복은 유효하지 않습니다. `<->`와 `--` 중복 비교에서는 endpoint 순서를 무시합니다.

## 레이아웃 스코프

다이어그램이나 그룹에는 하나의 `layout` 블록을 둘 수 있습니다. 그룹 블록은 직접 자식만, 다이어그램 블록은 다이어그램의 직접 자식만 영향을 줍니다. `rank`와 `order` 참조는 같은 스코프의 서로 다른 직접 자식을 최소 두 개 지정해야 합니다.

레이아웃에서 직접 자식 그룹은 하나의 항목입니다. 서로 다른 그룹의 하위 노드 연결은 직접 자식 항목 사이 연결이 되므로 그룹이 엣지 endpoint가 아니어도 상위 레이아웃으로 그룹을 배치할 수 있습니다.

## Direction, rank, order

```stack
layout {
  direction right
  rank same [web, worker]
  order [web, worker, database]
}
```

- `direction right`는 왼쪽에서 오른쪽, `direction down`은 위에서 아래 진행을 선호합니다. 강한 힌트지만 모든 엣지의 기하 방향을 보장하지 않으며 중첩 그룹에 상속되지 않습니다.
- `rank same [a, b]`는 나열된 직접 자식을 같은 레이아웃 rank에 두는 제약입니다. 한 스코프에서 같은 자식을 두 same-rank 문장에 넣을 수 없습니다.
- `order [a, b]`는 상대 순서 힌트입니다. 오른쪽 방향에서는 위에서 아래, 아래 방향에서는 왼쪽에서 오른쪽, 자동 레이아웃에서는 선택한 cross-axis를 따릅니다. 다른 자식은 생략할 수 있습니다.

렌더러는 포함, same-rank 제약, 가독성, 출력 경계를 지키기 위해 `order`를 벗어날 수 있습니다. 진단을 지원하는 도구는 이때 `STK4001`을 내야 합니다.

## 렌더러가 결정하는 것

Stack에는 좌표, 크기, 포트, 경로, 색상, 폰트, 줄바꿈, z-index가 없습니다. 렌더러는 겹침을 막고 포함과 방향을 보존하며 라벨을 읽기 쉽게 유지하고 노드 내부를 피해 엣지를 배치하며 의미 내용을 자르지 않고 캔버스를 확장합니다.
