{
  "type": "dfd",
  "font": "Pretendard",
  "bg": "#ffffff",
  "nodes": [
    {
      "id": "n0",
      "k": "rect",
      "x": 40,
      "y": 155,
      "w": 130,
      "h": 46,
      "label": "PC (송신)"
    },
    {
      "id": "n1",
      "k": "circle",
      "x": 270,
      "y": 130,
      "w": 100,
      "h": 100,
      "label": "P1\n청크 수신"
    },
    {
      "id": "n2",
      "k": "circle",
      "x": 490,
      "y": 130,
      "w": 100,
      "h": 100,
      "label": "P2\nFlash\n프로그램"
    },
    {
      "id": "n3",
      "k": "circle",
      "x": 710,
      "y": 130,
      "w": 100,
      "h": 100,
      "label": "P3\n장벽 확인\n검증 CRC"
    },
    {
      "id": "n4",
      "k": "circle",
      "x": 710,
      "y": 420,
      "w": 100,
      "h": 100,
      "label": "P4\n블록 읽기"
    },
    {
      "id": "n5",
      "k": "circle",
      "x": 490,
      "y": 420,
      "w": 100,
      "h": 100,
      "label": "P5\nGray 변환"
    },
    {
      "id": "n6",
      "k": "circle",
      "x": 270,
      "y": 420,
      "w": 100,
      "h": 100,
      "label": "P6\n송신"
    },
    {
      "id": "n7",
      "k": "rect",
      "x": 40,
      "y": 447,
      "w": 130,
      "h": 46,
      "label": "PC (수신)"
    },
    {
      "id": "n8",
      "k": "store",
      "x": 250,
      "y": 40,
      "w": 180,
      "h": 30,
      "label": "D1 | RAM 버퍼 ×3"
    },
    {
      "id": "n9",
      "k": "store",
      "x": 580,
      "y": 300,
      "w": 170,
      "h": 30,
      "label": "D2 | W25Q32JV (4 MiB)"
    },
    {
      "id": "n10",
      "k": "store",
      "x": 400,
      "y": 580,
      "w": 200,
      "h": 30,
      "label": "D3 | Gray 헤더·팔레트"
    },
    {
      "id": "n11",
      "k": "text",
      "x": 850,
      "y": 430,
      "w": 270,
      "h": 44,
      "fs": 11,
      "label": "실선 = 데이터 흐름\n점선 = 제어 · 이벤트 흐름"
    },
    {
      "id": "n12",
      "k": "note",
      "x": 850,
      "y": 150,
      "w": 270,
      "h": 86,
      "label": "장벽(P3) 통과 전에는\nP4 읽기 경로가 열리지 않는다\nD2 → P4 흐름은 T3 이후만 활성"
    }
  ],
  "edges": [
    {
      "id": "e0",
      "from": "n0",
      "to": "n1",
      "t": "flow",
      "label": "청크 4096 B"
    },
    {
      "id": "e1",
      "from": "n1",
      "to": "n8",
      "t": "flow",
      "label": "수신 버퍼 기록"
    },
    {
      "id": "e2",
      "from": "n8",
      "to": "n2",
      "t": "flow",
      "label": "버퍼 소유권 이관"
    },
    {
      "id": "e3",
      "from": "n1",
      "to": "n2",
      "t": "ctrl",
      "label": "버퍼 FULL 이벤트"
    },
    {
      "id": "e4",
      "from": "n2",
      "to": "n9",
      "t": "flow",
      "label": "페이지 ≤256 B"
    },
    {
      "id": "e5",
      "from": "n2",
      "to": "n3",
      "t": "flow",
      "label": "저장 완료 WIP=0"
    },
    {
      "id": "e6",
      "from": "n9",
      "to": "n3",
      "t": "flow",
      "label": "검증 재독출 CRC"
    },
    {
      "id": "e7",
      "from": "n3",
      "to": "n4",
      "t": "flow",
      "label": "장벽 통과 · 읽기 시작",
      "lbx": 75
    },
    {
      "id": "e8",
      "from": "n9",
      "to": "n4",
      "t": "flow",
      "label": "행 블록 (3072 B 배수)",
      "lbx": -18
    },
    {
      "id": "e9",
      "from": "n4",
      "to": "n5",
      "t": "flow",
      "label": "픽셀 행 3072 B"
    },
    {
      "id": "e10",
      "from": "n5",
      "to": "n6",
      "t": "flow",
      "label": "gray_row 3072 B"
    },
    {
      "id": "e11",
      "from": "n6",
      "to": "n7",
      "t": "flow",
      "label": "Gray BMP\n3,145,782 B"
    },
    {
      "id": "e12",
      "from": "n5",
      "to": "n10",
      "t": "flow",
      "label": "헤더·팔레트 기록"
    },
    {
      "id": "e13",
      "from": "n10",
      "to": "n6",
      "t": "flow",
      "label": "BMP 헤더 54 B",
      "lbx": -10
    },
    {
      "id": "e14",
      "from": "n2",
      "to": "n0",
      "t": "ctrl",
      "label": "ACK / credit 반환",
      "route": "elbow"
    }
  ]
}
