about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--res/gencharwidth.nim4
-rw-r--r--res/map/charwidth_gen.nim577
-rw-r--r--src/layout/engine.nim13
-rw-r--r--src/layout/renderdocument.nim134
-rw-r--r--src/server/buffer.nim2
-rw-r--r--src/utils/proptable.nim14
-rw-r--r--src/utils/strwidth.nim57
7 files changed, 545 insertions, 256 deletions
diff --git a/res/gencharwidth.nim b/res/gencharwidth.nim
index 3cc0bebd..a171f306 100644
--- a/res/gencharwidth.nim
+++ b/res/gencharwidth.nim
@@ -187,14 +187,14 @@ proc main() =
 
   echo "const DoubleWidthTable: PropertyTable = ["
   for u in DoubleWidthTable:
-    writer.write($u & ",")
+    writer.write($u & "u32,")
   writer.flush()
   echo "]"
   echo ""
 
   echo "const CombiningTable: PropertyTable = ["
   for u in CombiningTable:
-    writer.write($u & ",")
+    writer.write($u & "u32,")
   writer.flush()
   echo "]"
   echo ""
diff --git a/res/map/charwidth_gen.nim b/res/map/charwidth_gen.nim
index 93ee3733..4d32bf44 100644
--- a/res/map/charwidth_gen.nim
+++ b/res/map/charwidth_gen.nim
@@ -59,138 +59,455 @@ const Combining: array[13, tuple[ucs, mapped: uint32]] = [
 ]
 
 const DoubleWidthTable: PropertyTable = [
--1,0,0,-2147483648,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,201326592,1536,0,0,0,0,0,597504,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-1610612736,3145728,0,1048320,-2147483648,524288,1610615810,1065008,606864384,
-3104,256,12079104,0,14680064,-2147418112,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,402653184,0,2162688,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,-67108865,-1,-1,1048575,-1,-1,-1,-1,-1,-1,4194303,268369920,-1,2147483647,
--2,-1,-25165825,-1,-1,-1,-32,-65537,-1,-1,-32769,-1,-1,-65521,2147483647,-1,
--65281,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-57345,-1,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,536870911,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,67043328,-65536,-524289,3967,0,0,0,0,-2,-1,-1,1,0,0,0,127,
+4294967295u32,0u32,0u32,2147483648u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,4294967295u32,
+4294967295u32,4294967295u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,201326592u32,1536u32,0u32,0u32,0u32,0u32,0u32,597504u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+1610612736u32,3145728u32,0u32,1048320u32,2147483648u32,524288u32,1610615810u32,
+1065008u32,606864384u32,3104u32,256u32,12079104u32,0u32,14680064u32,
+2147549184u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,402653184u32,
+0u32,2162688u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,4227858431u32,
+4294967295u32,4294967295u32,1048575u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4194303u32,268369920u32,
+4294967295u32,2147483647u32,4294967294u32,4294967295u32,4269801471u32,
+4294967295u32,4294967295u32,4294967295u32,4294967264u32,4294901759u32,
+4294967295u32,4294967295u32,4294934527u32,4294967295u32,4294967295u32,
+4294901775u32,2147483647u32,4294967295u32,4294902015u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,0u32,0u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294909951u32,4294967295u32,127u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,536870911u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,15u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,4294967295u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,67043328u32,4294901760u32,4294443007u32,3967u32,0u32,0u32,0u32,0u32,
+4294967294u32,4294967295u32,4294967295u32,1u32,0u32,0u32,0u32,127u32,
 ]
 
 const CombiningTable: PropertyTable = [
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,65535,0,0,0,0,0,0,0,0,
-888,0,0,0,0,0,0,0,-131072,-1073741825,182,0,4128783,0,2147481600,65536,0,0,
--4194304,15775,163840,-65536,2047,0,0,131008,0,1046528,0,0,0,0,0,0,0,0,6,
-268435456,1974782,12,2,268435456,8222,12,6,268435456,14726,196608,6,268435456,
-8638,12,2,-1879048192,4202510,0,4,0,8193,0,0,-1073741824,6307265,0,0,
--1879048192,12352,12,0,0,8206,0,0,0,6030336,0,0,133300224,32640,0,0,468844544,
-16128,0,50331648,44040192,0,2147352576,-16842529,536870911,64,0,0,46522368,
-50331648,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,-2147483648,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1835008,1835008,786432,786432,
-0,1068498944,537919040,0,14336,0,0,0,0,512,0,0,0,235143559,0,0,0,0,0,0,25165824,
-0,0,0,0,0,0,0,15,399507456,4,1046528,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2047,
--1073741824,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63488,31744,0,64527,0,0,-65536,
-65535,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,64512,0,0,100663296,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,2112,96,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-1073741824,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65535,15,0,0,0,0,0,
--2147483648,0,0,0,0,0,0,0,234881024,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,4294967295u32,4294967295u32,
+4294967295u32,65535u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,888u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,4294836224u32,3221225471u32,182u32,0u32,4128783u32,
+0u32,2147481600u32,65536u32,0u32,0u32,4290772992u32,15775u32,163840u32,
+4294901760u32,2047u32,0u32,0u32,131008u32,0u32,1046528u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,6u32,268435456u32,1974782u32,12u32,2u32,268435456u32,
+8222u32,12u32,6u32,268435456u32,14726u32,196608u32,6u32,268435456u32,8638u32,
+12u32,2u32,2415919104u32,4202510u32,0u32,4u32,0u32,8193u32,0u32,0u32,
+3221225472u32,6307265u32,0u32,0u32,2415919104u32,12352u32,12u32,0u32,0u32,
+8206u32,0u32,0u32,0u32,6030336u32,0u32,0u32,133300224u32,32640u32,0u32,0u32,
+468844544u32,16128u32,0u32,50331648u32,44040192u32,0u32,2147352576u32,
+4278124767u32,536870911u32,64u32,0u32,0u32,46522368u32,50331648u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,4294967295u32,4294967295u32,4294967295u32,
+4294967295u32,4294967295u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+2147483648u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+1835008u32,1835008u32,786432u32,786432u32,0u32,1068498944u32,537919040u32,0u32,
+14336u32,0u32,0u32,0u32,0u32,512u32,0u32,0u32,0u32,235143559u32,0u32,0u32,0u32,
+0u32,0u32,0u32,25165824u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,15u32,
+399507456u32,4u32,1046528u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,2047u32,3221225472u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,63488u32,
+31744u32,0u32,64527u32,0u32,0u32,4294901760u32,65535u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,64512u32,0u32,0u32,100663296u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,2112u32,96u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+1073741824u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,
+0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,65535u32,15u32,0u32,0u32,0u32,
+0u32,0u32,2147483648u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,234881024u32,
 ]
 
