칸 격자
| 항목 | 값 |
|---|---|
| 상태 | 구현 |
요약
칸 격자(grid)는 구조 그림 안에 칸 단위로 나뉜 도형 하나를 그린다. 비트 필드, 배열, 스택 슬롯, 행렬처럼 칸의 폭과 순서가 뜻인 자료를 칸마다 글 하나로 적는다. 격자는 elkjs 배치에서 크기가 고정된 도형 하나이고, 칸 하나를 light로 밝히거나 선 끝으로 쓸 수 있다. 칸에서 나가는 선은 이웃 칸 글을 가리지 않고 행 사이 통로로 돌아 격자 밖으로 나간다.
동기
16비트 주소를 윗 10비트와 아랫 6비트로 나누는 그림은 두 필드의 폭이 10 대 6이어야 읽힌다. 상자 두 개로는 폭이 글 길이를 따라가 비율이 깨지고, 테이블은 열 이름과 타입을 적는 스키마라 값이 든 칸을 둘 수 없다. 배열의 칸 순서, 행렬의 빈 칸, 길게 늘어선 항목을 건너뛴 자리도 상자와 카드로는 적을 수 없어, 개발 문서에서 가장 자주 나오는 이 그림들을 그림 도구 밖에서 따로 그려야 했다.
예시
비트 필드의 10 대 6 폭
thinkflow
title "가상 주소를 VPN과 오프셋으로 나눈다"
grid va "가상 주소 (16비트)" cols=16 {
item vpn "VPN (10비트)" col=0 cols=10
item offset "오프셋 (6비트)" col=10 cols=6
}
grid pa "물리 주소 (16비트)" cols=16 {
item pfn "PFN (10비트)" col=0 cols=10
item offset "오프셋 (6비트)" col=10 cols=6
}
va -> pa "페이지 표 조회"
view graph down
scene "나누기" mode=static
light va.vpn va.offset
scene "바꾸기"
va -> pa time=800ms
light pa.pfn pa.offset
va와pa는 16칸 폭 격자이고,vpn은 10칸,offset은 6칸을 차지한다. 칸 폭은 10 대 6이다.va -> pa는 격자 전체를 잇는 선이다. 격자는 상자처럼 위아래로 놓인다.- 첫 단계에서 두 칸이 밝아지고, 둘째 단계에서 점이 선을 지난 뒤
pa의 두 칸이 밝아진다.
바깥 행 식별자와 안쪽 내용
열이 하나인 격자의 item은 key="Frame 0"처럼 행 식별자를 셀 왼쪽에 따로 둔다. 주소·페이지·프레임 번호와 저장 내용을 구분할 때 사용한다. 셀 본문과 연결점은 기존 item과 같으며 value ... on=ram.f0가 내용을 바꾸어도 바깥 식별자는 유지된다.
thinkflow
grid ram "물리 메모리" rows=2 {
item f0 "Page 1" key="Frame 0"
item f1 "빈 프레임" key="Frame 1" row=1
}
key는 cols=1인 격자의 item만 받으며 빈 글과 gap에는 사용할 수 없다. 글 폭과 줄 수로 바깥 영역을 재고 전체 도형 크기·글 상자·충돌 검사에 포함한다. 제목은 셀 묶음 위에 정렬한다. 왼쪽에서 들어오는 선은 식별자를 가리지 않도록 행 아래를 지나 셀에 닿는다. 색·글꼴·간격은 기존 격자 글과 공통 토큰을 사용한다.
칸을 합치고, 비우고, 글을 길게 쓰기
thinkflow
title "페이지 표 항목의 필드"
box mmu "MMU" "주소 변환"
grid pte "페이지 표 항목 (PTE)" rows=4 cols=6 {
item frame "프레임 번호" row=0 col=0 rows=2 cols=3
item valid "V" row=0 col=3
item dirty "D" row=0 col=4
item ref "R" row=0 col=5
item prot "권한 (읽기, 쓰기, 실행)" row=1 col=3 cols=3
item note "참조 비트는 CPU가 접근할 때 켜고, 운영체제가 주기적으로 지워 최근에 쓰지 않은 페이지를 교체 후보로 고른다" row=2 col=0 rows=2 cols=5
}
mmu -> pte "조회"
scene "상태 비트" mode=static
light pte.valid pte.dirty pte.ref
frame은 가로 3칸, 세로 2칸을 차지하는 합친 칸이다.note는 긴 한글 글이라 칸 안에서 줄을 바꾸고, 그 줄이 들어가도록 모든 행이 같이 높아진다.- 마지막 열의 아래 두 자리에는 칸이 없어 점선 테두리의 빈 칸으로 남는다.
칸에서 칸으로 잇기
thinkflow
title "가상 칸에서 페이지 표 행을 거쳐 물리 칸으로"
grid virt "가상 주소 공간" rows=3 {
item p0 "페이지 0" row=0
item p1 "페이지 1" row=1
item p2 "페이지 2" row=2
}
grid table "페이지 표" rows=3 cols=3 {
item hp "Page" row=0 col=0
item hf "Frame" row=0 col=1
item hg "Flags" row=0 col=2
item p1 "1" row=1 col=0
item f1 "7" row=1 col=1
item g1 "RW" row=1 col=2
item p2 "2" row=2 col=0
item f2 "3" row=2 col=1
item g2 "R" row=2 col=2
}
grid phys "물리 메모리" rows=4 {
item fr3 "프레임 3" row=0
gap skip "…" count=3 row=1
item fr7 "프레임 7" row=2
}
virt.p1 -> table.p1
virt.p2 -> table.p2
table.f1 -> phys.fr7
table.f2 -> phys.fr3
scene "조회"
virt.p1 -> table.p1 time=700ms
light table.f1
table.f1 -> phys.fr7 time=700ms
light phys.fr7
virt.p1처럼 칸을 선 끝으로 쓴다. 칸이 격자의 왼쪽 가장자리에 걸치면 칸에서 바로 나가고 들어온다(virt.p1에서table.p1로).- 표의 가운데 열
table.f1은 격자 안쪽 칸이라 그 아래 빈 줄(통로)로 내려가 격자 오른쪽으로 나간다. 통로는 행 사이를 벌린 빈 줄이라 이웃 칸 글을 가리지 않는다. - 이동은
칸 -> 칸으로 선을 고른다. 두 격자 사이 선이 하나뿐이면virt -> table로 줄여 쓸 수 있다.
상세 설계
문법
| 줄 | 뜻 |
|---|---|
grid id "제목" [rows=N] [cols=N] {, } |
격자. 구조 그림에서만 쓰고 그룹 안에도 둘 수 있다. 두 줄 사이에 칸을 둔다 |
item id "글" [row=N] [col=N] [rows=N] [cols=N] |
값이 든 칸 |
gap id "글" count=N [row=N] [col=N] [rows=N] [cols=N] |
생략한 칸. 글 뒤에 ×N을 붙여 그린다 |
light 격자 격자.칸 |
격자 전체나 칸 하나를 밝힌다. 칸은 item만 밝힌다 |
격자.칸 -> 도형 , 도형 -> 격자.칸, 격자.칸 -> 격자.칸 |
칸을 선 끝으로 쓴다. 같은 격자의 서로 다른 두 칸도 이을 수 있다(라벨 없음). 이동도 같은 이름으로 적는다 |
- 선택 사항의 값 형식과 판은 그림 문법의 문법 표가 정본이다.
rows,cols의 기본값은 1이고,row,col의 기본값은 0이다. row와col은 화면 좌표가 아니라 격자 안의 논리 인덱스다. 0부터 센다.- 칸 이름은 격자 안에서만 겹치지 않으면 된다. 다른 격자의 칸과 같은 이름을 써도 되고, 격자 밖에서는
격자.칸으로 부른다. 격자 이름은 다른 도형, 그룹 이름과 겹치지 않는다. - 오류: 크기가 0 이하이거나 정수가 아닌 값, 안전한 정수(2^53 - 1)를 넘는 값, 음수 인덱스, 인덱스와 크기의 합이 안전한 정수를 넘는 칸(끝 인덱스를 정확히 셀 수 없다), 격자 밖으로 나가는 칸, 겹치는 칸, 같은 칸 이름,
count없는gap, 칸 없는 격자, 닫지 않은 격자, 격자 밖의item과gap, 격자 안의 다른 문장은 줄 번호가 붙은 원본 오류다. grid,item,gap은 이름 자리에서 예약어가 아니다. 이 낱말을 도형, 그룹, 칸, 테이블 열 이름으로 쓴 원본은 그대로 읽힌다. 첫 낱말 자리에 오는grid만 격자 선언이다.gap은 선이나 이동의 끝이 될 수 없고 밝힐 수도 없다. 생략된 항목을 가리키려면item으로 꺼내 쓴다. 칸(a -> 격자.칸)과 격자 전체(a -> 격자) 모두 선 끝으로 쓸 수 있다.- 칸 선 끝의 오류: 없는 칸(가까운 이름을 제안),
gap, 점이 둘 이상인 이름, 같은 칸으로 가는 선, 라벨을 쓴 두 칸 선은 줄 번호가 붙은 원본 오류다. - 카드(
show)는 격자에 쓰지 않는다. 칸이 이미 격자의 내용이다.
크기
크기는 배치의 도형 크기 단계(2단계)에서 정하고, elkjs에는 그 사각형을 그대로 넘긴다.
- 칸 단위(가로, 세로)는 모든 행과 열에서 같다. 칸은 차지한 단위 수만큼 커져서, 합친 칸의 폭과 높이는 단위의 정수배다.
- 일반 격자의 가로 단위는 칸마다
(글 폭 + 안쪽 간격) / 차지한 열 수를 구해 필요한 폭을 계산한 뒤, 격자 전체가spacing.figure.node.max-width에 들어가는 선호 단위 폭과 비교해 작은 쪽을 쓴다. 글이 길면 칸 안에서 줄을 나눈다. 단위 폭은 올림하며spacing.figure.grid.cell과 제목을 담는 폭보다 좁아지지 않는다. 열이 많으면 최소 칸 크기를 지키기 위해 전체 폭이 선호 폭을 넘을 수 있다. - 한 행 전체를 빈 칸 없이 병합 필드만 채우고, 각 필드가 논리 열 둘 이상을 차지하면 비율형 필드 띠로 배치한다. 보이지 않는 논리 열마다 최소 폭을 예약하지 않고, 보이는 필드 각각의 최소 폭(
spacing.figure.grid.cell)과 제목을 지키면서spacing.figure.node.max-width를 선호 폭으로 쓴다. 필드 폭은 선언한cols에 비례하고 글자는 고정 크기로 줄을 나눈다. 단위 폭은 소수도 허용해 논리 비트 수가 커져도 빈 폭이 늘지 않는다. 개별 칸이나 빈 자리가 하나라도 있는 격자에는 이 규칙을 적용하지 않는다. - 칸 글은 칸 폭 안에서 줄을 나눈다. 세로 단위는 칸마다
(줄 수 × 줄 높이 + 안쪽 간격) / 차지한 행 수를 구해 가장 큰 값으로 정한다. 글이 긴 칸이 하나 있으면 모든 행이 그 높이로 같이 높아진다. 일부 칸만 늘려 비율을 깨뜨리지 않기 위해서다. - 격자는 칸 묶음의 위에 제목 줄을 두고, 틀과 칸 사이 간격은
spacing.3이다. - 칸이 없는 자리는 단위 하나짜리 빈 칸으로 그린다. 행과 열의 수에는 제품 상한이 없고, 빈 칸을 하나씩 만들지 않으므로 비용은 격자 크기가 아니라 선언한 칸 수에 비례한다(빈 칸 표현).
gap은 설명에서 일부를 생략하겠다는 뜻일 때만 쓰고, 렌더러가 큰 격자를gap으로 접지 않는다. - 행과 열의 개수는 안전한 양의 정수이고, 인덱스는 0 이상의 안전한 정수다(
Number.isSafeInteger). 격자의 폭과 높이가2^40px(약 1.1×10^12)를 넘으면 소수 첫째 자리까지 좌표를 정확히 쓸 수 없으므로 그 격자 줄의 오류다. 이 값은 행과 열의 상한이 아니라 좌표 정밀도의 한계이고, 칸 높이가 40px쯤이라 행이 수백억 개까지 들어간다.
칸의 값
value id "이름" on=격자.item from=값으로 칸의 고정 글 대신 바뀌는 값을 놓는다. ref, set, keep과 도착 시각은 카드 값과 같은 시간표를 사용한다. gap과 중복 바인딩은 선언 줄 오류다. 값의 모든 상태를 실제 글꼴로 재고 줄을 나눠 최대 너비·높이를 예약한다. 측정한 글 목록은 그림 검사와 이동 글 상자 회피에도 쓰며, SVG와 HTML은 같은 기간별 글 요소를 선택한다. 값이 없는 격자의 크기와 정적 글은 바꾸지 않는다.
배치
- 격자는
table과 같은 도형이다. elkjs는 내부 칸을 모르고, 선은 격자 테두리의 네 면 어디나 닿는다. 그룹 안에 둘 수 있다. - 칸 위치는 격자 왼쪽 위가 원점인 사각형으로 도형 크기와 함께 장면에 남는다(
scene.items[].cells). 빈 자리는 칸마다가 아니라 직사각형 구간으로 묶어empties에 남기고({ row0, row1, col0, col1, x, y, w, h }), 단위 칸 하나의 크기와 행 사이 통로 높이는unit에 남긴다. 그리는 코드와 글 상자 자리 계산이 같은 값을 쓴다. - 칸을 이은 선은 칸이 걸친 격자 면에서 바로 나가거나, 걸치지 않은 안쪽 칸이면 칸 아래 통로를 거쳐 격자 옆면으로 나간다. 통로가 있으면 행 사이가 벌어지고 칸 폭 비율은 그대로다. 면 고르기, 통로 크기, 줄 배정은 배치가 정본이다.
- 한 줄짜리 비트 띠는 칸이 위아래 면에 모두 걸쳐 세로 흐름에서는 위아래 면으로, 가로 흐름에서는 칸 아래 통로로 나간다.
그리기와 색
- 틀과 칸은
color.ui-card면과color.outline윤곽이고 글은color.ink다. 생략 칸(gap)은color.surface면에 점선 윤곽과color.ui-muted글이다. 빈 자리는 면 없이 점선 윤곽만 그린다(빈 칸 표현). - 밝힌 칸은
color.search-hover면(선택 행과 같다. 효과 한 벌의--fx-row를 HTML 재생기와 움직이는 SVG가 같이 읽는다, 배치)이고 윤곽은 이웃 칸과 같은 중립 구분선 그대로다. 선택 테두리를 따로 그리지 않아 칸 구분선과 선택이 겹쳐 두 겹이 되지 않는다. 칸이 밝아지고 꺼지는 것은 논리 경계에서 바로 바뀌고 CSS 전환을 걸지 않는다(재생). 파랑은 "지금 일어나는 것"만 뜻하므로 값의 크고 작음을 이 색으로 나타내지 않는다. - 이 짝들은 모두 대비 기준의 기존 짝(글자와 면, 경계와 면, 강조 그래픽과 면)이라 새 색 역할이 없다. 크기와 간격은 토큰
spacing.figure.grid.cell과 기존space.*뿐이다.
빈 칸 표현
빈 칸의 위치와 폭은 값이 든 칸만큼 그림의 뜻이므로 빈 칸을 없애거나 gap으로 바꾸지 않는다. 대신 빈 칸을 하나씩 만들지 않는다.
- 빈 자리 구간: 칸을 행 순서로 훑으며(sweep) 선언하지 않은 단위 칸을 직사각형 구간으로 묶는다. 칸이 시작하거나 끝나 빈 열 구간이 바뀔 때만 위 구간을 닫으므로 구간 수는 선언한 칸 수에 비례한다(칸 하나가 구간을 최대 셋으로 가른다). 행×열 크기의 배열을 만들지 않고, 칸 겹침 확인도 같은 쓸기라
O(c log c)다. 칸 이름은 격자마다Map으로 찾는다. - 그리기: 단위 칸 하나의 점선 윤곽을 담은 반복 무늬(
<pattern id="ge-번호">)를 한 번 정의하고, 모든 빈 구간을 이은 경로(<path class="grid-empty">) 하나를 그 무늬로 칠한다. 무늬 칸은 단위 칸에 통로 높이를 더한 크기라 행 사이 통로는 비어 있다. 윤곽은 칸 경계선을 굵기 절반만큼 비켜 무늬 칸 안에 온전히 넣고, 경로를 굵기 절반만큼 사방으로 넓혀 구간 바깥 경계선도 같은 굵기로 보인다. 그래서 선 굵기와 칸 자리는 칸마다 사각형을 그리던 때와 같고, 점선이 시작하는 자리만 칸 윗변과 왼쪽 변 시작으로 바뀐다. - 빈 자리 경로의 명령은 구간마다 다섯(
M h v h z)이고 예산이 센다. 하나의 경로로 합쳤다는 이유로 비용에서 빠지지 않는다.
예산
생성 비용을 실제로 늘리는 단위마다 이름 있는 예산이 있고, 그림 하나를 만드는 동안 모든 격자의 합계를 검사한다. 예산은 그림 문법의 budget-exceeded 진단으로 알리고 src/budget.js 한 곳에서 기본값, 검증, 초과 진단을 맡는다.
값이 연결된 칸은 시간표를 만든 뒤 장면별 값 묶음·갱신 면과 실제 표시 상태의 글 줄까지 다시 센다. 같은 글도 장면별로 별도 요소가 생기므로 각각 포함하며, 외부 행 식별자 글은 칸마다 한 번 센다.
| 이름 | 단위 | 기본 한도 |
|---|---|---|
grid-elements |
격자가 그리는 SVG 요소 수. 틀 사각형 1, 제목 글 줄마다 1, 칸마다 item 2(묶음, 사각형)와 gap 2에 칸 글 줄마다 1, 빈 자리가 있으면 3(무늬, 무늬 안 선, 경로). 글 줄은 그릴 때와 같은 줄 나눔(칸 폭에 따른 자동 줄 나눔)의 실제 결과다 |
500000 |
grid-path-commands |
빈 자리 경로의 명령 수(구간마다 5) | 1000000 |
chip-index |
이동 글 상자 계획 하나가 만드는 공간 색인의 칸 항목 수(도형과 글자 색인, 선과 틀까지 넣은 색인의 합). 색인을 만들기 전에 센다 | 2000000 |
- 검사는 크기와 배치를 정하기 전에 한다. 글 줄 수는 칸 글을 칸 폭에 맞춰 나눈 결과라 이 검사가 줄 나눔(칸 글 길이에 비례한 비용)을 먼저 하고 크기 계산이 그 결과를 다시 쓴다. 따라서 세는 요소 수는 실제로 그리는 수와 같고, 검사가 칸 수나 글 길이를 넘는 큰 할당을 하지 않으며, 초과하면 크기, 배치, 그리기에 들어가지 않고 파일도 쓰지 않는다. 시간표 항목은 격자 크기로 늘지 않는다(
light는 칸 하나를 가리키고 단계마다 줄 수만큼만 늘어난다)라 예산을 두지 않는다. - 초과 진단은 합계가 처음 한도를 넘은 격자의 줄에 붙고 필요한 양, 지금 한도, 올리는 방법을 적는다. 예:
this figure needs 502 SVG elements drawn by grids, over the budget grid-elements=100, and grid "g0" is where the total passes it. Raise it with --budget grid-elements=502 (the Action input budget: grid-elements=502), or shrink the grids. 넘는 예산마다 진단 하나이고code는budget-exceeded다. - 올리는 방법:
render,check,gallery,md가--budget 이름=값을 받고(여러 번 쓸 수 있다), GitHub Action은 입력budget(공백이나 쉼표로 나눈이름=값)을 같은 해석으로 넘긴다. 값은 양의 안전한 정수이고, 모르는 이름이나 틀린 값은 그림을 만들기 전에 사용법 오류(종료 2)다. - 기본 한도는 브라우저가 한 번에 그릴 수 있는 크기와 기본 Node 힙 안에 드는 값으로 정했다. 요소 500000은 빽빽한 316×316 격자(499282개)까지 한 그림으로 허용하고, 경로 명령 1000000은
gap칸 10만 개를 대각선 계단으로 놓은 입력(구간 20만 개, 명령 999990개)까지 허용한다. 일반 문서의 격자(수십~수백 칸)는 한도의 0.1% 아래다. 측정한 시간과 메모리는 이 문서에 적지 않고 GitHub 이슈 요약에 둔다. chip-index는 이동 글 상자 계획(재생)이 만드는 공간 색인의 크기를 막는다. 색인 크기는 칸 선언과 이동 수로 정해지고 논리 격자의 행×열과 무관하다(글 상자 계획의 공간 색인). 그래도 선언 수가 크면 색인이 커지므로, 이 예산은 색인을 만들기 전에 항목 수를 세어 한도를 넘으면budget-exceeded로 끝낸다. 진단 줄은 계획을 세운 이동의 줄이고, 필요한 항목 수와--budget chip-index=<N>을 알린다. 기본 한도 200만은 가장 큰 빽빽한 격자(grid-elements기본 한도 안의 316×316, 이동 글 하나, 25만 항목)의 여덟 배다.check-14의 흐름 점 한도(800)는 이 인터페이스로 옮기지 않았고 동작과 진단이 그대로다.- 이벤트 예산
events와chain(흐름 조건과 대기)도 같은 모듈과--budget을 쓰고, 이름은parseBudgetPair가 이 표와 함께 검사한다. 이 두 예산의 단위와 기본값은 재생이 정한다.
글 상자 계획의 공간 색인
이동 글 상자는 후보 자리마다 도형, 글자, 선, 틀과 겹치는지 재므로, 계획은 피할 사각형을 담은 공간 색인(src/chip-grid.js)으로 글 상자 둘레의 것만 잰다. 색인은 큰 사각형을 면적만큼의 칸으로 펼치지 않는다.
- 층별 격자: 칸 한 변이 64px인 층 0부터 한 층마다 4배씩 커지는 층이 있다. 사각형은 긴 쪽 변이 칸 한 변 이하인 가장 작은 층에 넣고, 그 층에서 걸치는 칸(최대 2×2) 항목만 만든다. 항목 수는 사각형 수의 네 배 이하이고 사각형의 크기와 논리 격자 면적에는 따르지 않는다. 격자 틀, 큰 합친 칸, 큰 빈 영역도 같다.
- 찾기: 글 상자 둘레의 칸을 층마다 찾아 사각형 번호를 겹치지 않게 오름차순으로 돌려준다. 후보 상자는 작아서 층마다 몇 칸만 본다. 닿지 않는 사각형이 섞일 수 있고, 실제 겹침은 호출한 쪽이 사각형마다 다시 잰다. 그래서 색인이 없던 때와 같은 사각형을 같은 순서로 재고 결과가 같다.
- 크기나 위치가 유한하지 않은 사각형은 칸에 넣지 않고 모든 질문의 후보로 낸다.
- 고정 행·열 제한은 없다. 칸 선언과 이동 수가 같으면 격자가 1010×1010이어도 색인 항목 수가 같다.
- 색인 항목은 만들기 전에 센다(
indexEntries). 두 색인(도형과 글자만, 선과 틀까지)의 합이chip-index를 넘으면 색인을 만들지 않고 끝낸다.
비용의 성질
- 희소 격자(
rows와cols만 크고 선언한 칸이 적은 격자)의 출력 크기와 처리 비용은 격자의 행×열이 아니라 선언한 칸 수에 따른다. 행×열 크기의 배열을 만들지 않기 때문이다. - 초과 검사는 선언을 읽은 뒤에 하므로 메모리의 하한은 선언한 칸 수에 비례한 입력 읽기 비용이다.
- 이동 글 상자 계획의 비용도 칸 선언과 이동 수에 따르고 논리 격자 면적에 따르지 않는다(글 상자 계획의 공간 색인).
- 측정한 시간과 메모리는 이 문서가 아니라 GitHub 이슈 요약에 둔다.
시간 흐름
light 격자.칸은 도형의light와 같은 박자 규칙이다. 한 장면 안에서 밝힌 칸은 남고 다음 장면이 시작하면 꺼진다. 시간표의partsOn에격자.칸이름으로 들어가고, HTML 재생기와 움직이는 SVG가 같은 값을 읽는다.light 격자는 격자 틀을 밝히고 칸은 밝히지 않는다. 칸의light도 틀을 밝히지 않는다.- 멈춘 SVG는 고른 장면의 마지막 모습이라 그 장면이 밝힌 칸(
partsOn)이 남고 점과 펄스는 없다. 다음 장면이 밝힌 칸은 보이지 않는다.
요구사항
시험은 공개 진입점으로 계약을 확인하고, 격자만의 계산(구간 계산, 공간 색인)은 공개 출력의 칸 위치와 오류로 본다. 칸의 모양처럼 공통 부품이 소유한 것은 격자 시험이 다시 보지 않는다. 아래 표에서 시험 칸이 "검증 요구사항, 미완료"인 항목은 이 계약을 직접 확인하는 자동 시험이 아직 없다는 뜻이다.
| 요구사항 | 검증 계획 |
|---|---|
| 칸의 너비와 높이는 차지한 칸 수에 비례한다(10 대 6 비트 필드, 합친 칸). 칸이 없는 자리는 빈 칸이고, 칸끼리 겹치지 않으며 모두 격자 안에 있다. | test/cards.test.js(S3) |
| 글이 긴 칸은 칸 안에서 줄을 바꾸고 모든 행의 높이가 같다. | 검증 요구사항, 미완료 |
| 격자는 구조 그림에서 크기가 고정된 도형 하나로 배치되고, 선은 격자 테두리에 닿는다. | 검증 요구사항, 미완료 |
| 칸 자리와 선택 사항을 어긴 원본, 격자 밖 칸, 틀린 칸 연결, 밝힐 수 없는 칸을 줄 번호와 함께 알린다. | test/kinds.test.js(K-grid), test/cards.test.js(S2) |
grid, item, gap을 쓴 원본이 오류 없이 읽힌다. |
test/examples.test.js(memory, stack, pointer 예제) |
| 문법 표에 모든 낱말과 선택 사항이 있고 문서의 표가 문법 표에서 만든 표와 같다. | npm run grammar가 문서의 표를 다시 쓴다. 어긋남을 자동으로 알리는 시험은 확인되지 않았다(검증 요구사항, 미완료) |
칸 light는 도형 light와 같은 박자 규칙이다. |
검증 요구사항, 미완료 |
| 칸에서 칸으로 가는 선이 칸 테두리에서 나가고 들어오며, 안쪽 칸으로 가는 선도 이웃 칸을 지나지 않는다. | test/kinds.test.js(K-grid)는 칸 연결 규칙만 본다. 선의 기하는 그림 검사 3번(칸), 4번(칸 테두리)이 strict 빌드에서 같은 규칙을 지킨다 |
| 합친 칸, 비트 띠, 같은 면에서 나가는 여러 선, 한 격자의 두 칸을 잇는 선이 섞여도 오류가 없다. | npm run fuzz(구조 그림에 칸 선 끝이 섞인다). 배치의 요구사항 표와 같은 명령 |
| 칸 면, 글, 윤곽은 모든 면에서 대비 기준을 넘는다. | 검증 요구사항, 미완료. 화면 값은 npm run check가 토큰 수준에서만 지킨다 |
| 선언 수가 같으면 논리 격자가 커져도 출력과 빈 구간 수가 같다(행×열에 비례하지 않는다). | 검증 요구사항, 미완료 |
예산은 모든 격자의 합계를 크기를 정하기 전에 검사하고, 한도와 같은 양은 통과하며, 초과는 필요한 양과 조정 방법을 알린다. --budget과 Action 입력 budget이 같은 해석이고, 잘못된 값은 만들기 전에 끝나고, 초과는 파일을 쓰지 않는다. |
검증 요구사항, 미완료 |
| 좌표 범위와 인덱스 합을 넘는 입력은 격자 줄의 오류이고 중단하지 않는다. | 검증 요구사항, 미완료 |
이동 글을 붙인 희소 격자의 공간 색인 삽입 수가 논리 격자 면적과 무관하고, 색인 예산(chip-index)을 넘으면 색인을 만들지 않고 budget-exceeded로 끝난다. 색인으로 구한 글 상자 후보가 색인 없이 구한 결과와 같다. |
검증 요구사항, 미완료. 빌드 시간은 npm run perf(로컬 전용)가 기준 파일과 견주지만 기준 파일이 아직 없어 지금은 비교하지 않는다(깨끗한 커밋에서 --write로 만든다) |
| 올바른 무작위 구조 그림(칸 격자가 섞인)이 배치 오류나 그림 검사 오류가 되지 않는다. | npm run fuzz(구조 그림의 4분의 1이 칸 격자를 담는다). 배치의 요구사항 표와 같은 명령 |
단점
- 칸 단위가 모든 행과 열에서 같아서, 폭이 서로 다른 열이나 높이가 서로 다른 행은 쓸 수 없다. 글이 긴 칸 하나가 모든 행을 높인다.
- 칸 안에는 글만 둔다. 칸 안 도형, 칸의 색 구분, 수치 농도는 없다.
- 칸 선 끝이 안쪽 칸으로 돌아야 하면 행 사이가 벌어져 격자가 높아진다. 한 통로에 선이 많으면
spacing.2-5씩 더 벌어진다. - 선이 칸 면에서 나가는 자리는 칸 폭을 고르게 나눈 곳이라 직접 고를 수 없다. 면 지정(
from-side)은 없다. - 빈 자리의 점선은 칸 윗변과 왼쪽 변부터 시작해 칸마다 사각형을 그리던 때와 점이 찍히는 자리가 조금 다르다. 선 굵기와 칸 자리는 같다.
- 칸을 많이 선언하면 칸마다 SVG 요소를 그리므로 빽빽한 격자는 선언한 칸 수에 비례한 크기가 된다. 기본 예산(요소 50만 개)을 넘으면 오류이고
--budget으로 올린다. 폭이 넘치면 그림 검사 10번이 경고한다.
페이징 주소 변환
examples/memory-address.thinkflow는 기존 grid, 병합 칸, 칸 -> 칸, view graph right, scene, light만 조합한다. width wide는 가로 순서를 위한 공통 캔버스 선택이다. VPN과 PFN은 5칸, 오프셋은 3칸을 차지하므로 주소 띠의 비율은 5:3이다. 페이지 표의 VPN은 행 인덱스이며, 왼쪽 조회 칸과 오른쪽 PFN 칸을 직접 연결해 행 사이 통로를 만들지 않는다. 모든 행은 이어지고 선택한 행의 칸을 함께 밝힌다.
가로 배치에서 서로 다른 한 행 격자의 같은 비율을 차지하는 오른쪽 끝 필드끼리 연결하면 두 필드의 아랫면을 연결점으로 쓴다. 필드 이름이나 예제 이름은 검사하지 않는다. 실제 경로는 ELK가 다른 도형을 피하도록 만들며 경로 점을 덮어쓰지 않는다. 좁은 배치로 방향이 바뀌면 기존 세로 연결점 규칙을 사용하고 사건 시각은 재배치 계약을 따른다.
이 예제는 단일 단계 페이지 표, 8바이트 페이지, 가상·물리 주소 각각 8비트인 교육용 모형이다. 75 = 9 × 8 + 3에서 VPN 9가 PFN 4에 대응하므로 결과는 35 = 4 × 8 + 3이다. TLB·다단계 표·권한 실패는 생략하며 모든 운영체제의 구현을 대표하지 않는다.
미해결 질문
- 칸 선언이 많은 격자는
item마다 묶음과 사각형 요소를 그린다. 칸 선언 자체를 구간이나 반복으로 줄여 적는 문법은 아직 없다.
데이터 구조와 과정
격자의 제목은 칸 묶음 위에 놓이며, 면과 선택 윤곽은 칸 묶음 자체를 감싼다. 제목까지 감싸는 외곽 카드와 내부 격자라는 이중 테두리를 만들지 않는다. 칸 연결·밝힘·좁은 배치는 기존 계약을 유지한다.
memory: 가상 페이지, 페이지 표의 VPN 인덱스·상주 여부·PFN, 물리 프레임의 대응과 접근 과정.memory-fault: 유효한 접근 중 저장장치 읽기가 필요한 페이지 부재를 다룬다. 빈 프레임 적재, 페이지 표 갱신, 명령 재시도를 번호로 연결한다. 격자에는 전후 관계를 표시하고show와value로 실제 진행 상태를 갱신한다. 모든 페이지 부재가 디스크 읽기를 요구한다는 뜻이 아니다. Linux 페이지 표 설명을 따른 교육용 축약이다.sql-join: orders.user_id와 users.id의 일치, 결과 행의 대응을 셀 연결과 장면으로 나타낸다. 결과 격자는 처음부터 보이고 순차 강조로 대응을 설명한다. 행 삽입 애니메이션이나 SQL 실행기가 아니며, 특정 물리 실행계획을 주장하지 않는다. PostgreSQL SELECT의 INNER JOIN 의미를 예시 데이터로 표현한다.
기존 grid, item, gap, 셀 연결, scene, light, show, value, set을 조합하며 메모리·SQL 전용 문법이나 예제별 CSS는 없다.