repo: hackvr-turbo
action: commit
revision: 
path_from: 
revision_from: ba91ddb261ce6ddb52ec68cd1a68f3a3c65786a6:
path_to: 
revision_to: 
git.thebackupbox.net
hackvr-turbo
git clone git://git.thebackupbox.net/hackvr-turbo
commit ba91ddb261ce6ddb52ec68cd1a68f3a3c65786a6
Author: Felix (xq) Queißner 
Date:   Wed Jul 1 23:50:50 2020 +0200

    Continues development of HackVR. Implements event resolving for add_state.

diff --git a/SPEC.md b/SPEC.md
index 7501be8f36268252813a87069b732c1cc596a805..
index ..e0eb639dbf5b883870d283cb1dd691d3cabd36dd 100644
--- a/SPEC.md
+++ b/SPEC.md
@@ -66,7 +66,7 @@ Closes hackvr only if the id that is doing it is the same as yours.`
 Flushes out locally-cached movement and rotation

 ### `[groupspec] flatten`
-combines group attributes to the shapes.
+Applies the current group transform to all contained vertices in the selected groups and will reset set the group transforms to *none*.

 ### `[groupspec] move [+]x [+]y [+]z`

diff --git a/lib/hackvr/data/test.hackvr b/lib/hackvr/data/test.hackvr
new file mode 100644
index 0000000000000000000000000000000000000000..d2718803f256cf82138ce67ac97aa82d0394f9a9
--- /dev/null
+++ b/lib/hackvr/data/test.hackvr
@@ -0,0 +1,736 @@
+wall_7_0 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_7_0 rotate 0 0 0
+wall_7_0 move 0 0 16
+wall_7_1 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_7_1 rotate 0 180 0
+wall_7_1 move 0 0 16
+wall_7_2 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_7_2 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_7_2 rotate 0 270 0
+wall_7_2 move 0 0 16
+wall_7_3 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_7_3 rotate 0 90 0
+wall_7_3 move 0 0 16
+wall_8_0 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_8_0 rotate 0 0 0
+wall_8_0 move 16 0 16
+wall_8_1 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_8_1 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_8_1 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_8_1 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_8_1 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_8_1 rotate 0 180 0
+door_close_8_1 move 18 0 8
+wall_8_1 rotate 0 180 0
+wall_8_1 move 16 0 16
+wall_8_2 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_8_2 rotate 0 270 0
+wall_8_2 move 16 0 16
+wall_8_3 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_8_3 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_8_3 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_8_3 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_8_3 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_8_3 rotate 0 90 0
+door_close_8_3 move 8 0 14
+wall_8_3 rotate 0 90 0
+wall_8_3 move 16 0 16
+wall_10_0 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_10_0 rotate 0 0 0
+wall_10_0 move 48 0 16
+wall_10_1 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_10_1 rotate 0 180 0
+wall_10_1 move 48 0 16
+wall_10_2 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_10_2 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_10_2 rotate 0 270 0
+wall_10_2 move 48 0 16
+wall_10_3 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_10_3 rotate 0 90 0
+wall_10_3 move 48 0 16
+wall_11_0 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_11_0 rotate 0 0 0
+wall_11_0 move 64 0 16
+wall_11_1 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_11_1 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_11_1 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_11_1 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_11_1 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_11_1 rotate 0 180 0
+door_close_11_1 move 66 0 8
+wall_11_1 rotate 0 180 0
+wall_11_1 move 64 0 16
+wall_11_2 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_11_2 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_11_2 rotate 0 270 0
+wall_11_2 move 64 0 16
+wall_11_3 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_11_3 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_11_3 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_11_3 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_11_3 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_11_3 rotate 0 90 0
+door_close_11_3 move 56 0 14
+wall_11_3 rotate 0 90 0
+wall_11_3 move 64 0 16
+wall_12_0 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_12_0 rotate 0 0 0
+wall_12_0 move 80 0 16
+wall_12_1 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_12_1 rotate 0 180 0
+wall_12_1 move 80 0 16
+wall_12_2 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_12_2 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_12_2 rotate 0 270 0
+wall_12_2 move 80 0 16
+wall_12_3 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_12_3 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_12_3 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_12_3 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_12_3 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_12_3 rotate 0 90 0
+door_close_12_3 move 72 0 14
+wall_12_3 rotate 0 90 0
+wall_12_3 move 80 0 16
+wall_13_0 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_13_0 rotate 0 0 0
+wall_13_0 move 96 0 16
+wall_13_1 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_13_1 rotate 0 180 0
+wall_13_1 move 96 0 16
+wall_13_2 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_13_2 rotate 0 270 0
+wall_13_2 move 96 0 16
+wall_13_3 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_13_3 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_13_3 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_13_3 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_13_3 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_13_3 rotate 0 90 0
+door_close_13_3 move 88 0 14
+wall_13_3 rotate 0 90 0
+wall_13_3 move 96 0 16
+wall_23_0 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_23_0 rotate 0 0 0
+wall_23_0 move 0 0 0
+wall_23_1 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_23_1 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_23_1 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_23_1 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_23_1 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_23_1 rotate 0 180 0
+door_close_23_1 move 2 0 -8
+wall_23_1 rotate 0 180 0
+wall_23_1 move 0 0 0
+wall_23_2 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_23_2 rotate 0 270 0
+wall_23_2 move 0 0 0
+wall_23_3 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_23_3 rotate 0 90 0
+wall_23_3 move 0 0 0
+wall_24_0 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_24_0 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_24_0 rotate 0 0 0
+wall_24_0 move 16 0 0
+wall_24_1 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_24_1 rotate 0 180 0
+wall_24_1 move 16 0 0
+wall_24_2 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_24_2 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_24_2 rotate 0 270 0
+wall_24_2 move 16 0 0
+wall_24_3 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_24_3 rotate 0 90 0
+wall_24_3 move 16 0 0
+wall_25_0 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_25_0 rotate 0 0 0
+wall_25_0 move 32 0 0
+wall_25_1 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_25_1 rotate 0 180 0
+wall_25_1 move 32 0 0
+wall_25_2 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_25_2 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_25_2 rotate 0 270 0
+wall_25_2 move 32 0 0
+wall_25_3 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_25_3 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_25_3 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_25_3 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_25_3 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_25_3 rotate 0 90 0
+door_close_25_3 move 24 0 -2
+wall_25_3 rotate 0 90 0
+wall_25_3 move 32 0 0
+wall_26_0 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_26_0 rotate 0 0 0
+wall_26_0 move 48 0 0
+wall_26_1 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_26_1 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_26_1 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_26_1 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_26_1 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_26_1 rotate 0 180 0
+door_close_26_1 move 50 0 -8
+wall_26_1 rotate 0 180 0
+wall_26_1 move 48 0 0
+wall_26_2 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_26_2 rotate 0 270 0
+wall_26_2 move 48 0 0
+wall_26_3 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_26_3 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_26_3 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_26_3 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_26_3 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_26_3 rotate 0 90 0
+door_close_26_3 move 40 0 -2
+wall_26_3 rotate 0 90 0
+wall_26_3 move 48 0 0
+wall_27_0 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_27_0 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_27_0 rotate 0 0 0
+wall_27_0 move 64 0 0
+wall_27_1 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_27_1 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_27_1 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_27_1 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_27_1 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_27_1 rotate 0 180 0
+door_close_27_1 move 66 0 -8
+wall_27_1 rotate 0 180 0
+wall_27_1 move 64 0 0
+wall_27_2 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_27_2 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_27_2 rotate 0 270 0
+wall_27_2 move 64 0 0
+wall_27_3 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_27_3 rotate 0 90 0
+wall_27_3 move 64 0 0
+wall_28_0 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_28_0 rotate 0 0 0
+wall_28_0 move 80 0 0
+wall_28_1 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_28_1 rotate 0 180 0
+wall_28_1 move 80 0 0
+wall_28_2 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_28_2 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_28_2 rotate 0 270 0
+wall_28_2 move 80 0 0
+wall_28_3 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_28_3 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_28_3 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_28_3 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_28_3 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_28_3 rotate 0 90 0
+door_close_28_3 move 72 0 -2
+wall_28_3 rotate 0 90 0
+wall_28_3 move 80 0 0
+wall_29_0 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_29_0 rotate 0 0 0
+wall_29_0 move 96 0 0
+wall_29_1 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_29_1 rotate 0 180 0
+wall_29_1 move 96 0 0
+wall_29_2 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_29_2 rotate 0 270 0
+wall_29_2 move 96 0 0
+wall_29_3 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_29_3 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_29_3 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_29_3 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_29_3 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_29_3 rotate 0 90 0
+door_close_29_3 move 88 0 -2
+wall_29_3 rotate 0 90 0
+wall_29_3 move 96 0 0
+wall_39_0 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_39_0 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_39_0 rotate 0 0 0
+wall_39_0 move 0 0 -16
+wall_39_1 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_39_1 rotate 0 180 0
+wall_39_1 move 0 0 -16
+wall_39_2 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_39_2 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_39_2 rotate 0 270 0
+wall_39_2 move 0 0 -16
+wall_39_3 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_39_3 rotate 0 90 0
+wall_39_3 move 0 0 -16
+wall_40_0 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_40_0 rotate 0 0 0
+wall_40_0 move 16 0 -16
+wall_40_1 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_40_1 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_40_1 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_40_1 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_40_1 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_40_1 rotate 0 180 0
+door_close_40_1 move 18 0 -24
+wall_40_1 rotate 0 180 0
+wall_40_1 move 16 0 -16
+wall_40_2 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_40_2 rotate 0 270 0
+wall_40_2 move 16 0 -16
+wall_40_3 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_40_3 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_40_3 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_40_3 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_40_3 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_40_3 rotate 0 90 0
+door_close_40_3 move 8 0 -18
+wall_40_3 rotate 0 90 0
+wall_40_3 move 16 0 -16
+wall_41_0 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_41_0 rotate 0 0 0
+wall_41_0 move 32 0 -16
+wall_41_1 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_41_1 rotate 0 180 0
+wall_41_1 move 32 0 -16
+wall_41_2 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_41_2 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_41_2 rotate 0 270 0
+wall_41_2 move 32 0 -16
+wall_41_3 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_41_3 rotate 0 90 0
+wall_41_3 move 32 0 -16
+wall_42_0 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_42_0 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_42_0 rotate 0 0 0
+wall_42_0 move 48 0 -16
+wall_42_1 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_42_1 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_42_1 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_42_1 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_42_1 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_42_1 rotate 0 180 0
+door_close_42_1 move 50 0 -24
+wall_42_1 rotate 0 180 0
+wall_42_1 move 48 0 -16
+wall_42_2 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_42_2 rotate 0 270 0
+wall_42_2 move 48 0 -16
+wall_42_3 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_42_3 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_42_3 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_42_3 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_42_3 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_42_3 rotate 0 90 0
+door_close_42_3 move 40 0 -18
+wall_42_3 rotate 0 90 0
+wall_42_3 move 48 0 -16
+wall_43_0 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_43_0 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_43_0 rotate 0 0 0
+wall_43_0 move 64 0 -16
+wall_43_1 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_43_1 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_43_1 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_43_1 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_43_1 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_43_1 rotate 0 180 0
+door_close_43_1 move 66 0 -24
+wall_43_1 rotate 0 180 0
+wall_43_1 move 64 0 -16
+wall_43_2 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_43_2 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_43_2 rotate 0 270 0
+wall_43_2 move 64 0 -16
+wall_43_3 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_43_3 rotate 0 90 0
+wall_43_3 move 64 0 -16
+wall_44_0 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_44_0 rotate 0 0 0
+wall_44_0 move 80 0 -16
+wall_44_1 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_44_1 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_44_1 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_44_1 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_44_1 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_44_1 rotate 0 180 0
+door_close_44_1 move 82 0 -24
+wall_44_1 rotate 0 180 0
+wall_44_1 move 80 0 -16
+wall_44_2 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_44_2 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_44_2 rotate 0 270 0
+wall_44_2 move 80 0 -16
+wall_44_3 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_44_3 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_44_3 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_44_3 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_44_3 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_44_3 rotate 0 90 0
+door_close_44_3 move 72 0 -18
+wall_44_3 rotate 0 90 0
+wall_44_3 move 80 0 -16
+wall_45_0 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_45_0 rotate 0 0 0
+wall_45_0 move 96 0 -16
+wall_45_1 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_45_1 rotate 0 180 0
+wall_45_1 move 96 0 -16
+wall_45_2 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_45_2 rotate 0 270 0
+wall_45_2 move 96 0 -16
+wall_45_3 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_45_3 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_45_3 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_45_3 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_45_3 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_45_3 rotate 0 90 0
+door_close_45_3 move 88 0 -18
+wall_45_3 rotate 0 90 0
+wall_45_3 move 96 0 -16
+wall_56_0 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_56_0 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_56_0 rotate 0 0 0
+wall_56_0 move 16 0 -32
+wall_56_1 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_56_1 rotate 0 180 0
+wall_56_1 move 16 0 -32
+wall_56_2 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_56_2 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_56_2 rotate 0 270 0
+wall_56_2 move 16 0 -32
+wall_56_3 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_56_3 rotate 0 90 0
+wall_56_3 move 16 0 -32
+wall_57_0 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_57_0 rotate 0 0 0
+wall_57_0 move 32 0 -32
+wall_57_1 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_57_1 rotate 0 180 0
+wall_57_1 move 32 0 -32
+wall_57_2 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_57_2 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_57_2 rotate 0 270 0
+wall_57_2 move 32 0 -32
+wall_57_3 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_57_3 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_57_3 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_57_3 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_57_3 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_57_3 rotate 0 90 0
+door_close_57_3 move 24 0 -34
+wall_57_3 rotate 0 90 0
+wall_57_3 move 32 0 -32
+wall_58_0 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_58_0 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_58_0 rotate 0 0 0
+wall_58_0 move 48 0 -32
+wall_58_1 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_58_1 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_58_1 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_58_1 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_58_1 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_58_1 rotate 0 180 0
+door_close_58_1 move 50 0 -40
+wall_58_1 rotate 0 180 0
+wall_58_1 move 48 0 -32
+wall_58_2 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_58_2 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_58_2 rotate 0 270 0
+wall_58_2 move 48 0 -32
+wall_58_3 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_58_3 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_58_3 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_58_3 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_58_3 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_58_3 rotate 0 90 0
+door_close_58_3 move 40 0 -34
+wall_58_3 rotate 0 90 0
+wall_58_3 move 48 0 -32
+wall_59_0 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_59_0 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_59_0 rotate 0 0 0
+wall_59_0 move 64 0 -32
+wall_59_1 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_59_1 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_59_1 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_59_1 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_59_1 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_59_1 rotate 0 180 0
+door_close_59_1 move 66 0 -40
+wall_59_1 rotate 0 180 0
+wall_59_1 move 64 0 -32
+wall_59_2 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_59_2 rotate 0 270 0
+wall_59_2 move 64 0 -32
+wall_59_3 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_59_3 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_59_3 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_59_3 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_59_3 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_59_3 rotate 0 90 0
+door_close_59_3 move 56 0 -34
+wall_59_3 rotate 0 90 0
+wall_59_3 move 64 0 -32
+wall_60_0 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_60_0 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_60_0 rotate 0 0 0
+wall_60_0 move 80 0 -32
+wall_60_1 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_60_1 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_60_1 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_60_1 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_60_1 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_60_1 rotate 0 180 0
+door_close_60_1 move 82 0 -40
+wall_60_1 rotate 0 180 0
+wall_60_1 move 80 0 -32
+wall_60_2 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_60_2 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_60_2 rotate 0 270 0
+wall_60_2 move 80 0 -32
+wall_60_3 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_60_3 rotate 0 90 0
+wall_60_3 move 80 0 -32
+wall_61_0 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_61_0 rotate 0 0 0
+wall_61_0 move 96 0 -32
+wall_61_1 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_61_1 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_61_1 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_61_1 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_61_1 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_61_1 rotate 0 180 0
+door_close_61_1 move 98 0 -40
+wall_61_1 rotate 0 180 0
+wall_61_1 move 96 0 -32
+wall_61_2 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_61_2 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_61_2 rotate 0 270 0
+wall_61_2 move 96 0 -32
+wall_61_3 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_61_3 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_61_3 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_61_3 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_61_3 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_61_3 rotate 0 90 0
+door_close_61_3 move 88 0 -34
+wall_61_3 rotate 0 90 0
+wall_61_3 move 96 0 -32
+wall_62_0 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_62_0 rotate 0 0 0
+wall_62_0 move 112 0 -32
+wall_62_1 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_62_1 rotate 0 180 0
+wall_62_1 move 112 0 -32
+wall_62_2 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_62_2 rotate 0 270 0
+wall_62_2 move 112 0 -32
+wall_62_3 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_62_3 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_62_3 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_62_3 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_62_3 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_62_3 rotate 0 90 0
+door_close_62_3 move 104 0 -34
+wall_62_3 rotate 0 90 0
+wall_62_3 move 112 0 -32
+wall_74_0 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_74_0 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_74_0 rotate 0 0 0
+wall_74_0 move 48 0 -48
+wall_74_1 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_74_1 rotate 0 180 0
+wall_74_1 move 48 0 -48
+wall_74_2 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_74_2 rotate 0 270 0
+wall_74_2 move 48 0 -48
+wall_74_3 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_74_3 rotate 0 90 0
+wall_74_3 move 48 0 -48
+wall_75_0 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_75_0 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_75_0 rotate 0 0 0
+wall_75_0 move 64 0 -48
+wall_75_1 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_75_1 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_75_1 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_75_1 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_75_1 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_75_1 rotate 0 180 0
+door_close_75_1 move 66 0 -56
+wall_75_1 rotate 0 180 0
+wall_75_1 move 64 0 -48
+wall_75_2 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_75_2 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_75_2 rotate 0 270 0
+wall_75_2 move 64 0 -48
+wall_75_3 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_75_3 rotate 0 90 0
+wall_75_3 move 64 0 -48
+wall_76_0 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_76_0 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_76_0 rotate 0 0 0
+wall_76_0 move 80 0 -48
+wall_76_1 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_76_1 rotate 0 180 0
+wall_76_1 move 80 0 -48
+wall_76_2 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_76_2 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_76_2 rotate 0 270 0
+wall_76_2 move 80 0 -48
+wall_76_3 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_76_3 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_76_3 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_76_3 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_76_3 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_76_3 rotate 0 90 0
+door_close_76_3 move 72 0 -50
+wall_76_3 rotate 0 90 0
+wall_76_3 move 80 0 -48
+wall_77_0 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_77_0 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_77_0 rotate 0 0 0
+wall_77_0 move 96 0 -48
+wall_77_1 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_77_1 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_77_1 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_77_1 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_77_1 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_77_1 rotate 0 180 0
+door_close_77_1 move 98 0 -56
+wall_77_1 rotate 0 180 0
+wall_77_1 move 96 0 -48
+wall_77_2 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_77_2 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_77_2 rotate 0 270 0
+wall_77_2 move 96 0 -48
+wall_77_3 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_77_3 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_77_3 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_77_3 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_77_3 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_77_3 rotate 0 90 0
+door_close_77_3 move 88 0 -50
+wall_77_3 rotate 0 90 0
+wall_77_3 move 96 0 -48
+wall_78_0 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_78_0 rotate 0 0 0
+wall_78_0 move 112 0 -48
+wall_78_1 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_78_1 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_78_1 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_78_1 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_78_1 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_78_1 rotate 0 180 0
+door_close_78_1 move 114 0 -56
+wall_78_1 rotate 0 180 0
+wall_78_1 move 112 0 -48
+wall_78_2 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_78_2 rotate 0 270 0
+wall_78_2 move 112 0 -48
+wall_78_3 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_78_3 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_78_3 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_78_3 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_78_3 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_78_3 rotate 0 90 0
+door_close_78_3 move 104 0 -50
+wall_78_3 rotate 0 90 0
+wall_78_3 move 112 0 -48
+wall_91_0 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_91_0 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_91_0 rotate 0 0 0
+wall_91_0 move 64 0 -64
+wall_91_1 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_91_1 rotate 0 180 0
+wall_91_1 move 64 0 -64
+wall_91_2 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_91_2 rotate 0 270 0
+wall_91_2 move 64 0 -64
+wall_91_3 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_91_3 rotate 0 90 0
+wall_91_3 move 64 0 -64
+wall_93_0 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_93_0 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_93_0 rotate 0 0 0
+wall_93_0 move 96 0 -64
+wall_93_1 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_93_1 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_93_1 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_93_1 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_93_1 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_93_1 rotate 0 180 0
+door_close_93_1 move 98 0 -72
+wall_93_1 rotate 0 180 0
+wall_93_1 move 96 0 -64
+wall_93_2 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_93_2 rotate 0 270 0
+wall_93_2 move 96 0 -64
+wall_93_3 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_93_3 rotate 0 90 0
+wall_93_3 move 96 0 -64
+wall_94_0 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_94_0 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_94_0 rotate 0 0 0
+wall_94_0 move 112 0 -64
+wall_94_1 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_94_1 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_94_1 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_94_1 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_94_1 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_94_1 rotate 0 180 0
+door_close_94_1 move 114 0 -72
+wall_94_1 rotate 0 180 0
+wall_94_1 move 112 0 -64
+wall_94_2 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_94_2 rotate 0 270 0
+wall_94_2 move 112 0 -64
+wall_94_3 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_94_3 rotate 0 90 0
+wall_94_3 move 112 0 -64
+wall_108_0 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_108_0 rotate 0 0 0
+wall_108_0 move 80 0 -80
+wall_108_1 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_108_1 rotate 0 180 0
+wall_108_1 move 80 0 -80
+wall_108_2 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_108_2 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_108_2 rotate 0 270 0
+wall_108_2 move 80 0 -80
+wall_108_3 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_108_3 rotate 0 90 0
+wall_108_3 move 80 0 -80
+wall_109_0 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_109_0 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_109_0 rotate 0 0 0
+wall_109_0 move 96 0 -80
+wall_109_1 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_109_1 rotate 0 180 0
+wall_109_1 move 96 0 -80
+wall_109_2 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_109_2 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_109_2 rotate 0 270 0
+wall_109_2 move 96 0 -80
+wall_109_3 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_109_3 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_109_3 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_109_3 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_109_3 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_109_3 rotate 0 90 0
+door_close_109_3 move 88 0 -82
+wall_109_3 rotate 0 90 0
+wall_109_3 move 96 0 -80
+wall_110_0 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_110_0 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_110_0 rotate 0 0 0
+wall_110_0 move 112 0 -80
+wall_110_1 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_110_1 rotate 0 180 0
+wall_110_1 move 112 0 -80
+wall_110_2 addshape 2 4  -7 0 7  -7 8 7  7 8 7  7 0 7
+wall_110_2 rotate 0 270 0
+wall_110_2 move 112 0 -80
+wall_110_3 addshape 2 4  -7 0 7  -7 8 7  -2 8 7  -2 0 7
+wall_110_3 addshape 2 4  2 0 7  2 8 7  7 8 7  7 0 7
+wall_110_3 addshape 2 4  -2 0 7  -2 8 7  -2 8 9  -2 0 9
+wall_110_3 addshape 2 4  2 0 9  2 8 9  2 8 7  2 0 7
+door_close_110_3 addshape 3 4  0 0 0  0 8 0  4 8 0  4 0 0
+door_close_110_3 rotate 0 90 0
+door_close_110_3 move 104 0 -82
+wall_110_3 rotate 0 90 0
+wall_110_3 move 112 0 -80
diff --git a/lib/hackvr/lib.zig b/lib/hackvr/lib.zig
index e67fbc81f2444e474339629a4ee147d74b7ef666..
index ..bc89afe6af8875dac8ad4708f5eb392cb6bdb5d1 100644
--- a/lib/hackvr/lib.zig
+++ b/lib/hackvr/lib.zig
@@ -1,16 +1,18 @@
 const std = @import("std");

-pub const parser = @import("parser.zig");
+pub const parsing = @import("parser.zig");

 comptime {
     // include the parser module for tests
-    _ = parser;
+    _ = parsing;
 }

 pub const real = f32;

 pub const Vec3D = struct {
-    x: real, y: real, z: real
+    x: real,
+    y: real,
+    z: real,
 };

 pub const Attribute = struct {
@@ -19,16 +21,224 @@ pub const Attribute = struct {
 };

 pub const Shape3D = struct {
-    pub const Flavor = enum {
-        polygon,
-        elliptic_arc,
-        cubic_bezier,
-        quad_bezier,
-    };
-
-    id: []const u8,
-    flavour: Flavor,
+    /// index into State.groups
+    group: usize,
     points: []Vec3D,
     velocity: Vec3D,
     attributes: Attribute,
 };
+
+pub const Group = struct {
+    const Self = @This();
+
+    name: []const u8,
+
+    /// flat list of all shapes
+    shapes: std.ArrayList(Shape3D),
+
+    pub fn init(allocator: *std.mem.Allocator, name: []const u8) Self {
+        return Self{
+            .name = name,
+            .shapes = std.ArrayList(Shape3D).init(allocator),
+        };
+    }
+
+    pub fn deinit(self: *Self) void {
+        self.shapes.deinit();
+        self.* = undefined;
+    }
+};
+
+pub const State = struct {
+    const Self = @This();
+
+    allocator: *std.mem.Allocator,
+
+    /// storage for shape vertices and group names
+    arena: std.heap.ArenaAllocator,
+
+    /// flat list of all groups
+    groups: std.ArrayList(Group),
+
+    pub fn init(allocator: *std.mem.Allocator) Self {
+        return Self{
+            .allocator = allocator,
+            .arena = std.heap.ArenaAllocator.init(allocator),
+            .groups = std.ArrayList(Group).init(allocator),
+        };
+    }
+
+    pub fn deinit(self: *Self) void {
+        for (self.groups.items) |*group| {
+            group.deinit();
+        }
+        self.groups.deinit();
+        self.arena.deinit();
+        self.* = undefined;
+    }
+
+    pub fn getOrCreateGroup(self: *Self, name: []const u8) !*Group {
+        for (self.groups.items) |*grp| {
+            if (std.mem.eql(u8, grp.name, name)) {
+                return grp;
+            }
+        }
+
+        const name_ptr = try std.mem.dupe(&self.arena.allocator, u8, name);
+        errdefer self.allocator.free(name_ptr);
+
+        const grp = try self.groups.addOne();
+        grp.* = Group.init(self.allocator, name_ptr);
+        return grp;
+    }
+};
+
+pub fn applyEventToState(state: *State, event: parsing.Event) !void {
+    switch (event) {
+        .add_shape => |cmd| {
+            if (isWildcardPattern(cmd.selector.groups))
+                return error.InvalidSelector;
+
+            const grp = try state.getOrCreateGroup(cmd.selector.groups);
+
+            const index = grp.shapes.items.len;
+
+            const shp = try grp.shapes.addOne();
+            errdefer {
+                // Remove the newly created shape
+                _ = grp.shapes.pop();
+            }
+
+            shp.* = Shape3D{
+                .group = index,
+                .velocity = Vec3D{ .x = 0, .y = 0, .z = 0 },
+                .attributes = Attribute{
+                    .color = cmd.color,
+                    .luminance = 200,
+                },
+                .points = try std.mem.dupe(&state.arena.allocator, Vec3D, cmd.polygon),
+            };
+        },
+        else => {
+            std.debug.print("Event {} not implemented yet!\n", .{@as(parsing.EventType, event)});
+        },
+    }
+}
+
+test "state.getOrCreateGroup" {
+    var state = State.init(std.testing.allocator);
+    defer state.deinit();
+
+    const grp1 = try state.getOrCreateGroup("grp");
+    const grp2 = try state.getOrCreateGroup("grp");
+
+    std.testing.expect(grp1 == grp2);
+}
+
+test "applyEventToState (add_shape)" {
+    var state = State.init(std.testing.allocator);
+    defer state.deinit();
+
+    var event = parsing.Event{
+        .add_shape = parsing.AddShapeData{
+            .selector = parsing.Selector{ .groups = "grp" },
+            .color = 123,
+            .polygon = &[_]Vec3D{
+                Vec3D{ .x = 1, .y = 2, .z = 3 },
+                Vec3D{ .x = 4, .y = 5, .z = 6 },
+                Vec3D{ .x = 7, .y = 8, .z = 9 },
+            },
+        },
+    };
+
+    try applyEventToState(&state, event);
+
+    std.testing.expectEqual(@as(usize, 1), state.groups.items.len);
+
+    const grp = &state.groups.items[0];
+    std.testing.expectEqualStrings("grp", grp.name);
+    std.testing.expectEqual(@as(usize, 1), grp.shapes.items.len);
+
+    const shp = &grp.shapes.items[0];
+    std.testing.expectEqual(@as(u8, 123), shp.attributes.color);
+    std.testing.expectEqual(@as(usize, 0), shp.group);
+    std.testing.expectEqualSlices(Vec3D, event.add_shape.polygon, shp.points);
+    std.testing.expectEqual(Vec3D{ .x = 0, .y = 0, .z = 0 }, shp.velocity);
+}
+
+test "Update state with file" {
+    var state = State.init(std.testing.allocator);
+    defer state.deinit();
+
+    var parser = parsing.Parser.init();
+
+    var src: []const u8 = @embedFile("./data/test.hackvr");
+    while (src.len > 0) {
+        var item = try parser.push(src);
+        switch (item) {
+            // should never be reached as the test.hackvr is a complete file, terminated by a LF
+            .needs_data => unreachable,
+
+            // should never be reached as the test.hackvr file is correct
+            .parse_error => unreachable,
+
+            .event => |ev| {
+                src = ev.rest;
+                try applyEventToState(&state, ev.event);
+            },
+        }
+    }
+
+    std.testing.expectEqual(@as(usize, 192), state.groups.items.len);
+}
+
+/// Tests if `group_name` matches the `pattern`.
+/// Pattern may be either a full text or a prefix followed by `*`.
+pub fn wildcardEquals(pattern: []const u8, group_name: []const u8) bool {
+    if (isWildcardPattern(pattern)) {
+        // wildcard match
+        if (pattern.len - 1 > group_name.len)
+            return false;
+        const prefix_len = pattern.len - 1;
+        return std.mem.eql(u8, pattern[0..prefix_len], group_name[0..prefix_len]);
+    } else {
+        // clean
+        return std.mem.eql(u8, pattern, group_name);
+    }
+}
+
+pub fn isWildcardPattern(pattern: []const u8) bool {
+    return (pattern.len > 0) and (pattern[pattern.len - 1] == '*');
+}
+
+test "wildcardEquals empty match" {
+    std.testing.expect(wildcardEquals("", ""));
+}
+
+test "wildcardEquals normal match" {
+    std.testing.expect(wildcardEquals("foobar", "foobar"));
+}
+
+test "wildcardEquals normal mismatch" {
+    std.testing.expect(wildcardEquals("barfoo", "foobar") == false);
+}
+
+test "wildcardEquals pattern too long" {
+    std.testing.expect(wildcardEquals("pattern", "bar") == false);
+}
+
+test "wildcardEquals group_name too long" {
+    std.testing.expect(wildcardEquals("pat", "foobar") == false);
+}
+
+test "wildcardEquals pattern wildcard exact match" {
+    std.testing.expect(wildcardEquals("pat*", "pat"));
+}
+
+test "wildcardEquals pattern wildcard prefix match" {
+    std.testing.expect(wildcardEquals("pat*", "pattern"));
+}
+
+test "wildcardEquals pattern wildcard prefix non-match" {
+    std.testing.expect(wildcardEquals("pattern*", "pat") == false);
+}
diff --git a/lib/hackvr/parser.zig b/lib/hackvr/parser.zig
index d37eeb4d937373131d51f6244c421ee8f2bdcfd3..
index ..f0befa1f730823f8ba855b34a25f04c7729e8f8c 100644
--- a/lib/hackvr/parser.zig
+++ b/lib/hackvr/parser.zig
@@ -309,7 +309,8 @@ pub const PushResult = union(enum) {
         /// while encountering this event.
         /// Feed it into `push` again until .needs_data happens.
         rest: []const u8,
-        event: ?Event,
+
+        event: Event,
     },

     /// A format error happened while processing the data.
@@ -733,3 +734,25 @@ test "parser: cmd move" {
         std.testing.expectEqual(MoveData.Type.down, result.move.direction);
     }
 }
+
+test "parser: whole file" {
+    var parser = Parser.init();
+
+    var src: []const u8 = @embedFile("./data/test.hackvr");
+
+    while (src.len > 0) {
+        var item = try parser.push(src);
+        switch (item) {
+            // should never be reached as the test.hackvr is a complete file, terminated by a LF
+            .needs_data => unreachable,
+
+            // should never be reached as the test.hackvr file is correct
+            .parse_error => unreachable,
+
+            .event => |ev| {
+                src = ev.rest;
+                // std.log.debug(.HackVR, "event: {}\n", .{ev.event});
+            },
+        }
+    }
+}

-----END OF PAGE-----