diff --git a/experiments/Untitled Diagram.xml b/experiments/Untitled Diagram.xml
deleted file mode 100644
index a3019f8..0000000
--- a/experiments/Untitled Diagram.xml
+++ /dev/null
@@ -1 +0,0 @@
-5VhNc9owEP01PjYjS8bGx4bQ9tDOZIZDk6OwN7YaYTFCfPXXV7ZkbGHDEEJgMuXASE+rlfR230rgkdFs813Sef5LpMA9jNKNRx48jKOBr79LYGuAIB4aIJMsNZDfABP2FyyILLpkKSwcQyUEV2zugokoCkiUg1Epxdo1exHcXXVOM+gAk4TyLvqbpSo36BCHDf4DWJbXK/thbEamNHnNpFgWdj0Pk5fqY4ZntPZlD7rIaSrWLYiMPTKSQijTmm1GwEtqa9rMvG8HRnf7llCoUyZEdhtqWx8dUs2E7QqpcpGJgvJxg95Xx4PSAdK9XM24bvq6CRumnkr4Dg9s97keKpTcmrFB3X22Hv6AUlubA3SphIaahX8KMbc+XhjnI8GFrDaqeYUwSTS+UFK8QmskjeIpKj2bw5UnOkiPhRZiKRNrhW3CUZmBtSK70OiMBzEDvX1tIoFTxVaud2pzL9vZNfzrhg1BfziGHxOO6Eg4AuwE5Au6Q35UI48gmT4EyM8TquBKobJLryhf7hWvVvTWOVMwmdNqv2tdKt0InUvTCqSCzXGiuhTUE4jdp63Nse2um0Ln1+UpbxW5EL2ftJqiFmseDrle4T5lK93MVHVIA03lPqL999j9D1Nny4XSxBX6Yug6mcLJ6+kLR+picfmTHalbhShOKlR1+9m9J57sjObSqMbOrUXDBPpFdj9EEYrOrkXk8rWomvpVSrptGcwFK9Si5fmxBFr6jl1948HeE2DPfifKfnvdMDtoBL47ykmaJ91C6WE9C5FPUS7DPXbwNcul36HoHF0hR1fYEZbvCgu/RVnn6SS43fMq6L2zy1z08adIRkJumY1Rz+X9jvT82DSLu2nmh1fKM//4O/5k3R79HRUH2NUuIuQNrPa+7y9G9bUUHR9UdPDm1/gF9BmgG76tw6PV7XacDK9Xs3S3+e/EvFWa/6fI+B8=
\ No newline at end of file
diff --git a/src/kdom.nim b/src/kdom.nim
index f933b87..607d882 100644
--- a/src/kdom.nim
+++ b/src/kdom.nim
@@ -258,6 +258,7 @@ type
paddingTop*: cstring
pageBreakAfter*: cstring
pageBreakBefore*: cstring
+ pointerEvents*: cstring
position*: cstring
right*: cstring
scrollbar3dLightColor*: cstring
diff --git a/src/vdom.nim b/src/vdom.nim
index c11d532..f022b7f 100644
--- a/src/vdom.nim
+++ b/src/vdom.nim
@@ -47,6 +47,7 @@ type
onkeyup, ## A key was released.
onkeydown, ## A key is pressed.
onkeypressed, # A key was pressed.
+ onfocus, ## An element got the focus.
onblur, ## An element lost the focus.
onchange, ## The selected value of an element was changed.
onscroll, ## The user scrolled within an element.
diff --git a/src/vstyles.nim b/src/vstyles.nim
index 161c207..252dda4 100644
--- a/src/vstyles.nim
+++ b/src/vstyles.nim
@@ -150,6 +150,7 @@ type
pageBreakInside
perspective
perspectiveOrigin
+ pointerEvents
position
quotes
resize
@@ -262,4 +263,4 @@ proc rgb*(r, g, b: range[0..255]): cstring =
cstring"rgb(" & &r & cstring", " & &g & cstring", " & &b & cstring")"
proc rgba*(r, g, b: range[0..255], alpha: float): cstring =
- cstring"rgb(" & &r & cstring", " & &g & cstring", " & &b & cstring", " & &alpha & cstring")"
+ cstring"rgba(" & &r & cstring", " & &g & cstring", " & &b & cstring", " & &alpha & cstring")"
diff --git a/tools/karun.nim b/tools/karun.nim
new file mode 100644
index 0000000..dd498ea
--- /dev/null
+++ b/tools/karun.nim
@@ -0,0 +1,41 @@
+## Simple tool to quickly run Karax applications. Generates the HTML
+## required to run a Karax app and opens it in a browser.
+
+import os, strutils, parseopt, browsers
+
+const
+ html = """
+
+
+
$1
+
+
+
+
+
+"""
+
+proc exec(cmd: string) =
+ if os.execShellCmd(cmd) != 0:
+ quit "External command failed: " & cmd
+
+proc main =
+ var op = initOptParser()
+ let rest = op.cmdLineRest
+ var file = ""
+ while true:
+ op.next()
+ case op.kind
+ of cmdLongOption, cmdShortOption: discard
+ of cmdArgument: file = op.key
+ of cmdEnd: break
+
+ if file.len == 0: quit "filename expected"
+ let name = file.splitFile.name
+ createDir("nimcache")
+ exec("nim js --out:nimcache/" & name & ".js " & rest)
+ let dest = "nimcache" / name & ".html"
+ writeFile(dest, html % name)
+ openDefaultBrowser(dest)
+
+main()