/* Sentence breakdown view — multi-granularity decomposition 昨日友達と渋谷で美味しいラーメンを食べました The most domain-specific surface in the batch. Sentence as a path through the knowledge graph; each granularity exposes a layer of that path. */ const SentenceBreakdown = () => { const [granularity, setGranularity] = React.useState("morpheme"); const [selectedTok, setSelectedTok] = React.useState(7); // Granularity layers, top-to-bottom: // 1) bunsetsu — phrase chunks // 2) morpheme — MeCab/Sudachi tokens // 3) kanji — kanji components // // Each token carries indices into all three layers. const tokens = [ { i:0, jp:"昨日", kana:"きのう", roma:"kinō", pos:"N · time", gloss:"yesterday", kanji:["昨","日"], bunsetsu:0, lemma:"昨日", freq: 312, jlpt:"N5", state:"mastered" }, { i:1, jp:"友達", kana:"ともだち", roma:"tomodachi", pos:"N", gloss:"friend", kanji:["友","達"], bunsetsu:1, lemma:"友達", freq: 540, jlpt:"N5", state:"mastered" }, { i:2, jp:"と", kana:"と", roma:"to", pos:"PRT · with", gloss:"with", kanji:[], bunsetsu:1, lemma:"と", freq: 18, jlpt:"N5", state:"mastered" }, { i:3, jp:"渋谷", kana:"しぶや", roma:"Shibuya", pos:"N · place", gloss:"Shibuya", kanji:["渋","谷"], bunsetsu:2, lemma:"渋谷", freq:8420, jlpt:"—", state:"learning" }, { i:4, jp:"で", kana:"で", roma:"de", pos:"PRT · loc.", gloss:"at, in", kanji:[], bunsetsu:2, lemma:"で", freq: 5, jlpt:"N5", state:"mastered" }, { i:5, jp:"美味しい", kana:"おいしい", roma:"oishii", pos:"i-adj", gloss:"delicious", kanji:["美","味"], bunsetsu:3, lemma:"美味しい", freq:2104, jlpt:"N5", state:"mastered" }, { i:6, jp:"ラーメン", kana:"らーめん", roma:"rāmen", pos:"N · loanword", gloss:"ramen", kanji:[], bunsetsu:3, lemma:"ラーメン", freq:1840, jlpt:"—", state:"mastered" }, { i:7, jp:"を", kana:"を", roma:"o", pos:"PRT · obj.", gloss:"(direct object)", kanji:[], bunsetsu:3, lemma:"を", freq: 3, jlpt:"N5", state:"frontier" }, // currently selected { i:8, jp:"食べました", kana:"たべました", roma:"tabemashita", pos:"V · past·polite", gloss:"ate", kanji:["食"], bunsetsu:4, lemma:"食べる", freq: 87, jlpt:"N5", state:"mastered" }, ]; // Bunsetsu groupings const bunsetsuGroups = [ { id:0, label:"adverbial", role:"when?", tokens:[0], gloss:"yesterday" }, { id:1, label:"subject(-ish)", role:"who-with?", tokens:[1,2], gloss:"with my friend" }, { id:2, label:"locative", role:"where?", tokens:[3,4], gloss:"in Shibuya" }, { id:3, label:"object", role:"what?", tokens:[5,6,7], gloss:"delicious ramen (obj.)" }, { id:4, label:"predicate", role:"verb", tokens:[8], gloss:"ate (past polite)" }, ]; // Kanji components for each token's kanji const kanjiInfo = { "昨":{r:"日 day", strokes:9, jlpt:"N4"}, "日":{r:"日 day", strokes:4, jlpt:"N5"}, "友":{r:"又 again", strokes:4, jlpt:"N4"}, "達":{r:"⻌ road", strokes:12, jlpt:"N3"}, "渋":{r:"氵water", strokes:11, jlpt:"—"}, "谷":{r:"谷 valley", strokes:7, jlpt:"N3"}, "美":{r:"羊 sheep", strokes:9, jlpt:"N3"}, "味":{r:"口 mouth", strokes:8, jlpt:"N4"}, "食":{r:"食 eat", strokes:9, jlpt:"N5"}, }; const sel = tokens[selectedTok]; return (
§ JP · SENTENCE / 日本語 · Sentence corpus / sent.jp.0832 · N4 · 9 morphemes · 9 kanji
Granularity
{["bunsetsu","morpheme","kanji"].map(g => ( ))}

Sentence
{tokens.map(t => ( setSelectedTok(t.i)}> {t.jp}{t.kana} ))}
Translation Yesterday I ate delicious ramen with my friend in Shibuya.

{/* Three-layer decomposition stack — only the active layer is fully rendered; the other layers show as collapsed strips above/below */}
{/* BUNSETSU LAYER */}
Layer · bunsetsu phrase chunks · 5
{bunsetsuGroups.map(b => (
{b.tokens.map(ti => {tokens[ti].jp})}
└─
{b.label} {b.role}
{b.gloss}
))}
{/* MORPHEME LAYER (default active) */}
Layer · morpheme SudachiPy · {tokens.length} tokens
i
surface
reading
lemma
POS
gloss
freq
state
{tokens.map(t => (
setSelectedTok(t.i)}>{t.i.toString().padStart(2,"0")}
setSelectedTok(t.i)}>{t.jp}
{t.kana}
{t.lemma}
{t.pos}
{t.gloss}
#{t.freq}
))}
{/* KANJI LAYER */}
Layer · kanji components {Object.keys(kanjiInfo).length} unique · radical decomposition
{Object.entries(kanjiInfo).map(([k, info]) => (
{k}
{info.r}
{info.strokes} st · {info.jlpt}
))}

{/* Selected token detail */}
Selected · token {sel.i.toString().padStart(2,"0")}

{sel.jp} {sel.kana} {sel.roma}
POS{sel.pos}
Gloss{sel.gloss}
Lemma{sel.lemma}
Freq#{sel.freq}
JLPT{sel.jlpt}
Bunsetsu{bunsetsuGroups[sel.bunsetsu].label}
{sel.jp === "を" && ( <>
Particle role
marks the direct object of 食べました. The full object phrase is 美味しいラーメン (delicious ramen). Without , the sentence is ungrammatical.
)}
{/* Path through the knowledge graph */}
Path · this sentence traverses

  • grammar.jp.particle.を N5
  • grammar.jp.particle.で N5
  • grammar.jp.i_adj.attributive N5
  • grammar.jp.verb.masu_past N5
  • grammar.jp.particle_chain.を_de N4 · frontier
  • vocab.jp.proper.shibuya place
9 graph nodes touched · 1 frontier · 0 locked

); }; window.SentenceBreakdown = SentenceBreakdown;