module Pages ( pageWrapper , mainPages , tagPages , postPages , projectPages ) where import Zoxuli import Lucid hiding (h2_, h3_, h4_, h5_, h6_) import Lucid.Base (makeAttribute) import Optics import GHC.Generics (Generic) import Data.Maybe (fromMaybe) import Data.List (elemIndex, intersperse) import Data.Text (Text, pack) import Control.Monad.State.Lazy (get, lift) import qualified Data.Set as Set pageWrapper :: Page -> Page pageWrapper page = page & #html .~ ( do doctype_ html_ [lang_ "en"] $ do head_ $ do title_ . toHtml $ "eevie nebulæ | " <> page.title meta_ [charset_ "UTF-8"] meta_ [name_ "viewport", content_ "width=device-width, initial-scale=1"] meta_ [name_ "author", content_ "eevie nebulæ"] meta_ [name_ "description", content_ "negentropic <> equilibrium"] link_ [rel_ "stylesheet", href_ "/css/styles.css"] link_ [rel_ "icon", href_ "data:image/svg+xml,🌌"] body_ $ do header_ . nav_ $ do p_ $ link False homePage "eevie nebulæ 🌌" ul_ $ mapM_ navLink navPages main_ $ do breadcrumbs page img_ [id_ "banner", src_ "/img/banner.png", alt_ ""] h1_ $ toHtml page.title page.html lift get <&> (^? #_Two % #footnotes) >>= \case Just footnotes@(_:_) -> do div_ [class_ "footnotes"] $ do h2_ "footnotes" ol_ $ mapM_ renderFootnote footnotes _ -> pure () lift get <&> (^? #_Two % #backlinks) >>= \case Just backlinks@(_:_) -> do div_ [class_ "backlinks"] $ do h2_ "backlinks" ul_ $ mapM_ renderBacklink backlinks _ -> pure () footer_ $ do code_ "negentropic <> equilibrium" hr_ [] link False sourcePage "source" " • "; link False contactPage "contact" " • "; link False todoPage "todo" " • "; linkToAnchor False homePage "anticopyright" "anticopyright" ) where navLink :: Page -> Zoxuli navLink p = li_ $ link False p p.title renderFootnote :: Footnote -> Zoxuli renderFootnote (Footnote index content) = li_ [id_ $ "fn" <> pack (show index)] $ do content; " " a_ [ href_ $ "#r" <> pack (show index) , makeAttribute "aria-label" "return to content" ] "↩" renderBacklink :: Link -> Zoxuli renderBacklink ln = li_ $ do toHtml ln.destinationTitle; ": \"" a_ [href_ $ "/" <> ln.destinationPath <> ".html#" <> slugify ln.body] $ toHtml ln.body "\"" -- | main pages mainPages :: [Page] mainPages = [ homePage , projectsPage , postsPage , tagsPage , seriesPage , sourcePage , contactPage , todoPage , digitalArtPage , photographyPage ] navPages :: [Page] navPages = [projectsPage, postsPage, tagsPage, seriesPage] homePage :: Page homePage = makePage "home" $ p_ $ do toc img_ [ src_ "/img/avatar.png" , class_ "pixel-art hovering-animation" , alt_ "a pixel art portrait of eevie floating amongst magic sigils" ] h2_ "who are you ?" p_ $ do "hi ! i'm eevie , pronouns she/her ." h2_ "what do you do ?" p_ $ do "i'm currently working on the intersection of anti-fascism , veganism , & transhumanism ." h2_ "where am i ?" code "haskell" "go North\nlook" p_ $ do "you hover to the center of a sea of emerald grass that ripples in slow-motion waves . warm gusts guide the smell of rain through the chilled night air . your sigils pepper the orb around you , threaded by semantic strands cast off from your imagined hands . your gaze turns to the edge of the sea where the " link True (fst wallOfShardsPost) "wall of shards" " approaches forebodingly ." h2_ "how do i leave a comment ?" p_ $ do "if you " link True contactPage "contact me" " with your name ( optional ) & comment , i might add it ." p_ "feel free to let me know if you notice any factual inaccuracies ior accessibility issues on my website !" h2_ "what does ior & eor mean ?" p_ $ do "i dislike the ambiguity of the word "; em_ "or"; " in cases where it could be inclusive eor " a_ [href_ "https://en.wikipedia.org/wiki/Exclusive_or"] "exclusive" " . so i call inclusive-or "; em_ "ior"; " & exclusive-or "; em_ "eor"; " ." h2_ "anticopyright" p_ $ do "all media , text , & other content on this website are in the public domain under " a_ [href_ "https://creativecommons.org/publicdomain/zero/1.0/?ref=chooser-v1"] "CC0 1.0 Universal" " , with the following exceptions :" ul_ $ do li_ $ do "the CSS for syntax highlighing was generated by " a_ [href_ "https://github.com/alecthomas/chroma"] "chroma" " , which is under the " a_ [href_ "https://github.com/alecthomas/chroma/blob/master/COPYING"] "MIT license" li_ $ do a_ [href_ "https://github.com/LivKing/Inclusive-Sans"] "inclusive sans" " & " a_ [href_ "https://github.com/subframe7536/Maple-font"] "maple mono" " are both under the " a_ [href_ "https://openfontlicense.org/"] "SIL Open Font License, Version 1.1" p_ $ do "see "; link True (fst unlicensePost) "this post" " for why i am against copyright ." projectsPage :: Page projectsPage = makePage "projects" $ do h2_ "software" p_ $ do "all of these software projects use the " link True (fst unlicensePost) "Unlicense"; " ." ul_ $ mapM_ (li_ . projectPreview) projectPages h2_ "art" ul_ $ do li_ $ link True digitalArtPage "digital" li_ $ link True photographyPage "photography" hr_ [] h2_ "stuff i'm working on" h3_ "N24 Manager" p_ "an app for sleep tracking & daily planning for entities with N24SWD ( non-24 hour sleep-wake disorder ) ." h3_ "Braids" p_ "a chat app where conversational branches can be split off into more branches , eor merged back together with other branches ." h3_ "Negentropy" p_ "a psychological horror interactive fiction game about stopping the heat death of the universe with your friends while consensus reality is hostile to you ." h3_ "Antibubble" p_ "a 2D puzzle game in the Negentropy universe where you traverse & manipulate hierarchies of nested bubble worlds ." postsPage :: Page postsPage = makePage "posts" $ do p_ "in which i externalize the technicolor collapse of techno-synaptic maps of mind matter i’m made of ." ul_ $ do li_ $ do "????-??-?? - "; todo "the oasis" mapM_ (li_ . postPreview) postPages tagsPage :: Page tagsPage = makePage "tags" $ do p_ "hypertext flowed through the cracks in the ground , illuminated by ambient amethyst light from the sky above ." ul_ $ mapM_ (li_ . tagPreview) allTags seriesPage :: Page seriesPage = makePage "series" $ do mapM_ renderSeries allSeries sourcePage :: Page sourcePage = makePage "source" $ do p_ $ do "you can view the " linkToAnchor True (fst howIUseComputersPost) "language" "Haskell" " source code of this website here , read the " link True (fst zoxuliProject) "story behind this design" " , ior view the full project on " a_ [href_ "https://git.sr.ht/~nebulae/eevie.dev"] "sourcehut"; " ." lift get <&> (^? #_Two % #srcFiles) >>= \case Just srcFiles -> mapM_ renderSrcFile srcFiles _ -> pure () where renderSrcFile :: SrcFile -> Zoxuli renderSrcFile f = do h2_ f.name p_ $ a_ [href_ $ "/src/" <> f.name] "raw file" rawHtml f.content contactPage :: Page contactPage = makePage "contact" $ do p_ $ do "you can reach me at " span_ [class_ "email"] $ do "eevie@sent"; b_ "obfuscation-text"; ".com" " ." todo "create a PGP key" h2_ "don't contact me if ..." p_ "don't contact me if you're hoping to collaborate on a project that has the intent of propagating stuff like fascism , nationalism , classism , speciesism , substratism , ageism , antisemitism , racism , colorism , sexism , deathism , ableism , sanism , transphobia , enbyphobia , interphobia , aphobia , lesbophobia , homophobia , biphobia , fatphobia , pluralphobia , etc." todo :: Text -> Zoxuli todo title = link True todoPage $ "todo : " <> title todoPage :: Page todoPage = makePage "todo" $ do ul_ $ do li_ $ do "follow Seirdy's " a_ [href_ "https://seirdy.one/posts/2020/11/23/website-best-practices/"] "best practices for inclusive textual websites" li_ "add a button to download the website as an archive" li_ "RSS/Atom feeds" p_ "any todos across the site are linked to this page , so you can view them in the list of backlinks :" photo :: Text -> Text -> Zoxuli photo file alt = img_ [ src_ $ "/img/" <> file , style_ "width: 100%" , alt_ alt ] digitalArtPage :: Page digitalArtPage = makePage "digital art" $ do p_ "a screenshot from my first attempt at making a low-poly 3D game :" photo "spiky_swamp.jpg" "a cloaked, humanoid creature with glowing eyes & a spiky tail stands beside a gramophone on a boardwalk in a misty swamp. trees with wide bases & black spikes are scattered around." hr_ [] p_ $ do "\""; b_ "trans hacker fae"; "\" , made using Blender , Godot , & Krita :" p_ "this piece is about how i used to be so gaslit into submission that i’d frequently compromise with entities who didn’t want me to exist , but now transphobes only make me want to scream & cry & then continue living on anyway in absolute , prideful defiance ." p_ $ do "( " a_ [href_ "/img/trans-hacker-fae.jpg"] "version without overlay" " )" photo "trans-hacker-fae-code.jpg" "a woman wearing a glass, polygonal skirt & round, glitchy sunglasses spreads her neon-colored wings. she is standing on a snowy hill beside a lamppost, & there is a city with towering skyscrapers across an ocean bay in the background. an overlay over her vision shows a terminal window with cute ASCII art borders. she just updated her source code so that she doesn't compromise with the gender police." hr_ [] p_ "pixel art of a friend's D&D character :" photo "vikram.png" "a person with a shaved head & a calm face stands in a crouched fighting position. they are wearing green robes with an abstract pattern in the middle." photographyPage :: Page photographyPage = makePage "photography" $ do photo "plants5.jpg" "a beetle resting on the center of a fully bloomed flower" photo "plants4.jpg" "a small butterfly in a bright field of flowers" photo "plants1.jpg" "a brightly lit plant with bundles of fuzzy pink flowers" photo "plants2.jpg" "a bundle of fuzzy white flowers in a verdant garden" photo "plants3.jpg" "stalks of bamboo in a forest with large bokeh in the background" -- | tag pages taggedPages :: [Page] taggedPages = (fst <$> projectPages) <> (fst <$> postPages) allTags :: [Text] allTags = deduplicate $ concatMap (^. #tags) taggedPages where deduplicate = Set.toList . Set.fromList pagesWithTag :: Text -> [Page] pagesWithTag tag = filter (elem tag . (^. #tags)) taggedPages tagPreview :: Text -> Zoxuli tagPreview tag = do toHtml . show . length $ pagesWithTag tag; " - " a_ [href_ $ "/tags/" <> slugify tag <> ".html"] $ toHtml tag renderTags :: [Text] -> Zoxuli renderTags tags = sequence_ . intersperse ", " $ renderTag <$> tags where renderTag :: Text -> Zoxuli renderTag tag = a_ [ href_ $ "/tags/" <> slugify tag <> ".html" ] $ toHtml tag tagPages :: [Page] tagPages = makeTagPage <$> allTags makeTagPage :: Text -> Page makeTagPage tag = Page tag path [] html where path = "tags/" <> slugify tag html = do p_ $ do "pages tagged \""; toHtml tag; "\":" ul_ . mapM_ (\p -> li_ $ link False p p.title) $ pagesWithTag tag -- | page series data Series = Series { name :: Text , pages :: [Page] } deriving (Generic) allSeries :: [Series] allSeries = [computingSeries, animalRightsSeries] computingSeries :: Series computingSeries = Series "liberatory computing ∀" [ fst zoxuliProject , fst coaltonRaylibProject , fst howIUseComputersPost , fst queerCybersecPost , fst unlicensePost ] animalRightsSeries :: Series animalRightsSeries = Series "animal rights" [ fst veganTipsPost , fst overfishingPost ] renderSeries :: Series -> Zoxuli renderSeries series = do h2_ series.name ol_ . mapM_ (\p -> li_ $ link False p p.title) $ series.pages seriesNav :: Page -> Zoxuli seriesNav page = mapM_ renderSeriesNav seriesWithPage where seriesWithPage = filter (elem page . (^. #pages)) allSeries renderSeriesNav :: Series -> Zoxuli renderSeriesNav (Series name ps) = p_ . span_ $ do let next xs x = lookup x . zip xs $ tail xs maybeLink t = maybe (pure ()) $ \p -> link False p t position = (+ 1) . fromMaybe 1 $ elemIndex page ps maybeLink "←" $ next (reverse ps) page " "; toHtml . show $ position; "/" toHtml . show $ length ps " in the series " a_ [ href_ $ "/series.html#" <> slugify name ] . toHtml $ name; " " maybeLink "→" $ next ps page -- | project pages projectWrapper :: Project -> Project projectWrapper project = project & _1 % #html %~ (meta <>) where meta = do div_ [style_ "overflow: scroll;"] $ table_ $ do tr_ $ do th_ "repo"; th_ "tags" tr_ $ do td_ . a_ [ href_ $ project ^. _2 % #repo ] . toHtml $ project ^. _2 % #repo td_ . renderTags $ project ^. _1 % #tags toc seriesNav $ fst project hr_ [] projectPreview :: Project -> Zoxuli projectPreview project = do a_ [ href_ $ project ^. _2 % #repo ] "repo" ; " - "; link False (fst project) $ project ^. _1 % #title projectPages :: [Project] projectPages = projectWrapper <$> [ zoxuliProject , swirlmaniaProject , coaltonRaylibProject ] zoxuliProject :: Project zoxuliProject = makeProject "zoxuli" "https://git.sr.ht/~nebulae/zoxuli" ["web dev", "haskell", "programming"] $ do h2_ "a humble goal" p_ "years ago , it started with a humble goal that many could relate to . i wanted to make a website to put my writing on ." p_ "\"making the website will be the simple part !\" , i thought , once . lol ." h2_ "static site generators" p_ "this would lead me on a long journey that ends at the website you're on today . i started off by learning about WordPress , then quickly realized that the WordPress interface was not accessible for me , although i would not have known to describe the problem like that at the time ." p_ $ do "looking for other options , i discovered " a_ [href_ "https://en.wikipedia.org/wiki/Static_site_generator"] "static site generators" " ( SSGs ) , which had the nice property that they were interfaced with using a text editor & a terminal window , which were more accessible to me . so i tried my best to learn the SSG Jekyll , but the documentation was too advanced for me at the time . i moved on to other projects for a while ." h2_ "a new problem" p_ "a while later , after i had learned more about programming for other reasons , i realized i could now understand the Jekyll documentation !" p_ $ do "except ... now my expectations for my website had changed significantly . now i wanted :" ul_ $ do li_ "excellent accessibility" li_ "post series with navigation" li_ "tables of contents" li_ "tags that work across multiple categories of pages" li_ "backlinks" li_ "footnotes" li_ "breadcrumbs" li_ "control over where & how the aforementioned elements appear" li_ "syntax highlighting" li_ "LaTeX" li_ "semantic markup" li_ "no javascript" li_ "broken link checking" li_ "simple & powerful extensibility in a comfortable language" li_ "the ability to write pages in any markup format" li_ "a fast development feedback loop" p_ $ do "i thought , hey , that's a lot of stuff to ask for , but there are " a_ [href_ "https://jamstack.org/generators/"] "hundreds" " ( eor likely thousands ) of SSGs , so surely at least one of them can do all that ?" h2_ "SSG frenzy" p_ $ do "i tried a lot of SSGs . the three that got me closest to all of my goals were " a_ [href_ "https://soupault.app/"] "Soupault"; " , " a_ [href_ "https://bagatto.co/"] "Bagatto"; " , & " a_ [href_ "https://jaspervdj.be/hakyll/"] "Hakyll" " . but none of those got me everything ( " todo "explain their strengths & shortcomings in detail" " ) . there might be another one out there , but i didn't find it ." p_ "not to worry though , because after trying so many SSGs, i was intimately familiar with the tradeoffs involved in their design , & felt comfortable writing my own from scratch ." h2_ "zoxuli : first attempt" p_ $ do "my first attempt ( " todo "share zoxuli v1" " ) was written in Common Lisp , & was most similar to Bagatto ." p_ $ do "the core idea was to have the user of the zoxuli library write a data structure describing the inputs & outputs of the site in Lisp , & the markup files ( ior stylesheet , ior whatever else - it was filetype agnostic ) could contain snippets of lisp surrounded by " inlineCode ".("; " & "; inlineCode ")." " that would be evaluated when the site was built ." p_ $ do "this meant that - as an example - if you wanted to generate backlinks , you could create a " inlineCode ".(link )." " function that would be used anywhere you needed links in your markup . the function would both render the link HTML ( using " a_ [href_ "https://github.com/ruricolist/spinneret"] "spinneret" " ) that gets inserted back into that position by zoxuli , & also store the link data into a variable . during the second pass , calls to a " inlineCode ".(backlinks)." " function would convert the collected links into backlinks & render them into HTML wherever you needed ." h2_ "zoxuli : final version" p_ "after giving version one a proper go , these were my issues with it :" ul_ $ do li_ "i ended up using so many Lisp functions in the markup that i felt like i would've been better off just writing the markup in spinneret" li_ "my implementation resulted in slower build times than i had hoped" li_ $ do "around that time , i realized i don't like programming in Lisp nearly as much as Haskell , especially after learning " a_ [href_ "https://www.parsonsmatt.org/2018/05/19/ghcid_for_the_win.html"] "how to use ghcid" " properly" li_ $ do "i also discovered the " a_ [href_ "https://hackage.haskell.org/package/lucid"] "lucid" " library for Haskell that i favored over spinneret for a few reasons" p_ "incorporating these observations , the final version of zoxuli is basically just a thin scaffold around lucid . the only thing from my prior criteria for an SSG that it doesn't support is the ability to use any markup format , but i enjoy writing lucid more than any other markup format i've tried , so that doesn't bother me ." p_ $ do "i ported this website from Hakyll to zoxuli & i'm quite pleased with the experience . the source code for this website is on the " link True sourcePage "source page" " . " swirlmaniaProject :: Project swirlmaniaProject = makeProject "swirlmania" "https://git.sr.ht/~nebulae/swirlmania" ["stepmania", "exercise", "coalton", "common lisp"] $ do h2_ "what it is" p_ "swirlmania is a CLI StepMania simfile ( .ssc ) processor with support for generating tech charts without double steps ." p_ "swirlmania has five modes for different levels of \"tech\" difficulty . put simply , \"tech\" here refers to how far your body may need to turn to hit the arrow patterns ." h2_ "why i made it" p_ $ do "i enjoy playing " a_ [href_ "https://projectoutfox.com/"] "Project OutFox" " ( a fork of StepMania ) on a dance pad for exercise , but finding simfiles ( which may also be refered to as charts/songs/levels ) that are of a consistent difficulty level can be challenging . i also have a strong preference for mid-speed technical maps without jumps , which makes things even more challenging . matching those criteria severely limits the song selection , but i would prefer to choose from any available level pack ." p_ $ do "charting my own simfiles , eor processing levels by hand is far too costly to my time for what is intended to be an exercise device , so i decided to write a program to process pre-existing levels automatically . there are a few level processors already in existence such as " a_ [href_ "https://github.com/phr00t/AutoStepper"] "AutoStepper" " , but as far as i can tell , none of them consistently maintain flow ( no double steps ) at higher tech levels . i'd also like to support more tech patterns in the future ." coaltonRaylibProject :: Project coaltonRaylibProject = makeProject "coalton-raylib" "https://git.sr.ht/~nebulae/coalton-raylib" ["game dev", "coalton", "common lisp", "programming"] $ do h2_ "the problem" p_ "i love programming in ML-family languages like Haskell & OCaml, but they typically aren't interactive like Common Lisp , which makes programming games more difficult ." p_ $ do "this is because you have to restart the entire program you're working on every time you compile a new change" footnote "there are ways to smooth this over , but they can add a lot of complexity" " ." h2_ "one possible solution" p_ $ do "as an ML language built on top of Common Lisp , " a_ [href_ "https://coalton-lang.github.io/20211010-introducing-coalton/"] "Coalton" " can provide a statically typed , functional ( with typeclasses ! ) , & highly interactive game programming environment ." p_ $ do "coalton-raylib is an example project i've shared that uses the " a_ [href_ "https://www.raylib.com/"] "raylib" " graphics library ." p_ $ do "i've written the draw loop in Common Lisp , & the data model & update functions in Coalton" footnote "that's just the method i found to be the most ergonomic , but i'm certain that others could find better ways of architecting a game with coalton" " . that means you can selectively reevaluate data & functions while the game is running , while benefiting from compile-time type errors if you make a mistake !" h2_ "conclusion" p_ "this was just a small experiment , that i figured i'd share in case it's useful for anyone else . i'm not sure if i'll use this for a larger game eor not , given that Coalton hasn't reached 1.0 yet , but it's great to know that it's a possibility ." -- | post pages postWrapper :: Post -> Post postWrapper post = post & _1 % #html %~ (meta <>) where meta = do div_ [style_ "overflow: scroll;"] $ table_ $ do tr_ $ do th_ "date"; th_ "tags"; th_ "author" tr_ $ do td_ . toHtml $ post ^. _2 % #date td_ . renderTags $ post ^. _1 % #tags td_ $ toHtml $ post ^. _2 % #author toc seriesNav $ fst post hr_ [] postPreview :: Post -> Zoxuli postPreview post = do toHtml $ post ^. _2 % #date; " - "; link False (fst post) $ post ^. _1 % #title postPages :: [Post] postPages = reverseChronological $ postWrapper <$> [ howIUseComputersPost , unlicensePost , veganTipsPost , queerCybersecPost , inferiPost , overfishingPost , wallOfShardsPost ] queerCybersecPost :: Post queerCybersecPost = makePost "queer cybersecurity resources" "2024-07-07" ["security", "privacy", "queer", "guide"] $ do h2_ "introduction" p_ "this is a list of resources for improving your digital security posture , prioritizing relevance to the risks queer folks face . i hope it is helpful !" p_ "note : these resources may have changed since i've shared them , & i don't necessarily endorse every strategy they recommend . security is highly contextual . try to confirm that any advice you encounter is not factually inaccurate , outdated , ior coming from a hostile source before incorporating it into your strategy ." h2_ "privacy & security" "these links are rather general in purpose , so you may need to explore them a bit to find what you are looking for :" ul_ $ do li_ $ a_ [href_ "https://gendersec.tacticaltech.org/wiki/index.php/Complete_manual"] "Zen & the art of making tech work for you - Gender & Tech Resources" li_ $ a_ [href_ "https://ssd.eff.org/"] "Surveillance Self-Defense - Electronic Frontier Foundation" li_ $ a_ [href_ "https://www.privacyguides.org/en/"] "Privacy Guides" h2_ "doxing" p_ "these guides go over both restorative & preventative strategies for if you’re a target of doxing :" ul_ $ do li_ $ a_ [href_ "https://crashoverridenetwork.tumblr.com/post/114270394687/so-youve-been-doxed-a-guide-to-best-practices"] "So You’ve Been Doxed - Crash Override Network" li_ $ a_ [href_ "https://gendersec.tacticaltech.org/wiki/index.php/Self-dox"] "Self-dox - Gender & Tech Resources" li_ $ a_ [href_ "https://arstechnica.com/information-technology/2015/03/anti-doxing-strategy-or-how-to-avoid-50-qurans-and-287-of-chick-fil-a/"] "Anti-doxing Strategy - Ars Technica" h2_ "social media" p_ "this website has a list of comprehensive guides for dealing with harassment , abuse , & privacy settings on a few of the most commonly used social media platforms :" p_ $ a_ [href_ "https://righttobe.org/guides/how-to-use-social-media-safely/"] "How To Use Social Media Safely - Right To Be" overfishingPost :: Post overfishingPost = makePost "\"overfishing\"" "2024-06-09" ["vegan", "language"] $ do p_ $ do "i hate the term " a_ [href_ "https://en.wikipedia.org/wiki/Overfishing"] "\"overfishing\"" " , because it implies that there’s an acceptable amount of " a_ [href_ "https://animalequality.org/issues/fish/"] "fishing" " ." inferiPost :: Post inferiPost = makePost "inferi monologue" "2024-05-20" ["fiction"] $ do p_ $ do "a headcannon of how " a_ [href_ "https://pottermore.fandom.com/wiki/Inferi"] "inferi" " would greet travelers :" blockquote_ $ do p_ "we , stacked like acrobats under the cavern lake surface , writhing in place without sound nor purpose , do cordially invite you & yours to our celebration . we know you’re busy , but spare us a second , & we’ll show you how cozy our waters can be ." p_ "what ? you don’t want to drown ? do we look like we’re drowning to you ? there’s more of us here than you could ever find up there - don’t you want friends ? you’ll drown in an absence of human contact if you don’t join us soon ." p_ $ do "i mean , come on . look at us . we have it all . we’re never alone , & we have each other’s backs , in a lattice configuration , & we never have to worry about defectors , because the waters are so "; b_ "cozy"; " ." p_ "what ? you don’t want to become incorporated into an evil horde ? do we look like an evil horde to you ? we all think you’re a [REDACTED] . you’ve been out of the water so long you’re maladjusted & don’t know right from wrong . i’m confident that even the other , more reasonable land-dwellers would agree with me ." p_ "you’re on your own , kiddo . we offered our gracious invitation , & you disrespected us . you know , there are those among us who used to be like you . then they joined us , & served their time , & now we’re all one big jolly family . i hope that one day , when you’re one of us like they are , you’ll be thankful we took you under our wing ." p_ "stop struggling , [REDACTED] ." p_ $ em_ "we already told you , the waters are cozy ." howIUseComputersPost :: Post howIUseComputersPost = makePost "how i use computers" "2024-08-24" ["qubesOS", "programming", "haskell", "purescript"] $ do h2_ "introduction" p_ "what follows is an outline of the various hardware & software i currently use for daily computing tasks , in case it's useful for someone else . this is not a prescription of how other entities should use technology , nor is it a description of my ideal computing environment ." todo "explain choices in more detail" h2_ "hardware" p_ "if i need to purchase a new device , i prefer to find one that is already used , due to the numerous ethical issues with the production of electronics by large companies ." p_ $ do "my primary computer is a Thinkpad T430 running " a_ [href_ "https://www.qubes-os.org/"] "QubesOS" " . i chose this laptop because , out of the options that can be flashed with " a_ [href_ "https://www.coreboot.org/"] "coreboot" " , it was old enough to be somewhat affordable" footnote "around 200 USD on Newegg" " , while still running fast enough for most tasks that don't involve graphics ." p_ "i don't use any peripherals except for a large monitor , to maintain good posture . i have tried mechanical keyboards , but i dislike like how they feel & sound compared to the built-in Thinkpad keyboard . split keyboards are more ergonomic though , so it would be nice to find a split rubber dome keyboard ." p_ $ do "my \"smart\"phone is a Pixel 4a" footnote "this was also around 200 USD on eBay" " running CalyxOS" footnote "i am planning to switch to GrapheneOS soon , for the additional security features & ability to use TalkBack , a screen reader . i could not figure out how to enable a screen reader on CalyxOS ." " ." h2_ "software" p_ $ do "i primarily use CalyxOS for taking notes with " a_ [href_ "https://f-droid.org/packages/com.orgzly/"] "Orgzly" " , tracking sleep with " a_ [href_ "https://f-droid.org/packages/hu.vmiklos.plees_tracker/"] "Plees Tracker" " , web browsing away from home , insecure communications , & listening to audio-based educational materials ." p_ "i use QubesOS for web browsing , programming , Serious Writing , & other various forms of expression ." p_ $ do "i chose QubesOS because i find " a_ [href_ "https://en.wikipedia.org/wiki/Ambient_authority"] "ambient authority" " horrifying , but i'm not aware of any robust " a_ [href_ "https://en.wikipedia.org/wiki/Capability-based_security"] "capability-based" " operating systems that would fill the same need for me ." p_ $ do "QubesOS is slow & " a_ [href_ "https://github.com/QubesOS/qubes-issues/issues/5907"] "doesn't have screen reader support" " yet , but it does have some great features like configuration using Salt" footnote $ do "ior maybe even nix-like configuration in the future if " a_ [href_ "https://spectrum-os.org/"] "Spectrum" " goes well" ", Whonix qubes , & offline qubes . here are a few things i've learned that make it more tolerable :" ul_ $ do li_ "install i3" ul_ $ do li_ "name your qubes using two-character strings so you can search for them more quickly with dmenu" li_ "make shortcuts for locking the screen & toggling the status bar" li_ $ do "make a shortcut ( mine is bound to "; kbd_ "Alt"; " + ";kbd_ "i"; " ) for opening a dmenu list of helper scripts & frequently opened programs" li_ $ do "use Salt , but not for "; em_ "everything"; " . some tasks are much simpler ior faster with a shell script in dom0 , so i use a top-level shell script to apply salt files & do other things" li_ $ do "if your qubes use XFCE , you can " code_ [class_ "verbatim"] "qvm-run" " the following command in each of your qubes to enable dark mode :" code "bash" "xfconf-query -c xsettings -p /Net/ThemeName -s 'Adwaita-dark'" li_ "it may not always seem like it at first , but most tasks can be automated from dom0 , including mounting & attaching drives inside qubes . i take advantage of this in a backup script that backs up specific qubes using BorgBackup" li_ "i wrote a shell script that copies dotfiles from one qube to the others & applies them , so i only have to clone my dotfiles in one place , but still have my bash aliases , helix config , etc. in every qube" li_ $ do "you can invoke rofi inside a qube using " code_ [class_ "verbatim"] "qvm-run" " in dom0 scripts , but you must use the rofi flag " code_ [class_ "verbatim"] "-normal-window" " to disable " code_ [class_ "verbatim"] "override_redirect" " , which allows the program window to appear undecorated & on top in X11" h2_ "programming" h3_ "language" p_ "currently , my favorite languages are Haskell & PureScript ." p_ "things i like about them are :" ul_ $ do li_ "very clean syntax" li_ "strict , static , & strong type system with inference" li_ "functional purity" li_ "high abstraction power" li_ "frequent overloading with typeclasses" li_ "hoogle/pursuit" li_ "ghcid/pscid" li_ "row polymorphism (in the case of PureScript)" li_ "automatically curried functions" li_ $ do "wonderful libraries like " a_ [href_ "https://github.com/ajnsit/concur"] "Concur" " & " a_ [href_ "https://hackage.haskell.org/package/optics"] "optics" p_ $ do "part of being autistic for me is that i get overwhelmed by extraneous detail "; em_ "very"; " easily , so i view many of these as accessibility features" footnote "however , i have heard that , for some other entities , these languages are quite unpleasant to work with for the very same reasons ." " for the way they keep code clean , easy to read , & reduce the number of things i have to keep in my head ." h3_ "code editor" p_ $ do "the code editor i use most often is " a_ [href_ "https://helix-editor.com/"] "helix"; " ." p_ $ do "my first editor was Sublime Text , then VSCodium , then Atom , & i finally found an editor i liked when i tried vim & realized i could mostly avoid using the mouse" footnote "using a mouse as an input device is fine , & i wish development software would use it more often . my issue is the precision required in most mouse-driven interfaces . precise clicks are difficult for me, & it would be much more accessible if elements that have a larger hitbox ( like radial menus ) were used more often ." " . once i was proficient with vim , i moved on to Doom Emacs ." p_ "Emacs has a lot going for it , like radical introspection & extensibility , but it was just too slow for me . the language servers for Haskell & PureScript would often crash my qube because of how much memory they used in Emacs . i also disliked dealing with the Doom abstraction , but when i tried going without it , maintaining a complex configuration was too time consuming ." p_ "so , i switched to helix . it is rarely too slow for me , even in a qube with 4GB of RAM . it hardly requires any configuration to match my Doom Emacs setup . after learning them properly , i've also grown to appreciate the Kakoune-inspired keybindings more than vim's ." unlicensePost :: Post unlicensePost = makePost "why i use the Unlicense & CC0" "2024-07-21" ["anticopyright", "philosophy"] $ do h2_ "introduction" p_ $ do "i don't know that much about the specifics of copyright law ; this post is more of a philosophical exploration of the concept of \"intellectual property\" in general" footnote "it's also not a comprehensive argument , as there are quite a few reasons i dislike \"intellectual property\" that aren't mentioned here ." " ." h2_ "\"intellectual property\" relies on death" p_ "what would \"perfect\" copyright enforcement look like ? extrapolating what i see as the current system’s telos , it would look like protected \"intellectual property\" being physically impossible to create for everyone in the universe except for the \"owner\" ." p_ "every time new \"intellectual property\" is created , everyone else’s agency decreases by some amount . it is a system reliant on death , because if death were abolished , all of the most important expressions would get copyrighted eventually , & never expire , rendering most entities born after that period unable to express much ." p_ "so , if copyright decreases everyone’s agency , uses death as a mechanism to redistribute temporal privilege , & relies on the distributed violence of the state to enforce all of this , what’s the alternative ?" h2_ "copyleft & copyfarleft" p_ "efforts to use the system against itself , like copyleft & copyfarleft , are admirable in terms of what they aim to achieve . they can stop entities who use your work from restricting others as much as they would have otherwise ." p_ "but if one has the option to forgo copyright entirely , i’m not convinced that copyleft is preferable . it still relies on the copyright system in a significant way . why rely on an inefficient system that harms others when you could oppose their usage of your work through other channels ?" p_ "some entities act like once you’ve given up your \"intellectual property\" you have no \"right\" to oppose anyone’s usage of it . this doesn’t make sense unless you view the legal system as the only way to stop harm ." p_ "as an example , if somebody used a painting i made in a widely shared fascist propaganda video without permission , there are numerous reasons why this is bad that are not \"they stole my 'intellectual property'\" . there are also countless ways to counteract this other than to wait around for the copyright system to punish them in a way that isn’t even responding directly to what was wrong about what they did in the first place ." h2_ "even copyleft causes psychic damage" p_ "another unfortunate side effect of copyleft’s strategy is that , similar to permissive licenses , even users of copyleft software that are trying their best to make their derivatives freely available have to worry about the chance that they misunderstand something & get punished by the legal system ." p_ $ do "anecdotally , trying to make sense of the rules for using copyleft software" footnote "which is an instance of trying to navigate the legal system" " was very difficult & stressful for me . i have a particularly low tolerance for that kind of thing , but i doubt that this is an uncommon experience more generally , at least to a lesser extent ." p_ "in contrast , i don't have those issues when i’m using public domain software , because there aren't so many rules to keep track of ." h2_ "releasing work into the public domain" p_ $ do "regarding anticopyright praxis , my current preference is to use the " a_ [href_ "https://unlicense.org/"] "Unlicense" " for code , & " a_ [href_ "https://creativecommons.org/public-domain/cc0/"] "CC0" " for everything else ." p_ "you could also just release stuff without a license notice at all , if you feel like the entities who will see your work can trust you enough to not do anything about \"infringements\" ." veganTipsPost :: Post veganTipsPost = makePost "a few vegan tips" "2024-07-03" ["vegan", "guide"] $ do h2_ "introduction" p_ "here are a few things i’ve learned since becoming vegan that weren’t immediately obvious , ior aren’t discussed as often by vegans because they’re about keeping insects ior wild animals safe ." p_ "i'm not an expert on animal welfare , so i may be mistaken about some of these . i’d also recommend prioritizing more effective forms of activism over spending too much time being fastidious about stuff like this . but i still think it's worth sharing the little ways we can try to avoid harming other living beings in everyday life ." h2_ "the tips" ul_ $ do li_ "be careful with stickers & sticky things . bugs can become trapped on them easily" li_ $ do "be "; em_ "very"; " distrustful of unfamiliar non-vegans’ assessments of whether things are vegan eor not" li_ $ do "if bugs get trapped in your bathtub frequently , you can leave a long strip of toilet paper draped into the tub when you're not using it to create an escape route for them to use when you're not there" footnote "i almost never see bugs trapped in the tub anymore after doing this" li_ $ do "if you share a home with rodents , there are effective methods to keep them out of your living spaces without harming them , like sealing gaps in your home with steel wool & being very careful to keep any traces of food tidy & well sealed . " todo "link to a detailed guide" li_ "don’t assume that random household items like toilet paper are vegan by default" li_ $ do "fireworks are " a_ [href_ "https://www.animal-ethics.org/how-fireworks-harm-nonhuman-animals/"] "harmful ior deadly" " to many living things" li_ "avoid unnecessary loud noises that could distress nearby animals . some music may be an exception , though , if it's not too loud" li_ "don’t walk when the ground is unlit to avoid crushing bugs" li_ $ do "reduce ior eliminate reliance on car travel for "; em_ "many"; " reasons" li_ "recreational fires often burn insects alive & wood smoke can be harmful to animals" li_ "avoid planting poisonous plants where wild animals might eat them" h2_ "related writing" p_ $ do "if you’re interested in more practical advice of this nature , i can recommend the writings of a researcher named " a_ [href_ "https://briantomasik.com/"] "Brian Tomasik" " . while i don’t always agree with his conclusions on many topics , as far as i can tell , he is earnestly trying to reduce the harm caused to wild animals & insects ( among others ) more than most entities i’ve encountered . he also documents his ideas in a very comprehensive & accessible way ." wallOfShardsPost :: Post wallOfShardsPost = makePost "wall of shards" "2024-05-10" ["fiction"] $ do p_ $ do "type "; code_ [class_ "verbatim"] "start" " to collect a shard ." code "haskell" "start" p_ $ em_ "shard count : 2" h2_ "your lab" p_ "you're sitting in your office chair . all of your research tools are systematically organized around you , with your computer terminal at the center of it all . your friend b6e is sitting here , staring at one of the photos on your wall , although you can't tell which one ." code "haskell" "talkTo b6e" p_ "you break the silence ." blockquote_ "are you ready to get started ?" blockquote_ "yeah . what will it feel like , exactly ? like will i even notice you're there ?" blockquote_ "well , i'm not completely sure , but it will probably be similar to what it feels like to focus on your thoughts in one of those terrible dining areas with televisions all over . difficult , & a struggle to not zone out & succumb to the noise ." blockquote_ "too bad i can't take a nap during it ." blockquote_ "i know right . well , if you're ready then have a seat & i'll start projecting ." p_ "she sits down & puts on the acrylic beanie . all of the cables dangling off of it match her hair color , which gives the illusion that her hair extends onto the floor ." code "haskell" "use Terminal" p_ $ do "you swivel over to your terminal & execute " code_ [class_ "verbatim"] "1ntr0j3ct.hs"; " ." blockquote_ "you named the script using leetspeak ?" blockquote_ "yep , it makes words taste better ." p_ "you get up & lie down on your yoga mat . your vision starts to fade ..." h2_ "the center" p_ "a sea of tall , green grass stretches endlessly in all directions except to the west , where a short , smoothly vertical cliff face wraps a plateau . you're sitting at the junction of a boardwalk splitting off to the north , south , & east ." p_ "you're not sure why , but this location feels like the central point in her mind , where all other synapse clusters meet . why then is it so barren ?" p_ "it's dark , but the moon is bright enough that you can see sheets of rain sweeping the expanse . the rain & wind produce a soothing noise that ripples in waves off of the grass ." p_ "even farther in the distance , you hear another ceaseless noise coming from all directions except up & down . it's a harsh , glass grinding static , but not quite painful because of how faint it is ." code "haskell" "go West" p_ "there is a cliff face to the west . you hover up to the top edge ." h2_ "eastern plateau ridge" p_ "you aren't that much higher than the boardwalks below , but you can see much farther into the distance from up here . there is a sliver of deep crimson shimmer spanning the entire horizon . maybe that's what's making that grinding noise ?" p_ "the footpath you're on continues to the north & south . to the west , the top of the plateau slopes downward toward a pool of glowing purple liquid . the pool appears to converge & warp in upon itself , almost as if a tiny black hole were floating a few meters above the surface ." p_ "there's a rectangular slot in the ground close by , but you can't see what's in it from here ." code "haskell" "examine Slot" h2_ "slot machine" p_ "now that you're closer to the slot , you notice a hand-written sign next to it that says :" blockquote_ "slot machine : enter the slot & slide like a coin to a random location" p_ "somebody walks over to you & asks what you're doing ." blockquote_ "hello ! i'm trying to figure out what the deal with this slot thing is ." blockquote_ "no you're not . i saw you over there trying to vandalize my hand-written sign ." blockquote_ "you what ? i didn't even touch the sign ." blockquote_ "then how did all of those purple stains get on it ?" p_ "you glance at the sign again . it does appear more stained than you remember it . you wonder , aloud :" blockquote_ "maybe it's from that pool over there ? whatever gravity well is swirling above the pool might have become volatile ." blockquote_ "that's certainly a possiblity . but it seems much more likely that you hated my handwriting style & wanted to destroy it yourself ." blockquote_ "you serious ? i didn't even think of the handwriting style until now. it was perfectly serviceable ." blockquote_ "oh ." p_ "they gaze into the distance uncomfortably ." p_ "the grinding sound grows louder , & the crimson glow brighter ." p_ $ em_ "shard count : 3" code "haskell" "ask SignPainter . about Sound" p_ "you ask the sign painter if they know where that sound is coming from ." blockquote_ "no ." code "haskell" "ask SignPainter . about CrimsonGlow" p_ "you ask them if they know what the crimson glow is coming from ." blockquote_ "no ." p_ "the sign painter sits on the ground , placing their legs into the slot . they carefully lower the rest of their body into the slot & let go. a few seconds later the sound of them sliding fades away completely ." p_ "it starts to rain . the droplets are purple , & stains your grey dress ." code "haskell" "go East" p_ "you hover back down the cliff face & land on the boardwalk again ." h2_ "the center" p_ "it feels nice to return to the center . that plateau to the west had an unpleasant vibe . the boardwalk continues to the north , south , & east ." code "haskell" "go West" p_ "you look back at the cliff face . a voice in your head says it may be a good idea to return to the slot machine , because it could spit you out where you need to go much faster than hovering there yourself ." p_ "but no . that would be a gamble ." p_ "you don't like leaving things to chance ." code "haskell" "go North" p_ "with your mind made up , you hover northward along the boardwalk ." h2_ "an expanse" p_ "you've reached the end of the boardwalk . this location is so far from the plateau that it's barely visible through the rain . the crimson glow to the north stretches higher into the sky here . it's like the source of the grinding noise is a wall in the distance that wraps around the boundary of b6e's mind ." p_ "there is a swarm of winged , metal centipedes flying over your head ." p_ "the grinding sound is loud enough here to put you on edge ." p_ $ em_ "shard count : 4" code "haskell" "ask Centipede . about Sound" p_ "you call out to the centipedes above you ." blockquote_ "excuse me , would any of you be able to help me answer a quick question ?" p_ "one of them lands in front of you . they are wearing a really cool sweater with a fractal pattern knitted onto it ." blockquote_ "i might be able to help ya ! what's ur question ?" blockquote_ "oh nice ! thank you . do you know what that glass grinding noise in the distance is ?" blockquote_ "ya mean death ?" blockquote_ "what ?" blockquote_ "death . like the thing that happens when ya have a shard count of 11 ? looks like ya have 4 shards . ya might wanna stop thinkin' 'bout the wall !! you'll get less shards that way !" p_ "the other centipedes start gliding to the southeast ." blockquote_ "that's what the shard count is about ? why would thinking about the wall give you more shards ? by the wall you mean that crimson thing in the distance , right ?" blockquote_ "hey kid i'm sorry but i gotta go my friends are leavin' & i don't wanna get left behind but i'm sure someone else can help ya out ! althoughhh a lotta entities might be hesitant ( ior worse ) to talk about the shards . not sure what to tell ya 'bout that ." blockquote_ "ok , well thanks for the info . i'll keep searching then ." blockquote_ "be careful ." p_ "they fly away ." code "haskell" "save" p_ $ em_ "serializing timeline ..." p_ $ em_ "game saved ." p_ $ em_ $ do "enter the code " code_ [class_ "verbatim"] "5nJ0kL3-001" " to restore the game to this point in time ." code "haskell" "pop"