1<!DOCTYPE html><html lang="en" data-theme="slack-ochin" data-dark-theme="slack-dark" data-light-theme="slack-ochin" data-theme-mode="light-dark-auto" data-theme-hash="e66e1d5f" style="--theme-font: Crimson Pro;--ec-frm-frameBoxShdCssVal: none;--ec-frm-edTabBrdRad: 0;--ec-frm-edTabBarBrdCol: color-mix(in srgb, var(--theme-foreground), 10%, transparent);--ec-brdCol: color-mix(in srgb, var(--theme-foreground), 10%, transparent);"> <head><meta charset="UTF-8"><meta content="width=device-width, initial-scale=1.0" name="viewport"><meta name="generator" content="Astro v5.13.5"><meta name="title" content="#6 - Adam Smith on Answer Set Programming - The Search Space"><meta name="description" content="Adam Smith talks about Answer Set Programming, and how he's used it in game design and other areas."><meta name="author" content="Felix Holmgren"><meta property="og:title" content="#6 - Adam Smith on Answer Set Programming - The Search Space"><meta property="og:description" content="Adam Smith talks about Answer Set Programming, and how he's used it in game design and other areas."><meta property="og:url" content="https://thesearch.space/episodes/6-adam-smith-on-answer-set-programming"><meta property="og:type" content="website"><meta property="og:image" content="https://thesearch.space/social-cards/__default.png"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:title" content="#6 - Adam Smith on Answer Set Programming - The Search Space"><meta name="twitter:description" content="Adam Smith talks about Answer Set Programming, and how he's used it in game design and other areas."><meta name="twitter:image" content="https://thesearch.space/social-cards/__default.png"><meta name="keywords" content="logic programming, prolog, podcast, ai, programming languages, symbolic ai, answer set programming, constraint programming, game design"><link rel="canonical" href="https://thesearch.space/episodes/6-adam-smith-on-answer-set-programming"><link rel="sitemap" href="/sitemap-index.xml"><link rel="icon" href="/favicon.ico" sizes="32x32"><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"><link rel="apple-touch-icon" href="/apple-touch-icon.png"><link rel="manifest" href="/site.webmanifest" crossorigin="use-credentials"><link rel="alternate" type="application/rss+xml" title="The Search Space" href="https://thesearch.space/rss.xml"><title>#6 - Adam Smith on Answer Set Programming - The Search Space</title><style>:root[data-theme="slack-ochin"] { 2--theme-foreground: #000; 3--theme-background: #fff; 4--theme-accent: #000; 5--theme-heading1: #000; 6--theme-heading2: #000; 7--theme-heading3: #000; 8--theme-heading4: #000; 9--theme-heading5: #000; 10--theme-heading6: #000; 11--theme-list: #000; 12--theme-italic: #c792ea; 13--theme-link: #000; 14--theme-separator: #000; 15--theme-note: #6182b8; 16--theme-tip: #91b859; 17--theme-important: #7c4dff; 18--theme-caution: #ffb62c; 19--theme-warning: #e53935; 20--theme-blue: #6182b8; 21--theme-green: #91b859; 22--theme-red: #e53935; 23--theme-yellow: #ffb62c; 24--theme-magenta: #7c4dff; 25--theme-cyan: #39adb5; 26} 27:root[data-theme="slack-dark"] { 28--theme-foreground: #e6e6e6; 29--theme-background: #222222; 30--theme-accent: #569cd6; 31--theme-heading1: #569cd6; 32--theme-heading2: #569cd6; 33--theme-heading3: #569cd6; 34--theme-heading4: #569cd6; 35--theme-heading5: #569cd6; 36--theme-heading6: #569cd6; 37--theme-list: #6796e6; 38--theme-italic: #e6e6e6; 39--theme-link: #e6e6e6; 40--theme-separator: #e6e6e6; 41--theme-note: #2472c8; 42--theme-tip: #0dbc79; 43--theme-important: #bc3fbc; 44--theme-caution: #e5e510; 45--theme-warning: #cd3131; 46--theme-blue: #2472c8; 47--theme-green: #0dbc79; 48--theme-red: #cd3131; 49--theme-yellow: #e5e510; 50--theme-magenta: #bc3fbc; 51--theme-cyan: #11a8cd; 52}</style>
52<script> 53 ;(function loadTheme() { 54 const pageDefaultTheme = document.documentElement.getAttribute('data-theme') 55 const pageDarkTheme = document.documentElement.getAttribute('data-dark-theme') 56 const pageLightTheme = document.documentElement.getAttribute('data-light-theme') 57 const pageThemeHash = document.documentElement.getAttribute('data-theme-hash') 58 if (!pageDefaultTheme || !pageDarkTheme || !pageLightTheme || !pageThemeHash) { 59 throw new Error('Theme attributes are required.') 60 } 61 const getStoredTheme = () => localStorage.getItem('data-theme') 62 let storedTheme = getStoredTheme() 63 const storedThemeHash = localStorage.getItem('data-theme-hash') 64 const themeHashMatches = storedThemeHash === pageThemeHash 65 66 if (!storedTheme || !storedThemeHash || !themeHashMatches) { 67 // Should be the first time loading the website 68 localStorage.setItem('data-theme', pageDefaultTheme) 69 localStorage.setItem('data-theme-hash', pageThemeHash) 70 } 71 72 if ( 73 themeHashMatches && 74 storedTheme && 75 storedTheme !== 'auto' && 76 storedTheme !== pageDefaultTheme 77 ) { 78 // The stored theme is different from the default theme, apply it 79 document.documentElement.setAttribute('data-theme', storedTheme) 80 } else if (pageDefaultTheme === 'auto' || storedTheme === 'auto') { 81 // If the default or stored theme is 'auto', apply the system preference 82 const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)') 83 document.documentElement.setAttribute( 84 'data-theme', 85 prefersDarkScheme.matches ? pageDarkTheme : pageLightTheme, 86 ) 87 prefersDarkScheme.addEventListener('change', (e) => { 88 if (getStoredTheme() === 'auto') { 89 const newTheme = e.matches ? pageDarkTheme : pageLightTheme 90 document.documentElement.setAttribute('data-theme', newTheme) 91 } 92 }) 93 } 94 })() 95</script>
95<link rel="stylesheet" href="/_astro/about.CZr4GseN.css"> 96<style>iframe.giscus-frame{margin-block:32px}button[data-astro-cid-a264jexy].scroll-up{transform:translateY(0);opacity:1;transition:transform .3s ease-in-out,opacity .5s cubic-bezier(.4,0,.2,1),background-color .15s cubic-bezier(.4,0,.2,1)}button[data-astro-cid-a264jexy].scroll-up:not(.active){transform:translateY(10px);opacity:0} 97:where([data-astro-image]){object-fit:var(--fit);object-position:var(--pos);height:auto}:where([data-astro-image=full-width]){width:100%}:where([data-astro-image=constrained]){max-width:100%} 98</style>
98<script type="module" src="/_astro/page.V2R8AmkL.js"></script>
98</head> <body class="w-full h-full m-0 bg-background text-foreground" style="--theme-font: Crimson Pro;--ec-frm-frameBoxShdCssVal: none;--ec-frm-edTabBrdRad: 0;--ec-frm-edTabBarBrdCol: color-mix(in srgb, var(--theme-foreground), 10%, transparent);--ec-brdCol: color-mix(in srgb, var(--theme-foreground), 10%, transparent);"> <div class="flex flex-col max-w-3xl min-h-screen border-accent/10 m-auto p-3 sm:py-5 sm:px-6 md:py-10" style="--theme-font: Crimson Pro;--ec-frm-frameBoxShdCssVal: none;--ec-frm-edTabBrdRad: 0;--ec-frm-edTabBarBrdCol: color-mix(in srgb, var(--theme-foreground), 10%, transparent);--ec-brdCol: color-mix(in srgb, var(--theme-foreground), 10%, transparent);"> <header> <div class="relative flex items-center justify-between bg-accent/10 rounded-xl"> <a id="logo" href="/" class="block px-4 py-1.5 max-w-full no-underline items-center bg-accent text-background font-bold rounded-xl font-sans"> The Search Space </a> <div class="flex items-center gap-3 sm:mr-3"> <site-search class="ms-auto" id="search" data-trailing-slashes="false"> <button class="hover:text-accent flex cursor-pointer items-center justify-center rounded-md" aria-keyshortcuts="Control+K Meta+K" data-open-modal disabled> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-6 text-accent"><path d="m21 21-4.34-4.34" /><circle cx="11" cy="11" r="8" /></svg> <span class="sr-only">Open Search</span> </button> <dialog aria-label="search" class="text-foreground! bg-background max-h-5/6 min-h-48 w-7/8 sm:w-5/6 max-w-xl border-double! border-4 border-accent/30 shadow-sm backdrop:backdrop-blur-sm open:flex mx-auto mt-10 sm:mt-16 mb-auto rounded-xl"> <div class="dialog-frame flex grow flex-col gap-4 p-6 pt-6 max-w-full"> <button class="cursor-pointer fixed top-2 right-2 rounded-full" data-close-modal> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-6 text-accent/50"><circle cx="12" cy="12" r="10" /><path d="m15 9-6 6" /><path d="m9 9 6 6" /></svg> </button> <div class="search-container"> <div id="pagefind-search" class="max-w-full"></div> </div> </div> </dialog> </site-search>
98<script type="module" src="/_astro/Search.astro_astro_type_script_index_0_lang.DgEFfGQ3.js"></script>
98 <button id="theme-change-button" class="block ml-auto" data-light="slack-ochin" data-dark="slack-dark"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="hidden size-6 text-accent" id="icon-light"><circle cx="12" cy="12" r="4" /><path d="M12 2v2" /><path d="M12 20v2" /><path d="m4.93 4.93 1.41 1.41" /><path d="m17.66 17.66 1.41 1.41" /><path d="M2 12h2" /><path d="M20 12h2" /><path d="m6.34 17.66-1.41 1.41" /><path d="m19.07 4.93-1.41 1.41" /></svg> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="hidden size-6 text-accent" id="icon-dark"><path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z" /></svg> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="hidden size-6 text-accent" id="icon-auto"><path d="M12 2v2" /><path d="M13 8.129A4 4 0 0 1 15.873 11" /><path d="m19 5-1.256 1.256" /><path d="M20 12h2" /><path d="M9 8a5 5 0 1 0 7 7 7 7 0 1 1-7-7" /></svg> </button>
98<script type="module">const t=document.getElementById("theme-change-button"),s=t?.getAttribute("data-light"),a=t?.getAttribute("data-dark"),o=t?.querySelector("#icon-light"),c=t?.querySelector("#icon-dark"),n=t?.querySelector("#icon-auto"),i=d=>{d===s?(o?.classList.remove("hidden"),c?.classList.add("hidden"),n?.classList.add("hidden")):d===a?(o?.classList.add("hidden"),c?.classList.remove("hidden"),n?.classList.add("hidden")):(o?.classList.add("hidden"),c?.classList.add("hidden"),n?.classList.remove("hidden"))};let r=localStorage.getItem("data-theme")||"auto";i(r);t?.addEventListener("click",()=>{const d=localStorage.getItem("data-theme")||a;let e;if(d===s?e=a:d===a?e="auto":e=s,e)if(i(e),localStorage.setItem("data-theme",e),e==="auto"){const l=window.matchMedia("(prefers-color-scheme: dark)");document.documentElement.setAttribute("data-theme",l.matches?a||"auto":s||"auto")}else document.documentElement.setAttribute("data-theme",e)});</script>
98 <nav id="nav-mobile" aria-label="Menu" class="p-0 text-accent sm:hidden"> <button id="nav-mobile-button" class="px-3 py-1 h-full cursor-pointer border-2 rounded-xl bg-background font-sans" type="button" aria-expanded="false" aria-controls="nav-menu-list"> 99â¾ 100</button> <ul id="nav-mobile-list" class="invisible absolute flex flex-col bg-background shadow text-accent border-2 m-0 p-2.5 top-11.5 left-auto right-0 z-50 rounded-xl"> <li class="p-1" aria-expanded="false"> <a class="font-sans" href="/"> Home </a> </li><li class="p-1" aria-expanded="false"> <a class="font-sans" href="/about"> About </a> </li><li class="p-1" aria-expanded="false"> <a class="font-sans underline" href="/episodes"> Episodes </a> </li><li class="p-1" aria-expanded="false"> <a class="font-sans" href="/subscribe"> Subscribe </a> </li> </ul> </nav> </div> </div> <nav aria-label="Menu" class="p-0 mt-4 ml-0.5 text-accent hidden sm:block"> <ul class="flex flex-row text-accent"> <li class="mr-5" aria-expanded="true"> <a class="font-sans" href="/"> Home </a> </li><li class="mr-5" aria-expanded="true"> <a class="font-sans" href="/about"> About </a> </li><li class="mr-5" aria-expanded="true"> <a class="font-sans underline" href="/episodes"> Episodes </a> </li><li class="mr-5" aria-expanded="true"> <a class="font-sans" href="/subscribe"> Subscribe </a> </li> </ul> </nav> </header>
100<script type="module">const t=document.getElementById("nav-mobile-button"),n=document.getElementById("nav-mobile-list"),o=n?.querySelectorAll("li"),a=i=>{let e=!1;e=!n?.classList.toggle("invisible"),t?.setAttribute("aria-expanded",e?"true":"false"),o?.forEach(l=>{l.setAttribute("aria-expanded",e?"true":"false")})};t?.addEventListener("click",i=>{a()});</script>
100 <main class="flex flex-col py-1" style="--theme-font: Crimson Pro;--ec-frm-frameBoxShdCssVal: none;--ec-frm-edTabBrdRad: 0;--ec-frm-edTabBarBrdCol: color-mix(in srgb, var(--theme-foreground), 10%, transparent);--ec-brdCol: color-mix(in srgb, var(--theme-foreground), 10%, transparent);"> <article class="max-w-full py-7.5" data-pagefind-body> <div class="md:mx-2"> <h1 id="6-adam-smith-on-answer-set-programming" class="mb-2 tracking-tight text-4xl/10 pb-3 border-b-6 101 md:mb-4 md:leading-16 md:border-b-10 md:text-6xl md:pb-8"> #6 - Adam Smith on Answer Set Programming </h1> <div class="my-2 mb-12 py-2"> <p class="text-base text-foreground/80"> February 15, 2024 ⢠73 Minutes </p> <div class="mt-2 flex flex-wrap gap-2"> <span class="text-xs font-mono bg-accent/10 text-accent px-2 py-1 rounded"> logic programming </span><span class="text-xs font-mono bg-accent/10 text-accent px-2 py-1 rounded"> answer set programming </span><span class="text-xs font-mono bg-accent/10 text-accent px-2 py-1 rounded"> constraint programming </span><span class="text-xs font-mono bg-accent/10 text-accent px-2 py-1 rounded"> game design </span> </div> </div> </div> <div class="my-8"> <iframe width="100%" height="180" frameborder="no" scrolling="no" seamless src="https://share.transistor.fm/e/50769725"></iframe> </div> <div class="mb-5 prose"> <p>Adam Smith talks about Answer Set Programming, and how heâs used it in game design, information visualization, and other areas.</p> 102<h2 id="show-notes"><a href="#show-notes">Show notes</a></h2> 103<p><a href="https://www.cs.uni-potsdam.de/~torsten/" rel="noreferrer noopener" target="_blank">Torsten Schaub at Potsdam University</a></p> 104<p>Several of his presentations contain the formula:</p> 105<p><strong>ASP = DB + LP + KR + SMT^n</strong></p> 106<ul> 107<li>ASP: Answer Set Programming</li> 108<li>DB: Database</li> 109<li>LP: Logic Programming</li> 110<li>KR: Knowledge Representation</li> 111<li>SMT: <a href="https://en.wikipedia.org/wiki/Satisfiability_modulo_theories" rel="noreferrer noopener" target="_blank">SAT Modulo Theories</a></li> 112</ul> 113<p>SAT solver: <a href="https://en.wikipedia.org/wiki/SAT_solver" rel="noreferrer noopener" target="_blank">Boolean Satisfiability</a></p> 114<blockquote> 115<p>this refraction game that I had made a puzzle generator for</p> 116</blockquote> 117<p>Described in <a href="https://adamsmith.as/dissertation/" rel="noreferrer noopener" target="_blank">Adamâs dissertation</a>.</p> 118<blockquote> 119<p>the Potassco tools from University of Potsdam</p> 120</blockquote> 121<p><a href="https://potassco.org/" rel="noreferrer noopener" target="_blank">potassco.org</a></p> 122<blockquote> 123<p>A book called Procedural Content Generation in Games</p> 124</blockquote> 125<p><a href="https://www.pcgbook.com/" rel="noreferrer noopener" target="_blank">www.pcgbook.com</a></p> 126<blockquote> 127<p>Thereâs this idea due to Kate Compton ⦠of the 10,000 bowls of oatmeal problem</p> 128</blockquote> 129<p><a href="http://www.galaxykate.com/blog/generator.html" rel="noreferrer noopener" target="_blank">http://www.galaxykate.com/blog/generator.html</a></p> 130<blockquote> 131<p>We modeled a design space of information visualizations, line plots and scatter plots and bar charts</p> 132</blockquote> 133<p><a href="https://adamsmith.as/papers/08440847.pdf" rel="noreferrer noopener" target="_blank">âFormalizing Visualization Design Knowledge as Constraints: Actionable and Extensible Models in Dracoâ</a></p> 134<blockquote> 135<p>a Python library called Clorm .. so that you can define your problem instances with Python objects</p> 136</blockquote> 137<p><a href="https://github.com/potassco/clorm" rel="noreferrer noopener" target="_blank">github.com/potassco/clorm</a></p> 138<blockquote> 139<p>the concept of <strong>elaboration tolerance</strong> that when someone gives you some clarification about how your domain works, can you incorporate that change by just adding more code to add more choices or more constraints?</p> 140</blockquote> 141<p>John McCarthyâs <a href="http://jmc.stanford.edu/articles/elaboration.html" rel="noreferrer noopener" target="_blank">paper on elaboration tolerance</a></p> 142<blockquote> 143<p>a paper from Google DeepMind ⦠describing a system called the Apperception Engine</p> 144</blockquote> 145<p><a href="https://arxiv.org/abs/1910.02227" rel="noreferrer noopener" target="_blank">âMaking sense of sensory inputâ</a>, Evans et al</p> 146<blockquote> 147<p>taught a class called <strong>Applied ASP</strong> a few years ago</p> 148</blockquote> 149<p>Lecture slides, programming assignments, reading assignments here: <a href="https://canvas.ucsc.edu/courses/1338" rel="noreferrer noopener" target="_blank">canvas.ucsc.edu/courses/1338</a></p> 150<blockquote> 151<p>Once you want to write a program thatâs more than 30 lines long, how do you profile it? How do you test it? How do you deploy it?</p> 152</blockquote> 153<p>Slides from a talk about Adamâs test automation framework: <a href="https://docs.google.com/presentation/d/1iJr9ieR9ad9hRetFi0vjFe6Uw8-6WxTgernaguI_QtY" rel="noreferrer noopener" target="_blank">Unit Test Automation for ASP with Ansunit</a></p> 154<p>Try ASP from your browser: <a href="https://potassco.org/clingo/run/" rel="noreferrer noopener" target="_blank">https://potassco.org/clingo/run/</a></p> </div> </article> <div class="flex flex-col sm:flex-row items-center justify-around sm:gap-5 max-w-full mb-6 py-10 bg-accent/8 p-4 rounded-xl"> <img src="/_astro/felix-holmgren-portrait.CiC7cI8h_1JiceV.webp" srcset="/_astro/felix-holmgren-portrait.CiC7cI8h_262FNn.webp 288w" alt="Felix Holmgren" loading="lazy" decoding="async" fetchpriority="auto" width="144" height="144" class="rounded-full border-8 border-accent/15 size-36 aspect-square box-content shrink-0"> <div> <div class="m-4 max-w-full prose"> <p>Thanks for listening! Feel free to check out other episodes or contact me via the social links in the footer. Or go <a href="https://ko-fi.com/searchspace" rel="noreferrer noopener" target="_blank">buy me a coffee</a>!</p> </div> </div> </div><button hidden class="scroll-up size-11 fixed flex items-center justify-center bg-background z-100 bottom-3 right-3 rounded-full border-2 border-accent/20 hover:bg-accent/10 md:size-12 md:bottom-5 md:right-5 lg:size-13 lg:bottom-6 lg:right-6" data-astro-cid-a264jexy> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="text-accent/50
154size-8 lg:size-9" data-astro-cid-a264jexy="true"><path d="m18 15-6-6-6 6" /></svg> </button>
154<script type="module">function c(t,n,r){const e=o=>{o.target===t&&o.propertyName===n&&(t.setAttribute("hidden","true"),t.removeEventListener("transitionend",e))};return{show(){t.removeEventListener("transitionend",e),t.removeAttribute("hidden"),t.offsetHeight,t.classList.add(r)},hide(){t.addEventListener("transitionend",e),t.classList.remove(r)}}}function d(){const t=document.querySelector("button.scroll-up"),n=document.querySelector("h1"),r=n?n.offsetTop:0;if(!t){console.warn("Scroll up button not found in the document.");return}t.addEventListener("click",()=>{window.scrollTo({top:r,behavior:"smooth"})});const e=document.querySelector("article div.prose");if(!e){console.warn("Prose element not found in the article.");return}const o=c(t,"opacity","active");new IntersectionObserver(i=>{i.forEach(s=>{s.isIntersecting?o.show():o.hide()})},{rootMargin:"0px 0px -95% 0px"}).observe(e)}d();</script>
154 </main> <footer class="mt-auto pt-9 md:pt-11 grow-0 flex flex-col gap-6 items-center justify-between max-w-full text-foreground/80"> <div class="flex w-full max-w-md items-center justify-between px-4"> <a href="https://mathstodon.xyz/@thesearchspace" target="_blank" rel="noopener noreferrer" class="social-link"> <span class="sr-only">Mastodon</span> <svg width="24" height="24" viewBox="0 0 24 24" class="size-7"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="M15.5 21.5c-10.5 2.5 -12.5 -2.5 -12.5 -8.5v-3c0 -6 2.5 -7 7 -7h4c4.5 0 7 1.5 7 5.5v4c0 6.5 -10 4 -13.5 4c-1 0 -1.5 7 8 5Z" /><path d="M7 13.5l0 -5.5c0 0 0.5 -2 2.5 -2c2 0 2.5 2 2.5 2l0 2.5l0 -2.5c0 0 0.5 -2 2.5 -2c2 0 2.5 2 2.5 2l0 5.5" /></g></svg> </a> <a href="https://www.linkedin.com/in/felixholmgren" target="_blank" rel="noopener noreferrer" class="social-link"> <span class="sr-only">LinkedIn</span> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-7"><path d="M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-2-2 2 2 0 0 0-2 2v7h-4v-7a6 6 0 0 1 6-6z" /><rect width="4" height="12" x="2" y="9" /><circle cx="4" cy="4" r="2" /></svg> </a> <a href="mailto:[email protected]" target="_blank" rel="noopener noreferrer" class="social-link"> <span class="sr-only">Email</span> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-7"><path d="m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7" /><rect x="2" y="4" width="20" height="16" rx="2" /></svg> </a> <a href="/rss.xml" class="social-link"> <span class="sr-only">RSS</span> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-7"><path d="M4 11a9 9 0 0 1 9 9" /><path d="M4 4a16 16 0 0 1 16 16" /><circle cx="5" cy="19" r="1" /></svg> </a> </div> <div class="flex flex-col md:flex-row flex-wrap flex-1 items-center justify-center"> <span class="my-1"> Felix Holmgren © 2025 155</span> <span class="mx-5 hidden md:block"> :: </span> <span class="my-1"> 156Powered by <a class="underline" target="_blank" rel="noopener noreferrer" href="https://astro.build">Astro</a> 157& <a class="underline" target="_blank" rel="noopener noreferrer" href="https://github.com/stelcodes/multiterm-astro">MultiTerm</a> </span> </div> </footer> </div> </body></html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.