From f4f77a6070fc5df9ba2c314d0a090f9bbb98dca2 Mon Sep 17 00:00:00 2001 From: Matthew Binning Date: Sat, 4 Apr 2026 11:48:33 -0700 Subject: [PATCH] feat!: Separate www into www/blog and www/private Now the private content is stored as a git submodule. This means I can keep that repo's source private, but still use it in the build product. The build product (website) relies on HTTP basic authentication, so access control is maintained throughout the SDLC. --- .forgejo/workflows/cd.yml | 9 +- .forgejo/workflows/ci.yml | 23 +- .forgejo/workflows/nightly.yml | 16 +- .gitignore | 8 +- .gitmodules | 3 + README.md | 32 +- book.toml | 3 - deploy.sh | 82 +- src/404.html | 218 ++ src/README.md | 17 + src/SUMMARY.md | 147 ++ src/book_reports/fasting_j_franklin.md | 248 +++ .../the_rust_programming_language.md | 1752 +++++++++++++++++ src/copper_chronicle.md | 1 + src/drafts/events/defcon.md | 5 + src/drafts/events/oktoberfest.md | 5 + src/drafts/faith.md | 3 + src/future_trips.md | 28 + src/menu.md | 61 + src/private | 1 + src/recipes/README.md | 1 + src/recipes/appetizers/README.md | 6 + .../appetizers/artichoke-spinach-dip.md | 21 + ...bacon-wrapped-goat-cheese-stuffed-dates.md | 14 + src/recipes/baked-goods/README.md | 9 + .../banana-chocolate-chip-bread.md | 13 + .../baked-goods/carrot-fig-macadamia-bread.md | 14 + .../chocolate-mint-protein-gunk-bars.md | 17 + .../baked-goods/purple-potato-pecan-bread.md | 13 + .../zucchini-and-chocolate-chip-bread.md | 13 + src/recipes/beverages/README.md | 8 + .../beverages/french-press-black-coffee.md | 13 + src/recipes/beverages/london-fog.md | 15 + src/recipes/beverages/milkshake.md | 11 + .../beverages/pour-over-black-coffee.md | 12 + src/recipes/breakfast/README.md | 8 + ...ble-sweet-potato-black-bean-ground-beef.md | 16 + src/recipes/breakfast/german-pancakes.md | 15 + .../pancake-fried-ham-runny-egg-avocado.md | 17 + .../protein-purple-potato-pancakes.md | 17 + src/recipes/camping/README.md | 14 + src/recipes/camping/cobblestacks-v2.md | 26 + .../curried-cashew-couscous-with-chicken.md | 9 + src/recipes/camping/jerky.md | 8 + src/recipes/camping/miso-salmon-and-rice.md | 8 + src/recipes/camping/protein-gunk.md | 14 + src/recipes/camping/shepherds-pie.md | 11 + src/recipes/camping/thanksgiving-meal.md | 11 + src/recipes/camping/veggie-bread.md | 12 + src/recipes/christmas/README.md | 7 + src/recipes/christmas/based-meatloaf.md | 12 + src/recipes/christmas/eggnog.md | 15 + .../gingerbread-fruitcake-muffins.md | 18 + src/recipes/desserts/README.md | 10 + .../desserts/chocolate-fat-bomb-cookies.md | 14 + src/recipes/desserts/mug-cakes.md | 4 + src/recipes/desserts/pumpkin-pie.md | 15 + src/recipes/desserts/red-wine-pears.md | 16 + ...d-peaches-with-honey-mint-and-ice-cream.md | 15 + src/recipes/desserts/ruby-cake.md | 13 + src/recipes/earth-day/README.md | 6 + src/recipes/earth-day/compote.md | 12 + src/recipes/earth-day/goat-root-stir-fry.md | 29 + src/recipes/fall/README.md | 9 + src/recipes/fall/butternut-squash-soup.md | 10 + .../fall/delicata-squash-with-parmesan.md | 8 + src/recipes/fall/miso-maple-acorn-squash.md | 14 + src/recipes/fall/roasted-kabocha-squash.md | 7 + .../fall/spiced-and-diced-sweet-potatoes.md | 9 + src/recipes/meals/README.md | 15 + src/recipes/meals/apple-salmon-salad.md | 10 + src/recipes/meals/greek-bowls.md | 10 + ...tloaf-purple-cabbage-slaw-parsnip-puree.md | 24 + .../meals/miso-oats-with-ground-beef.md | 8 + src/recipes/meals/pad-se-ew.md | 15 + src/recipes/meals/peanut-butter-chicken.md | 11 + .../pesto-chicken-and-spaghetti-squash.md | 9 + .../pistachio-encrusted-liver-burgers.md | 8 + src/recipes/meals/salmon-bowl.md | 8 + .../meals/steak-and-air-fried-broccoli.md | 8 + src/recipes/meals/sushi.md | 15 + src/recipes/misc/README.md | 28 + .../misc/balsamic-glazed-brussels-sprouts.md | 12 + src/recipes/misc/bone-broth.md | 18 + src/recipes/sides/README.md | 10 + src/recipes/sides/cabbage-steaks.md | 13 + src/recipes/sides/coconut-rice.md | 8 + src/recipes/sides/kale-dish.md | 9 + src/recipes/sides/roasted-vegetables.md | 8 + src/recipes/sides/stuffing.md | 10 + src/recipes/sides/vinaigrette.md | 12 + src/recipes/slow-cooker/README.md | 16 + .../balsamic-chicken-and-sausage.md | 9 + .../beef-kombucha-squash-red-curry.md | 10 + .../beef-shank-and-lentil-indian-curry.md | 10 + ...weet-yellow-curry-with-cauliflower-rice.md | 10 + .../slow-cooker/chicken-tortilla-soup.md | 13 + src/recipes/slow-cooker/gumbo.md | 13 + .../slow-cooker/lamb-roasted-roman-style.md | 10 + src/recipes/slow-cooker/oxtail-stew.md | 11 + ...ork-roast-or-ribs-with-butternut-squash.md | 9 + src/recipes/slow-cooker/pot-roast.md | 10 + src/recipes/slow-cooker/taco-soup.md | 12 + src/recipes/slow-cooker/turkey-chili.md | 12 + src/recipes/st-patricks-day/README.md | 10 + src/recipes/st-patricks-day/colcannon.md | 46 + .../st-patricks-day/corned-beef-2024.md | 14 + .../corned-beef-and-cabbage-2025.md | 14 + .../irish-green-milkshake-2025.md | 31 + .../irish-lamb-root-stew-2025.md | 14 + .../st-patricks-day/irish-soda-bread-2024.md | 14 + .../irish-whiskey-coffee-2024.md | 8 + src/reflections/celtic_camping.md | 24 + src/reflections/mycotoxins.md | 71 + src/reflections/stack_semantics.md | 33 + todo.txt | 8 +- 116 files changed, 3854 insertions(+), 118 deletions(-) create mode 100644 .gitmodules create mode 100644 src/404.html create mode 100644 src/README.md create mode 100644 src/SUMMARY.md create mode 100644 src/book_reports/fasting_j_franklin.md create mode 100644 src/book_reports/the_rust_programming_language.md create mode 100644 src/copper_chronicle.md create mode 100644 src/drafts/events/defcon.md create mode 100644 src/drafts/events/oktoberfest.md create mode 100644 src/drafts/faith.md create mode 100644 src/future_trips.md create mode 100644 src/menu.md create mode 160000 src/private create mode 100644 src/recipes/README.md create mode 100644 src/recipes/appetizers/README.md create mode 100644 src/recipes/appetizers/artichoke-spinach-dip.md create mode 100644 src/recipes/appetizers/bacon-wrapped-goat-cheese-stuffed-dates.md create mode 100644 src/recipes/baked-goods/README.md create mode 100644 src/recipes/baked-goods/banana-chocolate-chip-bread.md create mode 100644 src/recipes/baked-goods/carrot-fig-macadamia-bread.md create mode 100644 src/recipes/baked-goods/chocolate-mint-protein-gunk-bars.md create mode 100644 src/recipes/baked-goods/purple-potato-pecan-bread.md create mode 100644 src/recipes/baked-goods/zucchini-and-chocolate-chip-bread.md create mode 100644 src/recipes/beverages/README.md create mode 100644 src/recipes/beverages/french-press-black-coffee.md create mode 100644 src/recipes/beverages/london-fog.md create mode 100644 src/recipes/beverages/milkshake.md create mode 100644 src/recipes/beverages/pour-over-black-coffee.md create mode 100644 src/recipes/breakfast/README.md create mode 100644 src/recipes/breakfast/egg-scramble-sweet-potato-black-bean-ground-beef.md create mode 100644 src/recipes/breakfast/german-pancakes.md create mode 100644 src/recipes/breakfast/pancake-fried-ham-runny-egg-avocado.md create mode 100644 src/recipes/breakfast/protein-purple-potato-pancakes.md create mode 100644 src/recipes/camping/README.md create mode 100644 src/recipes/camping/cobblestacks-v2.md create mode 100644 src/recipes/camping/curried-cashew-couscous-with-chicken.md create mode 100644 src/recipes/camping/jerky.md create mode 100644 src/recipes/camping/miso-salmon-and-rice.md create mode 100644 src/recipes/camping/protein-gunk.md create mode 100644 src/recipes/camping/shepherds-pie.md create mode 100644 src/recipes/camping/thanksgiving-meal.md create mode 100644 src/recipes/camping/veggie-bread.md create mode 100644 src/recipes/christmas/README.md create mode 100644 src/recipes/christmas/based-meatloaf.md create mode 100644 src/recipes/christmas/eggnog.md create mode 100644 src/recipes/christmas/gingerbread-fruitcake-muffins.md create mode 100644 src/recipes/desserts/README.md create mode 100644 src/recipes/desserts/chocolate-fat-bomb-cookies.md create mode 100644 src/recipes/desserts/mug-cakes.md create mode 100644 src/recipes/desserts/pumpkin-pie.md create mode 100644 src/recipes/desserts/red-wine-pears.md create mode 100644 src/recipes/desserts/roasted-peaches-with-honey-mint-and-ice-cream.md create mode 100644 src/recipes/desserts/ruby-cake.md create mode 100644 src/recipes/earth-day/README.md create mode 100644 src/recipes/earth-day/compote.md create mode 100644 src/recipes/earth-day/goat-root-stir-fry.md create mode 100644 src/recipes/fall/README.md create mode 100644 src/recipes/fall/butternut-squash-soup.md create mode 100644 src/recipes/fall/delicata-squash-with-parmesan.md create mode 100644 src/recipes/fall/miso-maple-acorn-squash.md create mode 100644 src/recipes/fall/roasted-kabocha-squash.md create mode 100644 src/recipes/fall/spiced-and-diced-sweet-potatoes.md create mode 100644 src/recipes/meals/README.md create mode 100644 src/recipes/meals/apple-salmon-salad.md create mode 100644 src/recipes/meals/greek-bowls.md create mode 100644 src/recipes/meals/meatloaf-purple-cabbage-slaw-parsnip-puree.md create mode 100644 src/recipes/meals/miso-oats-with-ground-beef.md create mode 100644 src/recipes/meals/pad-se-ew.md create mode 100644 src/recipes/meals/peanut-butter-chicken.md create mode 100644 src/recipes/meals/pesto-chicken-and-spaghetti-squash.md create mode 100644 src/recipes/meals/pistachio-encrusted-liver-burgers.md create mode 100644 src/recipes/meals/salmon-bowl.md create mode 100644 src/recipes/meals/steak-and-air-fried-broccoli.md create mode 100644 src/recipes/meals/sushi.md create mode 100644 src/recipes/misc/README.md create mode 100644 src/recipes/misc/balsamic-glazed-brussels-sprouts.md create mode 100644 src/recipes/misc/bone-broth.md create mode 100644 src/recipes/sides/README.md create mode 100644 src/recipes/sides/cabbage-steaks.md create mode 100644 src/recipes/sides/coconut-rice.md create mode 100644 src/recipes/sides/kale-dish.md create mode 100644 src/recipes/sides/roasted-vegetables.md create mode 100644 src/recipes/sides/stuffing.md create mode 100644 src/recipes/sides/vinaigrette.md create mode 100644 src/recipes/slow-cooker/README.md create mode 100644 src/recipes/slow-cooker/balsamic-chicken-and-sausage.md create mode 100644 src/recipes/slow-cooker/beef-kombucha-squash-red-curry.md create mode 100644 src/recipes/slow-cooker/beef-shank-and-lentil-indian-curry.md create mode 100644 src/recipes/slow-cooker/chicken-sweet-yellow-curry-with-cauliflower-rice.md create mode 100644 src/recipes/slow-cooker/chicken-tortilla-soup.md create mode 100644 src/recipes/slow-cooker/gumbo.md create mode 100644 src/recipes/slow-cooker/lamb-roasted-roman-style.md create mode 100644 src/recipes/slow-cooker/oxtail-stew.md create mode 100644 src/recipes/slow-cooker/pork-roast-or-ribs-with-butternut-squash.md create mode 100644 src/recipes/slow-cooker/pot-roast.md create mode 100644 src/recipes/slow-cooker/taco-soup.md create mode 100644 src/recipes/slow-cooker/turkey-chili.md create mode 100644 src/recipes/st-patricks-day/README.md create mode 100644 src/recipes/st-patricks-day/colcannon.md create mode 100644 src/recipes/st-patricks-day/corned-beef-2024.md create mode 100644 src/recipes/st-patricks-day/corned-beef-and-cabbage-2025.md create mode 100644 src/recipes/st-patricks-day/irish-green-milkshake-2025.md create mode 100644 src/recipes/st-patricks-day/irish-lamb-root-stew-2025.md create mode 100644 src/recipes/st-patricks-day/irish-soda-bread-2024.md create mode 100644 src/recipes/st-patricks-day/irish-whiskey-coffee-2024.md create mode 100644 src/reflections/celtic_camping.md create mode 100644 src/reflections/mycotoxins.md create mode 100644 src/reflections/stack_semantics.md diff --git a/.forgejo/workflows/cd.yml b/.forgejo/workflows/cd.yml index fa7c6bf..2aa3626 100644 --- a/.forgejo/workflows/cd.yml +++ b/.forgejo/workflows/cd.yml @@ -8,7 +8,6 @@ on: required: true type: choice options: - - local - staging - prod @@ -19,7 +18,9 @@ jobs: - name: Download artifact uses: actions/download-artifact@v3 with: - name: site-${{ github.sha }} - path: blog/ + name: blog-${{ github.sha }} + path: book/ - name: Deploy - run: nix shell nixpkgs#rsync --command ./deploy.sh ${{ inputs.target }} + run: | + nix shell nixpkgs#rsync --command rsync -av --delete book/ /srv/www/binning.net/ + printf "✓ Local deployment complete!\n" \ No newline at end of file diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml index e599d3f..63258a7 100644 --- a/.forgejo/workflows/ci.yml +++ b/.forgejo/workflows/ci.yml @@ -8,11 +8,26 @@ jobs: runs-on: self-hosted steps: - uses: actions/checkout@v4 + with: + submodules: true - name: Build - run: nix shell nixpkgs#mdbook --command ./deploy.sh build + run: | + nix shell nixpkgs#mdbook --command mdbook build + printf "✓ Build complete!\n" - name: Upload artifact uses: actions/upload-artifact@v3 with: - name: site-${{ github.sha }} - path: blog/ - + name: blog-${{ github.sha }} + path: book/ + deploy: + runs-on: self-hosted + steps: + - name: Download artifact + uses: actions/download-artifact@v3 + with: + name: blog-${{ github.sha }} + path: book/ + - name: Deploy + run: | + nix shell nixpkgs#rsync --command rsync -av --delete book/ /srv/www/binning.net/ + printf "✓ Local deployment complete!\n" \ No newline at end of file diff --git a/.forgejo/workflows/nightly.yml b/.forgejo/workflows/nightly.yml index d898689..7ce7c12 100644 --- a/.forgejo/workflows/nightly.yml +++ b/.forgejo/workflows/nightly.yml @@ -10,12 +10,14 @@ jobs: steps: - uses: actions/checkout@v4 - name: Build - run: nix shell nixpkgs#mdbook --command ./deploy.sh build + run: | + nix shell nixpkgs#mdbook --command mdbook build + printf "✓ Build complete!\n" - name: Upload artifact uses: actions/upload-artifact@v3 with: - name: site-${{ github.sha }} - path: blog/ + name: blog-${{ github.sha }} + path: book/ deploy: @@ -25,7 +27,9 @@ jobs: - name: Download artifact uses: actions/download-artifact@v3 with: - name: site-${{ github.sha }} - path: blog/ + name: blog-${{ github.sha }} + path: book/ - name: Deploy - run: nix shell nixpkgs#rsync --command ./deploy.sh local + run: | + nix shell nixpkgs#rsync --command rsync -av --delete book/ /srv/www/binning.net/ + printf "✓ Local deployment complete!\n" diff --git a/.gitignore b/.gitignore index f66e219..d8fcb3e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -blog/ -src -content/* -example/* +# the build directory of mdbook +book/ +*.jpg +*.png \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..5ed5f5c --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "src/private"] + path = src/private + url = https://forgejo.binning.net/www/private diff --git a/README.md b/README.md index 2cb2fc5..d56df88 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,15 @@ -# WWW +# The Bin -Www is my personal website, blog project, and portfolio page. +This is my personal website, blog project, and portfolio page. It should be available at https://wwww.binning.dev # History -## 2025-02-28 - -I restarted this in [Rocket](https://rocket.rs) after yet another data loss event. - -## 2024-06-21 - -I migrated from cgit to forgejo and from kuberentes to simply nginx. - -## 2023-10-07 - -I merged the deployment repository into this one. -I also moved to self-hosting at some point. - -## 2022-01-05 - -I moved hosting to Vultr and moved to a Cobalt. -One neat command to unhide files was: - -`for i in \.*; do if [ ${i} != '.' ] && [ ${i} != '..' ]; then mv {.,}${i/\./} ; fi; done;` - -## 2018-12-16 - -I started this blog with [Namecheap][Namecheap], [Ruby][Ruby], [Jekyll][Jekyll], and [Github-Pages][Github-Pages]. +- 2025-02-28: I restarted this in [Rocket](https://rocket.rs) after yet another data loss event. +- 2024-06-21: I migrated from cgit to forgejo and from kuberentes to simply nginx. +- 2023-10-07: I merged the deployment repository into this one and moved to self-hosting. +- 2022-01-05: I moved hosting to Vultr and moved to a Cobalt. +- 2018-12-16: I started this blog with [Namecheap][Namecheap], [Ruby][Ruby], [Jekyll][Jekyll], and [Github-Pages][Github-Pages]. [Namecheap]: https://www.namecheap.com/ [Ruby]: https://www.ruby-lang.org/ diff --git a/book.toml b/book.toml index f5e7abf..92063b1 100644 --- a/book.toml +++ b/book.toml @@ -3,9 +3,6 @@ title = "The Bin" authors = ["Matthew Binning"] language = "en" -[build] -build-dir = "blog" - [output.html] default-theme = "rust" smart-punctuation = true diff --git a/deploy.sh b/deploy.sh index f329ca7..bb8283c 100755 --- a/deploy.sh +++ b/deploy.sh @@ -2,75 +2,21 @@ set -e -usage() { - printf "Usage: %s [build|staging|prod|local]\n\n build - Build the blog with mdbook\n staging - Deploy to local staging environment (/srv/www/stage.binning.net)\n prod - Deploy to production server via SSH (www.binning.net)\n local - Deploy directly to /srv/www/binning.net (used by Forgejo CI runner)\n\nExample:\n %s build\n %s staging\n %s prod\n %s local\n" "$0" "$0" "$0" "$0" "$0" - exit 1 -} +printf "Deploying to PRODUCTION environment...\n" -if [ $# -eq 0 ]; then - printf "Error: No command specified\n" - usage +REMOTE_HOST="crossbox" +REMOTE_USER="brimlock" +REMOTE_PATH="/srv/www/binning.net" + +if ! ssh -o BatchMode=yes -o ConnectTimeout=5 ${REMOTE_USER}@${REMOTE_HOST} exit 2>/dev/null; then + printf "Warning: SSH connection test failed. Ensure SSH keys are configured.\nYou may be prompted for a password.\n" fi -CMD=$1 +printf "Deploying website files...\n" +ssh ${REMOTE_USER}@${REMOTE_HOST} "mkdir -p /tmp/blog-deploy" +rsync -avz --delete blog/ ${REMOTE_USER}@${REMOTE_HOST}:/tmp/blog-deploy/ +ssh ${REMOTE_USER}@${REMOTE_HOST} "sudo rsync -avz --delete /tmp/blog-deploy/ ${REMOTE_PATH}/ && \ + sudo chown -R nginx:nginx ${REMOTE_PATH}/ && \ + printf 'Content deployed.\n'" -case $CMD in - build) - printf "Building blog with mdbook...\n" - [ -s src ] || ln -s /var/lib/www src - mdbook build - printf "✓ Build complete!\n" - ;; - - staging) - printf "Deploying to STAGING environment...\n" - - STAGING_PATH="/srv/www/stage.binning.net" - - sudo mkdir -p ${STAGING_PATH} - - printf "Deploying website files...\n" - sudo rsync -av --delete blog/ ${STAGING_PATH}/ - - sudo chown -R nginx:nginx ${STAGING_PATH}/ - - printf "✓ Staging deployment complete!\n Files deployed to: %s\n\nTo activate nginx, import staging.nginx.nix into your local NixOS config\nand run: sudo nixos-rebuild switch\n" "${STAGING_PATH}" - ;; - - prod) - printf "Deploying to PRODUCTION environment...\n" - - REMOTE_HOST="crossbox" - REMOTE_USER="brimlock" - REMOTE_PATH="/srv/www/binning.net" - - if ! ssh -o BatchMode=yes -o ConnectTimeout=5 ${REMOTE_USER}@${REMOTE_HOST} exit 2>/dev/null; then - printf "Warning: SSH connection test failed. Ensure SSH keys are configured.\nYou may be prompted for a password.\n" - fi - - printf "Deploying website files...\n" - ssh ${REMOTE_USER}@${REMOTE_HOST} "mkdir -p /tmp/blog-deploy" - rsync -avz --delete blog/ ${REMOTE_USER}@${REMOTE_HOST}:/tmp/blog-deploy/ - ssh ${REMOTE_USER}@${REMOTE_HOST} "sudo rsync -avz --delete /tmp/blog-deploy/ ${REMOTE_PATH}/ && \ - sudo chown -R nginx:nginx ${REMOTE_PATH}/ && \ - printf 'Content deployed.\n'" - - printf "✓ Production deployment complete!\n\nNginx configuration is managed by the nixos-config flake (hosts/crossbox/nginx.nix).\n" - ;; - - local) - printf "Deploying locally to production path...\n" - - LOCAL_PATH="/srv/www/binning.net" - - printf "Deploying website files...\n" - rsync -av --delete blog/ ${LOCAL_PATH}/ - - printf "✓ Local deployment complete!\n Files deployed to: %s\n" "${LOCAL_PATH}" - ;; - - *) - printf "Error: Invalid command '%s'\n" "$CMD" - usage - ;; -esac +printf "✓ Production deployment complete!\n\nNginx configuration is managed by the nixos-config flake (hosts/crossbox/nginx.nix).\n" \ No newline at end of file diff --git a/src/404.html b/src/404.html new file mode 100644 index 0000000..88405f1 --- /dev/null +++ b/src/404.html @@ -0,0 +1,218 @@ + + + + + + Page not found - The Copper Chronicle + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+
+

