digraph G {
  keydown[shape=box]
  keyup[shape=box]
  keyupIME[shape=box,label="keyup"]
  keypress1[shape=box,label="keypress"]
  keypress2[shape=box,label="keypress"]
  keylongpress[shape=box]
  textInput1[shape=parallelogram,label="textInput"]
  textInput2[shape=polygon,sides=4,skew=.4,peripheries=2,label="textInput (repeat)"]
  isSustained1[shape=diamond,label="sustained?"]
  isSustained2[shape=diamond,label="sustained?"]
  isCharKey1[shape=diamond,label="character\nkey?"]
  isCharKey2[shape=diamond,label="character\nkey?"]
  isModKey[shape=diamond,label="modifier\nkey?"]
  isIME[shape=diamond,label="IME?"]
  keysequence[shape=Msquare,label="combination\nof keys"]
  delay[shape=ellipse]
  modLoop[shape=ellipse,peripheries=2,label="wait for\nadditional\nkeys"]

  start -> keydown
  keydown -> keypress1
  keypress1 -> isIME
  isIME -> isCharKey1 [label=no,color=red]
  isIME -> isSustained1 [label=no,color=red]
  isIME -> keysequence [label=yes,color=green] 
  keysequence -> keyupIME
  keyupIME -> textInput1
  isCharKey1 -> isModKey [label=no,color=red]
  isCharKey1 -> textInput1 [label=yes,color=green]
  isSustained1 -> keyup [label=no,color=red]
  isSustained1 -> delay [label=yes,color=green] 
  isModKey -> modLoop [label=yes,color=green] 
  modLoop -> keydown [label="additional key",style=dashed] 
  delay-> keylongpress
  keylongpress -> keypress2
  keypress2 -> isSustained2
  isSustained2 -> keypress2 [label=yes,color=green]
  isSustained2 -> keyup [label=no,color=red]
  keypress2 -> isCharKey2
  isCharKey2 -> textInput2 [label=yes,color=green]
}

