diff options
-rw-r--r-- | _posts/hello_world.html | 9 | ||||
-rw-r--r-- | _posts/processPosts.js | 121 | ||||
-rw-r--r-- | index.css | 4 | ||||
-rw-r--r-- | index.html | 2 | ||||
-rw-r--r-- | posts.css | 44 | ||||
-rw-r--r-- | posts.html | 93 | ||||
-rw-r--r-- | posts/hello_world.html | 41 | ||||
-rw-r--r-- | posts/linear_system_solver.html | 102 | ||||
-rw-r--r-- | posts/linear_system_solver.html~ | 77 | ||||
-rw-r--r-- | posts/linear_system_solver.js | 172 | ||||
-rw-r--r-- | posts/linear_system_solver.js~ | 106 | ||||
-rwxr-xr-x | resume.html | 24 |
12 files changed, 238 insertions, 557 deletions
diff --git a/_posts/hello_world.html b/_posts/hello_world.html new file mode 100644 index 0000000..038f5db --- /dev/null +++ b/_posts/hello_world.html @@ -0,0 +1,9 @@ +<p> + Hello, world! +</p> +<p> + This is the first test of my simple, static blogging system. My goal is to avoid using anything too heavy and, instead, provide a simple script that will get run whenever I update a blog post. Heck, I could even set it up to a cronjob to refresh them everyday. But perhaps that is overkill for today 😆. I am satisfied with how it current works. +</p> +<p> + Expect to see some updates on Greek philosophy, emacs, and Linux coming soon to a website near you! +</p> diff --git a/_posts/processPosts.js b/_posts/processPosts.js new file mode 100644 index 0000000..9db4103 --- /dev/null +++ b/_posts/processPosts.js @@ -0,0 +1,121 @@ + + +const fs = require('fs'); +const path = require('path'); + +const tags = [ + { + id: 'personal', + title: 'Personal 👨' + } +] + +const posts = [ + { + url: "_posts/hello_world.html", + title: "Hello, World!", + tags: [ "personal" ] + } +]; + +function createTag(tag) { + return ` + <button id="${tag.id}">${tag.title}</button> + `; +} + +function createPostServableFile(post) { + const dir = path.resolve(path.join(__dirname, '..', 'posts')); + + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir); + } + + const baseFilePath = path.join(__dirname, '..', post.url); + const stats = fs.statSync(baseFilePath); + const content = fs.readFileSync(baseFilePath); + const fileName = post.url.substring(post.url.lastIndexOf('/')); + const filePath = path.join(dir, fileName); + fs.writeFileSync(filePath,` +<!DOCTYPE html> +<html lang="en"> + <head> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta charset="utf-8"> + <link rel="stylesheet" href="/index.css"> + <link rel="stylesheet" href="/posts.css"> + <title>Matthew Kosarek</title> + <link rel="shortcut icon" href="/favicon/favicon.ico" type="image/x-icon"> + </head> + <body> + <header> + <h1>Matthew Kosarek</h1> + <nav> + <ul> + <li><a href='/'>🏡 Home</a></li> + <li><a href='/resume.html'>📘 CV</a></li> + <li><a href="https://www.linkedin.com/in/matthew-kosarek/">🏢 LinkedIn</a></li> + <li><a href='/posts.html'>📝 Posts</a></li> + </ul> + </nav> + </header> + + <article> + <h2>${post.title}</h2> + <h3>Created ${stats.birthtime.toLocaleString()}. Last updated: ${stats.mtime.toLocaleString()}</h3> + ${content} + </article> + </body> +</html> + `) + return '/posts/' + fileName; +} + +function createPostLink(post) { + return ` + <li><a href="${createPostServableFile(post)}">${post.title}</a></li> + `; +} + +const output = ` +<!DOCTYPE html> +<html lang="en"> + <head> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta charset="utf-8"> + <link rel="stylesheet" href="/index.css"> + <link rel="stylesheet" href="/posts.css"> + <title>Matthew Kosarek</title> + <link rel="shortcut icon" href="/favicon/favicon.ico" type="image/x-icon"> + </head> + <body> + <header> + <h1>Matthew Kosarek</h1> + <nav> + <ul> + <li><a href='/'>🏡 Home</a></li> + <li><a href='/resume.html'>📘 CV</a></li> + <li><a href="https://www.linkedin.com/in/matthew-kosarek/">🏢 LinkedIn</a></li> + <li><a href='/posts.html'>📝 Posts</a></li> + </ul> + </nav> + </header> + + <section> + <h2>Tags</h2> + <div id='tag_list'> + ${tags.map(createTag)} + </div> + </section + + <section> + <h2>Posts</h2> + <ul id='post_list'> + ${posts.map(createPostLink)} + </ul> + </section> + </body> +</html> +` + +fs.writeFileSync(path.join(__dirname, '..', 'posts.html'), output); @@ -1,7 +1,7 @@ body { width: 60vw; height: 100vh; - font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + font-family: "Noto Sans", 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; font-size: 16px; background-color: transparent; color: black; @@ -102,7 +102,7 @@ section a:hover { .image_item > img { width: inherit; - border-radius: 3px; + border-radius: 3px; border: 2px solid rgba(0, 0, 0, 0.3); } @@ -21,7 +21,7 @@ <li><a href='/'>🏡 Home</a></li> <li><a href='/resume.html'>📘 CV</a></li> <li><a href="https://www.linkedin.com/in/matthew-kosarek/">🏢 LinkedIn</a></li> - <li style="display: none;"><a href='/posts.html'>📝 Posts</a></li> + <li><a href='/posts.html'>📝 Posts</a></li> </ul> </nav> </header> @@ -1,28 +1,38 @@ -#post_section { - width: 50%; - display: flex; - flex-direction: column; - align-items: center; - color: white; +#tag_list { + width: 100%; + display: flex; + flex-direction: row; + align-items: center; + column-gap: 4px; +} + +#tag_list > button { + padding: 8px; + cursor: pointer; +} - font-family: Arial,Helvetica Neue,Helvetica,sans-serif !important; +#post_list { + display: flex; + flex-direction: column; } article { - width: 100%; - text-align: left; - padding-top: 1rem; + width: 100%; + text-align: left; + padding-top: 1rem; } article > h2 { - padding: 0; - margin: 0; + color: black; + padding: 0; + margin: 0; } article > h3 { - color: lightgray; - font-size: 0.8rem; - font-weight: normal; - padding: 0; - margin: 0; + margin: 0; + margin-top: 12px; + color: gray; + font-size: 12px; + font-weight: normal; + padding: 0; } @@ -1,86 +1,43 @@ + <!DOCTYPE html> <html lang="en"> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <meta charset="utf-8"> - <link rel="stylesheet" href="/index.css"> + <meta charset="utf-8"> + <link rel="stylesheet" href="/index.css"> <link rel="stylesheet" href="/posts.css"> - <title>Matthew Kosarek</title> - <link rel="shortcut icon" href="/favicon/favicon.ico" type="image/x-icon"> + <title>Matthew Kosarek</title> + <link rel="shortcut icon" href="/favicon/favicon.ico" type="image/x-icon"> </head> <body> - <header> + <header> <h1>Matthew Kosarek</h1> <nav> <ul> <li><a href='/'>🏡 Home</a></li> <li><a href='/resume.html'>📘 CV</a></li> + <li><a href="https://www.linkedin.com/in/matthew-kosarek/">🏢 LinkedIn</a></li> <li><a href='/posts.html'>📝 Posts</a></li> </ul> </nav> - </header> - - <section id='post_section'> + </header> + + <section> + <h2>Tags</h2> + <div id='tag_list'> + + <button id="personal">Personal 👨</button> + + </div> + </section + + <section> + <h2>Posts</h2> + <ul id='post_list'> + + <li><a href="/posts//hello_world.html">Hello, World!</a></li> + + </ul> </section> - - <script> - function fetchHtml(fileName) { - return fetch(fileName).then((response) => { - return response.text(); - }); - } - - function nodeScriptReplace(node) { - if ( nodeScriptIs(node) === true ) { - node.parentNode.replaceChild( nodeScriptClone(node) , node ); - } - else { - var i = -1, children = node.childNodes; - while ( ++i < children.length ) { - nodeScriptReplace( children[i] ); - } - } - - return node; - } - function nodeScriptClone(node){ - var script = document.createElement("script"); - script.text = node.innerHTML; - - var i = -1, attrs = node.attributes, attr; - while ( ++i < attrs.length ) { - script.setAttribute( (attr = attrs[i]).name, attr.value ); - } - return script; - } - - function nodeScriptIs(node) { - return node.tagName === 'SCRIPT'; - } - - (function() { - var postList = [ - ]; - - var postContainer = document.getElementById('post_section'); - if (!postContainer) { - console.error('Could not find post container.'); - return; - } - - postList.forEach(function(postName) { - fetchHtml(postName).then(function(text) { - var newSection = document.createElement('article'); - newSection.innerHTML = text; - nodeScriptReplace(newSection); - postContainer.appendChild(newSection); - }); - }); - })(); - </script> - </body> - - <script src='/index.js'></script> - <script src='/mini-jquery.js' type='module'></script> </html> diff --git a/posts/hello_world.html b/posts/hello_world.html new file mode 100644 index 0000000..27106e1 --- /dev/null +++ b/posts/hello_world.html @@ -0,0 +1,41 @@ + +<!DOCTYPE html> +<html lang="en"> + <head> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta charset="utf-8"> + <link rel="stylesheet" href="/index.css"> + <link rel="stylesheet" href="/posts.css"> + <title>Matthew Kosarek</title> + <link rel="shortcut icon" href="/favicon/favicon.ico" type="image/x-icon"> + </head> + <body> + <header> + <h1>Matthew Kosarek</h1> + <nav> + <ul> + <li><a href='/'>🏡 Home</a></li> + <li><a href='/resume.html'>📘 CV</a></li> + <li><a href="https://www.linkedin.com/in/matthew-kosarek/">🏢 LinkedIn</a></li> + <li><a href='/posts.html'>📝 Posts</a></li> + </ul> + </nav> + </header> + + <article> + <h2>Hello, World!</h2> + <h3>Created 11/12/2022, 8:48:06 PM. Last updated: 11/13/2022, 7:51:38 PM</h3> + <p> + Hello, world! +</p> +<p> + This is the first test of my simple, static blogging system. My goal is to avoid using anything too heavy and, instead, provide a simple script that will get run whenever I update a blog post. Heck, I could even set it up to a cronjob to refresh them everyday. But perhaps that is overkill for today 😆. I am satisfied with how it current works. +</p> +<p> + Expect to see some updates on Greek philosophy, emacs, and Linux coming soon to a website near you! +</p> + + </article> + </body> +</html> +
\ No newline at end of file diff --git a/posts/linear_system_solver.html b/posts/linear_system_solver.html deleted file mode 100644 index a8b17e5..0000000 --- a/posts/linear_system_solver.html +++ /dev/null @@ -1,102 +0,0 @@ - -<h2>Linear Systems Solver</h2> -<h3>2021-08-01 by Matthew Kosarek</h3> -<p> - I wanted to write a little algorithm to visually solve linear systems of equations for fun. I am only going to deal with 3x3 matrices for now, but I'll make it so that I can easily extend it to more matrices in the future if I think that would be cool. - - <br/><br/> - - <div id='equation_container'> - <div id='matrix_lhs'></div> - <label>×</label> - <div id='unknown_variables'></div> - <label>=</label> - <div id='matrix_rhs'></div> - </div> - - <div id='solution_container'> - </div> - - <div id='actions_container'> - <button class='action_button'id='reset_button'> - Reset - </button> - <button class='action_button' id='solve_button'> - Solve - </button> - </div> - - <script src='/posts/linear_system_solver.js'></script> - - <style> - #equation_container { - display: flex; - flex-direction: row; - align-items: center; - width: 100%; - justify-content: center; - } - - #equation_container input { - width: 128px; - } - - #equation_container > label { - padding: 1rem; - } - - #matrix_lhs { - display: grid; - grid-gap: 1rem; - grid-template-columns: repeat(3, 1fr); - } - - #unknown_variables { - display: grid; - grid-gap: 1rem; - } - - #unknown_variables > input { - text-align: center; - } - - #matrix_rhs { - display: grid; - grid-gap: 1rem; - } - - #actions_container { - padding: 1rem; - text-align: center; - } - - #solve_button { - background-color: lightgreen; - } - - .augmented_matrix_container { - display: flex; - flex-direction: row; - width: 100%; - padding: 1rem; - } - - .augmented_matrix_container input { - width: 128px; - } - - .augmented_matrix_container > div:first-child { - display: grid; - grid-gap: 1rem; - grid-template-columns: repeat(3, 1fr); - padding-right: 0.5rem; - border-right: 1px dashed white; - } - - .augmented_matrix_container > div:last-child { - display: grid; - grid-gap: 1rem; - padding-left: 0.5rem; - } - </style> -</p> diff --git a/posts/linear_system_solver.html~ b/posts/linear_system_solver.html~ deleted file mode 100644 index a280a8b..0000000 --- a/posts/linear_system_solver.html~ +++ /dev/null @@ -1,77 +0,0 @@ - -<h2>Linear Systems Solver</h2> -<h3>2021-08-01 by Matthew Kosarek</h3> -<p> - I wanted to write a little algorithm to visually solve linear systems of equations for fun. I am only going to deal with 3x3 matrices for now, but I'll make it so that I can easily extend it to more matrices in the future if I think that would be cool. - - <br/><br/> - - <div id='equation_container'> - <div id='matrix_lhs'></div> - <label>×</label> - <div id='unknown_variables'></div> - <label>=</label> - <div id='matrix_rhs'></div> - </div> - - <div id='solution_container'> - </div> - - <div id='actions_container'> - <button class='action_button'id='reset_button'> - Reset - </button> - <button class='action_button' id='solve_button'> - Solve - </button> - </div> - - <script src='/posts/linear_system_solver.js'></script> - - <style> - #equation_container { - display: flex; - flex-direction: row; - align-items: center; - width: 100%; - justify-content: center; - } - - #equation_container input { - width: 128px; - } - - #equation_container > label { - padding: 1rem; - } - - #matrix_lhs { - display: grid; - grid-gap: 1rem; - grid-template-columns: repeat(3, 1fr); - } - - #unknown_variables { - display: grid; - grid-gap: 1rem; - } - - #unknown_variables > input { - text-align: center; - } - - #matrix_rhs { - display: grid; - grid-gap: 1rem; - } - - #actions_container { - padding: 1rem; - text-align: center; - } - - #solve_button { - background-color: lightgreen; - } - </style> -</p> diff --git a/posts/linear_system_solver.js b/posts/linear_system_solver.js deleted file mode 100644 index 9eb901f..0000000 --- a/posts/linear_system_solver.js +++ /dev/null @@ -1,172 +0,0 @@ -var $ = window.$, - rows = 3, - columns = 3, - currentLhs = [], // rows x columns matrix - currentRhs = []; // rows x 1 matrix - solutionContainer = $('#solution_container'); - -function main() { - $('#reset_button').on('click', onResetClicked); - $('#solve_button').on('click', onSolveClicked); - resetView(); -} - -function resetView() { - renderLHS(); - renderUnknowns(); - renderRHS(); - - currentLhs = []; - currentRhs = []; - for (var r = 0; r < rows; r++) { - for (var c = 0; c < columns; c++) { - currentLhs.push(0); - } - } - - for (var otherR = 0; otherR < rows; otherR++) { - currentRhs.push(0); - } - - solutionContainer.empty(); -} - -// Renders for the input container. -function renderLHS() { - var lhs = $('#matrix_lhs').empty(), - addCell = function(index) { - $('<input>').type('number').val(0).on('change', function(event) { - currentLhs[index] = Number(event.target.value); - }).appendTo(lhs); - }; - - for (var r = 0; r < rows; r++) { - for (var c = 0; c < columns; c++) { - addCell((r * rows) + c); - } - } -} - -function renderUnknowns() { - var unknownsContainer = $('#unknown_variables').empty(); - - for (var r = 0; r < columns; r++) { - var cell = $('<input>').disabled(true).val(String.fromCharCode('x'.charCodeAt(0) + r).toUpperCase()); - unknownsContainer.append(cell); - } -} - -function renderRHS() { - var rhs = $('#matrix_rhs').empty(), - addCell = function(index) { - $('<input>').type('number').val(0).on('change', function(event) { - currentRhs[index] = Number(event.target.value); - }).appendTo(rhs); - }; - - for (var r = 0; r < rows; r++) { - addCell(r); - } -} - -// Renders for the augmented matrix container -function renderAugmentedMatrix(lhs, rhs) { - var container = $('<div>').addClass('augmented_matrix_container'), - lhsContainer = $('<div>').appendTo(container), - rhsContainer = $('<div>').appendTo(container), - addLhsCell = function(index) { - $('<input>').type('number').val(lhs[index]).disabled(true).appendTo(lhsContainer); - }, - addRhsCell = function(index) { - $('<input>').type('number').val(rhs[index]).disabled(true).appendTo(rhsContainer); - }; - - for (var r = 0; r < rows; r++) { - for (var c = 0; c < columns; c++) { - addLhsCell(r * rows + c); - } - } - - for (var otherR = 0; otherR < rows; otherR++) { - addRhsCell(otherR); - } - - return container; -} - -// Solver helper functions -function findLargestValue(c, rowStart) { - var largestValue = 0, - largestRow = -1; - for (var r = rowStart; r < rows; r++) { - var currValue = Math.abs(currentLhs[r * rows + c]); - if (currValue > largestValue) { - largestValue = currValue; - largestRow = r; - } - } - return { - row: largestRow, - value: largestValue - }; -} - -function swapRows(r1, r2) { - if (r1 === r2) { - return; - } - - for (var c = 0; c < columns; c++) { - var temp = currentLhs[r1 * row + c]; - currentLhs[r1 * rows + c] = currentLhs[r2 * row + c]; - currentLhs[r2 * rows + c] = temp; - } - - var rhsTmp = currentRhs[r1]; - currentRhs[r1] = currentRhs[r2]; - currentRhs[r2] = rhsTmp; -} - -function multiplyRow(r, scale) { - for (var c = 0; c < columns; c++) { - currentLhs[r * rows + c] *= scale; - } - - currentRhs[r] *= scale; -} - -function addRow(r, a) { - for (var c = 0; c < columns; c++) { - currentLhs[r * rows + c] += a; - } - - currentRhs[r] += a; -} - -// Callbacks for actions -function onResetClicked() { - resetView(); -} - -function onSolveClicked() { - var rowStart = 0; - for (var c = 0; c < columns; c++) { - var largestForColumn = findLargestValue(c, rowStart); - if (largestForColumn.row >= 0) { - swapRows(rowStart, largestForColumn.row); - multiplyRow(rowStart, 1.0 / largestForColumn.value); - - for (var r = 0; r < rows; r++) { - if (r === rowStart) continue; - - } - } - - rowStart++; - } - - solutionContainer.append(renderAugmentedMatrix(currentLhs, currentRhs)); - solutionContainer.append(renderAugmentedMatrix(currentLhs, currentRhs)); -} - -main(); diff --git a/posts/linear_system_solver.js~ b/posts/linear_system_solver.js~ deleted file mode 100644 index 33fc026..0000000 --- a/posts/linear_system_solver.js~ +++ /dev/null @@ -1,106 +0,0 @@ -var $ = window.$, - rows = 3, - columns = 3, - currentLhs = [], // rows x columns matrix - currentRhs = []; // rows x 1 matrix - solutionContainer = $('#solution_container'); - -function main() { - $('#reset_button').on('click', onResetClicked); - $('#solve_button').on('click', onSolveClicked); - resetView(); -} - -function resetView() { - renderLHS(); - renderUnknowns(); - renderRHS(); - - currentLhs = []; - currentRhs = []; - for (var r = 0; r < rows; r++) { - for (var c = 0; c < columns; c++) { - currentLhs.push(0); - } - } - - for (var otherR = 0; otherR < rows; otherR++) { - currentRhs.push(0); - } - - solutionContainer.empty(); -} - -// Renders for the input container. -function renderLHS() { - var lhs = $('#matrix_lhs').empty(), - addCell = function(index) { - $('<input>').type('number').val(0).on('change', function(event) { - currentLhs[index] = Number(event.target.value); - }).appendTo(lhs); - }; - - for (var r = 0; r < rows; r++) { - for (var c = 0; c < columns; c++) { - addCell((r * rows) + c); - } - } -} - -function renderUnknowns() { - var unknownsContainer = $('#unknown_variables').empty(); - - for (var r = 0; r < columns; r++) { - var cell = $('<input>').disabled(true).val(String.fromCharCode('x'.charCodeAt(0) + r).toUpperCase()); - unknownsContainer.append(cell); - } -} - -function renderRHS() { - var rhs = $('#matrix_rhs').empty(), - addCell = function(index) { - $('<input>').type('number').val(0).on('change', function(event) { - currentRhs[index] = Number(event.target.value); - }).appendTo(rhs); - }; - - for (var r = 0; r < rows; r++) { - addCell(r); - } -} - -// Renders for the solution container -function renderAugmentedMatrix(lhs, rhs) { - var container = $('<div>').addClass('augmented_matrix_container'), - lhsContainer = $('<div>').appendTo(container), - rhsContainer = $('<div>').appendTo(container), - addLhsCell = function(index) { - $('<input>').type('number').val(lhs[index]).disabled(true).appendTo(lhsContainer); - }, - addRhsCell = function(index) { - $('<input>').type('number').val(rhs[index]).disabled(true).appendTo(rhsContainer); - }; - - for (var r = 0; r < rows; r++) { - for (var c = 0; c < columns; c++) { - addLhsCell(r * rows + c); - } - } - - for (var otherR = 0; otherR < rows; otherR++) { - addRhsCell(otherR); - } - - return container; -} - -// Callbacks for actions -function onResetClicked() { - resetView(); -} - -function onSolveClicked() { - solutionContainer.append(renderAugmentedMatrix(currentLhs, currentRhs)); -} - -main(); diff --git a/resume.html b/resume.html index e28129d..acac84c 100755 --- a/resume.html +++ b/resume.html @@ -1,14 +1,14 @@ <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <meta charset="utf-8"> - <link rel="stylesheet" href="/index.css"> - <link rel="stylesheet" href="/resume.css"> - <script src='/resume.js' defer></script> + <meta charset="utf-8"> + <link rel="stylesheet" href="/index.css"> + <link rel="stylesheet" href="/resume.css"> + <script src='/resume.js' defer></script> - <title>Matthew Kosarek - Resume</title> - <link rel="shortcut icon" href="/favicon/favicon.ico" type="image/x-icon"> - <meta name="description" content="The hosted resume of Matthew kosarek"> + <title>Matthew Kosarek - Resume</title> + <link rel="shortcut icon" href="/favicon/favicon.ico" type="image/x-icon"> + <meta name="description" content="The hosted resume of Matthew kosarek"> </head> <body> <header> @@ -17,8 +17,8 @@ <ul> <li><a href='/'>🏡 Home</a></li> <li><a href='/resume.html'>📘 CV</a></li> - <li><a href="https://www.linkedin.com/in/matthew-kosarek/">🏢 LinkedIn</a></li> - <li style="display: none;"><a href='/posts.html'>📝 Posts</a></li> + <li><a href="https://www.linkedin.com/in/matthew-kosarek/">🏢 LinkedIn</a></li> + <li><a href='/posts.html'>📝 Posts</a></li> </ul> </nav> </header> @@ -230,9 +230,9 @@ <h2>Projects</h2> <ul> <li>My <b>self-hosted personal website</b> where I do small projects in WebAssembly and OpenGL: <a href="https://matthewkosarek.xyz">https://matthewkosarek.xyz</a> - <li>A <b>game engine</b> that I built from scrach in C++ and OpenGL: <a href="https://github.com/mattkae/MatteEngine"">https://github.com/mattkae/MatteEngine</a></li> - <li>My <b>self-installing emacs configuration</b>: <a href="https://git.matthewkosarek.xyz/emacs_config/">https://git.matthewkosarek.xyz/emacs_config/</a> </li> - <li>Unfinished website about <b>realtime physics in video games</b>: <a href="https://physicsforgames.com/">https://physicsforgames.com/</a> </li> + <li>A <b>game engine</b> that I built from scrach in C++ and OpenGL: <a href="https://github.com/mattkae/MatteEngine"">https://github.com/mattkae/MatteEngine</a></li> + <li>My <b>self-installing emacs configuration</b>: <a href="https://git.matthewkosarek.xyz/emacs_config/">https://git.matthewkosarek.xyz/emacs_config/</a> </li> + <li>Unfinished website about <b>realtime physics in video games</b>: <a href="https://physicsforgames.com/">https://physicsforgames.com/</a> </li> </ul> </section> </section> |