diff --git a/src/layout/engine.nim b/src/layout/engine.nim
index 4c56ffd9..d2d22ab9 100644
--- a/src/layout/engine.nim
+++ b/src/layout/engine.nim
@@ -15,7 +15,7 @@ import utils/widthconv
 
 type
   LayoutState = ref object
-    attrs: WindowAttributes
+    attrsp: ptr WindowAttributes
     positioned: seq[AvailableSpace]
 
   # min-content: box width is longest word's width
@@ -45,6 +45,9 @@ type
     minHeight: LayoutUnit
     maxHeight: LayoutUnit
 
+template attrs(state: LayoutState): WindowAttributes =
+  state.attrsp[]
+
 func maxContent(): SizeConstraint =
   return SizeConstraint(t: MAX_CONTENT)
 
@@ -2774,13 +2777,13 @@ proc generateTableBox(styledNode: StyledNode, lctx: LayoutState,
   box.generateTableChildWrappers()
   return box
 
-proc renderLayout*(root: StyledNode, attrs: WindowAttributes): BlockBox =
+proc renderLayout*(root: StyledNode, attrsp: ptr WindowAttributes): BlockBox =
   let space = AvailableSpace(
-    w: stretch(attrs.width_px),
-    h: stretch(attrs.height_px)
+    w: stretch(attrsp[].width_px),
+    h: stretch(attrsp[].height_px)
   )
   let lctx = LayoutState(
-    attrs: attrs,
+    attrsp: attrsp,
     positioned: @[space]
   )
   let builder = root.generateBlockBox(lctx)
diff --git a/src/layout/renderdocument.nim b/src/layout/renderdocument.nim
index 0313ca2b..ef6504c8 100644
--- a/src/layout/renderdocument.nim
+++ b/src/layout/renderdocument.nim
@@ -29,7 +29,7 @@ type
 
   FlexibleGrid* = seq[FlexibleLine]
 
-func findFormatN*(line: FlexibleLine, pos: int): int =
+func findFormatN*(line: FlexibleLine; pos: int): int =
   var i = 0
   while i < line.formats.len:
     if line.formats[i].pos > pos:
@@ -37,34 +37,17 @@ func findFormatN*(line: FlexibleLine, pos: int): int =
     inc i
   return i
 
-func findFormat*(line: FlexibleLine, pos: int): FormatCell =
-  let i = line.findFormatN(pos) - 1
-  if i != -1:
-    result = line.formats[i]
-  else:
-    result.pos = -1
-
-func findNextFormat*(line: FlexibleLine, pos: int): FormatCell =
-  let i = line.findFormatN(pos)
-  if i < line.formats.len:
-    result = line.formats[i]
-  else:
-    result.pos = -1
-
-proc addLine*(grid: var FlexibleGrid) =
-  grid.add(FlexibleLine())
-
-proc addLines*(grid: var FlexibleGrid, n: int) =
+proc addLines(grid: var FlexibleGrid; n: int) =
   grid.setLen(grid.len + n)
 
-proc insertFormat*(line: var FlexibleLine, i: int, cell: FormatCell) =
+proc insertFormat(line: var FlexibleLine; i: int; cell: FormatCell) =
   line.formats.insert(cell, i)
 
-proc insertFormat*(line: var FlexibleLine, pos, i: int, format: Format,
+proc insertFormat(line: var FlexibleLine; pos, i: int; format: Format;
     node: StyledNode = nil) =
   line.insertFormat(i, FormatCell(format: format, node: node, pos: pos))
 
-proc addFormat*(line: var FlexibleLine, pos: int, format: Format,
+proc addFormat(line: var FlexibleLine; pos: int; format: Format;
     node: StyledNode = nil) =
   line.formats.add(FormatCell(format: format, node: node, pos: pos))
 
@@ -89,8 +72,8 @@ func toFormat(computed: CSSComputedValues): Format =
     flags: flags
   )
 
-proc setText(grid: var FlexibleGrid; linestr: string; x, y: int;
-    format: Format; node: StyledNode) {.inline.} =
+proc setText(grid: var FlexibleGrid; linestr: string; x, y: int; format: Format;
+    node: StyledNode) {.inline.} =
   assert linestr.len != 0
   var i = 0
   var r: Rune
@@ -225,13 +208,23 @@ proc setText(grid: var FlexibleGrid; linestr: string; x, y: int;
   assert grid[y].formats[fi].pos <= nx
   # That's it!
 
-proc setRowWord(grid: var FlexibleGrid; word: InlineAtom; offset: Offset;
-    attrs: WindowAttributes; format: Format; node: StyledNode) =
-  let y = toInt((offset.y + word.offset.y) div attrs.ppl) # y cell
+type RenderState = object
+  # Position of the absolute positioning containing block:
+  # https://drafts.csswg.org/css-position/#absolute-positioning-containing-block
+  absolutePos: seq[Offset]
+  bgcolor: CellColor
+  attrsp: ptr WindowAttributes
+
+template attrs(state: RenderState): WindowAttributes =
+  state.attrsp[]
+
+proc setRowWord(grid: var FlexibleGrid; state: var RenderState;
+    word: InlineAtom; offset: Offset; format: Format; node: StyledNode) =
+  let y = toInt((offset.y + word.offset.y) div state.attrs.ppl) # y cell
   if y < 0:
     # y is outside the canvas, no need to draw
     return
-  var x = toInt((offset.x + word.offset.x) div attrs.ppc) # x cell
+  var x = toInt((offset.x + word.offset.x) div state.attrs.ppc) # x cell
   var i = 0
   var r: Rune
   while x < 0 and i < word.str.len:
@@ -244,12 +237,12 @@ proc setRowWord(grid: var FlexibleGrid; word: InlineAtom; offset: Offset;
     let linestr = word.str.substr(i)
     grid.setText(linestr, x, y, format, node)
 
-proc setSpacing(grid: var FlexibleGrid; spacing: InlineAtom; offset: Offset;
-    attrs: WindowAttributes; format: Format; node: StyledNode) =
-  let y = toInt((offset.y + spacing.offset.y) div attrs.ppl) # y cell
+proc setSpacing(grid: var FlexibleGrid; state: var RenderState;
+    spacing: InlineAtom; offset: Offset; format: Format; node: StyledNode) =
+  let y = toInt((offset.y + spacing.offset.y) div state.attrs.ppl) # y cell
   if y < 0: return # y is outside the canvas, no need to draw
-  var x = toInt((offset.x + spacing.offset.x) div attrs.ppc) # x cell
-  let width = toInt(spacing.size.w div attrs.ppc) # cell width
+  var x = toInt((offset.x + spacing.offset.x) div state.attrs.ppc) # x cell
+  let width = toInt(spacing.size.w div state.attrs.ppc) # cell width
   if x + width < 0:
     return # highest x is outside the canvas, no need to draw
   var i = 0
@@ -260,10 +253,10 @@ proc setSpacing(grid: var FlexibleGrid; spacing: InlineAtom; offset: Offset;
     let linestr = ' '.repeat(width - i)
     grid.setText(linestr, x, y, format, node)
 
-proc paintBackground(grid: var FlexibleGrid; color: CellColor; startx,
-    starty, endx, endy: int; node: StyledNode; attrs: WindowAttributes) =
-  var starty = starty div attrs.ppl
-  var endy = endy div attrs.ppl
+proc paintBackground(grid: var FlexibleGrid; state: var RenderState;
+    color: CellColor; startx, starty, endx, endy: int; node: StyledNode) =
+  var starty = starty div state.attrs.ppl
+  var endy = endy div state.attrs.ppl
 
   if starty > endy:
     swap(starty, endy)
@@ -272,9 +265,9 @@ proc paintBackground(grid: var FlexibleGrid; color: CellColor; startx,
   if starty < 0: starty = 0
   if starty == endy: return # height is 0, no need to paint
 
-  var startx = startx div attrs.ppc
+  var startx = startx div state.attrs.ppc
 
-  var endx = endx div attrs.ppc
+  var endx = endx div state.attrs.ppc
   if endy < 0: endy = 0
 
   if startx > endx:
@@ -335,17 +328,11 @@ proc paintBackground(grid: var FlexibleGrid; color: CellColor; startx,
         grid[y].formats[fi].format.bgcolor = color
         grid[y].formats[fi].node = node
 
-type RenderState = object
-  # Position of the absolute positioning containing block:
-  # https://drafts.csswg.org/css-position/#absolute-positioning-containing-block
-  absolutePos: seq[Offset]
-  bgcolor: CellColor
-
 proc renderBlockBox(grid: var FlexibleGrid; state: var RenderState;
-  box: BlockBox; offset: Offset; attrs: WindowAttributes)
+  box: BlockBox; offset: Offset)
 
-proc paintInlineFragment(grid: var FlexibleGrid; fragment: InlineFragment;
-    offset: Offset; bgcolor: CellColor; attrs: WindowAttributes) =
+proc paintInlineFragment(grid: var FlexibleGrid; state: var RenderState;
+    fragment: InlineFragment; offset: Offset; bgcolor: CellColor) =
   let x = offset.x
   let y = offset.y
   let node = fragment.node
@@ -354,31 +341,31 @@ proc paintInlineFragment(grid: var FlexibleGrid; fragment: InlineFragment;
     let y0 = toInt(y + fragment.endOffset.y)
     let x1 = toInt(x + fragment.endOffset.x)
     let y1 = toInt(y + fragment.startOffset.y)
-    grid.paintBackground(bgcolor, x0, y0, x1, y1, node, attrs)
+    grid.paintBackground(state, bgcolor, x0, y0, x1, y1, node)
   else:
     let x0 = toInt(x + fragment.startOffset.x)
     let y0 = toInt(y)
     let x1 = toInt(x + fragment.size.w)
     let y1 = toInt(y + fragment.startOffset.y)
-    grid.paintBackground(bgcolor, x0, y0, x1, y1, node, attrs)
+    grid.paintBackground(state, bgcolor, x0, y0, x1, y1, node)
     let x2 = toInt(x)
     let y2 = y1
     let x3 = x1
     let y3 = toInt(y + fragment.endOffset.y)
-    grid.paintBackground(bgcolor, x2, y2, x3, y3, node, attrs)
+    grid.paintBackground(state, bgcolor, x2, y2, x3, y3, node)
     let x4 = x2
     let y4 = y3
     let x5 = toInt(x + fragment.endOffset.x)
     let y5 = toInt(y + fragment.size.h)
-    grid.paintBackground(bgcolor, x4, y4, x5, y5, node, attrs)
+    grid.paintBackground(state, bgcolor, x4, y4, x5, y5, node)
 
-proc renderInlineFragment(grid: var FlexibleGrid; state: var RenderState,
-    fragment: InlineFragment; offset: Offset; attrs: WindowAttributes) =
+proc renderInlineFragment(grid: var FlexibleGrid; state: var RenderState;
+    fragment: InlineFragment; offset: Offset) =
   assert fragment.atoms.len == 0 or fragment.children.len == 0
   let bgcolor = fragment.computed{"background-color"}
   if bgcolor.t == ctANSI or bgcolor.t == ctRGB and bgcolor.rgbacolor.a > 0:
     #TODO color blending
-    grid.paintInlineFragment(fragment, offset, bgcolor, attrs)
+    grid.paintInlineFragment(state, fragment, offset, bgcolor)
   if fragment.atoms.len > 0:
     let format = fragment.computed.toFormat()
     for atom in fragment.atoms:
@@ -388,11 +375,11 @@ proc renderInlineFragment(grid: var FlexibleGrid; state: var RenderState,
           x: offset.x + atom.offset.x,
           y: offset.y + atom.offset.y
         )
-        grid.renderBlockBox(state, atom.innerbox, offset, attrs)
+        grid.renderBlockBox(state, atom.innerbox, offset)
       of INLINE_WORD:
-        grid.setRowWord(atom, offset, attrs, format, fragment.node)
+        grid.setRowWord(state, atom, offset, format, fragment.node)
       of INLINE_SPACING:
-        grid.setSpacing(atom, offset, attrs, format, fragment.node)
+        grid.setSpacing(state, atom, offset, format, fragment.node)
   if fragment.computed{"position"} != POSITION_STATIC:
     if fragment.splitType != {stSplitStart, stSplitEnd}:
       if stSplitStart in fragment.splitType:
@@ -403,18 +390,18 @@ proc renderInlineFragment(grid: var FlexibleGrid; state: var RenderState,
       if stSplitEnd in fragment.splitType:
         discard state.absolutePos.pop()
   for child in fragment.children:
-    grid.renderInlineFragment(state, child, offset, attrs)
+    grid.renderInlineFragment(state, child, offset)
 
 proc renderRootInlineFragment(grid: var FlexibleGrid; state: var RenderState;
-    root: RootInlineFragment; offset: Offset; attrs: WindowAttributes) =
+    root: RootInlineFragment; offset: Offset) =
   let offset = Offset(
     x: offset.x + root.offset.x,
     y: offset.y + root.offset.y
   )
-  grid.renderInlineFragment(state, root.fragment, offset, attrs)
+  grid.renderInlineFragment(state, root.fragment, offset)
 
 proc renderBlockBox(grid: var FlexibleGrid; state: var RenderState;
-    box: BlockBox; offset: Offset; attrs: WindowAttributes) =
+    box: BlockBox; offset: Offset) =
   var stack = newSeqOfCap[tuple[
     box: BlockBox,
     offset: Offset
@@ -448,19 +435,19 @@ proc renderBlockBox(grid: var FlexibleGrid; state: var RenderState;
         let iy = toInt(offset.y)
         let iex = toInt(offset.x + box.size.w)
         let iey = toInt(offset.y + box.size.h)
-        grid.paintBackground(bgcolor, ix, iy, iex, iey, box.node, attrs)
+        grid.paintBackground(state, bgcolor, ix, iy, iex, iey, box.node)
       if box.computed{"background-image"}.t == CONTENT_IMAGE and
           box.computed{"background-image"}.s != "":
         # ugly hack for background-image display... TODO actually display images
         let s = "[img]"
-        let w = s.len * attrs.ppc
+        let w = s.len * state.attrs.ppc
         var ix = offset.x
         if box.size.w < w:
           # text is larger than image; center it to minimize error
           ix -= w div 2
           ix += box.size.w div 2
-        let x = toInt(ix div attrs.ppc)
-        let y = toInt(offset.y div attrs.ppl)
+        let x = toInt(ix div state.attrs.ppc)
+        let y = toInt(offset.y div state.attrs.ppl)
         if y >= 0 and x + w >= 0:
           grid.setText(s, x, y, box.computed.toFormat(), box.node)
 
@@ -471,24 +458,25 @@ proc renderBlockBox(grid: var FlexibleGrid; state: var RenderState;
             x: offset.x - box.marker.size.w,
             y: offset.y
           )
-          grid.renderRootInlineFragment(state, box.marker, offset, attrs)
+          grid.renderRootInlineFragment(state, box.marker, offset)
 
     if box.inline != nil:
       assert box.nested.len == 0
       if box.computed{"visibility"} == VISIBILITY_VISIBLE:
-        grid.renderRootInlineFragment(state, box.inline, offset, attrs)
+        grid.renderRootInlineFragment(state, box.inline, offset)
     else:
       for i in countdown(box.nested.high, 0):
         stack.add((box.nested[i], offset))
 
 proc renderDocument*(grid: var FlexibleGrid; bgcolor: var CellColor;
-    styledRoot: StyledNode; attrs: WindowAttributes) =
+    styledRoot: StyledNode, attrsp: ptr WindowAttributes) =
   grid.setLen(0)
   var state = RenderState(
-    absolutePos: @[Offset(x: 0, y: 0)]
+    absolutePos: @[Offset(x: 0, y: 0)],
+    attrsp: attrsp
   )
-  let rootBox = renderLayout(styledRoot, attrs)
-  grid.renderBlockBox(state, rootBox, Offset(x: 0, y: 0), attrs)
+  let rootBox = renderLayout(styledRoot, attrsp)
+  grid.renderBlockBox(state, rootBox, Offset(x: 0, y: 0))
   if grid.len == 0:
-    grid.addLine()
+    grid.addLines(1)
   bgcolor = state.bgcolor
diff --git a/src/server/buffer.nim b/src/server/buffer.nim
index 32592076..749c31d8 100644
--- a/src/server/buffer.nim
+++ b/src/server/buffer.nim
@@ -641,7 +641,7 @@ proc do_reshape(buffer: Buffer) =
     buffer.prevStyled = nil
   let styledRoot = buffer.document.applyStylesheets(uastyle,
     buffer.userstyle, buffer.prevStyled)
-  buffer.lines.renderDocument(buffer.bgcolor, styledRoot, buffer.attrs)
+  buffer.lines.renderDocument(buffer.bgcolor, styledRoot, addr buffer.attrs)
   buffer.prevStyled = styledRoot
 
 proc processData0(buffer: Buffer, data: openArray[char]): bool =
diff --git a/src/utils/proptable.nim b/src/utils/proptable.nim
index a34459a8..0087dd80 100644
--- a/src/utils/proptable.nim
+++ b/src/utils/proptable.nim
@@ -1,12 +1,10 @@
-import std/unicode
-
 # Lookup tables for characters on the BMP. This "only" takes up 8k of space
 # per table, as opposed to the 135k that storing all characters would require.
 # The downside is obviously that we need a binary search fallback for non-bmp.
 # We do not store a lookup table of ambiguous ranges, either.
 
 type
-  ptint* = int32
+  ptint* = uint32
   PropertyTable* = array[0x10000 div (sizeof(ptint) * 8), ptint]
   RangeMap* = openArray[(uint32, uint32)]
 
@@ -32,9 +30,9 @@ func makePropertyTable*(ranges: RangeMap, skip: RangeMap = @[]): PropertyTable =
     inc ucs
 
 {.push boundChecks:off.}
-func contains*(props: PropertyTable, r: Rune): bool =
-  let u = ptint(r)
-  let i = u div (sizeof(ptint) * 8)
-  let m = u mod (sizeof(ptint) * 8)
-  return (props[i] and (1 shl m)) != 0
+func contains*(props: PropertyTable, u: ptint): bool {.inline.} =
+  const isz = sizeof(ptint) * 8
+  let i = u div isz
+  let m = u mod isz
+  return (props[i] and (1u32 shl m)) != 0
 {.pop.}
diff --git a/src/utils/strwidth.nim b/src/utils/strwidth.nim
index 5ce2ba52..9cb115cc 100644
--- a/src/utils/strwidth.nim
+++ b/src/utils/strwidth.nim
@@ -7,48 +7,31 @@ import utils/map
 
 include res/map/charwidth_gen
 
-func isDoubleWidthHigh(r: Rune): bool =
-  return DoubleWidthRanges.isInRange(uint32(r))
-
-func isDoubleWidthAmbiguousHigh(r: Rune): bool =
-  # binary search in table of non-spacing characters
-  if DoubleWidthAmbiguousRanges.isInRange(uint32(r)):
-    return true
-  return r.isDoubleWidthHigh()
-
-func isCombining(r: Rune): bool =
-  return Combining.isInRange(uint32(r))
-
 # One of the few global variables in the code. Honestly, it should not exist.
-var is_cjk_ambiguous = false
+var isCJKAmbiguous = false
 proc set_cjk_ambiguous*(b: bool) =
-  is_cjk_ambiguous = b
+  isCJKAmbiguous = b
 
 # Warning: this shouldn't be called without normalization.
-# We could make this function more efficient in edge cases, but it's already
-# too complex for my taste.
 func width*(r: Rune): int =
-  {.cast(noSideEffect).}:
-    let u = uint32(r)
-    if u <= 0xFFFF:
-      if r in CombiningTable:
-        return 0
-      if not is_cjk_ambiguous:
-        if r in DoubleWidthTable:
-          return 2
-      else:
-        if r in DoubleWidthTable or DoubleWidthAmbiguousRanges.isInRange(u):
-          return 2
-    else:
-      if r.isCombining():
-        return 0
-      if not is_cjk_ambiguous:
-        if r.isDoubleWidthHigh():
-          return 2
-      else:
-        if r.isDoubleWidthAmbiguousHigh():
-          return 2
-    return 1
+  let u = uint32(r)
+  if u <= 0xFFFF: # fast path for BMP
+    if u in CombiningTable:
+      return 0
+    if u in DoubleWidthTable:
+      return 2
+    {.cast(noSideEffect).}:
+      if isCJKAmbiguous and DoubleWidthAmbiguousRanges.isInRange(u):
+        return 2
+  else:
+    if Combining.isInRange(u):
+      return 0
+    if DoubleWidthRanges.isInRange(u):
+      return 2
+    {.cast(noSideEffect).}:
+      if isCJKAmbiguous and DoubleWidthAmbiguousRanges.isInRange(u):
+        return 2
+  return 1
 
 # Width, but also works with tabs.
 # Needs the column width of the text so far.