diff --git a/content/pages/nixcon2022/index.md b/content/pages/nixcon2022/index.md deleted file mode 100644 index b664eaf..0000000 --- a/content/pages/nixcon2022/index.md +++ /dev/null @@ -1,11 +0,0 @@ -+++ -title = "NixCon 2022" -path = "/nixcon2022" -[extra] -isPage = true -+++ -Hi! - -You've reached the NixCon 2022 page. Links: -* [Slides](./slides) -* [Video (livestream)](https://youtu.be/l70haNBm1wc?t=4h34m28s) diff --git a/content/posts/nixcon2022-retrospective.md b/content/posts/nixcon2022-retrospective.md new file mode 100644 index 0000000..a715a5f --- /dev/null +++ b/content/posts/nixcon2022-retrospective.md @@ -0,0 +1,164 @@ ++++ +date = "2022-10-23" +draft = false +path = "/blog/nixcon2022-retrospective" +tags = ["nix", "haskell", "nixcon"] +title = "NixCon 2022!!" ++++ + +Well, that sure was a thing. It was more than a thing: it was a really good +thing. + +NixCon 2022 was my first in-person conference, and therefore also my first time +speaking at an in-person conference. I understand better why people want these. +It's really nice to be around The People For The Thing and meet new people +(whether they are wearing cat ears or otherwise). + +I met a whole *bunch* of people and made some new friends. + +I am not sure my feelings about the main venue, as it was really rather stuffy +in there, and I mostly avoided it to reduce my exposure to COVID. However the +rest of the college it was held at was pretty wonderful (modulo the lack of +WiFi for people without eduroam access, although that was worked around). + +## Speaking + +I delivered a talk "Debugging Closure Size Graphically". This was a fun +experience; it's a lot easier to deliver jokes in front of an audience. I'm +excited to see what people do with the tools I built, and I'm glad they are +open source now. + +In this talk, I show how I found issues with the closure size of Haskell and +Node.JS programs, then how I fixed the Node.JS issues. + +Links: +* [Livestream video][livestream] (a better recording with slides is coming soon) +* [Slides] +* Tools: + * nix-closure-graph: https://github.com/lf-/dotfiles/tree/main/programs/nix-closure-graph + * Graph viewer: https://mercurytechnologies.github.io/looking-glass-viewer/ + +[livestream]: https://youtu.be/l70haNBm1wc?t=4h34m10s +[Slides]: https://jade.fyi/nixcon2022/slides + +## The hacking room + +I spent most of the conference either in breakout rooms and later, the +hackathon room. We got the following done: + +### Incremental builds for Haskell + +This was done after an extremely useful discussion with [Jonas Chevalier +(@zimbatm)][Jonas Chevalier] and implemented in large part by [Harry Garrood]. +The idea is that we can achieve incremental builds of Haskell by doing an +impure dependency on the previous build, intentionally breaking the evaluation +chain. + +[Jonas Chevalier]: https://twitter.com/zimbatm +[Harry Garrood]: https://twitter.com/hdgarrood + +In practice, this looks like a setting on the Haskell builder to enable +a separate output for incremental information (which is the interface and +object files of the run), and a second setting to copy in incremental +information from some path. + +This approach [requires GHC 9.4][harry-blog] in order to use hash-based +incremental information rather than entirely relying on file timestamps as +was previously done. + +The reason this is fantastic is that it avoids the following false dichotomy of +flawed options: + * Use one derivation per file. This would pessimize build times by having to + invoke GHC for each file as [ghc-nix] does, eating startup costs for each + file, and also losing finer grained incremental support than "did the + file change". + + That is a completely valid and reasonable approach as it keeps the build + hermetic at the cost of more build time, but it relies heavily on + content-addressed derivations, and if you used it within Nix, it would + also use recursive Nix or [derivations-building-derivations]. + + * Change the project structure to use more packages so that Nix can + incrementally build at the package level. + + This is hard to do, and [multi-package pessimizes the developer + experience][mp-fail] due to lack of multiple home units support as well + as slowing down builds in development (as opposed to Nix builds) since + Cabal/GHC do not yet know how to build the non-dependent parts of + dependent packages at the same time. + + In my view, commercial projects probably should be one package as it + currently stands, because splitting packages is bad for development + efficiency, requiring duplicating dependency lists and doing a bunch of + other housekeeping, on top of the issues with concurrently working on + multiple packages described above. + + Note that as in the link above, calling GHC once per file *does* allow + solving the dependent-package parallelism problem, as Bazel does, but it + also pessimizes build times. + +We decided to have our cake and eat it too. We prototyped an approach of +letting GHC do the incremental builds in the way [Harry describes][harry-blog], +and then convincing Nix to let us do it. This leaves dev completely alone, and +constitutes only a minor impurity crime (since at least it is reproducible +given some effort!), while not pessimizing compile times at all. + +[harry-blog]: https://harry.garrood.me/blog/easy-incremental-haskell-ci-builds-with-ghc-9.4/ +[ghc-nix]: https://github.com/matthewbauer/ghc-nix +[derivations-building-derivations]: https://github.com/NixOS/rfcs/blob/master/rfcs/0092-plan-dynamism.md +[mp-fail]: ./cabal-test-dev-trick + +### [nix-otel] grows up + +Another really nice achievement of the conference is that, with the help of +[Linus Heckemann] and [Jean-François Roche], we have improved data quality in +nix-otel and poked at making it work in the daemon, after which it could be +integrated into Nix itself. + +Following discussions, it's likely that future structured logging will be +OpenTelemetry based as it avoids reinventing the wheel. + +The data quality improvement is that previously, changing phases in the builder +would not emit spans, which it now does. There is one span for each phase. This +was achieved by effectively postprocessing the log data from Nix. Also, there +was a memory corruption I fixed, which was somehow only causing missing data +rather than crashes. Yikes. + +We also now report 100% of the information that Nix gives us via the logger, +which means that further improvements will be in Nix itself, improving +logging for everyone. + +Linus worked on getting nix-otel to work in the daemon, which is still a work +in progress. We want to use settings for the API keys and endpoint to avoid +needing environment variables for them. On that account, we arrived at hunting +a bug in our settings handling in which the settings were not getting their +values properly. + +Another thing that was discussed is making the daemon and client cooperate +since the client knows some things the daemon doesn't, and the daemon has +better timing information. This can be done pretty easily by having the client +do propagation of trace IDs to the daemon, and keeping track of whether log +data was forwarded (and in that case, not sending it to OpenTelemetry since it +already was sent). + +Once this foundational work is done, nix-otel can be integrated into Nix +itself, potentially representing the first Rust in Nix since the previous +attempt that had significantly more complicated foreign-function-interface +usage, leading to its failure. + +Looking forward, another thing we can probably do is to use the `$NIX_LOG_FD` +infrastructure that already exists to build an OpenTelemetry +propagator/exporter that can be used within builds to also instrument the +inside of builds. + +[nix-otel]: https://github.com/lf-/nix-otel +[Linus Heckemann]: https://twitter.com/linux_hackerman +[Jean-François Roche]: https://github.com/jfroche + +## oops, feelings + +Paris is beautiful. I really appreciate having a practical transit system and +being able to walk everywhere. + +Certainly this trip has renewed my motivation for looking into possibly moving +to Europe in the next few years. diff --git a/content/posts/nixcon2022/index.md b/content/posts/nixcon2022/index.md new file mode 100644 index 0000000..355dd06 --- /dev/null +++ b/content/posts/nixcon2022/index.md @@ -0,0 +1,354 @@ ++++ +title = "NixCon 2022: Debugging Closure Sizes Graphically with nix-closure-graph" +path = "/nixcon2022" +draft = false +tags = ["nix", "haskell", "nixcon", "javascript"] +date = "2022-10-20" ++++ + +I delivered a talk "Debugging Closure Size Graphically" at NixCon 2022. This +blog post is intended as a textual version of the talk although it is not a +script. + +Here are links to the live version: + +* [Livestream video][livestream] (a better recording with slides is coming soon) +* [Slides] +* Tools: + * nix-closure-graph: https://github.com/lf-/dotfiles/tree/main/programs/nix-closure-graph + * Graph viewer: https://mercurytechnologies.github.io/looking-glass-viewer/ + +[nix-closure-graph]: https://github.com/lf-/dotfiles/tree/main/programs/nix-closure-graph +[looking-glass]: https://mercurytechnologies.github.io/looking-glass-viewer/ +[looking-glass-github]: https://github.com/MercuryTechnologies/looking-glass-viewer +[livestream]: https://youtu.be/l70haNBm1wc?t=4h34m10s +[Slides]: https://jade.fyi/nixcon2022/slides + +## Closure size + +Nix's smallest unit of building is a so-called "derivation". Generally there is +one of these per package or per part of a NixOS system. The derivation is a +concept at the layer of the Nix store. + +Xe has said that [Nix is a compiler from Haskell to Bash][xe-why], which is a +quite good if flippant explanation of how the Nix language relates to the build +system: the "haskell" part is the Nix language, and the "bash" is the full +invocation of some builder (typically written in bash) to actually build the +thing, produced by `builtins.derivation`. + +You can see the content of a derivation created by a Nix expression like so: + +{% codesample(desc="`nix show-derivation nixpkgs#hello`") %} + +```json + » nix show-derivation nixpkgs#hello +{ + "/nix/store/vdqm71n5bkfydjwjwmx2rkj18jrpxlmx-hello-2.12.1.drv": { + "outputs": { + "out": { + "path": "/nix/store/m2wybrc3grfn76hxcv4gyiyncng17z30-hello-2.12.1" + } + }, + "inputSrcs": [ + "/nix/store/9krlzvny65gdc8s7kpb6lkx8cd02c25b-default-builder.sh" + ], + "inputDrvs": { + "/nix/store/004b0bvpjng4l23kahn6vzawlpr6dx75-bash-5.1-p16.drv": [ + "out" + ], + "/nix/store/gajvqygc937wsfjdkpfpqrrk3mlpyy6z-stdenv-linux.drv": [ + "out" + ], + "/nix/store/j80mkmlf7xv7cqn3chh7ghi1r96406m2-hello-2.12.1.tar.gz.drv": [ + "out" + ] + }, + "system": "x86_64-linux", + "builder": "/nix/store/dd3713mm8wql4r2d5jxx0f58g16nfm4h-bash-5.1-p16/bin/bash", + "args": [ + "-e", + "/nix/store/9krlzvny65gdc8s7kpb6lkx8cd02c25b-default-builder.sh" + ], + "env": { + "buildInputs": "", + "builder": "/nix/store/dd3713mm8wql4r2d5jxx0f58g16nfm4h-bash-5.1-p16/bin/bash", + "cmakeFlags": "", + "configureFlags": "", + "depsBuildBuild": "", + "depsBuildBuildPropagated": "", + "depsBuildTarget": "", + "depsBuildTargetPropagated": "", + "depsHostHost": "", + "depsHostHostPropagated": "", + "depsTargetTarget": "", + "depsTargetTargetPropagated": "", + "doCheck": "1", + "doInstallCheck": "", + "mesonFlags": "", + "name": "hello-2.12.1", + "nativeBuildInputs": "", + "out": "/nix/store/m2wybrc3grfn76hxcv4gyiyncng17z30-hello-2.12.1", + "outputs": "out", + "patches": "", + "pname": "hello", + "propagatedBuildInputs": "", + "propagatedNativeBuildInputs": "", + "src": "/nix/store/pa10z4ngm0g83kx9mssrqzz30s84vq7k-hello-2.12.1.tar.gz", + "stdenv": "/nix/store/vsw40d3nb6mpjf770iv58czisf65lzzl-stdenv-linux", + "strictDeps": "", + "system": "x86_64-linux", + "version": "2.12.1" + } + } +} +``` + +{% end %} + +[xe-why]: https://twitter.com/leftpaddotpy/status/1578914185857372165 + +The "closure" of some Nix store path, for instance, of the "out" output of the +"hello" derivation above, refers to all the store paths referenced in that +store path, and the store paths referenced in such references recursively. If +you would like a mathy definition, see [Eelco's PhD thesis][phd-thesis], page +96. + +[phd-thesis]: https://edolstra.github.io/pubs/phd-thesis.pdf + +Put another way, the closure is "your thing and everything it depends on, +recursively". + +The way that runtime dependencies are created in Nix is that Nix will +effectively `grep` for the hash part of any inputs of a derivation, which will +form the runtime dependencies. + +This is unlike most other systems, which require explicit specification of +runtime dependencies, potentially allowing forgetting some (which will work on +the maintainer's machine that has the software but not on a fresh install). Nix +has the opposite problem: it's easy to accidentally *create* runtime +dependencies, since any reference to the build inputs in the outputs can create +one. + +Closure sizes *largely* don't matter if you are building on the same system +that you are running the software on, besides leaving some stuff around that +the garbage collector can't delete due to pointless references. However, the +entire closure needs to be shipped around whenever you are deploying Nix-built +software to another machine, using up space (prod generally has less space than +your laptop!) and bandwidth. + +### spaghetti monsters + +Let the spaghetti monster be a stand-in for your choice of large thing; perhaps +a compiler, a build system, some interpreter you don't actually need at +runtime, or anything else. + +If the spaghetti monster is in `buildInputs` of your derivation: + +![silly drawing of mkDerivation with a build input of a drawing of a spaghetti +monster](slides/img/fsm-drv-1.svg) + +... *and* its store path appears in the output: + +![continuation of the previous image, with a buildPhase echoing spaghetti monster into $out](slides/img/fsm-drv-2.svg) + +then the derivation will depend on the spaghetti monster at runtime, and thus +you will be transporting a big spaghetti monster along with your software, +anywhere it goes (such as in a Docker image or a NixOS deployment): + +![little container ship with a container mostly containing spaghetti monster and insignificantly containing myapp](slides/img/fsm-docker.svg) + +## Figuring out what your software depends on + +You can use `nix path-info` to list the dependencies of a store path +`-r`ecursively, with `-s`izes, and closure `-S`izes, in `-h`uman readable form. + +```text +~ » nix path-info -rsSh nixpkgs#hello +/nix/store/c8aj6kzv5h7c5vympiy7l1p3aw626yqy-libobjc-11.0.0 199.7K 199.7K +/nix/store/y5cp9q9h6p80mzbsijs00zxpi7g0lc9d-apple-framework-CoreFoundation-11.0.0 667.1K 866.8K +/nix/store/xbqj64vdr3z13nlf8cvl1lf5lxa16mha-hello-2.12.1 126.9K 993.7K +``` + +This is, however, unhelpful, since this is actually structurally a graph, and +this view does not make it obvious what depends on what. + +Nix actually can output GraphViz with `nix-store --query --graph` but it +doesn't show sizes so it is unhelpful. + +### Just render a graph then! + +I wrote a program in `jq`, everyone's favourite [language that, like Nix, is +also allegedly Haskell][xe-why], which generates GraphViz with good quality +output. It can be invoked with [`nix-closure-graph nixpkgs#python3 > +img.svg`][nix-closure-graph]. + +This works pretty well for Python (open the image in a new tab if you want to +look at it more closely): + +graphviz graph showing nodes for each of the packages Python depends on + +But not so for NixOS closures: + +incomprehensible graphviz graph absolutely covered in lines for a nixos image + + +### Just render a graph, but not with GraphViz + +Writing a better graph viewer sounds hard, but it turns out +[Sigma.js](https://www.sigmajs.org/) already did the hard part of writing a +graph renderer that does well with big graphs, and I had already built a +Sigma-based graph viewer as a prototype at work as part of my internship +project. + +I believe that it's not practical to show large graphs non-interactively: since +GraphViz contains the results of several papers on graph layout and it is slow +while also having poor output for large graphs, it follows that the only +practical option is to do something worse and faster for layout and make up for +it with interactivity. Sigma seems to be one of the better options for building +a viewer that does that. + +[Looking Glass][looking-glass], my graph viewer, consists of a simple JSON +format (intended to be simple enough you can generate it directly out of +PostgreSQL) and a properties panel to list arbitrary data of nodes. + +It's [open source][looking-glass-github] under the MIT license, if you want to +hack on it. + +![Looking glass showing an extremely busy, yet somewhat usable view of a NixOS closure](./slides/img/nixos-closure.png) + +To use it, you can do a command like `nix-closure-graph --lg nixpkgs#python3 | +xsel -b` (pick your store path and clipboard tool of choice), then paste the +JSON into the box in the viewer. + +[Here is the JSON from my NixOS closure, for example](./slides/graphs/nixos.json) + +#### Why is GHC in my NixOS closure? + +This is possibly a known issue, or possibly fixed in newer GHC, or possibly me +forgetting to use `pkgs.haskell.lib.justStaticExecutables`. Regardless, it's +not on purpose. + +## Practical closure size problems + +I was packaging [actual-budget], a budgeting program, to run it on fly.io. So I +figured out how to build a docker image for it with Nix. You can get the +[final version here](https://github.com/lf-/actual-server/tree/flake). + +[actual-budget]: https://actualbudget.com/ + +However, I had a problem: + +```text + » ls -lah $(readlink result) +-r--r--r-- 1 root root 219M Dec 31 1969 /nix/store/6r0nslg23w2sa6a2zril3g0fvd6mnp1q-actual-server.tar.gz +``` + +200MB compressed is not good. It's just some JavaScript, what happened there? + +![screenshot of the graph viewer showing that actual-server depends on actual-server-modules, a store path of suspiciously similar size](./slides/img/actual-stage0.png) + +It appears that for some reason `actual-server` and `actual-server-modules` are +both there, which is not quite right. + +Also, it appears that Python got in there somehow, which is not necessary: + +![screenshot of the graph viewer showing that nodejs depends on +python](./slides/img/actual-stage0-python.png) + +### What went wrong? + +Python is in there because of an exceedingly poorly named legacy build system +inherited from Chromium called "Generate Your Projects", which compiles weird +Python into Makefiles. + +Unfortunately Actual uses some native extensions, but *after* building those +with "Generate Your Projects", there's no reason at all to have Python around. + +It turns out, nixpkgs ships a version of NodeJS that does not include Python +or npm, called [`nodejs-slim`][nodejs-slim]. + +[nodejs-slim]: https://github.com/nixos/nixpkgs/blob/4567b99d17d3e0f96e0022c18f92a08a03e91f3e/pkgs/top-level/all-packages.nix#L8586-L8588 + +The app is there twice because of a symlink: + +```text +» nix why-depends -a --precise \ + /nix/store/qq1zblyp6ysx-actual-server \ + /nix/store/i778ag8s7jf8-actual-sync-modules-1.0.1 + +/nix/store/qq1zblyp6ysx96vd8havhw0wcsihcidf-actual-server +└───libexec/actual-sync/deps/actual-sync/node_modules + -> /nix/store/i778ag8s7jf8b-actual-sync-mo> + → /nix/store/i778ag8s7jf8-actual-sync-modules-1.0.1 +``` + +However, if we look at what's actually in that symlink, we will find nothing +necessary at all. + +```text +» ls -a result/libexec/actual-sync/deps/actual-sync/node_modules +. .. .bin + » ls -a result/libexec/actual-sync/deps/actual-sync/node_modules/.bin +. .. eslint prettier tsc tsserver uuid +``` + +![Scooby Doo 'let's see who this is anyway' meme, unmasking 'closure size' to +be 'totally pointless stuff'](./slides/img/lets-see-who-this-really-is.png) + +### Fixing it + +The solution to Python being there is to remove all references to `nodejs` and +replace the relevant ones with `nodejs-slim`. This was easiest to do by just +doing a silly find command to delete the ones in unimportant scripts, then +manually patching the shebang of the entry point script using `sed`. + +The app being included twice was fixed by deleting the symlink and replacing it +with a new symlink to the right relative path (since apparently it was not only +a closure size problem but also wrong). + +It's a good idea to put the package you want to exclude in +[`disallowedRequisites`](https://nixos.org/manual/nix/stable/language/advanced-attributes.html#adv-attr-disallowedRequisites) +or `disallowedReferences` so that Nix will fail the build if it appears again. + +All in all it looks like the following: ([original +source](https://github.com/lf-/actual-server/blob/flake/flake.nix#L40-L51)) + +```nix +prev.mkYarnPackage rec { + # ... + + # we don't need to have the full-fat nodejs with python + # (for gyp) and so on except to build. It is undesirably + # referenced by binaries in dependencies, and also would be + # patchShebang'd into bin/actual-server as well if we + # didn't disable that and do it manually. + dontPatchShebangs = true; + extraBuildInputs = [ final.removeReferencesTo ]; + disallowedRequisites = [ final.nodejs-16_x ]; + + distPhase = '' + # redundant symlink that introduces a 150mb runtime dep + # on the actual-server-modules derivation + rm $out/libexec/actual-sync/deps/actual-sync/node_modules + # .. and replace it with a relative symlink inside the + # package so the server can find its web files + ln -s $out/libexec/actual-sync/node_modules $out/libexec/actual-sync/deps/actual-sync/node_modules + + # manually patchelf actual-server + sed -i '1c #!${final.nodejs-slim-16_x}/bin/node' "$(readlink -f "$out/bin/actual-server")" + + # break unnecessary dependency binaries + find "$out" -type f -exec remove-references-to -t ${final.nodejs-16_x} '{}' + + ''; +} +``` + +## Conclusion + +Don't ship around spaghetti monsters if it can be avoided: closure size matters +whenever you are shipping around Nix build output. + +Most often, closure size is down to accidentally depending on build tools and +other packages, and it can be solved case-by-case by adding fixup scripts to +remove pointless references. + diff --git a/content/pages/nixcon2022/slides/LICENSE b/content/posts/nixcon2022/slides/LICENSE similarity index 100% rename from content/pages/nixcon2022/slides/LICENSE rename to content/posts/nixcon2022/slides/LICENSE diff --git a/content/pages/nixcon2022/slides/README.md b/content/posts/nixcon2022/slides/README.md similarity index 100% rename from content/pages/nixcon2022/slides/README.md rename to content/posts/nixcon2022/slides/README.md diff --git a/content/pages/nixcon2022/slides/css/layout.scss b/content/posts/nixcon2022/slides/css/layout.scss similarity index 100% rename from content/pages/nixcon2022/slides/css/layout.scss rename to content/posts/nixcon2022/slides/css/layout.scss diff --git a/content/pages/nixcon2022/slides/css/print/paper.scss b/content/posts/nixcon2022/slides/css/print/paper.scss similarity index 100% rename from content/pages/nixcon2022/slides/css/print/paper.scss rename to content/posts/nixcon2022/slides/css/print/paper.scss diff --git a/content/pages/nixcon2022/slides/css/print/pdf.scss b/content/posts/nixcon2022/slides/css/print/pdf.scss similarity index 100% rename from content/pages/nixcon2022/slides/css/print/pdf.scss rename to content/posts/nixcon2022/slides/css/print/pdf.scss diff --git a/content/pages/nixcon2022/slides/css/reveal.scss b/content/posts/nixcon2022/slides/css/reveal.scss similarity index 100% rename from content/pages/nixcon2022/slides/css/reveal.scss rename to content/posts/nixcon2022/slides/css/reveal.scss diff --git a/content/pages/nixcon2022/slides/css/theme/README.md b/content/posts/nixcon2022/slides/css/theme/README.md similarity index 100% rename from content/pages/nixcon2022/slides/css/theme/README.md rename to content/posts/nixcon2022/slides/css/theme/README.md diff --git a/content/pages/nixcon2022/slides/css/theme/source/beige.scss b/content/posts/nixcon2022/slides/css/theme/source/beige.scss similarity index 100% rename from content/pages/nixcon2022/slides/css/theme/source/beige.scss rename to content/posts/nixcon2022/slides/css/theme/source/beige.scss diff --git a/content/pages/nixcon2022/slides/css/theme/source/black.scss b/content/posts/nixcon2022/slides/css/theme/source/black.scss similarity index 100% rename from content/pages/nixcon2022/slides/css/theme/source/black.scss rename to content/posts/nixcon2022/slides/css/theme/source/black.scss diff --git a/content/pages/nixcon2022/slides/css/theme/source/blood.scss b/content/posts/nixcon2022/slides/css/theme/source/blood.scss similarity index 100% rename from content/pages/nixcon2022/slides/css/theme/source/blood.scss rename to content/posts/nixcon2022/slides/css/theme/source/blood.scss diff --git a/content/pages/nixcon2022/slides/css/theme/source/league.scss b/content/posts/nixcon2022/slides/css/theme/source/league.scss similarity index 100% rename from content/pages/nixcon2022/slides/css/theme/source/league.scss rename to content/posts/nixcon2022/slides/css/theme/source/league.scss diff --git a/content/pages/nixcon2022/slides/css/theme/source/moon.scss b/content/posts/nixcon2022/slides/css/theme/source/moon.scss similarity index 100% rename from content/pages/nixcon2022/slides/css/theme/source/moon.scss rename to content/posts/nixcon2022/slides/css/theme/source/moon.scss diff --git a/content/pages/nixcon2022/slides/css/theme/source/night.scss b/content/posts/nixcon2022/slides/css/theme/source/night.scss similarity index 100% rename from content/pages/nixcon2022/slides/css/theme/source/night.scss rename to content/posts/nixcon2022/slides/css/theme/source/night.scss diff --git a/content/pages/nixcon2022/slides/css/theme/source/serif.scss b/content/posts/nixcon2022/slides/css/theme/source/serif.scss similarity index 100% rename from content/pages/nixcon2022/slides/css/theme/source/serif.scss rename to content/posts/nixcon2022/slides/css/theme/source/serif.scss diff --git a/content/pages/nixcon2022/slides/css/theme/source/simple.scss b/content/posts/nixcon2022/slides/css/theme/source/simple.scss similarity index 100% rename from content/pages/nixcon2022/slides/css/theme/source/simple.scss rename to content/posts/nixcon2022/slides/css/theme/source/simple.scss diff --git a/content/pages/nixcon2022/slides/css/theme/source/sky.scss b/content/posts/nixcon2022/slides/css/theme/source/sky.scss similarity index 100% rename from content/pages/nixcon2022/slides/css/theme/source/sky.scss rename to content/posts/nixcon2022/slides/css/theme/source/sky.scss diff --git a/content/pages/nixcon2022/slides/css/theme/source/solarized.scss b/content/posts/nixcon2022/slides/css/theme/source/solarized.scss similarity index 100% rename from content/pages/nixcon2022/slides/css/theme/source/solarized.scss rename to content/posts/nixcon2022/slides/css/theme/source/solarized.scss diff --git a/content/pages/nixcon2022/slides/css/theme/source/white.scss b/content/posts/nixcon2022/slides/css/theme/source/white.scss similarity index 100% rename from content/pages/nixcon2022/slides/css/theme/source/white.scss rename to content/posts/nixcon2022/slides/css/theme/source/white.scss diff --git a/content/pages/nixcon2022/slides/css/theme/template/exposer.scss b/content/posts/nixcon2022/slides/css/theme/template/exposer.scss similarity index 100% rename from content/pages/nixcon2022/slides/css/theme/template/exposer.scss rename to content/posts/nixcon2022/slides/css/theme/template/exposer.scss diff --git a/content/pages/nixcon2022/slides/css/theme/template/mixins.scss b/content/posts/nixcon2022/slides/css/theme/template/mixins.scss similarity index 100% rename from content/pages/nixcon2022/slides/css/theme/template/mixins.scss rename to content/posts/nixcon2022/slides/css/theme/template/mixins.scss diff --git a/content/pages/nixcon2022/slides/css/theme/template/settings.scss b/content/posts/nixcon2022/slides/css/theme/template/settings.scss similarity index 100% rename from content/pages/nixcon2022/slides/css/theme/template/settings.scss rename to content/posts/nixcon2022/slides/css/theme/template/settings.scss diff --git a/content/pages/nixcon2022/slides/css/theme/template/theme.scss b/content/posts/nixcon2022/slides/css/theme/template/theme.scss similarity index 100% rename from content/pages/nixcon2022/slides/css/theme/template/theme.scss rename to content/posts/nixcon2022/slides/css/theme/template/theme.scss diff --git a/content/pages/nixcon2022/slides/dist/reset.css b/content/posts/nixcon2022/slides/dist/reset.css similarity index 100% rename from content/pages/nixcon2022/slides/dist/reset.css rename to content/posts/nixcon2022/slides/dist/reset.css diff --git a/content/pages/nixcon2022/slides/dist/reveal.css b/content/posts/nixcon2022/slides/dist/reveal.css similarity index 100% rename from content/pages/nixcon2022/slides/dist/reveal.css rename to content/posts/nixcon2022/slides/dist/reveal.css diff --git a/content/pages/nixcon2022/slides/dist/reveal.esm.js b/content/posts/nixcon2022/slides/dist/reveal.esm.js similarity index 100% rename from content/pages/nixcon2022/slides/dist/reveal.esm.js rename to content/posts/nixcon2022/slides/dist/reveal.esm.js diff --git a/content/pages/nixcon2022/slides/dist/reveal.esm.js.map b/content/posts/nixcon2022/slides/dist/reveal.esm.js.map similarity index 100% rename from content/pages/nixcon2022/slides/dist/reveal.esm.js.map rename to content/posts/nixcon2022/slides/dist/reveal.esm.js.map diff --git a/content/pages/nixcon2022/slides/dist/reveal.js b/content/posts/nixcon2022/slides/dist/reveal.js similarity index 100% rename from content/pages/nixcon2022/slides/dist/reveal.js rename to content/posts/nixcon2022/slides/dist/reveal.js diff --git a/content/pages/nixcon2022/slides/dist/reveal.js.map b/content/posts/nixcon2022/slides/dist/reveal.js.map similarity index 100% rename from content/pages/nixcon2022/slides/dist/reveal.js.map rename to content/posts/nixcon2022/slides/dist/reveal.js.map diff --git a/content/pages/nixcon2022/slides/dist/theme/beige.css b/content/posts/nixcon2022/slides/dist/theme/beige.css similarity index 100% rename from content/pages/nixcon2022/slides/dist/theme/beige.css rename to content/posts/nixcon2022/slides/dist/theme/beige.css diff --git a/content/pages/nixcon2022/slides/dist/theme/black.css b/content/posts/nixcon2022/slides/dist/theme/black.css similarity index 100% rename from content/pages/nixcon2022/slides/dist/theme/black.css rename to content/posts/nixcon2022/slides/dist/theme/black.css diff --git a/content/pages/nixcon2022/slides/dist/theme/blood.css b/content/posts/nixcon2022/slides/dist/theme/blood.css similarity index 100% rename from content/pages/nixcon2022/slides/dist/theme/blood.css rename to content/posts/nixcon2022/slides/dist/theme/blood.css diff --git a/content/pages/nixcon2022/slides/dist/theme/fonts/league-gothic/LICENSE b/content/posts/nixcon2022/slides/dist/theme/fonts/league-gothic/LICENSE similarity index 100% rename from content/pages/nixcon2022/slides/dist/theme/fonts/league-gothic/LICENSE rename to content/posts/nixcon2022/slides/dist/theme/fonts/league-gothic/LICENSE diff --git a/content/pages/nixcon2022/slides/dist/theme/fonts/league-gothic/league-gothic.css b/content/posts/nixcon2022/slides/dist/theme/fonts/league-gothic/league-gothic.css similarity index 100% rename from content/pages/nixcon2022/slides/dist/theme/fonts/league-gothic/league-gothic.css rename to content/posts/nixcon2022/slides/dist/theme/fonts/league-gothic/league-gothic.css diff --git a/content/pages/nixcon2022/slides/dist/theme/fonts/league-gothic/league-gothic.eot b/content/posts/nixcon2022/slides/dist/theme/fonts/league-gothic/league-gothic.eot similarity index 100% rename from content/pages/nixcon2022/slides/dist/theme/fonts/league-gothic/league-gothic.eot rename to content/posts/nixcon2022/slides/dist/theme/fonts/league-gothic/league-gothic.eot diff --git a/content/pages/nixcon2022/slides/dist/theme/fonts/league-gothic/league-gothic.ttf b/content/posts/nixcon2022/slides/dist/theme/fonts/league-gothic/league-gothic.ttf similarity index 100% rename from content/pages/nixcon2022/slides/dist/theme/fonts/league-gothic/league-gothic.ttf rename to content/posts/nixcon2022/slides/dist/theme/fonts/league-gothic/league-gothic.ttf diff --git a/content/pages/nixcon2022/slides/dist/theme/fonts/league-gothic/league-gothic.woff b/content/posts/nixcon2022/slides/dist/theme/fonts/league-gothic/league-gothic.woff similarity index 100% rename from content/pages/nixcon2022/slides/dist/theme/fonts/league-gothic/league-gothic.woff rename to content/posts/nixcon2022/slides/dist/theme/fonts/league-gothic/league-gothic.woff diff --git a/content/pages/nixcon2022/slides/dist/theme/fonts/source-sans-pro/LICENSE b/content/posts/nixcon2022/slides/dist/theme/fonts/source-sans-pro/LICENSE similarity index 100% rename from content/pages/nixcon2022/slides/dist/theme/fonts/source-sans-pro/LICENSE rename to content/posts/nixcon2022/slides/dist/theme/fonts/source-sans-pro/LICENSE diff --git a/content/pages/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-italic.eot b/content/posts/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-italic.eot similarity index 100% rename from content/pages/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-italic.eot rename to content/posts/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-italic.eot diff --git a/content/pages/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-italic.ttf b/content/posts/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-italic.ttf similarity index 100% rename from content/pages/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-italic.ttf rename to content/posts/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-italic.ttf diff --git a/content/pages/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-italic.woff b/content/posts/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-italic.woff similarity index 100% rename from content/pages/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-italic.woff rename to content/posts/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-italic.woff diff --git a/content/pages/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-regular.eot b/content/posts/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-regular.eot similarity index 100% rename from content/pages/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-regular.eot rename to content/posts/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-regular.eot diff --git a/content/pages/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-regular.ttf b/content/posts/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-regular.ttf similarity index 100% rename from content/pages/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-regular.ttf rename to content/posts/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-regular.ttf diff --git a/content/pages/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-regular.woff b/content/posts/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-regular.woff similarity index 100% rename from content/pages/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-regular.woff rename to content/posts/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-regular.woff diff --git a/content/pages/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-semibold.eot b/content/posts/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-semibold.eot similarity index 100% rename from content/pages/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-semibold.eot rename to content/posts/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-semibold.eot diff --git a/content/pages/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-semibold.ttf b/content/posts/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-semibold.ttf similarity index 100% rename from content/pages/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-semibold.ttf rename to content/posts/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-semibold.ttf diff --git a/content/pages/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-semibold.woff b/content/posts/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-semibold.woff similarity index 100% rename from content/pages/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-semibold.woff rename to content/posts/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-semibold.woff diff --git a/content/pages/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-semibolditalic.eot b/content/posts/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-semibolditalic.eot similarity index 100% rename from content/pages/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-semibolditalic.eot rename to content/posts/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-semibolditalic.eot diff --git a/content/pages/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-semibolditalic.ttf b/content/posts/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-semibolditalic.ttf similarity index 100% rename from content/pages/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-semibolditalic.ttf rename to content/posts/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-semibolditalic.ttf diff --git a/content/pages/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-semibolditalic.woff b/content/posts/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-semibolditalic.woff similarity index 100% rename from content/pages/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-semibolditalic.woff rename to content/posts/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro-semibolditalic.woff diff --git a/content/pages/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro.css b/content/posts/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro.css similarity index 100% rename from content/pages/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro.css rename to content/posts/nixcon2022/slides/dist/theme/fonts/source-sans-pro/source-sans-pro.css diff --git a/content/pages/nixcon2022/slides/dist/theme/league.css b/content/posts/nixcon2022/slides/dist/theme/league.css similarity index 100% rename from content/pages/nixcon2022/slides/dist/theme/league.css rename to content/posts/nixcon2022/slides/dist/theme/league.css diff --git a/content/pages/nixcon2022/slides/dist/theme/moon.css b/content/posts/nixcon2022/slides/dist/theme/moon.css similarity index 100% rename from content/pages/nixcon2022/slides/dist/theme/moon.css rename to content/posts/nixcon2022/slides/dist/theme/moon.css diff --git a/content/pages/nixcon2022/slides/dist/theme/night.css b/content/posts/nixcon2022/slides/dist/theme/night.css similarity index 100% rename from content/pages/nixcon2022/slides/dist/theme/night.css rename to content/posts/nixcon2022/slides/dist/theme/night.css diff --git a/content/pages/nixcon2022/slides/dist/theme/serif.css b/content/posts/nixcon2022/slides/dist/theme/serif.css similarity index 100% rename from content/pages/nixcon2022/slides/dist/theme/serif.css rename to content/posts/nixcon2022/slides/dist/theme/serif.css diff --git a/content/pages/nixcon2022/slides/dist/theme/simple.css b/content/posts/nixcon2022/slides/dist/theme/simple.css similarity index 100% rename from content/pages/nixcon2022/slides/dist/theme/simple.css rename to content/posts/nixcon2022/slides/dist/theme/simple.css diff --git a/content/pages/nixcon2022/slides/dist/theme/sky.css b/content/posts/nixcon2022/slides/dist/theme/sky.css similarity index 100% rename from content/pages/nixcon2022/slides/dist/theme/sky.css rename to content/posts/nixcon2022/slides/dist/theme/sky.css diff --git a/content/pages/nixcon2022/slides/dist/theme/solarized.css b/content/posts/nixcon2022/slides/dist/theme/solarized.css similarity index 100% rename from content/pages/nixcon2022/slides/dist/theme/solarized.css rename to content/posts/nixcon2022/slides/dist/theme/solarized.css diff --git a/content/pages/nixcon2022/slides/dist/theme/white.css b/content/posts/nixcon2022/slides/dist/theme/white.css similarity index 100% rename from content/pages/nixcon2022/slides/dist/theme/white.css rename to content/posts/nixcon2022/slides/dist/theme/white.css diff --git a/content/pages/nixcon2022/slides/graphs/nixos.json b/content/posts/nixcon2022/slides/graphs/nixos.json similarity index 100% rename from content/pages/nixcon2022/slides/graphs/nixos.json rename to content/posts/nixcon2022/slides/graphs/nixos.json diff --git a/content/pages/nixcon2022/slides/graphs/step0.json b/content/posts/nixcon2022/slides/graphs/step0.json similarity index 100% rename from content/pages/nixcon2022/slides/graphs/step0.json rename to content/posts/nixcon2022/slides/graphs/step0.json diff --git a/content/pages/nixcon2022/slides/gulpfile.js b/content/posts/nixcon2022/slides/gulpfile.js similarity index 100% rename from content/pages/nixcon2022/slides/gulpfile.js rename to content/posts/nixcon2022/slides/gulpfile.js diff --git a/content/pages/nixcon2022/slides/img/actual-stage0-python.png b/content/posts/nixcon2022/slides/img/actual-stage0-python.png similarity index 100% rename from content/pages/nixcon2022/slides/img/actual-stage0-python.png rename to content/posts/nixcon2022/slides/img/actual-stage0-python.png diff --git a/content/pages/nixcon2022/slides/img/actual-stage0.png b/content/posts/nixcon2022/slides/img/actual-stage0.png similarity index 100% rename from content/pages/nixcon2022/slides/img/actual-stage0.png rename to content/posts/nixcon2022/slides/img/actual-stage0.png diff --git a/content/pages/nixcon2022/slides/img/fsm-docker.svg b/content/posts/nixcon2022/slides/img/fsm-docker.svg similarity index 100% rename from content/pages/nixcon2022/slides/img/fsm-docker.svg rename to content/posts/nixcon2022/slides/img/fsm-docker.svg diff --git a/content/pages/nixcon2022/slides/img/fsm-drv-1.svg b/content/posts/nixcon2022/slides/img/fsm-drv-1.svg similarity index 100% rename from content/pages/nixcon2022/slides/img/fsm-drv-1.svg rename to content/posts/nixcon2022/slides/img/fsm-drv-1.svg diff --git a/content/pages/nixcon2022/slides/img/fsm-drv-2.svg b/content/posts/nixcon2022/slides/img/fsm-drv-2.svg similarity index 100% rename from content/pages/nixcon2022/slides/img/fsm-drv-2.svg rename to content/posts/nixcon2022/slides/img/fsm-drv-2.svg diff --git a/content/pages/nixcon2022/slides/img/fsm-runtime-dep.svg b/content/posts/nixcon2022/slides/img/fsm-runtime-dep.svg similarity index 100% rename from content/pages/nixcon2022/slides/img/fsm-runtime-dep.svg rename to content/posts/nixcon2022/slides/img/fsm-runtime-dep.svg diff --git a/content/pages/nixcon2022/slides/img/github-issues.png b/content/posts/nixcon2022/slides/img/github-issues.png similarity index 100% rename from content/pages/nixcon2022/slides/img/github-issues.png rename to content/posts/nixcon2022/slides/img/github-issues.png diff --git a/content/pages/nixcon2022/slides/img/lets-see-who-this-really-is.png b/content/posts/nixcon2022/slides/img/lets-see-who-this-really-is.png similarity index 100% rename from content/pages/nixcon2022/slides/img/lets-see-who-this-really-is.png rename to content/posts/nixcon2022/slides/img/lets-see-who-this-really-is.png diff --git a/content/pages/nixcon2022/slides/img/lets-see-who-this-really-is.xcf b/content/posts/nixcon2022/slides/img/lets-see-who-this-really-is.xcf similarity index 100% rename from content/pages/nixcon2022/slides/img/lets-see-who-this-really-is.xcf rename to content/posts/nixcon2022/slides/img/lets-see-who-this-really-is.xcf diff --git a/content/pages/nixcon2022/slides/img/livedemo.mp4 b/content/posts/nixcon2022/slides/img/livedemo.mp4 similarity index 100% rename from content/pages/nixcon2022/slides/img/livedemo.mp4 rename to content/posts/nixcon2022/slides/img/livedemo.mp4 diff --git a/content/pages/nixcon2022/slides/img/nixos-closure.png b/content/posts/nixcon2022/slides/img/nixos-closure.png similarity index 100% rename from content/pages/nixcon2022/slides/img/nixos-closure.png rename to content/posts/nixcon2022/slides/img/nixos-closure.png diff --git a/content/pages/nixcon2022/slides/img/nixosClosure.png b/content/posts/nixcon2022/slides/img/nixosClosure.png similarity index 100% rename from content/pages/nixcon2022/slides/img/nixosClosure.png rename to content/posts/nixcon2022/slides/img/nixosClosure.png diff --git a/content/pages/nixcon2022/slides/img/nixosClosure.svg b/content/posts/nixcon2022/slides/img/nixosClosure.svg similarity index 100% rename from content/pages/nixcon2022/slides/img/nixosClosure.svg rename to content/posts/nixcon2022/slides/img/nixosClosure.svg diff --git a/content/pages/nixcon2022/slides/img/python3Closure.svg b/content/posts/nixcon2022/slides/img/python3Closure.svg similarity index 100% rename from content/pages/nixcon2022/slides/img/python3Closure.svg rename to content/posts/nixcon2022/slides/img/python3Closure.svg diff --git a/content/pages/nixcon2022/slides/index.html b/content/posts/nixcon2022/slides/index.html similarity index 100% rename from content/pages/nixcon2022/slides/index.html rename to content/posts/nixcon2022/slides/index.html diff --git a/content/pages/nixcon2022/slides/js/components/playback.js b/content/posts/nixcon2022/slides/js/components/playback.js similarity index 100% rename from content/pages/nixcon2022/slides/js/components/playback.js rename to content/posts/nixcon2022/slides/js/components/playback.js diff --git a/content/pages/nixcon2022/slides/js/config.js b/content/posts/nixcon2022/slides/js/config.js similarity index 100% rename from content/pages/nixcon2022/slides/js/config.js rename to content/posts/nixcon2022/slides/js/config.js diff --git a/content/pages/nixcon2022/slides/js/controllers/autoanimate.js b/content/posts/nixcon2022/slides/js/controllers/autoanimate.js similarity index 100% rename from content/pages/nixcon2022/slides/js/controllers/autoanimate.js rename to content/posts/nixcon2022/slides/js/controllers/autoanimate.js diff --git a/content/pages/nixcon2022/slides/js/controllers/backgrounds.js b/content/posts/nixcon2022/slides/js/controllers/backgrounds.js similarity index 100% rename from content/pages/nixcon2022/slides/js/controllers/backgrounds.js rename to content/posts/nixcon2022/slides/js/controllers/backgrounds.js diff --git a/content/pages/nixcon2022/slides/js/controllers/controls.js b/content/posts/nixcon2022/slides/js/controllers/controls.js similarity index 100% rename from content/pages/nixcon2022/slides/js/controllers/controls.js rename to content/posts/nixcon2022/slides/js/controllers/controls.js diff --git a/content/pages/nixcon2022/slides/js/controllers/focus.js b/content/posts/nixcon2022/slides/js/controllers/focus.js similarity index 100% rename from content/pages/nixcon2022/slides/js/controllers/focus.js rename to content/posts/nixcon2022/slides/js/controllers/focus.js diff --git a/content/pages/nixcon2022/slides/js/controllers/fragments.js b/content/posts/nixcon2022/slides/js/controllers/fragments.js similarity index 100% rename from content/pages/nixcon2022/slides/js/controllers/fragments.js rename to content/posts/nixcon2022/slides/js/controllers/fragments.js diff --git a/content/pages/nixcon2022/slides/js/controllers/keyboard.js b/content/posts/nixcon2022/slides/js/controllers/keyboard.js similarity index 100% rename from content/pages/nixcon2022/slides/js/controllers/keyboard.js rename to content/posts/nixcon2022/slides/js/controllers/keyboard.js diff --git a/content/pages/nixcon2022/slides/js/controllers/location.js b/content/posts/nixcon2022/slides/js/controllers/location.js similarity index 100% rename from content/pages/nixcon2022/slides/js/controllers/location.js rename to content/posts/nixcon2022/slides/js/controllers/location.js diff --git a/content/pages/nixcon2022/slides/js/controllers/notes.js b/content/posts/nixcon2022/slides/js/controllers/notes.js similarity index 100% rename from content/pages/nixcon2022/slides/js/controllers/notes.js rename to content/posts/nixcon2022/slides/js/controllers/notes.js diff --git a/content/pages/nixcon2022/slides/js/controllers/overview.js b/content/posts/nixcon2022/slides/js/controllers/overview.js similarity index 100% rename from content/pages/nixcon2022/slides/js/controllers/overview.js rename to content/posts/nixcon2022/slides/js/controllers/overview.js diff --git a/content/pages/nixcon2022/slides/js/controllers/plugins.js b/content/posts/nixcon2022/slides/js/controllers/plugins.js similarity index 100% rename from content/pages/nixcon2022/slides/js/controllers/plugins.js rename to content/posts/nixcon2022/slides/js/controllers/plugins.js diff --git a/content/pages/nixcon2022/slides/js/controllers/pointer.js b/content/posts/nixcon2022/slides/js/controllers/pointer.js similarity index 100% rename from content/pages/nixcon2022/slides/js/controllers/pointer.js rename to content/posts/nixcon2022/slides/js/controllers/pointer.js diff --git a/content/pages/nixcon2022/slides/js/controllers/print.js b/content/posts/nixcon2022/slides/js/controllers/print.js similarity index 100% rename from content/pages/nixcon2022/slides/js/controllers/print.js rename to content/posts/nixcon2022/slides/js/controllers/print.js diff --git a/content/pages/nixcon2022/slides/js/controllers/progress.js b/content/posts/nixcon2022/slides/js/controllers/progress.js similarity index 100% rename from content/pages/nixcon2022/slides/js/controllers/progress.js rename to content/posts/nixcon2022/slides/js/controllers/progress.js diff --git a/content/pages/nixcon2022/slides/js/controllers/slidecontent.js b/content/posts/nixcon2022/slides/js/controllers/slidecontent.js similarity index 100% rename from content/pages/nixcon2022/slides/js/controllers/slidecontent.js rename to content/posts/nixcon2022/slides/js/controllers/slidecontent.js diff --git a/content/pages/nixcon2022/slides/js/controllers/slidenumber.js b/content/posts/nixcon2022/slides/js/controllers/slidenumber.js similarity index 100% rename from content/pages/nixcon2022/slides/js/controllers/slidenumber.js rename to content/posts/nixcon2022/slides/js/controllers/slidenumber.js diff --git a/content/pages/nixcon2022/slides/js/controllers/touch.js b/content/posts/nixcon2022/slides/js/controllers/touch.js similarity index 100% rename from content/pages/nixcon2022/slides/js/controllers/touch.js rename to content/posts/nixcon2022/slides/js/controllers/touch.js diff --git a/content/pages/nixcon2022/slides/js/index.js b/content/posts/nixcon2022/slides/js/index.js similarity index 100% rename from content/pages/nixcon2022/slides/js/index.js rename to content/posts/nixcon2022/slides/js/index.js diff --git a/content/pages/nixcon2022/slides/js/reveal.js b/content/posts/nixcon2022/slides/js/reveal.js similarity index 100% rename from content/pages/nixcon2022/slides/js/reveal.js rename to content/posts/nixcon2022/slides/js/reveal.js diff --git a/content/pages/nixcon2022/slides/js/utils/color.js b/content/posts/nixcon2022/slides/js/utils/color.js similarity index 100% rename from content/pages/nixcon2022/slides/js/utils/color.js rename to content/posts/nixcon2022/slides/js/utils/color.js diff --git a/content/pages/nixcon2022/slides/js/utils/constants.js b/content/posts/nixcon2022/slides/js/utils/constants.js similarity index 100% rename from content/pages/nixcon2022/slides/js/utils/constants.js rename to content/posts/nixcon2022/slides/js/utils/constants.js diff --git a/content/pages/nixcon2022/slides/js/utils/device.js b/content/posts/nixcon2022/slides/js/utils/device.js similarity index 100% rename from content/pages/nixcon2022/slides/js/utils/device.js rename to content/posts/nixcon2022/slides/js/utils/device.js diff --git a/content/pages/nixcon2022/slides/js/utils/loader.js b/content/posts/nixcon2022/slides/js/utils/loader.js similarity index 100% rename from content/pages/nixcon2022/slides/js/utils/loader.js rename to content/posts/nixcon2022/slides/js/utils/loader.js diff --git a/content/pages/nixcon2022/slides/js/utils/util.js b/content/posts/nixcon2022/slides/js/utils/util.js similarity index 100% rename from content/pages/nixcon2022/slides/js/utils/util.js rename to content/posts/nixcon2022/slides/js/utils/util.js diff --git a/content/pages/nixcon2022/slides/package-lock.json b/content/posts/nixcon2022/slides/package-lock.json similarity index 100% rename from content/pages/nixcon2022/slides/package-lock.json rename to content/posts/nixcon2022/slides/package-lock.json diff --git a/content/pages/nixcon2022/slides/package.json b/content/posts/nixcon2022/slides/package.json similarity index 100% rename from content/pages/nixcon2022/slides/package.json rename to content/posts/nixcon2022/slides/package.json diff --git a/content/pages/nixcon2022/slides/plugin/highlight/highlight.esm.js b/content/posts/nixcon2022/slides/plugin/highlight/highlight.esm.js similarity index 100% rename from content/pages/nixcon2022/slides/plugin/highlight/highlight.esm.js rename to content/posts/nixcon2022/slides/plugin/highlight/highlight.esm.js diff --git a/content/pages/nixcon2022/slides/plugin/highlight/highlight.js b/content/posts/nixcon2022/slides/plugin/highlight/highlight.js similarity index 100% rename from content/pages/nixcon2022/slides/plugin/highlight/highlight.js rename to content/posts/nixcon2022/slides/plugin/highlight/highlight.js diff --git a/content/pages/nixcon2022/slides/plugin/highlight/monokai.css b/content/posts/nixcon2022/slides/plugin/highlight/monokai.css similarity index 100% rename from content/pages/nixcon2022/slides/plugin/highlight/monokai.css rename to content/posts/nixcon2022/slides/plugin/highlight/monokai.css diff --git a/content/pages/nixcon2022/slides/plugin/highlight/plugin.js b/content/posts/nixcon2022/slides/plugin/highlight/plugin.js similarity index 100% rename from content/pages/nixcon2022/slides/plugin/highlight/plugin.js rename to content/posts/nixcon2022/slides/plugin/highlight/plugin.js diff --git a/content/pages/nixcon2022/slides/plugin/highlight/zenburn.css b/content/posts/nixcon2022/slides/plugin/highlight/zenburn.css similarity index 100% rename from content/pages/nixcon2022/slides/plugin/highlight/zenburn.css rename to content/posts/nixcon2022/slides/plugin/highlight/zenburn.css diff --git a/content/pages/nixcon2022/slides/plugin/markdown/markdown.esm.js b/content/posts/nixcon2022/slides/plugin/markdown/markdown.esm.js similarity index 100% rename from content/pages/nixcon2022/slides/plugin/markdown/markdown.esm.js rename to content/posts/nixcon2022/slides/plugin/markdown/markdown.esm.js diff --git a/content/pages/nixcon2022/slides/plugin/markdown/markdown.js b/content/posts/nixcon2022/slides/plugin/markdown/markdown.js similarity index 100% rename from content/pages/nixcon2022/slides/plugin/markdown/markdown.js rename to content/posts/nixcon2022/slides/plugin/markdown/markdown.js diff --git a/content/pages/nixcon2022/slides/plugin/markdown/plugin.js b/content/posts/nixcon2022/slides/plugin/markdown/plugin.js similarity index 100% rename from content/pages/nixcon2022/slides/plugin/markdown/plugin.js rename to content/posts/nixcon2022/slides/plugin/markdown/plugin.js diff --git a/content/pages/nixcon2022/slides/plugin/math/katex.js b/content/posts/nixcon2022/slides/plugin/math/katex.js similarity index 100% rename from content/pages/nixcon2022/slides/plugin/math/katex.js rename to content/posts/nixcon2022/slides/plugin/math/katex.js diff --git a/content/pages/nixcon2022/slides/plugin/math/math.esm.js b/content/posts/nixcon2022/slides/plugin/math/math.esm.js similarity index 100% rename from content/pages/nixcon2022/slides/plugin/math/math.esm.js rename to content/posts/nixcon2022/slides/plugin/math/math.esm.js diff --git a/content/pages/nixcon2022/slides/plugin/math/math.js b/content/posts/nixcon2022/slides/plugin/math/math.js similarity index 100% rename from content/pages/nixcon2022/slides/plugin/math/math.js rename to content/posts/nixcon2022/slides/plugin/math/math.js diff --git a/content/pages/nixcon2022/slides/plugin/math/mathjax2.js b/content/posts/nixcon2022/slides/plugin/math/mathjax2.js similarity index 100% rename from content/pages/nixcon2022/slides/plugin/math/mathjax2.js rename to content/posts/nixcon2022/slides/plugin/math/mathjax2.js diff --git a/content/pages/nixcon2022/slides/plugin/math/mathjax3.js b/content/posts/nixcon2022/slides/plugin/math/mathjax3.js similarity index 100% rename from content/pages/nixcon2022/slides/plugin/math/mathjax3.js rename to content/posts/nixcon2022/slides/plugin/math/mathjax3.js diff --git a/content/pages/nixcon2022/slides/plugin/math/plugin.js b/content/posts/nixcon2022/slides/plugin/math/plugin.js similarity index 100% rename from content/pages/nixcon2022/slides/plugin/math/plugin.js rename to content/posts/nixcon2022/slides/plugin/math/plugin.js diff --git a/content/pages/nixcon2022/slides/plugin/notes/notes.esm.js b/content/posts/nixcon2022/slides/plugin/notes/notes.esm.js similarity index 100% rename from content/pages/nixcon2022/slides/plugin/notes/notes.esm.js rename to content/posts/nixcon2022/slides/plugin/notes/notes.esm.js diff --git a/content/pages/nixcon2022/slides/plugin/notes/notes.js b/content/posts/nixcon2022/slides/plugin/notes/notes.js similarity index 100% rename from content/pages/nixcon2022/slides/plugin/notes/notes.js rename to content/posts/nixcon2022/slides/plugin/notes/notes.js diff --git a/content/pages/nixcon2022/slides/plugin/notes/plugin.js b/content/posts/nixcon2022/slides/plugin/notes/plugin.js similarity index 100% rename from content/pages/nixcon2022/slides/plugin/notes/plugin.js rename to content/posts/nixcon2022/slides/plugin/notes/plugin.js diff --git a/content/pages/nixcon2022/slides/plugin/notes/speaker-view.html b/content/posts/nixcon2022/slides/plugin/notes/speaker-view.html similarity index 100% rename from content/pages/nixcon2022/slides/plugin/notes/speaker-view.html rename to content/posts/nixcon2022/slides/plugin/notes/speaker-view.html diff --git a/content/pages/nixcon2022/slides/plugin/search/plugin.js b/content/posts/nixcon2022/slides/plugin/search/plugin.js similarity index 100% rename from content/pages/nixcon2022/slides/plugin/search/plugin.js rename to content/posts/nixcon2022/slides/plugin/search/plugin.js diff --git a/content/pages/nixcon2022/slides/plugin/search/search.esm.js b/content/posts/nixcon2022/slides/plugin/search/search.esm.js similarity index 100% rename from content/pages/nixcon2022/slides/plugin/search/search.esm.js rename to content/posts/nixcon2022/slides/plugin/search/search.esm.js diff --git a/content/pages/nixcon2022/slides/plugin/search/search.js b/content/posts/nixcon2022/slides/plugin/search/search.js similarity index 100% rename from content/pages/nixcon2022/slides/plugin/search/search.js rename to content/posts/nixcon2022/slides/plugin/search/search.js diff --git a/content/pages/nixcon2022/slides/plugin/zoom/plugin.js b/content/posts/nixcon2022/slides/plugin/zoom/plugin.js similarity index 100% rename from content/pages/nixcon2022/slides/plugin/zoom/plugin.js rename to content/posts/nixcon2022/slides/plugin/zoom/plugin.js diff --git a/content/pages/nixcon2022/slides/plugin/zoom/zoom.esm.js b/content/posts/nixcon2022/slides/plugin/zoom/zoom.esm.js similarity index 100% rename from content/pages/nixcon2022/slides/plugin/zoom/zoom.esm.js rename to content/posts/nixcon2022/slides/plugin/zoom/zoom.esm.js diff --git a/content/pages/nixcon2022/slides/plugin/zoom/zoom.js b/content/posts/nixcon2022/slides/plugin/zoom/zoom.js similarity index 100% rename from content/pages/nixcon2022/slides/plugin/zoom/zoom.js rename to content/posts/nixcon2022/slides/plugin/zoom/zoom.js diff --git a/content/pages/nixcon2022/slides/styles.css b/content/posts/nixcon2022/slides/styles.css similarity index 100% rename from content/pages/nixcon2022/slides/styles.css rename to content/posts/nixcon2022/slides/styles.css