Document not found (404)

+

This URL is invalid, sorry. Please use the navigation bar or search to continue.

+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + +
+ + diff --git a/src/README.md b/src/README.md new file mode 100644 index 0000000..2dd2da6 --- /dev/null +++ b/src/README.md @@ -0,0 +1,17 @@ +# Welcome + +Welcome to my personal website, blog, and landing page for other self-hosted software. This website serves as a space to share musings, stories, and chronicles, about all of those things. + +![cover photo](cover-photo.jpg) + +## About + +My name is Matt. I am a software engineer living in the West. My interests include software, defense, EW, drones, and data security and privacy. Other personal interests of mine include linguistics, philosophy, and theology, to name a few. + +## Genealogy + +The title of this website you may recognize as a surname. I am also interested in family history and genealogy. If you have some relation or interest to this surname, please feel free to reach out. I am planning a genealogical project. + +## Contact + +**Email:** matthew@binning.net diff --git a/src/SUMMARY.md b/src/SUMMARY.md new file mode 100644 index 0000000..c310eb0 --- /dev/null +++ b/src/SUMMARY.md @@ -0,0 +1,147 @@ +# The Bin + +[Welcome](README.md) + +--- + +# Blog + +- [Reflections]() + - [Celtic Camping](reflections/celtic_camping.md) + - [On Mycotoxins](reflections/mycotoxins.md) + - [Stack Semantics](reflections/stack_semantics.md) +- [Events]() + - [Future Trips](future_trips.md) +- [Book Reports]() + - [Deep Work](book_reports/deep_work.md) + - [The Rust Programming Language](book_reports/the_rust_programming_language.md) + +--- + +# Cooking + +- [Menu](menu.md) +- [Cookbook](recipes/README.md) + - [Beverages](recipes/beverages/README.md) + - [Pour-Over Black Coffee](recipes/beverages/pour-over-black-coffee.md) + - [London Fog](recipes/beverages/london-fog.md) + - [French Press Black Coffee](recipes/beverages/french-press-black-coffee.md) + - [Milkshake](recipes/beverages/milkshake.md) + - [Appetizers](recipes/appetizers/README.md) + - [Artichoke Spinach Dip](recipes/appetizers/artichoke-spinach-dip.md) + - [Bacon Wrapped Dates](recipes/appetizers/bacon-wrapped-goat-cheese-stuffed-dates.md) + - [Baked Goods](recipes/baked-goods/README.md) + - [Banana Chocolate Chip Bread](recipes/baked-goods/banana-chocolate-chip-bread.md) + - [Chocolate Mint Protein Gunk Bars](recipes/baked-goods/chocolate-mint-protein-gunk-bars.md) + - [Zucchini and Chocolate Chip Bread](recipes/baked-goods/zucchini-and-chocolate-chip-bread.md) + - [Carrot, Fig, Macadamia Bread](recipes/baked-goods/carrot-fig-macadamia-bread.md) + - [Purple Potato, Pecan Bread](recipes/baked-goods/purple-potato-pecan-bread.md) + - [Breakfast](recipes/breakfast/README.md) + - [German Pancakes](recipes/breakfast/german-pancakes.md) + - [Pancake, Fried Ham, Runny Egg, & Avocado](recipes/breakfast/pancake-fried-ham-runny-egg-avocado.md) + - [Egg Scramble](recipes/breakfast/egg-scramble-sweet-potato-black-bean-ground-beef.md) + - [Proplto Pancakes](recipes/breakfast/protein-purple-potato-pancakes.md) + - [Meals](recipes/meals/README.md) + - [Meatloaf, Purple Cabbage Slaw, & Parsnip Puree](recipes/meals/meatloaf-purple-cabbage-slaw-parsnip-puree.md) + - [Pistachio Liver Burgers](recipes/meals/pistachio-encrusted-liver-burgers.md) + - [Greek Bowls](recipes/meals/greek-bowls.md) + - [Miso Oats with Ground Beef](recipes/meals/miso-oats-with-ground-beef.md) + - [Salmon Bowl](recipes/meals/salmon-bowl.md) + - [Pad Se Ew](recipes/meals/pad-se-ew.md) + - [Sushi](recipes/meals/sushi.md) + - [Pesto Chicken and Spaghetti Squash](recipes/meals/pesto-chicken-and-spaghetti-squash.md) + - [Steak & Air-Fried Broccoli](recipes/meals/steak-and-air-fried-broccoli.md) + - [Apple Salmon Salad](recipes/meals/apple-salmon-salad.md) + - [Peanut Butter Chicken](recipes/meals/peanut-butter-chicken.md) + - [Sides](recipes/sides/README.md) + - [Stuffing](recipes/sides/stuffing.md) + - [Vinaigrette](recipes/sides/vinaigrette.md) + - [Kale Dish](recipes/sides/kale-dish.md) + - [Roasted Vegetables](recipes/sides/roasted-vegetables.md) + - [Cabbage Steaks](recipes/sides/cabbage-steaks.md) + - [Coconut Rice](recipes/sides/coconut-rice.md) + - [Slow Cooker](recipes/slow-cooker/README.md) + - [Beef Kombucha Squash Red Curry](recipes/slow-cooker/beef-kombucha-squash-red-curry.md) + - [Balsamic Chicken and Sausage](recipes/slow-cooker/balsamic-chicken-and-sausage.md) + - [Pot Roast](recipes/slow-cooker/pot-roast.md) + - [Chicken Sweet Yellow Curry](recipes/slow-cooker/chicken-sweet-yellow-curry-with-cauliflower-rice.md) + - [Beef Shank and Lentil Indian Curry](recipes/slow-cooker/beef-shank-and-lentil-indian-curry.md) + - [Pork Roast or Ribs with Butternut Squash](recipes/slow-cooker/pork-roast-or-ribs-with-butternut-squash.md) + - [Gumbo](recipes/slow-cooker/gumbo.md) + - [Lamb Roasted Roman Style](recipes/slow-cooker/lamb-roasted-roman-style.md) + - [Taco Soup](recipes/slow-cooker/taco-soup.md) + - [Turkey Chili](recipes/slow-cooker/turkey-chili.md) + - [Chicken Tortilla Soup](recipes/slow-cooker/chicken-tortilla-soup.md) + - [Oxtail Stew](recipes/slow-cooker/oxtail-stew.md) + - [Desserts](recipes/desserts/README.md) + - [Ruby Cake](recipes/desserts/ruby-cake.md) + - [Pumpkin Pie](recipes/desserts/pumpkin-pie.md) + - [Roasted Peaches](recipes/desserts/roasted-peaches-with-honey-mint-and-ice-cream.md) + - [Red Wine Pears](recipes/desserts/red-wine-pears.md) + - [Chocolate Fat Bomb Cookies](recipes/desserts/chocolate-fat-bomb-cookies.md) + - [Mug Cakes](recipes/desserts/mug-cakes.md) + - [Seasonal](recipes/fall/README.md) + - [Miso Maple Acorn Squash](recipes/fall/miso-maple-acorn-squash.md) + - [Delicata Squash with Parmesan](recipes/fall/delicata-squash-with-parmesan.md) + - [Roasted Kabocha Squash](recipes/fall/roasted-kabocha-squash.md) + - [Butternut Squash Soup](recipes/fall/butternut-squash-soup.md) + - [Spiced and Diced Sweet Potatoes](recipes/fall/spiced-and-diced-sweet-potatoes.md) + - [Eggnog](recipes/christmas/eggnog.md) + - [Gingerbread Fruitcake Muffins](recipes/christmas/gingerbread-fruitcake-muffins.md) + - [Based Meatloaf](recipes/christmas/based-meatloaf.md) + - [Corned Beef and Cabbage](recipes/st-patricks-day/corned-beef-and-cabbage-2025.md) + - [Corned Beef](recipes/st-patricks-day/corned-beef-2024.md) + - [Irish Lamb Root Stew](recipes/st-patricks-day/irish-lamb-root-stew-2025.md) + - [Irish Soda Bread](recipes/st-patricks-day/irish-soda-bread-2024.md) + - [Irish Green Milkshake](recipes/st-patricks-day/irish-green-milkshake-2025.md) + - [Irish Whiskey Coffee](recipes/st-patricks-day/irish-whiskey-coffee-2024.md) + - [Goat Root Stir Fry](recipes/earth-day/goat-root-stir-fry.md) + - [Compote](recipes/earth-day/compote.md) + - [Camping](recipes/camping/README.md) + - [Cobblestacks v2](recipes/camping/cobblestacks-v2.md) + - [Shepherd's Pie](recipes/camping/shepherds-pie.md) + - [Curried Cashew Couscous with Chicken](recipes/camping/curried-cashew-couscous-with-chicken.md) + - [Miso Salmon & Rice](recipes/camping/miso-salmon-and-rice.md) + - [Thanksgiving Meal](recipes/camping/thanksgiving-meal.md) + - [Jerky](recipes/camping/jerky.md) + - [Veggie Bread](recipes/camping/veggie-bread.md) + - [Protein Gunk](recipes/camping/protein-gunk.md) + - [Miscellaneous](recipes/misc/README.md) + - [Balsamic Glazed Brussels Sprouts](recipes/misc/balsamic-glazed-brussels-sprouts.md) + - [Bone Broth](recipes/misc/bone-broth.md) + +--- + +# 🔒 Authentication Required + +- [The Copper Chronicle](copper_chronicle.md) + - [2024]() + - [Prelude](private/copper-chronicle/chapter_0/index.md) + - [Big Sur Adventure](private/copper-chronicle/chapter_1/big_sur.md) + - [📷 Big Sur Photos](private/copper-chronicle/chapter_1/photos.md) + - [San Luis Obispo](private/copper-chronicle/chapter_2/san_luis_obispo.md) + - [Her Birthday](private/copper-chronicle/chapter_3/her_birthday.md) + - [📷 Independence Day](private/copper-chronicle/chapter_4/independence_day.md) + - ["Mundane" Date]() + - [A Beach Wedding]() + - [Apple Hill](private/copper-chronicle/chapter_apple_hill/index.md) + - [Dove Hunting](private/copper-chronicle/chapter_7/dove_hunting.md) + - [📷 Dove Hunting Photos](private/copper-chronicle/chapter_7/photos.md) + - [Scouting](./chapter_7/scouting.md) + - [Frog Water](./chapter_7/frog_water.md) + - [Dragon's Milk](./chapter_7/dragons_milk.md) + - [Retrospective](./chapter_7/retrospective.md) + - [📷 Shasta & Dunsmuir](private/copper-chronicle/chapter_8/shasta_trip.md) + - [A Russian Wedding]() + - [Candlelight Concert](./chapter_10/README.md) + - [Thanksgiving](private/copper-chronicle/chapter_thanksgiving/index.md) + - [Melodrama](private/copper-chronicle/chapter_melodrama/index.md) + - [2025]() + - [New Years](private/copper-chronicle/2025_new_years/index.md) + - [Saint Patrick's Day](private/copper-chronicle/2025_saint_patricks/index.md) + - [May](private/copper-chronicle/2025_may/index.md) + - [Matheney Reunion](private/copper-chronicle/2025_matheney_reunion/index.md) + - [2026]() + - [Mission Family Statement](private/copper-chronicle/mission_family_statement.md) + - [ROM](private/copper-chronicle/ROM.md) +- [Resume](private/resume.md) diff --git a/src/book_reports/fasting_j_franklin.md b/src/book_reports/fasting_j_franklin.md new file mode 100644 index 0000000..87700c5 --- /dev/null +++ b/src/book_reports/fasting_j_franklin.md @@ -0,0 +1,248 @@ +# Synthesis of Fasting by J. Franklin + +## Practice of Fasting + +### How to Fast + +Taper off food intake when preparing. +Try to drink at least 1 gal of purified water throughout the first day. + +**Remain modest (or in secret) while fasting.** (Matthew 6:1-18) +Basically, virtue signaling like the pharisees takes away all blessing from it. + +Humble yourself rather than give a performance of strife, anger, and lashing out. +This may mean taking responsibility, praying for protection and healing, even protection from oneself, and repenting for mistakes and sins, and wrongheadedness. + +Enter a fast having repented of any known sins. +Fasting will bring even hidden things to the surface so you can repent. + +**Combine fasting with prayer and reading the Word.** +Fasting is a continual prayer. + +Fast from coffee for 40 days, then see what addiction remains. + +#### Fasting and Mourning + +> Men and beast wore sackcloth while fasting and cried mightily to God as part of repentance. +> -John 3:7-9 + +"Mourn" and "fast" are interchangeable in the bible (maybe somewhat). +_Citation is needed here._ + +**Fast for a specific purpose.** +The focus of fasting is on God and "lovesickness" for Him rather than our own physical needs or what we stand to gain. + +**While fasting, pray and focus on the needs of others.** +Prayer that goes along with fasting is a time to "press into God". + +Fast especially for the "little ones" (children), or probably anyone vulnerable, especially in wicked times. + +**Fast for a member of the family (or friend) if something is/has gone wrong with/for them.** +This is what a church might do. + +_Is it worth considering just wearing a plain white T-shirt and jeans, as some equivalent to sackcloth?_ + +#### Monitoring + +> There is nothing more worrisome than fasting. + +> Fasting is easier with grace. + +**Monitor how you are doing, and pray about it.** + +> If you want to please God, believe God. + +> Faith and patience must go together. + +**Pray about it, believe the promises, and have patience.** +We do not need even much faith for miracles, only as _small_ as a mustard seed. (Matt 17:20) +Christ said so, and though Peter had little faith, with that he was able to walk on water for a time. + +### When to Fast + +**Fast all day before church to sensitize oneself to church.** + +**Fast at the beginning of the year to set the tone for the rest of the year.** +This is like giving the first part to God of every day, week, dollar, and consideration in decisions. +This is Matt 6:33 -- Seek _first_ the Kingdom... +Know that there is never a convenient time to fast. + +## Types of Fasts + +Scripture has: +- Absolute: taking in nothing, including water. +- Normal: no food for some amount of days. Clear broth and juices may be allowed. +- Partial: usually certain foods or drinks for an extended period of time. +- Daniel: eliminate meats, breads, and sweets for 21 days. + +Significant lengths in the Bible are 3, 7, 21, and 40 days. +Half day and full day are also seen. + +## Beyond Fasting + +Fasting is only one tool or step in the process of [[#sanctification]]. + +But a man is the priest of his home and has many duties and pursuits. + +**Exercise sanctification daily** by _practicing purity_ and being _set apart from the world and from sin_. + +> Exhort one another daily to not fall to a hardened heart by sin and depart from God due to an evil heart of unbelief. +> -Heb 3:12-13 + +This implies: + +**Surround yourself with a desirable and motivating community.** +**Exhort and ask to be exhorted.** +**Pray with purpose and for exhortation from God in the mornings.** + +## Purpose of Fasting + +### Physical + +#### Healing + +**Howbeit this kind goeth not out but by prayer and fasting** Matthew 17:20-21 +Matthew 17:20 - With this, nothing is impossible. + +Isaiah 58:8 - Healing will follow fasting. + +Water is the flushing agent. +Urine turns darker. +Impurities and poisons are "burnt for energy". +Headaches are a sign that fasting was/is needed. + +Cognition and senses improve. +Addictions are broken. + +Chronic or severe health conditions can improve with long fasts. +There is an allegory of Christ's fasting for 40 days: +Flies represent demons, and cancer and mold may represent corruption. +Flies' life cycles range from 1 to 40 days. +To utterly destroy them, you have to spray pesticides for 40 days. + +#### Poverty Mitigation + +Fasting mitigates poverty, probably by saving time on cooking, eating, doing dishes, cleaning, cutting out grocery expenses, and other un-necessities. + +Fasting breaks us from routine. + +Fasting helps you discern what you need from what you want. + +Fasting can end demonic attacks and break generational curses -- By this, the author means we can give ourselves space and time to disrupt our self-destructive patterns that harm us generationally. + +### Spirtual + +Worry more about your spirit than about food or clothing. (Matt 6:25) + +#### Sensitization + +Fasting is useful in getting direction from God. +Fasting in increasing sensitivity allows us to hear "secrets", i.e. plans, secrets, and knowledge of God. + +Among the trinity, fasting increases closeness with the Holy Spirit. +Fasting makes one particularly more sensitive to the timing and voice of the Holy Spirit. + +As in Mark 2:22, fasting is what renews our bodies as wineskins. +It follows that the blood of Christ is the new wine. + +Matthew 6 -- God rewards openly for praying, fasting, and giving. +Ecclesiastes 4:12 - Solomon describes this as the _threefold chord_ of prayer, fasting, and giving. + +Fasting gets us away from our own desires that we might know His. +As you fast, it becomes less about you. + +#### Worship + +Fasting is a continual form of worship, and an offering of oneself as a living sacrifice. See ROM 12:1 +Worship, as in fasting, magnifies God and so reduces the apparent size of your problems. + +We need to stop measuring our God by the size of our problems, and instead by how great He is. + +#### The Mind + +It also allows you to release unforgiveness and bitterness. + +Mutual assurance/care while fasting for others fulfills the Law of Christ and is corrective to pride. (Gal 6:1-3) +However, one must be trained with tender hands. + +Fasting positions us and prepares us for what is to come. + +Fasting sharpens the Word in your heart and on your tongue. + +One may not walk into all His promises at once, but over time. + +#### Addictions + +Fasting also helps break sexual addictions and perversions. +One mechanism is probably related to lowering sex drive. + +#### Sanctification + +Sanctification is the process of becoming more holy or Christlike. +Theologically, it is allowing the Holy Spirit to make us more Christlike in what we do, think, and desire. + +> If God has blessed your life, you are in critical need of sanctification. + +Over time after initial acceptance of Christ, complacency and hidden sins build up. +If we are to see God's wonders, like the Israelites toward the Promised Land, we must confront sin in our lives and live holy. + +Fasting is an essential means of sanctification, or pulling yourself away from the world. +It filters your life, between serving the spirit and serving "the flesh" (Gal 5:19-21). +In other words, it cuts away dead things and hidden sins, i.e. circumcision of the heart. + +## Spiritual Premises for Fasting + +Matthew 5:6 - Spiritual "hunger" and "thirst" are mentioned in-place of earthly eating and drinking in scripture. +This is fasting. + +Jesus fasted despite having power, because some supernatural release happens with it. +Luke 5:34-35 - then they will fast in those days (when Jesus is taken away). + +Jesus never healed anyone until after he fasted 40 days. + +Matt 26:29 - Technically Christ is fasting until the end times, when he drinks with us in His Father's Kingdom. + +Acts 10:30-31 - Fasting is what opened the door (in part) to the gentiles via Cornelius. + +> To loose the bonds of wickedness +> -Isa 58:6-7 + +By making do with less, we become less dependent on the world's offerings and demands, and so we shrink/thin, and the shackles loosen. + +### Gluttony + +Our stomachs are metaphorically the bottomless pit. +Heb 12:15-17 -- Esau lost his birthright partly due to hunger and not fasting. + +### Manna + +Manna apparently was perfectly balanced, so that there was not one sick or feeble person among them for 40 years. +Despite this, people were not content. + +Kibroth Hattaavah was the result, where quail was sent and people grew sick on it. + +## Trivia + +TODO: Revise this with See Also + +John 14:30 - Christ points out that the enemy is the ruler of this world, but he is apart from him. +40 represents cleansing and purifying. +"Revival" includes in Joel 2:28 prophesying, dreaming dreams, and seeing visions. +Heb 4:16 - the throne of grace is a canonical object. +Heb 411:13 - " division of soul and spirit" +2 Chronicles 7:14 - about healing, including prayer in the process (but not fasting) +Ps 24:3-4 - This is God's place because he is so far above us. But we think to put ourselves there because our casual ego blinds us. +Heb 11:5 - God translated Enoch. +Heb 11:16 - You must believe that God is a rewarder. +Jude 14-15 - Enoch did not try to please people. + +## See Also + +101 Reasons to Fast - Bob Rodgers +Toxic Relief - Don Colbert +Dr. Tanner was supposedly someone who had miraculous transformations with long fasts. +Children of light - Eph 5:8-10 +The World Hunger Movement has a program called " Let it Growl". +The Hall of Faith is another canonical object. +"God is no respecter of persons." +Healing evangelists include Smith Wigglesworth. (A.C. Had a book of his.) diff --git a/src/book_reports/the_rust_programming_language.md b/src/book_reports/the_rust_programming_language.md new file mode 100644 index 0000000..d33758f --- /dev/null +++ b/src/book_reports/the_rust_programming_language.md @@ -0,0 +1,1752 @@ +# The Rust Programming Language + +These are my notes as I go through the main Rust book. + +My goal is that these notes be a "living" document. +As I program more and more in Rust, I will update these notes. +I will remove the obvious stuff people can grasp quickly. +I will then add more info on nuances I uncover. + +## 1 Getting Started + +https://doc.rust-lang.org/book/ + +These are the interesting tidbits that stand out from the book. + +Rust is an "expression based" language. +File extension is .rs. + +rustc +rustfmt +rustdoc + +## 2 Programming a Guessing Game + +This introduces a basic REPL. + +Why is `std::cmp::Ordering` used for basic comparison of numbers? + +### `.expect()` and `Result` + +`Result`is a type-parameterized enum. +These kinds of enums have variants of `Ok` and `Err`. +`.expect()` may be called on a `Result` type. +This will either unwrap it or fail with a message. + +`{var}` is the "crab pincer" syntax for `println!` + +## 3 Common Programming Concepts + +### 3.1 Variables and Mutability + +`const` is basically `constexpr`; its value/definition must be known at compile time. +Normal variables are constants (immutable). +`mut` are "normal", mutable variables. + +#### Variable Types + +##### Mutable + +`let mut = ` for a variable proper + +##### Immutable + +`let = ` for an immutable. +These are clutch in applying transformations through shadowing. + +##### Constants + +Compared to variables (even immutable), constants can only be set to a constant expression, and they can be declared in any scope. + +Shadowing lets you: + +1. Reuse names. +2. Hide values in higher-scopes when you might be using a value derived from it in a narrower scope. +3. "Change" the type of the variable (cannot do this by mutating a variable). +4. Basically mutate it, but it is explicit, and it becomes implicitly immutable again immediately. + +### 3.2 Data Types + +`isize` and `usize` are word-length for the compile target's architecture. + +A byte literal `b'A'` is specifically for u8 bytes. + +When compiled with `--release`, integers will overflow. +Otherwise the program panics. +Overflowing can be handled differently with methods: + +- `wrapping_*` +- `checked_*` +- `overflowing_*` +- `saturating_*` + +Rust's `char` is 4 bytes and represents a Unicode scalar value. +It ranges from `U+0000` to `U+D7FF` and `U+E000` to `U+10FFFF` inclusive. + +#### Ranges + +inclusive-exclusive: `START...END` +inclusive-inclusive: `START...=END` + +#### Tuples + +Tuples are a primitive, compound type and allow destructuring. +Indexing is also possible with a dot operator. +```rust +let tup = (1, 2.0, false); +let (x, y, z) = tup; +let y = tup.0; +``` + +The `()` empty tuple is called _unit_. +This is like `void` in that it is returned implicitly if there are no other returns. + +#### Arrays + +Arrays are defined on the stack and have a fixed length. +Otherwise you will need a vector. + +Arrays can be initialized either as `[type; length]` or `[value; length]` with +the latter's value being repeated. + +### 3.3 Functions + +Parameters must have a type annotation. +`fn foo(some_var : i32){}` + +Expressions' return value is their final expression. + +```Rust +{ + let x = 2; + x + 6 +} // returns 8 +``` + +Of course, these are used as function bodies. + +### 3.4 Comments + +`//` comments can be inline. +`///` are documentation comments (Markdown-ready which compile to HTML through Cargo). +Panics, Errors, Safety, and Examples are common headings. +`//!` adds commentary to the containing item (such as a crate or module) rather than the below piece of code. + +### 3.6 Macros + +`fn foo!(){}` + +`dbg!()` is a useful macro to print debug information of arguments and simultaneously return ownership. + +### 3.5 Control Flow + +`if` is an expression (with "arms" like match) so it may be used as a ternary. +`let number = if condition { 5 } else { 6 };`. +Because of this, all arms must return the same type. + +#### Loops + +`loop`, `while`, and `for` +`for` is basically an enhanced for loop in C/++. + +```Rust + [expression] { + ; {STATEMENTS}... +} +``` + +Loops can have labels. + +```Rust +'label: loop { + +} +``` + +You can break on these so to not break on the innermost loop. + +`break 'label;` + +You can return a value to make a loop an expression on a break. + +`break some_val;` + +With `loop`s, a value may be added to the end of the `break` statement to return a value. +This means the loop is an expression and can be assigned from. + +Loops may have labels `'label: loop { ...; break 'label; }` to specify non-innermost breaks. + +`while` loops are also available. + +`for` loops are more like C++ enhanced for loops. + +They're also like Python for loops with a range type. +Ranges are provided by the standard library and apparently the literal looks like `(x..y)`. + +## 4 Understanding Ownership + +### 4.1 What is Ownership? + +String literals are on the stack, but `String`s are allocated to the heap. +Thus string literals are constexpr, basically. +Because Strings are on the heap, `String::push_str(self, str)` is the name of the appending function. + +**Memory is automatically returned once the variable that owns it goes out of scope.** +This pattern is called RAII (resource acquisition is initialization) in C++. +The actual "free" function called in rust at the end of scope is called `drop`. +This means there must be only one "owner". + +Double free error: Another pointer to the same data on a heap goes out of scope. + +Assigning one variable to another is actually an ambiguous operation. + +On the heap: + +Instead of `shallow copy`s (copying structured data and pointer values), rust performs `move`s. +The first variable becomes invalidated. +Rust never automatically performs deep copies (`clone()`) which would copy all member pointers blocks of memory. +Some data implements `Clone` though, then `.clone()` will perform a deep copy. + +stack-only data: + +If all data is on the stack, there is no difference between a deep and shallow copy. +Thus, if stack-only data implements `copy()`, no `move` occurs, just copy semantics. +The primitives types and tuples of only primitives implement the Copy trait. + +#### Ownership and Functions + +Passing arguments to parameters uses the exact same ambiguous semantics as variable assignments. + +If anything is moved in rather than copied in, the drop at the end of the function scope could be problematic. +You _could_ return a tuple with the extra values of anything moved in to move it back out. +That's "too much ceremony" though, so you get references. + +### 4.2 References and Borrowing + +You can have as many immutable references to a variable as you like. +Once you have an immutable reference, that's the only reference you can have of it for the remainder of its scope. + +A scope of a reference ends with its last usage, so a scope is not strictly a syntactic block. It can be confusingly more forgiving. + +### 4.3 The Slice Type + +A "string slice" is `&str` and the literal looks like `&s[0..len]`. +The inclusive beginning and exclusive ending can be omitted, i.e. `&s[..]`. +Indices can be variables, e.g. `&s[2..i]`. + +Immutable borrows of slices help ensure that the underlying data is not mutated later. +This is as opposed to calculating some index and storing it in an unrelated variable. + +Slicing can be performed on either `&String` or string slices `&str`. +Deref coercion can implicitly convert a string reference to a string slice. + +References to strings are equivalent to whole slices of strings. +String literals are string slices. + +There is a type for a general slice of a collection. +It has a type of the form `&[i32]`. + +One can take a slice of a string or an array. +A string slice is `&str` (not to be confused with the more specialized &String). + +An array slice type is something like `&[i32]`. +An array slice literal is something like `&a[1..3]` + +### 4.4 Cloning + +Copying stack allocations (most primitives) gives you a copy. +Copying heap allocations (boxes/pointers) gives you a shallow copy. +It also _invalidates_ the original copy. +To do a deep copy, call `.clone()`. + +## 5 Using Structs to Structure Related Data + +_Field Init Shorthand_ lets us pass arguments that match the name of a struct field without specifying the struct field. + +```Rust +fn factory(some_field : fieldType) -> Some_Struct { + Some_Struct { + some_field, + some_field2 : some_field_other, + } +}; +``` + +_Struct update syntax_ lets us create a struct by specifying a struct to base the rest of the values on (after explicitly setting some values). +This syntax will move or copy individual fields to the new struct, so some fields of the old struct may become unusable. + +```rust +let another_struct = Some_Struct { + field1 : val1 + ..old_struct +}; +``` + +Tuple structs, e.g. `struct Point(i32, i32)` are like structs without names for fields. +They let you define distinct types, but give you the dot operator and indexing of tuples. + +```Rust +struct Color(u8, u8, u8, u8); +let color = Color(0,1,2,3); +``` + +Order matters and they can be destructured, like tuples. +Field names are not provided. +Dot access operator is also valid. + +_Unit-like structs_ are structs with no fields. +They can simply serve as a basis to implement traits on. + +```Rust +struct UnitStruct; +let unit_struct = UnitStruct; +``` + +These are probably good for defining traits on. + +Storing references in a struct requires the use of lifetimes. + +`println!(structure:?)` is permissible if the structure implements `Debug`. +`println!(structure:#?)` for pretty-print is also permissible with `Debug`. +These are different than `dbg!(...)``. +This will instead print to stderr, and it takes and returns ownership, rather than borrowing. + +### Method Syntax + +Similar to Python's fucky OOP +basically moving functions into a struct namespace creates a method, but the +first param must be a `&self` (mutable or not). This is shorthand for +`self : &Self` which is shorthand for whatever self actually is in the `impl`. + +``` +struct SomeStruct ... +... +impl SomeStruct { + fn some_function(&self) {...} +} +``` + +Automatic referencing and dereferencing - all arrow operators or other +notions just get wrapped up in a simple dot operator. + +In methods `&self` is shorthand for `self : &Self`. +In the receiver type, you can do any of: + +- an immutable borrow (reading) +- a mutable borrow (mutating) +- or taking ownership (consuming) + +Taking ownership is rare and more for a special circumstance of preventing the method caller from using the original structure afterward. + +A rust convention for getters is to simply use the field name. +This makes it read-only and provides a space for manipulation before returning the private value. + +_automatic referencing and dereferencing_ is possible because the receiver type is explicit. +(I.e. there is no `->` operator like in C++, only `.`.) + +All methods are associated functions. +An associated function without a `self` is like a static/class method. +You use `::` on the type to invoke it. + +Specifying no self parameter in an `impl` block, like Python creates a sort of +static method on the structure. (Rust uses the word namespace for both this, +accessed by ImplName:: and for namespaces proper from modules.) + +## 6 Enums and Pattern Matching + +Enums can be like C-style enums, but they can be more like Java record types. +You can have individual, static instantiations/variants imbued with different data. + +Variants' data can even be of different types. +These can even be structs or other enums. +```Rust +pub enum Thing { + Variant1, + Variant2{named_field: i32}, + Variant3(i32) + +} +``` + +Enums can have methods. +Enums can be generic. + +`Option` is how the concept of `null` is implemented. +`None` is the equivalent variant. + +### The Match Control Flow Construct + +In `match` expressions, enums support value binding. +Matches are exhaustive. +The catch-all (default) case just uses a variable rather than a value as the match arm. +Using `_` is the same, but the compiler will not issue a warning if the value is not used. + +To do nothing with a branch, use the unit value. +`_ => ()` + +### Concise Control Flow with `if let` + +`if let` is basically a degenerate form of a match. +It avoids some boilerplate for contriving an equivalent match expression. + +You match on one variant and may perform variable binding. + +An `else` in an `if let` is equivalent to a `_` in a match block. + +## 7 Managing Growing Projects + +In growth order, +Modules -> Files -> Crates -> Packages -> Workspaces + +Crates are a rust construct, while packages are a cargo construct. +Workspaces are a development time grouping of interrelated packages that evolve together. + +Packages must have at least one crate. +Only one can be a library crate. + +`src/main.rs` and `src/lib.rs` are special names that will be detected as the crate root for Cargo. +Then the build result will use the name given in the package manifest. +`src/bin` can have other executable crates. + +### Defining Modules to Control Scope and Privacy + +Basically `mod` declares a submodule. + +`pub` on a module and on its members allows you to use those members in the context where you "include" it with mod. +Otherwise, it is still visible to sibling and child modules. + +### Modules + +These introduce namespaces, are related to `crate`s and allow access +specification. (Rust calls it "Privacy Boundary"). + +```Rust +mod some_module { + fn some_function(){ + ... + } +} +pub some_public_function () { + crate::some_module::some_function() // absolute path + some_module::some_function() // relative path +} +``` + +For privacy boundaries, modules, structs, funtions, etc are all private. A child item can access its parent's fields (so siblings can access each other) however a parent cannot access its child (nested) private fields. + +To make something public, use `pub` before the identifier. +`super` can be used to access the immediate parent scope. + +Structs need a specifier on each field. Enums only need one at the top-level identifier, and all its variants a public by default. + +`std::` actually specifies an absolute path to the standard library. It is not specified in [dependencies] however because it "ships with Rust." + +There is a top-level crate (with the same semantics as a module) named `crate`. From it, absolute paths to other modules within the crate can be accessed. +`crate::SomeModule::` + +### Use + +Bringing in the parent module and referring the target field with the parent's namespace is idiomatic for functions. +For structs and enums, it is idiomatic to refer to the entire path + +`use std::io;` is an example of including packages. +`use rand::Rng;` is an example of using traits. +`use std::cmp::Ordering;` for an enumeration + +`as` is used in the same way as Python to rename something included. +`pub use` allows _reexporting_ or making something that is private and nested some levels in the inner scope to be public to the outter/world. + +Nested paths work with use. + +```Rust +use std +use std::io +use std::cmp +// OR +use std::{self,io,cmp} // Self works here too! +``` + +#### Glob Operator + +This works for including things. +It is not advised but convenient for writing test code, or for this "prelude pattern." + +`use std::collections::*` + +#### File Separation + +`use ;` with a semi-colon rather than block means loading defs from a file with the same name as the package. + +## 8 Common Collections + +### Vectors + +```Rust +v : Vec = Vec::new(); // declaration by function +v = vec![1, 2, 3]; // declaration by macro +v.push(4) +let elem : &i32 = &v[2]; // gets reference, good for crashing in error handling +let elem2 = v.get(3); // gets Option<&T> + +Iterating over immutable references, then mutable +```Rust +let v = vec![100, 32, 57]; +for i in &v { + println!("{}", i); +} + +let mut v = vec![100, 32, 57]; +for i in &mut v { + *i += 50; +} +``` + +Indexing with `[]` can cause a panic. +`.get()` returns an `Option`. + +You can iterate over a vector mutably or immutably. +Regardless, you cannot mutate the vector reference itself at that point. + +Wrapping different types in enum variants lets you make a vector of one enum type. +Then you essentially have a vector of different types. + +### Strings + +A string slice is `str`. +Usually it is borrowed as `&str`. +The data of the string is stored elsewhere. + +String literals are stored in the program binary. +They are one form of string slices. + +Concatenate with `+`, `format!()`, `.push_str()`, and for single chars, `.push()`. + +`+` looks weird, because the first argument is the `String` itself (consumes). +The second is an `&str`. + +When adding multiple, it looks weird, so `format!()` is a good idea. + +Indexing into string slices requires a range. +`string[0..2]` +This is because indexing could represent bytes, characters, or graphemes. +This is dangerous though, and could cause a panic at runtime. +`.chars()` and `.bytes()` are useful methods for iteration. + +`.split_whitespace()` is a solid method. + +### HashMaps + +HashMaps are not in the prelude for the core language, but they can be included +from the standard library. They also cover the idea of dictionaries/associative +arrays in Rust. +```Rust +use std::collections::HashMap; +``` + +One way to generate a HashMap is to create iterators from vectors with `.to_iter()` and then calling `.zip(...)` to create tuple pairs, and finally `.collect()` to return to an annotated `HashMap<_,_>` + +`.get()` returns an `Option` as usual. + +`.insert()` for new values or for **overridding** + +`.entry()` returns an Entry, from which `or_insert()` may be called to +conditionally insert (only new values), and a ref to the value is returned. + +`.split_whitespace()` + +There's a sort of "structured binding" for key-value pairs. + +```Rust +for (key, value) in &scores { + println!("{}: {}", key, value); +} +``` + +HashMaps may either own their keys and values, or they may have references to them. +`entry(...).or_insert()` is a decently powerful idiom for HashMaps. + +## 9 Error Handling + +Functions, many from the standard library, return a `Result` enumeration. These +are generic and specialized for different modules, like `std::io`. + +These errors must be handled (???: before end of scope or their lifetimes?). +`.unwrap()` may be used as a more convenient alternative to a match expression to bind the success value or call `panic!()` on failure. + +`Result` also contains an `expect` method to add error handling throughout the code. This is like unwrap but one can provide the message to panic. + +The `?` operator allows error propagation by either returning the wrapped `Ok` value or by returning the entire wrapping of the `Err` value. This uses a `from()` function to convert the returned `Err` to the calling functions return `Err`. + +These can be chained as in `File::open("hello.txt")?.read_to_string(&mut s)?;` + +`std::ops::Try` is the trait behind `Option` and `Result`. + +`fn main() -> Result<(), Box>` is main's other valid return type. + +### Result + +`Result` +`unwrap_or_else()` allows a closure for not sunny cases. +`unwrap()` may simply panic. +`expect()` is similar but you provide a message. + +`?` is the error propagation operator. +The function must have a `Result` return type. +The operator also adds a `From` implementation to the error to convert it to the return type. + +This may also be used with `Option` where the early return is `None`. These cannot be mixed and matched with `Result` though. +Anything that implements `FromResidual` can actually be used. + +Main may return `Result<(), Box`. The latter is a trait object, but that is not explained here. +Main may return anything that implements `std::process::Termination`. +That gives a `report` function that returns an `ExitCode`. + +Panic is good for tests, prototypes, or examples. +It is also good when the caller has no way of course correction. For example, only having bad input to supply to a function. This is a contract violation. + +Basically use Result if you can recover. + +### Panic! + +The `panic!("Message");` macro causes Rust to either unwind the stack and exit +or to abort and leave the OS to clean up the memory. + +To allow aborting, in Cargo.toml append to the appropriate profile. +```toml +[profile.release] +panic = 'abort' +``` +`RUST_BACKTRACE` is an environment variable which if set to 1 (or further to +'FULL') will give backtraces at panicking. + +## 10 Generics, Types, Traits, and Lifetimes + +### Generics Data Types + +Use generics when you find that your code only differs by types (think a payload sender generic over two different parts of an application with different types). + +Also, use generics if you are expressing logic of how some types relate to each other without using the type details. Say, collections. + +Traits may be used as basically concepts/constraints, called **trait bounds**. +`` + +Type parameters may be applied to structs. + +```rust +struct Point{ + x: X, + y: Y, +} +``` + +Type parameters may be added to implementations. +`impl Something` + +Specifying the type parameter the first time ties it to the second specification. This lets the compiler know that this isn't a simple implementation for a concrete type T. +I.e. +This disambiguates specialization of concrete types +`impl Something` + +At the same time, methods within the impl can have their own separate type parameter. + +```rust + fn mixup(other: Point) -> Point { + Point { + x: self.x, + y: other.y + } + } +``` + +Enums may be generic. `Option ` has one parameter and `Result` has two. + +Monomorphization is Rust's name for type erasure or name mangling. + + +### Traits: Defining Shared Behavior + +They are similar to interfaces. + +Traits are functionality shareable with other types. + +_Trait definitions are a way to group method signatures together to define a set of behaviors necessary to accomplish some purpose._ + +The _orphan rule_ as part of _coherence_ means to implement a trait on a type, the trait or the type must be local. + +Traits may provide default implementations in their definition. + +This lends to the template method pattern. +A default implementation may call other methods that have no default. +Thus only those need to be implemented to give the higher level method. + +An overriding trait method cannot call the default method. + + +`impl Trait` syntax is basically taking a trait as a function parameter. +It is syntactic sugar for `trait bound syntax` which is the same but shows the trait as a type parameter. + +Compare these. The latter restricts types to be the same. +`pub fn notify(item1: &impl Summary, item2: &impl Summary) {` +And +`pub fn notify(item1: &T, item2: &T) {` + +Multiple trait bounds can be expressed with `+`. + +Where clauses are nice. + +You can return an impl Trait. +The caller will only see the trait object. + +_Blanket implementation_ is implementing a trait on anything that implements another trait. + +```rust +impl ToString for T { + // --snip-- +} +``` + +### Lifetimes + +Lifetime parameters only make sense on references. + +It seems the generic lifetime parameters just link formal parameters with the return type. +These are _input lifetimes_ and _output lifetime_ for functions. + +There are _lifetime elision rules_ that are not quite full lifetime inference. + +1. Every input parameter gets an input lifetime. +2. If there is only one input lifetime, it is assigned to the output lifetime. (Having an output lifetime unrelated to input doesn't make sense, because independently created references would become dangling) +3. If `self` is present, it's lifetime is assigned to the output lifetime (makes methods cleaner often). + +## 11 Testing + +Using _attributes_ enables unit (and integration) tests. These are the #[] +above some definitions. +```Rust +#[cfg(test)] +mod tests { + #[test] + fn it_works() { + assert_eq!(2 + 2, 4); + } +} +``` +`cargo test` can be used to build the test module and run all unit tests in +separate threads. + +`assert_eq!()`, `assert_ne!()`, `assert!()`, are useful macros for unit tests. The +first two provide a bit more detail to cargo by default. + +Any string after the arguments is passed to `format!()` for more detailed. +`#[should_panic]` can be attributed after a `#[test]` and can even be made to +match on specific panic messages with a parameter. +```Rust +#[test] +#[should_panic(expected = "some substring")] +``` + +`Result` can also be returned by tests (so, Ok(value) for success or +Err(message) for failure. This allows the `?` to be used. + +`#[ignored]` is useful. + +`#[cfg(test)]` is on the module. +`#[test]` is on the function. + +`assert!()`, `assert_eq!()`, and `assert_ne!()` macros are available. + +The latter two require their operands to have implemented both `PartialEq` and `Debug` for comparison and printing respectively. + +`#[should_panic]` and `#[should_panic, expected="..."]` are useful. + +Tests can also not be based on panicking. +Then they return `Result` (e.g. `Result<(), String>`). +To check for an `Err` variant, use `assert!(value.is_err())`. + +Tests run in parallel by default. +This means if a test shares resources like a file, either copies of resources must be made, or tests must be run serially, or I guess some synchronization could be done. + +Flags can be passed to: show success output, filter by name (including test module name), and run ignored tests. + +`#[ignore]` goes after the test macro. + +### Unit Tests +`#[cfg(test)]` means to only compile the module when the configuration +attribute includes the test parameter (this is provided by `cargo test`). + +### Integration Tests +For Cargo under `tests/*.rs` all files will be compiled as separate test crates +; however, source files under subfolders will not be (so common code may be +extracted). + +Modules here do not need the configuration attribute, since the folder path +implies compilation specifically for testing. + +**Binary crates do not have integration tests, only library crates.** + +Unit test convention is to have the `#[#cfg(test)]` module in the source file alongside the code. This macro will only have the test code built with `cargo test`. This makes `use super::*;` common. + +Integration tests are specifically for the public API and use a `tests/` directory. +Each file is a separate crate representing a separate integration. +`cargo test --test ` will target only that integration. + +Subdirectories under `tests/` do not get handled as files directly under it do. This may be used to provide common code to share between integration tests. + +Integration tests are only for library crates `src/lib.rs`. However, a binary crate that factors out its functionality may then use them. + +### Automated Tests +`cargo test -- --test-threads=1` can be used to run tests serially (no +parallelism). +`cargo test ` will match test functions names on a pattern. Test +modules become a part of this pattern. +`cargo test -- --ignored` runs the ignored tests only. + +## 12 Command Line Program + +The configuration structure and run function are broken out into library code. +The run function returns a `Result<(), Box>` which can be propagated. +That is handled with a process exit code in main. + +Environment variables are accessed with `env::var`. +CLI arguments are accessed with `env::args()`. +It also uses `std::process` for exit codes. + +`std::env::var` +Printing to standard error may be done with `eprintln!()`. + +## 13 Functional Features + +### Closures + +Closures are basically lambdas. +`let foo = || x + 2;` +The syntax can be annotated or pretty reduced. +Closures pass arguments in the same three ways as functions. +Explicitly taking ownership (moving/capturing) can be done with `move`. + +Functions that take closures may have their parameters trait bound. +There are three `Fn` traits. +`FnOnce` means the closure gives back ownership of something it captured. +The means it cannot be called again. +`FnMut` mutates something it captures. +It can be called more than once. +`Fn` does neither, so it can be called more than once and concurrently. + +### Iterators + +Iterators are used for functional programming style and allow the abstraction +of often more mundane iteration tasks (such as on CLI arguments). + +_zero-cost abstraction_ coined by Stroustrup. +This sort of means that lower-level code that is hand-written is subject to +inoptimization and higher-level abstractions may be more optimized by the +compiler (nothing is lost by using higher-level abstractions). + +The iterator trait is pretty simple. +It has an associated type though. +That has its own syntax. +`iter()`, `iter_mut()`, `into_iter()` provide the three forms of getting values. The first is an immutable reference and the last is ownership. + +There are _consuming adapters_ like `.sum()` and `.collect()`. +These use up the iterator and produce a result based on all the items. + +There are _iterator adapters_ which produce a new iterator by changing the original. +An example of this is `.map()` which takes a closure, applied for each item. + +Then there is a good demonstration of improving the handling of `env::args` (an iterator) by directly using that rather than collecting it into a `vec`. + +Also there is an example of, instead of declaring a temporary buffer, looping through lines, and filtering by assigning to the buffer, a simple iterator adapter _.filter()_ is used. +This shows that **iterators are basically loops as objects** which can have operations applied to them. + +## 14 Cargo + +crates.io +Existing repos can be easily translated to cargo repos. + +`cargo new ` or `cargo new --lib ` + +In the package... +cargo build +cargo build --release +cargo run +cargo check +cargo update +cargo doc --open # builds and presents all dependency docs + +Specifying dependencies uses SemVer. +``` +[dependencies] +a_pkg = "3.4.1" +``` +A bare version number is shorthand for "^3.4.1" which really matches any +version that is API-compatible (so, up to the next minor release). + +### Locking + +Cargo.lock contains version numbers of dependencies where the last stable build +was made. These will not update unless `cargo update` is run. + +Even with an update, the dependency will not roll to the next minor release +unless the Cargo.toml file is actually changed. + +### Crates + +Packages (the source repo started by Cargo) can either contain (or produce, in +a sense) either binary crates or a single library crate. + +#### Implicit Crate + +There is a top-level crate (with the same semantics as a module) named `crate`. +From it, absolute paths to other modules within the crate can be accessed. +`crate::SomeModule::` + +#### Automated Tests + +`cargo test -- --test-threads=1` can be used to run tests serially (no +parallelism). +`cargo test ` will match test functions names on a pattern. Test +modules become a part of this pattern. +`cargo test -- --ignored` runs the ignored tests only. + +### Release profiles + +These are different configuration options in the TOML file for different kinds +of releases of the software. + +`[profile.dev]`, `[profile.release]`, etc. + +### Packaging + +The `[package]` tag is used. Under this is specified common data with which to +upload a software package to crates.io. + +`cargo login` uses `~/.cargo/credentials` to store the private API token. + +???: Is there a way to spin up a common registry for Rust crates? There must +be. + +`cargo yank --vers x.y.z` locks prevents future projects from using your software version +within their Cargo.lock file. It does not delete code. +`cargo yank --vers x.y.z --undo` undoes this (unsurprisingly). + +### Workspaces + +a set of packages that share the same `Cargo.lock` and output directory. +``` +├── Cargo.lock +├── Cargo.toml +├── add-one +│ ├── Cargo.toml +│ └── src +│ └── lib.rs +├── adder +│ ├── Cargo.toml +│ └── src +│ └── main.rs +└── target +``` +Different versions of dependencies within different TOML files will be resolved +and will be decided within the top-level Cargo.lock file. + +Dependency paths must be added in one crate's toml file to another crate in +order to use that crate. `use` statements must still be used. + +`cargo run -p ` allows one to run a specific crate in the workspace. +`cargo test -p ` + +`cargo install` can be used to additionally install extensions to Cargo itself, +so called `cargo-`. These can then be run as `cargo `. + +**Cargo packages are intended for developers, not system operation.** (apparently) + +## 15 Smart Pointers + +Smart pointers own their data, unlike references. + +Smart pointers are structs that implement `Deref` and `Drop` + +- `String` and `Vec` +- `Box` - heap allocation +- `Rc` - reference counting +- `Ref`, `RefMut`, `RefCell` enforce borrowing rules at runtime rather than at compile time. + +Standard pointers in Rust are like references but can own their data. + +_interior mutability pattern_ + +`Box` is a for simple heap allocation. +It is useful in, say, creating _recursive types_. + +A box in the standard library is basically a tuple of one element. +This element implements `Deref`, so that the `*` operator may be called on it. +This operator first gets a reference to the inner element (in the tuple). +This would seem backwards. +_Then_ it de-references that to get and return the inner value. + +### Implicit Deref Coercions + +_Deref coercion_ is similar to automatic unboxing. +It can do more though (or auto-unboxing is one type). + +Passing references or pointers (such as `Box<>` values) may be automatically, implicitly dereferenced. +It seems harry but makes the code look cleaner. + +For example, `Box` can be passed to `&str` and coerced to that type. + +```rust +fn main() { + let m = MyBox::new(String::from("Rust")); + hello(&m); +} +``` + +Without deref coercion, you would need to write: + +```rust +fn main() { + let m = MyBox::new(String::from("Rust")); + hello(&(*m)[..]); +} +``` + +There is also `DerefMut`. +Per the book, + +> Rust does deref coercion when it finds types and trait implementations in three cases: +> +> - From `&T` to `&U` when `T: Deref` +> - From `&mut T` to `&mut U` when `T: DerefMut` +> - From `&mut T` to `&U` when `T: Deref` + +### Drop + +Drop is the other trait included in the prelude to implement for a smart pointer. +This executes right as the pointer goes out of scope. + +```Rust + +impl Drop for CustomSmartPointer { + fn drop(&mut self) { ... }} +``` + +It cannot be called manually if destruction is desired before end of scope. +Instead, `std::mem::drop()` must be called. +(Otherwise this would cause a _double free error_). + +### Reference Counting + +`std::rc::Rc` is **not** brought into scope by the prelude. +This allows multiple references to the same object (which will not be destructed until the final reference goes out of scope). + +Declare a `Rc` rather than `Box` if ownership must be shared. +`Rc` is for single-threaded applications only. +`Rc` only allows immutable borrows. + +For example, two pointers in two different objects point to the same data. +`Rc::clone(&some_rc)` is convention over `some_rc.clone()` because it is unlike other cloning methods. +Rather than make a deep-copy, it just bumps the reference count. + +The count may be gotten with `Rc::strong_count(&rc)`. + +### Interior Mutability + +This can be done with `RefCel`. + +`RefCell<>` moves borrow checking to runtime. +This is useful for example for creating mock objects which must conform to immutable signatures but hold mutable data. +(See the explanation below.) + +`Cell<>` does this for copying data and `Mutex<>` for thread-safe scenarios. + +It's weird because it looks like it defeats the purpose of immutability. +I think the idea is that the `RefCel` itself, the pointer, is constant but can point to mutable data. +This seems to be the canonical construct in rust with this power, called _interior mutability_. + +Violating the borrow checker's rules with this will cause a runtime panic, not a compilation error. + +The example is a long one, showing mocking for testing. +Instead of state verification, it shows that the methods called on the collaborator objects by the method under test can be wired to verify the object under test. + +This can be chained with `Rc` to get a shared pointer to mutable data, i.e. `Rc>`. +Calling `.borrow()` returns an immutable pointer, specifically a `Ref`. +Calling `.borrow_mut()` returns a mutable pointer, specifically a `RefMut`. + +`Mutex` is the thread-safe version of `RefCel`. + +Using `Rc` can create reference cycles, like a cycle in a linked list. +When the two original pointers to the two data are dropped, the internal linkages between them remain (accounted for in the reference counting). +This means the memory would never be unallocated. + +A way to avoid this is with `Weak`, which is a type related to `Rc`. + +These are almost like symlinks v. hard links. +They increase the `.weak_count()` but not `.strong_count()`. +So if a weak link remains but the strong count hits zero, the memory is still unallocated. + +It is the same otherwise, but semantically it doesn't express ownership. + +For example, in a tree, the parent has an `Rc` to children nodes. +The children nodes have a `Weak` to their parent. + +To use a `Weak`, you have to `weak.borrow().upgrade()` and check the `Option`. +Or `Rc::downgrade(&strong)` + +## 16 Fearless Concurrency + +`handle : JoinHandle = thread::spawn(|| {})` +Can `move` captures into the thread. +`handle.join().unwrap()` +`thread::sleep(time::Duration::from_secs(1))` + +Also, to avoid `move` into threads. +``` +thread::scope(|s| { + s.spawn(|| { + println!("Here's a vector: {v:?}"); + }); + }); +``` + +### Messaging Passing + +`use std::sync::mpsc` +`let (rx, tx) = mpsc::channel();` + +You can give a transmitter to another thread. +Threads must own their transmitter (or I guess receiver). + +Sending data moves it to the other thread. +Sending returns a `Result` so you can check if the channel already closed. + +You can call `recv` on the receiver, which blocks but will return a `Result`. +An error will be returned when thecloses. + +`try_recv` will return immediately, either with `Some(T)` or an `Err` if there are no messages. + +You can also clone transmitters, fulfilling the name _multiple producer single consumer (MPSC)_. +So, multiple threads can have their own producer/transmitter. + +### Shared Memory + +Messaging passing is the equivalent of a single owner of data. +Shared memory is like having multiple owners. + +This can be done with a `std::sync::Mutex`. +A good metaphor is acquiring a microphone in a panel in order to speak among a crowd. + +`Mutex::new(...)` returns a `Mutex`. +Calling `.lock()` will block and return a `LockResult`. +It will be an `Err` variant if another thread with the lock panicked. +Otherwise it will be a `MutexGuard`. +That is a smart pointer which can be dereferenced to access/modify the value you care about. +It will also unlock the mutex on its `Drop` implementation. + +The problem with Mutexes (Mutices?) is that you need a shared reference among threads to make them useful. +Thus you must wrap them into a reference counting construct like `Rc`. +`Rc` is not thread-safe, however, but `Arc` is. +This is an _atomic_ `Rc`. + +There are other atomic primitives. + +Using `Arc>` is analgous to `Rc>` in single-threaded world. +This is because `Mutex`, like `RefCel` actually provides _interior mutability_. + +Mutexes can lead to _deadlocks_. + +### Send and Sync + +Both `std::marker::{Send,Sync}` are "marker traits". +All they do is mark the thing that implements it. +If something implements `Send`, it is safe to `move` to another thread. +`Rc` cannot implement this, for example, because sending a `.clone()` could have logical rammifications (both clones update the same count). + +If it implements `Sync`, immutable references to it can be sent to another thread. +(If `&T: Send` then `T: Sync`.) + +Implementing these yourself is part of unsafe rust. +A type built only of types that have these markers will then have these markers themselves. + +## 17 Fundamentals of Asynchronous Programming: Async, Await, Futures, and Streams + +There is a trait `Future`, which is the backbone of asynchronous Rust. + +`async` marks functions as asynchronous. They can be interrupted and resumed. +Calling `.await` on a future is a time (an "await point") for the `async` function to either continue immediately or be interrupted. +(This lets the async runtime know it is a good time.) +This is because a future is expected to take some amount of time, so it may make sense to `.await` it. + +`async` functions actually compile to regular functions that return an anonymous implementation of `Future`. +In other words, +``` +async fn foo() -> bool { + true +} +``` +becomes +``` +fn foo() -> impl Future { + async { + true + } +} +``` +So there are just `async` and `async move` blocks. + +An async runtime is basically a statemachine with an `executor` which is the side that executes the statemachine. +`select!` can be used to await multiple async functions. + +Async becomes concurrent when wrapping in tasks. +You can join on tasks much like threads. +You can use an async runtine's (separate) join function to join multiple task handles. This will wait until all are complete. + +Async messages/channels are similar to mpsc. +However the receiver is mutable. +`rx.recv()` also produces a Future. +You can receive an unknown number of values with while let. +``` +while let Some(value) = rx.recv().await { println!("received '{value}'"); } +``` + +However, the transmitter must close to end this loop. It will only close at the end of the transmitting task if the transmitting task owns the transmitter. For this, you need to `async move`. + +`join()` has related methods like `join3()` to add more Futures. +`join!(...)` can take any known number of Futures +`join_all(...)` can take an iterator (unknown) of Futures (but they must have the same `` type). +It is a tradeoff. +To create an iterator of Futures, you use a trait object. +This is similar to `Box::new(dyn Future)` but you must pin it. +`Box::pin(my_future)`. +You don't actually need the heap allocation, just the pin, so you can use a `Pin<&mut dyn Future>` type. +You can construct that with `pin!(async {...})`. + +You can `race()` futures like joining then, but only one completes. +You can also `yield_now()` to introduce an await point at any time. + + +## 18 OOP + +Rust supports OOP in that it: + +- provides objects and methods via structs, enums, and implementations. +- provides encapsulation with `pub` +- provides limited inheritance with default trait implementations +- provides _bounded parametric polymorphism_ using generics and trait bounds + +Trait objects allow dynamic dispatch, whereas generics allow static dispatch. +Dynamic dispatch has a runtime penalty, but it makes the code more re-usable. + +Dynamic dispatch is done with `dyn`. +Basically you use a pointer to a trait object. +The indirection is necessary, because you do not know the size of the backing implementation. +`field : Box` + +### State Pattern + +There is then an example of the _state pattern_, which is one of the GoF patterns (I think). +This has a wrapper object that holds a state value. +That state value is really a pointer to a trait object. +The trait has methods that define the state's transition to other states. +Thus when any of those methods are called, the current state may transition to another state per its encapsulated implementation. +The wrapper object also implements the trait and just forwards it to its current state. + +The pointer to the trait is also wrapped with `Option`. +This is necessary during state transition for the rust ownership system. +This is so the state can be `.take()`, replaced with none, and then the value can transitioned and reassigned to the pointer of the wrapper object. + +Then the chapter shows that this is all not as efficient as a more rust-y way. +This way is to just define each trait implementation (the various states) as separate structs. +Those then have methods that consume themselves and construct the next struct. +This is much simpler because, it seems, the consumption semantics of rust are utilized rather than all the `.take()` nonsense. + +## 19 Patterns and Matching + +Patterns are a language construct used in several contexts. + +The most obvious is at the beginning of match arms. +Also they are used with `if let` and `while let`. +Actually they are used with simple `if`, like in tuple destructuring. +They are also used with function parameters and closure parameters. + +**Named variables in a pattern will shadow variables outside the match arm's scope.** + +_Refutable_ patterns are those that may fail, because they have some structure that may mismatch the value given. + +_Irrefutable_ will always match/bind. +These could be a simple variable or an `_`. + +`let` requires an irrefutable pattern while `if let` requires a refutable pattern. +Otherwise each expression would be meaningless. +`match` allows one branch to have an irrefutable arm. + +`let else` might be a valid construct without an `if`. Hmm. + +### Syntax + +You can match literals and named variables. +Because named variables shadow higher scope variables, you cannot use them as conditionals in the match arm directly. +You need a MatchGuard. + +A `|` can join different conditions in a pattern. + +You can destructure structs as well. +You can also use struct field init shorthand to capture a component in a new, independent variable. +You can also match with a field of a structure at a certain value. + +The wildcard `_` never binds. +A name starting with an `_` does (and takes ownership). +However an unused warning will never be issued for of. + +The `..` syntax is like a wildcard but for a range. +It can even appear in the middle of a tuple. + +A match guard is basically just a ` if ... => { }` +This allows using outter, non-shadowed variables. +It is an _and_ with the pattern, and the pattern can have _or_ with `|`. + +There is also the `@` syntax. +This can be applied to binding in a pattern to also test the value. +The book shows an example of a range. +`id : id_variable @ 3..=7` + +## 20 Advanced Features + +### Unsafe + +There are five things that unsafe rust gives you. +- dereferencing raw pointers +- calling unsafe functions or methods +- accessing/modifying mutable static variables +- implementing unsafe traits +- accessing fields of a union + +#### Raw Pointers + +Raw pointers are similar to C-pointers. + +For immutable (`*const i32`): +`let ro = &raw const num` +For mutable (`*mut i32`): +`let rw = &raw mut num` + +With a numeric address (a `usize`), you can cast it as a raw pointer. +`let r1 = some_address as *const i32;` +They may be declared anywhere but only dereferenced in an `unsafe {}` block + +#### Unsafe Functions + +Declare unsafe functions as `unsafe fn foo(){}` which can only be called in an unsafe block. + +```rust +unsafe { + unsafe_function(); +} + +unsafe fn unsafe_function() { +} +``` + +This seems redundant but is sort of a handshake between the caller and the subroutine to help minimize the scope of the unsafe function. I guess this is similar to minimizing scopes or error handling and async functions. Break up scope as much as you can. + +Their example is sort of trivial, but they show using an assert to first confirm some data is good (splittable at some index), and then using an unsafe std library function to split an array and get two immutable references at once. + +#### Extern Blocks + +Using an extern block to declare foreign functions (like prototypes/signatures) is marked unsafe. + +```rust +unsafe extern "C" { + fn abs(input: i32) -> i32; +} +``` + +Here "C" isn't really just the language, it's C's ABI. So any language that uses C's ABI can be linked to this. + +Calls to extern blocks (foreign function interface) must be wrapped in unsafe blocks. + +But since we know C's abs function is safe, we can mark it as safe. Then it doesn't require an unsafe block at the call site. + +```rust +unsafe extern "C" { + safe fn abs(input: i32) -> i32; +} +``` + +Providing a function from Rust callable by foreign languages does require unsafe in the no_mangle attribute. This is because, without the compiler mangling function names, they could collide. So you have to make sure that won't happen yourself. I guess that relates to monomorphization. Just like async, extern goes after visibility but before fn. + +```Rust +#[unsafe(no_mangle)] +pub extern "C" fn call_from_c() { + println!("Just called a Rust function from C!"); +} +``` + +#### Mutable Static + +Basically const and static are similar, but static has a fixed memory address. Const is more about the value, not about storing... Therefore unlike const, static can be mutable. + +I guess too, const is like constexpr, whereas static is like traditional const. + +If a static is made mutable, then accessing/modifying is inherently unsafe. + +```Rust +static mut COUNTER: u32 = 0; + +fn add_to_count(inc: u32) { + unsafe { + COUNTER += inc; + } +} +``` + +#### Unsafe Traits and Impls + +As with other categories, this is two things. +Both marking a trait as unsafe when "at least one if its methods has invariant that the compiler can't verify." + +```rust +unsafe trait Foo { + // methods +} +``` + +And marking unsafe implementations, such as implementing `Send` and `Sync` for a struct containing raw pointers. + +```rust +unsafe impl Foo for i32 { + // +} +``` + +#### Accessing Fields of a Union + +??? + +#### Miri + +You can add the nightly rustup component `miri` to do dynamic analysis against unsafe rust code. + +### Advanced Traits +#### Associated Types v. Generic Traits + +"Associated types let the implementor absorb the decision to determine a type, so that callers don't have to carry the type everywhere." + +The key insight is: "Associated types also become part of the trait’s contract: implementors of the trait must provide a type to stand in for the associated type placeholder." + +The mental model: use an associated type when the type is an output or consequence of the implementing type (one right answer), and use a generic parameter when the trait should be implementable for many different types simultaneously (like `From`). + +... + +Basically this is an alternative to generic traits. +The difference is you can only implement traits with associated types once. +It semantically indicates a different relationship: one implementor has "one output type". + +It is used specifically to constrain design. +That constrain buys you things. It allows the compiler to infer types in places. It makes trait bounds simpler/cleaner. + +Better yet, it also removes the burden of the caller to determine/specify type parameters at call sites, because they are already fully known. + +For example, Iter has an associated type Item. +The one implementing Iter specifies its type. +Otherwise, the caller (constructor of the implementor) must also provide the type parameter that makes sense with the iterator. + +For example, `HashMap` implements iterator with `Item = (K, V)`. Then `map.iter()` can be used. With a hypothetical `Iter`, that "bubbles up" or percolates up to the caller, so they would have to specify `HashMap`, but I is already known by the internals of the `HashMap`. + +Technically, you could forward a type parameter from the implement or to the associated type. This would return you to having `HashMap` and defeat the purpose of an associated type. + +On the contrary, associated types enable GAT, or generic associated types. This let's you have something advanced, like iterating over items from an implementor whose lifetime is bound to the implementor. Seems... Complex. + +#### Default Generic Type Parameters and Operator Overloading + +This has a pretty badass example with using the newtype pattern to create millimeter and meter types around i32, and then implementing add for millimeters. That defaults to adding another millimeters to the RHS, however, another implementation can be used to implement adding meters. The associated type for both is the single, correct output type of millimeters. + +Extra about custom literals... + +| Technique | Syntax | Notes | +| -------------------- | ---------------- | -------------------------- | +| Constructor | Meters::new(5.0) | Most idiomatic | +| Into | 5.0.into() | Requires type annotation | +| Macro | m!(5.0) | Closest to custom literals | +| Extension trait | 5.0_f64.m() | Most fluent/ergonomic | +| Operator overloading | m!(5) + m!(3) | Combine with any | +The extension trait + operator overloading combo is as close to custom literal ergonomics as you'll get in Rust today. There's a long-standing desire for proper custom literals in the community, but it hasn't made it into the language yet. + +#### Disambiguating Between Methods with the Same Name + +Implementors can implement multiple methods from different traits with the same name, and even their own method of the same name. + +Their own, direct method is preferred. + +To then specify one of the other methods, you use that reversed syntax similar to `String::from`, like + +```rust +MyTrait::method(&my_obj); +``` + +Left off at... "However, associated functions that are not" + +If you're "overriding" an associated function from a trait with an implementor's own method, then you have to use fully qualified syntax to invoke the associated function. So like... + +```rust +::baby_name(); +``` + +#### Supertraits + +Basically this is Java's extend syntax, but on traits. +It is syntactic sugar for taking a bound on Self. +In other words, +```rust +trait Warrior: Fighter {} + +// equivalent to + +trait Warrior where Self: Fighter {} +``` + +#### Newtype Capability + +Newtype let's you get past the orphan rule. +You can implement external traits on external types, because you're implementing them on the wrapper. + +But then, to make something like "embedding" (Go terminology), you would have to implement `Deref` on the wrapper. + +### Advanced Types + +#### Newtype Pattern v. Type Aliases + +Basically this just says, use newtype to not confuse units and to further minimally hide private APIs/restrict types. + +Meanwhile, an actually type alias + +#### Empty/Never Type + +The type `!` is used when something diverges or never returns. This can be coerced into any type. So like, a match arm that diverges will work with any return type. I guess that also explains `let ... else { ... }` + +#### Unsized Types + +`str` and trait objects are unsized. +`str` is because different objects have different lengths, yet for one type, there must be one size. + +So, these must be used behind a pointer of any kind. +References are typical but others work. + +Generics implicitly take a `Sized` bound, but you can overrideit with + +```rust +fn too(t: &T) { + // t can be any pointer. +} +``` + +`t` must still be a pointer type despite the trait bound. +The `?` is special only for the `Sized` bound, which means may or may not. + +### Advanced Functions and Closures + +You can take function pointers as arguments. +This is _type_ `fn` as opposed to traits like trait `Fn`. + +```rust +fn do_twice(f: fn(i32) -> i32, arg: i32) -> i32 { f(arg) + f(arg) } +``` + +Function pointers can be coerced to those traits/closures. +They are flexible as arguments, but the reciprocal is true for parameters. +Requiring a function pointer as an argument makes you unable to pass closures. So accepting one of the closure traits is best. + +The name of enum variants become initializer functions, which become function pointers, which can be coerced into closures. For example: + +```rust +enum Color { + RGB(u64), + GrayScale +} +let color_list: Vec = (0u64..20u64).map(Color::RGB).collect(); +``` + +#### Returning Closures + +You can return a closure as a function pointer if it doesn't capture anything. +If it does, you can return it with the `impl trait` syntax. +But if you are trying to call it more than once and return different opaque types, you need to use `Box Retval>` + +### Macros + +There are declarative macros and 3 procedural macros. +Declarative are the `macro_rules!`. +Procedural include: +- custom derive on structs and enums +- attribute macro on any type +- function-like macros + +Macros can provide function overloading (taking a variable number of arguments anyway). + +Macros must be written above where they are called, unlike functions. + +Declarative macros are basically match expressions, but against rust code, and they cause code generation in the macro's place. +```rust + +`#[macro_export]` +macro_rules! guh { + ( $() ) => { ... }; +} +``` + +The Little Book of Rust Macros + +Derive macros have way more steps. +1. First you create a crate for your trait. +2. Then you need to create a separate, sub-crate (conventionally named with `_derive`) . +3. It must have `proc-macro = true` in its Cargo.toml +4. You use a macro on your derivation function, tale in a TokenStream and return a TokenStream. +5. Then you normally use the syn and quote crates to parse and generate rust code respectively. +6. `stringify!` keeps expressions unevaluated for the macro. + +Attribute macros are very similar, but more flexible. +You use `#[proc_macro_attribute]` rather than `#[process_macro_derive]`. +Then you write a function that takes two token streams, the first is the attribute and the second whatever is wraps. + +Function-like are similar to derive in that they take one token stream. They use `#[proc_macro]`. + +# Async / Await + +Concurrent programming is writing code in such a way that it appears to do multiple things at once. + +It is entirely within the program. + +It cannot make the program faster, but it can make the program more responsive. + +Threads are owned and managed by the OS. +One process may have multiple threads. +Threads share memory. + +Tasks on the other hand are managed by the asynchronous runtime within the program. + +The OS _preemptively_ schedules threads to run. +It _context switches_ to do so. +Tasks, at least with Rust's tokio runtime are _cooperative_. +They voluntarily yield control. + +_Green threads_ typically refer to tasks that are preemptive. +Also, tasks are internally structurally different from threads. + +Async IO is separate from, but often used with, async concurrency. It is also called "nonblocking IO". + +Instead of a thread blocking and waiting doe the OS while other threads run, the OS does not block the program with the async runtime. The async runtime returns control to a different task. Then when IO results are available, the runtime provides it to the waiting task. + +Often programs use both async tasks and threads. +Sometimes the async runtime uses multiple threads without them being written into the programming logic. +This may be necessary because only threads can execute on multiple cores for parallelism. + +Zero processing and synchronization requiring tasks present a challenge for scheduling algorithms. + +Concurrency is a pattern controlled by the code and parallelism is a resource provided by the scheduler. + +A task group could be an idea of assigning all tasks to one thread locked to one core, so they run concurrently but never in parallel. + +Runtimes have a _reactor_/_event loop_/_driver_, _scheduler_, and _executor/runtime. + +Calling await joins the future's execution to the current async task. + +Sleeping a task uses the runtime's sleep method, not the thread sleep method. + +Actually making tasks concurrent requires that the task be spawned, not awaited. + +Spawning a task returns a JoinHandle future. Awaiting that future is like joining a thread. + + + +# Per John Moon + +Style/idiom linting: `cargo clippy` on project +Building configs into the binary: macro `include_str` +Command line arguments: `clap-rs` +Printing structs: `#[derive(Debug)]` then `println!("{:?}", my_struct)` + +# Rocket + +The lifecycle is: + +1. routing +2. validation +3. processing +4. response + +Routes have `#[get]`, put, post, delete, head, patch, or options. + +There are two kinds of entrypoints. +`#[launch]` and `#[rocket::main]` + +Head requests are handled automatically if there is only a get route (no explicit head route). + +Rocket will reinterpret web forms submitted by `post` as a different HTTP method if the content type and form's first field fulfill some requirements. +This gets around web browsers' only supporting forms with `get` and `post`. + +Dynamic paths use `` in the path of the route. +A segment is one part of a route between slashes. + +These dynamic segments bind to function parameters. +Any type implementing `FromParam` can be used as the parameter. +These are _parameter guards_. + +With _segment guards_, a parameter may bind to the rest of a path. +In the path, there is ``. +The parameter must implement `FromSegments`. + +There is an example of serving a static file with a route. +There is an example of using a one line file server with no route (but still a mount point). + +Ignore segments with `<_>` and `<_..>`. + +Rocket forwards failed parameter bindings to the next route. +A failure on the final forwarding guard triggers the error catcher. + +You can bind to an `Option<>` or `Result<>` and not deal with forwarding. +The `rank` parameter in a route may be necessary to resolve collisions. + +Automatically assigned ranks have negative values (higher precedence). +Basically the more specific a route and more specific a query, the higher the precedence. +This uses a system of "colors". + +- static +- partial +- wild +- none + +# Exam + +_What inspires you to learn something new?_ + +For me, there are several motivating factors: novelty, effectiveness and efficiency, helpfulness, and competitiveness. Novelty is the simplest, intrinsic motivation, or as a coworker termed it, "chasing the shiny". I take a simple joy in discovering new ways to think about problems or finding elegant solutions. For example, at my most recent workplace, we switched from a pattern of using GNU make to using a new tool Earthly. The new tool was highly compatible with Docker (in a CI/CD or build context) but also provided the DAG semantics that GNU make provides. + +There is also the matter of effectiveness at solving the problem at hand. That is, I want to learn the new thing that is "the tool for the job". For example, on a recent project, I had to write a micro-service to integrate with gRPC, Helm, and NATS. Many on our team had opted for Java or Python for their services, but only Golang had native integrations for all three. I dove into it eagerly. As it turned out, Go was also more efficient, with a much faster turn-around for prototypes, compared to getting Java (and Maven) working in our environment. + +I am also motivated by becoming more efficient. In terms of the "1% rule", if I become 1% more efficient each day, the compound effect is enormous. For example, integrating AI into my workflow with Ollama and Continue has certainly granted this and more. + +Similarly, remaining competitive with the market is a huge motivation for me to learn new things. For example, Rust and Go are two languages that are "hotter" on the market, especially with the Department of Defense aiming to replace legacy C++ systems with Rust, and the Linux kernel starting new modules in Rust instead of C. Aligning my own projects on my own time is one way I do this. For example, I have been switching my personal website from the static site generator Cobalt (written in rust) to Rocket (an actual rust library, similar to Python's flask) plus MdBook (the rust library that the rust documentation is processed with). + +Lastly, learning new things lets me be more helpful in the workplace. I had the privilege of working for several years with a "10x developer" (or so we liked to refer to him as), who always seemed to have a solution when I was spinning my wheels. It was very inspiring for me to become the same in my professional growth. Although I can't dive into every technology, I can try to constantly add tools to my toolbox and increase my vocabulary to navigate new problems when they arise. + +_What's one professional achievement you are particularly proud of, and why?_ + +``` +

