aboutsummaryrefslogtreecommitdiffstats
path: root/root/articles
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2020-01-25 12:57:36 +0000
committers-ol <s-ol@users.noreply.github.com>2020-01-25 12:57:36 +0000
commit2b91c3d0af33099f7b260a41efac252655104c50 (patch)
tree4636152e118d90381a584f2636da34efbe8dd568 /root/articles
parentcorrection in portfolio (diff)
parentupdate README.md (diff)
downloadmmm-2b91c3d0af33099f7b260a41efac252655104c50.tar.gz
mmm-2b91c3d0af33099f7b260a41efac252655104c50.zip
Merge branch 'ba'
Diffstat (limited to 'root/articles')
-rw-r--r--root/articles/$order3
-rw-r--r--root/articles/mmmfs/$order14
-rw-r--r--root/articles/mmmfs/abstract/text$markdown+sidenotes.md14
-rw-r--r--root/articles/mmmfs/ba_log/$order15
-rw-r--r--root/articles/mmmfs/ba_log/2019-10-07/text$markdown.md40
-rw-r--r--root/articles/mmmfs/ba_log/2019-10-08/text$markdown.md58
-rw-r--r--root/articles/mmmfs/ba_log/2019-10-09/text$markdown.md9
-rw-r--r--root/articles/mmmfs/ba_log/2019-10-10/text$markdown.md46
-rw-r--r--root/articles/mmmfs/ba_log/2019-10-11/text$markdown.md30
-rw-r--r--root/articles/mmmfs/ba_log/2019-10-14/text$markdown.md101
-rw-r--r--root/articles/mmmfs/ba_log/2019-10-15/text$markdown.md70
-rw-r--r--root/articles/mmmfs/ba_log/2019-10-24/text$markdown.md32
-rw-r--r--root/articles/mmmfs/ba_log/2019-10-26/text$markdown.md62
-rw-r--r--root/articles/mmmfs/ba_log/2019-10-27/$order1
-rw-r--r--root/articles/mmmfs/ba_log/2019-10-27/text$markdown.md77
-rw-r--r--root/articles/mmmfs/ba_log/2019-10-27/video/video$webm.webmbin0 -> 5209109 bytes
-rw-r--r--root/articles/mmmfs/ba_log/2019-10-29/$order1
-rw-r--r--root/articles/mmmfs/ba_log/2019-10-29/text$markdown.md38
-rw-r--r--root/articles/mmmfs/ba_log/2019-10-29/video/video$mp4.mp4bin0 -> 3944233 bytes
-rw-r--r--root/articles/mmmfs/ba_log/2019-11-01/$order1
-rw-r--r--root/articles/mmmfs/ba_log/2019-11-01/demo/video$webm.webmbin0 -> 9968238 bytes
-rw-r--r--root/articles/mmmfs/ba_log/2019-11-01/text$markdown.md18
-rw-r--r--root/articles/mmmfs/ba_log/2019-11-25/$order1
-rw-r--r--root/articles/mmmfs/ba_log/2019-11-25/demo/video$webm.webmbin0 -> 1380724 bytes
-rw-r--r--root/articles/mmmfs/ba_log/2019-11-25/text$markdown.md89
-rw-r--r--root/articles/mmmfs/ba_log/2019-12-20/text$markdown+sidenotes.md39
-rw-r--r--root/articles/mmmfs/ba_log/intro: text$markdown.md4
-rw-r--r--root/articles/mmmfs/ba_log/print: text$moonscript -> fn -> mmm$dom.moon19
-rw-r--r--root/articles/mmmfs/ba_log/start/text$markdown.md25
-rw-r--r--root/articles/mmmfs/ba_log/text$moonscript -> fn -> mmm$dom.moon15
-rw-r--r--root/articles/mmmfs/conclusion/text$markdown+sidenotes.md11
-rw-r--r--root/articles/mmmfs/empty/title: text$plain1
-rw-r--r--root/articles/mmmfs/evaluation/text$markdown+sidenotes.md173
-rw-r--r--root/articles/mmmfs/examples/$order5
-rw-r--r--root/articles/mmmfs/examples/gallery/$order2
-rw-r--r--root/articles/mmmfs/examples/gallery/actual_image/image$png.png (renamed from root/articles/mmmfs/gallery/actual_image/image$png.png)bin678429 -> 678429 bytes
-rw-r--r--root/articles/mmmfs/examples/gallery/actual_image/preview: image$png.png (renamed from root/articles/mmmfs/gallery/actual_image/preview: image$png.png)bin31880 -> 31880 bytes
-rw-r--r--root/articles/mmmfs/examples/gallery/link_to_image/URL -> image$png (renamed from root/articles/mmmfs/gallery/link_to_image/URL -> image$png)0
-rw-r--r--root/articles/mmmfs/examples/gallery/link_to_image/preview: URL -> image$png (renamed from root/articles/mmmfs/gallery/link_to_image/preview: URL -> image$png)0
-rw-r--r--root/articles/mmmfs/examples/gallery/slideshow: text$moonscript -> fn -> mmm$component.moon (renamed from root/articles/mmmfs/gallery/slideshow: text$moonscript -> fn -> mmm$component.moon)0
-rw-r--r--root/articles/mmmfs/examples/gallery/text$moonscript -> fn -> mmm$dom.moon (renamed from root/articles/mmmfs/gallery/text$moonscript -> fn -> mmm$dom.moon)0
-rw-r--r--root/articles/mmmfs/examples/gallery/title: text$plain1
-rw-r--r--root/articles/mmmfs/examples/image/URL -> image$png (renamed from root/articles/mmmfs/image/URL -> image$png)0
-rw-r--r--root/articles/mmmfs/examples/image/title: text$plain1
-rw-r--r--root/articles/mmmfs/examples/implementation: text$markdown+sidenotes.md88
-rw-r--r--root/articles/mmmfs/examples/intro: text$markdown+sidenotes.md10
-rw-r--r--root/articles/mmmfs/examples/language_support/$order3
-rw-r--r--root/articles/mmmfs/examples/language_support/javascript/text$javascript -> mmm$dom.js (renamed from root/articles/mmmfs/language_support/javascript/text$javascript -> mmm$dom.js)0
-rw-r--r--root/articles/mmmfs/examples/language_support/javascript/title: text$plain (renamed from root/articles/mmmfs/language_support/javascript/title: text$plain)0
-rw-r--r--root/articles/mmmfs/examples/language_support/lua/text$lua -> mmm$dom.lua (renamed from root/articles/mmmfs/language_support/lua/text$lua -> mmm$dom.lua)0
-rw-r--r--root/articles/mmmfs/examples/language_support/lua/title: text$plain (renamed from root/articles/mmmfs/language_support/lua/title: text$plain)0
-rw-r--r--root/articles/mmmfs/examples/language_support/moonscript/text$moonscript -> mmm$dom.moon (renamed from root/articles/mmmfs/language_support/moonscript/text$moonscript -> mmm$dom.moon)0
-rw-r--r--root/articles/mmmfs/examples/language_support/moonscript/title: text$plain (renamed from root/articles/mmmfs/language_support/moonscript/title: text$plain)0
-rw-r--r--root/articles/mmmfs/examples/language_support/preview: text$markdown (renamed from root/articles/mmmfs/language_support/preview: text$markdown)0
-rw-r--r--root/articles/mmmfs/examples/language_support/text$moonscript -> fn -> mmm$dom.moon (renamed from root/articles/mmmfs/language_support/text$moonscript -> fn -> mmm$dom.moon)0
-rw-r--r--root/articles/mmmfs/examples/language_support/title: text$plain (renamed from root/articles/mmmfs/language_support/title: text$plain)0
-rw-r--r--root/articles/mmmfs/examples/markdown/text$markdown.md20
-rw-r--r--root/articles/mmmfs/examples/markdown/title: text$plain1
-rw-r--r--root/articles/mmmfs/examples/pinwall/$order3
-rw-r--r--root/articles/mmmfs/examples/pinwall/image/image$png.pngbin0 -> 128929 bytes
-rw-r--r--root/articles/mmmfs/examples/pinwall/image/pinwall_info: text$json1
-rw-r--r--root/articles/mmmfs/examples/pinwall/text$moonscript -> fn -> mmm$dom.moon120
-rw-r--r--root/articles/mmmfs/examples/pinwall/text/pinwall_info: text$json1
-rw-r--r--root/articles/mmmfs/examples/pinwall/text/text$plain.txt4
-rw-r--r--root/articles/mmmfs/examples/pinwall/title: text$plain1
-rw-r--r--root/articles/mmmfs/examples/pinwall/video/URL -> video$mp41
-rw-r--r--root/articles/mmmfs/examples/pinwall/video/pinwall_info: text$json1
-rw-r--r--root/articles/mmmfs/examples/text$moonscript -> fn -> mmm$dom.moon44
-rw-r--r--root/articles/mmmfs/framework/text$markdown+sidenotes.md96
-rw-r--r--root/articles/mmmfs/gallery/preview: text$moonscript -> fn -> mmm$dom.moon7
-rw-r--r--root/articles/mmmfs/gallery/title: text$plain1
-rw-r--r--root/articles/mmmfs/historical-approaches/$order1
-rw-r--r--root/articles/mmmfs/historical-approaches/star-graph/image$png.pngbin0 -> 87351 bytes
-rw-r--r--root/articles/mmmfs/historical-approaches/star-graph/note: text$markdown.md4
-rw-r--r--root/articles/mmmfs/historical-approaches/text$markdown+sidenotes.md73
-rw-r--r--root/articles/mmmfs/image/preview: text$moonscript -> fn -> mmm$dom.moon5
-rw-r--r--root/articles/mmmfs/image/title: text$plain1
-rw-r--r--root/articles/mmmfs/introduction/text$markdown.md18
-rw-r--r--root/articles/mmmfs/markdown/preview: text$markdown.md6
-rw-r--r--root/articles/mmmfs/markdown/title: text$plain1
-rw-r--r--root/articles/mmmfs/mmmfs/$order3
-rw-r--r--root/articles/mmmfs/mmmfs/text$markdown+sidenotes.md197
-rw-r--r--root/articles/mmmfs/mmmfs/tree_mainstream/text$mermaid-graph11
-rw-r--r--root/articles/mmmfs/mmmfs/tree_mmmfs/text$mermaid-graph21
-rw-r--r--root/articles/mmmfs/mmmfs/type_coercion_graph/text$mermaid-graph22
-rw-r--r--root/articles/mmmfs/motivation/$order2
-rw-r--r--root/articles/mmmfs/motivation/app-types/text$markdown.md3
-rw-r--r--root/articles/mmmfs/motivation/creative/text$markdown.md2
-rw-r--r--root/articles/mmmfs/motivation/text$markdown+sidenotes.md138
-rw-r--r--root/articles/mmmfs/print: text$moonscript -> fn -> mmm$dom.moon26
-rw-r--r--root/articles/mmmfs/references/$order22
-rw-r--r--root/articles/mmmfs/references/acm-dl/text$bibtex5
-rw-r--r--root/articles/mmmfs/references/adobe/text$bibtex8
-rw-r--r--root/articles/mmmfs/references/alternatives-to-trees/text$bibtex7
-rw-r--r--root/articles/mmmfs/references/appliances/text$bibtex7
-rw-r--r--root/articles/mmmfs/references/aspect-ratios/text$bibtex7
-rw-r--r--root/articles/mmmfs/references/dijkstra/text$bibtex17
-rw-r--r--root/articles/mmmfs/references/hypercard/text$bibtex6
-rw-r--r--root/articles/mmmfs/references/inkandswitch/markdown: text$moonscript -> fn -> text$markdown.md1
-rw-r--r--root/articles/mmmfs/references/inkandswitch/text$bibtex7
-rw-r--r--root/articles/mmmfs/references/linux-exec/text$bibtex8
-rw-r--r--root/articles/mmmfs/references/lock-in/text$bibtex7
-rw-r--r--root/articles/mmmfs/references/market-share/text$bibtex7
-rw-r--r--root/articles/mmmfs/references/memex/text$bibtex8
-rw-r--r--root/articles/mmmfs/references/mime-types/text$bibtex14
-rw-r--r--root/articles/mmmfs/references/osx-files/text$bibtex7
-rw-r--r--root/articles/mmmfs/references/poc-or-gtfo/text$bibtex8
-rw-r--r--root/articles/mmmfs/references/renaming/text$bibtex7
-rw-r--r--root/articles/mmmfs/references/subtext/cite$doi1
-rw-r--r--root/articles/mmmfs/references/subtext/text$bibtex18
-rw-r--r--root/articles/mmmfs/references/super-powers/text$bibtex7
-rw-r--r--root/articles/mmmfs/references/text$moonscript -> fn -> mmm$dom.moon13
-rw-r--r--root/articles/mmmfs/references/transclusion/text$bibtex10
-rw-r--r--root/articles/mmmfs/references/unix/text$bibtex7
-rw-r--r--root/articles/mmmfs/references/wikipedia/text$bibtex7
-rw-r--r--root/articles/mmmfs/references/xerox-star/cite$doi1
-rw-r--r--root/articles/mmmfs/references/xerox-star/text$bibtex18
-rw-r--r--root/articles/mmmfs/statement-of-originality/text$html+frag.html13
-rw-r--r--root/articles/mmmfs/table-of-contents/text$html+frag.html91
-rw-r--r--root/articles/mmmfs/text$moonscript -> fn -> mmm$dom.moon263
-rw-r--r--root/articles/mmmfs/title/text$html+frag.html21
-rw-r--r--root/articles/realities/text$moonscript -> mmm$component.moon (renamed from root/articles/realities/text$moonscript -> mmm$dom.moon)2
-rw-r--r--root/articles/xy-workshop/$order10
-rw-r--r--root/articles/xy-workshop/01/text$html+frag.html7
-rw-r--r--root/articles/xy-workshop/01b/text$markdown.md12
-rw-r--r--root/articles/xy-workshop/01c/$order1
-rw-r--r--root/articles/xy-workshop/01c/text$markdown.md5
-rw-r--r--root/articles/xy-workshop/01c/video/URL -> youtube$video1
-rw-r--r--root/articles/xy-workshop/02/text$markdown.md12
-rw-r--r--root/articles/xy-workshop/03/text$markdown.md12
-rw-r--r--root/articles/xy-workshop/04/text$markdown.md9
-rw-r--r--root/articles/xy-workshop/05/text$markdown.md12
-rw-r--r--root/articles/xy-workshop/06/text$markdown.md6
-rw-r--r--root/articles/xy-workshop/07/text$markdown.md6
-rw-r--r--root/articles/xy-workshop/08/$order1
-rw-r--r--root/articles/xy-workshop/08/image/image$png.pngbin0 -> 285163 bytes
-rw-r--r--root/articles/xy-workshop/08/text$markdown.md4
-rw-r--r--root/articles/xy-workshop/description: text$plain2
-rw-r--r--root/articles/xy-workshop/text$moonscript -> fn -> mmm$dom.moon70
139 files changed, 2474 insertions, 273 deletions
diff --git a/root/articles/$order b/root/articles/$order
new file mode 100644
index 0000000..66aad40
--- /dev/null
+++ b/root/articles/$order
@@ -0,0 +1,3 @@
+mmmfs
+xy-workshop
+realities
diff --git a/root/articles/mmmfs/$order b/root/articles/mmmfs/$order
new file mode 100644
index 0000000..d58d878
--- /dev/null
+++ b/root/articles/mmmfs/$order
@@ -0,0 +1,14 @@
+title
+abstract
+table-of-contents
+introduction
+motivation
+historical-approaches
+framework
+mmmfs
+examples
+evaluation
+conclusion
+references
+ba_log
+statement-of-originality
diff --git a/root/articles/mmmfs/abstract/text$markdown+sidenotes.md b/root/articles/mmmfs/abstract/text$markdown+sidenotes.md
new file mode 100644
index 0000000..c7d6c9c
--- /dev/null
+++ b/root/articles/mmmfs/abstract/text$markdown+sidenotes.md
@@ -0,0 +1,14 @@
+abstract
+========
+
+Current end-user operating systems are based on a set of design principles and computing paradigms that make them
+simple to use in some circumstances but are very inflexible for user customization and adaptation. In this thesis, these
+limitations and design principles will be discussed and contrasted by an analysis of historic systems that solved these
+issues by following different design goals. Based on this analysis, as well as further literature, an evaluation
+framework for end-user computing systems is established.
+The design and implementation of a new end-user computing system, which focuses on a file system with rich file types
+and a type coercion system as its central paradigm, is discussed. Following this, the capabilities of the system are
+demonstrated using multiple example use-cases. An evaluation of these examples as well as the system itself according
+to the framework established earlier shows that the proposed system is indeed very flexible and useful for a wide
+variety of uses involving multimedia content from various sources, although the system has many flaws that would hinder
+widespread adoption.
diff --git a/root/articles/mmmfs/ba_log/$order b/root/articles/mmmfs/ba_log/$order
new file mode 100644
index 0000000..a77277a
--- /dev/null
+++ b/root/articles/mmmfs/ba_log/$order
@@ -0,0 +1,15 @@
+start
+2019-10-07
+2019-10-08
+2019-10-09
+2019-10-10
+2019-10-11
+2019-10-14
+2019-10-15
+2019-10-24
+2019-10-26
+2019-10-27
+2019-10-29
+2019-11-01
+2019-11-25
+2019-12-20
diff --git a/root/articles/mmmfs/ba_log/2019-10-07/text$markdown.md b/root/articles/mmmfs/ba_log/2019-10-07/text$markdown.md
new file mode 100644
index 0000000..46c6892
--- /dev/null
+++ b/root/articles/mmmfs/ba_log/2019-10-07/text$markdown.md
@@ -0,0 +1,40 @@
+Today I started working on the HTTP server that finds, converts and serves content stored in the (SQL) backend just-in-time (later the server could also cache content).
+
+The server can handle these types of requests:
+
+## Fileder Index Requests
+A request like `GET /path/to/fileder/` (note the trailing slash) is used to query the contents of a fileder.
+It solicits a JSON-encoded response that contains the full paths to all children of this fileder, as well as all facets currently stored, e.g:
+
+ {
+ "children": [
+ "/projects/vcv_mods",
+ "/projects/HowDoIOS",
+ "/projects/iii-telefoni",
+ "/projects/btrktrl",
+ "/projects/demoloops",
+ "/projects/VJmidiKit",
+ "/projects/gayngine",
+ "/projects/themer",
+ "/projects/chimpanzee_bukkaque"
+ ],
+ "facets": [
+ ["", "text/moonscript -> fn -> mmm/dom"],
+ ["name", "alpha"],
+ ["title", "text/plain"]
+ ]
+ }
+
+## Facet Requests
+A request like `GET /path/to/fileder/facet_name` is used to query a facet.
+To differentiate a request for the 'unnamed' facet from an index request, unnamed facets are represented as a `:` character instead.
+The type to ask for can be specified in a `MMM-Accept` header separately, it defaults to `text/html`.
+
+The server either sends back the (possibly converted) facet with a `200 OK` status,
+or a `406 Not Acceptable` error if no conversion was possible.
+
+I also restructured the code a bit and moved some of the HTML-rendering code into the main mmmfs code.
+Then I renamed the `text/html` type to `text/html+frag`, since it refers to only a fragment of HTML code, not a whole document,
+and added a new *convert* from `text/html+frag` to `text/html` that wraps the fragment in the HTML template and style.
+
+the full code change is in commits [81e143f](https://git.s-ol.nu/mmm/commit/81e143fa8181a6adb58d7fba632bd31a13164410/) and [ad26c7c](https://git.s-ol.nu/mmm/commit/ad26c7c4e374f66a978f9946bbb083377f2224a6/)
diff --git a/root/articles/mmmfs/ba_log/2019-10-08/text$markdown.md b/root/articles/mmmfs/ba_log/2019-10-08/text$markdown.md
new file mode 100644
index 0000000..c10b75f
--- /dev/null
+++ b/root/articles/mmmfs/ba_log/2019-10-08/text$markdown.md
@@ -0,0 +1,58 @@
+Today I mostly fixed the output/rendering of the 'live' server I implemented yesterday.
+
+I changed the URL scheme, it no longer uses headers, which made it hard to link to resources through `<link>` and `<script>` tags.
+Instead the path, facet-name and type are now all part of the URI:
+
+| URI | fileder path | facet name | type |
+| ---------------------------------------------- | ------------------ | --------------- | ------------------------------ |
+| `/fileder/facet: type/subtype -> wrapped/type` | `/path/to/fileder` | `facet` | `type/subtype -> wrapped/type` |
+| `/fileder/: some/type` | `/fileder` | (default facet) | `some/type` |
+| `/fileder/alternate:` | `/fileder` | `alternate` | `text/html` (default type) |
+| `/path` | `/path` | (default facet) | `text/html` (default type) |
+| `/` | `/` | (default facet) | `text/html` (default type) |
+
+The fileder-index metadata was moved to a `?index` 'pseudofacet' (e.g. `/fileder/?index`).
+
+**EDIT 2019-10-09:**
+> I will take this chance to show and hopefully explain the point of this all again:
+> With the system running it is now possible to demonstrate the type-coercion that powers the system.
+>
+> In the system, every piece of data (the *facet*s) is stored together with it's *type*.
+> When requesting data, it can of course be loaded with that *type*, yielding the data unmodified,
+> but it is also possible to demand a different *type* that may be more useful to the receiving application.
+>
+> as an example we can take for example this article about one of the internal libraries for writing HTML documents:
+> [`/meta/mmm.dom/`](/meta/mmm.dom/).
+>
+> The path `/meta/mmm.dom/` corresponds, according to the table above, to the default facet of the `/meta/mmm.dom` fileder,
+> and since no type was specified, it is assumed that the browser wants a `text/html` document.
+> The follwing path gives the same result, but makes this explicit:
+> [`/meta/mmm.dom/:text/html`](/meta/mmm.dom/:text/html)
+>
+> now, instead of asking for the rendered HTML document, we can also ask for the source, which is of the type
+> `text/moonscript -> mmm/dom` (a Moonscript file that evaluates to a website-fragment):
+> [`meta/mmm.dom/:text/moonscript -> mmm/dom`](/meta/mmm.dom/:text/moonscript%20-%3E%20mmm/dom)
+>
+> the source code was written in MoonScript, which compiles to Lua before it is executed.
+> We can also ask the server to do that for us:
+> `text/lua -> mmm/dom` (a Lua file that evaluates to a website-fragment):
+> [`meta/mmm.dom/:text/lua -> mmm/dom`](/meta/mmm.dom/:text/lua%20-%3E%20mmm/dom)
+>
+> or, we could ask for the generated html fragment, but without the full HTML layout around it -
+> that would be the type `text/html+frag`, as mentioned in the last post:
+> [`meta/mmm.dom/:text/html+frag`](/meta/mmm.dom/:text/html+frag)
+>
+> lastly, we could also ask the system to generate a link to this content, in the `text/html` format (`URL -> text/html`):
+> [`meta/mmm.dom/:URL -> text/html`](/meta/mmm.dom/:URL%20-%3E%20text/html)
+> this might seem somewhat redundant, since we need a link to access this link,
+> but it can be useful when a component cannot work with binary data directly, e.g. when mentioning or embedding an image
+> or a video file.
+
+I also added support to the server for serving static assets (e.g. the CSS stylesheet) from the `static` directory.
+These files are accessible through the `/.static/` route (e.g. `/.static/main.css`), where they shouldn't interfere
+with the mmmfs contents.
+With the layout adjsuted to use these new paths, the live server now looks properly styled again too!
+
+Finally I worked on the Dockerfile and my deployment a bit,
+so that my updates to the code will now be automatically applied to my test site,
+which is available at [ba.s-ol.nu](//ba.s-ol.nu) (which might be where you are reading this right now!).
diff --git a/root/articles/mmmfs/ba_log/2019-10-09/text$markdown.md b/root/articles/mmmfs/ba_log/2019-10-09/text$markdown.md
new file mode 100644
index 0000000..702620d
--- /dev/null
+++ b/root/articles/mmmfs/ba_log/2019-10-09/text$markdown.md
@@ -0,0 +1,9 @@
+I added another driver/store that loads files straight from disk \[[`86bbe80`][86bbe80]\],
+and made the server load the fileder tree when it receives a request for content, rather than loading the whole tree up front.
+This means that I can work on the content again and see changes in the browser without restarting the server every time \[[`97bc4a0`][97bc4a0]\],
+This feature should be made unnecessary by the in-page editing feature, but until then it's important for my workflow.
+
+I also started cleaning up the mmmfs article a bit, and integrating this project log in a way that will make it available online soon.
+
+[86bbe80]: https://git.s-ol.nu/mmm/commit/86bbe805a7ec49a8b891412713ea43d6e46d0d73/
+[97bc4a0]: https://git.s-ol.nu/mmm/commit/97bc4a0d8d866026905eac6f0ba08b75f166219a/
diff --git a/root/articles/mmmfs/ba_log/2019-10-10/text$markdown.md b/root/articles/mmmfs/ba_log/2019-10-10/text$markdown.md
new file mode 100644
index 0000000..010f861
--- /dev/null
+++ b/root/articles/mmmfs/ba_log/2019-10-10/text$markdown.md
@@ -0,0 +1,46 @@
+Today I moved the static resources needed by the web-frontend into the content of the mmmfs itself:
+The server doesn't make an exception for static files anymore (as described in [a previous update][2019-10-08]),
+but rather the files are just in a fileder called `static` now, and properly typed, here:
+
+- [/static/style/](/static/style/:%20text/html+interactive)
+- [/static/mmm/](/static/mmm/:%20text/html+interactive)
+
+This removed a big exception and left the server implementation much cleaner and shorter, as can be seen in the corresponding commit [`005cc9b`][005cc9b].
+
+I also changed the route syntax introduced in [`2019-10-08`][2019-10-08] for getting the fileder index,
+now instead of being hard-coded to return a JSON value at `?index` \[[`b36a1a6`][b36a1a6]\].
+`?index` is treated as a pseudo-facet that can be requested in different types, just like real facets.
+I also added a second pseudo-facet `?tree`, which works like `?index`, except that it recurses and includes
+all content below the current fileder, rather than just including the child-fileders.
+
+Here are some example links for viewing these:
+
+- [`/?index: text/html`](/?index:%20text/html)
+- [`/articles/mmmfs/ba_log/?index: text/html`](/articles/mmmfs/ba_log/?index:%20text/html)
+
+Finally I added a third pseudo-facet called `?interactive` that renders the Inspector that the old page ran on,
+allowing to inspect raw facets, and bringing back the navbar \[[`9ab2f0f`][9ab2f0f]\].
+
+Now that there was a way to serve the Browser to the client again, I got to work on fixing it there.
+This involved a bigger changes in the shared mmm internals:
+
+Up to this point, for each request to render a fileder, the server would load that fileder,
+with all its facets and their values, as well as all children and their facets and children recursively.
+That means that when the root fileder is rendered, currently 120MB of data have to be loaded from disk (or a database).
+Now that the client can render content within the web browser again, that would be even worse due to the network delay.
+
+To solve this, the Fileder implementation now lazy-loads \[[`9632233`][9632233]\].
+When a Fileder is created, it initially knows only its path, but doesn't know which facets or children it contains.
+As soon as that data is attempted to be accessed, the fileder loads in the list of its children and facets from the datastore.
+The facet contents are loaded only when they are actually needed to fulfill a data request or conversion.
+
+With this need for optimization taken care of, I added a new datastore (`web`) \[[`91546d1`][91546d1]\], that can run on the client.
+Instead of directly accessing a database or physical file system, like the `sql` and `fs` stores, the `web` store delegates all
+requests to the server APIs I have been building, such as the new `?index` pseudo-facet.
+
+[2019-10-08]: /articles/mmmfs/ba_log/2019-10-08/
+[005cc9b]: https://git.s-ol.nu/mmm/commit/005cc9b3914128267017620984aee921999e173f/
+[b36a1a6]: https://git.s-ol.nu/mmm/commit/b36a1a6c61a6e8bff156ce4e2dc66fe8ed8cd95e/
+[9ab2f0f]: https://git.s-ol.nu/mmm/commit/9ab2f0fe3a1a043300536a057bafe5058d987d7f/
+[9632233]: https://git.s-ol.nu/mmm/commit/9632233c16a26f017c648faf36a6b26833e62f2e/
+[91546d1]: https://git.s-ol.nu/mmm/commit/91546d12919736b08567d7174bf1063cab0838f0/
diff --git a/root/articles/mmmfs/ba_log/2019-10-11/text$markdown.md b/root/articles/mmmfs/ba_log/2019-10-11/text$markdown.md
new file mode 100644
index 0000000..0b58c75
--- /dev/null
+++ b/root/articles/mmmfs/ba_log/2019-10-11/text$markdown.md
@@ -0,0 +1,30 @@
+Yesterday I got client-side access to the whole mmmfs tree to work via the new `web` datastore,
+but the requests were still extremely inefficient.
+This was because the organisation of the interface between the `Fileder` implementation and the datastore,
+which required the Fileder to make two separate requests to `?index` to fetch its children and facets,
+and also couldn't take advantage of the `?tree` pseudo-facet to bundle together multiple indexes in a single request.
+
+To fix this I added a new datastore method called `get_index` that returns both facet and child information \[[`e2a4257`][e2a4257]\]
+The Fileder implementation now uses this method instead of asking individually for the two pieces of information
+when lazy-loading fileder contents.
+The `get_index` method can also be instructed to recursively load to a fixed depth.
+A Fileder can also be instantiated using such a nested index,
+which causes it to immediately preload up to the same depth without the need for fetching more data.
+This allows some more optimizations, like having the client preload 3-levels deep when it launches,
+which seems like a decent heuristic of the data actually required for most pages and minimizes load time.
+
+I also added some tests for the `Key` class that I use in many different places to represent facet names and types \[[`782d072`][782d072]\]].
+
+The `?interactive` pseudo-facet from yesterday was changed to the `text/html+interactive` type instead \[[`8cdf5d4`][8cdf5d4]\].
+This was a bit of a tough decision, because it is a bit un-idiomatic: rendering the browser page still requires an exception in the browser.
+In the end the motivation for the change was that it should be possible,
+for user ergonomics, to link to the interactive view of a given facet of a given fileder.
+With `?interactive` being a facet, it wasn't possible to specify the facet without jumping out of the adressing system.
+With these updates on the other hand it is possible to link fo example:
+
+- to the main content of the root fileder, as an interactive view: [`/: text/html+interactive`](/:%20text/html+interactive)
+- to the page title of the root fileder, as an interactive view: [`/title: text/html+interactive`](/title:%20text/html+interactive)
+
+[e2a4257]: https://git.s-ol.nu/mmm/commit/e2a4257fc05d37822df2b7bbe0f587645375edf2/
+[782d072]: https://git.s-ol.nu/mmm/commit/782d0725f3f29eaa7d4a12213fb00c6643795348/
+[8cdf5d4]: https://git.s-ol.nu/mmm/commit/8cdf5d4a363ba99a6356e7e1dfe0dfb39e6fb13e/
diff --git a/root/articles/mmmfs/ba_log/2019-10-14/text$markdown.md b/root/articles/mmmfs/ba_log/2019-10-14/text$markdown.md
new file mode 100644
index 0000000..e42f8be
--- /dev/null
+++ b/root/articles/mmmfs/ba_log/2019-10-14/text$markdown.md
@@ -0,0 +1,101 @@
+I finally added a better type-conversion-path-finding algorithm \[[`deb21aa`][deb21aa]\].
+The old algorithm only took into consideration how many steps it took to get from type A (stored on disk) to type B (requested).
+This could lead to problems, for example in this situation:
+
+On Disk: `text/moonscript -> fn -> mmm/dom` (a moonscript file that contains a function that returns a bit of UI)
+Requested: `mmm/dom`
+Known Conversions:
+1. `text/moonscript` to `mmm/dom` (displays the source code with highlighting)
+2. `text/moonscript -> ???` to `???` (evaluates the moonscript file)
+3. `fn -> ???` to `???` (calls the function, providing access to children and other facets)
+
+Since conversion 1 only takes a single step, it would have been preferred by the old algorithm (although there were workarounds for this).
+The new algorithm adds the concept of conversion-cost, that has to be specified for each conversion.
+The conversions 2 and 3 now have a cost of `1`, while conversion 1 has a cost of `5`.
+The conversions are simply added up and the path with the lowest cost is chosen.
+Like in other pathfinding applications like digital games, the cost metric is also used by the algorithm to enhance the search itself,
+it prioritises searching further on the path with the least current cost.
+
+To implement this optimization I implemented a priority queue:
+
+ -- a priority queue with an index
+ -- only one element with a given key may exist at a time
+ -- when an element with an existing key is added,
+ -- the element with lower priority survives.
+ class Queue
+ new: =>
+ @values = {}
+ @index = {}
+
+ -- add a value with a given priority to the queue
+ -- if no key is specified, assume the element is uniq
+ add: (value, priority, key) =>
+ entry = { :value, :key, :priority }
+
+ if key
+ if old_entry = @index[key]
+ -- already have an entry for this key
+ -- if it is lower priority, we leave it there and do nothing
+ if old_entry.priority < priority
+ return
+
+ -- otherwise we remove the old one and continue as normal
+ -- find the index of the old entry
+ local i
+ for ii, entry in ipairs @values
+ if entry == old_entry
+ i = ii
+ break
+
+ -- remove it
+ table.remove @values, i
+
+ -- store this entry in the index
+ @index[key] = entry
+
+ -- store lowest priority last
+ for i, v in ipairs @values
+ if v.priority < priority
+ -- i is the first key that is lower,
+ -- we want to insert right before it
+ table.insert @values, i, entry
+ return
+
+ -- couldn't find a key with a lower priority,
+ -- so insert at the end
+ table.insert @values, entry
+
+ peek: =>
+ entry = @values[#@values]
+ if entry
+ { :value, :priority, :key } = entry
+ @index[key] = nil if key
+ value, priority
+
+ pop: =>
+ entry = table.remove @values
+ if entry
+ { :value, :priority, :key } = entry
+ @index[key] = nil if key
+ value, priority
+
+ -- iterator, yields (value, priority), low priority first
+ poll: => @.pop, @
+
+ {
+ :Queue
+ }
+
+This priority queue behaves mostly as expected, but I added an extra feature to make sure that only the
+best conversion path to a specific type is considered for further searching:
+When adding a new element to the Queue, an extra `key` can be passed.
+If a key is passed, the Queue makes sure that there is only ever one element with that key in the queue.
+When a second element would be introduced, the queue discards whichever element has a higher priority value.
+
+This way I can use the type that a conversion path leads to as the key,
+and the queue will automatically discard a worse solution if a better one is found that leads to the same type result.
+
+To make sure the Queue implementation was solid, I also added unit tests for it: [`spec/queue_spec.moon`][spec]
+
+[deb21aa]: https://git.s-ol.nu/mmm/commit/deb21aa43fe8bf11eb276803973b272913b7e716/
+[spec]: https://git.s-ol.nu/mmm/blob/deb21aa43fe8bf11eb276803973b272913b7e716/spec/queue_spec.moon
diff --git a/root/articles/mmmfs/ba_log/2019-10-15/text$markdown.md b/root/articles/mmmfs/ba_log/2019-10-15/text$markdown.md
new file mode 100644
index 0000000..d4e4121
--- /dev/null
+++ b/root/articles/mmmfs/ba_log/2019-10-15/text$markdown.md
@@ -0,0 +1,70 @@
+I'm giving a workshop next weekend, and I had to create the slides for that.
+Since one of the aspirations of `mmmfs` is to be easily adaptable to any kind of data organization and -presentation task,
+that was a good opportunity to try and implement a simple slideshow system.
+
+I started by creating a new fileder to hold the slideshow, [`/articles/xy-workshop`](/articles/xy-workshop/).
+In the main facet, I created a MoonScript file.
+Since the facet needs to access its children (the individual slides), I also used the `fn ->` type,
+that injects the current fileder into the script.
+
+`text/moonscript -> fn -> mmm/dom`
+
+ import ReactiveVar, tohtml, fromhtml, text, elements from require 'mmm.component'
+ import article, button, div, span from elements
+
+ =>
+ index = ReactiveVar 1
+ slide = index\map (index) -> @children[index]
+
+ local view
+ view = div {
+ style: ... -- styling ommited here
+
+ div {
+ style: ... -- styling omitted here
+
+ slide\map => @get 'mmm/dom'
+ }
+ }
+
+ local left, right
+ if MODE == 'CLIENT'
+ left = (_, e) ->
+ e\preventDefault!
+ index\transform (a) -> math.max 1, a - 1
+
+ right = (_, e) ->
+ e\preventDefault!
+ index\transform (a) -> math.min #@children, a + 1
+
+ tohtml with article!
+ \append div {
+ button '<', onclick: left
+ ' '
+ span index\map (t) -> text t
+ ' '
+ button '>', onclick: right
+ }
+ \append view
+
+I used the `mmm.component` library that lets me create reactive UIs.
+First I declare the reactive variable `index`, the current slide number.
+Then I derive the `slide` reactive variable, that is defined to be the child with index `index` -
+since these are `ReactiveVar`s, whenever `index` changes, `slide` will automatically load the current slide fileder.
+
+Then I create the main slide view, which consists mainly of two containers and some styling.
+Inside, I derive another reactivevar from `slide`: whenever a new `slide` is selected,
+this piece of code will request the main content in `mmm/dom` format and replace the current view content with that.
+
+Lastly I construct a little navigation UI, consisting of the left and right buttons.
+When one of them is clicked, it modifies the `index` variable, making sure to stay in the range of existing slides.
+The rest of the UI then reactively updates accordingly.
+
+Lastly I added keyboard controls for cycling through the slides, as well as a button to enter fullscreen mode.
+You can find the extended code for that in the commit [`ca24ef1`][ca24ef1],
+but it is not a lot either: with the additions the file is 70 lines long.
+
+With this done, it is just a matter of creating children-fileders and placing whichever content I want in them,
+they behave just like any other page of the system now.
+
+[ca24ef1]: https://git.s-ol.nu/mmm/blob/ca24ef108dbb11860e719711e4e7fbd6323aee0e/root/articles/xy-workshop/text%24moonscript%20-%3E%20fn%20-%3E%20mmm%24dom.moon
diff --git a/root/articles/mmmfs/ba_log/2019-10-24/text$markdown.md b/root/articles/mmmfs/ba_log/2019-10-24/text$markdown.md
new file mode 100644
index 0000000..dbb838a
--- /dev/null
+++ b/root/articles/mmmfs/ba_log/2019-10-24/text$markdown.md
@@ -0,0 +1,32 @@
+While writing some of the main section of the thesis today,
+I felt the need to illustrate some subject matter with a diagram depicting a folder structure.
+Knowing of some similar tools that generate SVG diagrams from textual descriptions,
+some quick research turned up [mermaid JS][mermaid].
+
+I tried it in their online live editor first to verify that it would indeed do what I needed it to,
+and then added it to the set of supported types in mmm (on the clientside only) \[[`2ff6f90`][2ff6f90]\].
+This was pretty easy in the end, all it took was adding mermaid.js to the interactive version's resources (in `build/server.moon`)
+and then definig the `convert` (and thereby implicitly defining the corresponding type, `text/mermaid-graph`):
+
+ {
+ inp: 'text/mermaid-graph'
+ out: 'mmm/dom'
+ cost: 1
+ transform: (source) =>
+ with container = document\createElement 'div'
+ cb = (svg, two) =>
+ .innerHTML = svg
+ window.mermaid\render "mermaid-#{id_counter}", source, cb
+ }
+
+The code is quite short, since all it needs to do is create a container element,
+then tell mermaid.js to render the textual definition.
+Once mermaid.js is done, the rendered content is added in the container element.
+
+Here is one of the two diagrams that I implemented the feature for,
+you can also follow the link through to the source and view the textual representation using the 'inspect' button.
+
+<mmm-embed path="/articles/mmmfs/mmmfs/tree_mainstream"></mmm-embed>
+
+[mermaid]: https://mermaidjs.github.io/mermaid-live-editor/
+[2ff6f90]: https://git.s-ol.nu/mmm/commit/2ff6f906c498c1b742dd8437a09c97ebe29a652a/
diff --git a/root/articles/mmmfs/ba_log/2019-10-26/text$markdown.md b/root/articles/mmmfs/ba_log/2019-10-26/text$markdown.md
new file mode 100644
index 0000000..d5cd9bd
--- /dev/null
+++ b/root/articles/mmmfs/ba_log/2019-10-26/text$markdown.md
@@ -0,0 +1,62 @@
+Besides some smaller fixes with the styling of the page, and in particular the diagrams introduced in [`2019-10-24`][2019-10-24],
+I finally (re-)implemented children-ordering in the `fs`-store of mmmmfs
+(the `sql` store is still missing it, but I am not currently using it either) \[[`a62f63b`][a62f63b]\]:
+Files on the regular filesystem don't have a particular order, but in mmmfs the order of children is is guaranteed,
+so that arranging children in a particular order becomes a meaningful tool.
+
+To store the ordering data, a 'magic' file called `$order` is (optionally) stored in each directory in the filesystem.
+The file lists all child fileders by name in the given order.
+When the children of a fileder are requested (in `list_fileders_in` or `get_index`, which relies on the former),
+all children that are mentioned in `$order` are returned in that order,
+while all remaining children are sorted alphabetically and appended at the end of the list.
+This way the order is guaranteed to be stable even if no `$order` file is specified,
+or when the `$order` file has not been updated after adding new children.
+
+Here is the commented implementation in MoonScript:
+
+ list_fileders_in: (path='') =>
+ -- create a mapping of all child-fileders
+ -- in 'entries' (name -> path)
+ entries = {}
+ for entry_name in lfs.dir @root .. path
+ continue if '.' == entry_name\sub 1, 1
+ entry_path = @root .. "#{path}/#{entry_name}"
+ if 'directory' ~= lfs.attributes entry_path, 'mode'
+ continue
+
+ entries[entry_name] = "#{path}/#{entry_name}"
+
+ -- where we will store our sorted list of children
+ sorted = {}
+
+ -- check for existance of the order file
+ order_file = @root .. "#{path}/$order"
+ if 'file' == lfs.attributes order_file, 'mode'
+ for line in io.lines order_file
+ path = assert entries[line], "entry in $order but not on disk: #{line}"
+
+ -- add all $order-entries to the sorted output in the same order they appear.
+ -- also flag these entries as already added
+ table.insert sorted, path
+ sorted[line] = true
+
+ -- find the he remaining (non-flagged) entries, sort them alphabetically
+ -- and then append them to the sorted output list
+ entries = [path for entry, path in pairs entries when not sorted[entry]]
+ table.sort entries
+ for path in *entries
+ table.insert sorted, path
+
+ -- return an iterator over the sorted output
+ coroutine.wrap ->
+ for path in *sorted
+ coroutine.yield path
+
+The interface for reordering fileders is still missing in the code,
+and just while writing this I realized that the current implementation is in fact buggy:
+when a fileder that is mentioned in `$order` is deleted via the `stores.fs` API,
+it is not removed from `$order`, causing an error the next time the fileder is listed.
+I will probably get around to fixing both of these problems when I build the corresponding UI.
+
+[2019-10-24]: /articles/mmmfs/ba_log/2019-10-24/
+[a62f63b]: https://git.s-ol.nu/mmm/commit/a62f63bc00cd63a98b349a2574e3e9e14c95a441/
diff --git a/root/articles/mmmfs/ba_log/2019-10-27/$order b/root/articles/mmmfs/ba_log/2019-10-27/$order
new file mode 100644
index 0000000..2b68b52
--- /dev/null
+++ b/root/articles/mmmfs/ba_log/2019-10-27/$order
@@ -0,0 +1 @@
+video
diff --git a/root/articles/mmmfs/ba_log/2019-10-27/text$markdown.md b/root/articles/mmmfs/ba_log/2019-10-27/text$markdown.md
new file mode 100644
index 0000000..3e9f886
--- /dev/null
+++ b/root/articles/mmmfs/ba_log/2019-10-27/text$markdown.md
@@ -0,0 +1,77 @@
+Today I finally reached the ability of editing content inside of mmmfs directly!
+
+<mmm-embed path="video" nolink></mmm-embed>
+
+Content is currently not saved anywhere, but the basis of the feature is there.
+For the moment this is implemented as yeat another *convert* that simply converts
+from `text/.*` (any textual code) to `mmm/dom` (web UI) \[[`28653c9`][28653c9]\].
+However this *convert* is only applied in the inspector view (more on that below).
+First, here is the convert itself:
+
+ {
+ inp: 'text/([^ ]*).*'
+ out: 'mmm/dom'
+ cost: 0
+ transform: (value, fileder, key) =>
+ mode = @from\match @convert.inp
+ Editor value, mode, fileder, key
+ }
+
+and the main part of the code, the `Editor` widget:
+
+```moonscript
+class Editor
+ new: (value, mode, @fileder, @key) =>
+ @node = div class: 'editor'
+ -- 'o' is a little helper for converting a Lua table to a JS object
+ @cm = window\CodeMirror @node, o {
+ :value
+ :mode
+ lineNumber: true
+ lineWrapping: true
+ autoRefresh: true
+ theme: 'hybrid'
+ }
+
+ @cm\on 'changes', (_, mirr) ->
+ window\clearTimeout @timeout if @timeout
+ @timeout = window\setTimeout (-> @change!), 300
+
+ change: =>
+ @timeout = nil
+ doc = @cm\getDoc!
+ if @lastState and doc\isClean @lastState
+ -- no changes since last event
+ return
+
+ @lastState = doc\changeGeneration true
+ value = doc\getValue!
+
+ @fileder.facets[@key] = value
+ BROWSER\refresh!
+```
+
+I chose the [CodeMirror][codemirror] library as the basis for the editor,
+because it seemed like one of the leanest ones I could find
+(and yet it is quite heavy at 100kb plus styling and language support addons).
+The code for the editor is also quite minimale it really just creates a wrapper for the editor
+and tells CodeMirror to set itself up inside.
+Whenever changes are detected, a timeout of 300ms is started,
+after which the preview is refreshed to preview the changes.
+If more changes are made within the 300ms, the timer is reset to 300ms,
+so that the preview update doesn't interrupt the typing flow.
+
+I also spent some time refactoring the global list of converts out into multiple smaller plugins
+(although a lot of global converts remain at the moment) \[[`abefbf8`][abefbf8]\].
+A plugin can export a list of converts as well as a list of 'editors', which are essentially no different,
+except that they are taken into consideration only when converting content for the inspector.
+
+Breaking the converts up into little packages like that makes it a lot easier to edit,
+and allows enabling and disabling individual features very easily.
+I am also considering moving the converts into the mmmfs data itself,
+to make extending the system and working inside the system more congruent,
+and this is a good way of testing my idea of how the modularization of the system should work.
+
+[codemirror]: https://codemirror.net/
+[28653c9]: https://git.s-ol.nu/mmm/commit/28653c9ae46b2b3e42c2c75879589138c731f37b/
+[abefbf8]: https://git.s-ol.nu/mmm/commit/abefbf82531021f5ca4149675932a7fe2ff37dde/
diff --git a/root/articles/mmmfs/ba_log/2019-10-27/video/video$webm.webm b/root/articles/mmmfs/ba_log/2019-10-27/video/video$webm.webm
new file mode 100644
index 0000000..020e352
--- /dev/null
+++ b/root/articles/mmmfs/ba_log/2019-10-27/video/video$webm.webm
Binary files differ
diff --git a/root/articles/mmmfs/ba_log/2019-10-29/$order b/root/articles/mmmfs/ba_log/2019-10-29/$order
new file mode 100644
index 0000000..2b68b52
--- /dev/null
+++ b/root/articles/mmmfs/ba_log/2019-10-29/$order
@@ -0,0 +1 @@
+video
diff --git a/root/articles/mmmfs/ba_log/2019-10-29/text$markdown.md b/root/articles/mmmfs/ba_log/2019-10-29/text$markdown.md
new file mode 100644
index 0000000..4119d21
--- /dev/null
+++ b/root/articles/mmmfs/ba_log/2019-10-29/text$markdown.md
@@ -0,0 +1,38 @@
+Today I implemented updating/saving content in the server, and bridged the feature to the client.
+In the inspector there is now a `save changes` button that (attempts to) save the content on
+the server's filesystem \[[`4b8d9be`][4b8d9be]\].
+
+<mmm-embed path="video" nolink>demonstration of editing and persistantly saving facet</mmm-embed>
+
+Originally I wanted to create a `sandbox` fileder that was to be edited by any one online \[[`d9eafa2`][d9eafa2]\].
+I restricted editing to only fileders underneath `/sandbox`, but then upon publishing quickly realized
+that this left open a major security vulnerability, since content can be evaluated on server or client:
+if a client were to create a facet `exploit: text/lua -> text/plain` with the following content in the root:
+
+```lua
+pass = io.open('/etc/passwd', 'r')
+return pass:read("*all")
+```
+
+...and then request that facet as converted to `text/plain` (`GET /exploit: text/plain`),
+then that Lua code would be executed on the server, and return the confidential `passwd` file on the server.
+This basically meant handing anyone online full unconditionaly access to my server
+(or at least the VM running the website, and potentially options to escalate from there).
+
+As a result I had to choose to either disable public editing, or disable server-side code execution.
+Because server-side execution is a major feature of mmmfs, I settled for the following compromise \[[`1e3b0a1`][1e3b0a1]\]:
+
+- when developing and running locally, editing and code execution are both enabled in 'unsafe mode'
+- on https://ba.s-ol.nu, editing is disabled but code execution is possible
+- on https://sandbox.s-ol.nu, editing is enabled but code server-side code execution is disabled
+
+The Sandbox can now be found at the following address, at least until the thesis project is concluded:
+
+# [`sandbox.s-ol.nu`](https://sandbox.s-ol.nu)
+
+Currently it is only possible to edit existing facets,
+but creation and deletion of facets and fileders should be implemented soon.
+
+[4b8d9be]: https://git.s-ol.nu/mmm/commit/4b8d9be10e4517114c0c216fa24aaaa310503d4a/
+[d9eafa2]: https://git.s-ol.nu/mmm/commit/d9eafa21ad1d6ad340b5744d69e9fc68ce2083cb/
+[1e3b0a1]: https://git.s-ol.nu/mmm/commit/1e3b0a12060dce916b686921c94520202c4cb130/
diff --git a/root/articles/mmmfs/ba_log/2019-10-29/video/video$mp4.mp4 b/root/articles/mmmfs/ba_log/2019-10-29/video/video$mp4.mp4
new file mode 100644
index 0000000..162d0fc
--- /dev/null
+++ b/root/articles/mmmfs/ba_log/2019-10-29/video/video$mp4.mp4
Binary files differ
diff --git a/root/articles/mmmfs/ba_log/2019-11-01/$order b/root/articles/mmmfs/ba_log/2019-11-01/$order
new file mode 100644
index 0000000..1549b67
--- /dev/null
+++ b/root/articles/mmmfs/ba_log/2019-11-01/$order
@@ -0,0 +1 @@
+demo
diff --git a/root/articles/mmmfs/ba_log/2019-11-01/demo/video$webm.webm b/root/articles/mmmfs/ba_log/2019-11-01/demo/video$webm.webm
new file mode 100644
index 0000000..1463897
--- /dev/null
+++ b/root/articles/mmmfs/ba_log/2019-11-01/demo/video$webm.webm
Binary files differ
diff --git a/root/articles/mmmfs/ba_log/2019-11-01/text$markdown.md b/root/articles/mmmfs/ba_log/2019-11-01/text$markdown.md
new file mode 100644
index 0000000..afcaf0a
--- /dev/null
+++ b/root/articles/mmmfs/ba_log/2019-11-01/text$markdown.md
@@ -0,0 +1,18 @@
+In the last two days I implemented the remaining features for full editing support in the browser:
+
+- support for adding, removing facets in the inspector \[[`dc08e26`][dc08e26]\]
+- support for adding, removing fileders in the inspector \[[`ff9ee8e`][ff9ee8e]\]
+- implemented the API for reordering fileders as mentioned in [`2019-10-26`][2019-10-26] \[[`053e607`][053e607]\]
+- support for reordering fileders in the inspector \[[`16232a2`][16232a2]\]
+
+Here is a short demo video of these features:
+
+<mmm-embed nolink path="demo"></mmm-embed>
+
+As usual, this can be tried out immediately at [`sandbox.s-ol.nu`](//sandbox.s-ol.nu)
+
+[2019-10-26]: /articles/mmmfs/ba_log/2019-10-26/
+[dc08e26]: https://git.s-ol.nu/mmm/commit/dc08e262cd53a48480a88235aa58500f0638ad79/
+[ff9ee8e]: https://git.s-ol.nu/mmm/commit/ff9ee8e99cd5f5c420ba0501c335ac18f1b10769/
+[053e607]: https://git.s-ol.nu/mmm/commit/053e607a49989b2d4491c20ff14c839b7161d713/
+[16232a2]: https://git.s-ol.nu/mmm/commit/16232a2509a87a900b69b2d0f826a2e3edec3f96/
diff --git a/root/articles/mmmfs/ba_log/2019-11-25/$order b/root/articles/mmmfs/ba_log/2019-11-25/$order
new file mode 100644
index 0000000..1549b67
--- /dev/null
+++ b/root/articles/mmmfs/ba_log/2019-11-25/$order
@@ -0,0 +1 @@
+demo
diff --git a/root/articles/mmmfs/ba_log/2019-11-25/demo/video$webm.webm b/root/articles/mmmfs/ba_log/2019-11-25/demo/video$webm.webm
new file mode 100644
index 0000000..bdf9d9c
--- /dev/null
+++ b/root/articles/mmmfs/ba_log/2019-11-25/demo/video$webm.webm
Binary files differ
diff --git a/root/articles/mmmfs/ba_log/2019-11-25/text$markdown.md b/root/articles/mmmfs/ba_log/2019-11-25/text$markdown.md
new file mode 100644
index 0000000..48a0bb4
--- /dev/null
+++ b/root/articles/mmmfs/ba_log/2019-11-25/text$markdown.md
@@ -0,0 +1,89 @@
+There was a longer break in development of the projects as I have been focusing on the thesis,
+where progress is not represented accurately in the repository.
+
+There was also some progress on featurse that haven't been tidied up and committed yet,
+such as drag'n'drop / direct file upload. Those features will probably get their own post sometime soon.
+
+Today I spent some time to implement one of the example use-cases that will be part of the theoretical text as well,
+[the 'pinwall' demo][pinwall] \[[`5ec1fe2`][5ec1fe2]\].
+
+The Pinwall example renders all its children as resizeable and movable boxes that can be freely positioned on a canvas:
+
+<mmm-embed nolink path="demo"></mmm-embed>
+
+Any changes to the box positions and sizes are saved persistently as a `pinwall_info` facet on each child.
+For example the size and coordinates of the image can be found at [`image/pinwall_info: text/json`][info].
+
+Rendering the children themselves is pretty easy:
+
+```moon
+import article, div from require 'mmm.dom'
+import convert from require 'mmm.mmmfs.conversion'
+
+update_info = (fileder, x, y, w, h) ->
+ info = (fileder\get 'pinwall_info: table') or x: 100, y: 100, w: 300, h: 300
+ info.x = x if x
+ info.y = y if y
+ info.w = w if w
+ info.h = h if h
+
+ json = convert 'table', 'text/json', info, fileder, 'pinwall_info'
+ fileder\set 'pinwall_info: text/json', json
+
+=>
+ observe = ... -- (ommited - calls `update_info` when child is resized)
+
+ children = for child in *@children
+ info = (child\get 'pinwall_info: table') or x: 100, y: 100, w: 300, h: 300
+ wrapper = div {
+ style:
+ position: 'absolute'
+ -- (more styling omitted here)
+
+ left: "#{info.x}px"
+ top: "#{info.y}px"
+ width: "#{info.w}px"
+ height: "#{info.h}px"
+
+ -- handle for moving the child
+ div {
+ style:
+ -- (styling omitted here)
+
+ onmousedown: ... -- (omitted)
+ }
+
+ -- child content
+ div {
+ style:
+ width: '100%'
+ height: '100%'
+ background: 'var(--white)'
+
+ (child\gett 'mmm/dom')
+ }
+ }
+
+ observe wrapper, child
+
+ wrapper
+
+ children.style = {
+ width: '1000px'
+ height: '500px'
+ }
+
+ children.onmouseup = ... -- (omitted)
+ children.onmousemove = ... -- (omitted)
+ children.onmouseleave = ... -- (omitted)
+
+ article children
+```
+
+[The rest of the code][source] is just about catching the events when the mouse is clicked/release/moved and when a child is resized,
+and then calling `update_info` as appropriate.
+
+[info]: /articles/mmmfs/examples/pinwall/image/pinwall_info:%20text/html+interactive
+[pinwall]: /articles/mmmfs/examples/pinwall/
+[source]: https://git.s-ol.nu/mmm/blob/5ec1fe2fc943ad4123fac138de70d4152e8b341d/root/articles/mmmfs/examples/pinwall/text%24moonscript%20-%3E%20fn%20-%3E%20mmm%24dom.moon
+[5ec1fe2]: https://git.s-ol.nu/mmm/blob/5ec1fe2fc943ad4123fac138de70d4152e8b341d/
diff --git a/root/articles/mmmfs/ba_log/2019-12-20/text$markdown+sidenotes.md b/root/articles/mmmfs/ba_log/2019-12-20/text$markdown+sidenotes.md
new file mode 100644
index 0000000..3de1a9c
--- /dev/null
+++ b/root/articles/mmmfs/ba_log/2019-12-20/text$markdown+sidenotes.md
@@ -0,0 +1,39 @@
+In the last three days I have been working extensively on support for sidenotes and academic referencing,
+inspired by Edward Tufte's style of publishing (as seen in *Beatiful Evidence* and documented in [tufte-css][tufte-css].
+
+To this end margin-notes have been implemented in the CSS styling of the page using two classes, `sidenote` and
+`sidenote-container`, which are to be applied to individual sidenotes and the containing document respectively.
+Sidenotes are then pulled out of their surrounding context using `position: absolute` and placed in a margin that is
+left free by `sidenote-container`.
+
+Inside of markdown files, sidenotes can then be added simply using basic HTML, like so:
+
+```md
+<div class="sidenote">additional information to be found on the margin</div>
+An example paragraph of text, describing something.
+```
+
+Which will render like this:
+
+> <div class="sidenote">additional information to be found on the margin</div>
+> An example paragraph of text, describing something.
+
+Additionally, conversions from `text/bibtex`, a reference specification format, to `mmm/dom` have been added, that
+create citations using the metadata available in the BibTeX file.
+
+For example the following BibTeX is rendered like this:
+
+<mmm-embed nolink path="../../references/inkandswitch" facet="markdown"></mmm-embed>
+
+> <mmm-embed wrap="raw" path="../../references/inkandswitch"></mmm-embed>
+
+I also added a special override that links to
+BibTeX files by placing the citation in a sidenote, and adding a footnote indicator in-text.
+
+There is also a handy convert that turns ACM Digital Library links into URLs that directly return the BibTeX file,
+which allows me to cite the links directly without manually adding the BibTeX information to my document.
+
+All of this is implemented in the `cites` plug-in: [`cites.moon`][cites.moon].
+
+[cites.moon]: https://git.s-ol.nu/mmm/blob/ba/mmm/mmmfs/plugins/cites.moon
+[tufte-css]: https://edwardtufte.github.io/tufte-css/
diff --git a/root/articles/mmmfs/ba_log/intro: text$markdown.md b/root/articles/mmmfs/ba_log/intro: text$markdown.md
new file mode 100644
index 0000000..37366cf
--- /dev/null
+++ b/root/articles/mmmfs/ba_log/intro: text$markdown.md
@@ -0,0 +1,4 @@
+The following pages document the development of the `mmmfs` system described above in the form of a project log.
+Please note that the log has been written primarily for viewing using a web browser, and as such makes extensive use of
+hyperlinking, and also includes some videos that cannot be reproduced in print. It is therefore recommended to view the
+live version of the log online at the following address: [s-ol.nu/ba/log](https://s-ol.nu/ba/log).
diff --git a/root/articles/mmmfs/ba_log/print: text$moonscript -> fn -> mmm$dom.moon b/root/articles/mmmfs/ba_log/print: text$moonscript -> fn -> mmm$dom.moon
new file mode 100644
index 0000000..97ebd4c
--- /dev/null
+++ b/root/articles/mmmfs/ba_log/print: text$moonscript -> fn -> mmm$dom.moon
@@ -0,0 +1,19 @@
+import div, section, h1, h2, hr from require 'mmm.dom'
+import link_to from (require 'mmm.mmmfs.util') require 'mmm.dom'
+import ropairs from require 'mmm.ordered'
+
+=>
+ div {
+ class: 'print-ownpage'
+
+ h1 (link_to @, "appendix: project log"), id: 'ba-log'
+ @gett 'intro: mmm/dom'
+ table.unpack for post in *@children
+ continue if post\get 'hidden: bool'
+
+ section {
+ hr!
+ h2 link_to post, post\gett 'name: mmm/dom'
+ (post\gett 'mmm/dom')
+ }
+ }
diff --git a/root/articles/mmmfs/ba_log/start/text$markdown.md b/root/articles/mmmfs/ba_log/start/text$markdown.md
new file mode 100644
index 0000000..d56130b
--- /dev/null
+++ b/root/articles/mmmfs/ba_log/start/text$markdown.md
@@ -0,0 +1,25 @@
+The system described in the thesis and subject to the following blog posts was partially pre-existing to the work
+done as part of the thesis and thesis project. The `mmmfs` system was originally developed as the software for my
+personal website, with development beginning around May 2018. In this phase of development the website and system
+changed shape drastically multiple times. In the following paragraphs I will describe the state of the project at
+the last revision prior to the beginning of the thesis project, as it existed before the 7th of October 2019.
+All developments since this revision have been tracked in the following project log entries, and are to be considered
+the practical contributions to the thesis project.
+
+In this revision, the system existed as a tool to produce a static website representing the contents of the `mmmfs`
+system in browsable HTML format. The tool had to be run manually after changes, or using a build tool like [`tup`][tup].
+A primitive *Inspector* tab was present in the HTML output and allowed viewing the raw `mmmfs` contents, but all editing
+of content had to be done with external tools and in the external file-system. To see changes in the browser, a
+compilation phase had to be triggered and completed, and consecutively the page reloaded in the browser. There was no
+server-side component that could convert content or store changes for clients. The tool could only accept content from
+the filesystem, not from zip archives or SQLite databases. The conversion algorithm used was more naive and was not
+able to track cost values, which meant that some more advanced conversions couldn't be implemented.
+
+There was already an example implementation of a simple slideshow present, but due to the lack of editing capabilities
+there was no pinwall examle. There was also no support for side- or marginnotes, or academic referencing and citations.
+There also was no support for [`mermaid`][mermaid] diagrams or JSON-encoded data, and there was no plugin interface.
+The HTML template, CSS styling and JS runtime were all built and tracked outside of the `mmmfs` system itself.
+There was no unit tests for any of the project.
+
+[tup]: http://gittup.org/tup/
+[mermaid]: https://mermaidjs.github.io/
diff --git a/root/articles/mmmfs/ba_log/text$moonscript -> fn -> mmm$dom.moon b/root/articles/mmmfs/ba_log/text$moonscript -> fn -> mmm$dom.moon
new file mode 100644
index 0000000..b6b0756
--- /dev/null
+++ b/root/articles/mmmfs/ba_log/text$moonscript -> fn -> mmm$dom.moon
@@ -0,0 +1,15 @@
+import div, h1, ul, li from require 'mmm.dom'
+import link_to from (require 'mmm.mmmfs.util') require 'mmm.dom'
+import ropairs from require 'mmm.ordered'
+
+=>
+ div {
+ h1 (link_to @, "appendix: project log"), id: 'ba-log'
+ @gett 'intro: mmm/dom'
+ ul do
+ posts = for post in *@children
+ continue if post\get 'hidden: bool'
+ li link_to post, post\gett 'name: mmm/dom'
+
+ posts
+ }
diff --git a/root/articles/mmmfs/conclusion/text$markdown+sidenotes.md b/root/articles/mmmfs/conclusion/text$markdown+sidenotes.md
new file mode 100644
index 0000000..92230a0
--- /dev/null
+++ b/root/articles/mmmfs/conclusion/text$markdown+sidenotes.md
@@ -0,0 +1,11 @@
+# 8&emsp;conclusion
+
+The historical analysis and the evaluation of the proposed system show that many of the limitations of current
+mainstream operating systems can be worked around effectively. The flaws can also be attributed in part to some
+concrete design paradigms, which future system designers may seek to avoid. To this end, the framework provided for
+evaluation may also be useful.
+
+The system proposed and developed in the project corresponding to this thesis has been shown to successfully implement
+many of the properties were hoped to be achieved, such as a modular and consistent architecture and strong support for
+mixed-content transclusions. On the other hand, some limitations in the design are apparent. Many of these limitations
+constitute candidate topics for further research, and most can be attributed to trade-offs made in the development process.
diff --git a/root/articles/mmmfs/empty/title: text$plain b/root/articles/mmmfs/empty/title: text$plain
deleted file mode 100644
index 911f98b..0000000
--- a/root/articles/mmmfs/empty/title: text$plain
+++ /dev/null
@@ -1 +0,0 @@
-Hey I'm an almost empty Fileder.
diff --git a/root/articles/mmmfs/evaluation/text$markdown+sidenotes.md b/root/articles/mmmfs/evaluation/text$markdown+sidenotes.md
new file mode 100644
index 0000000..65024d4
--- /dev/null
+++ b/root/articles/mmmfs/evaluation/text$markdown+sidenotes.md
@@ -0,0 +1,173 @@
+# 7&emsp;evaluation
+In this section, I will first take a look at the implementations of the examples for the use cases outlined above,
+and evaluate them with regard to the framework derived in the corresponding section above. After that, some general
+concerns and insights that have become apparent while developing the system and working with it will be reviewed.
+
+## 7.1&emsp;examples
+### 7.1.1&emsp;publishing and blogging
+Since mmmfs has grown out of the need for a versatile content management system for a personal website and blog, it is
+not surprising to see that it is still up to that job. Nevertheless, it is worth taking a look at its strengths and
+weaknesses in this context:
+
+The system has proven itself perfect for publishing small- and medium-size articles and blog posts, especially for its
+ability to flexibly transclude content from any source. This includes diagrams (such as in this thesis),
+videos (as in the documentation in the appendix), but also less conventional media such as
+interactive diagrams<mmm-embed path="../references/aspect-ratios" wrap="sidenote"></mmm-embed> or twitter postings.
+
+On the other hand, the development of the technical framework for this thesis has posed greater challenges.
+While the reference and sidenote systems integrated well with the rest of the system, some features like automated
+table-of-contents and section numbering were less obvious to tackle and finally completed manually.
+This is mostly due to the approach of splitting up the thesis into a multitude of fileders, and the current lack of
+mechanisms to re-capture information spread throughout the resulting hierarchy effectively.
+
+### 7.1.2&emsp;pinwall
+The pinwall example shows some strengths of the mmmfs system pretty convincingly.
+The type coercion layer completely abstracts away the complexities of transcluding different types of content,
+and only positioning and sizing the content, as well as enabling interaction, remain to handle in the pinwall fileder.
+
+A great benefit of the use of mmmfs versus other technology for realizing this example is that the example can
+seamlessly embed not only plain text, markdown, images, videos, and interactive widgets, but also follow links to all
+of these types of content, and display them meaningfully. Accomplishing this with traditional frameworks would take
+great effort, where mmmfs benefits from the reuse of these conversions across the whole system.
+
+In addition, the script for the pinwall folder is 120 lines long, of which 30 lines are styling, while almost 60 lines
+take care of capturing and handling JS events. The bulk of complexity is therefore shifted towards interacting with the
+UI layer (in this case the browser), which could feasibly be simplified through a custom abstraction layer or the use of
+output means other than the web.
+
+### 7.1.3&emsp;slideshow
+A simplified image slideshow example consists of only 20 lines of code and demonstrates how the reactive component
+framework simplifies the generation of ad-hoc UI dramatically:
+
+```moon
+import ReactiveVar, text, elements from require 'mmm.component'
+import div, a, img from elements
+
+=>
+ index = ReactiveVar 1
+
+ prev = (i) -> math.max 1, i - 1
+ next = (i) -> math.min #@children, i + 1
+
+ div {
+ div {
+ a 'prev', href: '#', onclick: -> index\transform prev
+ index\map (i) -> text " image ##{i} "
+ a 'next', href: '#', onclick: -> index\transform next
+ },
+ index\map (i) ->
+ child = assert @children[i], "image not found!"
+ img src: @children[i]\gett 'URL -> image/png'
+ }
+```
+
+The presentation framework is a bit longer, but the added complexity is again required to deal with browser quirks,
+such as the fullscreen API and sizing content proportionally to the viewport size.
+The parts of the code dealing with the content are essentially identical, except that content is transcluded via the
+more general `mmm/dom` type-interface, allowing for a greater variety of types of content to be used as slides.
+
+## 7.2&emsp;general concerns
+While the system has proven pretty successful and moldable to the different use-cases that it has been tested in,
+there are also limitations in the proposed system that have become obvious in developing and working with the system.
+In this section, these limitations will be discussed individually, and directions for further research and solutions will
+be given where apparent.
+
+### 7.2.1&emsp;global set of converts
+In the current system, there is only a single, global set of *converts* that can be potentially applied to facets
+anywhere in the system.
+Therefore it is necessary to encode behavior directly (as code) in facets wherever exceptional behavior is required.
+For example, if a fileder containing multiple images wants to provide custom UI for each image when viewed independently,
+this code has to either be attached to every image individually (and redundantly), or added as a global convert.
+To make sure this convert does not interfere with images elsewhere in the system, it would be necessary to introduce
+a new type and change the images to use it, which may present even more problems, and works against the principle of
+compatibility that the system has been constructed for.
+
+A potential direction of research in the future is to allow specifying *converts* as part of the fileder tree.
+Application of *converts* could then be scoped to their fileders' subtrees, such that for any facet only the *converts*
+stored in the chain of its parents upwards are considered.
+This way, *converts* can be added locally if they only make sense within a given context.
+Additionally, it could be made possible to use this mechanism to locally override *converts* inherited from
+further up in the tree, for example, to specialize types based on their context in the system.
+
+<mmm-embed wrap="marginnote" path="../references/alternatives-to-trees">See also </mmm-embed>
+The biggest downside to this approach would be that it presents another pressure factor for, while also reinforcing,
+the hierarchical organization of data, thereby exacerbating the limits of hierarchical structures.
+
+### 7.2.2&emsp;code outside of the system
+At the moment, a large part of the mmmfs codebase is still separate from the content and developed outside of mmmfs
+itself. This is a result of the development process of mmmfs and was necessary to start the project as the filesystem
+itself matured, but has now become a limitation of the user experience: potential users of mmmfs would generally start
+by becoming familiar with the operation of mmmfs from within the system, as this is the expected (and designated)
+experience developed for them. All of the code that lives outside of the mmmfs tree is therefore invisible and opaque
+to them, actively limiting their understanding, and thereby the customizability, of the system.
+
+This weakness represents a failure to (fully) implement the quality of a "Living System" as proposed by
+*Ink and Switch*<mmm-embed path="../references/inkandswitch" wrap="sidenote"></mmm-embed>.
+
+In general, however, some portion of code may always have to be left outside of the system.
+This also wouldn't necessarily represent a problem, but in this case it is particularly relevant
+for the global set of *converts* (see above), as well as the layout used to render the web view.
+Both of these are expected to undergo changes as users adapt the system to their own content types and
+domains of interest, as well as their visual identity, respectively.
+
+### 7.2.3&emsp;type system
+The currently used type system based on strings and pattern matching has been largely satisfactory
+but has proven problematic for some anticipated use cases.
+It should be considered to switch to a more intricate,
+structural type system that allows encoding more concrete meta-data alongside the type,
+and to match *converts* based on a more flexible scheme of pattern matching.
+For example, it is envisaged to store the resolution of an image file in its type.
+Many *converts* might choose to ignore this additional information,
+but others could use this information to generate lower-resolution 'thumbnails' of images automatically.
+Using these mechanisms for example images could be requested with a maximum-resolution constraint to save on bandwidth
+when embedded in other documents.
+
+<div style="break-before: page;"></div>
+
+### 7.2.4&emsp;type-coercion
+By giving the system more information about the data it is dealing with,
+and then relying on the system to automatically transform between data-types,
+it is easy to lose track of which format data is concretely stored in.
+In much the same way that the application-centric paradigm alienates users from an understanding
+and feeling of ownership of their data by overemphasizing the tools in between,
+the automagical coercion of data types introduces distance between the user and
+an understanding of the data in the system.
+This poses a threat to the transparency of the system, and potentially a lack of the "Embodiment" quality (see above).
+
+Potential solutions could be to communicate the conversion path clearly and explicitly together with the content,
+as well as making this display interactive to encourage experimentation with custom conversion queries.
+Emphasizing the conversion process more strongly in this way might be a way to turn this feature from an opaque
+hindrance into a transparent tool. This should represent a challenge mostly in terms of UX and UI design.
+
+### 7.2.5&emsp;in-system editing
+Because many *converts* are not necessarily reversible, it is very hard to implement generic ways of editing stored data
+in the same format it is viewed. For example, the system trivially converts markdown-formatted text sources into
+viewable HTML markup, but it is hardly possible to propagate changes to the viewable HTML back to the markdown source.
+This particular instance of the problem might be solvable using a Rich-Text editor, but the general problem worsens when
+the conversion path becomes more complex: If the markdown source was fetched via HTTP from a remote URL (e.g. if the
+facet's type was `URL -> text/markdown`), it is not possible to edit the content at all, since the only data owned by
+the system is the URL string itself, which is not part of the viewable representation. Similarly, when viewing output
+that is generated by code (e.g. `text/moonscript -> mmm/dom`), the code itself is not visible to the user, and if the
+user wishes to change parts of the representation, the system is unable to relate these changes to elements of the code
+or assist the user in doing so.
+
+However, even where plain text is used and edited, a shortcoming of the current approach to editing is evident:
+The content editor is wholly separate from the visible representation, and only facets of the currently viewed fileder
+can be edited. This means that content cannot be edited in its context, which is exacerbated by the extreme
+fragmentation of content that mmmfs encourages.
+
+As a result, interacting with the system at large is still a very different experience from editing content (and
+thereby extending the system) in it. This is expected to represent a major hurdle for users getting started with the
+system and is a major shortcoming in enabling end-user programming, as set as a goal for this project.
+A future iteration should carefully reconsider how editing could be integrated more holistically with the other core
+concepts of the design.
+
+<div style="break-before: page;"></div>
+
+### 7.2.6&emsp;end-user adoption
+As mentioned above, a conscious choice was made to exclude the implementation of a dedicated end-user programming
+facility in the system, and instead conventional programming languages and mechanisms were relied upon as the central
+way of customizing the system and experience. While this was a crucial choice to make in order to proceed with the
+project as a whole, it means that the system currently can not be adopted and used to its full extent by
+end-users. This also means that a full evaluation of the system with regard to end-user empowerment has to be left open
+until this can be changed by further work.
diff --git a/root/articles/mmmfs/examples/$order b/root/articles/mmmfs/examples/$order
new file mode 100644
index 0000000..4ee3140
--- /dev/null
+++ b/root/articles/mmmfs/examples/$order
@@ -0,0 +1,5 @@
+language_support
+image
+markdown
+gallery
+pinwall
diff --git a/root/articles/mmmfs/examples/gallery/$order b/root/articles/mmmfs/examples/gallery/$order
new file mode 100644
index 0000000..9d438bd
--- /dev/null
+++ b/root/articles/mmmfs/examples/gallery/$order
@@ -0,0 +1,2 @@
+link_to_image
+actual_image
diff --git a/root/articles/mmmfs/gallery/actual_image/image$png.png b/root/articles/mmmfs/examples/gallery/actual_image/image$png.png
index b499413..b499413 100644
--- a/root/articles/mmmfs/gallery/actual_image/image$png.png
+++ b/root/articles/mmmfs/examples/gallery/actual_image/image$png.png
Binary files differ
diff --git a/root/articles/mmmfs/gallery/actual_image/preview: image$png.png b/root/articles/mmmfs/examples/gallery/actual_image/preview: image$png.png
index f9dbfad..f9dbfad 100644
--- a/root/articles/mmmfs/gallery/actual_image/preview: image$png.png
+++ b/root/articles/mmmfs/examples/gallery/actual_image/preview: image$png.png
Binary files differ
diff --git a/root/articles/mmmfs/gallery/link_to_image/URL -> image$png b/root/articles/mmmfs/examples/gallery/link_to_image/URL -> image$png
index 7cf76ff..7cf76ff 100644
--- a/root/articles/mmmfs/gallery/link_to_image/URL -> image$png
+++ b/root/articles/mmmfs/examples/gallery/link_to_image/URL -> image$png
diff --git a/root/articles/mmmfs/gallery/link_to_image/preview: URL -> image$png b/root/articles/mmmfs/examples/gallery/link_to_image/preview: URL -> image$png
index 2b2233b..2b2233b 100644
--- a/root/articles/mmmfs/gallery/link_to_image/preview: URL -> image$png
+++ b/root/articles/mmmfs/examples/gallery/link_to_image/preview: URL -> image$png
diff --git a/root/articles/mmmfs/gallery/slideshow: text$moonscript -> fn -> mmm$component.moon b/root/articles/mmmfs/examples/gallery/slideshow: text$moonscript -> fn -> mmm$component.moon
index 0178ac2..0178ac2 100644
--- a/root/articles/mmmfs/gallery/slideshow: text$moonscript -> fn -> mmm$component.moon
+++ b/root/articles/mmmfs/examples/gallery/slideshow: text$moonscript -> fn -> mmm$component.moon
diff --git a/root/articles/mmmfs/gallery/text$moonscript -> fn -> mmm$dom.moon b/root/articles/mmmfs/examples/gallery/text$moonscript -> fn -> mmm$dom.moon
index 9bdac54..9bdac54 100644
--- a/root/articles/mmmfs/gallery/text$moonscript -> fn -> mmm$dom.moon
+++ b/root/articles/mmmfs/examples/gallery/text$moonscript -> fn -> mmm$dom.moon
diff --git a/root/articles/mmmfs/examples/gallery/title: text$plain b/root/articles/mmmfs/examples/gallery/title: text$plain
new file mode 100644
index 0000000..2e9ef34
--- /dev/null
+++ b/root/articles/mmmfs/examples/gallery/title: text$plain
@@ -0,0 +1 @@
+a gallery of images
diff --git a/root/articles/mmmfs/image/URL -> image$png b/root/articles/mmmfs/examples/image/URL -> image$png
index c586722..c586722 100644
--- a/root/articles/mmmfs/image/URL -> image$png
+++ b/root/articles/mmmfs/examples/image/URL -> image$png
diff --git a/root/articles/mmmfs/examples/image/title: text$plain b/root/articles/mmmfs/examples/image/title: text$plain
new file mode 100644
index 0000000..dca924f
--- /dev/null
+++ b/root/articles/mmmfs/examples/image/title: text$plain
@@ -0,0 +1 @@
+link to a remote image
diff --git a/root/articles/mmmfs/examples/implementation: text$markdown+sidenotes.md b/root/articles/mmmfs/examples/implementation: text$markdown+sidenotes.md
new file mode 100644
index 0000000..8a6a185
--- /dev/null
+++ b/root/articles/mmmfs/examples/implementation: text$markdown+sidenotes.md
@@ -0,0 +1,88 @@
+## 6.1&emsp;publishing and blogging
+### 6.1.1&emsp;blogging
+Blogging is pretty straightforward since it generally just involves publishing lightly-formatted text,
+interspersed with media such as images and videos or perhaps social media posts.
+Markdown is a great tool for this job, and has been integrated into the system to much success:
+There are two different types registered with *converts*: `text/markdown` and `text/markdown+span`.
+They both render to HTML (and DOM nodes), so they are immediately viewable as part of the system.
+The only difference for `text/markdown+span` is that it is limited to a single line,
+and doesn't render as a paragraph but rather just a line of text.
+This makes it suitable for denoting formatted-text titles and other small strings of text.
+
+The problem of embedding other content together with text comfortably is also solved easily
+because Markdown allows embedding arbitrary HTML in the document.
+This made it possible to define a set of pseudo-HTML elements in the Markdown-convert,
+`<mmm-embed>` and `<mmm-link>`, which respectively embed and link to other content native to mmmfs.
+
+### 6.1.2&emsp;academic publishing
+<div class="sidenote" style="margin-top: 1.25rem">
+One of the 'standard' solutions, <a href="https://www.latex-project.org/">LaTeX</a>,
+is arguably at least as complex as the mmm system proposed here, but has a much narrower scope,
+since it does not support interaction.
+</div>
+
+Academic publishing is notoriously complex, involving not only the transclusion of diagrams
+and other media but generally requiring precise and consistent control over formatting and layout.
+Some of these complexities are tedious to manage but present good opportunities for programmatic
+systems and media to do work for the writer.
+
+One such topic is the topic of references.
+References appear in various formats at multiple positions in an academic document;
+usually, they are referenced via a reduced visual form within the text of the document
+and then shown again with full details at the end of the document.
+
+For the sake of this thesis, referencing has been implemented using a subset of the popular
+BibTeX format for describing citations. Converts have been implemented for the `text/bibtex`
+type to convert to a full reference format (to `mmm/dom`) and to an inline side-note reference
+(`mmm/dom+link`) that can be transcluded using the `<mmm-link>` pseudo-tag.
+
+For convenience, a convert from the `URL -> cite/acm` type has been provided to `URL -> text/bibtex`,
+which generates links to the ACM Digital Library<mmm-embed path="../references/acm-dl" wrap="sidenote"></mmm-embed>
+API for accessing BibTeX citations for documents in the library. This means that it is enough to store the link to the
+ACM DL entry in mmmfs, and the reference will automatically be fetched, and therefore stay up to date with potential
+remote corrections.
+
+## 6.2&emsp;pinwall
+In many situations, and particularly for creative work, it is often useful to compile resources of
+different types for reference or inspiration and arrange them spatially so that they can be viewed
+at a glance or organized into different contexts, etc.
+Such a pinwall could serve for example to organize references to articles,
+to collect visual inspiration for a mood board, etc.
+
+As a collection, the Pinwall is primarily mapped to a Fileder in the system.
+Any content that is placed within can then be rendered by the Pinwall,
+which can constrain every piece of content to a rectangular piece on its canvas.
+This is possible through a simple script, e.g. of the type `text/moonscript -> fn -> mmm/dom`,
+which enumerates the list of children, wraps each in such a rectangular container
+and outputs the list of containers as DOM elements.
+
+The position and size of each panel are stored in an ad-hoc facet, encoded in the JSON data format:
+`pinwall_info: text/json`. Such a facet is set on each child and read whenever the script is called
+to render the children, plugging the values within the facet into the visual styling of the document.
+
+The script can also set event handlers that react to user input while the document is loaded,
+and allow the user to reposition and resize the individual pinwall items by clicking and dragging
+on the upper border or lower right-hand corner respectively.
+Whenever a change is made the event handler can then update the value in the `pinwall_info` facet,
+so that the updated position and size are stored for the next time the pinwall is opened.
+
+## 6.3&emsp;slideshow
+Another common use of digital documents is as aids in a verbal presentation.
+These often take the form of slideshows, for the creation of which a number of established applications exist.
+In simple terms, a slideshow is simply a linear series of screen-sized documents, that can be
+advanced (and rewound) one by one using keypresses.
+
+The implementation of this is rather straightforward as well.
+The slideshow as a whole becomes a fileder with a script that generates a designated viewport rectangle,
+as well as a control interface with keys for advancing the active slide.
+It also allows putting the browser into fullscreen mode to maximize screen space and remove visual elements
+of the website that may distract from the presentation, and register an event handler for keyboard accelerators
+for moving through the presentation.
+
+Finally, the script simply embeds the first of its child-fileders into the viewport rectangle.
+Once the current slide is changed, the next embedded child is simply chosen.
+
+<!--
+## code documentation
+/meta/mmm.dom/:%20text/html+interactive
+-->
diff --git a/root/articles/mmmfs/examples/intro: text$markdown+sidenotes.md b/root/articles/mmmfs/examples/intro: text$markdown+sidenotes.md
new file mode 100644
index 0000000..126f407
--- /dev/null
+++ b/root/articles/mmmfs/examples/intro: text$markdown+sidenotes.md
@@ -0,0 +1,10 @@
+# 6&emsp;example use-cases
+To illustrate the capabilities of the proposed system, and to compare the results with the framework introduced above,
+a number of example use cases have been chosen and implemented from the perspective of a user.
+In the following section I will introduce these use cases and briefly summarize the implementation
+approach in terms of the capabilities of the proposed system.
+
+<div style="break-before: page;"></div>
+
+<span class="sidenote">The online version is available at [s-ol.nu/ba](https://s-ol.nu/ba).</span>
+The following examples can be viewed and inspected in the interactive version online:
diff --git a/root/articles/mmmfs/examples/language_support/$order b/root/articles/mmmfs/examples/language_support/$order
new file mode 100644
index 0000000..3cc0e47
--- /dev/null
+++ b/root/articles/mmmfs/examples/language_support/$order
@@ -0,0 +1,3 @@
+javascript
+moonscript
+lua
diff --git a/root/articles/mmmfs/language_support/javascript/text$javascript -> mmm$dom.js b/root/articles/mmmfs/examples/language_support/javascript/text$javascript -> mmm$dom.js
index de56531..de56531 100644
--- a/root/articles/mmmfs/language_support/javascript/text$javascript -> mmm$dom.js
+++ b/root/articles/mmmfs/examples/language_support/javascript/text$javascript -> mmm$dom.js
diff --git a/root/articles/mmmfs/language_support/javascript/title: text$plain b/root/articles/mmmfs/examples/language_support/javascript/title: text$plain
index 581fbc7..581fbc7 100644
--- a/root/articles/mmmfs/language_support/javascript/title: text$plain
+++ b/root/articles/mmmfs/examples/language_support/javascript/title: text$plain
diff --git a/root/articles/mmmfs/language_support/lua/text$lua -> mmm$dom.lua b/root/articles/mmmfs/examples/language_support/lua/text$lua -> mmm$dom.lua
index 62e79f1..62e79f1 100644
--- a/root/articles/mmmfs/language_support/lua/text$lua -> mmm$dom.lua
+++ b/root/articles/mmmfs/examples/language_support/lua/text$lua -> mmm$dom.lua
diff --git a/root/articles/mmmfs/language_support/lua/title: text$plain b/root/articles/mmmfs/examples/language_support/lua/title: text$plain
index 0f9d550..0f9d550 100644
--- a/root/articles/mmmfs/language_support/lua/title: text$plain
+++ b/root/articles/mmmfs/examples/language_support/lua/title: text$plain
diff --git a/root/articles/mmmfs/language_support/moonscript/text$moonscript -> mmm$dom.moon b/root/articles/mmmfs/examples/language_support/moonscript/text$moonscript -> mmm$dom.moon
index 5cc50e6..5cc50e6 100644
--- a/root/articles/mmmfs/language_support/moonscript/text$moonscript -> mmm$dom.moon
+++ b/root/articles/mmmfs/examples/language_support/moonscript/text$moonscript -> mmm$dom.moon
diff --git a/root/articles/mmmfs/language_support/moonscript/title: text$plain b/root/articles/mmmfs/examples/language_support/moonscript/title: text$plain
index f8871ac..f8871ac 100644
--- a/root/articles/mmmfs/language_support/moonscript/title: text$plain
+++ b/root/articles/mmmfs/examples/language_support/moonscript/title: text$plain
diff --git a/root/articles/mmmfs/language_support/preview: text$markdown b/root/articles/mmmfs/examples/language_support/preview: text$markdown
index d6c2845..d6c2845 100644
--- a/root/articles/mmmfs/language_support/preview: text$markdown
+++ b/root/articles/mmmfs/examples/language_support/preview: text$markdown
diff --git a/root/articles/mmmfs/language_support/text$moonscript -> fn -> mmm$dom.moon b/root/articles/mmmfs/examples/language_support/text$moonscript -> fn -> mmm$dom.moon
index 4ae0679..4ae0679 100644
--- a/root/articles/mmmfs/language_support/text$moonscript -> fn -> mmm$dom.moon
+++ b/root/articles/mmmfs/examples/language_support/text$moonscript -> fn -> mmm$dom.moon
diff --git a/root/articles/mmmfs/language_support/title: text$plain b/root/articles/mmmfs/examples/language_support/title: text$plain
index ae06474..ae06474 100644
--- a/root/articles/mmmfs/language_support/title: text$plain
+++ b/root/articles/mmmfs/examples/language_support/title: text$plain
diff --git a/root/articles/mmmfs/examples/markdown/text$markdown.md b/root/articles/mmmfs/examples/markdown/text$markdown.md
new file mode 100644
index 0000000..880eedb
--- /dev/null
+++ b/root/articles/mmmfs/examples/markdown/text$markdown.md
@@ -0,0 +1,20 @@
+This is a markdown document rendered using [marked][marked] on the client, and [discount][discount] on the server.
+All Markdown features are supported, for example there is support for lists...
+
+- a list of things
+- (two things)
+
+...and syntax-highlighted code tags:
+
+```
+print "Hello World"
+```
+
+Since Markdown supports inline HTML, mmmfs shorthands can also be used to embed and reference content from elsewhere in
+the system. For example, the title of this fileder can be embedded using
+`<mmm-embed facet="title"></mmm-embed>`:
+
+<mmm-embed facet="title"></mmm-embed>
+
+[marked]: https://marked.js.org/
+[discount]: https://luarocks.org/modules/craigb/discount
diff --git a/root/articles/mmmfs/examples/markdown/title: text$plain b/root/articles/mmmfs/examples/markdown/title: text$plain
new file mode 100644
index 0000000..7915148
--- /dev/null
+++ b/root/articles/mmmfs/examples/markdown/title: text$plain
@@ -0,0 +1 @@
+markdown content
diff --git a/root/articles/mmmfs/examples/pinwall/$order b/root/articles/mmmfs/examples/pinwall/$order
new file mode 100644
index 0000000..b8b054a
--- /dev/null
+++ b/root/articles/mmmfs/examples/pinwall/$order
@@ -0,0 +1,3 @@
+image
+text
+video
diff --git a/root/articles/mmmfs/examples/pinwall/image/image$png.png b/root/articles/mmmfs/examples/pinwall/image/image$png.png
new file mode 100644
index 0000000..1628d99
--- /dev/null
+++ b/root/articles/mmmfs/examples/pinwall/image/image$png.png
Binary files differ
diff --git a/root/articles/mmmfs/examples/pinwall/image/pinwall_info: text$json b/root/articles/mmmfs/examples/pinwall/image/pinwall_info: text$json
new file mode 100644
index 0000000..e5893ac
--- /dev/null
+++ b/root/articles/mmmfs/examples/pinwall/image/pinwall_info: text$json
@@ -0,0 +1 @@
+{"x": 94.0, "y": 265.0, "w": 205.0, "h": 155.0} \ No newline at end of file
diff --git a/root/articles/mmmfs/examples/pinwall/text$moonscript -> fn -> mmm$dom.moon b/root/articles/mmmfs/examples/pinwall/text$moonscript -> fn -> mmm$dom.moon
new file mode 100644
index 0000000..e611579
--- /dev/null
+++ b/root/articles/mmmfs/examples/pinwall/text$moonscript -> fn -> mmm$dom.moon
@@ -0,0 +1,120 @@
+import article, div from require 'mmm.dom'
+import convert from require 'mmm.mmmfs.conversion'
+
+update_info = (fileder, x, y, w, h) ->
+ info = (fileder\get 'pinwall_info: table') or x: 100, y: 100, w: 300, h: 300
+ info.x = x if x
+ info.y = y if y
+ info.w = w if w
+ info.h = h if h
+
+ json = convert 'table', 'text/json', info, fileder, 'pinwall_info'
+ fileder\set 'pinwall_info: text/json', json
+
+CLIENT = MODE == 'CLIENT'
+
+=>
+
+ pending = {}
+ observe = if CLIENT
+ map = {}
+ observer = js.new js.global.ResizeObserver, (_, entries) ->
+ for entry in js.of entries
+ if child = map[entry.target]
+ rect = entry.contentRect
+ pending[child] = -> update_info child, nil, nil, rect.width, rect.height
+
+ (node, child) ->
+ map[node] = child
+ observer\observe node
+
+ drag = nil
+
+ children = for child in *@children
+ info = (child\get 'pinwall_info: table') or x: 100, y: 100, w: 300, h: 300
+ wrapper = div {
+ style:
+ position: 'absolute'
+ padding: '10px'
+ resize: 'both'
+ overflow: 'hidden'
+ background: 'var(--gray-dark)'
+ border: '1px solid var(--gray-bright)'
+
+ left: "#{info.x}px"
+ top: "#{info.y}px"
+ width: "#{info.w}px"
+ height: "#{info.h}px"
+
+ -- handle for moving the child
+ div {
+ style:
+ top: '0'
+ left: '0'
+ right: '0'
+ height: '10px'
+ cursor: 'pointer'
+ position: 'absolute'
+
+ onmousedown: CLIENT and (_, e) ->
+ node = e.target.parentElement
+ drag = {
+ :child
+ :node
+
+ startX: tonumber node.style.left\match '(%d+)px'
+ startY: tonumber node.style.top\match '(%d+)px'
+ startMouseX: e.clientX
+ startMouseY: e.clientY
+ }
+ }
+
+ -- child content
+ div {
+ style:
+ width: '100%'
+ height: '100%'
+ background: 'var(--white)'
+
+ (child\gett 'mmm/dom')
+ }
+ }
+
+ -- listen for resize events
+ observe wrapper, child if CLIENT
+ wrapper
+
+ children.style = {
+ width: '1000px'
+ height: '500px'
+ }
+
+ if CLIENT
+ children.onmousemove = (_, e) ->
+ return unless drag
+
+ x = drag.startX + (e.clientX - drag.startMouseX)
+ y = drag.startY + (e.clientY - drag.startMouseY)
+ drag.node.style.left = "#{x}px"
+ drag.node.style.top = "#{y}px"
+
+ children.onmouseup = (_, e) ->
+ for k, func in pairs pending
+ func!
+ pending = {}
+
+ return unless drag
+
+ x = drag.startX + (e.clientX - drag.startMouseX)
+ y = drag.startY + (e.clientY - drag.startMouseY)
+ update_info drag.child, x, y
+ drag = nil
+
+ children.onmouseleave = (_, e) ->
+ return unless drag
+
+ drag.node.style.left = "#{drag.startX}px"
+ drag.node.style.top = "#{drag.startY}px"
+ drag = nil
+
+ article children
diff --git a/root/articles/mmmfs/examples/pinwall/text/pinwall_info: text$json b/root/articles/mmmfs/examples/pinwall/text/pinwall_info: text$json
new file mode 100644
index 0000000..39bdb45
--- /dev/null
+++ b/root/articles/mmmfs/examples/pinwall/text/pinwall_info: text$json
@@ -0,0 +1 @@
+{"x": 53.0, "y": 64.0, "w": 396.0, "h": 74.0} \ No newline at end of file
diff --git a/root/articles/mmmfs/examples/pinwall/text/text$plain.txt b/root/articles/mmmfs/examples/pinwall/text/text$plain.txt
new file mode 100644
index 0000000..8838e5a
--- /dev/null
+++ b/root/articles/mmmfs/examples/pinwall/text/text$plain.txt
@@ -0,0 +1,4 @@
+This is a pinwall example.
+Every box is a separate fileder.
+The boxes can be rearranged and resized freely.
+If the server is in read-write mode, the changes are saved persistently in real time.
diff --git a/root/articles/mmmfs/examples/pinwall/title: text$plain b/root/articles/mmmfs/examples/pinwall/title: text$plain
new file mode 100644
index 0000000..c629992
--- /dev/null
+++ b/root/articles/mmmfs/examples/pinwall/title: text$plain
@@ -0,0 +1 @@
+a pinwall
diff --git a/root/articles/mmmfs/examples/pinwall/video/URL -> video$mp4 b/root/articles/mmmfs/examples/pinwall/video/URL -> video$mp4
new file mode 100644
index 0000000..6364771
--- /dev/null
+++ b/root/articles/mmmfs/examples/pinwall/video/URL -> video$mp4
@@ -0,0 +1 @@
+https://file-examples.com/wp-content/uploads/2017/04/file_example_MP4_480_1_5MG.mp4
diff --git a/root/articles/mmmfs/examples/pinwall/video/pinwall_info: text$json b/root/articles/mmmfs/examples/pinwall/video/pinwall_info: text$json
new file mode 100644
index 0000000..7be8702
--- /dev/null
+++ b/root/articles/mmmfs/examples/pinwall/video/pinwall_info: text$json
@@ -0,0 +1 @@
+{"x": 534.0, "y": 136.0, "w": 387.0, "h": 218.0} \ No newline at end of file
diff --git a/root/articles/mmmfs/examples/text$moonscript -> fn -> mmm$dom.moon b/root/articles/mmmfs/examples/text$moonscript -> fn -> mmm$dom.moon
new file mode 100644
index 0000000..2988f29
--- /dev/null
+++ b/root/articles/mmmfs/examples/text$moonscript -> fn -> mmm$dom.moon
@@ -0,0 +1,44 @@
+-- main content
+-- doesn't have a name prefix (e.g. preview: fn -> mmm/dom)
+-- uses the 'fn ->' conversion to execute the lua function on @get
+-- resolves to a value of type mmm/dom
+=>
+ html = require 'mmm.dom'
+ import h4, div, a, span, ul, li from html
+ import link_to from (require 'mmm.mmmfs.util') html
+
+ -- render a preview block
+ preview = (child) ->
+ -- get 'title' as 'text/plain' (error if no value or conversion possible)
+ title = child\gett 'title', 'text/plain'
+
+ -- get 'preview' as a DOM description (nil if no value or conversion possible)
+ -- content = child\get 'preview', 'mmm/dom'
+
+ -- div {
+ -- h4 title, style: { margin: 0, cursor: 'pointer' }, onclick: -> BROWSER\navigate child.path
+ -- content or span '(no renderable content)', style: { color: 'red' },
+ -- style: {
+ -- display: 'inline-block',
+ -- width: '300px',
+ -- height: '200px',
+ -- padding: '4px',
+ -- margin: '8px',
+ -- border: '4px solid #eeeeee',
+ -- overflow: 'hidden',
+ -- },
+ -- }
+
+ li link_to child
+
+ examples = ul for child in *@children
+ preview child
+
+ div {
+ style:
+ 'break-after': 'page'
+
+ (@gett 'intro: mmm/dom')
+ examples
+ (@gett 'implementation: mmm/dom')
+ }
diff --git a/root/articles/mmmfs/framework/text$markdown+sidenotes.md b/root/articles/mmmfs/framework/text$markdown+sidenotes.md
new file mode 100644
index 0000000..e5f3c7e
--- /dev/null
+++ b/root/articles/mmmfs/framework/text$markdown+sidenotes.md
@@ -0,0 +1,96 @@
+# 4&emsp;evaluation framework
+
+In this section, I will collect approaches and reviews of different end-user software systems from current literature,
+as well as derive and present my own requirements and guiding principles for the development of a new system.
+
+Firstly, I will take a look at a framework for evaluating end-user computing systems from literature, before presenting
+three concrete design principles and components for a new system.
+
+4.1&emsp;qualities of successful end-user computing
+---------------------------------------------------
+
+*Ink and Switch* suggest three qualities for tools striving to support <span style="display: inline-block;">
+end-user programming<mmm-embed path="../references/inkandswitch" wrap="sidenote"></mmm-embed>:</span>
+
+- *Embodiment*, i.e. reifying central concepts of the programming model as more concrete, tangible objects
+ in the digital space (for example, through visual representation),
+ in order to reduce cognitive load on the user.
+- *Living System*, by which they seem to describe the malleability of a system or environment,
+ and in particular the ability to make changes at different levels of depth in the system with
+ very short feedback loops and a feeling of direct experience.
+- *In-place toolchain*, denoting the availability of tools to customize and author the experience,
+ as well as a certain accessibility of these tools, granted by a conceptual affinity between the
+ use of the tools and general 'passive' use of containing system at large.
+
+These serve as guiding principles for the design and evaluation of computer systems for end-users but are by nature
+very abstract. The following properties are therefore derived as more concrete proposals based on more specific
+constraints: namely the construction of a system for end-users to keep, structure and display personal information and
+thoughts.
+
+<div style="break-after: page;"></div>
+
+4.2&emsp;modularity
+-------------------
+
+The *UNIX Philosophy*<mmm-embed path="../references/unix" wrap="sidenote"></mmm-embed> describes the software design
+paradigm pioneered in the creation of the Unix operating system at the AT&T Bell Labs research center in the 1960s. The
+concepts are considered quite influential and are still notably applied in the Linux community. Many attempts at
+summaries exist, but the following includes the pieces that are especially relevant even today:
+
+<mmm-embed path="../references/unix" wrap="marginnote"></mmm-embed>
+> Even though the UNIX system introduces a number of innovative programs and techniques, no single program or idea makes
+> it work well. Instead, what makes it effective is the approach to programming, a philosophy of using the computer.
+> Although that philosophy can't be written down in a single sentence, at its heart is the idea that the power of a
+> system comes more from the relationships among programs than from the programs themselves. Many UNIX programs do quite
+> trivial things in isolation, but, combined with other programs, become general and useful tools.
+
+This approach has multiple benefits with regard to end-user programmability: Assembling the system out of simple,
+modular pieces means that for any given task a user may want to implement, it is very likely that preexisting parts
+of the system can help the user realize a solution. Wherever such a preexisting part exists, it pays off designing it
+in such a way that it is easy to integrate for the user later. Assembling the system as a collection of modular,
+interacting pieces also enables future growth and customization, since pieces may be swapped out with customized or
+alternate software at any time.
+
+Settling on a specific modular design model, and reifying other components of a system in terms of it, also corresponds
+directly to the concept of *Embodiment* described by Ink & Switch.
+
+4.3&emsp;content transclusion
+-----------------------------
+
+The strengths of modular architectures should similarly extend also into the way the system will be used by users.
+If users are to store their information and customized behavior in such an architecture, then powerful tools need to be
+present in order to assemble more complex solutions out of such parts. Therefore static content should be able to be
+linked to (as envisioned for the *Memex*, see above), but also to be <mmm-embed wrap="marginnote"
+path="../references/transclusion">The term <i>transclusion</i> refers to the concept of including content from a
+separate document, possibly stored remotely, by reference rather than by duplication. See also
+</mmm-embed>*transcluded*,
+to facilitate the creation of flexible data formats and interactions, such that e.g. a slideshow slide can include
+content in a variety other formats (such as images and text) from anywhere else in the system. Behaviors also should be
+able to be transcluded and reused to facilitate the creation of ad-hoc systems and applets based on user needs. For
+example, a user-created todo list should be able to take advantage of a sketching tool the user already has access to.
+
+By forming the immediately user-visible layer of the system out of the same abstractions that the deeper levels of the
+system are made of, the sense of a *Living System* is also improved: skills that are learned at one (lower) level of the
+system carry on into further interaction with the system on deeper levels, as does progress in understanding the
+system's mechanisms.
+
+While there are drawbacks to cloud-storage of data (as outlined above), the utility of distributed systems is
+acknowledged, and the system should therefore be able to include content and behaviors via the network.
+This ability should be integrated deeply into the system, so that data can be treated independently of its origin and
+storage conditions, with as little caveats as possible. In particular, the interactions of remote data access and
+content transclusion should be paid attention to and taken into consideration for a system's design.
+
+4.4&emsp;end-user programming
+-----------------------------
+
+In order to provide users full access to their information as well as the computational infrastructure,
+users need to be able to finely customize and reorganize the smallest pieces to suit their own purposes,
+in other words: be able to program.
+
+While there is an ongoing area of research focusing on the development of new programming paradigms,
+methodologies, and tools that are more accessible and cater to the wide
+range of end-users<mmm-embed path="../references/subtext" wrap="sidenote"></mmm-embed>,
+in order to keep the scope of this work appropriate,
+conventional programming languages are used for the time being.
+Confidence is placed in the fact that eventually more user-friendly languages will be available and,
+given the goal of modularity, should be implementable in a straightforward fashion.
diff --git a/root/articles/mmmfs/gallery/preview: text$moonscript -> fn -> mmm$dom.moon b/root/articles/mmmfs/gallery/preview: text$moonscript -> fn -> mmm$dom.moon
deleted file mode 100644
index 5285629..0000000
--- a/root/articles/mmmfs/gallery/preview: text$moonscript -> fn -> mmm$dom.moon
+++ /dev/null
@@ -1,7 +0,0 @@
-import div, img, br from require 'mmm.dom'
-
-=> div {
- 'the first pic as a little taste:',
- br!,
- img src: @children[1]\get 'preview', 'URL -> image/png'
-}
diff --git a/root/articles/mmmfs/gallery/title: text$plain b/root/articles/mmmfs/gallery/title: text$plain
deleted file mode 100644
index ad74eec..0000000
--- a/root/articles/mmmfs/gallery/title: text$plain
+++ /dev/null
@@ -1 +0,0 @@
-A Gallery of 25 random pictures, come on in!
diff --git a/root/articles/mmmfs/historical-approaches/$order b/root/articles/mmmfs/historical-approaches/$order
new file mode 100644
index 0000000..b98a91b
--- /dev/null
+++ b/root/articles/mmmfs/historical-approaches/$order
@@ -0,0 +1 @@
+star-graph
diff --git a/root/articles/mmmfs/historical-approaches/star-graph/image$png.png b/root/articles/mmmfs/historical-approaches/star-graph/image$png.png
new file mode 100644
index 0000000..ed4003c
--- /dev/null
+++ b/root/articles/mmmfs/historical-approaches/star-graph/image$png.png
Binary files differ
diff --git a/root/articles/mmmfs/historical-approaches/star-graph/note: text$markdown.md b/root/articles/mmmfs/historical-approaches/star-graph/note: text$markdown.md
new file mode 100644
index 0000000..eb115dd
--- /dev/null
+++ b/root/articles/mmmfs/historical-approaches/star-graph/note: text$markdown.md
@@ -0,0 +1,4 @@
+<p><i>How systems influenced later systems. This graph summarizes how various systems related to Star have influenced
+one another over the years. Time progresses downwards. Double arrows indicate direct successors (i.e.,
+follow-on versions). [...]</i></p>
+<mmm-embed wrap="raw" path="../../references/xerox-star"></mmm-embed>
diff --git a/root/articles/mmmfs/historical-approaches/text$markdown+sidenotes.md b/root/articles/mmmfs/historical-approaches/text$markdown+sidenotes.md
new file mode 100644
index 0000000..dfe9390
--- /dev/null
+++ b/root/articles/mmmfs/historical-approaches/text$markdown+sidenotes.md
@@ -0,0 +1,73 @@
+<div style="break-before: page;"></div>
+
+# 3&emsp;historical approaches
+
+Two of the earliest holistic computing systems, the Xerox Alto and Xerox Star, both developed at Xerox PARC and
+introduced in the 70s and early 80s pioneered not only graphical user-interfaces but also the "Desktop Metaphor".
+The desktop metaphor presents information as stored in "Documents" that can be organized in folders and on the
+"Desktop". It invokes a strong analogy to physical tools. One of the differences between the Xerox Star system and
+other systems at the time, as well as the systems we use currently, is that the type of data a file represents is
+directly known to the system.
+
+In a retrospective analysis of the Xerox Star's impact on the computer industry, the desktop metaphor is described as
+follows:
+
+<mmm-embed path="../references/xerox-star" wrap="marginnote"></mmm-embed>
+> In a Desktop metaphor system, users deal mainly with data files, oblivious to the existence of programs.
+> They do not "invoke a text editor", they "open a document".
+> The system knows the type of each file and notifies the relevant application program when one is opened.
+>
+> The disadvantage of assigning data files to applications is that users sometimes want to operate on a file with a
+> program other than its "assigned" application. \[...\]
+> Star's designers feel that, for its audience, the advantages of allowing users to forget about programs outweighs
+> this disadvantage.
+
+Other systems at the time lacked any knowledge of the type of files, and while mainstream operating systems of today
+have retro-fit the ability to associate and memorize the preferred applications to use for a given file based on its
+name suffix, the intention of making applications a secondary, technical detail of working with the computer has
+surely been lost.
+
+Another design detail of the Star system is the concept of "properties" that are stored for "objects" throughout the
+system (the objects being anything from files to characters or paragraphs). These typed pieces of information are
+labeled with a name and persistently stored, providing a mechanism to store metadata such as user preference for
+ordering or the default view mode of a folder for example.
+
+The earliest indirect influence for the Xerox Alto and many other systems of its time was the *Memex*.
+The *Memex* is a hypothetical device and system for knowledge management. Proposed by Vannevar Bush in 1945<mmm-embed
+path="../references/memex" wrap="sidenote"></mmm-embed>, the concept predates much of the technology that later was used
+to implement many parts of the vision.
+
+<mmm-embed path="star-graph" facet="note" wrap="marginnote" style="margin-top: 1rem;"></mmm-embed>
+<mmm-embed path="star-graph" nolink></mmm-embed>
+
+<!--
+While the article extrapolates from existing technology at the time, describing at times
+very concrete machinery based on microfilm and mechanical contraptions, many of the conceptual predictions became
+true or inspired ....
+-->
+
+One of the most innovative elements of Bush's predictions is the idea of technologically cross-referenced and
+connected information, which would later be known and created as *hypertext*. While hypertext powers the majority of
+today's internet, many of the advantages that Bush imagined have not carried over into the personal use of computers.
+There are very few tools for creating personal, highly-interconnected knowledge bases, even though it is technologically
+feasible and a proven concept (exemplified for example by the massively successful online encyclopedia
+*Wikipedia*<mmm-embed path="../references/wikipedia" wrap="sidenote"></mmm-embed>).
+
+While there are few such tools available today, one of the systems that could be said to have come closest to a
+practical implementation of a Memex-inspired system for personal use might be Apple's *HyperCard*.
+
+In a live demonstration<mmm-embed path="../references/hypercard" wrap="sidenote"></mmm-embed>, the creators of the
+software showcase a system of stacks of cards that together implement, amongst others, a calendar (with yearly and
+weekly views), a list of digital business cards for storing phone numbers and addresses, and a todo list. However these
+stacks of cards are not just usable by themselves, it is also demonstrated how stacks can link to each other in
+meaningful ways, such as jumping to the card corresponding to a specific day from the yearly calendar view or
+automatically looking up the card corresponding to a person's first name from a mention of the name in the text on a
+different card.
+
+Alongside Spreadsheets, *HyperCard* remains one of the most successful implementations of end-user programming, even
+today. While its technical abilities have been long matched and surpassed by other software (such as the ubiquitous
+*Hypertext Markup Language* HTML, and the associated programming language *JavaScript*), these technical successors have
+failed the legacy of *HyperCard* as an end-user tool: While it is easier than ever to publish content on the web
+(through various social media and microblogging services), the benefits of hypermedia as a customizable medium for
+personal management have nearly vanished. End-users do not create hypertext anymore.
+
diff --git a/root/articles/mmmfs/image/preview: text$moonscript -> fn -> mmm$dom.moon b/root/articles/mmmfs/image/preview: text$moonscript -> fn -> mmm$dom.moon
deleted file mode 100644
index 6c431d0..0000000
--- a/root/articles/mmmfs/image/preview: text$moonscript -> fn -> mmm$dom.moon
+++ /dev/null
@@ -1,5 +0,0 @@
-import img from require 'mmm.dom'
-
--- look for main content with 'URL to png' type
--- and wrap in an mmm/dom image tag
-=> img src: @gett 'URL -> image/png'
diff --git a/root/articles/mmmfs/image/title: text$plain b/root/articles/mmmfs/image/title: text$plain
deleted file mode 100644
index 60a556f..0000000
--- a/root/articles/mmmfs/image/title: text$plain
+++ /dev/null
@@ -1 +0,0 @@
-Hey I'm like a link to a picture or smth
diff --git a/root/articles/mmmfs/introduction/text$markdown.md b/root/articles/mmmfs/introduction/text$markdown.md
new file mode 100644
index 0000000..b8550fe
--- /dev/null
+++ b/root/articles/mmmfs/introduction/text$markdown.md
@@ -0,0 +1,18 @@
+1&emsp;introduction
+====================
+
+As of December 2019, there are only four major operating systems available to end-users for desktop and mobile
+devices<mmm-embed path="../references/market-share" wrap="sidenote"></mmm-embed>. All of these systems are comparatively inflexible and
+can only be customized by users where the system or application developers have anticipated a need with corresponding
+options. Only a small minority of professional or hobby developers have the knowledge and tools at their disposal to
+create their own digital experiences, and even for them, the process is often too complex and inefficient to do so
+effectively.
+However, historically, empowered ownership of the computing experience was not meant to be restricted only to
+end-users. Many computing systems designed during the computer revolution were designed specifically with the goal of
+complete customizability by users, but little of this approach remains in the systems we use today.
+
+In the first section of this thesis, I will discuss some of the limitations of mainstream operating systems and
+potential causes in detail. Next, I will highlight some of the contrasting approaches found in historic computing
+systems, and then derive a framework for the evaluation of end-user computing systems with regard to user empowerment.
+I will then discuss a new computing system, demonstrate it in some example use cases, and evaluate it using the
+framework.
diff --git a/root/articles/mmmfs/markdown/preview: text$markdown.md b/root/articles/mmmfs/markdown/preview: text$markdown.md
deleted file mode 100644
index 4b38ef2..0000000
--- a/root/articles/mmmfs/markdown/preview: text$markdown.md
+++ /dev/null
@@ -1,6 +0,0 @@
-See I have like
-
-- a list of things
-- (two things)
-
-and some bold **text** and `code tags` with me.
diff --git a/root/articles/mmmfs/markdown/title: text$plain b/root/articles/mmmfs/markdown/title: text$plain
deleted file mode 100644
index 319068d..0000000
--- a/root/articles/mmmfs/markdown/title: text$plain
+++ /dev/null
@@ -1 +0,0 @@
- I'm not even five lines of markdown but i render myself!
diff --git a/root/articles/mmmfs/mmmfs/$order b/root/articles/mmmfs/mmmfs/$order
new file mode 100644
index 0000000..5a5d5ab
--- /dev/null
+++ b/root/articles/mmmfs/mmmfs/$order
@@ -0,0 +1,3 @@
+type_coercion_graph
+tree_mmmfs
+tree_mainstream
diff --git a/root/articles/mmmfs/mmmfs/text$markdown+sidenotes.md b/root/articles/mmmfs/mmmfs/text$markdown+sidenotes.md
new file mode 100644
index 0000000..f04e671
--- /dev/null
+++ b/root/articles/mmmfs/mmmfs/text$markdown+sidenotes.md
@@ -0,0 +1,197 @@
+# 5&emsp;system description
+
+Alongside this thesis, a new end-user computing system has been developed together with the framework presented above.
+The system, `mmmfs`, is a personal data storage and processing system that was initially developed as a tool for
+generating static websites but has now been extended with capabilities for live interaction and introspection, as well
+as embedded editing, as part of this work.
+
+mmmfs has been designed with a focus on data ownership for users. One of the main driving ideas is to unlock data
+from external data silos and file formats by making data available uniformly across different storage systems and
+formats. Secondly, computation and interactive elements are also integrated into this paradigm, so that mmmfs can be
+seamlessly extended and molded to the user's needs.
+
+The abstraction of data types is accomplished using two major components, the *Type System and Coercion Engine* and
+the *Fileder Unified Data Model* for unified data storage and access. In the next sections, the design and
+implementation of these two components will be described in detail.
+
+## 5.1&emsp;data storage model
+The Fileder Model is the underlying unified data storage model.
+Like many data storage models it is based fundamentally on the concept of a hierarchical tree-structure.
+
+<mmm-embed path="tree_mainstream">schematic view of an example tree in a mainstream filesystem</mmm-embed>
+
+In common filesystems, as pictured, data can be organized hierarchically into *folders* (or *directories*),
+which serve only as containers of *files*, in which data is actually stored. While *directories* are fully transparent
+to both system and user (they can be created, browsed, listed and viewed by both), *files* are, from the system
+perspective, mostly opaque and inert blocks of data.
+
+Some metadata, such as file size and access permissions, is associated with each file,
+but notably, the type of data is generally not actually stored in the filesystem,
+but determined loosely based on multiple heuristics depending on the system and context.
+Some notable mechanisms are:
+
+- Suffixes at the end of the filename are often used to indicate which kind of data a file contains. However there is no
+ centralized standardization of suffixes, and often one suffix is used for multiple incompatible versions of a
+ file-formats, or multiple suffixes are used interchangeably for one format.
+- Many file-formats specify a specific data-pattern either at the very beginning or very end of a given file.
+ On UNIX systems the `libmagic` database and library of these so-called *magic constants* is commonly used to guess
+ the file-type based on these fragments of data.
+- on UNIX systems, files to be executed are checked by a variety of methods<mmm-embed path="../references/linux-exec"
+ wrap="sidenote"></mmm-embed> in order to determine which format would fit. For example, script files, the "shebang"
+ symbol, `#!`, can be used to specify the program that should parse this file in the first line of the file.
+
+It should be clear already from this short list that to mainstream operating systems, as well as the applications
+running on them, the format of a file is almost completely unknown and, at best, educated guesses can be made.
+
+Because these various mechanisms are applied at different times by the operating system and applications, it is possible
+for files to be labeled or considered as being in different formats at the same time by different components of the
+system.
+
+This leads to confusion about the factual format of data among users<mmm-embed path="../references/renaming"
+wrap="sidenote" style="margin-top: -3rem;">For example, the difference between changing a file extension and converting
+a file between two formats is often unclear to users, as evident from questions like this: </mmm-embed>, but can
+also pose a serious security risk:
+Under some circumstances, it is possible that a file contains maliciously-crafted code and is treated as an executable
+by one software component, while a security mechanism meant to detect such code determines the same file to be a
+legitimate image<mmm-embed path="../references/poc-or-gtfo" wrap="sidenote" style="margin-top: 2rem"></mmm-embed>
+(the file may in fact be valid in both formats).
+
+In mmmfs, the example above might look like this instead:
+<mmm-embed path="tree_mmmfs">schematic view of an example mmmfs tree</mmm-embed>
+
+Superficially, this may look quite similar: there are still only two types of nodes (referred to as *fileders* and
+*facets*), and again one of them, the *fileders* are used only to hierarchically organize *facets*. Unlike *files*,
+*facets* don't only store a freeform *name*, there is also a dedicated *type* field associated with every *facet*, that
+is explicitly designed to be understood and used by the system.
+
+Despite the similarities, the semantics of this system are very different: In mainstream filesystems, each *file* stands
+for itself only; i.e. in a *directory*, no relationship between *files* is assumed by default, and files are most of the
+time read or used outside of the context they exist in in the filesystem.
+
+In mmmfs, a *facet* should only ever be considered an aspect of its *fileder*, and never as separate from it.
+A *fileder* can contain multiple *facets*, but they are meant to be alternate or equivalent representations of the
+*fileder* itself. Though for some uses it is required, software generally does not have to be directly aware of the
+*facets* existing within a *fileder*, rather it assumes the presence of content in the representation that it requires,
+and simple requests it. The *Type Coercion Engine* (see below) will then attempt to satisfy this request based on the
+*facets* that are in fact present.
+
+Semantically a *fileder*, like a *directory*, also encompasses all the other *fileders* nested within itself
+(recursively). Since *fileders* are the primary unit of data to be operated upon, *fileder* nesting emerges as a natural
+way of structuring complex data, both for access by the system and its components, as well as the user themself.
+
+<div style="break-after: page;"></div>
+
+## 5.2&emsp;type system and coercion engine
+As mentioned above, *facets* store data alongside its *type*, and when a component of the system requires data from a
+*fileder*, it has to specify the *expected type* (or a list of these) that it requires the data to be in. The system
+then attempts to coerce one of the existing facets into the *expected type*, if possible. This process can involve many
+steps such as converting between similar file formats, running executable code stored in a facet, or fetching remote
+content. The component that requested the data is isolated from this process and does not have to deal with any of the
+details.
+
+In the current iteration of the type system, types are simple strings of text and loosely based on MIME-types<mmm-embed
+path="../references/mime-types" wrap="sidenote"></mmm-embed>.
+MIME types consist of a major- and minor category, and optionally a 'suffix'.
+Here are some common MIME-types that are also used in mmmfs:
+
+- `text/html` and `text/html+frag` (mmmfs only)
+- `text/javascript`
+- `image/png`
+- `image/jpeg`
+
+While these types allow some amount of specificity, they fall short of describing their content especially in cases
+where formats overlap: Source code, for example, is often distributed in `.tar.gz` archive files (directory-trees that
+are first bundled into an `application/x-tar` archive, and then compressed into an `application/gzip` archive). Using
+either of these two types is respectively incorrect or insufficient information to properly treat and extract the
+contained data.
+
+To mitigate this problem, mmmfs *types* can be nested. This is denoted in mmmfs *type* strings using the `->` symbol,
+e.g. the mmmfs *types* `application/gzip -> application/tar -> dirtree` and `URL -> image/jpeg` describe a
+tar-gz-compressed directory tree and the URL linking to a JPEG-encoded picture respectively.
+
+Depending on the outer type this nesting can mean different things:
+for URLs, the nested type is expected to be found after fetching the URL with HTTP,
+compression formats are expected to contain contents of the nested types,
+and executable formats are expected to output data of the nested type.
+
+It is a lot more important to be able to accurately describe the type of a *facet* in mmmfs than in mainstream operating
+systems because while in the latter types are mostly used only associate an application that will then prompt the user
+for further steps if necessary, mmmfs uses the *type* to automatically find one or more programs to execute, in order to
+convert or transform the data stored in a *facet* into the *type* required in the context where it was requested.
+
+This process of *type coercion* uses a database of known *converts* that can be applied to data. Every *convert*
+consists of a description of the input *types* that it can accept, the output *type* it would produce for a given input
+type, as well as the code for actually converting a given piece of data. Simple *converts* may simply consist of a fixed
+in and output type, such as this *convert* for rendering Markdown-encoded text to an HTML hypertext fragment:
+
+ {
+ inp: 'text/markdown'
+ out: 'text/html+frag'
+ transform: (value, ...) ->
+ -- implementation stripped for brevity
+ }
+
+Other *converts*, on the other hand, may accept a wide range of input types:
+
+ {
+ inp: 'URL -> image/.*'
+ out: 'text/html+frag'
+ transform: (url) -> img src: url
+ }
+
+This convert uses a Lua Pattern to specify that it can accept an URL to any type of image,
+and convert it to an HTML fragment.
+
+By using the pattern substitution syntax provided by the Lua `string.gsub` function, converts can also make the type
+they return depend on the input type, as is required often when nested types are unpacked:
+
+ {
+ inp: 'application/gzip -> (.*)'
+ out: '%1'
+ transform: (data) ->
+ -- implementation stripped for brevity
+ }
+
+This *convert* accepts an `application/gzip` *type* wrapping any other *type*, and captures that nested type in a
+pattern group. It then uses the substitution syntax to specify that nested type as the output of the conversion.
+For an input *type* of `application/gzip -> image/png` this *convert* would therefore generate the type `image/png`.
+
+This last example further demonstrates the flexibility of this approach:
+
+ {
+ inp: 'text/moonscript -> (.*)'
+ out: 'text/lua -> %1'
+ transform: (code) -> moonscript.to_lua code
+ }
+
+This *convert* transpiles MoonScript source-code into Lua source-code, while keeping the nested type
+(in this case the result expected when executing either script) the same.
+
+In addition to the attributes shown above, every *convert* is also rated with a *cost* value. The cost value is meant to
+roughly estimate both the cost (in terms of computing power) of the conversion, as well as the accuracy or immediacy of
+the conversion. For example, resizing an image to a lower size should have a high cost, because the process is
+computationally expensive, but also because a smaller image represents the original image to a lesser degree.
+Similarly, a URL to a piece of content is a less immediate representation than the content itself, so the cost of a
+*convert* that simply generates the URL to a piece of data should be high even if the process is very cheap to compute.
+
+Cost is defined in this way to make sure that the result of a type-coercion operation reflects the content that was
+present as accurately as possible. It is also important to prevent some nonsensical results from occurring, such as
+displaying a link to content instead of the content itself because the link is cheaper to create than completely
+converting the content does.
+
+Type coercion is implemented using a general pathfinding algorithm, based on *Dijkstra's Algorithm*<mmm-embed
+path="../references/dijkstra" wrap="sidenote"></mmm-embed>. First, the set of given *types* is found by selecting all
+*facets* of the *fileder* that match the *name* given in the query. The set of given *types* is marked in green in the
+following example graph.
+From there the algorithm recursively checks whether it can reach other *types* by applying all matching *converts* to
+the *type* that is the cheapest to reach currently, excluding any *types* that have already been exhaustively-searched
+in this way. All *types* found that have not yet been inserted into the set of given *types* are then added to the
+set, so that they may be searched as well.
+
+The algorithm doesn't stop immediately after reaching a *type* from the result set, it continues to search until it
+either completely exhausts the result-space, or until all non-exhaustively searched paths already have costs higher than
+the allowed maximum. This ensures that the optimal path is found, even if a more expensive path is found more quickly
+initially.
+
+<mmm-embed path="type_coercion_graph">excerpt of the graph of conversion paths from two starting facets to mmm/dom
+</mmm-embed>
diff --git a/root/articles/mmmfs/mmmfs/tree_mainstream/text$mermaid-graph b/root/articles/mmmfs/mmmfs/tree_mainstream/text$mermaid-graph
new file mode 100644
index 0000000..3227e47
--- /dev/null
+++ b/root/articles/mmmfs/mmmfs/tree_mainstream/text$mermaid-graph
@@ -0,0 +1,11 @@
+graph TD
+ Documents --> Movies --> m1{{A Movie.mp4}}
+ Documents --> Pictures --> vacation[Summer Vacation]
+ vacation --> v1{{1.jpg}}
+ vacation --> v2{{2.jpg}}
+ Pictures --> Projects
+ Projects --> p1{{1.jpg}}
+ Projects --> p2{{2.jpg}}
+
+ classDef file fill:#f9f;
+ class m1,v1,v2,p1,p2 file;
diff --git a/root/articles/mmmfs/mmmfs/tree_mmmfs/text$mermaid-graph b/root/articles/mmmfs/mmmfs/tree_mmmfs/text$mermaid-graph
new file mode 100644
index 0000000..7b4f6f4
--- /dev/null
+++ b/root/articles/mmmfs/mmmfs/tree_mmmfs/text$mermaid-graph
@@ -0,0 +1,21 @@
+graph TD
+ Documents --> Movies --> m1[A Movie.mp4]
+ m1 --> m1.f{{video/mp4}}
+
+ Documents --> Pictures --> vacation[Summer Vacation]
+ vacation --> slideshow{{slideshow: script -> UI}}
+ vacation --> gallery{{gallery: script -> UI}}
+ vacation --> v1[1.jpg]
+ vacation --> v2[2.jpg]
+ v1 --> v1.f{{image/jpeg}}
+ v2 --> v2.f{{image/jpeg}}
+
+ Pictures --> Projects
+ Projects --> p1[1.jpg]
+ Projects --> p2[2.jpg]
+ p1 --> p1.f{{image/jpeg}}
+ p2 --> p2.f{{image/jpeg}}
+
+ classDef default fill:#f00,stroke:#333,stroke-width:4px;
+ classDef file fill:#f9f;
+ class slideshow,gallery,m1.f,v1.f,v2.f,p1.f,p2.f file;
diff --git a/root/articles/mmmfs/mmmfs/type_coercion_graph/text$mermaid-graph b/root/articles/mmmfs/mmmfs/type_coercion_graph/text$mermaid-graph
new file mode 100644
index 0000000..cf2cf1e
--- /dev/null
+++ b/root/articles/mmmfs/mmmfs/type_coercion_graph/text$mermaid-graph
@@ -0,0 +1,22 @@
+graph LR
+ md_lua[text/lua -> text/markdown]
+ md[text/markdown]
+ moon[text/moonscript -> fn -> mmm/dom]
+ lua[text/lua -> fn -> mmm/dom]
+ fn[fn -> mmm/dom]
+ dom[mmm/dom]
+ moon_url[URL -> text/moonscript -> fn -> mmm/dom]
+ lua_url[URL -> text/lua -> fn -> mmm/dom]
+
+ md_lua -- cost: 1 --> md -- cost: 2 --> dom
+ moon -- cost: 5 --> moon_url
+ moon -- cost: 1 --> fn -- cost: 2 --> dom
+ moon -- cost: 2 --> lua -- cost: 5 --> lua_url
+ lua -- cost: 1 --> fn
+ moon_url -- cost: 10 --> dom
+ lua_url -- cost: 10 -->dom
+
+ classDef given fill:#ada;
+ classDef path stroke:#ada;
+ linkStyle 3,1,0,4 stroke:#8d8,stroke-width:2px
+ class md_lua,moon given
diff --git a/root/articles/mmmfs/motivation/$order b/root/articles/mmmfs/motivation/$order
new file mode 100644
index 0000000..accfc0b
--- /dev/null
+++ b/root/articles/mmmfs/motivation/$order
@@ -0,0 +1,2 @@
+app-types
+creative
diff --git a/root/articles/mmmfs/motivation/app-types/text$markdown.md b/root/articles/mmmfs/motivation/app-types/text$markdown.md
new file mode 100644
index 0000000..aedef1c
--- /dev/null
+++ b/root/articles/mmmfs/motivation/app-types/text$markdown.md
@@ -0,0 +1,3 @@
+While there can be a distinction between *Native Applications* and *Web Applications* or *Cloud Services*, the following
+arguments apply to all different technical implementations of this same concept. The problems associated specifically
+with Web- and Cloud-based application models will be discussed separately below.
diff --git a/root/articles/mmmfs/motivation/creative/text$markdown.md b/root/articles/mmmfs/motivation/creative/text$markdown.md
new file mode 100644
index 0000000..9dd6162
--- /dev/null
+++ b/root/articles/mmmfs/motivation/creative/text$markdown.md
@@ -0,0 +1,2 @@
+Note that 'creative' here does not only mean 'artistic': this applies to any field, and limits the ability of domain
+experts to push the boundaries of practice by using technology in innovative ways.
diff --git a/root/articles/mmmfs/motivation/text$markdown+sidenotes.md b/root/articles/mmmfs/motivation/text$markdown+sidenotes.md
new file mode 100644
index 0000000..64a3459
--- /dev/null
+++ b/root/articles/mmmfs/motivation/text$markdown+sidenotes.md
@@ -0,0 +1,138 @@
+# 2&emsp;drawbacks of current systems
+
+The project that this thesis accompanies was created out of frustration with the computing systems that are currently
+popular and widely available to end-users. The following sections document and exemplify the perceived shortcomings that
+these systems exhibit, as attributed to specific concepts or paradigms that the systems seem to be designed around.
+
+2.1&emsp;application-centric design
+-----------------------------------
+
+The majority of users interact with modern computing systems in the form of smartphones, laptops or desktop PCs,
+using the mainstream operating systems Apple iOS and Mac&nbsp;OS&nbsp;X, Microsoft&nbsp;Windows or Android.
+
+<mmm-embed path="app-types" wrap="marginnote"></mmm-embed>
+All of these operating systems share the concept of *Applications* (or *Apps*) as one of the core pieces of their
+interaction model. The functionality and capabilities of digital devices are bundled, marketed, sold and distributed
+as applications. This focus on applications as the primary unit of systems can be seen as the root cause of multiple
+problems.
+
+For one, since applications are produced by private companies on the software market,
+developers compete on features integrated into their applications. To stay relevant, monolithic software or software
+suites tend to accrete features rather then modularize and delegate to other software<mmm-embed wrap="sidenote"
+path="../references/appliances"></mmm-embed>. This makes many software packages more complex and unintuitive than
+they need to be, and also cripples interoperability between applications and data formats.
+
+Because (private) software developers are incentivized to keep customers, they make use of network effects to keep
+customers locked-in. This often means re-implementing services and functionality that is already available to users,
+and integrating it directly in other applications or as a new product by the same organization.
+While this strategy helps big software companies retain customers, it harms users, who have to navigate a complex
+landscape of multiple incompatible, overlapping, and competing software ecosystems.
+Data of the same kind, a rich-text document, for example, can be shared easily within the software systems of a certain
+manufacturer and with other users of the same, but sharing with users of a competing system, even if it has almost the
+same capabilities, can often be problematic<mmm-embed path="../references/lock-in" wrap="sidenote"></mmm-embed>.
+
+Another issue is that due to the technical challenges of development in this paradigm, applications are designed and
+developed by experts in application development, rather than experts in the domain of the tool. While developers may
+solicit feedback, advice, and ideas from domain experts, communication is a barrier. Additionally, domain experts are
+generally unfamiliar with the technical possibilities, and may therefore not be able to express feedback that would lead
+to more significant advances.
+<mmm-embed path="creative" wrap="marginnote"></mmm-embed>
+As a result, creative use of computer technology is limited to programmers, since applications constrain their users to
+the paths and abilities that the developers anticipated and deemed useful.
+
+The application-centric computing metaphor treats applications as black boxes and provides no means to understand,
+customize or modify the behavior of apps, intentionally obscuring the inner-workings of applications and
+completely cutting users off from this type of ownership over their technology. While the trend seems to be to further
+hide the way desktop operating systems work<mmm-embed path="../references/osx-files" wrap="sidenote"></mmm-embed>,
+mobile systems like Apple's *iOS* were designed as such *walled gardens* from the start.
+
+2.2&emsp;cloud computing
+------------------------
+
+*Web Apps* often offer similar functionality to other applications but are subject to additional limitations:
+In most cases, they are only accessible or functional in the presence of a stable internet connection,
+and they have very limited access to the resources of the physical computer they are running on.
+For example, they usually cannot interact directly with the file system, hardware peripherals or other applications,
+other than through a standardized set of interactions (e.g. selecting a file via a visual menu, capturing audio and
+video from a webcam, opening another website).
+
+Cloud software, as well as subscription-model software with online-verification mechanisms, are additionally subject
+to license changes, updates modifying, restricting or simply removing past functionality, etc. Additionally, many cloud
+software solutions and ecosystems store the users' data in the cloud, often across national borders, where legal and
+privacy concerns are intransparently handled by the companies. If a company, for any reason, is unable or unwilling to
+continue servicing a customer, the user's data may be irrecoverably lost (or access prevented). This can have serious
+consequences<mmm-embed path="../references/adobe" wrap="sidenote"></mmm-embed>, especially for professional users, for
+whom an inability to access their tools or their cloud-stored data can pose an existential threat.
+
+2.3&emsp;inert data (and data formats)
+--------------------------------------
+
+Cragg coins the term "inert data"<mmm-embed path="../references/super-powers" wrap="sidenote"></mmm-embed> for the data
+created and left behind by apps and applications in the computing model that is currently prevalent: Most data today
+is either intrinsically linked to one specific application, that controls and limits access to the actual information,
+or, even worse, stored in the cloud where users have no direct access at all. In the latter case, users depend solely on
+online tools that require a stable network connection and a modern browser and could be modified, removed, or otherwise
+negatively impacted at any moment.
+
+Aside from being inaccessible to users, the resulting complex proprietary formats are also opaque and useless to other
+applications and the operating system, which often is a huge missed opportunity:
+The .docx format, for example, commonly used for storing mostly textual data enriched with images and on occasion videos,
+is in fact a type of archive that can contain many virtual files internally, such as the various media files contained
+within. However this is completely unknown to the user and operating system, and so users are unable to access the
+contents in this way. As a result, editing an image contained in a word document is far from a trivial task: first the
+document has to be opened in a word processing application, then the image has to be exported from it and saved in its
+own, temporary file. This file can then be edited and saved back to disk. Once updated, the image may be reimported
+into the .docx document. If the word-processing application supports this, the old image may be replaced directly,
+otherwise, the user may have to remove the old image, insert the new one, and carefully ensure that the positioning in
+the document remains intact.
+
+2.4&emsp;disjointed filesystems
+-------------------------------
+
+The filesystems and file models used on modern computing devices generally operate on the assumption that every
+individual file stands for itself. Grouping of files in folders is allowed as a convenience for users, but most
+applications only ever concern themselves with a single file at a time, independent of the context the file is stored
+in.
+
+Data rarely really fits this concept of individual files very well, and even when it does, it is rarely exposed to
+the user that way: The 'Contacts' app on a mobile phone, for example, does not store each contact's information in a
+separate 'file' (as the word may suggest initially), but rather keeps all information in a single database file,
+which is hidden away from the user. Consequently, access to the information contained in the database is only enabled
+through the contacts application's graphical interface, and not through other applications that generically operate on
+files.
+
+Another example illustrates how a more powerful file (organization) system could render such formats and applications
+obsolete: Given the simple task of collecting and arranging a mixed collection of images, videos, and texts to
+brainstorm, many might be tempted to open an application like *Microsoft Word* or *Adobe Photoshop* and create a new
+document there. Both *Photoshop* files and *Word* documents are capable of containing texts and images, but when such
+content is copied into them from external sources, such as other files on the same computer, or quotes and links from
+the internet, these relationships are irrevocably lost. As illustrated above, additionally, it becomes a lot harder to
+edit the content once it is aggregated. To choose an application for this task is a hard trade-off to make, because in
+applications primarily designed for word processing, arranging content visually is hard to do, and image editing and
+video embedding options are limited, while tools better suited to these tasks lack nuance when working with text.
+
+To avoid facing this dilemma, a more sensible system could leave the task of positioning and aggregating content of
+different types to one software component, while multiple different software components could be responsible for editing
+the individual pieces of content so that the most appropriate one can be chosen for each element. While creating the
+technological interface between these components is certainly a challenge, the resulting system would greatly benefit
+from the exponentially-growing capabilities resulting from the modular reuse of components across many contexts: A rich
+text editor component could be used for example not just in a mixed media collection as proposed above, but also for
+an email editor or the input fields in a browser.
+
+<div style="height: 2rem;"></div>
+
+To summarize, for various reasons, the metaphors and driving concepts of computing interfaces today prevent users from
+deeply understanding the software they use and the data they own, from customizing and improving their experience and
+interactions, and from properly owning, contextualizing and connecting their data.
+
+Interestingly, these deficits do not appear throughout the history of today's computing systems but are based in rather
+recent developments in the field. In fact, the most influential systems in the past aspired to the polar opposites, as I
+will show in the next section.
+
+<!--
+Chiusano blames these issues on the metaphor of the *machine*, and likens apps and applications to appliances.
+According to him, what should really be provided are *tools*:
+composable pieces of software that naturally lend themselves to, or outrightly call for,
+integration into the users' other systems and customization,
+rather than lure into the walled-gardens of corporate ecosystems using network-effects.
+-->
diff --git a/root/articles/mmmfs/print: text$moonscript -> fn -> mmm$dom.moon b/root/articles/mmmfs/print: text$moonscript -> fn -> mmm$dom.moon
new file mode 100644
index 0000000..615075a
--- /dev/null
+++ b/root/articles/mmmfs/print: text$moonscript -> fn -> mmm$dom.moon
@@ -0,0 +1,26 @@
+-- main content
+-- doesn't have a name prefix (e.g. preview: fn -> mmm/dom)
+-- uses the 'fn ->' conversion to execute the lua function on @get
+-- resolves to a value of type mmm/dom
+=>
+ html = require 'mmm.dom'
+ import article, h1, p, div from html
+ import moon from (require 'mmm.highlighting').languages
+
+ article with _this = class: 'sidenote-container spacious', style: { 'max-width': '640px', 'line-height': '1.5' }
+ append = (a) -> table.insert _this, a
+
+ append div {
+ h1 'Empowered End-User Computing', style: { 'margin-bottom': 0 }
+ p {
+ style:
+ 'margin-top': 0
+ 'padding-bottom': '0.2em'
+ 'border-bottom': '1px solid black'
+
+ "A Historical Investigation and Development of a File-System-Based Environment"
+ }
+ }
+
+ for child in *@children
+ append (child\get 'print: mmm/dom') or (child\gett 'mmm/dom')
diff --git a/root/articles/mmmfs/references/$order b/root/articles/mmmfs/references/$order
new file mode 100644
index 0000000..d2a668b
--- /dev/null
+++ b/root/articles/mmmfs/references/$order
@@ -0,0 +1,22 @@
+poc-or-gtfo
+aspect-ratios
+memex
+appliances
+super-powers
+dijkstra
+subtext
+mime-types
+alternatives-to-trees
+xerox-star
+unix
+transclusion
+adobe
+acm-dl
+hypercard
+inkandswitch
+linux-exec
+wikipedia
+market-share
+osx-files
+renaming
+lock-in
diff --git a/root/articles/mmmfs/references/acm-dl/text$bibtex b/root/articles/mmmfs/references/acm-dl/text$bibtex
new file mode 100644
index 0000000..8fb36a2
--- /dev/null
+++ b/root/articles/mmmfs/references/acm-dl/text$bibtex
@@ -0,0 +1,5 @@
+@online{acm-dl,
+ title = {ACM Digital Library},
+ url = {https://dl.acm.org},
+ year = {n. d.},
+}
diff --git a/root/articles/mmmfs/references/adobe/text$bibtex b/root/articles/mmmfs/references/adobe/text$bibtex
new file mode 100644
index 0000000..55904aa
--- /dev/null
+++ b/root/articles/mmmfs/references/adobe/text$bibtex
@@ -0,0 +1,8 @@
+@online{adobe,
+ title = {Adobe is cutting off users in Venezuela due to US sanctions},
+ url = {https://www.theverge.com/2019/10/7/20904030/adobe-venezuela-photoshop-behance-us-sanctions},
+ publisher = {The Verge},
+ author = {Lee, Dami},
+ year = {2019, October 7},
+ visited = {2019-12-18},
+}
diff --git a/root/articles/mmmfs/references/alternatives-to-trees/text$bibtex b/root/articles/mmmfs/references/alternatives-to-trees/text$bibtex
new file mode 100644
index 0000000..19c134e
--- /dev/null
+++ b/root/articles/mmmfs/references/alternatives-to-trees/text$bibtex
@@ -0,0 +1,7 @@
+@web{alternatives:to:trees,
+ title = {Alternatives to Trees},
+ url = {https://www.oocities.org/tablizer/sets1.htm},
+ author = {Jacobs, B.}
+ year = {2004},
+ visited = {2019-12-18},
+}
diff --git a/root/articles/mmmfs/references/appliances/text$bibtex b/root/articles/mmmfs/references/appliances/text$bibtex
new file mode 100644
index 0000000..56fa8c8
--- /dev/null
+++ b/root/articles/mmmfs/references/appliances/text$bibtex
@@ -0,0 +1,7 @@
+@online{appliances,
+ title = {The future of software, the end of apps, and why UX designers should care about type theory},
+ url = {http://pchiusano.github.io/2013-05-22/future-of-software.html},
+ author = {Chiusano, Paul},
+ year = {2013},
+ visited = {2019-12-18},
+}
diff --git a/root/articles/mmmfs/references/aspect-ratios/text$bibtex b/root/articles/mmmfs/references/aspect-ratios/text$bibtex
new file mode 100644
index 0000000..37cea92
--- /dev/null
+++ b/root/articles/mmmfs/references/aspect-ratios/text$bibtex
@@ -0,0 +1,7 @@
+@web{aspect:ratios,
+ title = {Aspect-ratio independent UIs},
+ url = {https://s-ol.nu/aspect-ratios},
+ author = {Bekic, Sol}
+ year = {2019},
+ visited = {2019-12-18},
+}
diff --git a/root/articles/mmmfs/references/dijkstra/text$bibtex b/root/articles/mmmfs/references/dijkstra/text$bibtex
new file mode 100644
index 0000000..c38a470
--- /dev/null
+++ b/root/articles/mmmfs/references/dijkstra/text$bibtex
@@ -0,0 +1,17 @@
+@article{10.1007/BF01386390,
+ author = {Dijkstra, Edsger W.},
+ title = {A Note on Two Problems in Connexion with Graphs},
+ year = {1959},
+ issue_date = {December 1959},
+ publisher = {Springer-Verlag},
+ address = {Berlin, Heidelberg},
+ volume = {1},
+ number = {1},
+ issn = {0029-599X},
+ url = {https://doi.org/10.1007/BF01386390},
+ doi = {10.1007/BF01386390},
+ journal = {Numer. Math.},
+ month = dec,
+ pages = {269–271},
+ numpages = {3}
+}
diff --git a/root/articles/mmmfs/references/hypercard/text$bibtex b/root/articles/mmmfs/references/hypercard/text$bibtex
new file mode 100644
index 0000000..b23cfcb
--- /dev/null
+++ b/root/articles/mmmfs/references/hypercard/text$bibtex
@@ -0,0 +1,6 @@
+@online{hypercard,
+ title = {Computer Chronicles, Episode 501},
+ url = {https://archive.org/details/CC501_hypercard},
+ visited = {2019-12-18},
+ year = {1987},
+}
diff --git a/root/articles/mmmfs/references/inkandswitch/markdown: text$moonscript -> fn -> text$markdown.md b/root/articles/mmmfs/references/inkandswitch/markdown: text$moonscript -> fn -> text$markdown.md
new file mode 100644
index 0000000..9439841
--- /dev/null
+++ b/root/articles/mmmfs/references/inkandswitch/markdown: text$moonscript -> fn -> text$markdown.md
@@ -0,0 +1 @@
+=> "```\n" .. (@gett 'text/bibtex') .. "\n```"
diff --git a/root/articles/mmmfs/references/inkandswitch/text$bibtex b/root/articles/mmmfs/references/inkandswitch/text$bibtex
new file mode 100644
index 0000000..8b5f298
--- /dev/null
+++ b/root/articles/mmmfs/references/inkandswitch/text$bibtex
@@ -0,0 +1,7 @@
+@online{inkandswitch,
+ title = {End-user Programming},
+ url = {https://inkandswitch.com/end-user-programming.html},
+ publisher = {Ink & Switch},
+ year = {2019},
+ visited = {2019-12-18},
+}
diff --git a/root/articles/mmmfs/references/linux-exec/text$bibtex b/root/articles/mmmfs/references/linux-exec/text$bibtex
new file mode 100644
index 0000000..e0e415f
--- /dev/null
+++ b/root/articles/mmmfs/references/linux-exec/text$bibtex
@@ -0,0 +1,8 @@
+@online{linux:exec,
+ title = {How does Linux execute a file?},
+ url = {https://stackoverflow.com/a/23295724/1598293},
+ publisher = {stackoverflow.com},
+ note = {answered by osgx},
+ visited = {2019-12-18},
+ year = 2014,
+}
diff --git a/root/articles/mmmfs/references/lock-in/text$bibtex b/root/articles/mmmfs/references/lock-in/text$bibtex
new file mode 100644
index 0000000..28d780c
--- /dev/null
+++ b/root/articles/mmmfs/references/lock-in/text$bibtex
@@ -0,0 +1,7 @@
+@online{lock:in,
+ title = {The Cloud is the Ultimate Vendor Lock-in},
+ url = {https://www.digital-manifesto.org/the-cloud-is-the-ultimate-vendor-lock-in/},
+ author = {Zielemans, François},
+ year = {2017},
+ visited = {2019-11-18},
+}
diff --git a/root/articles/mmmfs/references/market-share/text$bibtex b/root/articles/mmmfs/references/market-share/text$bibtex
new file mode 100644
index 0000000..430af2f
--- /dev/null
+++ b/root/articles/mmmfs/references/market-share/text$bibtex
@@ -0,0 +1,7 @@
+@online{market:share,
+ title = {Operating System Market Share - Desktop and Mobile},
+ year = {2019},
+ url = {https://s-ol.nu/ba/ref/nms},
+ oldURL = {https://netmarketshare.com/operating-system-market-share.aspx?options=%7B%22filter%22%3A%7B%22%24and%22%3A%5B%7B%22deviceType%22%3A%7B%22%24in%22%3A%5B%22Desktop%2Flaptop%22%2C%22Mobile%22%5D%7D%7D%5D%7D%2C%22dateLabel%22%3A%22Trend%22%2C%22attributes%22%3A%22share%22%2C%22group%22%3A%22platform%22%2C%22sort%22%3A%7B%22share%22%3A-1%7D%2C%22id%22%3A%22platformsDesktop%22%2C%22dateInterval%22%3A%22Monthly%22%2C%22dateStart%22%3A%222018-12%22%2C%22dateEnd%22%3A%222019-11%22%2C%22hiddenSeries%22%3A%7B%7D%2C%22tableOrder%22%3A%5B%5B2%2C%22desc%22%5D%5D%2C%22segments%22%3A%22-1000%22%7D},
+ publisher = {NetMarketShare},
+}
diff --git a/root/articles/mmmfs/references/memex/text$bibtex b/root/articles/mmmfs/references/memex/text$bibtex
new file mode 100644
index 0000000..313eec7
--- /dev/null
+++ b/root/articles/mmmfs/references/memex/text$bibtex
@@ -0,0 +1,8 @@
+@online{memex,
+ author = {Bush, Vannevar},
+ title = {As we may think},
+ journal = {Atlantic Monthly},
+ year = {1945},
+ visited = {2019-12-18},
+ url = {https://www.theatlantic.com/magazine/archive/1945/07/as-we-may-think/303881/}
+}
diff --git a/root/articles/mmmfs/references/mime-types/text$bibtex b/root/articles/mmmfs/references/mime-types/text$bibtex
new file mode 100644
index 0000000..c49b553
--- /dev/null
+++ b/root/articles/mmmfs/references/mime-types/text$bibtex
@@ -0,0 +1,14 @@
+@article{rfc6838,
+ series = {Request for Comments},
+ number = 6838,
+ howpublished = {RFC 6838},
+ publisher = {Internet Engineering Task Force},
+ doi = {10.17487/RFC6838},
+ url = {https://tools.ietf.org/html/rfc6838},
+ author = {Freed, Ned and Klensin, John C. and Hansen, Tony},
+ title = {Media Type Specifications and Registration Procedures},
+ pagetotal = 32,
+ year = 2013,
+ month = jan,
+ abstract = {This document defines procedures for the specification and registration of media types for use in HTTP, MIME, and other Internet protocols. This memo documents an Internet Best Current Practice.},
+}
diff --git a/root/articles/mmmfs/references/osx-files/text$bibtex b/root/articles/mmmfs/references/osx-files/text$bibtex
new file mode 100644
index 0000000..7c70a87
--- /dev/null
+++ b/root/articles/mmmfs/references/osx-files/text$bibtex
@@ -0,0 +1,7 @@
+@online{osx:files,
+ title = {Where is "Show Package Contents"},
+ url = {https://discussions.apple.com/thread/6740790},
+ publisher = {Apple Communities},
+ visited = {2019-12-27},
+ year = 2014,
+}
diff --git a/root/articles/mmmfs/references/poc-or-gtfo/text$bibtex b/root/articles/mmmfs/references/poc-or-gtfo/text$bibtex
new file mode 100644
index 0000000..7cac092
--- /dev/null
+++ b/root/articles/mmmfs/references/poc-or-gtfo/text$bibtex
@@ -0,0 +1,8 @@
+@article{PoC:or:GTFO,
+ author = {Albertini, Ange},
+ title = {Abusing file formats; or, Corkami, the Novella},
+ year = {2015},
+ journal = {PoC||GTFO},
+ volume = {7},
+ pages = {18-41},
+}
diff --git a/root/articles/mmmfs/references/renaming/text$bibtex b/root/articles/mmmfs/references/renaming/text$bibtex
new file mode 100644
index 0000000..660bc2c
--- /dev/null
+++ b/root/articles/mmmfs/references/renaming/text$bibtex
@@ -0,0 +1,7 @@
+@online{renaming,
+ title = {Why is it possible to convert a file just by renaming it?},
+ url = {https://askubuntu.com/q/166602},
+ publisher = {askubuntu.com},
+ year = 2012,
+ visited = {2019-12-18},
+}
diff --git a/root/articles/mmmfs/references/subtext/cite$doi b/root/articles/mmmfs/references/subtext/cite$doi
new file mode 100644
index 0000000..2ac65b5
--- /dev/null
+++ b/root/articles/mmmfs/references/subtext/cite$doi
@@ -0,0 +1 @@
+10.1145/1103845.1094851
diff --git a/root/articles/mmmfs/references/subtext/text$bibtex b/root/articles/mmmfs/references/subtext/text$bibtex
new file mode 100644
index 0000000..7e9eb9d
--- /dev/null
+++ b/root/articles/mmmfs/references/subtext/text$bibtex
@@ -0,0 +1,18 @@
+@article{10.1145/1103845.1094851,
+ author = {Edwards, Jonathan},
+ title = {Subtext: Uncovering the Simplicity of Programming},
+ year = {2005},
+ issue_date = {October 2005},
+ publisher = {Association for Computing Machinery},
+ address = {New York, NY, USA},
+ volume = {40},
+ number = {10},
+ issn = {0362-1340},
+ url = {https://doi.org/10.1145/1103845.1094851},
+ doi = {10.1145/1103845.1094851},
+ journal = {SIGPLAN Not.},
+ month = oct,
+ pages = {505–518},
+ numpages = {14},
+ keywords = {copying, non-textual programming, prototypes, visual programming},
+}
diff --git a/root/articles/mmmfs/references/super-powers/text$bibtex b/root/articles/mmmfs/references/super-powers/text$bibtex
new file mode 100644
index 0000000..5eabda8
--- /dev/null
+++ b/root/articles/mmmfs/references/super-powers/text$bibtex
@@ -0,0 +1,7 @@
+@online{super:powers,
+ title = {Super-powers, but not yours},
+ url = {http://object.network/manifesto-negative.html},
+ author = {Cragg, Duncan},
+ year = {2016},
+ visited = {2019-12-18},
+}
diff --git a/root/articles/mmmfs/references/text$moonscript -> fn -> mmm$dom.moon b/root/articles/mmmfs/references/text$moonscript -> fn -> mmm$dom.moon
new file mode 100644
index 0000000..7b96c10
--- /dev/null
+++ b/root/articles/mmmfs/references/text$moonscript -> fn -> mmm$dom.moon
@@ -0,0 +1,13 @@
+=>
+ html = require 'mmm.dom'
+ import div, h1, ol, li from html
+
+ refs = for ref in *@children
+ li ref\gett 'mmm/dom'
+ div {
+ class: 'print-ownpage'
+
+ h1 "references", id: 'references'
+ ol with refs
+ refs.style = 'line-height': 'normal'
+ }
diff --git a/root/articles/mmmfs/references/transclusion/text$bibtex b/root/articles/mmmfs/references/transclusion/text$bibtex
new file mode 100644
index 0000000..e323662
--- /dev/null
+++ b/root/articles/mmmfs/references/transclusion/text$bibtex
@@ -0,0 +1,10 @@
+@article{article,
+ author = {Kolbitsch, Josef and Maurer, Hermann},
+ year = {2006},
+ month = {06},
+ pages = {161-173},
+ title = {Transclusions in an HTML-Based Environment},
+ volume = {14},
+ journal = {CIT},
+ doi = {10.2498/cit.2006.02.07},
+}
diff --git a/root/articles/mmmfs/references/unix/text$bibtex b/root/articles/mmmfs/references/unix/text$bibtex
new file mode 100644
index 0000000..70b139d
--- /dev/null
+++ b/root/articles/mmmfs/references/unix/text$bibtex
@@ -0,0 +1,7 @@
+@book{10.5555/577766,
+ author = {Kernighan, Brian W. and Pike, Rob},
+ title = {The UNIX Programming Environment},
+ year = {1983},
+ isbn = {0139376992},
+ publisher = {Prentice Hall Professional Technical Reference}
+}
diff --git a/root/articles/mmmfs/references/wikipedia/text$bibtex b/root/articles/mmmfs/references/wikipedia/text$bibtex
new file mode 100644
index 0000000..d88d58c
--- /dev/null
+++ b/root/articles/mmmfs/references/wikipedia/text$bibtex
@@ -0,0 +1,7 @@
+@online{wikipedia,
+ title = {Hyperlink - Wikis},
+ url = {https://en.wikipedia.org/wiki/Hyperlink#Wikis},
+ publisher = {wikipedia.org},
+ visited = {2019-12-18},
+ year = {n. d.},
+}
diff --git a/root/articles/mmmfs/references/xerox-star/cite$doi b/root/articles/mmmfs/references/xerox-star/cite$doi
new file mode 100644
index 0000000..b849172
--- /dev/null
+++ b/root/articles/mmmfs/references/xerox-star/cite$doi
@@ -0,0 +1 @@
+10.1109/2.35211
diff --git a/root/articles/mmmfs/references/xerox-star/text$bibtex b/root/articles/mmmfs/references/xerox-star/text$bibtex
new file mode 100644
index 0000000..870eed4
--- /dev/null
+++ b/root/articles/mmmfs/references/xerox-star/text$bibtex
@@ -0,0 +1,18 @@
+@article{10.1109/2.35211,
+ oldauthor = {Johnson, Jeff and Roberts, Teresa L. and Verplank, William and Smith, David C. and Irby, Charles H. and Beard, Marian and Mackey, Kevin},
+ author = {Johnson, Jeff et al.},
+ title = {The Xerox Star: A Retrospective},
+ year = {1989},
+ issue_date = {September 1989},
+ publisher = {IEEE Computer Society Press},
+ address = {Washington, DC, USA},
+ volume = {22},
+ number = {9},
+ issn = {0018-9162},
+ url = {https://doi.org/10.1109/2.35211},
+ doi = {10.1109/2.35211},
+ journal = {Computer},
+ month = sep,
+ pages = {11–26, 28–29},
+ numpages = {1},
+}
diff --git a/root/articles/mmmfs/statement-of-originality/text$html+frag.html b/root/articles/mmmfs/statement-of-originality/text$html+frag.html
new file mode 100644
index 0000000..d6dcbc0
--- /dev/null
+++ b/root/articles/mmmfs/statement-of-originality/text$html+frag.html
@@ -0,0 +1,13 @@
+<div class="print-only print-ownpage" style="margin: 4cm 0 0;">
+<h1 id="statement">statement of originality</h1>
+<p style="margin-top: 5cm">
+This is to certify that the content of this project, documentation and thesis is my own work. It
+has not been submitted for any other degree or other purposes. I certify that the intellectual
+content of my submission is the product of my own work and that all the assistance received in
+preparing it as well as all sources used have been properly acknowledged.
+</p>
+
+<div style="border-top: 1px solid #000; width: 7cm; margin-top: 3cm;">
+Sol Bekic
+</div>
+</div>
diff --git a/root/articles/mmmfs/table-of-contents/text$html+frag.html b/root/articles/mmmfs/table-of-contents/text$html+frag.html
new file mode 100644
index 0000000..2b94109
--- /dev/null
+++ b/root/articles/mmmfs/table-of-contents/text$html+frag.html
@@ -0,0 +1,91 @@
+<!--
+{
+ const fmt = x => `<a href="#${x.id}">${x.innerText}</a>`;
+
+ const parse = e => ({
+ num: +e.tagName.substr(1),
+ fmt: fmt(e),
+ });
+
+ const render = (list) => {
+ let str = '';
+ let num = 0;
+ for (e of list) {
+ while (e.num > num) {
+ str += '<ol style="list-style: none; padding-left: 2rem;">'
+ num += 1;
+ }
+
+ while (e.num < num) {
+ str += '</ol>';
+ num -= 1;
+ }
+
+ str += `<li>${e.fmt}</li>`;
+ }
+ return str;
+ };
+
+ render([...$0.querySelectorAll('h1, h2, h3, h4, h5').values()].map(parse));
+}
+-->
+<section class="print-ownpage">
+ <h1 id="table-of-contents">table of contents</h1>
+ <ol style="list-style: none;">
+ <li><a href="#abstract">abstract</a></li>
+ <li><a href="#table-of-contents">table of contents</a></li>
+ <li><a href="#1introduction">1&emsp;introduction</a></li>
+ <li><a href="#2drawbacks-of-current-systems">2&emsp;drawbacks of current systems</a></li>
+ <ol style="list-style: none; padding-left: 2rem;">
+ <li><a href="#21application-centric-design">2.1&emsp;application-centric design</a></li>
+ <li><a href="#22cloud-computing">2.2&emsp;cloud computing</a></li>
+ <li><a href="#23inert-data-and-data-formats">2.3&emsp;inert data (and data formats)</a></li>
+ <li><a href="#24disjointed-filesystems">2.4&emsp;disjointed filesystems</a></li>
+ </ol>
+ <li><a href="#3historical-approaches">3&emsp;historical approaches</a></li>
+ <li><a href="#4evaluation-framework">4&emsp;evaluation framework</a></li>
+ <ol style="list-style: none; padding-left: 2rem;">
+ <li><a href="#41qualities-of-successful-end-user-computing">4.1&emsp;qualities of successful end-user computing</a></li>
+ <li><a href="#42modularity">4.2&emsp;modularity</a></li>
+ <li><a href="#43content-transclusion">4.3&emsp;content transclusion</a></li>
+ <li><a href="#44end-user-programming">4.4&emsp;end-user programming</a></li>
+ </ol>
+ <li><a href="#5system-description">5&emsp;system description</a></li>
+ <ol style="list-style: none; padding-left: 2rem;">
+ <li><a href="#51data-storage-model">5.1&emsp;data storage model</a></li>
+ <li><a href="#52type-system-and-coercion-engine">5.2&emsp;type system and coercion engine</a></li>
+ </ol>
+ <li><a href="#6example-use-cases">6&emsp;example use-cases</a></li>
+ <ol style="list-style: none; padding-left: 2rem;">
+ <li><a href="#61publishing-and-blogging">6.1&emsp;publishing and blogging</a></li>
+ <ol style="list-style: none; padding-left: 2rem;">
+ <li><a href="#611blogging">6.1.1&emsp;blogging</a></li>
+ <li><a href="#612scientific-publishing">6.1.2&emsp;scientific publishing</a></li>
+ </ol>
+ <li><a href="#62pinwall">6.2&emsp;pinwall</a></li>
+ <li><a href="#63slideshow">6.3&emsp;slideshow</a></li>
+ </ol>
+ <li><a href="#7evaluation">7&emsp;evaluation</a></li>
+ <ol style="list-style: none; padding-left: 2rem;">
+ <li><a href="#71examples">7.1&emsp;examples</a></li>
+ <ol style="list-style: none; padding-left: 2rem;">
+ <li><a href="#711publishing-and-blogging">7.1.1&emsp;publishing and blogging</a></li>
+ <li><a href="#712pinwall">7.1.2&emsp;pinwall</a></li>
+ <li><a href="#713slideshow">7.1.3&emsp;slideshow</a></li>
+ </ol>
+ <li><a href="#72general-concerns">7.2&emsp;general concerns</a></li>
+ <ol style="list-style: none; padding-left: 2rem;">
+ <li><a href="#721global-set-of-converts">7.2.1&emsp;global set of converts</a></li>
+ <li><a href="#722code-outside-of-the-system">7.2.2&emsp;code outside of the system</a></li>
+ <li><a href="#723type-system">7.2.3&emsp;type system</a></li>
+ <li><a href="#724type-coercion">7.2.4&emsp;type-coercion</a></li>
+ <li><a href="#725in-system-editing">7.2.5&emsp;in-system editing</a></li>
+ <li><a href="#726end-user-adoption">7.2.6&emsp;end-user adoption</a></li>
+ </ol>
+ </ol>
+ <li><a href="#8conclusion">8&emsp;conclusion</a></li>
+ <li><a href="#references">references</a></li>
+ <li><a href="#ba-log">appendix: project log</a></li>
+ <li><a href="#statement">statement of originality</a></li>
+ </ol>
+</section>
diff --git a/root/articles/mmmfs/text$moonscript -> fn -> mmm$dom.moon b/root/articles/mmmfs/text$moonscript -> fn -> mmm$dom.moon
index 7bb192d..6c5b1d3 100644
--- a/root/articles/mmmfs/text$moonscript -> fn -> mmm$dom.moon
+++ b/root/articles/mmmfs/text$moonscript -> fn -> mmm$dom.moon
@@ -4,260 +4,23 @@
-- resolves to a value of type mmm/dom
=>
html = require 'mmm.dom'
- import article, h1, h2, h3, p, div, a, sup, ol, li, span, code, pre, br from html
+ import article, h1, p, div from html
import moon from (require 'mmm.highlighting').languages
- article with _this = {}
+ article with _this = class: 'sidenote-container spacious', style: { 'max-width': '640px', 'line-height': '1.5' }
append = (a) -> table.insert _this, a
- footnote, getnotes = do
- local *
- notes = {}
+ append div {
+ h1 'Empowered End-User Computing', style: { 'margin-bottom': 0 }
+ p {
+ style:
+ 'margin-top': 0
+ 'padding-bottom': '0.2em'
+ 'border-bottom': '1px solid black'
- id = (i) -> "footnote-#{i}"
-
- footnote = (stuff) ->
- i = #notes + 1
- notes[i] = stuff
- sup a "[#{i}]", style: { 'text-decoration': 'none' }, href: '#' .. id i
-
- footnote, ->
- args = for i, note in ipairs notes
- li (span (tostring i), id: id i), ': ', note
- notes = {}
- table.insert args, style: { 'list-style': 'none', 'font-size': '0.8em' }
- ol table.unpack args
-
- -- @TODO: s/filesystem/a way of organizing files/g
- append h1 'mmmfs', style: { 'margin-bottom': 0 }
- append p "a file and operating system to live in", style: { 'margin-top': 0, 'padding-bottom': '0.2em', 'border-bottom': '1px solid black' }
-
- append h2 "motivation"
- append p "Today, computer users are losing more and more control over their data. Between web and cloud
- applications holding customer data hostage for providing the services, unappealing and limited mobile file
- browsing experiences and the non-interoperable, proprietary file formats holding on to their own data has
- become infeasible for many users. mmmfs is an attempt at rethinking file-systems and the computer user
- experience to give control back to and empower users."
-
- append p "mmmfs tries to provide a filesystem that is powerful enough to let you use it as your canvas for thinking,
- and working at the computer. mmmfs is made for more than just storing information. Files in mmmfs can interact
- and morph to create complex behaviours."
-
- append p "Let us take as an example the simple task of collecting and arranging a mixed collection of images, videos
- and texts in order to brainstorm. To create an assemblage of pictures and text, many might be tempted to open an
- Application like Microsoft Word or Adobe Photoshop and create a new document there. Both photoshop files and
- word documents are capable of containing texts and images, but when the files are saved, direct access to the
- contained data is lost. It is for example a non-trivial and unenjoyable task to edit an image file contained
- in a word document in another application and have the changes apply to the document. In the same way,
- text contained in a photoshop document cannot be edited in a text editor of your choice."
-
- append p "mmmfs tries to change all this. In mmmfs, files can contain other files and so the collage document
- becomes a container for the collected images and texts just as a regular directory would. This way the individual
- files remain accessible and can be modified whenever necessary, while the collage document can be edited to
- change the order, sizes and spatial arrangement of it's content if this is wanted, for example."
-
- append p "The mmmfs file-type system also allows storing types of information that have become impractical to use
- with current filesystems simply because noone has cared to make suitable applications for them. It is not common
- practice, for example, to store direct links to online content on the disk for example. In mmmfs, a link to a
- picture can be stored wherever an actual picture is expected for example, the system will take care of retrieving
- the real picture as necessary."
-
- -- @TODO: motivation / outline problem + need
- -- * applications don't let users *do* things (http://pchiusano.github.io/2013-05-22/future-of-software.html)
- -- * applications are just (collections of) files - most users don't know this (anymore)
- -- * users should know their system and how to move around in it
- -- * filesystem trees are only *okay* for organizing information:
- -- - users sooner or later choose something smarter because:
- -- * filesystems work the same in every folder, even though the context can be very different
- -- * appliances put their complex, structured data into opaque blocks
- -- * the FS should be able to solve the structure issue
- -- * the benefit is interoperability: edit the image of your report
- -- * in image editor while the document editor automatically refreshes
- -- * file formats dont mean much to users, they are meant for applications - let applications take care of converting them
- -- * report.doc, report.pdf, report_orignal.pdf, report_old.doc, report2.doc....
-
- append p do
- fileder = footnote "fileder: file + folder. 'node', 'table' etc. are too general to be used all over."
-
- -- @TODO: mention:
- -- can store anything - text, an image, a link to a website or video,
- -- a program and anything else you can think of.
- "in mmmfs, directories, files and applications are all kind of the same thing, or something like that.
- Listen, I don't really know yet either. The idea is that there is only one type of 'thing' -
- a fileder", fileder, ". A fileder can store multiple variants and metadata of its content,
- such as a markdown text and a rendered HTML version of the same document.
- It could also store a script that transforms the markdown version into HTML and is executed on demand,
- automatically."
-
- append p "Fileders can also have other fileders as their children (just like directories do in a normal
- filesystem). You can make a fileder view query these children and display them however you want.
- A 'Pictures' fileder, for example, could contain a script within itself that renders all the picture files
- you put into it as little previews and lets you click on them to view the full image."
-
- append p "This means the 'Pictures' fileder can also have an alternate slideshow mode, with fullscreen view and
- everything (some of this is built, check out the gallery example below), or one that displays geotagged images
- on a world map, if you really want that. Maybe you could build a music folder that contains links to youtube
- videos, spotify tracks and just plain mp3 files, and the folder knows how to play them all.", br!, "
- In this way fileders fulfil the purpose of 'Applications' too."
-
- -- @TODO: BUT doesn't have to be only for one type of file:
- -- @TODO: rework
- -- making a multi-media collage representing your thoughts and mental organization of a topic
- append p "A fileder is also responsible for how it's children are sorted, filtered and interacted with.
- For example you should be able to create a fileder that is essentially a 'word document' equivalent: it can
- contain images, websites, links and of course text as children and let you reorder, layout and edit them
- whenever you open the fileder."
-
- append p "Sounds cool, no? Here's some examples of things a fileder can be or embed:"
-
- -- render a preview block
- preview = (child) ->
- -- get 'title' as 'text/plain' (error if no value or conversion possible)
- title = child\gett 'title', 'text/plain'
-
- -- get 'preview' as a DOM description (nil if no value or conversion possible)
- content = child\get 'preview', 'mmm/dom'
-
- div {
- h3 title, style: { margin: 0, cursor: 'pointer' }, onclick: -> BROWSER\navigate child.path
- content or span '(no renderable content)', style: { color: 'red' },
- style: {
- display: 'inline-block',
- width: '300px',
- height: '200px',
- padding: '4px',
- margin: '8px',
- border: '4px solid #eeeeee',
- overflow: 'hidden',
- },
+ "A Historical Investigation and Development of a File-System-Based Environment"
}
+ }
- append div for child in *@children
- preview child
-
- append h2 "details"
- -- @TODO s/parts: dimensions, aspects?
- -- @TODO: first mention both facets & children; then go into detail
- -- @TODO: main content
- append do
- name = html.i 'name'
- type = html.i 'type'
-
- p "Fileders are made up of two main parts. The first is the list of ", (html.i 'facets'), ",
- which are values identified by a ", name, " and ", type, ". These values are queried using strings like ",
- (code 'title: text/plain'), " or ", (code 'mmm/dom'), ", which describe both the ", name,
- " of a facet (", (moon '"title"'), " and ", (moon '""'), ", the unnamed/main facet) and the ", type,
- " of a facet. Facet types can be something resembling a MIME-type or a more complex structure
- (see ", (html.i "type chains"), " below). A fileder can have multiple facets of different types
- set that share a ", name, ". In this case the overlapping facets are considered equivalent and the one
- with the most appropriate ", type, " is selected, depending on the query.
- The unnamed facet is considered a fileder's 'main content', i.e. what you are interested in when viewing it."
-
- append p "The second part of a fileder is the list of it's children, which are fileders itself.
- The children are stored in an ordered list and currently identified by their ", (code 'name: alpha'),
- " facet for UI and navigation purposes only (not sure if this is a good idea tbh)."
-
- append do
- mmmdom = code ('mmm/dom'), footnote span (code 'mmm/dom'), " is a polymorphic content type;
- on the server it is just an HTML string (like ", (code 'text/html'), "),
- but on the client it is a JS DOM Element instance."
-
- p "What you are viewing right now is the main facet of the root fileder.
- The facet is queried as ", mmmdom, ", a website fragment (DOM node). This website fragment
- is then added to the page in the main content area, where you are most likely reading it right now."
-
- p "Anyway, this node is set up as a very generic sort of index thing and just lists its children-fileders'
- alongside this text part you are reading.", br!, "For each child it displays the ", (code 'title: text/plain'),
- " and shows the ", (code 'preview: mmm/dom'), " facet (if set)."
-
- append h3 "converts"
- append p "So far I have always listed facets as they are being queried, but a main feature of mmmfs is
- type conversion. This means that you generally ask for content in whichever format suits your application,
- and rely on the type resolution mechanism to make that happen."
-
- append pre moon [[
--- render a preview block
-preview = (title, content) -> div {
- h3 title, style: { ... },
- content or span '(no renderable content)', style: { ... },
- style: { ... }
-}
-
-append div for child in *@children
--- get 'title' as 'text/plain' (error if no value or conversion possible)
-title = child\gett 'title', 'text/plain'
-
--- get 'preview' as a DOM description (nil if no value or conversion possible)
-content = child\get 'preview', 'mmm/dom'
-
-preview title, content
- ]]
-
- append p "Here the code that renders these previews. You can see it ", (html.i "asks"), " for the
- facets ", (code 'title: text/plain'), ' and ', (code 'preview: mmm/dom'), "), but the values don't actually have to
- be ", (html.i "defined"), " as these types.
- For example, the markdown child below only provides ", (code 'preview'), " as ", (code 'text/markdown'), ":"
-
- append pre moon [[
-Fileder {
- 'title: text/plain': "I'm not even five lines of markdown but i render myself!",
- 'preview: text/markdown': "See I have like
-
- - a list of things
- - (two things)
-
- and some bold **text** and `code tags` with me.",
-}
- ]]
-
- append p "Then, globally, there are some conversion paths specified; such as one that maps from ",
- (code 'text/markdown'), " to ", (code 'mmm/dom'), ":"
-
- append pre moon [[
-{
- inp: 'text/markdown',
- out: 'mmm/dom',
- transform: (md) ->
- -- polymorphic client/serverside implementation here,
- -- uses lua-discount on the server, marked.js on the client
-}
- ]]
-
- append h3 "type chains"
- append p "In addition, a facet type can be encoded using multiple types in a ", (code 'type chain'), ".
- For example the root node you are viewing currently is actually defined as ", (code 'fn -> mmm/dom'), ",
- meaning it's value is a pre moon function returing a regular ", (code 'mmm/dom'), " value."
-
- append p "Both value chains and 'sideways' converts are resolved using the same mechanism,
- so this page is being rendered just using ", (moon "append root\\get 'mmm/dom'"), " as well.
- The convert that resolves the moon type is defined as follows:"
-
- append pre moon [[
-{
- inp: 'fn -> (.+)',
- out: '%1',
- transform: (val, fileder) -> val fileder
-}
- ]]
-
- append p "The example with the image is curious as well. In mmmfs, you might want to save a link to an image,
- without ever saving the actual image on your hard drive (or wherever the data may ever be stored - it is
- quite transient currently). The image Fileder below has it's main (unnamed) value tagged as ",
- (code 'URL -> image/png'), " - a png image, encoded as an URL. When accessed as ", (code 'image/png'), "
- the URL should be resolved, and the binary data provided in it's place (yeah right - I haven't build that yet)."
-
- append p "However, if a script is aware of URLs and knows a better way to handle them, then it can ask for and
- use the URL directly instead.
- This is what the image demo does in order to pass the URL to an ", (code 'img'), " tag's ", (code 'src'), " attribute:"
-
- append pre moon [[
-Fileder {
- 'title: text/plain': "Hey I'm like a link to picture or smth",
- 'URL -> image/png': 'https://picsum.photos/200?random',
- 'preview: fn -> mmm/dom': =>
- import img from require 'mmm.dom'
- img src: @gett 'URL -> image/png' -- look for main content with 'URL to png' type
-}
- ]]
-
- append getnotes!
+ for child in *@children
+ append child\gett 'mmm/dom'
diff --git a/root/articles/mmmfs/title/text$html+frag.html b/root/articles/mmmfs/title/text$html+frag.html
new file mode 100644
index 0000000..063b52a
--- /dev/null
+++ b/root/articles/mmmfs/title/text$html+frag.html
@@ -0,0 +1,21 @@
+<div class="print-only print-ownpage" style="font-size: 1.5rem; width: calc(100% + var(--sidenote-width))">
+ <div style="font-size: 2rem; margin-top: 4cm">
+ <h1>Empowered End-User Computing:</h1>
+ <span>A Historical Investigation and Development of a File-System-Based Environment</span>
+ </div>
+ <div style="width: 14cm; margin: 7cm auto 0">
+ <p>by</p>
+ <p>
+ Sol Bekic<br />
+ Student ID 11114279<br />
+ sol.bekic+ba@s-ol.nu
+ </p>
+ <p>
+ written in the Winter Term 2019/20<br />
+ for BA Digital Games<br />
+ at Cologne Game Lab / TH Köln
+ </p>
+ <p>supervised by Prof. Dr. Gundolf S. Freyermuth</p>
+ <p>submitted on 2020-01-07</p>
+ </div>
+</div>
diff --git a/root/articles/realities/text$moonscript -> mmm$dom.moon b/root/articles/realities/text$moonscript -> mmm$component.moon
index 7689dbb..a7dc365 100644
--- a/root/articles/realities/text$moonscript -> mmm$dom.moon
+++ b/root/articles/realities/text$moonscript -> mmm$component.moon
@@ -24,7 +24,7 @@ if MODE == 'SERVER'
render: =>
rplc = with div id: @id, :style
\append '(diagram goes here)'
- -- \append "<script type=\"application/lua\">
+ -- \append "<script type=\"text/lua\">
-- local rplc = js.global.document:getElementById('#{@id}');
-- local fn = #{compile @func}
-- diag = Diagram(fn)
diff --git a/root/articles/xy-workshop/$order b/root/articles/xy-workshop/$order
new file mode 100644
index 0000000..4600622
--- /dev/null
+++ b/root/articles/xy-workshop/$order
@@ -0,0 +1,10 @@
+01
+02
+03
+05
+04
+07
+01b
+06
+08
+01c
diff --git a/root/articles/xy-workshop/01/text$html+frag.html b/root/articles/xy-workshop/01/text$html+frag.html
new file mode 100644
index 0000000..2441f62
--- /dev/null
+++ b/root/articles/xy-workshop/01/text$html+frag.html
@@ -0,0 +1,7 @@
+<div style="margin-top: 4em">
+ <h2>Oscilloscope Music and Games with Pure Data</h2>
+ <br />
+ <br />
+ <br />
+ <p>sol bekic, 2019</p>
+</div>
diff --git a/root/articles/xy-workshop/01b/text$markdown.md b/root/articles/xy-workshop/01b/text$markdown.md
new file mode 100644
index 0000000..22c1454
--- /dev/null
+++ b/root/articles/xy-workshop/01b/text$markdown.md
@@ -0,0 +1,12 @@
+who am i?
+=========
+
+my name is sol,
+i like to program, build hardware and play with technology.
+
+- github: @s-ol
+- mastodon: @s-ol\@merveilles.town
+- twitter: @S0lll0s
+- links to all of those, email, and more info:
+ https://s-ol.nu
+
diff --git a/root/articles/xy-workshop/01c/$order b/root/articles/xy-workshop/01c/$order
new file mode 100644
index 0000000..2b68b52
--- /dev/null
+++ b/root/articles/xy-workshop/01c/$order
@@ -0,0 +1 @@
+video
diff --git a/root/articles/xy-workshop/01c/text$markdown.md b/root/articles/xy-workshop/01c/text$markdown.md
new file mode 100644
index 0000000..ba5718c
--- /dev/null
+++ b/root/articles/xy-workshop/01c/text$markdown.md
@@ -0,0 +1,5 @@
+what am i going to talk about?
+==============================
+Plonat Atek - E317 - B14 / Pavillon 6
+
+<iframe width="1220" height="630" frameborder="0" src="//www.youtube.com/embed/SIQAk9_nc-s"></iframe>
diff --git a/root/articles/xy-workshop/01c/video/URL -> youtube$video b/root/articles/xy-workshop/01c/video/URL -> youtube$video
new file mode 100644
index 0000000..bf07555
--- /dev/null
+++ b/root/articles/xy-workshop/01c/video/URL -> youtube$video
@@ -0,0 +1 @@
+https://www.youtube.com/watch?v=SIQAk9_nc-s
diff --git a/root/articles/xy-workshop/02/text$markdown.md b/root/articles/xy-workshop/02/text$markdown.md
new file mode 100644
index 0000000..3496b23
--- /dev/null
+++ b/root/articles/xy-workshop/02/text$markdown.md
@@ -0,0 +1,12 @@
+what am i going to talk about?
+==============================
+
+<br />
+
+- sound + scopes
+ - what is sound?
+ - what is an oscilloscope?
+- pd + the audiovisual
+ - osc~ + output~
+ - numbers boxes + sliders
+ - lissajous figures + sync
diff --git a/root/articles/xy-workshop/03/text$markdown.md b/root/articles/xy-workshop/03/text$markdown.md
new file mode 100644
index 0000000..c90491e
--- /dev/null
+++ b/root/articles/xy-workshop/03/text$markdown.md
@@ -0,0 +1,12 @@
+what is sound?
+==============
+<br />
+
+- *vibrations* in the air
+- movement of your ear drum
+- movement of a speaker membrane
+- numbers in a file on your computer
+
+what do they all have in common?
+- something is *changing over time*
+ - a wave!
diff --git a/root/articles/xy-workshop/04/text$markdown.md b/root/articles/xy-workshop/04/text$markdown.md
new file mode 100644
index 0000000..e07fbca
--- /dev/null
+++ b/root/articles/xy-workshop/04/text$markdown.md
@@ -0,0 +1,9 @@
+what is sound?
+==============
+
+waves are *something* changing over time:
+
+- in the air: pressure (in one spot)
+- ear drum and speakers: distance from normal position
+- audio cable: voltage over time
+- sound file: number over time
diff --git a/root/articles/xy-workshop/05/text$markdown.md b/root/articles/xy-workshop/05/text$markdown.md
new file mode 100644
index 0000000..256c654
--- /dev/null
+++ b/root/articles/xy-workshop/05/text$markdown.md
@@ -0,0 +1,12 @@
+what is sound?
+==============
+
+attributes of waves:
+
+| waves <div style="display: inline-block; width: 50px;"></div> | sounds <div style="display: inline-block; width: 10px;"></div> | |
+|-------------|--------------------|----------------------------------|
+| `amplitude` | `volume` | how far does the wave fluctuate? |
+| `frequency` | `pitch` | how often does the wave repeat? |
+| `shape` | `timbre` | (literally just the shape) |
+
+...let's look at + hear some examples!
diff --git a/root/articles/xy-workshop/06/text$markdown.md b/root/articles/xy-workshop/06/text$markdown.md
new file mode 100644
index 0000000..fa5b139
--- /dev/null
+++ b/root/articles/xy-workshop/06/text$markdown.md
@@ -0,0 +1,6 @@
+on computers, sound is stored as a list of `samples`:
+
+- `sample rate`: how many samples per second are recorded
+- `sample size` or `bit depth`: how accurate is each sample
+
+![](https://i0.wp.com/www.mobilebeat.com/wp-content/uploads/2017/05/Screen-Shot-2017-05-05-at-3.55.46-PM.png)
diff --git a/root/articles/xy-workshop/07/text$markdown.md b/root/articles/xy-workshop/07/text$markdown.md
new file mode 100644
index 0000000..518b9fb
--- /dev/null
+++ b/root/articles/xy-workshop/07/text$markdown.md
@@ -0,0 +1,6 @@
+what is an oscilloscope?
+========================
+
+- machine for measuring and visualizing electronic waves (voltage)
+
+![](https://www.electronics-notes.com/images/cathode-ray-tube-diagram-01.svg)
diff --git a/root/articles/xy-workshop/08/$order b/root/articles/xy-workshop/08/$order
new file mode 100644
index 0000000..773b222
--- /dev/null
+++ b/root/articles/xy-workshop/08/$order
@@ -0,0 +1 @@
+image
diff --git a/root/articles/xy-workshop/08/image/image$png.png b/root/articles/xy-workshop/08/image/image$png.png
new file mode 100644
index 0000000..ff82a9d
--- /dev/null
+++ b/root/articles/xy-workshop/08/image/image$png.png
Binary files differ
diff --git a/root/articles/xy-workshop/08/text$markdown.md b/root/articles/xy-workshop/08/text$markdown.md
new file mode 100644
index 0000000..92ab316
--- /dev/null
+++ b/root/articles/xy-workshop/08/text$markdown.md
@@ -0,0 +1,4 @@
+what is an oscilloscope?
+========================
+
+![](/articles/xy-workshop/08/image/:image/png)
diff --git a/root/articles/xy-workshop/description: text$plain b/root/articles/xy-workshop/description: text$plain
new file mode 100644
index 0000000..c3fefe0
--- /dev/null
+++ b/root/articles/xy-workshop/description: text$plain
@@ -0,0 +1,2 @@
+workshop: oscilloscope music and games with pure data
+
diff --git a/root/articles/xy-workshop/text$moonscript -> fn -> mmm$dom.moon b/root/articles/xy-workshop/text$moonscript -> fn -> mmm$dom.moon
new file mode 100644
index 0000000..701a14c
--- /dev/null
+++ b/root/articles/xy-workshop/text$moonscript -> fn -> mmm$dom.moon
@@ -0,0 +1,70 @@
+import ReactiveVar, tohtml, fromhtml, text, elements from require 'mmm.component'
+import article, button, div, span from elements
+
+=>
+ index = ReactiveVar 1
+ slide = index\map (index) -> @children[index]
+
+ local view
+ view = div {
+ style:
+ position: 'relative'
+ 'padding-top': '56.25%'
+
+ div {
+ style:
+ position: 'absolute'
+ display: 'flex'
+ 'flex-direction': 'column'
+ top: 0
+ left: 0
+ right: 0
+ bottom: 0
+ padding: '1em'
+ background: '#eeeeee'
+ 'box-sizing': 'border-box'
+
+ slide\map => @get 'mmm/dom'
+ }
+ }
+
+ local left, right, viewNode
+ if MODE == 'CLIENT'
+ left = (_, e) ->
+ e\preventDefault!
+ index\transform (a) -> math.max 1, a - 1
+
+ right = (_, e) ->
+ e\preventDefault!
+ index\transform (a) -> math.min #@children, a + 1
+
+ viewNode = tohtml view
+ viewNode.tabIndex = 1
+ viewNode\addEventListener 'keydown', (_, e) ->
+ switch e.key
+ when 'r'
+ e\preventDefault!
+ size = viewNode.offsetHeight / 15
+ viewNode.style.fontSize = "#{size}px"
+
+ when 'ArrowLeft'
+ left _, e
+ when 'ArrowRight'
+ right _, e
+
+ tohtml with article!
+ \append div {
+ style:
+ display: 'flex'
+
+ button '<', onclick: left
+ ' '
+ span index\map (t) -> text t
+ ' '
+ button '>', onclick: right
+ div style: flex: '1'
+ button 'fullscreen', onclick: (_, e) ->
+ e\preventDefault!
+ viewNode\requestFullscreen!
+ }
+ \append view