diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..8ad74f7
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,2 @@
+# Normalize EOL for all files that Git considers text files.
+* text=auto eol=lf
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..0af181c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+# Godot 4+ specific ignores
+.godot/
+/android/
diff --git a/TheProject.html b/TheProject.html
new file mode 100644
index 0000000..499dbce
--- /dev/null
+++ b/TheProject.html
@@ -0,0 +1,73 @@
+
+The World Wide Web project
+
+
+
+World Wide Web The WorldWideWeb (W3) is a wide-area
+hypermedia information retrieval
+initiative aiming to give universal
+access to a large universe of documents.
+Everything there is online about
+W3 is linked directly or indirectly
+to this document, including an executive
+summary of the project, Mailing lists
+, Policy , November's W3 news ,
+Frequently Asked Questions .
+
+What's out there?
+ Pointers to the
+world's online information, subjects
+, W3 servers , etc.
+ Help
+ on the browser you are using
+ Software Products
+ A list of W3 project
+components and their current state.
+(e.g. Line Mode ,X11 Viola , NeXTStep
+, Servers , Tools , Mail robot ,
+Library )
+ Technical
+ Details of protocols, formats,
+program internals etc
+ Bibliography
+ Paper documentation
+on W3 and references.
+ People
+ A list of some people involved
+in the project.
+ History
+ A summary of the history
+of the project.
+ How can I help ?
+ If you would like
+to support the web..
+ Getting code
+ Getting the code by
+anonymous FTP , etc.
+
+
diff --git a/document.tscn b/document.tscn
new file mode 100644
index 0000000..46dd8cb
--- /dev/null
+++ b/document.tscn
@@ -0,0 +1,658 @@
+[gd_scene format=3 uid="uid://qs3uqv4jnev3"]
+
+[node name="Root" type="Node"]
+
+[node name="Document" type="Node" parent="."]
+
+[node name="root-685" type="Control" parent="Document"]
+layout_mode = 3
+anchors_preset = 0
+offset_right = 621.5
+offset_bottom = 646.0
+
+[node name="body-903" type="Control" parent="Document/root-685"]
+anchors_preset = 0
+offset_left = 5.0
+offset_top = 5.0
+offset_right = 621.5
+offset_bottom = 646.0
+
+[node name="h1-864" type="Control" parent="Document/root-685/body-903"]
+anchors_preset = 0
+offset_top = 20.0
+offset_right = 240.5
+offset_bottom = 62.0
+
+[node name="TEXT-604" type="Label" parent="Document/root-685/body-903/h1-864"]
+layout_mode = 0
+offset_right = 239.0
+offset_bottom = 42.0
+theme_override_colors/font_color = Color(0, 0, 0, 1)
+theme_override_font_sizes/font_size = 30
+text = "World Wide Web"
+
+[node name="INLINE-563" type="Control" parent="Document/root-685/body-903"]
+anchors_preset = 0
+offset_top = 82.0
+offset_right = 183.5
+offset_bottom = 128.0
+
+[node name="TEXT-924" type="Label" parent="Document/root-685/body-903/INLINE-563"]
+layout_mode = 0
+offset_right = 304.0
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 0, 1)
+theme_override_font_sizes/font_size = 16
+text = "The WorldWideWeb (W3) is a wide-area"
+
+[node name="a-151" type="Label" parent="Document/root-685/body-903/INLINE-563"]
+layout_mode = 0
+offset_left = 305.5
+offset_right = 399.5
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 1, 1)
+theme_override_font_sizes/font_size = 16
+text = "hypermedia"
+
+[node name="TEXT-182" type="Label" parent="Document/root-685/body-903/INLINE-563"]
+layout_mode = 0
+offset_left = 401.0
+offset_right = 963.0
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 0, 1)
+theme_override_font_sizes/font_size = 16
+text = "information retrieval initiative aiming to give universal access to a large "
+
+[node name="TEXT-297" type="Label" parent="Document/root-685/body-903/INLINE-563"]
+layout_mode = 0
+offset_top = 23.0
+offset_right = 182.0
+offset_bottom = 46.0
+theme_override_colors/font_color = Color(0, 0, 0, 1)
+theme_override_font_sizes/font_size = 16
+text = "universe of documents."
+
+[node name="p-527" type="Control" parent="Document/root-685/body-903"]
+anchors_preset = 0
+offset_top = 138.0
+offset_right = 616.5
+offset_bottom = 184.0
+
+[node name="TEXT-587" type="Label" parent="Document/root-685/body-903/p-527"]
+layout_mode = 0
+offset_right = 748.0
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 0, 1)
+theme_override_font_sizes/font_size = 16
+text = "Everything there is online about W3 is linked directly or indirectly to this document, including an"
+
+[node name="a-34" type="Label" parent="Document/root-685/body-903/p-527"]
+layout_mode = 0
+offset_left = 749.5
+offset_right = 902.5
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 1, 1)
+theme_override_font_sizes/font_size = 16
+text = "executive summary"
+
+[node name="TEXT-340" type="Label" parent="Document/root-685/body-903/p-527"]
+layout_mode = 0
+offset_left = 904.0
+offset_right = 954.0
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 0, 1)
+theme_override_font_sizes/font_size = 16
+text = "of the "
+
+[node name="TEXT-529" type="Label" parent="Document/root-685/body-903/p-527"]
+layout_mode = 0
+offset_top = 23.0
+offset_right = 59.0
+offset_bottom = 46.0
+theme_override_colors/font_color = Color(0, 0, 0, 1)
+theme_override_font_sizes/font_size = 16
+text = "project,"
+
+[node name="a-202" type="Label" parent="Document/root-685/body-903/p-527"]
+layout_mode = 0
+offset_left = 60.5
+offset_top = 23.0
+offset_right = 152.5
+offset_bottom = 46.0
+theme_override_colors/font_color = Color(0, 0, 1, 1)
+theme_override_font_sizes/font_size = 16
+text = "Mailing lists"
+
+[node name="TEXT-45" type="Label" parent="Document/root-685/body-903/p-527"]
+layout_mode = 0
+offset_left = 154.0
+offset_top = 23.0
+offset_right = 159.0
+offset_bottom = 46.0
+theme_override_colors/font_color = Color(0, 0, 0, 1)
+theme_override_font_sizes/font_size = 16
+text = ","
+
+[node name="a-391" type="Label" parent="Document/root-685/body-903/p-527"]
+layout_mode = 0
+offset_left = 160.5
+offset_top = 23.0
+offset_right = 206.5
+offset_bottom = 46.0
+theme_override_colors/font_color = Color(0, 0, 1, 1)
+theme_override_font_sizes/font_size = 16
+text = "Policy"
+
+[node name="TEXT-480" type="Label" parent="Document/root-685/body-903/p-527"]
+layout_mode = 0
+offset_left = 208.0
+offset_top = 23.0
+offset_right = 311.0
+offset_bottom = 46.0
+theme_override_colors/font_color = Color(0, 0, 0, 1)
+theme_override_font_sizes/font_size = 16
+text = ", November's"
+
+[node name="a-867" type="Label" parent="Document/root-685/body-903/p-527"]
+layout_mode = 0
+offset_left = 312.5
+offset_top = 23.0
+offset_right = 382.5
+offset_bottom = 46.0
+theme_override_colors/font_color = Color(0, 0, 1, 1)
+theme_override_font_sizes/font_size = 16
+text = "W3 news"
+
+[node name="TEXT-749" type="Label" parent="Document/root-685/body-903/p-527"]
+layout_mode = 0
+offset_left = 384.0
+offset_top = 23.0
+offset_right = 389.0
+offset_bottom = 46.0
+theme_override_colors/font_color = Color(0, 0, 0, 1)
+theme_override_font_sizes/font_size = 16
+text = ","
+
+[node name="a-39" type="Label" parent="Document/root-685/body-903/p-527"]
+layout_mode = 0
+offset_left = 390.5
+offset_top = 23.0
+offset_right = 608.5
+offset_bottom = 46.0
+theme_override_colors/font_color = Color(0, 0, 1, 1)
+theme_override_font_sizes/font_size = 16
+text = "Frequently Asked Questions"
+
+[node name="TEXT-481" type="Label" parent="Document/root-685/body-903/p-527"]
+layout_mode = 0
+offset_left = 610.0
+offset_top = 23.0
+offset_right = 615.0
+offset_bottom = 46.0
+theme_override_colors/font_color = Color(0, 0, 0, 1)
+theme_override_font_sizes/font_size = 16
+text = "."
+
+[node name="dl-693" type="Control" parent="Document/root-685/body-903"]
+anchors_preset = 0
+offset_top = 204.0
+offset_right = 570.5
+offset_bottom = 641.0
+
+[node name="dt-368" type="Control" parent="Document/root-685/body-903/dl-693"]
+anchors_preset = 0
+offset_right = 139.5
+offset_bottom = 23.0
+
+[node name="a-803" type="Label" parent="Document/root-685/body-903/dl-693/dt-368"]
+layout_mode = 0
+offset_right = 138.0
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 1, 1)
+theme_override_font_sizes/font_size = 16
+text = "What's out there?"
+
+[node name="dd-251" type="Control" parent="Document/root-685/body-903/dl-693"]
+anchors_preset = 0
+offset_left = 40.0
+offset_top = 23.0
+offset_right = 570.5
+offset_bottom = 46.0
+
+[node name="TEXT-648" type="Label" parent="Document/root-685/body-903/dl-693/dd-251"]
+layout_mode = 0
+offset_right = 331.0
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 0, 1)
+theme_override_font_sizes/font_size = 16
+text = "Pointers to the world's online information,"
+
+[node name="a-790" type="Label" parent="Document/root-685/body-903/dl-693/dd-251"]
+layout_mode = 0
+offset_left = 332.5
+offset_right = 396.5
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 1, 1)
+theme_override_font_sizes/font_size = 16
+text = "subjects"
+
+[node name="TEXT-956" type="Label" parent="Document/root-685/body-903/dl-693/dd-251"]
+layout_mode = 0
+offset_left = 398.0
+offset_right = 403.0
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 0, 1)
+theme_override_font_sizes/font_size = 16
+text = ","
+
+[node name="a-821" type="Label" parent="Document/root-685/body-903/dl-693/dd-251"]
+layout_mode = 0
+offset_left = 404.5
+offset_right = 490.5
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 1, 1)
+theme_override_font_sizes/font_size = 16
+text = "W3 servers"
+
+[node name="TEXT-65" type="Label" parent="Document/root-685/body-903/dl-693/dd-251"]
+layout_mode = 0
+offset_left = 492.0
+offset_right = 529.0
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 0, 1)
+theme_override_font_sizes/font_size = 16
+text = ", etc."
+
+[node name="dt-660" type="Control" parent="Document/root-685/body-903/dl-693"]
+anchors_preset = 0
+offset_top = 46.0
+offset_right = 37.5
+offset_bottom = 69.0
+
+[node name="a-615" type="Label" parent="Document/root-685/body-903/dl-693/dt-660"]
+layout_mode = 0
+offset_right = 36.0
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 1, 1)
+theme_override_font_sizes/font_size = 16
+text = "Help"
+
+[node name="dd-487" type="Control" parent="Document/root-685/body-903/dl-693"]
+anchors_preset = 0
+offset_left = 40.0
+offset_top = 69.0
+offset_right = 269.5
+offset_bottom = 92.0
+
+[node name="TEXT-928" type="Label" parent="Document/root-685/body-903/dl-693/dd-487"]
+layout_mode = 0
+offset_right = 228.0
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 0, 1)
+theme_override_font_sizes/font_size = 16
+text = "on the browser you are using"
+
+[node name="dt-663" type="Control" parent="Document/root-685/body-903/dl-693"]
+anchors_preset = 0
+offset_top = 92.0
+offset_right = 144.5
+offset_bottom = 115.0
+
+[node name="a-325" type="Label" parent="Document/root-685/body-903/dl-693/dt-663"]
+layout_mode = 0
+offset_right = 143.0
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 1, 1)
+theme_override_font_sizes/font_size = 16
+text = "Software Products"
+
+[node name="dd-554" type="Control" parent="Document/root-685/body-903/dl-693"]
+anchors_preset = 0
+offset_left = 40.0
+offset_top = 115.0
+offset_right = 104.0
+offset_bottom = 161.0
+
+[node name="TEXT-601" type="Label" parent="Document/root-685/body-903/dl-693/dd-554"]
+layout_mode = 0
+offset_right = 471.0
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 0, 1)
+theme_override_font_sizes/font_size = 16
+text = "A list of W3 project components and their current state. (e.g."
+
+[node name="a-468" type="Label" parent="Document/root-685/body-903/dl-693/dd-554"]
+layout_mode = 0
+offset_left = 472.5
+offset_right = 553.5
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 1, 1)
+theme_override_font_sizes/font_size = 16
+text = "Line Mode"
+
+[node name="TEXT-293" type="Label" parent="Document/root-685/body-903/dl-693/dd-554"]
+layout_mode = 0
+offset_left = 555.0
+offset_right = 588.0
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 0, 1)
+theme_override_font_sizes/font_size = 16
+text = ",X11"
+
+[node name="a-271" type="Label" parent="Document/root-685/body-903/dl-693/dd-554"]
+layout_mode = 0
+offset_left = 589.5
+offset_right = 627.5
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 1, 1)
+theme_override_font_sizes/font_size = 16
+text = "Viola"
+
+[node name="TEXT-223" type="Label" parent="Document/root-685/body-903/dl-693/dd-554"]
+layout_mode = 0
+offset_left = 629.0
+offset_right = 634.0
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 0, 1)
+theme_override_font_sizes/font_size = 16
+text = ","
+
+[node name="a-315" type="Label" parent="Document/root-685/body-903/dl-693/dd-554"]
+layout_mode = 0
+offset_left = 635.5
+offset_right = 711.5
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 1, 1)
+theme_override_font_sizes/font_size = 16
+text = "NeXTStep"
+
+[node name="TEXT-203" type="Label" parent="Document/root-685/body-903/dl-693/dd-554"]
+layout_mode = 0
+offset_left = 713.0
+offset_right = 718.0
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 0, 1)
+theme_override_font_sizes/font_size = 16
+text = ","
+
+[node name="a-216" type="Label" parent="Document/root-685/body-903/dl-693/dd-554"]
+layout_mode = 0
+offset_left = 719.5
+offset_right = 777.5
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 1, 1)
+theme_override_font_sizes/font_size = 16
+text = "Servers"
+
+[node name="TEXT-467" type="Label" parent="Document/root-685/body-903/dl-693/dd-554"]
+layout_mode = 0
+offset_left = 779.0
+offset_right = 784.0
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 0, 1)
+theme_override_font_sizes/font_size = 16
+text = ","
+
+[node name="a-611" type="Label" parent="Document/root-685/body-903/dl-693/dd-554"]
+layout_mode = 0
+offset_left = 785.5
+offset_right = 826.5
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 1, 1)
+theme_override_font_sizes/font_size = 16
+text = "Tools"
+
+[node name="TEXT-194" type="Label" parent="Document/root-685/body-903/dl-693/dd-554"]
+layout_mode = 0
+offset_left = 828.0
+offset_right = 833.0
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 0, 1)
+theme_override_font_sizes/font_size = 16
+text = ","
+
+[node name="a-69" type="Label" parent="Document/root-685/body-903/dl-693/dd-554"]
+layout_mode = 0
+offset_left = 834.5
+offset_right = 915.5
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 1, 1)
+theme_override_font_sizes/font_size = 16
+text = "Mail robot"
+
+[node name="TEXT-823" type="Label" parent="Document/root-685/body-903/dl-693/dd-554"]
+layout_mode = 0
+offset_left = 917.0
+offset_right = 922.0
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 0, 1)
+theme_override_font_sizes/font_size = 16
+text = ","
+
+[node name="a-529" type="Label" parent="Document/root-685/body-903/dl-693/dd-554"]
+layout_mode = 0
+offset_left = 923.5
+offset_right = 924.5
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 1, 1)
+theme_override_font_sizes/font_size = 16
+
+[node name="a-76" type="Label" parent="Document/root-685/body-903/dl-693/dd-554"]
+layout_mode = 0
+offset_top = 23.0
+offset_right = 55.0
+offset_bottom = 46.0
+theme_override_colors/font_color = Color(0, 0, 1, 1)
+theme_override_font_sizes/font_size = 16
+text = "Library"
+
+[node name="TEXT-794" type="Label" parent="Document/root-685/body-903/dl-693/dd-554"]
+layout_mode = 0
+offset_left = 56.5
+offset_top = 23.0
+offset_right = 62.5
+offset_bottom = 46.0
+theme_override_colors/font_color = Color(0, 0, 0, 1)
+theme_override_font_sizes/font_size = 16
+text = ")"
+
+[node name="dt-715" type="Control" parent="Document/root-685/body-903/dl-693"]
+anchors_preset = 0
+offset_top = 161.0
+offset_right = 74.5
+offset_bottom = 184.0
+
+[node name="a-506" type="Label" parent="Document/root-685/body-903/dl-693/dt-715"]
+layout_mode = 0
+offset_right = 73.0
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 1, 1)
+theme_override_font_sizes/font_size = 16
+text = "Technical"
+
+[node name="dd-794" type="Control" parent="Document/root-685/body-903/dl-693"]
+anchors_preset = 0
+offset_left = 40.0
+offset_top = 184.0
+offset_right = 440.5
+offset_bottom = 207.0
+
+[node name="TEXT-321" type="Label" parent="Document/root-685/body-903/dl-693/dd-794"]
+layout_mode = 0
+offset_right = 399.0
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 0, 1)
+theme_override_font_sizes/font_size = 16
+text = "Details of protocols, formats, program internals etc"
+
+[node name="dt-702" type="Control" parent="Document/root-685/body-903/dl-693"]
+anchors_preset = 0
+offset_top = 207.0
+offset_right = 99.5
+offset_bottom = 230.0
+
+[node name="a-109" type="Label" parent="Document/root-685/body-903/dl-693/dt-702"]
+layout_mode = 0
+offset_right = 98.0
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 1, 1)
+theme_override_font_sizes/font_size = 16
+text = "Bibliography"
+
+[node name="dd-615" type="Control" parent="Document/root-685/body-903/dl-693"]
+anchors_preset = 0
+offset_left = 40.0
+offset_top = 230.0
+offset_right = 389.5
+offset_bottom = 253.0
+
+[node name="TEXT-842" type="Label" parent="Document/root-685/body-903/dl-693/dd-615"]
+layout_mode = 0
+offset_right = 348.0
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 0, 1)
+theme_override_font_sizes/font_size = 16
+text = "Paper documentation on W3 and references."
+
+[node name="dt-153" type="Control" parent="Document/root-685/body-903/dl-693"]
+anchors_preset = 0
+offset_top = 253.0
+offset_right = 54.5
+offset_bottom = 276.0
+
+[node name="a-969" type="Label" parent="Document/root-685/body-903/dl-693/dt-153"]
+layout_mode = 0
+offset_right = 53.0
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 1, 1)
+theme_override_font_sizes/font_size = 16
+text = "People"
+
+[node name="dd-652" type="Control" parent="Document/root-685/body-903/dl-693"]
+anchors_preset = 0
+offset_left = 40.0
+offset_top = 276.0
+offset_right = 386.5
+offset_bottom = 299.0
+
+[node name="TEXT-234" type="Label" parent="Document/root-685/body-903/dl-693/dd-652"]
+layout_mode = 0
+offset_right = 345.0
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 0, 1)
+theme_override_font_sizes/font_size = 16
+text = "A list of some people involved in the project."
+
+[node name="dt-723" type="Control" parent="Document/root-685/body-903/dl-693"]
+anchors_preset = 0
+offset_top = 299.0
+offset_right = 57.5
+offset_bottom = 322.0
+
+[node name="a-888" type="Label" parent="Document/root-685/body-903/dl-693/dt-723"]
+layout_mode = 0
+offset_right = 56.0
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 1, 1)
+theme_override_font_sizes/font_size = 16
+text = "History"
+
+[node name="dd-315" type="Control" parent="Document/root-685/body-903/dl-693"]
+anchors_preset = 0
+offset_left = 40.0
+offset_top = 322.0
+offset_right = 352.5
+offset_bottom = 345.0
+
+[node name="TEXT-548" type="Label" parent="Document/root-685/body-903/dl-693/dd-315"]
+layout_mode = 0
+offset_right = 311.0
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 0, 1)
+theme_override_font_sizes/font_size = 16
+text = "A summary of the history of the project."
+
+[node name="dt-76" type="Control" parent="Document/root-685/body-903/dl-693"]
+anchors_preset = 0
+offset_top = 345.0
+offset_right = 127.0
+offset_bottom = 368.0
+
+[node name="a-59" type="Label" parent="Document/root-685/body-903/dl-693/dt-76"]
+layout_mode = 0
+offset_right = 116.0
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 1, 1)
+theme_override_font_sizes/font_size = 16
+text = "How can I help"
+
+[node name="TEXT-830" type="Label" parent="Document/root-685/body-903/dl-693/dt-76"]
+layout_mode = 0
+offset_left = 117.5
+offset_right = 125.5
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 0, 1)
+theme_override_font_sizes/font_size = 16
+text = "?"
+
+[node name="dd-186" type="Control" parent="Document/root-685/body-903/dl-693"]
+anchors_preset = 0
+offset_left = 40.0
+offset_top = 368.0
+offset_right = 332.5
+offset_bottom = 391.0
+
+[node name="TEXT-389" type="Label" parent="Document/root-685/body-903/dl-693/dd-186"]
+layout_mode = 0
+offset_right = 291.0
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 0, 1)
+theme_override_font_sizes/font_size = 16
+text = "If you would like to support the web.."
+
+[node name="dt-644" type="Control" parent="Document/root-685/body-903/dl-693"]
+anchors_preset = 0
+offset_top = 391.0
+offset_right = 100.5
+offset_bottom = 414.0
+
+[node name="a-484" type="Label" parent="Document/root-685/body-903/dl-693/dt-644"]
+layout_mode = 0
+offset_right = 99.0
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 1, 1)
+theme_override_font_sizes/font_size = 16
+text = "Getting code"
+
+[node name="dd-372" type="Control" parent="Document/root-685/body-903/dl-693"]
+anchors_preset = 0
+offset_left = 40.0
+offset_top = 414.0
+offset_right = 358.5
+offset_bottom = 437.0
+
+[node name="TEXT-189" type="Label" parent="Document/root-685/body-903/dl-693/dd-372"]
+layout_mode = 0
+offset_right = 153.0
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 0, 1)
+theme_override_font_sizes/font_size = 16
+text = "Getting the code by"
+
+[node name="a-817" type="Label" parent="Document/root-685/body-903/dl-693/dd-372"]
+layout_mode = 0
+offset_left = 154.5
+offset_right = 278.5
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 1, 1)
+theme_override_font_sizes/font_size = 16
+text = "anonymous FTP"
+
+[node name="TEXT-13" type="Label" parent="Document/root-685/body-903/dl-693/dd-372"]
+layout_mode = 0
+offset_left = 280.0
+offset_right = 317.0
+offset_bottom = 23.0
+theme_override_colors/font_color = Color(0, 0, 0, 1)
+theme_override_font_sizes/font_size = 16
+text = ", etc."
diff --git a/formatted.html b/formatted.html
new file mode 100644
index 0000000..be8b2b1
--- /dev/null
+++ b/formatted.html
@@ -0,0 +1,52 @@
+
+ The World Wide Web project
+
+
+
+
+ World Wide Web
+ The WorldWideWeb (W3) is a wide-area
+ hypermedia information retrieval
+ initiative aiming to give universal
+ access to a large universe of documents.
+ Everything there is online about
+ W3 is linked directly or indirectly
+ to this document, including an executive
+ summary of the project, Mailing lists
+ , Policy , November's W3 news ,
+ Frequently Asked Questions .
+
+ What's out there?
+ Pointers to the
+ world's online information, subjects
+ , W3 servers , etc.
+ Help
+ on the browser you are using
+ Software Products
+ A list of W3 project
+ components and their current state.
+ (e.g. Line Mode ,X11 Viola
+ , NeXTStep
+ , Servers , Tools , Mail robot ,
+ Library )
+ Technical
+ Details of protocols, formats,
+ program internals etc
+ Bibliography
+ Paper documentation
+ on W3 and references.
+ People
+ A list of some people involved
+ in the project.
+ History
+ A summary of the history
+ of the project.
+ How can I help ?
+ If you would like
+ to support the web..
+ Getting code
+ Getting the code by
+ anonymous FTP , etc.
+
+
\ No newline at end of file
diff --git a/icon.svg b/icon.svg
new file mode 100644
index 0000000..9d8b7fa
--- /dev/null
+++ b/icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icon.svg.import b/icon.svg.import
new file mode 100644
index 0000000..b222bdc
--- /dev/null
+++ b/icon.svg.import
@@ -0,0 +1,37 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://lsd3drj5u66y"
+path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://icon.svg"
+dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
+svg/scale=1.0
+editor/scale_with_editor_scale=false
+editor/convert_colors_with_editor_theme=false
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..840428a
--- /dev/null
+++ b/index.html
@@ -0,0 +1,74 @@
+
+The World Wide Web project
+
+
+
+World Wide Web The WorldWideWeb (W3) is a wide-area
+hypermedia information retrieval
+initiative aiming to give universal
+access to a large universe of documents.
+Everything there is online about
+W3 is linked directly or indirectly
+to this document, including an executive
+summary of the project, Mailing lists
+, Policy , November's W3 news ,
+Frequently Asked Questions .
+
+What's out there?
+ Pointers to the
+world's online information, subjects
+, W3 servers , etc.
+ Help
+ on the browser you are using
+ Software Products
+ A list of W3 project
+components and their current state.
+(e.g. Line Mode ,X11 Viola , NeXTStep
+, Servers , Tools , Mail robot ,
+Library )
+ Technical
+ Details of protocols, formats,
+program internals etc
+ Bibliography
+ Paper documentation
+on W3 and references.
+ People
+ A list of some people involved
+in the project.
+ History
+ A summary of the history
+of the project.
+ How can I help ?
+ If you would like
+to support the web..
+ Getting code
+ Getting the code by
+anonymous FTP , etc.
+
+
+
diff --git a/project.godot b/project.godot
new file mode 100644
index 0000000..9eb93be
--- /dev/null
+++ b/project.godot
@@ -0,0 +1,20 @@
+; Engine configuration file.
+; It's best edited using the editor UI and not directly,
+; since the parameters that go here are not all obvious.
+;
+; Format:
+; [section] ; section goes between []
+; param=value ; assign values to parameters
+
+config_version=5
+
+[application]
+
+config/name="BrowserJam"
+run/main_scene="res://document.tscn"
+config/features=PackedStringArray("4.3", "Forward Plus")
+config/icon="res://icon.svg"
+
+[rendering]
+
+environment/defaults/default_clear_color=Color(1, 1, 1, 1)
diff --git a/scripts/document.gd b/scripts/document.gd
new file mode 100644
index 0000000..b5c8846
--- /dev/null
+++ b/scripts/document.gd
@@ -0,0 +1,47 @@
+@tool
+extends EditorScript
+
+func _create_block_node(block: Layout.BlockNode) -> Node:
+ var box = Control.new()
+ box.name = block.dom_node.tag_name + "-" + str(randi_range(0, 1000))
+ box.position = block.rect.position
+ box.size = block.rect.size
+ return box
+
+func _create_text_fragment(parent: Node, fragment: Layout.TextFragment) -> Node:
+ var label = Label.new()
+ label.text = fragment.text
+ label.name = fragment.dom_node.tag_name + "-" + str(randi_range(0, 1000))
+ label.position = fragment.rect.position
+ label.size = fragment.rect.size
+
+ var style = fragment.dom_node.style
+ label.set('theme_override_font_sizes/font_size', style.font_size)
+ label.set('theme_override_colors/font_color', style.text_color)
+
+ parent.add_child(label, true)
+ label.set_owner(get_editor_interface().get_edited_scene_root())
+ return label
+
+func _create_block(parent: Node, block: Layout.BlockNode):
+ var box = _create_block_node(block)
+ parent.add_child(box, true)
+ box.set_owner(get_editor_interface().get_edited_scene_root())
+
+ for block_child in block.block_children:
+ _create_block(box, block_child)
+ for text_fragment in block.text_fragments:
+ _create_text_fragment(box, text_fragment)
+
+func _run() -> void:
+ var file = FileAccess.open("res://TheProject.html", FileAccess.READ);
+ var source = file.get_as_text()
+
+ var parser = Parser.new(source)
+ var dom_tree = DOM.build_dom_tree(parser)
+ var layout_tree = Layout.build_layout_tree(dom_tree)
+ layout_tree.layout(1000)
+ layout_tree.debug_print()
+
+ var document_node = get_editor_interface().get_edited_scene_root().get_node('Document')
+ _create_block(document_node, layout_tree)
diff --git a/scripts/dom.gd b/scripts/dom.gd
new file mode 100644
index 0000000..9027470
--- /dev/null
+++ b/scripts/dom.gd
@@ -0,0 +1,97 @@
+class_name DOM
+
+const SELF_CLOSING_TAGS = [
+ 'nextid'
+]
+
+static func _text_for_rendering(text: String) -> String:
+ var result = ''
+ var in_whitespace = false
+ for c in text:
+ if c in [' ', '\t', '\n', '\r']:
+ if not in_whitespace:
+ result += ' '
+ in_whitespace = true
+ else:
+ result += c
+ in_whitespace = false
+ return result.strip_edges()
+
+class DomNode:
+ var tag_name: String
+ var style: Style
+ var text: String
+ var children: Array[DomNode]
+
+ func _init(tag_name: String, parent_style: Style):
+ self.tag_name = tag_name
+ self.style = Style.apply_default_style_for_element(tag_name, parent_style)
+
+ func add_child(child: DomNode):
+ children.append(child)
+
+ func inner_text():
+ var result = text
+ for child in children:
+ result += child.text
+ return DOM._text_for_rendering(result)
+
+ func find(of_tag_name: String) -> DomNode:
+ if tag_name == of_tag_name:
+ return self
+ for child in children:
+ var found = child.find(of_tag_name)
+ if found != null:
+ return found
+ return null
+
+ func debug_print(indent: int = 0):
+ print(' '.repeat(indent * 4) + tag_name)
+ for child in children:
+ child.debug_print(indent + 1)
+
+static func _should_auto_close(tag_name: String, top_of_stack: String) -> bool:
+ const BLOCK = ['p', 'dl']
+ const DESCRIPTION_LIST_ITEM = ['dt', 'dd']
+
+ if tag_name in BLOCK and top_of_stack in BLOCK:
+ return true
+ if tag_name in DESCRIPTION_LIST_ITEM and top_of_stack in DESCRIPTION_LIST_ITEM:
+ return true
+ return false
+
+static func build_dom_tree(parser: Parser) -> DomNode:
+ var root = DomNode.new('root', Style.new())
+ var stack: Array[DomNode] = [root]
+
+ while true:
+ var token = parser.next()
+ if token == null:
+ break
+
+ var top_of_stack = stack[len(stack) - 1]
+ var tag_name = token.tag_name.to_lower()
+
+ if token.type == Token.Type.Text:
+ var text_node = DomNode.new('TEXT', top_of_stack.style)
+ text_node.text = token.text
+ top_of_stack.add_child(text_node)
+ continue
+
+ if token.type == Token.Type.Tag and not token.is_closing:
+ if _should_auto_close(tag_name, top_of_stack.tag_name):
+ stack.pop_back()
+ top_of_stack = stack[len(stack) - 1]
+
+ var node = DomNode.new(tag_name, top_of_stack.style)
+ top_of_stack.add_child(node)
+ if not tag_name in SELF_CLOSING_TAGS:
+ stack.append(node)
+ continue
+
+ if token.type == Token.Type.Tag and token.is_closing:
+ if top_of_stack.tag_name != tag_name:
+ print('Closing wrong tag ' + tag_name + ' insead of ' + top_of_stack.tag_name)
+ stack.pop_back()
+ continue
+ return root
diff --git a/scripts/layout.gd b/scripts/layout.gd
new file mode 100644
index 0000000..2ea8981
--- /dev/null
+++ b/scripts/layout.gd
@@ -0,0 +1,156 @@
+class_name Layout
+
+const CHAR_SIZE = 10
+
+const BLOCK_NODES = [
+ 'body',
+ 'h1',
+ 'p',
+ 'dl',
+ 'dt',
+ 'dd',
+]
+
+static func _text_size(text: String, style: Style) -> Vector2:
+ var font = Label.new().get_theme_default_font()
+ return font.get_string_size(text, HORIZONTAL_ALIGNMENT_LEFT, -1, style.font_size)
+
+class InlineNode:
+ var text: String
+ var dom_node: DOM.DomNode
+
+ func _init(dom_node: DOM.DomNode):
+ self.dom_node = dom_node
+ self.text = dom_node.inner_text()
+
+ func debug_print(indent: int = 0):
+ print(' '.repeat(indent*4) + 'InlineNode')
+
+class TextFragment:
+ var dom_node: DOM.DomNode
+ var text: String
+ var rect: Rect2
+
+ func _init(dom_node: DOM.DomNode, text: String, rect: Rect2):
+ self.dom_node = dom_node
+ self.text = text
+ self.rect = rect
+
+class BlockNode:
+ var block_children: Array[BlockNode]
+ var inline_children: Array[InlineNode]
+ var text_fragments: Array[TextFragment]
+
+ var rect: Rect2
+ var dom_node: DOM.DomNode
+
+ func _init(dom_node: DOM.DomNode):
+ self.dom_node = dom_node
+ self.block_children = []
+ self.inline_children = []
+ self.text_fragments = []
+
+ func are_children_inline():
+ return len(inline_children) > 0
+
+ func _layout_block(max_width: float):
+ for child in block_children:
+ var style = child.dom_node.style
+ child.layout(max_width - style.margin_left - style.margin_right)
+
+ var y = 0
+ for child in block_children:
+ var style = child.dom_node.style
+ y += style.margin_top
+ child.rect.position.x = style.margin_left
+ child.rect.position.y = y
+ y += child.rect.size.y
+ y += style.margin_bottom
+ rect = rect.merge(child.rect)
+
+ func _layout_inline(max_width: float):
+ text_fragments = []
+
+ var x = 0
+ var y = 0
+ var line_height = 0
+ for child in inline_children:
+ var style = child.dom_node.style
+ var fragment_rect = Rect2(x, y, 0, 0)
+ var fragment_text = ''
+
+ var words = child.text.split(' ')
+ for i in range(len(words)):
+ var word = words[i]
+ if i != len(words) - 1:
+ word += ' '
+
+ var word_size = Layout._text_size(word, style)
+ if x + word_size.x > max_width:
+ var fragment = TextFragment.new(child.dom_node, fragment_text, fragment_rect)
+ text_fragments.append(fragment)
+
+ x = 0
+ y += line_height
+ line_height = 0
+
+ fragment_text = ''
+ fragment_rect = Rect2(x, y, 0, 0)
+
+ fragment_rect.size.x += word_size.x
+ fragment_rect.size.y = max(fragment_rect.size.y, word_size.y)
+ fragment_text += word
+
+ x += word_size.x
+ line_height = max(line_height, word_size.y)
+
+ var fragment = TextFragment.new(child.dom_node, fragment_text, fragment_rect)
+ text_fragments.append(fragment)
+ x += 1.5 # Space width
+ rect.size.x = x
+ rect.size.y = y + line_height
+
+ func layout(max_width: float):
+ if are_children_inline():
+ _layout_inline(max_width)
+ else:
+ _layout_block(max_width)
+
+ func debug_print(indent: int = 0):
+ print(' '.repeat(indent*4) + 'BlockNode rect=' + str(rect))
+ for child in block_children:
+ child.debug_print(indent + 1)
+ for child in inline_children:
+ child.debug_print(indent + 1)
+
+static func _inline_children_to_block(block: BlockNode):
+ var inline_block = BlockNode.new(DOM.DomNode.new('INLINE', Style.new()))
+ inline_block.inline_children = block.inline_children
+ block.inline_children = []
+ block.block_children.append(inline_block)
+
+static func _build_layout_tree_block(dom_node: DOM.DomNode) -> BlockNode:
+ var block = BlockNode.new(dom_node)
+ for child in dom_node.children:
+ if child.tag_name in BLOCK_NODES:
+ if len(block.inline_children) > 0:
+ _inline_children_to_block(block)
+ block.block_children.append(_build_layout_tree_block(child))
+ continue
+
+ if child.tag_name == 'TEXT' and len(child.text.strip_edges()) == 0:
+ continue # Ignore whitespace text.
+ block.inline_children.append(InlineNode.new(child))
+
+ if len(block.block_children) > 0 and len(block.inline_children) > 0:
+ _inline_children_to_block(block)
+
+ return block
+
+static func build_layout_tree(dom: DOM.DomNode) -> BlockNode:
+ var body = dom.find('body')
+ assert(body != null)
+
+ var html = BlockNode.new(dom)
+ html.block_children.append(_build_layout_tree_block(body))
+ return html
diff --git a/scripts/parser.gd b/scripts/parser.gd
new file mode 100644
index 0000000..62cf61a
--- /dev/null
+++ b/scripts/parser.gd
@@ -0,0 +1,86 @@
+class_name Parser
+
+const EOF = ''
+
+enum State {
+ Text,
+ TagName,
+ AttributeName,
+}
+
+var _source: String
+var _state = State.Text
+var _index: int = 0
+
+var _current_token: Token
+
+func _init(source: String) -> void:
+ self._source = source
+ self._current_token = Token.new()
+
+func _next_char() -> String:
+ if _index >= len(_source):
+ return EOF
+ var c = _source[_index]
+ _index += 1
+ return c
+
+func _emit_token() -> Token:
+ var token = _current_token
+ _current_token = Token.new()
+ return token
+
+func _on_text() -> Token:
+ match _next_char():
+ '<':
+ _state = State.TagName
+ if len(_current_token.text) > 0:
+ _current_token.type = Token.Type.Text
+ return _emit_token()
+ EOF:
+ if len(_current_token.text) > 0:
+ _current_token.type = Token.Type.Text
+ return _emit_token()
+ var c:
+ _current_token.text += c
+ return null
+
+func _on_tag_name() -> Token:
+ match _next_char():
+ ' ', '\t', '\n', '\r':
+ _state = State.AttributeName
+ '/':
+ _current_token.is_closing = true
+ '>':
+ _state = State.Text
+ _current_token.type = Token.Type.Tag
+ return _emit_token()
+ EOF:
+ assert(false, 'TODO')
+ var c:
+ _current_token.tag_name += c
+ return null
+
+func _on_attibute_name() -> Token:
+ match _next_char():
+ '>':
+ _state = State.Text
+ _current_token.type = Token.Type.Tag
+ return _current_token
+ EOF:
+ assert(false, 'TODO')
+ return null
+
+func _parse_char() -> Token:
+ match _state:
+ State.Text: return _on_text()
+ State.TagName: return _on_tag_name()
+ State.AttributeName: return _on_attibute_name()
+ return null
+
+func next() -> Token:
+ while _index < len(_source):
+ var token = _parse_char()
+ if token != null:
+ return token
+ return null
diff --git a/scripts/style.gd b/scripts/style.gd
new file mode 100644
index 0000000..4975b30
--- /dev/null
+++ b/scripts/style.gd
@@ -0,0 +1,36 @@
+class_name Style
+
+static func _copy_style(parent_style: Style) -> Style:
+ var style = Style.new()
+ style.font_size = parent_style.font_size
+ style.text_color = parent_style.text_color
+ return style
+
+static func apply_default_style_for_element(tag_name: String, parent_style: Style) -> Style:
+ var style = _copy_style(parent_style)
+ match tag_name:
+ 'body':
+ style.margin_top = 5
+ style.margin_bottom = 5
+ style.margin_left = 5
+ style.margin_right = 5
+ 'h1':
+ style.font_size = 30
+ style.margin_top = 20
+ style.margin_bottom = 20
+ 'a':
+ style.text_color = Color.BLUE
+ 'p', 'dl':
+ style.margin_top = 10
+ style.margin_bottom = 10
+ 'dd':
+ style.margin_left = 40
+ return style
+
+var font_size: float = 16
+var text_color: Color = Color.BLACK
+
+var margin_top: float = 0
+var margin_bottom: float = 0
+var margin_left: float = 0
+var margin_right: float = 0
diff --git a/scripts/token.gd b/scripts/token.gd
new file mode 100644
index 0000000..3659cca
--- /dev/null
+++ b/scripts/token.gd
@@ -0,0 +1,21 @@
+class_name Token
+
+enum Type {
+ Text,
+ Tag,
+}
+
+var type: Type
+var text: String = ''
+var tag_name: String = ''
+var is_closing: bool = false
+
+func _to_string() -> String:
+ match type:
+ Type.Text: return 'Text(%s)' % text
+ Type.Tag:
+ if is_closing:
+ return 'ClosingTag(name=%s)' % tag_name
+ else:
+ return 'OpenTag(name=%s)' % tag_name
+ _: return 'Unknown'
diff --git a/simple.html b/simple.html
new file mode 100644
index 0000000..1822e1e
--- /dev/null
+++ b/simple.html
@@ -0,0 +1,23 @@
+
+The World Wide Web project
+
+
+
+World Wide Web The WorldWideWeb (W3) is a wide-area
+hypermedia information retrieval
+initiative aiming to give universal
+access to a large universe of documents.
+Everything there is online about
+W3 is linked directly or indirectly
+to this document, including an executive
+summary of the project, Mailing lists
+, Policy , November's W3 news ,
+Frequently Asked Questions .
+
+