I am particularly proud of my work on one software "candidate" (or "epic" in agile methodology terms) called the "diamond" because of its deadline, scope, and my execution of it. The diamond was a "symbology" (or symbol) drawn on the HUD (heads-up display) of the A-10 aircraft. Anything in the pilot's line of sight that fell within the diamond was defined to be in range of the heat-seeking laser rockets. The diamond had been designed by some systems engineers but no implementation was started yet.


In terms of deadline, the diamond had been a "want-to-have" candidate that had been pushed out several times. We were nearing the end of our software release cycle, but I felt confident that with enough effort and focus, I could complete it. I volunteered to take it on. The estimate of time it would take has been one of my most accurate in my professional career, likely because I had had great exposure to the different subsystems of the A-10. On the last long day of the implementation phase, right before the "code freeze", I had my last successful test on the high fidelity test stand.


In terms of scope, the diamond touched three major subsystems of the aircraft. While it was displayed alone on the HUD through vector graphics (and an assembly language), command-and-control of the drawing hardware was done through another system. That system also plumbed values used for the diamond by yet another system. The data flow was complex, but fortunately, I had previously volunteered to work all of the various subsystems that it required, including legacy ones.


Lastly, in terms of my execution, it was a rare software problem that felt like "pure development". The effort was not wasted in monotonous tasking, such as for information foraging or software approvals. Once I had the data properly plumbed, it was a joy of algorithm design and mathematical calculation. I determined the correct formulas for drawing the vectors based on the input and translating that to the assembly language of the HUD.

