@ -0,0 +1,2 @@ | |||
.vscode | |||
node_modules |
@ -0,0 +1,21 @@ | |||
# How does this work | |||
_This file is intended to help you remember the thing you made way back then..._ | |||
## Instructions | |||
1. Create your html file and put it in `/posts` | |||
2. Then create the meta file for it of the same name but using the ext `.json`. This file should look like: | |||
{ | |||
"title": "Something Decent - Levi Olson", | |||
"permalink": "/posts/something-decent", | |||
"created_at": "2018-04-27T17:05:19-06:00", | |||
"created_at_short": "2018-04-27", | |||
"post_title": "the start of something... decent", | |||
"active": "posts", | |||
"content_file": "something-decent.html", | |||
"categories" : ["misc", "programming", "js", "etc..."] | |||
} | |||
3. That's it. |
@ -0,0 +1,77 @@ | |||
'use strict' | |||
const express = require('express') | |||
const fs = require('fs') | |||
const path = require('path') | |||
const app = express() | |||
app.set('view engine', 'ejs') | |||
app.get('/', (req, res) => { | |||
res.render('pages/index', { | |||
title: "Levi Olson", | |||
active: "home", | |||
content: "" | |||
}) | |||
}) | |||
app.get('/posts', (req, res) => { | |||
const postDir = __dirname + '/posts' | |||
let files = fs.readdirSync(postDir, 'utf8') | |||
let data = { | |||
title: "Posts - Levi Olson", | |||
active: "posts", | |||
posts: [] | |||
} | |||
for (let i = 0; i < files.length; i++) { | |||
if (path.extname(files[i]) === '.json') { | |||
data.posts.push(getData(files[i])) | |||
} | |||
} | |||
res.render('pages/posts', data) | |||
}) | |||
function getData(file) { | |||
let postData | |||
try { | |||
postData = JSON.parse(fs.readFileSync('./posts/' + file, 'utf8')) | |||
postData.content = fs.readFileSync('./posts/' + postData.content_file, 'utf8') | |||
} catch (e) { | |||
return | |||
} | |||
return postData | |||
} | |||
app.get('/about', (req, res) => { | |||
res.sendFile(__dirname + '/views/pages/about.html') | |||
}) | |||
app.get('/uncopyright', (req, res) => { | |||
return res.sendFile(__dirname + '/views/pages/uncopyright.html') | |||
}) | |||
app.get('/404', (req, res) => { | |||
return res.status(404).render('pages/404', { | |||
title: "Page Not Found - Levi Olson", | |||
active: "" | |||
}) | |||
}) | |||
app.get('/core.css', (req, res) => { | |||
res.sendFile(__dirname + '/core.css') | |||
}) | |||
app.get('/posts/:post', (req, res) => { | |||
let post = req.params.post | |||
let postData | |||
try { | |||
postData = JSON.parse(fs.readFileSync('./posts/' + post + '.json', 'utf8')) | |||
postData.content = fs.readFileSync('./posts/' + postData.content_file, 'utf8') | |||
} catch (e) { | |||
return res.redirect('/404') | |||
} | |||
return res.render('pages/post', postData) | |||
}) | |||
app.listen(3000, () => console.log('Example app listening on port 3000!')) |
@ -0,0 +1,217 @@ | |||
body { | |||
font-family: Hack, Menlo, Monaco, Ubuntu Mono, monospace; | |||
font-size: 14px; | |||
color: #ddd; | |||
background: #222; | |||
padding: 20px; | |||
margin: 0; | |||
display: flex; | |||
justify-content: center; | |||
line-height: 1.5; | |||
} | |||
h1, | |||
h2, | |||
h3, | |||
h4, | |||
h5, | |||
h6, | |||
p, | |||
code, | |||
kbd, | |||
tt, | |||
var { | |||
font-size: 14px; | |||
} | |||
article h1, | |||
h2, | |||
h3, | |||
h4, | |||
h5, | |||
h6 { | |||
padding: 20px 0 20px 0 | |||
} | |||
blockquote { | |||
border-left: 5px solid #ddd; | |||
margin: 0; | |||
padding: 0 20px 0 20px; | |||
margin: 0 0 40px 0; | |||
} | |||
.container { | |||
display: flex; | |||
flex-direction: column; | |||
width: 100%; | |||
max-width: 700px; | |||
align-items: center; | |||
} | |||
header { | |||
padding-top: 20px; | |||
padding-bottom: 40px; | |||
} | |||
footer.footer-container { | |||
align-self: left; | |||
padding-top: 120px; | |||
} | |||
div.site { | |||
align-items: center; | |||
width: 100%; | |||
} | |||
a { | |||
color: #fff; | |||
} | |||
a:hover { | |||
color: #999; | |||
} | |||
a:visited { | |||
color: #eee; | |||
} | |||
code { | |||
color: #ddd; | |||
background: #333; | |||
} | |||
pre { | |||
background: #333; | |||
} | |||
.main-menu a, | |||
.social-menu a { | |||
color: #ddd; | |||
} | |||
.main-menu-container { | |||
margin-top: 0em; | |||
} | |||
nav { | |||
width: 100%; | |||
} | |||
nav ul { | |||
padding: 0 0 100px 0; | |||
margin: 0; | |||
} | |||
nav ul li { | |||
font-size: 14px; | |||
display: inline-block; | |||
text-transform: lowercase; | |||
} | |||
nav ul li.logo a { | |||
text-decoration: none; | |||
} | |||
nav ul li a:hover { | |||
border-bottom: none; | |||
color: #999; | |||
} | |||
.title { | |||
margin-bottom: 0; | |||
text-transform: none; | |||
color: #ddd; | |||
padding-bottom: 0; | |||
} | |||
main { | |||
align-self: left; | |||
} | |||
div.meta { | |||
padding-right: 10px; | |||
} | |||
.list-item-header h3, | |||
header { | |||
padding: 0; | |||
margin: 0; | |||
} | |||
article li { | |||
list-style-type: square; | |||
} | |||
.list { | |||
display: -webkit-box; | |||
display: -ms-flexbox; | |||
display: flex; | |||
-webkit-box-orient: vertical; | |||
-webkit-box-direction: normal; | |||
-ms-flex-flow: column nowrap; | |||
flex-flow: column nowrap; | |||
margin: 0; | |||
padding: 0; | |||
list-style: none; | |||
} | |||
.list-item article { | |||
display: -webkit-box; | |||
display: -ms-flexbox; | |||
display: flex; | |||
-webkit-box-orient: horizontal; | |||
-webkit-box-direction: normal; | |||
-ms-flex-flow: row nowrap; | |||
flex-flow: row nowrap; | |||
-webkit-box-align: baseline; | |||
-ms-flex-align: baseline; | |||
align-items: baseline; | |||
} | |||
pre { | |||
padding: 20px 10px; | |||
} | |||
code { | |||
color: lightcoral; | |||
} | |||
pre>code { | |||
color: #ddd; | |||
} | |||
.mute { | |||
color: #999; | |||
} | |||
/* | |||
Hack Font | |||
*/ | |||
@font-face { | |||
font-family: 'Hack'; | |||
src: url('fonts/hack-regular.woff2?sha=e700a30') format('woff2'), url('fonts/hack-regular.woff?sha=e700a30') format('woff'); | |||
font-weight: 400; | |||
font-style: normal; | |||
} | |||
@font-face { | |||
font-family: 'Hack'; | |||
src: url('fonts/hack-bold.woff2?sha=e700a30') format('woff2'), url('fonts/hack-bold.woff?sha=e700a30') format('woff'); | |||
font-weight: 700; | |||
font-style: normal; | |||
} | |||
@font-face { | |||
font-family: 'Hack'; | |||
src: url('fonts/hack-italic.woff2?sha=e700a30') format('woff2'), url('fonts/hack-italic.woff?sha=e700a30') format('woff'); | |||
font-weight: 400; | |||
font-style: italic; | |||
} | |||
@font-face { | |||
font-family: 'Hack'; | |||
src: url('fonts/hack-bolditalic.woff2?sha=e700a30') format('woff2'), url('fonts/hack-bolditalic.woff?sha=e700a30') format('woff'); | |||
font-weight: 700; | |||
font-style: italic; | |||
} |
@ -0,0 +1,18 @@ | |||
{ | |||
"name": "levi", | |||
"version": "1.0.0", | |||
"description": "", | |||
"main": "app.js", | |||
"dependencies": { | |||
"ejs": "^2.5.9", | |||
"express": "^4.16.3", | |||
"nodemon": "^1.17.3" | |||
}, | |||
"devDependencies": {}, | |||
"scripts": { | |||
"start": "./node_modules/.bin/nodemon app.js", | |||
"test": "echo \"Error: no test specified\" && exit 1" | |||
}, | |||
"author": "", | |||
"license": "ISC" | |||
} |
@ -0,0 +1,133 @@ | |||
<p>You may think your password is secure. Maybe you have chosen an obscure word, mixed in numbers, and added a | |||
<code>!</code> to the end. Think you’re pretty safe, huh?</p> | |||
<p>The truth is, you aren’t. I can crack a 5 character password in less then 139 seconds!</p> | |||
<p>We have been trained over time, by | |||
<em>unproven</em> security techniques, to make our passwords contain numbers and letters; sometimes even an | |||
<code>@</code> or | |||
<code>#</code> or | |||
<code>!</code> is added to the mix. | |||
<strong>But</strong> the truth is, we are only making it harder on ourselves with passwords that are difficult to remember, but | |||
easy to guess in a brute-force attack (automated hacking software).</p> | |||
<p>Although a 128-character | |||
<em>totally random</em> password would be phenomenal, 8 characters is about all that can be enforced without frustrating | |||
users. However, an 8-character password comprised of uppercase, lowercase, and numbers can be cracked overnight in a | |||
real world brute-force attack.</p> | |||
<h2 id="the-scoop-on-alpha-numeric-passwords">The Scoop on Alpha-Numeric Passwords</h2> | |||
<p>Even though we are trained to think that a password of | |||
<code>Blu3D0g5</code> is the most secure type of password, it can still be cracked by a brute-force attack. | |||
</p> | |||
<p>Bare with me while I explain… | |||
<em>with some maths!</em> | |||
</p> | |||
<p>For every character in an alpha-numeric password there are | |||
<code>62</code> possibilities. First, you have the | |||
<code>26</code> character alphabet in lowercase, then | |||
<code>26</code> more in uppercase, and | |||
<code>10</code> digits.</p> | |||
<div> | |||
<pre style="text-align: center;"><code>26 + 26 + 10 = 62</code></pre> | |||
</div> | |||
<p>This is to say that if you choose 8 characters, | |||
<em>completely at random</em>, your password would be very secure. However, we typically take a familiar word, or couple | |||
of words, and add some uppercase letters, or replace | |||
<code>e</code> with | |||
<code>3</code>, etc… which is | |||
<strong>not</strong> secure.</p> | |||
<p>When we calculate the Information Entropy (known as the lack of order or predictability) we can see that a completely random | |||
character set is great, but when it is derived from an English word, or contains a date, it is simply terrible. The equation | |||
looks like this:</p> | |||
<div> | |||
<pre style="text-align: center;"><code>[Password_Length] * log2([Number_of_Possibilities]) = "Information Entropy"</code></pre> | |||
</div> | |||
<div> | |||
<pre><code>8 * log2(62) = "~48 bits" | |||
# which would take almost 9,000 years at 1,000 guesses per second</code></pre> | |||
</div> | |||
<p> | |||
<em>But, when your password isn’t | |||
<strong>completely</strong> random, it’s not that simple.</em> | |||
</p> | |||
<p>Because the password we chose was actually two words, | |||
<code>blue</code> and | |||
<code>dogs,</code> with some uppercase and numbers mixed in, the total Entropy is | |||
<strong>MUCH</strong> less. Something closer to | |||
<code>~28 bits</code>.</p> | |||
<p> | |||
<strong>So let’s calculate what this actually means.</strong> A brute-force attacker can easily guess 1,000 times per second. | |||
The total number of options to guess can be calculated by taking the base 2 to the total number of bits.</p> | |||
<div> | |||
<pre><code>2^28 = 268,435,456 | |||
# This is the total number of possibilities the password could be.</code></pre> | |||
</div> | |||
<p>In theory though, an attacker only needs to guess about half the total number of options before stumbling upon the correct | |||
one. So:</p> | |||
<div> | |||
<pre><code>268,435,456 / 2 = 134,217,728 | |||
# Total number of guesses it takes to guess your password | |||
134,217,728 / 1,000 = ~134,218 | |||
# At 1,000 guesses per second, it takes about 134,218 seconds | |||
134,218 / 60 = ~2,237 | |||
# Or 2,237 minutes | |||
2,237 / 60 = ~37 | |||
# Or 37 hours to guess your password</code></pre> | |||
</div> | |||
<hr> | |||
<h2 id="in-contrast">In Contrast</h2> | |||
<p>Let’s say we use 4 | |||
<strong>random</strong> words, without any numbers, and all lowercase. For example: | |||
<code>yellow</code> | |||
<code>tiger</code> | |||
<code>note</code> | |||
<code>basket</code>. There are an incalculable amount of words for you to choose from, but most likely, you will choose from | |||
about 7,000 of the most commonly used words. If you use unique words like | |||
<code>laggardly</code> or | |||
<code>pomological</code>, the total time to crack your password will increase | |||
<strong>exponentially</strong>!</p> | |||
<p>Using this new data, the Information Entropy is now calculated as:</p> | |||
<div> | |||
<pre style="text-align: center;"><code>[Number_of_words] * log2(7,000)</code></pre> | |||
</div> | |||
<p>So, this new password now has | |||
<code>~51 bits</code> of Entropy, and using the same time calculations above, we estimate our password would take about | |||
<code>35,702 years</code> to crack at the rate of 1,000 guesses per second.</p> | |||
<p>That is in stark contrast to the short 37 hours it takes to crack the | |||
<code>Blu3D0g5</code> password.</p> | |||
<hr> | |||
<h2 id="the-take-away">The Take Away</h2> | |||
<p>By simply increasing the length of our passwords and using words randomly mixed together, we can have the most secure passwords | |||
that attackers will struggle to figure out, but that we can actually remember. I personally will never forget | |||
<code>yellow</code> | |||
<code>tiger</code> | |||
<code>note</code> | |||
<code>basket</code> as long as I live. However, now I can’t use it.</p> |
@ -0,0 +1,9 @@ | |||
{ | |||
"title": "I can crack your password - Levi Olson", | |||
"permalink": "/posts/i-can-crack-your-password", | |||
"created_at": "2018-04-27T07:05:32-06:00", | |||
"created_at_short": "2018-04-27", | |||
"post_title": "i can crack your password", | |||
"active": "posts", | |||
"content_file": "i-can-crack-your-password.html" | |||
} |
@ -0,0 +1,4 @@ | |||
<blockquote> | |||
<p>the start of something... decent</p> | |||
</blockquote> | |||
<p>I don't expect to have a lot to say, but when I do, I'd like a place to put it.</p> |
@ -0,0 +1,9 @@ | |||
{ | |||
"title": "Something Decent - Levi Olson", | |||
"permalink": "/posts/something-decent", | |||
"created_at": "2018-04-27T17:05:19-06:00", | |||
"created_at_short": "2018-04-27", | |||
"post_title": "the start of something... decent", | |||
"active": "posts", | |||
"content_file": "something-decent.html" | |||
} |
@ -0,0 +1,45 @@ | |||
<!DOCTYPE html> | |||
<html lang="en"> | |||
<head> | |||
<% include ../partials/head %> | |||
</head> | |||
<body class="home type-page"> | |||
<div class="container"> | |||
<% include ../partials/header %> | |||
<main class="main" id="main"> | |||
<article class="entry"> | |||
<header class="header-container"> | |||
<div class="header entry-header"> | |||
<div class="header-info"> | |||
<h1 class="title"> | |||
404 | |||
</h1> | |||
</div> | |||
<div class="meta"> | |||
<span class="posted-on"> | |||
<time class="date" datetime="2018-04-27T17:05:19-06:00"></time> | |||
</span> | |||
</div> | |||
</div> | |||
</header> | |||
<div class="entry-content"> | |||
<h2>What on earth are your trying to pull hot shot.</h2> | |||
<a href="/">Turn around</a> | |||
</div> | |||
<footer class="entry-footer-container"> | |||
<div class="entry-footer"> | |||
</div> | |||
</footer> | |||
</article> | |||
</main> | |||
<% include ../partials/footer %> | |||
</div> | |||
</body> | |||
</html> |
@ -0,0 +1,62 @@ | |||
<!DOCTYPE html> | |||
<html> | |||
<head> | |||
<title>Levi Olson</title> | |||
<meta charset="UTF-8"> | |||
<meta name="viewport" content="width=device-width, initial-scale=1"> | |||
<!-- <link rel="stylesheet" href="core.css"> --> | |||
<style> | |||
body { | |||
background-color: #222 !important; | |||
color: #fff !important; | |||
font-family: monospace !important; | |||
font-size: 20px !important; | |||
line-height: 1.4 !important; | |||
padding-top: 120px !important; | |||
padding-bottom: 60px !important; | |||
overflow-x: none !important; | |||
} | |||
main { | |||
padding-right: 10px !important; | |||
padding-left: 10px !important; | |||
margin-right: auto !important; | |||
margin-left: auto !important; | |||
max-width: 600px !important; | |||
min-width: 280px !important; | |||
} | |||
a { | |||
text-decoration: none !important; | |||
outline: none !important; | |||
font-weight: bold !important; | |||
color: #777 !important; | |||
} | |||
a:hover, | |||
a:active, | |||
a:focus { | |||
color: #888 !important; | |||
} | |||
</style> | |||
</head> | |||
<body> | |||
<main> | |||
<p> | |||
Owner of | |||
<a href="https://securepass.io/" target="_blank">this company</a>, | |||
<br />former Senior Software Engineer at | |||
<a href="https://carsforsale.com" target="_blank">this company</a>, | |||
<br /> look what | |||
<a href="https://github.com/leothelocust">I can do</a>, | |||
<br /> contact me | |||
<a href="mailto:me@leviolson.com">here</a> | |||
<br /> or read stuff I write | |||
<a href="/posts">here</a>. | |||
</p> | |||
</main> | |||
</body> | |||
</html> |
@ -0,0 +1,53 @@ | |||
<!DOCTYPE html> | |||
<html lang="en"> | |||
<head> | |||
<% include ../partials/head %> | |||
</head> | |||
<body class="home type-page"> | |||
<div class="container"> | |||
<% include ../partials/header %> | |||
<main class="main" id="main"> | |||
<article class="entry"> | |||
<header class="header-container"> | |||
<div class="header entry-header"> | |||
<div class="header-info"> | |||
<h1 class="title"> | |||
<a href="/"></a> | |||
</h1> | |||
</div> | |||
<div class="meta"> | |||
<span class="posted-on"> | |||
<time class="date" datetime="2018-04-27T17:05:19-06:00"></time> | |||
</span> | |||
</div> | |||
</div> | |||
</header> | |||
<div class="entry-content"> | |||
<p>So, we've been trying to get our 5 yr old son to finish drinking his milk.</p> | |||
<p>One of the ways we have encourage him is to explain that milk contains proteins that | |||
are good for the body and help build strong muscles. Skim is good, 1% is good, 2% is even better. | |||
</p> | |||
<p>He thought for a while, and said...<br /><br /></p> | |||
<blockquote> | |||
<p>Dad, have you been drinking 100% milk? | |||
<br />Cause your muscles are sooo big! | |||
</p> | |||
</blockquote> | |||
<p>And that my friends is why being a dad is the best.</p> | |||
</div> | |||
<footer class="entry-footer-container"> | |||
<div class="entry-footer"> | |||
</div> | |||
</footer> | |||
</article> | |||
</main> | |||
<% include ../partials/footer %> | |||
</div> | |||
</body> | |||
</html> |
@ -0,0 +1,46 @@ | |||
<!DOCTYPE html> | |||
<html lang="en"> | |||
<head> | |||
<% include ../partials/head %> | |||
</head> | |||
<body class="home type-page"> | |||
<div class="container"> | |||
<% include ../partials/header %> | |||
<main class="main" id="main"> | |||
<article class="entry"> | |||
<header class="header-container"> | |||
<div class="header entry-header"> | |||
<div class="header-info"> | |||
<h1 class="title"> | |||
<a href="<%= permalink %>"><%= post_title %></a> | |||
</h1> | |||
</div> | |||
<div class="meta"> | |||
<span class="posted-on"> | |||
<time class="date" datetime="<%= created_at %>"><%= created_at_short %></time> | |||
</span> | |||
</div> | |||
</div> | |||
</header> | |||
<div class="entry-content" style="padding-top: 50px;"> | |||
<%- content %> | |||
</div> | |||
<footer class="entry-footer-container" style="padding-top:100px;"> | |||
<div class="entry-footer"> | |||
<p>- until next time.</p> | |||
</div> | |||
</footer> | |||
</article> | |||
</main> | |||
<% include ../partials/footer %> | |||
</div> | |||
</body> | |||
</html> |
@ -0,0 +1,56 @@ | |||
<!DOCTYPE html> | |||
<html lang="en"> | |||
<head> | |||
<% include ../partials/head %> | |||
</head> | |||
<body class="home type-page"> | |||
<div class="container"> | |||
<% include ../partials/header %> | |||
<main id='main' class='main'> | |||
<header class='header-container'> | |||
<div class='header list-header'> | |||
<div class='header-info'> | |||
<h1 class='title'>Posts</h1> | |||
</div> | |||
</div> | |||
</header> | |||
<div class='list-container'> | |||
<ul class='list'> | |||
<% posts.forEach(function(post) { %> | |||
<li class='list-item'> | |||
<article> | |||
<div class='meta'> | |||
<span> | |||
<time datetime='<%= post.created_at %>'><%= post.created_at_short %></time> | |||
</span> | |||
</div> | |||
<header class='list-item-header'> | |||
<h3 class='list-item-title'> | |||
<a href='<%= post.permalink %>'><%= post.title %></a> | |||
</h3> | |||
</header> | |||
</article> | |||
</li> | |||
<% }) %> | |||
</ul> | |||
</div> | |||
</main> | |||
<footer id='footer' class='footer-container'> | |||
<div class='footer'> | |||
<div class='copyright'> | |||
<p> | |||
<a href='/uncopyright'>uncopyright</a> | |||
</p> | |||
</div> | |||
</div> | |||
</footer> | |||
</div> | |||
</div> | |||
</body> | |||
</html> |
@ -0,0 +1,69 @@ | |||
<!DOCTYPE html> | |||
<html lang="en"> | |||
<head> | |||
<meta charset='utf-8'> | |||
<meta name="viewport" content="width=device-width, initial-scale=1"> | |||
<title>uncopyright</title> | |||
<link rel='stylesheet' href='core.css'> | |||
</head> | |||
<body class='page type-page layout-simple'> | |||
<div class="container"> | |||
<nav> | |||
<ul> | |||
<li> | |||
<a href="/">home</a> | |||
</li> | |||
<li> | |||
<a href="/posts">posts</a> | |||
</li> | |||
<li> | |||
<a href="/about">about</a> | |||
</li> | |||
<li> | |||
<a href="https://github.com/leothelocust">projects</a> | |||
</li> | |||
</ul> | |||
</nav> | |||
<main id='main' class='main'> | |||
<article lang='en' class='entry'> | |||
<div class='entry-content'> | |||
<p>Based on the | |||
<a href="http://mnmlist.com/uncopyright/" target="_blank">license from mnmlist</a>.</p> | |||
<p>This site is exists without copyrights. Its creator has released all claims on copyright and has | |||
<strong>put all the content into the public domain.</strong> | |||
</p> | |||
<p>No permission is needed to copy, distribute, or modify the content of this site. Credit is appreciated | |||
but not required.</p> | |||
<p> | |||
<strong>Terms and Conditions for Copying, Distribution and Modification</strong> | |||
</p> | |||
<ul> | |||
<li>Do whatever you like.</li> | |||
</ul> | |||
</div> | |||
</article> | |||
</main> | |||
<footer id='footer' class='footer-container'> | |||
<div class='footer'> | |||
<div class='copyright'> | |||
<p> | |||
<a href='/uncopyright'>uncopyright</a> | |||
</p> | |||
</div> | |||
</div> | |||
</footer> | |||
</div> | |||
</div> | |||
</body> | |||
</html> |
@ -0,0 +1,9 @@ | |||
<footer id="footer" class="footer-container"> | |||
<div class="footer"> | |||
<div class="copyright"> | |||
<p> | |||
<a href="/uncopyright">uncopyright</a> | |||
</p> | |||
</div> | |||
</div> | |||
</footer> |
@ -0,0 +1,7 @@ | |||
<meta charset="UTF-8"> | |||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |||
<meta http-equiv="X-UA-Compatible" content="ie=edge"> | |||
<title> | |||
<%= title %> | |||
</title> | |||
<link rel="stylesheet" href="/core.css"> |
@ -0,0 +1,16 @@ | |||
<nav> | |||
<ul> | |||
<li class="<% if (active == 'home') { %> logo <% } %>"> | |||
<a href="/">home</a> | |||
</li> | |||
<li class="<% if (active == 'posts') { %> logo <% } %>"> | |||
<a href="/posts">posts</a> | |||
</li> | |||
<li> | |||
<a href="/about">about</a> | |||
</li> | |||
<li> | |||
<a href="https://github.com/leothelocust">projects</a> | |||
</li> | |||
</ul> | |||
</nav> |