ESP32-S3 Bench Guide
ESP32-S3 N16R8 bench guide: live pinout, lessons, simulators and the bench log.
같은 해 한국·중국·일본과 세계에서는 무슨 일이 있었을까? 왕조와 사건을 한 시간축에 나란히 놓고 확대해 보는 역사 연표. 출처를 확인한 항목은 공공 자료 링크를 함께 보여 줍니다.
Translation pending
EducationHTML · JavaScriptGitHub @shiroleestudioOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗거의 모든 것의 타임라인 — 한국사·중국사·일본사와 주제사를 한 시간축에 나란히 놓고 확대해 보는 역사 연표. (예전 이름: 빅 히스토리 연표) 이름·주소·설명은
site.json한 곳에서 바꿉니다.
왕조·국가사와 주제사를 한 장의 거대한 그림판에서 나란히 비교하는 역사 연표입니다. 아기 토끼 시로(shirolee studio)가 시대를 깡충 건너는 테마입니다. 기본은 연한 종이(라이트), 설정에서 밤하늘(다크)이나 시스템 따라가기를 고를 수 있습니다. 서버도 데이터베이스도 없는 정적 웹앱이라 인터넷 없이도 동작하고, PWA(홈 화면에 추가)나 Capacitor(iOS/Android)로 그대로 확장할 수 있습니다.
art/*.svg, 토끼들이 그 시대 안에서 논다 · 명화 오마주 포함)가 교차 페이드로 깔립니다.현재 데이터: 17개 카테고리 / 459개 항목 (모두 status: draft — 검토 전 초안입니다)
⚠️ 내용 신뢰도: 459개 항목은 전부 검토 전 초안이고, 공인 자료로 연도를 확인해 출처를 단 것은 133개입니다(한국사 51·중국사 16·일본사 23·세계사 1·경제·건축·동양 칸 42). 4장 내용의 출처와 신뢰도 를 꼭 읽어 주세요.
index.html 을 브라우저로 열면 끝입니다. (data/bundle.js 를 대신 읽습니다. 아래 참고)
npm run serve # npx serve -l 5173 . → http://localhost:5173
# 또는 Node 없이
python3 -m http.server 5173
왜 두 가지인가요? 브라우저는
file://로 연 페이지가fetch()로 옆의 JSON 파일을 읽는 것을 막습니다. 그래서 JSON 원본을 그대로 담은 사본data/bundle.js를 함께 두고,file://일 때는 자동으로 그쪽을 읽습니다. JSON 을 고쳤다면npm run build를 한 번 실행해서 사본을 갱신해 주세요. (로컬 서버로만 쓸 거라면 없어도 됩니다.)
npm run validate # 스키마 + 교차 검사 (오류가 있으면 종료 코드 1)
npm run fix # era_note 같은 자동 채움 가능한 항목을 채운 뒤 재검증
npm run build # validate + 버전 스탬프 + data/bundle.js 재생성
코드나 데이터를 고쳤으면 배포 전에 반드시 npm run build 를 돌리세요.
scripts/stamp.js 가 css/js 참조에 ?v=<해시> 를 붙이고 sw.js 의 캐시 이름을
같은 해시로 맞춥니다. 이게 없으면 브라우저·서비스워커가 예전 파일을 계속 써서
배포해도 화면이 그대로인 문제가 생깁니다. (해시는 소스 내용에서 자동 계산)
의존성 설치(npm install)는 필요 없습니다. 검증기는 Node 기본 기능만 씁니다.
index.html 화면 뼈대 (6개 탭 + 상세 팝업)
css/styles.css 디자인 토큰과 스타일 (시대 팔레트는 데이터에 있음)
art/<시대>.svg 시대별 첫 장면 디오라마 (매니페스트 eras[].diorama · scenes)
art/<장면>.svg, art/homage-*.svg 시대 안의 장면들 · 명화 오마주 장면 (eras[].scenes[].diorama)
js/data.js 데이터 로딩 (fetch ↔ bundle 자동 전환)
js/common.js 공용 도우미 (연도 글자, 장면 목록)
js/hud.js 시간 계기판 (굴러가는 연도 숫자 + 시대 구간 스크러버)
js/branch.js 갈림길(대체역사 게임) — 스테이지 목록·게이지·룰렛·결말 등급·결말 도감
js/quiz.js 퀴즈(데모) — 연표 끼워 넣기(오늘의 퀴즈·연습), 결과 나누기
js/tour.js 처음 온 사람을 위한 사용법 안내(단계 카드·가리키기·다시 보지 않기)
p/ 검색용 글 페이지(자동 생성 — scripts/pages.js)
site.json 사이트 이름·주소·설명(검색 머리말·글 페이지·사이트맵이 여기서 읽음)
js/zoom.js 탐험 그림판 — 카메라·입력(끌기·핀치·눕히기)·사건 자리 잡기·비행·열 이름 덮개
js/plane.js 그림판 붓 — Three.js(WebGL2) 로 도형·글자를 GPU 에, 안 되면 Canvas 2D
vendor/three.min.js Three.js r170 중 쓰는 부분만 묶은 것 (MIT, vendor/three.LICENSE) — 6-4 참고
js/app.js 탭·배경·무대·계기판·카테고리·검색·상세 팝업 조립
data/index.json ★ 매니페스트 — 데이터 파일 + 시대 구간 + 팔레트
data/<이름>.json ★ 실제 항목들 (국가별·주제별로 파일 분리)
data/alt/index.json 갈림길 시나리오 목록 (실제 연표와 분리)
data/alt/<이름>.json 갈림길 시나리오 한 편
data/bundle.js 위 JSON 들의 자동 생성 사본 (file:// 전용, 직접 수정 금지)
schema/index.schema.json 매니페스트 JSON Schema
schema/entries.schema.json 항목 JSON Schema
schema/alt-index.schema.json, schema/scenario.schema.json 갈림길 JSON Schema
scripts/validate.js 검증 스크립트
scripts/bundle.js bundle.js 생성기
scripts/stamp.js 배포 버전 스탬프(캐시 무효화) 찍기
manifest.webmanifest, sw.js, icons/ PWA 관련 파일
LICENSE 앱 코드 라이선스 (MIT)
THIRD-PARTY-NOTICES.md 제3자 구성요소 고지 (글꼴)
data/LICENSE.md 연표 데이터 라이선스(CC BY 4.0) + 데이터 작성 규칙
화면 코드는 데이터 구조를 하드코딩하지 않습니다. 카테고리 목록, 레인 이름, 색상,
시대 프리셋까지 전부 data/index.json 에서 흘러나옵니다.
해당 파일(data/korea-dynasty.json 등)의 entries 배열만 고치면 됩니다.
{
"id": "korea-gojoseon",
"category": "왕조사",
"subcategory": "한국",
"title": "고조선",
"region": "동아시아",
"start_year": -2333,
"end_year": -108,
"era_note": "기원전 2333년 ~ 기원전 108년",
"description": "단군왕검 건국 전승에서 비롯된 한반도 최초의 국가로, 기원전 108년 한 무제의 침공으로 멸망했다.",
"tags": ["고대", "국가형성"],
"sources": ["국사편찬위원회 한국사 개설"],
"status": "draft"
}
| 필드 | 규칙 |
|---|---|
id | 전체 데이터에서 유일. 소문자·숫자·하이픈. 관례: <데이터셋id>-<식별자> |
category / subcategory | 매니페스트에 등록한 값과 정확히 같아야 함 (검증됨) |
start_year / end_year | 기원전은 음수 (기원전 2333년 → -2333). 연도 0은 쓰지 않음 |
단일 사건은 start_year 와 end_year 를 같게 → 연표에 점(point)으로 표시 | |
era_note | 비워두면 npm run fix 가 "기원전 2333년 ~ 기원전 108년" 형식으로 채움 |
description | 한 문장짜리 간략 해설, 100자 이내(두 문장 이상이거나 100자를 넘으면 검증 경고). 상세 팝업과 검색 결과에 그대로 나온다 |
kind | 항목 종류. polity(나라·왕조·제국·정권) · era(시대 구분: 헤이안 시대, 춘추시대, 일제강점기, 통일신라처럼 한 나라 안의 시기) · trend(흐름: 르네상스, 냉전) · event(사건: 전쟁, 혁명). 왕조·국가사 항목에는 꼭 적는다(빠지면 검증 경고) — 왕조 칸은 polity·era 만 그리고, 계기판 '지금 이때'는 polity 를 나라마다 긴 것부터 2개까지 보여 주며, 그 해에 polity 가 없을 때만 era 하나로 대신한다(점선 칩) |
parent | (선택) 상위 왕조·나라의 항목 id(같은 파일 안). 탐험 화면에서 상위 칸 안에 그린다 — 예: 무신정권 → korea-goryeo, 제1공화국 → korea-rok. 기간이 상위 밖으로 나가면 검증 경고 |
area | (선택) 본토와 따로 오래 이어진 주변 지역 이름(탐라·류큐·에조 등). 국가사 열 오른쪽 가장자리 줄에 그린다 |
start_md | (선택) 시작일의 월·일 "MM-DD". 확인된 날짜만 적는다(지금 화면에는 쓰지 않고 데이터로만 남긴다) |
art | (선택) 이 항목에 넣을 삽화의 의도(작업 메모, 화면에는 나오지 않음) |
dating_note | (선택) 연대의 근거·한계. 문헌 전승 연대, 추정치, 학설이 갈리는 연대면 여기에 밝힌다(검토용 기록. 팝업은 연도·사건·설명·출처만 보여 준다) |
sources | 직접 확인한 자료만 적는다(URL 권장). 팝업 맨 아래 출처 · … 로 나오고, 비어 있으면 '아직 확인 전(검토 전 초안)' |
status | draft(검토 전) 또는 reviewed(검토 완료) |
수정 후:
npm run build # 검증 + bundle.js 갱신
Claude Code 에게 부탁할 때 "조선 왕조 추가해줘, 1392~1897" 처럼 한 문장이면 됩니다. 해당 JSON 편집 → (필요하면) 매니페스트 갱신 →
npm run build까지 한 번에 처리됩니다. 별도 관리자 화면은 없습니다. 변경 이력은 git 로그가 검토 로그 역할을 합니다.
① 파일 만들기 — data/vietnam-dynasty.json
{
"$schema": "../schema/entries.schema.json",
"dataset": "vietnam",
"entries": [
{
"id": "vietnam-ly",
"category": "왕조사",
"subcategory": "베트남",
"title": "리 왕조",
"region": "동남아시아",
"start_year": 1009,
"end_year": 1225,
"description": "탕롱(하노이)을 수도로 삼아 베트남의 독립 왕조 체제를 다졌다.",
"tags": ["중세", "왕조"],
"sources": ["위키백과 베트남사 개괄"],
"status": "draft"
}
]
}
② 매니페스트에 한 줄 등록 — data/index.json 의 datasets 배열에 추가
{
"id": "vietnam",
"file": "vietnam-dynasty.json",
"track": "nation",
"category": "왕조사",
"subcategory": "베트남",
"label": "베트남사",
"color": "#c0392b",
"region": "동남아시아",
"order": 33
}
끝입니다. 화면 코드는 한 줄도 건드리지 않습니다. 레인·필터 칩·색상이 자동으로 생깁니다.
국가 추가와 똑같습니다. category 를 "의학사", track 을 "theme" 로 두면 주제사 그룹에 붙습니다.
아예 새로운 트랙(예: "경제사 묶음")을 만들고 싶다면 data/index.json 의 tracks 에
{"id": "economy", "label": "경제·사회사", "order": 3} 을 추가하고 데이터셋의 track 에 그 id를 쓰면 됩니다.
음악·미술·철학·문학은 동양과 서양을 따로 둡니다(*-west.json / *-east.json).
나누는 기준은 항목의 region — 동아시아·남아시아는 동양, 그 밖(유럽·지중해·서아시아·아메리카·세계)은 서양입니다.
이슬람 철학처럼 서아시아에서 그리스 전통을 이은 것은 서양 쪽 흐름에 둡니다. 종교·과학·기술은 지역을 넘나드는 흐름이라 나누지 않았습니다.
| 필드 | 설명 |
|---|---|
tracks[] | 화면 위쪽 필터의 큰 묶음 (nation=왕조·국가사, theme=주제사) |
datasets[] | 데이터 파일 목록. id·file·track·category·subcategory·label·color 필수 |
datasets[].order | 레인 정렬 순서 (작을수록 위) |
datasets[].hidden_by_default | true 면 처음에 꺼진 상태로 시작 |
datasets[].periods | (국가사) 시대 묶음 {label, start_year, end_year, note} — 열 왼쪽 띠에 세로로 적힌다. 시작 순, 겹치지 않게. 경계 연도는 공인 자료(교과서·국사편찬위원회 등)의 시대 구분을 따르고, 어디서 끊었는지는 note 에 |
eras[] | 시대 구간. 화면의 시대 섹션·계기판 구간·배경 팔레트가 전부 여기서 만들어진다 |
eras[].start_year / end_year | 그 시대에 들어갈 사건의 start_year 범위 (끝값은 포함하지 않음) |
eras[].day / night | 배경 그라데이션 두 색 (위→아래). 낮/야경 각각 |
eras[].day_blob / night_blob | 배경에 떠다니는 블롭 두 색 |
eras[].art | 그 시대에 넣을 삽화의 의도. 넓은 화면의 여백에 자리표시자로 표시된다 |
시대 하나에 그림 한 장이면 긴 시대(고대 등)에서는 같은 그림이 계속 이어져 밋밋합니다.
그래서 시대 안을 장면으로 나눕니다. data/index.json 의 eras[].scenes 에 시작 연도 순으로 적으면 됩니다.
"scenes": [
{ "id": "ancient-river", "label": "강가의 첫 문명", "start_year": -3500, "diorama": "art/ancient.svg" },
{ "id": "ancient-dice", "label": "주사위 놀이", "start_year": -550, "diorama": "art/homage-dice.svg",
"after": "엑세키아스, 「주사위 놀이하는 아킬레우스와 아이아스」 흑화 암포라, 기원전 530년경" }
]
고대 아래에 주사위 놀이처럼 장면 이름이 나옵니다.0 -200 1600 900)으로, 표·카드가 덮는 가운데는 비우고 좌우에 무대를 둡니다.
art/_shiro.svg 의 시로와, 장면 SVG 안의 #bun(털빛을 fill 로 바꾸는 친구 토끼)을 씁니다.명화 오마주 — 장면에 after(원작 표기)를 적으면 설정 탭 '명화 오마주'에 자동으로 출처가 나옵니다.
저작권이 끝난(퍼블릭 도메인) 작품만 씁니다. 기준은 작가 사망 후 70년이 지났고(한국·EU),
미국에서는 1931년 이전 발표작인 것입니다. 구도만 빌려 새로 그리고, 원작의 사진·스캔 이미지는 쓰지 않습니다
(미술관 사진에는 별도 권리가 있을 수 있음). 지금 쓰는 10점은 모두 이 기준을 만족합니다.
가상의 역사는 data/alt/ 에만 둡니다. 실제 연표 매니페스트(data/index.json)와 섞이지 않으므로,
가상 내용이 실제 연표에 나타나는 일은 없습니다.
data/alt/<id>.json 을 만들고 data/alt/index.json 의 scenarios 에 { "id", "file" } 한 줄을 더한다.npm run validate → npm run build.시나리오 한 편은 노드(node)를 id 로 이어 붙인 갈래 이야기입니다. 예시는 data/alt/sample.json(내용은 자리표시).
| 필드 | 뜻 |
|---|---|
anchor | 갈라지는 지점. entry = 실제 연표 항목 id, year, note = 그때 실제로 일어난 일 |
compare | '실제 역사' 칸에 나란히 보여 줄 카테고리 id (예: ["korea","china"]) |
start | 첫 노드 id |
status | sample(틀 확인용) · draft(쓰는 중) · ready(완성) — 앞의 둘은 화면에 배지로 표시 |
노드 kind: "event" | 가상 사건. next 로 다음 노드 |
노드 kind: "choice" | 갈림길. options 2개 이상, 각 선택지는 to(정해진 결과) 또는 outcomes(확률로 갈림: [{ "chance": 0.7, "to": "…", "label": "…" }], 합 1) |
노드 kind: "ending" | 결말. reality 에 '실제로는 ~' 을 적는다 |
노드 real | (선택) 견줘 볼 실제 항목 id — 범위 밖이어도 '실제 역사' 칸에 나온다 |
stats | (게임) 게이지 4개까지 — [{ "id": "power", "label": "국력", "icon": "🛡️", "init": 5 }], 0~10 |
effects | (게임) 선택지·확률 결과·장면에 붙이는 게이지 변화 — { "power": 2, "people": -1 }(한 번에 -3~3) |
zero | (게임) 게이지가 0 이 되면 바로 떨어지는 결말 — { "people": "end-revolt" } |
결말 tone | (게임) 결말 등급 best 최고의 결말 · good 좋은 결말 · mixed 씁쓸한 결말 · bad 파국 — 결말 도감 색 |
검증기가 잡아 주는 것: 없는 노드로 이어짐, 고리(끝나지 않는 이야기), 시작에서 닿지 않는 노드, 확률 합이 1 이 아님, 실제 연표에 없는 항목 id, 거꾸로 가는 연도(경고), stats 에 없는 게이지, 결말이 아닌 zero 대상.
항목을 공개 데이터와 견주어 연도를 확인하는 도구입니다. 데이터 파일은 바꾸지 않고 리포트만 만듭니다 — 무엇을 고치고 들일지는 사람이 리포트를 보고 정합니다.
npm run sources:match # = node scripts/match-wikidata.js (받은 응답은 .cache/sources 에 남아 다음엔 빠름)
node scripts/match-wikidata.js --fresh # 모두 새로 받기
결과: data/review/wikidata-report.md(사람용 표) · data/review/wikidata-match.json(항목별 후보·연도·판정)
| 출처 | 라이선스 | 쓰는 곳 |
|---|---|---|
| Wikidata | CC0 | 한국어 이름으로 항목을 찾고 시작·끝 연도(설립·해체, 시작·끝, 출생·사망, 발표, 발견·발명, 초연)를 견줌 |
| Cliopatria (Seshat) | CC BY 4.0 | 국가사 항목에 '지도에 그려진 기간'을 참고로 붙임 — 건국·멸망 연도가 아니고, Wikidata 연결이 틀린 곳도 있어(조선 → 고조선) 보조로만 |
sources 에 적습니다.github/workflows/sources.yml, Actions 탭 → sources → Run workflow)에서 돌려도 됩니다이 연표의 내용은 아직 검증되지 않았습니다. 지금 상태를 있는 그대로 적습니다.
status: draft 입니다.sources 에
[항목명],『한국민족문화대백과사전』 + 주소 를 달았습니다(확인표: data/review/korea-check.md, 추가 9개: data/review/korea-new.md).
대조는 Claude 가 했으므로 사람이 다시 확인하기 전까지는 draft 로 둡니다. 팝업에는 출처 · <항목 링크> (검토 전 초안) 로 나옵니다."Encyclopaedia Britannica 개괄" 같은 출처 문자열이 붙어 있었지만,
이는 항목별로 확인한 인용이 아니라 파일 단위로 일괄 부여된 라벨이었습니다.
검증된 것처럼 오해될 수 있어 모두 비웠습니다. 지금은 팝업에 '출처 미확인' 으로 정직하게 표시됩니다.dating_note 를 달아 근거와 한계를 밝혔습니다.
(고조선·삼국 건국 연대, 하상주단대공정 연대, 석가모니·예수 생몰, 메소포타미아 연대기,
선사 시대 구간 등)sources 에 확인한 자료를 적습니다. 되짚을 수 있는 형태가 좋습니다.
"sources": [
"https://ko.wikipedia.org/wiki/고조선",
"국사편찬위원회, 『한국사』 4권, 12쪽"
]
status 를 reviewed 로 바꿉니다.npm run validate — reviewed 인데 sources 가 비어 있으면 오류로 막습니다.
검증 결과 맨 끝에 출처 표기: n/459 로 진행 상황이 나옵니다.git 커밋 이력이 그대로 검토 로그가 되므로, 누가 언제 무엇을 확인했는지 남습니다.
역사 전체가 한 장의 거대한 그림입니다 — 세로는 시간(위가 옛날), 가로는 카테고리마다 한 열(국가사 → 주제사). 그림은 화면보다 커서 상하좌우 어디로든 끌고 던질 수 있고, 줌하면 시간축과 열 너비가 함께 변합니다(멀리서는 모든 열이 한눈에 보이는 포스터, 다가가면 열이 넓어져 카드가 펼쳐짐) (ChronoZoom 처럼 실제 시간 비율 — 선사 3만 년이 길고 문명사는 아래쪽에 모여 있는 것이 빅 히스토리의 실제 모습).
| 동작 | 방법 |
|---|---|
| 확대·축소 | 핀치(손가락·트랙패드 — 손가락을 그대로 따라감), ⌘/Ctrl+휠(마우스 — 한 칸씩 부드럽게), + / -, 빈 곳 두 번 톡·더블클릭 = 다가가기. 모두 커서·손가락 자리 기준 |
| 이동 | 상하좌우 끌기 — 손가락·마우스를 1:1로 따라오고, 던지면 그 방향으로 미끄러짐. 끝(역사 처음·지금, 첫·마지막 열)을 넘기면 고무줄처럼 덜 따라오다 놓으면 튕겨 돌아온다(열이 화면에 다 들어와도 옆으로 밀린다). 트랙패드 두 손가락 스크롤·마우스 휠(위아래 = 시간, 옆 = 열. 맥의 관성 스크롤 그대로), 윈도 마우스는 Shift+휠로 가로, ↑↓←→, PageUp/Down — Figma·Miro·tldraw 같은 무한 캔버스 앱의 표준 조작 |
| 눕히기 | 스타워즈 오프닝처럼 그림판을 뒤로 눕힌다 — 과거가 저 멀리, 지금이 코앞. 두 손가락을 나란히 대고 함께 위로 밀면 눕고 아래로 당기면 선다(벌리고 오므리면 줌), Alt(맥 Option)+휠, Alt+끌기, T 키(0° ↔ 40°). 최대 60°, 5° 아래로 놓으면 납작하게 돌아온다. 눕혀도 초점 고리의 해는 그대로이고, 끌기·톡·줌이 모두 손가락 밑의 점 기준으로 동작한다. Ctrl·⌘+휠은 줌(트랙패드 핀치도 브라우저가 Ctrl+휠로 보낸다. 사파리는 gesture 이벤트) |
| 열 | 화면 위에 열 이름이 붙어 있다. 열 이름을 톡 치면 그 열로 다가간다 |
| 연도 축 | 국가사 열과 주제사 열 사이에 끼어 그림과 함께 옆으로 움직인다(처음엔 화면 가운데). 화면 밖으로 나가려 하면 왼쪽·오른쪽 가장자리에 붙어 따라오고, 오른쪽에 붙으면 눈금이 그림 쪽을 보게 뒤집힌다. 국가사만·주제사만 켜면 맨 앞에 |
| 시대로 날아가기 | 계기판 ‹ ›, 1~6, 계기판 띠 — 멀면 잠깐 물러났다 다가가는 비행 |
| 시간 눈금 | 줌에 맞춰 1만 년 → 1천 년 → 100년 → 10년 → 1년 |
| 사건 | 자리가 넉넉하면 카드, 빠듯하면 이름표, 더 빠듯하면 점, 그래도 없으면 +N 묶음(톡 → 그쪽으로 다가감). 나라·왕조 > 시대 > 나머지 순으로 자리를 잡는다 |
| 왕조 칸 | 국가사 열은 왕조·시대를 이름이 들어간 칸으로 그립니다(왕조 표처럼). 같은 때의 나라는 열 폭을 나눠 나란히(혼자면 꽉 차게), 하위 시기(parent)는 상위 칸 안에, 주변 지역(area)은 오른쪽 가장자리 줄에. 이름은 보이는 부분 위쪽에 붙어 따라오고, 좁으면 세로로 씁니다. 초점선의 해에 걸린 칸이 진해집니다. 톡 → 펼치기 |
| 시대 묶음 | 국가사 열 왼쪽 띠(매니페스트 periods — 삼국 시대·송원 시대·중세 …). 톡 → 그 시대로 |
| 지금 어디? | 왼쪽 연도 축의 숨 쉬는 고리(초점선)에 걸린 해가 계기판 숫자가 된다 |
| 계기판 | 아래 알약 ‹ 기원전 653년 고대 ˄ ›. 숫자를 누르면 시대 띠(톡 → 날아가기, 끌기 → 따라오기)와 지금 이때(초점선의 해에 나라마다 이어지던 나라·왕조, 나라마다 최대 2개 · 없으면 시대 이름 점선 칩 · 누르면 상세)가 펼쳐지고, 그림판을 다시 만지면 접힌다 |
| 펼치기 | 왕조 칸·사건을 누르면 그 기간이 화면을 채우도록 날아가고(van Wijk–Nuij 줌 경로: 멀면 한 번 물러났다가 다가간다), 그 열이 넓어지고 칸이 열을 꽉 채우며(옆 칸을 덮으며) 테두리가 둘러지고, 이름 아래로 연도(카테고리 색 점) · 한 문장 설명 · 출처 · 갈림길 이 나옵니다. 사건은 카드가 열 폭으로 커지며 제목 아래로 같은 내용이 나옵니다. 글은 칸 위쪽에 붙어 따라오고, 출처를 누르면 원문이 열립니다. 접기는 Esc 또는 빈 곳 톡. 검색·퀴즈·계기판에서 열어도 같은 식. 펼치지 않아도 칸이 넉넉히 커지면(폭 150px 넘게) 이름 아래로 설명이 서서히 나온다 |
| 키보드 | ↑↓ 조금 · PageUp/Down·Space 한 화면 · ←→ 옆 열 · +− 줌 · T 눕히기 · 1~6 시대 · Home/End · / 검색 |
조작감을 바꾸고 싶다면 js/zoom.js 맨 위 상수를 고치면 됩니다 —
FRICTION(작을수록 멀리 미끄러짐), RUBBER(끝 너머로 따라오는 비율), SPRING(되돌아오는 빠르기), TILT_MAX·TILT_ON(눕히는 각도).
prefers-reduced-motion 을 켠 기기에서는 날아가기·눕히기 같은 연출 없이 바로 이동합니다.
그리기 — 판(열·사건·눈금)은 js/plane.js 의 붓이 칠합니다. Three.js(WebGL2)가 되면 모든 도형을 인스턴스 한 번으로,
글자는 한 번 쓴 문자열을 글자판 텍스처(한 채널, 밉맵)에 두고 다시 써서 GPU 로 그리고, 눕히기는 원근 카메라를 기울입니다.
WebGL2 가 없으면 Canvas 2D 로 칠하고 눕히기는 CSS 3D 로 합니다(주소 뒤에 ?2d 를 붙이면 이 모드를 확인할 수 있음).
열 이름은 판 위에 납작하게 붙은 덮개 캔버스에 그려 눕혀도 똑바로 읽힙니다.
화면 읽기 프로그램을 쓰거나 사건을 글로 차례대로 읽고 싶다면 검색 탭을 여세요 — 검색어가 없으면 전체 항목이 시대순으로 나옵니다.
처음 접속하면 연표 위에 6단계 안내 카드가 뜹니다 — 나란히 보기 → 움직이기 → 확대하기 → 눌러서 펼치기(고려를 실제로 펼쳐 보임) → 계기판 → 탭. 마우스·트랙패드와 터치에 맞춰 말이 바뀌고, 그림판 단계는 화면을 어둡게 하지 않아 안내를 보며 바로 해 볼 수 있습니다.
Esc 나 건너뛰기 로 닫기, 이전 으로 되돌아가기js/app.js 의 키(bighistory.tour1) 번호를 올려 모두에게 다시 보여 줍니다카드게임 'Timeline' 처럼 사건 카드를 한 장씩 받아 연표의 알맞은 자리에 끼워 넣습니다(다섯 장).
실제 역사의 한 장면에서 다른 길을 골라 가는 대체역사 게임.
data/alt/ 에 status 가 sample 이 아닌 시나리오가 하나라도 있을 때만 탭이 보입니다(지금은 예시뿐이라 숨김).
확인하려면 주소 뒤에 ?branch 를 붙입니다.
시작·이어서·다시 하기+1·−2 로 보인다.
2칸 이하면 깜빡이고, 0 이 되면 그 자리에서 정해 둔 결말로 떨어진다계속 →, 갈림길은 A·B 버튼. '운에 맡김 · 70 : 30' 선택지는 룰렛이 돌다 멈춰 결과를 정한다결과 나누기실제 역사와 나란히 보기(펼치면 같은 시간축에 실제 | 가상)↶ 한 수 무르기, 처음부터. 진행 상황과 찾은 결말은 기기에만 저장된다갈림길 · … 버튼이 나온다.전체 선택 / 전체 해제 와 트랙별(왕조·국가사 / 주제사) 카드 목록. 끈 카테고리는 연표에서 사라진다.
검색어가 없으면 전체 항목을 시대순으로 보여 준다(그림판 대신 글로 읽는 목록).
이름·설명·태그·지역을 부분 일치로 찾고(/ 키로 바로 이동), 추천어 칩으로 질의를 넣을 수 있다. 결과를 누르면 연표로 날아가 그 항목이 펼쳐진다.
내용 신뢰도 고지, 데이터·소프트웨어 라이선스, 개인정보 고지.
UI 아이디어는 저작권 보호 대상이 아니지만, 화면 그림·아이콘·문장·코드는 보호됩니다. 아래 작품에서는 배치와 상호작용 아이디어만 참고했고, 이 저장소의 코드와 그래픽은 모두 새로 만들었습니다.
| 참고한 것 | 가져온 아이디어 | 이 앱에서 |
|---|---|---|
| Scale of the Universe 2 | 전체를 한 줄로 보여 주는 아래 막대 + 큰 숫자 | 시간 계기판, 굴러가는 연도 |
| The Histomap (John B. Sparks, 1931) | 문명·국가를 나란한 색 흐름으로 | 국가사 열의 왕조 띠, '지금 이때' 단면 |
| The History of Everything (2Dimensions, 앱) | 세로 타임라인 + 옆에 긴 시대를 막대로 | 세로 시간축과 왕조 띠 |
| Histography, Timeline Eons, ChronoZoom | 카테고리 필터, 확대/시대 건너뛰기 | 카테고리 탭, 시대 점프·스크러버 |
빌드 과정이 없으므로 저장소를 그대로 올리면 됩니다.
npm run build 로 data/bundle.js 를 최신화하고 커밋합니다.main)와 폴더 / (root) 를 선택하면 https://<계정>.github.io/<저장소>/ 로 열립니다. 지금 주소는 https://shiroleestudio.github.io/prettymuchtimelines/ (저장소 shiroleestudio/prettymuchtimelines). 옛 주소 dooholee96-code.github.io/THEBIGHISTORY 는 개인 계정의 리다이렉트 저장소가 넘겨줍니다.모든 경로가 상대 경로라서 하위 경로 배포에서도 그대로 동작합니다.
연표 화면은 캔버스라 검색 엔진이 내용을 거의 읽지 못하므로, npm run build 가 글 페이지를 따로 만듭니다(scripts/pages.js).
| 만드는 것 | 내용 |
|---|---|
p/<id>.html | 출처를 확인한 항목마다 한 장 — 이름·연도·설명·출처, 같은 시기 다른 나라·주제 목록, 같은 줄의 앞뒤, 연표에서 펼쳐 보기(→ index.html#e=<id>, 그 항목을 바로 펼침) |
p/index.html | 카테고리별 항목 목록(설정 탭에서도 링크) |
sitemap.xml, robots.txt | 위 페이지와 첫 화면 주소 |
index.html 머리말 | <!-- seo:start --> ~ <!-- seo:end --> — 제목·설명·대표 이미지(icons/og.jpg)·구조화 데이터 |
이름·주소·설명은 site.json 한 곳에서 읽습니다. 이름을 정하거나 도메인을 옮기면 site.json 만 고치고 npm run build.
출처가 없는 초안 항목은 검색에 내보내지 않습니다(출처를 붙이면 다음 빌드부터 페이지가 생김).
등록(사람이 한 번 해야 하는 일):
site.json 의 url) → 소유 확인에서 'HTML 태그'를 고르면 나오는
content="…" 값을 site.json 의 verify.google 에 넣고 빌드·배포 → 확인 → Sitemaps 에 sitemap.xml 제출verify.naver 에 넣고 빌드·배포 → 확인 →
요청 › 사이트맵 제출에 sitemap.xmlgithub.io/<저장소>/ 하위 경로에 있으면 robots.txt 는 검색 엔진이 읽지 않습니다(도메인 맨 앞에 있어야 함).
사이트맵은 위처럼 직접 제출하면 되고, 자체 도메인을 연결하면 robots.txt 도 그대로 쓰입니다.대표 이미지 icons/og.jpg(1200×630)는 연표 화면을 찍은 것입니다. 이름이 바뀌면 다시 찍어 두세요.
manifest.webmanifest 와 sw.js 가 이미 들어 있습니다. https 또는 localhost 로 열면
서비스워커가 등록되어 오프라인에서도 동작하고, 모바일 브라우저에서 "홈 화면에 추가"를 하면
주소창 없는 앱처럼 실행됩니다.
서비스워커는 네트워크 우선으로 동작합니다. 온라인이면 항상 서버의 최신 파일을 쓰고,
네트워크가 없거나 느릴 때만(4초) 캐시 사본으로 대체합니다. 배포 때마다 npm run build 로
버전 스탬프가 바뀌므로 새 코드가 곧바로 반영됩니다.
예전 버전이 계속 보인다면 (캐시 우선이던 옛 서비스워커가 남아 있는 경우) 주소 뒤에
?v=2를 붙여 한 번 열거나, 새로고침을 두 번 하세요. 그래도 그대로면 개발자도구 → Application → Service workers → Unregister 후 새로고침. 지금 어떤 빌드가 떠 있는지는 브라우저 콘솔의[app] Timeline of Pretty Much Everything <해시>줄로 확인합니다.
이 앱은 웹 표준만 쓰고 데이터도 파일 기반이라(브라우저 저장소에 의존하지 않음) 코드 수정 없이 네이티브로 감쌀 수 있습니다.
npm install @capacitor/core @capacitor/cli
npx cap init "Timeline of Pretty Much Everything" com.example.bighistory --web-dir=.
npm install @capacitor/ios @capacitor/android
npx cap add ios
npx cap add android
npx cap sync # 웹 자산을 네이티브 프로젝트로 복사
npx cap open ios # Xcode (App Store 제출)
npx cap open android # Android Studio (Play Store 제출)
webDir 를 저장소 루트로 두면 index.html·css/·js/·data/ 가 그대로 앱 번들에 들어갑니다.
(node_modules, ios, android, scripts 는 .gitignore/.capacitorignore 로 제외)fonts/ 에 파일로 들어 있어 앱 번들에도 그대로 포함되고, 외부에서 받지 않습니다.capacitor:// 스킴이라 fetch 가 동작하므로 JSON 을 직접 읽습니다.
data/bundle.js 는 그대로 두어도 무해합니다.data/ 만 원격에서
내려받아 갱신하는 식으로 js/data.js 한 파일만 고치면 됩니다.파일로 바로 열기(file://)에서도 돌도록 ES 모듈 대신 전역 THREE 하나로 묶어 둡니다.
js/plane.js 가 쓰는 것만 골라 묶어서 전체(약 1.2MB)보다 작습니다(약 470KB, gzip 120KB).
새 클래스를 쓰게 되면 아래 entry.js 에 이름을 더하고 다시 묶으세요.
mkdir /tmp/three-build && cd /tmp/three-build && npm init -y && npm i [email protected] [email protected]
cat > entry.js <<'JS'
export {
WebGLRenderer, Scene, Camera, Mesh,
InstancedBufferGeometry, InstancedBufferAttribute, BufferAttribute,
ShaderMaterial, DataTexture, Vector2,
RGBAFormat, RedFormat, UnsignedByteType, LinearMipmapLinearFilter, LinearFilter,
DynamicDrawUsage, CustomBlending, OneFactor, OneMinusSrcAlphaFactor,
REVISION
} from 'three';
JS
npx esbuild entry.js --bundle --minify --format=iife --global-name=THREE --target=es2018 \
--legal-comments=none --outfile=<저장소>/vendor/three.min.js
묶은 뒤 파일 맨 위에 출처 한 줄 주석을 다시 달고, npm run build 로 스탬프를 갱신하세요.
THIRD-PARTY-NOTICES.md 에 추가하세요.0 을 넣으면 검증에서 걸립니다.광고를 붙여 서비스해도 되는 구조입니다. 근거를 정리해 둡니다.
| 구성요소 | 라이선스 | 상업적 이용 | 의무 |
|---|---|---|---|
앱 코드 (index.html, css/, js/, scripts/) | MIT — LICENSE | 가능 | 저작권 고지 유지 |
연표 데이터 (data/) | CC BY 4.0 — data/LICENSE.md | 가능 | 저작자 표시 |
글꼴 Gaegu · Gowun Dodum (fonts/) | SIL OFL 1.1 | 가능 | 고지 유지(fonts/OFL-*.txt 동봉) |
package.json 에 dependencies 가 하나도 없어 전이 의존성 위험이 없습니다.fonts/ 에 담아 함께 배포합니다(SIL OFL 1.1, 재배포 가능, 전문 동봉).
분석 도구·추적 스크립트는 없고 쿠키도 쓰지 않습니다. (보기 설정과 갈림길 진행 상황만 기기의 localStorage 에 남습니다)icons/ 는 이 저장소에서 직접 만든 것입니다.THIRD-PARTY-NOTICES.md상업적 이용에 문제가 생기는 거의 유일한 경로는 다른 저작물의 문장을 그대로 옮기는 것입니다. 특히 위키백과는 CC BY-SA 라 문장을 옮기면 그 의무가 데이터 전체로 번질 수 있습니다.
description·summary 는 반드시 직접 쓰세요.sources 에 확인용으로 적어도 됩니다. npm run validate 가 위키 계열 링크를 만나면
이 규칙을 다시 알려 줍니다.data/LICENSE.md지금은 쿠키도 외부 전송도 없지만, 광고 스크립트를 넣는 순간 달라집니다.
reviewed 로 끌어올린 뒤 신청하는 편이 유리합니다
(현재 459개 전부 draft, 출처가 있는 것은 133개).main 에 푸시 → 1~2분 뒤 https://shiroleestudio.github.io/prettymuchtimelines/ . 서비스워커 때문에 이미 열어 둔 폰은 한 번 더 열어야 새 버전이 뜬다.git revert <커밋> 후 푸시. 빌드 결과(data/bundle.js 등)도 그 커밋에 들어 있으므로 함께 돌아간다.npm run validate 가 잡는다. Pages 설정은 Settings → Pages → main / root..nvmrc(22). 런타임 의존성이 없으므로 npm install 없이 node scripts/… 가 바로 돈다..github/workflows/sources.yml(매주 Wikidata 대조)은 저장소에 60일간 커밋이 없으면 GitHub 이 자동으로 끈다. 리포트가 안 오면 Actions 탭에서 다시 켠다. 데이터 파일은 건드리지 않으니 꺼져도 사이트는 멀쩡하다.vendor/three.min.js(r170) 고정. 올릴 이유가 생길 때만 6-4 절차로.CHANGELOG.md 한 줄 + Releases 에서 vX.Y.Z 태그.STUDIO.md.