+``` + +_What new skill are you interested in learning?_ + +``` +

There are several new skills I am interested in learning, ultimately to center my technical stack and increase my knowledge of the domain. To center my technical stack, these include rust libraries focused on command-and-control, tooling for behavior-driven development and software architecture. To increase my knowledge of the domain, this includes things like launch stages, mission assurance, space observability, signal processing, etc.

+``` + +_Please share how you resolved a conflict within your team._ + +``` +

Our team had a long running issue of what versioning strategy should be used in a new system-of-systems. Many of the components we had inherited from other teams and times, and at least one was from an external party. This meant there were many different versioning strategies, such as SemVer or simply raw dates. Sometimes source repositories would use things like git submodules, or during build time, they would pull in dependencies from other projects.


We had a meeting about this, but there was not a clear agenda, and it was unclear who would take responsibility for making the final decision. Many of the positions in the meeting had overlap, but ultimately, no decision was made. An email chain begun by a grumpy systems engineer asked what progress was made and when would a ruling be made.


I captured the positions of the team members on how to do the versioning, and I explained in-depth how my solution would cover their needs. In particular, the boundaries of a source repository should not be determined by semantics (or what seems "sensible"), or by how big the repository is, or otherwise. Instead it should be handled by what can be versioned independently. I then broke out all of the components in the new system-of-systems, and how we might proceed implementing it. At the end of my explanation, I asked if this solution was sufficient, or if not, what particular shortcomings it had. Ultimately, the team lead agreed with my position and championed it, so it was implemented.

+``` + +_What does the await operator do in Rust?_ + +``` +

Conceptually, it adds the execution of the future it is called on (some asynchronous task) to the current asynchronous task. If that asynchronous task can complete without blocking, it does so and returns immediately. If it must block, the async runtime may switch to another task.

+``` diff --git a/src/copper_chronicle.md b/src/copper_chronicle.md new file mode 100644 index 0000000..7c6473f --- /dev/null +++ b/src/copper_chronicle.md @@ -0,0 +1 @@ +These are some of my adventures and travels with Copper. From the stunning coastline of Big Sur to mountain adventures in Northern California, these are the stories of our explorations together. diff --git a/src/drafts/events/defcon.md b/src/drafts/events/defcon.md new file mode 100644 index 0000000..02b20d3 --- /dev/null +++ b/src/drafts/events/defcon.md @@ -0,0 +1,5 @@ +# DefCon + +*This article is coming soon.* + +Notes and reflections from DefCon. diff --git a/src/drafts/events/oktoberfest.md b/src/drafts/events/oktoberfest.md new file mode 100644 index 0000000..6771078 --- /dev/null +++ b/src/drafts/events/oktoberfest.md @@ -0,0 +1,5 @@ +# Oktoberfest + +*This article is coming soon.* + +Celebrating traditions and community. diff --git a/src/drafts/faith.md b/src/drafts/faith.md new file mode 100644 index 0000000..742a676 --- /dev/null +++ b/src/drafts/faith.md @@ -0,0 +1,3 @@ +# On Faith as a Classical Virtue + +*This article is coming soon.* diff --git a/src/future_trips.md b/src/future_trips.md new file mode 100644 index 0000000..03e1fe1 --- /dev/null +++ b/src/future_trips.md @@ -0,0 +1,28 @@ +# Future Trips + +- Malta +- Baja +- Falklands +- Hawaii +- Costa Rica +- Medellin, Colombia +- Bahamas +- American Samoa + +# National Parks + +These national parks are **off** the list. + +- Bryce Canyon +- Redwoods + +# State Parks + +These state parks are **off** the list. + +- Alcatraz +- Antelope Island +- Castle Crags +- Folsom Lake SRA +- Muir Woods +- Pismo State Beach diff --git a/src/menu.md b/src/menu.md new file mode 100644 index 0000000..f6aff95 --- /dev/null +++ b/src/menu.md @@ -0,0 +1,61 @@ +# Menu + +A curated selection from our recipe collection. + +## ☕ Beverages + +- [Pour-Over Black Coffee](recipes/beverages/pour-over-black-coffee.md) + *Coffee beans, hot water* +- [London Fog](recipes/beverages/london-fog.md) + *Earl Grey tea, manuka honey, steamed milk* +- [French Press Black Coffee](recipes/beverages/french-press-black-coffee.md) + *Coarse ground coffee, hot water* +- [Milkshake](recipes/beverages/milkshake.md) + *Heavy cream, milk, blackberries, Medjool dates, vanilla whey protein, vanilla extract, manuka honey, peanut butter* + +## 🥖 Appetizers + +- [Artichoke Spinach Dip](recipes/appetizers/artichoke-spinach-dip.md) + *Artichoke hearts, fresh spinach, cashew cream, nutritional yeast, garlic, lemon juice, salt, pepper* +- [Bacon Wrapped Dates](recipes/appetizers/bacon-wrapped-goat-cheese-stuffed-dates.md) + *Medjool dates, goat cheese, bacon strips, optional honey, optional almonds* + +## 🍞 Baked Goods + +- [Banana Chocolate Chip Bread](recipes/baked-goods/banana-chocolate-chip-bread.md) + *Ripe bananas, flour, sugar or sweetener, eggs, butter or oil, chocolate chips, baking soda, vanilla extract, salt* + +## 🍳 Breakfast + +- [Egg Scramble](recipes/breakfast/egg-scramble-sweet-potato-black-bean-ground-beef.md) + *Eggs, ground beef, sweet potato, black beans, green enchilada sauce, onions, cumin, chili powder* +- [Proplto Pancakes](recipes/breakfast/protein-purple-potato-pancakes.md) + *Purple potatoes, eggs, protein powder, oat flour, baking powder, cinnamon, salt, milk* + +## 🎄 Seasonal Favorites + +- [Eggnog](recipes/christmas/eggnog.md) + *Raw cultured cream, raw eggs, vanilla extract, nutmeg, raw honey, peppermint tea, cacao nibs* +- [Gingerbread Fruitcake Muffins](recipes/christmas/gingerbread-fruitcake-muffins.md) + *Pastry flour, baking soda, buttermilk, butter, allulose, eggs, molasses, dried fruits, chopped nuts, cinnamon, cloves, ginger, salt, vanilla extract* + +## 🍨 Desserts + +- [Roasted Peaches](recipes/desserts/roasted-peaches-with-honey-mint-and-ice-cream.md) + *Fresh peaches, honey, fresh mint leaves, vanilla ice cream, butter, optional cinnamon* + +## 🍽️ Main Dishes + +- [Pistachio Liver Burgers](recipes/meals/pistachio-encrusted-liver-burgers.md) + *Beef liver, lion's mane mushrooms, ground beef, crushed pistachios, seasonings* +- [Salmon Bowl](recipes/meals/salmon-bowl.md) + *Salmon fillet, coconut rice, cabbage slaw, fresh mango, sesame seeds* +- [Steak & Air-Fried Broccoli](recipes/meals/steak-and-air-fried-broccoli.md) + *Steak, fresh broccoli florets, olive oil, salt, pepper, garlic powder* + +## 🥗 Sides + +- [Roasted Vegetables](recipes/sides/roasted-vegetables.md) + *Mixed vegetables (Brussels sprouts, carrots, bell peppers, zucchini), olive oil, salt, pepper, herbs (rosemary, thyme), garlic* +- [Cabbage Steaks](recipes/sides/cabbage-steaks.md) + *Cabbage, olive oil, salt, pepper, garlic powder, optional balsamic glaze* diff --git a/src/private b/src/private new file mode 160000 index 0000000..28cfe76 --- /dev/null +++ b/src/private @@ -0,0 +1 @@ +Subproject commit 28cfe7618cc6babe24b12de6620e066af402e4e9 diff --git a/src/recipes/README.md b/src/recipes/README.md new file mode 100644 index 0000000..88d71d4 --- /dev/null +++ b/src/recipes/README.md @@ -0,0 +1 @@ +This is a growing collection. From holiday traditions to camping food, these recipes have been tested and enjoyed with friends and family. diff --git a/src/recipes/appetizers/README.md b/src/recipes/appetizers/README.md new file mode 100644 index 0000000..66ad221 --- /dev/null +++ b/src/recipes/appetizers/README.md @@ -0,0 +1,6 @@ +# Appetizers + +Starters and finger foods. + +- [Artichoke Spinach Dip (GF & DF)](artichoke-spinach-dip.md) +- [Bacon Wrapped Goat Cheese Stuffed Dates](bacon-wrapped-goat-cheese-stuffed-dates.md) diff --git a/src/recipes/appetizers/artichoke-spinach-dip.md b/src/recipes/appetizers/artichoke-spinach-dip.md new file mode 100644 index 0000000..7f7a24b --- /dev/null +++ b/src/recipes/appetizers/artichoke-spinach-dip.md @@ -0,0 +1,21 @@ +*Source: Abby* + +## Description +Gluten-free and dairy-free version. + +## Ingredients +- Artichoke hearts, chopped +- Fresh spinach +- Cashew cream or dairy-free cream cheese +- Nutritional yeast +- Garlic +- Lemon juice +- Salt, pepper +- Optional: dairy-free parmesan + +## Instructions +1. Sauté spinach and garlic until wilted. +2. Mix with chopped artichokes and cashew cream. +3. Add nutritional yeast, lemon juice, seasonings. +4. Bake at 350°F for 20 minutes until bubbly. +5. Serve with crackers or vegetables. diff --git a/src/recipes/appetizers/bacon-wrapped-goat-cheese-stuffed-dates.md b/src/recipes/appetizers/bacon-wrapped-goat-cheese-stuffed-dates.md new file mode 100644 index 0000000..91b1453 --- /dev/null +++ b/src/recipes/appetizers/bacon-wrapped-goat-cheese-stuffed-dates.md @@ -0,0 +1,14 @@ +*Source: Abby* + +## Ingredients +- Medjool dates, pitted +- Goat cheese +- Bacon strips, cut in half +- Optional: honey for drizzling +- Optional: almonds to stuff inside + +## Instructions +1. Stuff each date with goat cheese (and almond if using). +2. Wrap with half strip of bacon, secure with toothpick. +3. Bake at 400°F for 15-20 minutes until bacon is crispy. +4. Optional: drizzle with honey before serving. diff --git a/src/recipes/baked-goods/README.md b/src/recipes/baked-goods/README.md new file mode 100644 index 0000000..947827e --- /dev/null +++ b/src/recipes/baked-goods/README.md @@ -0,0 +1,9 @@ +# Baked Goods + +Breads, muffins, and bars. + +- [Zucchini and Chocolate Chip Bread](zucchini-and-chocolate-chip-bread.md) +- [Carrot, Fig, Macadamia Bread/Bricks](carrot-fig-macadamia-bread.md) +- [Purple Potato, Pecan Bread/Bricks](purple-potato-pecan-bread.md) +- [Chocolate Mint Protein Gunk Bars](chocolate-mint-protein-gunk-bars.md) +- [Banana Chocolate Chip Bread](banana-chocolate-chip-bread.md) diff --git a/src/recipes/baked-goods/banana-chocolate-chip-bread.md b/src/recipes/baked-goods/banana-chocolate-chip-bread.md new file mode 100644 index 0000000..936e252 --- /dev/null +++ b/src/recipes/baked-goods/banana-chocolate-chip-bread.md @@ -0,0 +1,13 @@ +*Source: Abby* + +## Ingredients +- Ripe bananas, mashed (3-4) +- Flour +- Sugar or sweetener +- Eggs +- Butter or oil +- Chocolate chips +- Baking soda +- Vanilla extract +- Salt +- Optional: walnuts diff --git a/src/recipes/baked-goods/carrot-fig-macadamia-bread.md b/src/recipes/baked-goods/carrot-fig-macadamia-bread.md new file mode 100644 index 0000000..af68368 --- /dev/null +++ b/src/recipes/baked-goods/carrot-fig-macadamia-bread.md @@ -0,0 +1,14 @@ +*Source: Abby* + +## Ingredients +- Grated carrots +- Dried figs, chopped +- Macadamia nuts, chopped +- Flour +- Eggs +- Oil or butter +- Sweetener +- Baking powder +- Spices (cinnamon, nutmeg, ginger) +- Vanilla extract +- Salt diff --git a/src/recipes/baked-goods/chocolate-mint-protein-gunk-bars.md b/src/recipes/baked-goods/chocolate-mint-protein-gunk-bars.md new file mode 100644 index 0000000..5d3cec1 --- /dev/null +++ b/src/recipes/baked-goods/chocolate-mint-protein-gunk-bars.md @@ -0,0 +1,17 @@ +*Source: Abby* + +## Ingredients +- Protein powder (chocolate) +- Oats +- Nut butter (peanut or almond) +- Honey or maple syrup +- Cocoa powder +- Peppermint extract +- Dark chocolate chips +- Salt + +## Instructions +1. Mix all ingredients until well combined. +2. Press into pan lined with parchment. +3. Refrigerate until firm, cut into bars. +4. Store in fridge or freezer. diff --git a/src/recipes/baked-goods/purple-potato-pecan-bread.md b/src/recipes/baked-goods/purple-potato-pecan-bread.md new file mode 100644 index 0000000..03ffd10 --- /dev/null +++ b/src/recipes/baked-goods/purple-potato-pecan-bread.md @@ -0,0 +1,13 @@ +*Source: Abby* + +## Ingredients +- Purple potatoes, cooked and mashed +- Pecans, chopped +- Flour +- Eggs +- Oil or butter +- Sweetener +- Baking powder +- Cinnamon +- Vanilla extract +- Salt diff --git a/src/recipes/baked-goods/zucchini-and-chocolate-chip-bread.md b/src/recipes/baked-goods/zucchini-and-chocolate-chip-bread.md new file mode 100644 index 0000000..4a36b63 --- /dev/null +++ b/src/recipes/baked-goods/zucchini-and-chocolate-chip-bread.md @@ -0,0 +1,13 @@ +*Source: Abby* + +## Ingredients +- Grated zucchini (about 2 cups) +- Flour +- Sugar or sweetener +- Eggs +- Oil or butter +- Chocolate chips +- Baking soda +- Cinnamon +- Vanilla extract +- Salt diff --git a/src/recipes/beverages/README.md b/src/recipes/beverages/README.md new file mode 100644 index 0000000..48d9087 --- /dev/null +++ b/src/recipes/beverages/README.md @@ -0,0 +1,8 @@ +# Beverages + +Coffee, tea, and other drinks for all year round. + +- [Pour-Over Black Coffee](pour-over-black-coffee.md) +- [London Fog](london-fog.md) +- [French Press Black Coffee](french-press-black-coffee.md) +- [Milkshake](milkshake.md) diff --git a/src/recipes/beverages/french-press-black-coffee.md b/src/recipes/beverages/french-press-black-coffee.md new file mode 100644 index 0000000..1b5c3f8 --- /dev/null +++ b/src/recipes/beverages/french-press-black-coffee.md @@ -0,0 +1,13 @@ +*Source: Matt* + +## Ingredients +- 30g coarse ground coffee +- 500ml hot water (195-205°F) + +## Instructions +1. Add ground coffee to French press. +2. Pour hot water over grounds, stir gently. +3. Place lid on press, don't plunge yet. +4. Steep for 4 minutes. +5. Slowly press plunger down. +6. Serve immediately. diff --git a/src/recipes/beverages/london-fog.md b/src/recipes/beverages/london-fog.md new file mode 100644 index 0000000..f6aa621 --- /dev/null +++ b/src/recipes/beverages/london-fog.md @@ -0,0 +1,15 @@ +*Source: Matt* + +## Ingredients +- 1 Earl Grey tea bag +- 1 cup hot water +- 1/2 cup steamed milk +- 1 tsp manuka honey +- Optional: vanilla extract + +## Instructions +1. Steep Earl Grey tea in hot water for 3-4 minutes. +2. Steam or heat milk until frothy. +3. Remove tea bag, stir in honey. +4. Pour steamed milk over tea. +5. Optional: add a drop of vanilla extract. diff --git a/src/recipes/beverages/milkshake.md b/src/recipes/beverages/milkshake.md new file mode 100644 index 0000000..2f31137 --- /dev/null +++ b/src/recipes/beverages/milkshake.md @@ -0,0 +1,11 @@ +*Source: Matt* + +## Ingredients +- 240ml heavy cream +- 120ml milk +- 120g blackberries +- 100g Medjool dates +- 30g vanilla whey protein +- 5ml vanilla extract +- 10g manuka honey +- 2 tbsp peanut butter diff --git a/src/recipes/beverages/pour-over-black-coffee.md b/src/recipes/beverages/pour-over-black-coffee.md new file mode 100644 index 0000000..790f495 --- /dev/null +++ b/src/recipes/beverages/pour-over-black-coffee.md @@ -0,0 +1,12 @@ +*Source: Matt* + +## Ingredients +- 20-25g freshly ground coffee (medium-fine grind) +- 350ml hot water (195-205°F) + +## Instructions +1. Place filter in dripper, rinse with hot water. +2. Add ground coffee, create small well in center. +3. Pour 50ml water in circular motion, let bloom 30 seconds. +4. Continue pouring in slow circles until reaching 350ml total. +5. Total brew time: 2.5-3.5 minutes. diff --git a/src/recipes/breakfast/README.md b/src/recipes/breakfast/README.md new file mode 100644 index 0000000..1098a81 --- /dev/null +++ b/src/recipes/breakfast/README.md @@ -0,0 +1,8 @@ +# Breakfast Recipes + +Morning meals to start your day. + +- [German Pancakes (Crepes)](german-pancakes.md) +- [Pancake, Fried Ham, Runny Egg, & Avocado](pancake-fried-ham-runny-egg-avocado.md) +- [Egg Scramble with Sweet Potato, Black Bean, & Ground Beef](egg-scramble-sweet-potato-black-bean-ground-beef.md) +- [Protein Purple Potato Pancakes (Proplto Cakes)](protein-purple-potato-pancakes.md) diff --git a/src/recipes/breakfast/egg-scramble-sweet-potato-black-bean-ground-beef.md b/src/recipes/breakfast/egg-scramble-sweet-potato-black-bean-ground-beef.md new file mode 100644 index 0000000..8993a80 --- /dev/null +++ b/src/recipes/breakfast/egg-scramble-sweet-potato-black-bean-ground-beef.md @@ -0,0 +1,16 @@ +*Source: Abby* + +## Ingredients +- Eggs +- Ground beef +- Sweet potato, diced +- Black beans +- Green enchilada sauce +- Onions +- Seasonings (cumin, chili powder) + +## Instructions +1. Cook ground beef with onions and seasonings. +2. Add diced sweet potato, cook until tender. +3. Add black beans and enchilada sauce, heat through. +4. Scramble eggs in the mixture. diff --git a/src/recipes/breakfast/german-pancakes.md b/src/recipes/breakfast/german-pancakes.md new file mode 100644 index 0000000..e0d9832 --- /dev/null +++ b/src/recipes/breakfast/german-pancakes.md @@ -0,0 +1,15 @@ +*Source: Abby* + +## Ingredients +- Eggs +- Milk +- Flour +- Butter +- Salt +- Vanilla extract (optional) + +## Instructions +1. Blend eggs, milk, flour, and salt until smooth. +2. Heat butter in a pan, pour thin layer of batter. +3. Cook until edges lift, flip and cook other side. +4. Serve with jam, cream, or savory fillings. diff --git a/src/recipes/breakfast/pancake-fried-ham-runny-egg-avocado.md b/src/recipes/breakfast/pancake-fried-ham-runny-egg-avocado.md new file mode 100644 index 0000000..742017b --- /dev/null +++ b/src/recipes/breakfast/pancake-fried-ham-runny-egg-avocado.md @@ -0,0 +1,17 @@ +*Source: Abby* + +## Description +A hearty breakfast stack. + +## Ingredients +- Pancake batter +- Ham slices +- Eggs +- Avocado +- Butter for cooking + +## Assembly +1. Cook pancake as base. +2. Fry ham until crispy. +3. Fry egg to desired doneness. +4. Stack: pancake, ham, egg, sliced avocado on top. diff --git a/src/recipes/breakfast/protein-purple-potato-pancakes.md b/src/recipes/breakfast/protein-purple-potato-pancakes.md new file mode 100644 index 0000000..0d6a084 --- /dev/null +++ b/src/recipes/breakfast/protein-purple-potato-pancakes.md @@ -0,0 +1,17 @@ +*Source: Matt* + +## Ingredients +- Purple potatoes, cooked and mashed +- Eggs +- Protein powder (vanilla or unflavored) +- Oat flour +- Baking powder +- Cinnamon +- Salt +- Milk + +## Instructions +1. Mix mashed purple potatoes with eggs. +2. Add protein powder, oat flour, baking powder, cinnamon, salt. +3. Add milk to desired consistency. +4. Cook on griddle like regular pancakes. diff --git a/src/recipes/camping/README.md b/src/recipes/camping/README.md new file mode 100644 index 0000000..78d0923 --- /dev/null +++ b/src/recipes/camping/README.md @@ -0,0 +1,14 @@ +# Camping & Backpacking Recipes + +Trail-ready food for outdoor adventures. + +See [Wikibooks: Camp Cooking](https://en.m.wikibooks.org/wiki/Cookbook:Camp_Cooking) + +- [Cobblestacks v2](cobblestacks-v2.md) +- [Shepherd's Pie](shepherds-pie.md) +- [Curried Cashew Couscous with Chicken](curried-cashew-couscous-with-chicken.md) +- [Miso Salmon & Rice](miso-salmon-and-rice.md) +- [Thanksgiving Meal](thanksgiving-meal.md) +- [Jerky](jerky.md) +- [Veggie Bread](veggie-bread.md) +- [Protein Gunk](protein-gunk.md) diff --git a/src/recipes/camping/cobblestacks-v2.md b/src/recipes/camping/cobblestacks-v2.md new file mode 100644 index 0000000..f3c8c82 --- /dev/null +++ b/src/recipes/camping/cobblestacks-v2.md @@ -0,0 +1,26 @@ +*Source: Matt* + +## Description +Originally from [Eat Sleep Wild](https://eatsleepwild.com/the-best-homemade-energy-bars-for-hiking-and-backpacking/) + +## Ingredients +- 360g mashed banana (about 3 large) +- 1 tsp vanilla extract +- 200g porridge oats +- 90g goji berries +- 50g walnuts +- 30g chia seeds +- 80g pepita seeds +- 60g sliced almonds +- 25g ground flax seed meal +- 1 tsp cinnamon +- 1/4 tsp fine sea salt + +## Instructions +1. Preheat oven to 180°C / 350°F. Grease and line 9″ x 13″ dish with parchment. +2. Mash banana, stir in vanilla. Add remaining ingredients, mix well. +3. Let sit 5-10 minutes for chia to absorb moisture. +4. Press into dish with wet hands until compacted. +5. Bake 22-26 minutes until firm and golden on edges. +6. Cool 10 minutes, lift out, cool completely, slice into bars. +7. Store in fridge for a week or freezer for 4-6 weeks. diff --git a/src/recipes/camping/curried-cashew-couscous-with-chicken.md b/src/recipes/camping/curried-cashew-couscous-with-chicken.md new file mode 100644 index 0000000..a6d29a3 --- /dev/null +++ b/src/recipes/camping/curried-cashew-couscous-with-chicken.md @@ -0,0 +1,9 @@ +*Source: Abby* + +## Ingredients +- Couscous +- Chicken, cooked and dehydrated +- Cashews, chopped +- Curry powder +- Dried vegetables +- Bouillon diff --git a/src/recipes/camping/jerky.md b/src/recipes/camping/jerky.md new file mode 100644 index 0000000..7d588a2 --- /dev/null +++ b/src/recipes/camping/jerky.md @@ -0,0 +1,8 @@ +*Source: Abby* + +## Ingredients +- Lean meat (beef, venison, or turkey) +- Soy sauce or coconut aminos +- Worcestershire sauce +- Spices (garlic, pepper, paprika) +- Optional: liquid smoke diff --git a/src/recipes/camping/miso-salmon-and-rice.md b/src/recipes/camping/miso-salmon-and-rice.md new file mode 100644 index 0000000..6eddc10 --- /dev/null +++ b/src/recipes/camping/miso-salmon-and-rice.md @@ -0,0 +1,8 @@ +*Source: Abby* + +## Ingredients +- Instant rice +- Salmon (canned or dehydrated) +- Miso paste packet +- Dried seaweed +- Sesame seeds diff --git a/src/recipes/camping/protein-gunk.md b/src/recipes/camping/protein-gunk.md new file mode 100644 index 0000000..c955cb4 --- /dev/null +++ b/src/recipes/camping/protein-gunk.md @@ -0,0 +1,14 @@ +*Source: Abby* + +## Description +High-protein no-bake bars for the trail. + +## Ingredients +- Protein powder +- Nut butter +- Honey or dates +- Oats +- Nuts and seeds +- Optional: chocolate chips + +See also: [Backpacker's Shepherd's Pie](https://byucampcooking.blogspot.com/2014/03/backpackers-shepherds-pie.html?m=1) (external link) diff --git a/src/recipes/camping/shepherds-pie.md b/src/recipes/camping/shepherds-pie.md new file mode 100644 index 0000000..44db3dd --- /dev/null +++ b/src/recipes/camping/shepherds-pie.md @@ -0,0 +1,11 @@ +*Source: Abby* + +## Description +Dehydrated backpacking version. + +## Ingredients +- Ground beef or lamb, cooked and dehydrated +- Mashed potatoes (instant or dehydrated) +- Mixed vegetables, dehydrated +- Gravy mix +- Seasonings diff --git a/src/recipes/camping/thanksgiving-meal.md b/src/recipes/camping/thanksgiving-meal.md new file mode 100644 index 0000000..e88042f --- /dev/null +++ b/src/recipes/camping/thanksgiving-meal.md @@ -0,0 +1,11 @@ +*Source: Abby* + +## Description +Dehydrated Thanksgiving dinner for the trail. + +## Ingredients +- Turkey, cooked and dehydrated +- Instant mashed potatoes +- Stuffing mix +- Dried cranberries +- Gravy mix diff --git a/src/recipes/camping/veggie-bread.md b/src/recipes/camping/veggie-bread.md new file mode 100644 index 0000000..ddf19b2 --- /dev/null +++ b/src/recipes/camping/veggie-bread.md @@ -0,0 +1,12 @@ +*Source: Abby* + +## Description +Dense, hearty bread with vegetables for backpacking. + +## Ingredients +- Flour +- Grated vegetables (zucchini, carrot) +- Eggs +- Oil +- Baking powder +- Seasonings diff --git a/src/recipes/christmas/README.md b/src/recipes/christmas/README.md new file mode 100644 index 0000000..09462fa --- /dev/null +++ b/src/recipes/christmas/README.md @@ -0,0 +1,7 @@ +# Christmas Recipes + +Holiday favorites for the festive season. + +- [Eggnog](eggnog.md) +- [Gingerbread Fruitcake (Muffins)](gingerbread-fruitcake-muffins.md) +- [Based Meatloaf](based-meatloaf.md) diff --git a/src/recipes/christmas/based-meatloaf.md b/src/recipes/christmas/based-meatloaf.md new file mode 100644 index 0000000..9975a9f --- /dev/null +++ b/src/recipes/christmas/based-meatloaf.md @@ -0,0 +1,12 @@ +*Source: Matt* + +## Description +From Based Cooking + +## Ingredients +- 2 lbs ground beef +- Beef liver +- Beets +- 4 eggs +- 1/4 cup milk +- Mustard, onion, garlic, tomato, hot sauce diff --git a/src/recipes/christmas/eggnog.md b/src/recipes/christmas/eggnog.md new file mode 100644 index 0000000..be1af7b --- /dev/null +++ b/src/recipes/christmas/eggnog.md @@ -0,0 +1,15 @@ +*Source: Matt* + +## Description +Adapted from [Bumblebee Apothecary](https://bumblebeeapothecary.com/healthy-eggnog-recipe/) + +*Made for Abby and the Leons on December 12, 2024* + +## Ingredients +- 1 cup raw cultured cream +- 2 raw eggs +- 1 tsp vanilla extract +- 1/4 tsp nutmeg +- 3 tsp raw honey +- 4 bags peppermint tea in maybe 1/3 cup water (extract would be better) +- Cacao nibs for garnish diff --git a/src/recipes/christmas/gingerbread-fruitcake-muffins.md b/src/recipes/christmas/gingerbread-fruitcake-muffins.md new file mode 100644 index 0000000..72012fd --- /dev/null +++ b/src/recipes/christmas/gingerbread-fruitcake-muffins.md @@ -0,0 +1,18 @@ +*Source: Matt* + +## Description +Based on [Keeper of the Home](https://keeperofthehome.org/gingerbread-fruitcake/) + +*Be sure to blend dry and wet separately then finally together.* + +## Ingredients +- 3 cups pastry flour +- 1 tsp baking soda +- 1 cup buttermilk +- 1/2 cup butter +- 1/2 cup allulose (brown) +- 2 large eggs +- 1.5 cups unsulphered molasses +- 3 cups dried fruits +- 1 cup chopped nuts +- Cinnamon, cloves, ginger, salt, vanilla extract to taste diff --git a/src/recipes/desserts/README.md b/src/recipes/desserts/README.md new file mode 100644 index 0000000..4d132c4 --- /dev/null +++ b/src/recipes/desserts/README.md @@ -0,0 +1,10 @@ +# Desserts + +Sweet treats and after-dinner delights. + +- [Ruby Cake](ruby-cake.md) +- [Pumpkin Pie](pumpkin-pie.md) +- [Roasted Peaches with Honey, Mint, & Ice Cream](roasted-peaches-with-honey-mint-and-ice-cream.md) +- [Red Wine Pears](red-wine-pears.md) +- [Chocolate Fat Bomb Cookies](chocolate-fat-bomb-cookies.md) +- [Mug Cakes](mug-cakes.md) diff --git a/src/recipes/desserts/chocolate-fat-bomb-cookies.md b/src/recipes/desserts/chocolate-fat-bomb-cookies.md new file mode 100644 index 0000000..73de7db --- /dev/null +++ b/src/recipes/desserts/chocolate-fat-bomb-cookies.md @@ -0,0 +1,14 @@ +*Source: Matt* + +## Description +From Ketoconnect + +## Ingredients +- 1/2 cup erythritol +- 1/2 cup cocoa powder +- 1/4 cup butter +- 2 eggs +- 1 tsp vanilla +- 1 cup almond flour +- 1 tsp baking powder +- Pinch of salt diff --git a/src/recipes/desserts/mug-cakes.md b/src/recipes/desserts/mug-cakes.md new file mode 100644 index 0000000..2922e64 --- /dev/null +++ b/src/recipes/desserts/mug-cakes.md @@ -0,0 +1,4 @@ +*Source: Matt* + +## Description +Originally from Ketoconnect diff --git a/src/recipes/desserts/pumpkin-pie.md b/src/recipes/desserts/pumpkin-pie.md new file mode 100644 index 0000000..b41809e --- /dev/null +++ b/src/recipes/desserts/pumpkin-pie.md @@ -0,0 +1,15 @@ +*Source: Abby* + +## Ingredients +- Pie crust +- Pumpkin puree (fresh or canned) +- Eggs +- Heavy cream or evaporated milk +- Sugar or sweetener +- Cinnamon +- Ginger +- Nutmeg +- Cloves +- Salt + +**See also:** [Pumpkin Pie from Scratch](https://farmhouseharvest.net/pumpkin-pie-from-scratch/) diff --git a/src/recipes/desserts/red-wine-pears.md b/src/recipes/desserts/red-wine-pears.md new file mode 100644 index 0000000..b81bbba --- /dev/null +++ b/src/recipes/desserts/red-wine-pears.md @@ -0,0 +1,16 @@ +*Source: Abby* + +## Ingredients +- Pears, peeled (stems intact) +- Red wine +- Sugar or honey +- Cinnamon stick +- Star anise +- Vanilla bean or extract +- Orange peel + +## Instructions +1. Combine wine, sweetener, and spices in pot. +2. Add pears, simmer 20-30 minutes, turning occasionally. +3. Remove pears, reduce liquid to syrup. +4. Serve pears with syrup drizzled over. diff --git a/src/recipes/desserts/roasted-peaches-with-honey-mint-and-ice-cream.md b/src/recipes/desserts/roasted-peaches-with-honey-mint-and-ice-cream.md new file mode 100644 index 0000000..2937526 --- /dev/null +++ b/src/recipes/desserts/roasted-peaches-with-honey-mint-and-ice-cream.md @@ -0,0 +1,15 @@ +*Source: Abby* + +## Ingredients +- Fresh peaches, halved and pitted +- Honey +- Fresh mint leaves +- Vanilla ice cream +- Butter +- Optional: cinnamon + +## Instructions +1. Place peach halves cut-side up in baking dish. +2. Drizzle with honey, dot with butter. +3. Roast at 375°F for 20-25 minutes until tender. +4. Serve warm with ice cream and fresh mint. diff --git a/src/recipes/desserts/ruby-cake.md b/src/recipes/desserts/ruby-cake.md new file mode 100644 index 0000000..63a7348 --- /dev/null +++ b/src/recipes/desserts/ruby-cake.md @@ -0,0 +1,13 @@ +*Source: Abby* + +## Ingredients +- Flour +- Sugar +- Cocoa powder +- Eggs +- Butter or oil +- Buttermilk +- Red food coloring +- Baking soda +- Vanilla extract +- Salt diff --git a/src/recipes/earth-day/README.md b/src/recipes/earth-day/README.md new file mode 100644 index 0000000..ff69f81 --- /dev/null +++ b/src/recipes/earth-day/README.md @@ -0,0 +1,6 @@ +# Earth Day Recipes + +Made for housemates Ray and Will on April 27th, 2024. + +- [Goat Root Stir Fry](goat-root-stir-fry.md) +- [Compote](compote.md) diff --git a/src/recipes/earth-day/compote.md b/src/recipes/earth-day/compote.md new file mode 100644 index 0000000..7255145 --- /dev/null +++ b/src/recipes/earth-day/compote.md @@ -0,0 +1,12 @@ +*Source: Matt* + +## Ingredients +- One pack raspberries +- One pack blueberries +- One pack blackberries +- 3 tbsp manuka honey + +## Instructions +1. Add all berries to a pot, fill with water until submerged. +2. Bring to a boil, simmer for 20 minutes. +3. Strain or blend, add to pitcher, mix in honey while hot. diff --git a/src/recipes/earth-day/goat-root-stir-fry.md b/src/recipes/earth-day/goat-root-stir-fry.md new file mode 100644 index 0000000..b6ddf98 --- /dev/null +++ b/src/recipes/earth-day/goat-root-stir-fry.md @@ -0,0 +1,29 @@ +*Source: Matt* + +## Ingredients + +**The Meat:** +- Lamb loin chop +- Lamb shoulder chop +- Lamb leg chop + +**The Base:** +- 1 bunch collard greens +- 1 bunch chard +- Coconut aminos + +**The Roots:** +- One turnip +- One radish +- One beet +- One rutabaga +- One parsnip +- One (midsize) carrot + +**Seasoning (in decreasing order):** +- Nutritional yeast +- Dill +- Cumin +- Coriander +- Ginger +- Cardamom diff --git a/src/recipes/fall/README.md b/src/recipes/fall/README.md new file mode 100644 index 0000000..24f8a38 --- /dev/null +++ b/src/recipes/fall/README.md @@ -0,0 +1,9 @@ +# Fall Recipes + +Seasonal recipes celebrating autumn harvest and flavors. + +- [Miso Maple Acorn Squash](miso-maple-acorn-squash.md) +- [Delicata Squash with Parmesan](delicata-squash-with-parmesan.md) +- [Roasted Kabocha Squash](roasted-kabocha-squash.md) +- [Butternut Squash Soup](butternut-squash-soup.md) +- [Spiced and Diced Sweet Potatoes](spiced-and-diced-sweet-potatoes.md) diff --git a/src/recipes/fall/butternut-squash-soup.md b/src/recipes/fall/butternut-squash-soup.md new file mode 100644 index 0000000..98e644e --- /dev/null +++ b/src/recipes/fall/butternut-squash-soup.md @@ -0,0 +1,10 @@ +*Source: Abby* + +## Ingredients +- Butternut squash, cubed +- Onion +- Garlic +- Vegetable or chicken broth +- Coconut milk or cream +- Sage, nutmeg +- Salt, pepper diff --git a/src/recipes/fall/delicata-squash-with-parmesan.md b/src/recipes/fall/delicata-squash-with-parmesan.md new file mode 100644 index 0000000..ac21f5f --- /dev/null +++ b/src/recipes/fall/delicata-squash-with-parmesan.md @@ -0,0 +1,8 @@ +*Source: Abby* + +## Ingredients +- Delicata squash, sliced in rings +- Olive oil +- Parmesan cheese, grated +- Salt, pepper +- Fresh herbs (optional) diff --git a/src/recipes/fall/miso-maple-acorn-squash.md b/src/recipes/fall/miso-maple-acorn-squash.md new file mode 100644 index 0000000..d6af7dd --- /dev/null +++ b/src/recipes/fall/miso-maple-acorn-squash.md @@ -0,0 +1,14 @@ +*Source: Abby* + +## Ingredients +- Acorn squash, halved +- Miso paste +- Maple syrup +- Butter +- Sesame seeds + +## Instructions +1. Roast squash halves at 400°F for 30 minutes. +2. Mix miso, maple syrup, and melted butter. +3. Brush mixture on squash, roast 10 more minutes. +4. Garnish with sesame seeds. diff --git a/src/recipes/fall/roasted-kabocha-squash.md b/src/recipes/fall/roasted-kabocha-squash.md new file mode 100644 index 0000000..adc9284 --- /dev/null +++ b/src/recipes/fall/roasted-kabocha-squash.md @@ -0,0 +1,7 @@ +*Source: Abby* + +## Ingredients +- Kabocha squash, cut into wedges +- Olive oil +- Salt +- Optional: honey, cinnamon diff --git a/src/recipes/fall/spiced-and-diced-sweet-potatoes.md b/src/recipes/fall/spiced-and-diced-sweet-potatoes.md new file mode 100644 index 0000000..2d114a0 --- /dev/null +++ b/src/recipes/fall/spiced-and-diced-sweet-potatoes.md @@ -0,0 +1,9 @@ +*Source: Matt* + +## Ingredients +- Sweet potatoes, diced +- Olive oil +- Cinnamon +- Nutmeg +- Ginger +- Salt diff --git a/src/recipes/meals/README.md b/src/recipes/meals/README.md new file mode 100644 index 0000000..6b0db19 --- /dev/null +++ b/src/recipes/meals/README.md @@ -0,0 +1,15 @@ +# Meals + +Main dishes and complete meals for everyday cooking. + +- [Meatloaf, Purple Cabbage Slaw, & Parsnip Puree](meatloaf-purple-cabbage-slaw-parsnip-puree.md) +- [Pistachio Encrusted Liver Burgers](pistachio-encrusted-liver-burgers.md) +- [Greek Bowls](greek-bowls.md) +- [Miso Oats with Ground Beef](miso-oats-with-ground-beef.md) +- [Salmon Bowl](salmon-bowl.md) +- [Pad Se Ew](pad-se-ew.md) +- [Sushi](sushi.md) +- [Pesto Chicken and Spaghetti Squash](pesto-chicken-and-spaghetti-squash.md) +- [Steak & Air-Fried Broccoli](steak-and-air-fried-broccoli.md) +- [Apple Salmon Salad](apple-salmon-salad.md) +- [Peanut Butter Chicken](peanut-butter-chicken.md) diff --git a/src/recipes/meals/apple-salmon-salad.md b/src/recipes/meals/apple-salmon-salad.md new file mode 100644 index 0000000..00e94be --- /dev/null +++ b/src/recipes/meals/apple-salmon-salad.md @@ -0,0 +1,10 @@ +*Source: Abby* + +## Ingredients +- Cooked salmon +- Mixed greens +- Apple, diced +- Celery, chopped +- Red onion, diced +- Walnuts +- Lemon vinaigrette diff --git a/src/recipes/meals/greek-bowls.md b/src/recipes/meals/greek-bowls.md new file mode 100644 index 0000000..d1ab0a7 --- /dev/null +++ b/src/recipes/meals/greek-bowls.md @@ -0,0 +1,10 @@ +*Source: Abby* + +## Ingredients +- Protein of choice +- Cucumber +- Tomatoes +- Red onion +- Feta cheese +- Olives +- Tzatziki sauce diff --git a/src/recipes/meals/meatloaf-purple-cabbage-slaw-parsnip-puree.md b/src/recipes/meals/meatloaf-purple-cabbage-slaw-parsnip-puree.md new file mode 100644 index 0000000..263bb06 --- /dev/null +++ b/src/recipes/meals/meatloaf-purple-cabbage-slaw-parsnip-puree.md @@ -0,0 +1,24 @@ +*Source: Abby* + +## Description +A complete meal with meatloaf, colorful slaw, and creamy root vegetable puree. + +## Ingredients + +**Meatloaf:** +- Ground beef +- Eggs +- Breadcrumbs or oats +- Onion, garlic +- Seasonings + +**Purple Cabbage Slaw:** +- Purple cabbage, shredded +- Carrots, shredded +- Vinegar-based dressing + +**Parsnip Puree:** +- Parsnips, peeled and chopped +- Butter +- Cream or milk +- Salt, pepper diff --git a/src/recipes/meals/miso-oats-with-ground-beef.md b/src/recipes/meals/miso-oats-with-ground-beef.md new file mode 100644 index 0000000..0d588c4 --- /dev/null +++ b/src/recipes/meals/miso-oats-with-ground-beef.md @@ -0,0 +1,8 @@ +*Source: Abby* + +## Ingredients +- Rolled oats +- Ground beef +- Miso paste +- Scallions +- Seasonings diff --git a/src/recipes/meals/pad-se-ew.md b/src/recipes/meals/pad-se-ew.md new file mode 100644 index 0000000..5709dcf --- /dev/null +++ b/src/recipes/meals/pad-se-ew.md @@ -0,0 +1,15 @@ +*Source: Abby* + +## Description +Thai stir-fried noodle dish. + +## Ingredients +- Wide rice noodles +- Protein (chicken, beef, or tofu) +- Chinese broccoli (gai lan) +- Eggs +- Dark soy sauce +- Light soy sauce +- Oyster sauce +- Sugar +- Garlic diff --git a/src/recipes/meals/peanut-butter-chicken.md b/src/recipes/meals/peanut-butter-chicken.md new file mode 100644 index 0000000..d17846c --- /dev/null +++ b/src/recipes/meals/peanut-butter-chicken.md @@ -0,0 +1,11 @@ +*Source: Matt* + +## Ingredients +- Chicken pieces +- Natural peanut butter +- Coconut milk +- Soy sauce +- Garlic +- Ginger +- Lime juice +- Vegetables (bell peppers, carrots) diff --git a/src/recipes/meals/pesto-chicken-and-spaghetti-squash.md b/src/recipes/meals/pesto-chicken-and-spaghetti-squash.md new file mode 100644 index 0000000..8c5e824 --- /dev/null +++ b/src/recipes/meals/pesto-chicken-and-spaghetti-squash.md @@ -0,0 +1,9 @@ +*Source: Abby* + +## Ingredients +- Chicken breast +- Spaghetti squash +- Basil pesto +- Parmesan cheese +- Cherry tomatoes +- Garlic diff --git a/src/recipes/meals/pistachio-encrusted-liver-burgers.md b/src/recipes/meals/pistachio-encrusted-liver-burgers.md new file mode 100644 index 0000000..6fa0518 --- /dev/null +++ b/src/recipes/meals/pistachio-encrusted-liver-burgers.md @@ -0,0 +1,8 @@ +*Source: Abby* + +## Ingredients +- Beef liver +- Lion's mane mushrooms +- Ground beef +- Crushed pistachios +- Seasonings diff --git a/src/recipes/meals/salmon-bowl.md b/src/recipes/meals/salmon-bowl.md new file mode 100644 index 0000000..50a6787 --- /dev/null +++ b/src/recipes/meals/salmon-bowl.md @@ -0,0 +1,8 @@ +*Source: Abby* + +## Ingredients +- Salmon fillet +- Coconut rice +- Cabbage slaw +- Fresh mango +- Sesame seeds diff --git a/src/recipes/meals/steak-and-air-fried-broccoli.md b/src/recipes/meals/steak-and-air-fried-broccoli.md new file mode 100644 index 0000000..b87287b --- /dev/null +++ b/src/recipes/meals/steak-and-air-fried-broccoli.md @@ -0,0 +1,8 @@ +*Source: Abby* + +## Ingredients +- Steak (your preferred cut) +- Fresh broccoli florets +- Olive oil +- Salt, pepper +- Garlic powder diff --git a/src/recipes/meals/sushi.md b/src/recipes/meals/sushi.md new file mode 100644 index 0000000..1f7a8d2 --- /dev/null +++ b/src/recipes/meals/sushi.md @@ -0,0 +1,15 @@ +*Source: Abby* + +## Description +Homemade sushi rolls. + +## Ingredients +- Sushi rice +- Nori sheets +- Fresh fish (salmon, tuna) +- Avocado +- Cucumber +- Rice vinegar +- Soy sauce +- Wasabi +- Pickled ginger diff --git a/src/recipes/misc/README.md b/src/recipes/misc/README.md new file mode 100644 index 0000000..797a9f3 --- /dev/null +++ b/src/recipes/misc/README.md @@ -0,0 +1,28 @@ +# Miscellaneous Recipes + +Drinks, snacks, sides, and external links. + +## Quick Tips + +- Salt garlic before mincing +- Wet tortillas before frying + +## Recipes + +- [Balsamic Glazed Brussels Sprouts](balsamic-glazed-brussels-sprouts.md) +- [Bone Broth](bone-broth.md) + +## External Recipe Links + +### From Wikibooks Cookbook +- [Blackberry Oat Bars (Gluten-Free)](https://en.m.wikibooks.org/wiki/Cookbook:Blackberry_Oat_Bars_(Gluten-Free)) +- [Oatmeal Muffins](https://en.m.wikibooks.org/wiki/Cookbook:Oatmeal_Muffins) +- [Anzac Biscuits I](https://en.m.wikibooks.org/wiki/Cookbook:Anzac_Biscuits_I) + +### Other Links +- [Oatmeal Pancakes](https://based.cooking/oatmeal-pancakes/) (Based Cooking) +- [Pumpkin Pie from Scratch](https://farmhouseharvest.net/pumpkin-pie-from-scratch/) +- [Protein Bread](https://theeastcoastkitchen.com/protein-bread/) +- [Beef Tallow](https://heygrillhey.com/beef-tallow/) +- [Guide for Substituting Eggs](https://www.kingarthurbaking.com/blog/2021/01/21/guide-for-substituting-eggs-best-egg-replacers) +- [Backpacker's Shepherd's Pie](https://byucampcooking.blogspot.com/2014/03/backpackers-shepherds-pie.html?m=1) diff --git a/src/recipes/misc/balsamic-glazed-brussels-sprouts.md b/src/recipes/misc/balsamic-glazed-brussels-sprouts.md new file mode 100644 index 0000000..5028e5a --- /dev/null +++ b/src/recipes/misc/balsamic-glazed-brussels-sprouts.md @@ -0,0 +1,12 @@ +*Source: Matt* + +## Ingredients +- 1.5 lbs Brussels sprouts (halved) +- 3 tbsp olive oil +- Salt & pepper +- 3 tbsp balsamic vinegar +- 1-2 tbsp honey +- 2 cloves garlic + +## Instructions +Roast Brussels sprouts with oil at 400°F for 20-25 min. Make glaze by simmering vinegar, honey, and garlic 3-5 min. Toss and serve. diff --git a/src/recipes/misc/bone-broth.md b/src/recipes/misc/bone-broth.md new file mode 100644 index 0000000..b4ce200 --- /dev/null +++ b/src/recipes/misc/bone-broth.md @@ -0,0 +1,18 @@ +*Source: Abby* + +## Ingredients +- Beef, chicken, or lamb bones (with marrow) +- Water +- Apple cider vinegar (2-3 tbsp) +- Vegetables (onions, carrots, celery) +- Herbs (bay leaf, thyme, parsley) +- Salt, peppercorns + +## Instructions +1. Roast bones at 400°F for 30 minutes. +2. Place bones in large pot, cover with water. +3. Add vinegar, let sit 30 minutes. +4. Bring to boil, reduce to simmer. +5. Simmer 12-24 hours (beef), 8-12 hours (chicken). +6. Add vegetables and herbs last 2 hours. +7. Strain, season, store or freeze. diff --git a/src/recipes/sides/README.md b/src/recipes/sides/README.md new file mode 100644 index 0000000..e4f8700 --- /dev/null +++ b/src/recipes/sides/README.md @@ -0,0 +1,10 @@ +# Side Dishes + +Vegetables, salads, and accompaniments for all year round. + +- [Stuffing](stuffing.md) +- [Vinaigrette](vinaigrette.md) +- [Kale Dish](kale-dish.md) +- [Roasted Vegetables](roasted-vegetables.md) +- [Cabbage Steaks](cabbage-steaks.md) +- [Coconut Rice](coconut-rice.md) diff --git a/src/recipes/sides/cabbage-steaks.md b/src/recipes/sides/cabbage-steaks.md new file mode 100644 index 0000000..13a42f0 --- /dev/null +++ b/src/recipes/sides/cabbage-steaks.md @@ -0,0 +1,13 @@ +*Source: Matt* + +## Ingredients +- Cabbage, cut into thick slices +- Olive oil +- Salt, pepper +- Garlic powder +- Optional: balsamic glaze + +## Instructions +1. Brush cabbage steaks with oil, season. +2. Roast at 400°F for 25-30 minutes, flipping once. +3. Drizzle with balsamic if desired. diff --git a/src/recipes/sides/coconut-rice.md b/src/recipes/sides/coconut-rice.md new file mode 100644 index 0000000..c65b909 --- /dev/null +++ b/src/recipes/sides/coconut-rice.md @@ -0,0 +1,8 @@ +*Source: Abby* + +## Ingredients +- White or jasmine rice +- Coconut milk +- Water +- Salt +- Optional: lime zest, cilantro diff --git a/src/recipes/sides/kale-dish.md b/src/recipes/sides/kale-dish.md new file mode 100644 index 0000000..5a4f6fd --- /dev/null +++ b/src/recipes/sides/kale-dish.md @@ -0,0 +1,9 @@ +*Source: Abby* + +## Ingredients +- Kale, chopped +- Garlic +- Olive oil +- Lemon juice +- Red pepper flakes +- Parmesan (optional) diff --git a/src/recipes/sides/roasted-vegetables.md b/src/recipes/sides/roasted-vegetables.md new file mode 100644 index 0000000..dfd8bd5 --- /dev/null +++ b/src/recipes/sides/roasted-vegetables.md @@ -0,0 +1,8 @@ +*Source: Abby* + +## Ingredients +- Mixed vegetables (Brussels sprouts, carrots, bell peppers, zucchini) +- Olive oil +- Salt, pepper +- Herbs (rosemary, thyme) +- Garlic diff --git a/src/recipes/sides/stuffing.md b/src/recipes/sides/stuffing.md new file mode 100644 index 0000000..5b4c13e --- /dev/null +++ b/src/recipes/sides/stuffing.md @@ -0,0 +1,10 @@ +*Source: Abby* + +## Ingredients +- Bread cubes (day-old) +- Celery +- Onions +- Butter +- Broth +- Herbs (sage, thyme, parsley) +- Eggs diff --git a/src/recipes/sides/vinaigrette.md b/src/recipes/sides/vinaigrette.md new file mode 100644 index 0000000..8acf3f2 --- /dev/null +++ b/src/recipes/sides/vinaigrette.md @@ -0,0 +1,12 @@ +*Source: Abby* + +## Description +Basic salad dressing. + +## Ingredients +- Olive oil (3 parts) +- Vinegar or lemon juice (1 part) +- Dijon mustard +- Honey +- Salt, pepper +- Garlic (optional) diff --git a/src/recipes/slow-cooker/README.md b/src/recipes/slow-cooker/README.md new file mode 100644 index 0000000..2b04205 --- /dev/null +++ b/src/recipes/slow-cooker/README.md @@ -0,0 +1,16 @@ +# Slow Cooker & Crock Pot Recipes + +Hearty meals for the slow cooker. + +- [Beef Kombucha Squash Red Curry](beef-kombucha-squash-red-curry.md) +- [Balsamic Chicken and Sausage](balsamic-chicken-and-sausage.md) +- [Pot Roast](pot-roast.md) +- [Chicken Sweet Yellow Curry with Cauliflower Rice](chicken-sweet-yellow-curry-with-cauliflower-rice.md) +- [Beef Shank and Lentil Indian Curry](beef-shank-and-lentil-indian-curry.md) +- [Pork Roast or Ribs with Butternut Squash](pork-roast-or-ribs-with-butternut-squash.md) +- [Gumbo](gumbo.md) +- [Lamb Roasted Roman Style](lamb-roasted-roman-style.md) +- [Taco Soup](taco-soup.md) +- [Turkey Chili](turkey-chili.md) +- [Chicken Tortilla Soup](chicken-tortilla-soup.md) +- [Oxtail Stew](oxtail-stew.md) diff --git a/src/recipes/slow-cooker/balsamic-chicken-and-sausage.md b/src/recipes/slow-cooker/balsamic-chicken-and-sausage.md new file mode 100644 index 0000000..b50b864 --- /dev/null +++ b/src/recipes/slow-cooker/balsamic-chicken-and-sausage.md @@ -0,0 +1,9 @@ +*Source: Abby* + +## Ingredients +- Chicken pieces +- Italian sausage +- Balsamic vinegar +- Garlic +- Onions +- Herbs (rosemary, thyme) diff --git a/src/recipes/slow-cooker/beef-kombucha-squash-red-curry.md b/src/recipes/slow-cooker/beef-kombucha-squash-red-curry.md new file mode 100644 index 0000000..289365f --- /dev/null +++ b/src/recipes/slow-cooker/beef-kombucha-squash-red-curry.md @@ -0,0 +1,10 @@ +*Source: Abby* + +## Ingredients +- Beef chunks +- Squash, cubed +- Kombucha +- Red curry paste +- Coconut milk +- Vegetables +- Spices diff --git a/src/recipes/slow-cooker/beef-shank-and-lentil-indian-curry.md b/src/recipes/slow-cooker/beef-shank-and-lentil-indian-curry.md new file mode 100644 index 0000000..7e06b09 --- /dev/null +++ b/src/recipes/slow-cooker/beef-shank-and-lentil-indian-curry.md @@ -0,0 +1,10 @@ +*Source: Abby* + +## Ingredients +- Beef shanks +- Lentils +- Curry spices (turmeric, cumin, coriander, garam masala) +- Tomatoes +- Onions +- Ginger, garlic +- Coconut milk diff --git a/src/recipes/slow-cooker/chicken-sweet-yellow-curry-with-cauliflower-rice.md b/src/recipes/slow-cooker/chicken-sweet-yellow-curry-with-cauliflower-rice.md new file mode 100644 index 0000000..9015a39 --- /dev/null +++ b/src/recipes/slow-cooker/chicken-sweet-yellow-curry-with-cauliflower-rice.md @@ -0,0 +1,10 @@ +*Source: Abby* + +## Ingredients +- Chicken pieces +- Yellow curry paste +- Coconut milk +- Cauliflower rice +- Bell peppers +- Onions +- Ginger, garlic diff --git a/src/recipes/slow-cooker/chicken-tortilla-soup.md b/src/recipes/slow-cooker/chicken-tortilla-soup.md new file mode 100644 index 0000000..af7db8f --- /dev/null +++ b/src/recipes/slow-cooker/chicken-tortilla-soup.md @@ -0,0 +1,13 @@ +*Source: Abby (from Mom)* + +## Ingredients +- Chicken breast +- Black beans +- Corn +- Tomatoes +- Chicken broth +- Onions +- Garlic +- Cumin, chili powder +- Tortilla strips +- Toppings: cheese, avocado, cilantro, lime diff --git a/src/recipes/slow-cooker/gumbo.md b/src/recipes/slow-cooker/gumbo.md new file mode 100644 index 0000000..e9d1ae0 --- /dev/null +++ b/src/recipes/slow-cooker/gumbo.md @@ -0,0 +1,13 @@ +*Source: Abby* + +## Ingredients +- Andouille sausage +- Chicken +- Shrimp +- Okra +- Bell peppers +- Celery +- Onions (the "holy trinity") +- Roux (flour and oil) +- Cajun spices +- Rice for serving diff --git a/src/recipes/slow-cooker/lamb-roasted-roman-style.md b/src/recipes/slow-cooker/lamb-roasted-roman-style.md new file mode 100644 index 0000000..d35dbdd --- /dev/null +++ b/src/recipes/slow-cooker/lamb-roasted-roman-style.md @@ -0,0 +1,10 @@ +*Source: Abby* + +## Ingredients +- Lamb roast +- Garlic +- Rosemary +- Anchovies +- White wine +- Olive oil +- Potatoes diff --git a/src/recipes/slow-cooker/oxtail-stew.md b/src/recipes/slow-cooker/oxtail-stew.md new file mode 100644 index 0000000..725dd9c --- /dev/null +++ b/src/recipes/slow-cooker/oxtail-stew.md @@ -0,0 +1,11 @@ +*Source: Abby* + +## Ingredients +- Oxtails +- Root vegetables (carrots, parsnips, turnips) +- Onions +- Garlic +- Tomatoes +- Beef broth +- Red wine +- Herbs (bay leaf, thyme) diff --git a/src/recipes/slow-cooker/pork-roast-or-ribs-with-butternut-squash.md b/src/recipes/slow-cooker/pork-roast-or-ribs-with-butternut-squash.md new file mode 100644 index 0000000..5352022 --- /dev/null +++ b/src/recipes/slow-cooker/pork-roast-or-ribs-with-butternut-squash.md @@ -0,0 +1,9 @@ +*Source: Abby* + +## Ingredients +- Pork roast or ribs +- Butternut squash, cubed +- Apples +- Onions +- Broth +- Herbs and spices diff --git a/src/recipes/slow-cooker/pot-roast.md b/src/recipes/slow-cooker/pot-roast.md new file mode 100644 index 0000000..747bbfd --- /dev/null +++ b/src/recipes/slow-cooker/pot-roast.md @@ -0,0 +1,10 @@ +*Source: Abby* + +## Ingredients +- Chuck roast +- Potatoes +- Carrots +- Onions +- Beef broth +- Worcestershire sauce +- Herbs diff --git a/src/recipes/slow-cooker/taco-soup.md b/src/recipes/slow-cooker/taco-soup.md new file mode 100644 index 0000000..dd982a8 --- /dev/null +++ b/src/recipes/slow-cooker/taco-soup.md @@ -0,0 +1,12 @@ +*Source: Abby* + +## Ingredients +- Ground beef or turkey +- Black beans +- Pinto beans +- Corn +- Diced tomatoes +- Green chilies +- Taco seasoning +- Beef broth +- Toppings: cheese, sour cream, avocado diff --git a/src/recipes/slow-cooker/turkey-chili.md b/src/recipes/slow-cooker/turkey-chili.md new file mode 100644 index 0000000..504c6cb --- /dev/null +++ b/src/recipes/slow-cooker/turkey-chili.md @@ -0,0 +1,12 @@ +*Source: Abby* + +## Ingredients +- Ground turkey +- Kidney beans +- Black beans +- Tomatoes +- Onions +- Bell peppers +- Chili powder +- Cumin +- Garlic diff --git a/src/recipes/st-patricks-day/README.md b/src/recipes/st-patricks-day/README.md new file mode 100644 index 0000000..e7a74bb --- /dev/null +++ b/src/recipes/st-patricks-day/README.md @@ -0,0 +1,10 @@ +# St. Patrick's Day Recipes + +Traditional Irish recipes for celebrating the green. + +- [Corned Beef and Cabbage (2025)](corned-beef-and-cabbage-2025.md) +- [Corned Beef (2024)](corned-beef-2024.md) +- [Irish Lamb Root Stew (2025)](irish-lamb-root-stew-2025.md) +- [Irish Soda Bread (2024)](irish-soda-bread-2024.md) +- [Irish Green Milkshake (2025)](irish-green-milkshake-2025.md) +- [Irish Whiskey Coffee (2024)](irish-whiskey-coffee-2024.md) diff --git a/src/recipes/st-patricks-day/colcannon.md b/src/recipes/st-patricks-day/colcannon.md new file mode 100644 index 0000000..63f6702 --- /dev/null +++ b/src/recipes/st-patricks-day/colcannon.md @@ -0,0 +1,46 @@ +*A classic Irish comfort dish of creamy mashed potatoes with buttery cabbage — simple, hearty, and satisfying.* + +**Serves:** 4 +**Prep time:** 15 minutes +**Cook time:** 25 minutes + +## Ingredients + +- 1 kg floury potatoes (e.g. Maris Piper or Russet), peeled and quartered +- 300 g green cabbage, finely shredded +- 150 ml buttermilk, warmed +- 60 g unsalted butter +- 6 spring onions (scallions), finely sliced +- 1 tsp salt +- ½ tsp freshly ground black pepper +- 20 g extra butter, to serve + +### Instructions + +1. Boil the potatoes + +Place the potatoes in a large pot of salted cold water. Bring to a boil, then reduce to a steady simmer and cook for **20–25 minutes** until completely tender when pierced with a knife. + +2. Cook the cabbage + +While the potatoes cook, melt half the butter (30 g) in a large pan over medium heat. Add the spring onions and soften for 2 minutes, then add the shredded cabbage with a splash of water. Sauté for **4–5 minutes** until tender but still vibrant green. Season lightly and set aside. + +3. Drain and steam-dry + +Drain the cooked potatoes well, then return them to the hot pot. Let them sit over very low heat for **1–2 minutes** to steam off any excess moisture — this is the key to fluffy mash. + +4. Mash the potatoes + +Mash the potatoes until completely smooth. Gently warm the buttermilk (don't boil), then gradually beat it into the mash along with the remaining 30 g of butter. The mash should be creamy and fluffy. + +5. Combine and season + +Fold the cooked cabbage and spring onion mixture into the mash until evenly combined. Season generously with salt and freshly ground black pepper to taste. + +6. Serve + +Spoon the colcannon into warmed bowls, make a well in the centre of each portion, and add a knob of the extra butter to melt into a golden pool. Serve immediately. + +## Notes + +- Apparently, this is traditionally served with a fried egg on top, or alongside boiled ham, sausages, or Irish bacon for a full meal. \ No newline at end of file diff --git a/src/recipes/st-patricks-day/corned-beef-2024.md b/src/recipes/st-patricks-day/corned-beef-2024.md new file mode 100644 index 0000000..8e38f64 --- /dev/null +++ b/src/recipes/st-patricks-day/corned-beef-2024.md @@ -0,0 +1,14 @@ +*Source: Matt* + +## Ingredients +- Corned beef +- Potatoes +- Salt, pepper, cumin, coriander, cinnamon, nutmeg, ginger + +## Instructions +1. Cut the corned beef into slices. +2. Apply seasoning to all sides. +3. Dice potatoes into one inch pieces. +4. Lay the slices into a crockpot. +5. Garnish with the potatoes. +6. Slow cook. diff --git a/src/recipes/st-patricks-day/corned-beef-and-cabbage-2025.md b/src/recipes/st-patricks-day/corned-beef-and-cabbage-2025.md new file mode 100644 index 0000000..5a84f5c --- /dev/null +++ b/src/recipes/st-patricks-day/corned-beef-and-cabbage-2025.md @@ -0,0 +1,14 @@ +*Source: Matt* + +## Ingredients +- 4 lbs corned beef brisket +- 1 large head of cabbage, cut into wedges +- 2 large onions, quartered +- 1 lb rutabaga, peeled and cut into chunks +- 1 lb celeriac, peeled and cut into chunks +- 2 tbsp mustard seeds +- 2 tbsp whole coriander seeds +- 4 bay leaves +- 1 tbsp ground ginger +- Salt and pepper to taste +- Water for cooking diff --git a/src/recipes/st-patricks-day/irish-green-milkshake-2025.md b/src/recipes/st-patricks-day/irish-green-milkshake-2025.md new file mode 100644 index 0000000..c13f577 --- /dev/null +++ b/src/recipes/st-patricks-day/irish-green-milkshake-2025.md @@ -0,0 +1,31 @@ +*Source: Matt* + +*A clean, minty, naturally green shake with an Irish-inspired spirit.* + +The spinach and matcha together should produce a strong natural green, making food coloring unlikely to be needed. +Goat milk is nods to Ireland's strong dairy tradition. + +**Serves:** 2 + +## Ingredients + +| Amount | Ingredient | +|--------|------------| +| 160ml | heavy cream | +| 120ml | goat milk | +| 20g | baby spinach | +| 12ml | manuka honey | +| 5ml | vanilla extract | +| 2ml | peppermint extract | +| 3g | matcha powder | +| 75g | green apple, cored and chopped (approx. ½ medium) | +| 15g | butterball lettuce leaves | +| 2–3 drops | green food coloring *(optional)* | + +## Method + +1. Wash the spinach, lettuce, and apple. Core and chop the apple. +2. Pour the heavy cream and goat milk into a blender, then add the honey, vanilla extract, peppermint extract, and matcha powder. +3. Add the spinach, apple, and lettuce. +4. Blend on high until completely smooth, about 60 seconds. +5. Taste and adjust honey if needed. Add food coloring only if a more vivid green is desired. Pour into a chilled glass and serve immediately. diff --git a/src/recipes/st-patricks-day/irish-lamb-root-stew-2025.md b/src/recipes/st-patricks-day/irish-lamb-root-stew-2025.md new file mode 100644 index 0000000..ade279d --- /dev/null +++ b/src/recipes/st-patricks-day/irish-lamb-root-stew-2025.md @@ -0,0 +1,14 @@ +*Source: Matt* + +## Ingredients +- 4 lbs lamb shoulder, cut into 1.5-inch cubes +- 1/4 cup olive oil +- 8 cups bone broth +- 6 cloves garlic, minced +- 2 lbs turnips, peeled and cut into chunks +- 1 lb carrots, peeled and cut into chunks +- 1 lb parsnips, peeled and cut into chunks +- 2 tbsp fresh thyme leaves +- 1/4 cup fresh parsley, chopped +- 1 tsp ground cardamom +- Salt and pepper to taste diff --git a/src/recipes/st-patricks-day/irish-soda-bread-2024.md b/src/recipes/st-patricks-day/irish-soda-bread-2024.md new file mode 100644 index 0000000..6643e98 --- /dev/null +++ b/src/recipes/st-patricks-day/irish-soda-bread-2024.md @@ -0,0 +1,14 @@ +*Source: Matt* + +## Ingredients +- 170g wholemeal flour +- 170g plain flour +- 1/2 tsp salt +- 1/2 tsp baking soda +- 290ml buttermilk + +## Instructions +1. Mix together the dry ingredients. +2. Knead and flatten on a floury surface. +3. Cut a cross in the top of each loaf. +4. Bake at 280°C for 30 minutes. diff --git a/src/recipes/st-patricks-day/irish-whiskey-coffee-2024.md b/src/recipes/st-patricks-day/irish-whiskey-coffee-2024.md new file mode 100644 index 0000000..f3d4a6f --- /dev/null +++ b/src/recipes/st-patricks-day/irish-whiskey-coffee-2024.md @@ -0,0 +1,8 @@ +*Source: Matt* + +## Ingredients +- 1.5 fl.oz. Irish cream +- 1.5 fl.oz. Irish whiskey +- 1 cup hot brewed coffee +- 1 tablespoon whipped cream +- 1 dash ground nutmeg diff --git a/src/reflections/celtic_camping.md b/src/reflections/celtic_camping.md new file mode 100644 index 0000000..a781230 --- /dev/null +++ b/src/reflections/celtic_camping.md @@ -0,0 +1,24 @@ +Derived from the boring history episode + +Bushcraft a roundhouse. +The shape helps with wind. +The fire is central. +The mutual body heat helps. +The flooring is dried and dead leafs/pine/etc. +The thatched roof allows smoke out but holds some back till it can be absorbed above. +This keeps out insects and keeps heat in. + +Camp with just a brat (Celtic cloak) and leather bag of essentials. +Go somewhere safe on a Friday evening to camp and do this. +The brat can be converted to a tent with stakes. + +Dried meats, dried cheeses, fire starting kit including, flint, steel, and char cloth. Dry tinder in a bag carefully constructed from woven +Build an underlayer of bedding out of bracken, dead and dried plant material, heather, fern, fibers, etc. + +Build a fire and place stones in to warm them. +Place them amid the sleeping area. +They can discharge over night after the fire dies, amid the sleeping area. + +The Celtic point is bodily conditioning, survival skills, naturalist skills, and spiritual growth, memorization, and reflection. +Hypothetically, you could adapt over 3 days, or take a Monday off to adapt over 4 days. +You could chain this with fasting. diff --git a/src/reflections/mycotoxins.md b/src/reflections/mycotoxins.md new file mode 100644 index 0000000..78bb49e --- /dev/null +++ b/src/reflections/mycotoxins.md @@ -0,0 +1,71 @@ +Mycotoxin results +Future of the protocol +- other binders, maybe for aflatoxin +Killing protocol +- nystatin, caprylic acid, oregano oil, undecyclenic acid, berberine +Three day fast and reduced inflammation + +**Binders (rotate these, don't take all at once):** +- **Activated charcoal** - 1-2g, 2x/day, away from food/meds (2+ hours) +- **Bentonite clay** - 1-2 tsp in water, away from meals +- **Chlorella** - 3-6g/day +- **Cholestyramine** (prescription, but most effective for many mycotoxins) + +**Glutathione support:** +- **Liposomal glutathione** - 500-1000mg/day +- **NAC** - 600-1200mg, 2x/day +- **Alpha-lipoic acid** - 300-600mg/day + +**Liver support:** +- **Milk thistle** - 200-400mg standardized extract, 2-3x/day +- **Phosphatidylcholine** - supports cell membranes + +**Anti-inflammatory (for neuro):** +- **Curcumin** (liposomal or with piperine) - 1000-2000mg/day +- **Omega-3s (high EPA/DHA)** - 2-3g/day +- **Resveratrol** - 200-500mg/day + +**Antifungal (if colonization confirmed):** +- **Nystatin** (prescription preferred) +- **Caprylic acid** - 1000-2000mg with meals +- **Oregano oil** - follow label, cycles of 2 weeks on/off + +**Critical notes:** +- Space binders 2+ hours from everything else +- Start low, go slow - die-off can worsen symptoms temporarily +- Stay hydrated, support drainage (sauna if tolerated) +- Address the source or you're spinning wheels + +Working with a practitioner experienced in mold illness (CIRS protocol) would optimize this. + +**Most comparable OTC antifungals for gut:** + +**Caprylic acid** - Probably closest to nystatin functionally +- Disrupts fungal cell membranes +- Stays in the gut (not systemic) +- Dose: 1000-2000mg with each meal +- Look for delayed-release or time-release formulas so it reaches lower GI + +**Undecylenic acid** (from castor oil) +- Similar mechanism to caprylic acid, sometimes considered stronger +- 200-250mg, 3x/day with meals +- Often combined with caprylic acid in formulas + +**Saccharomyces boulardii** (probiotic yeast) +- Competes with pathogenic fungi +- Produces caprylic acid naturally +- 5-10 billion CFU/day +- Won't be killed by antifungals like bacteria-based probiotics + +**Oregano oil** +- Strong antimicrobial, including antifungal +- 150-200mg standardized extract (minimum 70% carvacrol), 2-3x/day +- Use cycles: 2 weeks on, 1-2 weeks off +- Can be harsh on gut, take with food + +**Berberine** +- Broad antimicrobial including antifungal +- 500mg, 2-3x/day +- Also helps with blood sugar + +**Combination approach often works better** - rotate or combine 2-3 of these rather than relying on just one. Start one at a time to monitor tolerance. \ No newline at end of file diff --git a/src/reflections/stack_semantics.md b/src/reflections/stack_semantics.md new file mode 100644 index 0000000..a6e226e --- /dev/null +++ b/src/reflections/stack_semantics.md @@ -0,0 +1,33 @@ +# Stack Semantics + +A friend of mine, Falco, "gifted" this to his every workplace. +It's a representation of a stack semantics shown at runtime. + +``` +branch name +commit ID +build number +build node (I guess this is hostname below) +timestamp + +compiler info +- language +- compiler ID +- compiler version +- compiler target +- toolchain +- language standard +- language extensions +environment +- host + - hostname + - operating system + - architecture +- processor + - family + - description + - physical cores + - logical cores +``` + +In rust, this can be implemented by passing these fields from `build.rs` with a little help from the `vergen` library. diff --git a/todo.txt b/todo.txt index 6d6dc6c..8dce369 100644 --- a/todo.txt +++ b/todo.txt @@ -1,8 +1,5 @@ -Personalize the index page. -Personalize the introduction page of the blog. - +Split www into www/blog, www/content, and www/assets Determine which articles should be incorporated into the website -Integrate photos for recipes Build out the Copper Chronicle Fill out the DefCon article Fill out the Oktoberfest article with old physical notes in big binder @@ -40,3 +37,6 @@ x 2026-03-22 Remove the one line descriptions from the menu. x 2026-03-22 Move the resume to the private section and add the lock symbol. x 2026-03-23 Reduce the CSS where possible. Match my website's theme to align with mdbook's theme. x Set up nightly builds +x Personalize the index page. +x Personalize the introduction page of the blog. +