Переглянути джерело

update portfolio, add more projects, update resume

use updated smd tool to regenerate pages
cdelorme 7 роки тому
батько
коміт
1cf4869252

+ 9 - 14
public/index.html

@@ -7,34 +7,29 @@
         <meta name="description" content="">
         <title>index | Casey DeLorme's Portfolio / caseydelorme.com</title>
         <link rel="icon" type="image/x-icon" href="https://d2xxklvztqk0jd.cloudfront.net/favicon.ico" />
-        <link rel="stylesheet" type="text/css" href="/css/main.css#2df346a">
+        <link rel="stylesheet" type="text/css" href="/css/main.css#9682a1d">
     </head>
     <body>
         <header class="group">
             <h1><a href='/'>Casey DeLorme</a></h1>
-            
             <nav>
                 <ul>
-                
-                    <li><a href='/index.html'>index</a></li>
-                
-                    <li><a href='/projects/'>projects</a></li>
-                
-                    <li><a href='/resume.html'>resume</a></li>
-                
+                    <li><a href="/projects">Projects</a></li>
+                    <li><a href="/resume.html">Resume</a></li>
                 </ul>
             </nav>
-            
         </header>
 
         <div class="content group">
             <p>Welcome to my portfolio website.</p>
 
-<p>I&rsquo;m a <strong>Software developer, systems administrator, and technology enthusiast.</strong></p>
+<p>I am a <strong>Software developer, systems administrator, devops engineer, and technology enthusiast.</strong></p>
 
-<p>My life objectives are to challenge conventions by looking at new ways of employing all the wild new technologies that continue to evolve around us.  This is what leads us to major breakthroughts in software design and architecture, which allows our field to continue improving and building best practices.</p>
+<p>My life objectives are to challenge conventions by looking at new ways of employing all the wild new technologies that continue to evolve around us.  This is what leads us to major breakthroughs in software design and architecture, which allows our field to continue improving and building best practices.</p>
 
-<p>Interested in my skills?  Checkout my <a href="/resume.html">resume</a>, or my <a href="https://github.com/cdelorme">github account</a> for projects.  Looking to contact me?  Feel free to shoot me an <a href="mailto:cdelorme@gmail.com">email</a>.</p>
+<p>I am currently employed by <a href="https://www.ellucian.com/">ellucian</a>, a higher education software company, where I write infrastructure, automation, tools, and services in <a href="https://golang.org/">go</a> and <a href="https://nodejs.org/en/">node</a> that live in <a href="https://aws.amazon.com/">AWS (Amazon Web Services)</a> for my own team and others under the title of &ldquo;Devops Engineer Principal&rdquo;.</p>
+
+<p>Interested in my skills?  Checkout my <a href="/resume.html">resume</a>, or my <a href="https://github.com/cdelorme">github account</a> for <a href="/projects">projects</a>.  Looking to contact me?  Feel free to send me an <a href="mailto:cdelorme@gmail.com">email</a>.</p>
 
         </div>
 
@@ -45,7 +40,7 @@
             <a href='https://github.com/cdelorme' class='link github'></a>
             <a href='skype:casey.delorme?chat' class='link skype'></a>
             <div class="scripts">
-                <script type="text/javascript" src="/js/main.js#2df346a" async></script>
+                <script type="text/javascript" src="/js/main.js#9682a1d" async></script>
             </div>
         </footer>
 

+ 90 - 0
public/projects/accelerator.html

@@ -0,0 +1,90 @@
+<!doctype html>
+<html lang="en">
+    <head>
+        <meta charset="utf-8">
+        <meta http-equiv="X-UA-Compatible" content="IE=edge">
+        <meta name="viewport" content="width=device-width, initial-scale=1">
+        <meta name="description" content="">
+        <title>accelerator | Casey DeLorme's Portfolio / caseydelorme.com</title>
+        <link rel="icon" type="image/x-icon" href="https://d2xxklvztqk0jd.cloudfront.net/favicon.ico" />
+        <link rel="stylesheet" type="text/css" href="/css/main.css#9682a1d">
+    </head>
+    <body>
+        <header class="group">
+            <h1><a href='/'>Casey DeLorme</a></h1>
+            <nav>
+                <ul>
+                    <li><a href="/projects">Projects</a></li>
+                    <li><a href="/resume.html">Resume</a></li>
+                </ul>
+            </nav>
+        </header>
+
+        <div class="content group">
+            <h3><a href="https://github.com/cdelorme/level/tree/master/cmd/accelerator">accelerator</a></h3>
+
+<p>This was a fun and amusing project I chose to build for a variety of reasons.</p>
+
+<p>There are few free utilities that provide file deduplication, even on open sourced platforms.  <em>There are some complex features as part of modern file systems, but they generally don&rsquo;t resolve the underlying problem and are not portable.</em></p>
+
+<p>I myself have roughly 6 terrabytes of personal data files, a lot of which includes images, videos, and of course copious amounts of text files from project source code.  While this may differ from the average user to some degree, I have found that many suffer from the same problem of redundant copies, often due to the lack of a good backup strategy.  <em>This problem is compounding, and exists long after you have found a good backup strategy.</em></p>
+
+<p>The objective was to produce a relatively simple command line tool that could handle file deduplication on personal computers.  <em>Ideally, it would run fast, and with a high degree of reliability/accuracy.</em></p>
+
+<p><strong>The tools naming is loosely based on events during a storyline in an <a href="https://myanimelist.net/anime/6213/Toaru_Kagaku_no_Railgun">anime</a>.</strong></p>
+
+<h4>iterations</h4>
+
+<p>This project has undergone several iterations to reach its current state.</p>
+
+<p>The first iteration was based almost entirely around sha256 hash comparisons, under the assumption that:</p>
+
+<p><a href="http://crypto.stackexchange.com/questions/1170/best-way-to-reduce-chance-of-hash-collisions-multiple-hashes-or-larger-hash"><img src="http://i.stack.imgur.com/46Vwb.jpg" alt="sha256 is preferred" /></a></p>
+
+<p>After realizing that for duplicate data the files must be the same size, a second iteration grouped the files by size.</p>
+
+<p>A third iteration added the concurrency model using channels, <em>which was my first taste of concurrency in go and appeared to boost the speed significantly.</em>  By concurrently comparing each group on its own thread, I was able to parallelize the process, which mainly improved the hash generation.</p>
+
+<p>A friend suggested leading with crc32 since the computation was faster than sha256, which would allow for early identification of unmatched files.  This led to the fourth iteration where crc32 was introduced.</p>
+
+<p>After encountering a strange and poorly documented windows behavior, where resource exhaustion would terminate a process, I realized that loading entire files into memory was probably not a wise choice and a fifth iteration introduced buffered hashing.</p>
+
+<p>I began to question scenarios that could yield sha256 collisions, and decided that I would rather add byte-by-byte comparison as a final check.  This led to a sixth iteration.</p>
+
+<p>With the buffering now in place, I tried moving towards mutex-based concurrency due to the complex appearance of the channel based model, but during the process noticed that eliminating concurrency resulted in faster execution times.  Thus the seventh iteration was the removal of concurrency and converting the code to a pipeline system with placeholders for expected functionality.</p>
+
+<p>The eighth iteration came from the desire to clean the syntax to match other projects and the &ldquo;publicly accepted standard&rdquo;, add <a href="http://godoc.org/github.com/cdelorme/level">godocs</a>, and eliminate YAGNI artifacts.  I ended up renaming the repository and library, gave the command line a better name, dropped features that would have reduced the accuracy of the system or relied heavily on external tools, and consolidated the code into a single simple structure.</p>
+
+<p>The current, ninth iteration, involved minimizing the exposed behaviors from the library, fixing placement of various components, separating metrics into its own library as a dependency, and removing the hashing behavior after realizing the cost of hashing was not only significantly greater than byte-by-byte comparison but was also thrashing the disk.  <strong>This is 232 lines of library, 40 lines of command line, and 109 lines of tests with over 90% coverage, omitting tests that would require mocking a file system.</strong></p>
+
+<h4>lessons</h4>
+
+<p>Attempting to test every possible file system behavior by abstracting and overriding (or by mocking) is a fools errand, and you can simply rely on basic error handling for that remaining 10% coverage.</p>
+
+<p>Even with buffering, hashing still requires the entire file to be read, whereas byte-by-byte comparison can terminate as early as the first 4k read.  <strong>This is why you should always approach the problem with the simplest solution first.</strong></p>
+
+<p>I had originally planned to introduce alternative comparison behavior, such as content comparison to find partial-matching files, and multimedia comparison which would have relied on separate tools.  <strong>Instead I chose to do one thing well.</strong></p>
+
+<p>I spent some time considering reimplementation of parallelism and attempting to optimize the file comparison algorithm reducing the total number of times file comparison is run.  Theoretically neither of these implementations would have worked well; the file system is not able to operate in parallel, and you cannot take advantage of disk cache when you are bouncing the read head between 4k reads across a large number of files.  <strong>Understanding the foundations of the problem as well as what your code is actually doing on a system is essential to writing a good application.</strong></p>
+
+<h4>future</h4>
+
+<p>I considered a web interface to make it more usable, but introducing a method of canceling a scan, reporting or requesting the status, and pause behavior would require significant amounts of complexity and re-work and it isn&rsquo;t a priority.</p>
+
+<p><strong><em>updated on 2017-07-18</em></strong></p>
+
+        </div>
+
+        <footer class="group">
+            <a href='https://www.facebook.com/CaseyRDeLorme' class='link facebook'></a>
+            <a href='https://www.linkedin.com/in/cdelorme' class='link linkedin'></a>
+            <a href='https://www.youtube.com/user/LordOfElm' class='link youtube'></a>
+            <a href='https://github.com/cdelorme' class='link github'></a>
+            <a href='skype:casey.delorme?chat' class='link skype'></a>
+            <div class="scripts">
+                <script type="text/javascript" src="/js/main.js#9682a1d" async></script>
+            </div>
+        </footer>
+
+    </body>
+</html>

+ 48 - 0
public/projects/appinator.html

@@ -0,0 +1,48 @@
+<!doctype html>
+<html lang="en">
+    <head>
+        <meta charset="utf-8">
+        <meta http-equiv="X-UA-Compatible" content="IE=edge">
+        <meta name="viewport" content="width=device-width, initial-scale=1">
+        <meta name="description" content="">
+        <title>appinator | Casey DeLorme's Portfolio / caseydelorme.com</title>
+        <link rel="icon" type="image/x-icon" href="https://d2xxklvztqk0jd.cloudfront.net/favicon.ico" />
+        <link rel="stylesheet" type="text/css" href="/css/main.css#9682a1d">
+    </head>
+    <body>
+        <header class="group">
+            <h1><a href='/'>Casey DeLorme</a></h1>
+            <nav>
+                <ul>
+                    <li><a href="/projects">Projects</a></li>
+                    <li><a href="/resume.html">Resume</a></li>
+                </ul>
+            </nav>
+        </header>
+
+        <div class="content group">
+            <h3><a href="https://github.com/cdelorme/appinator">appinator</a></h3>
+
+<p>This is another whimsical utility I wrote to make testing applications on OSX easier.</p>
+
+<p>In particular, I was writing go applications that use <a href="https://github.com/go-gl/gl">opengl</a> and <a href="https://github.com/go-gl/glfw">glfw</a>, which when run directly launch a terminal.</p>
+
+<p><em>By creating an OSX bundle I am able to hide the terminal, which works wonderfully.</em></p>
+
+<p><strong><em>written on 2017-04-13</em></strong></p>
+
+        </div>
+
+        <footer class="group">
+            <a href='https://www.facebook.com/CaseyRDeLorme' class='link facebook'></a>
+            <a href='https://www.linkedin.com/in/cdelorme' class='link linkedin'></a>
+            <a href='https://www.youtube.com/user/LordOfElm' class='link youtube'></a>
+            <a href='https://github.com/cdelorme' class='link github'></a>
+            <a href='skype:casey.delorme?chat' class='link skype'></a>
+            <div class="scripts">
+                <script type="text/javascript" src="/js/main.js#9682a1d" async></script>
+            </div>
+        </footer>
+
+    </body>
+</html>

+ 19 - 27
public/projects/caseydelorme.com.html

@@ -7,62 +7,54 @@
         <meta name="description" content="">
         <title>caseydelorme.com | Casey DeLorme's Portfolio / caseydelorme.com</title>
         <link rel="icon" type="image/x-icon" href="https://d2xxklvztqk0jd.cloudfront.net/favicon.ico" />
-        <link rel="stylesheet" type="text/css" href="/css/main.css#2df346a">
+        <link rel="stylesheet" type="text/css" href="/css/main.css#9682a1d">
     </head>
     <body>
         <header class="group">
             <h1><a href='/'>Casey DeLorme</a></h1>
-            
             <nav>
                 <ul>
-                
-                    <li><a href='/index.html'>index</a></li>
-                
-                    <li><a href='/projects/'>projects</a></li>
-                
-                    <li><a href='/resume.html'>resume</a></li>
-                
+                    <li><a href="/projects">Projects</a></li>
+                    <li><a href="/resume.html">Resume</a></li>
                 </ul>
             </nav>
-            
         </header>
 
         <div class="content group">
-            <h1><a href="https://github.com/cdelorme/caseydelorme.com">caseydelorme.com</a></h1>
+            <h3><a href="https://github.com/cdelorme/caseydelorme.com">caseydelorme.com</a></h3>
 
-<p>This site began with the concept of a simplified static site generator.  As a result I built <a href="staticmd.html">staticmd</a> first.</p>
+<p>This site began with the concept of a simplified static site generator, which resulted in writing <a href="accelerator.html">accelerator</a> first.</p>
 
-<p>The goal of this site was to replace a traditional dynamic system with raw static content.  I would then replace (and redirect) my <a href="http://www.cdelorme.com">old site</a> with this one.</p>
+<p>The goal of this site was to replace a traditional dynamic system with raw static content and redirect the domain after.</p>
 
-<h2>design considerations</h2>
+<h4>design considerations</h4>
 
 <p>One major consideration was taking advantage of content delivery using AWS S3 and CloudFront services for any static or binary contents.  This provides a significantly greater degree of scalability, in that I can create as many servers as necessary to deliver the websites static content, while binary/static files all come from one place.</p>
 
-<p>Right now that includes images, fonts, and some static third-party css and javascript.  Because my own css and javascript are still under construction it made sense to include them using git-hash-versioning.  This ensures the browser won&rsquo;t cache incorrectly.  <em>In the future I could use that versioning to minify, name, and upload my content to S3 and use the CDN exclusively for all versions.</em></p>
+<p>Right now that includes images, fonts, and some static third-party css and javascript.  Because my own css and javascript are still under construction it made sense to include them using git-hash-versioning to ensure the browser won&rsquo;t cache incorrectly.  <em>In the future I could continue to version but also minify and upload the changed files to S3 so I could benefit from using it for all &ldquo;static&rdquo; files.</em></p>
 
 <p>Another advantage to moving away from a dynamic website is that when dealing with basic static html we can enable simple caching directly through nginx without concern for other layers; there is no CMS to contend with or concern for &ldquo;immediately up-to-date&rdquo; contents.</p>
 
-<p>I decided to implement <code>https</code> because I intend to use the domain for experiments from time to time, and also <a href="https://www.startssl.com/">because it&rsquo;s free</a>.</p>
+<p>I decided to implement <code>https</code> because I intend to use the domain for experiments from time to time, <em>and also <a href="https://letsencrypt.org/">because it&rsquo;s free</a>.</em></p>
 
-<p>Finally, I am using git, as well as github, as a means of version control for my website now.  This allows me to enable a simple cronjob to pull changes hourly, and know that I can update my site from any computer by simply pushing new static html to the github repository.  This also means I have a backup, and a means of distribution/deployment in a way that is scalable.</p>
+<p>Finally, I am using git, as well as github, as a means of version control for my website now.  This allows me to enable a simple cronjob to pull changes hourly, and know that I can update my site from any computer by simply pushing new static html to the github repository.  This also means I have a backup, and a very simple distribution and deployment method.</p>
 
-<h2>future plans</h2>
+<h4>future plans</h4>
 
-<p>I have a list of enhancements I&rsquo;d like to add in the future, which may involve changes to my <code>staticmd</code> project as well:</p>
+<p>I have two considerations for the next steps:</p>
 
 <ul>
-<li>move css and javascript to cdn</li>
-<li>implement date tracking</li>
-<li>improved indexing, navigation, and primary index file identification</li>
+<li>possibly switch to <a href="https://gohugo.io/">hugo</a></li>
+<li>generate the site on the server after pulling changes and remove html from the repository</li>
 </ul>
 
-<p>For any binary file or large file it would make sense to keep it out of the repository and to use a content delivery network.  However, for the builtin css and javascript, being so small, there isn&rsquo;t a problem having as many copies as there are machines with the content.  Further, if I needed to scale the deployment mechanism uses the repository and should always have the latest copy of content.  That said, using some sort of task automator, like <a href="http://gruntjs.com/">grunt</a>, would allow me to minify, name, and upload my javascript and css to the same AWS CloudFront I use for other files.  If anything it would be good practice for any future sites I choose to work on.</p>
+<p>The custom tool I built was more of a proof-of-concept, and while neat it isn&rsquo;t the best option out there.  Another tool built in go with much greater stability is available, and might be worth trying.</p>
 
-<p>I would like to be able to identify when a file was created and last updated, and provide these either below the first header, or at the bottom of the content.  For now, the date created and updated is technically accessible in the repository, but readers won&rsquo;t want to be bothered to look that far, so I can manually add dates for the time being.  The concerns here include whether the file system will correctly track the date created and modified of a file, especially if the files consist of a fresh clone.</p>
+<p>Right now I commit the parsed html directly to the repository, and while this means deployment is a simple <code>git pull</code>, it also means that the compiled version of every file is taking space up in the repository redundantly.</p>
 
-<p>I took shortcuts with the current implementation of staticmd&rsquo;s index builder and identification.  Ideally I wanted to go the github route and work with <code>readme.md</code> as the <strong>primary</strong> index file.  However, to conditionally pick between two possible index files adds a bunch more complication, so I ended up sticking with one.  In the future I would like to correct this, and improve how I generate the indexes and main navigation as well.  Things like sort-by-date-order, folders-first, and intelligently ignoring index pages (again complications if two files could both potentially be an index page).</p>
+<p><em>Finally, I might move the css and javascript to the same S3 CDN that I use for images.</em></p>
 
-<h5><em>written on 2014-12-22</em></h5>
+<p><strong><em>updated on 2017-07-18</em></strong></p>
 
         </div>
 
@@ -73,7 +65,7 @@
             <a href='https://github.com/cdelorme' class='link github'></a>
             <a href='skype:casey.delorme?chat' class='link skype'></a>
             <div class="scripts">
-                <script type="text/javascript" src="/js/main.js#2df346a" async></script>
+                <script type="text/javascript" src="/js/main.js#9682a1d" async></script>
             </div>
         </footer>
 

+ 48 - 0
public/projects/dot-files.html

@@ -0,0 +1,48 @@
+<!doctype html>
+<html lang="en">
+    <head>
+        <meta charset="utf-8">
+        <meta http-equiv="X-UA-Compatible" content="IE=edge">
+        <meta name="viewport" content="width=device-width, initial-scale=1">
+        <meta name="description" content="">
+        <title>dot-files | Casey DeLorme's Portfolio / caseydelorme.com</title>
+        <link rel="icon" type="image/x-icon" href="https://d2xxklvztqk0jd.cloudfront.net/favicon.ico" />
+        <link rel="stylesheet" type="text/css" href="/css/main.css#9682a1d">
+    </head>
+    <body>
+        <header class="group">
+            <h1><a href='/'>Casey DeLorme</a></h1>
+            <nav>
+                <ul>
+                    <li><a href="/projects">Projects</a></li>
+                    <li><a href="/resume.html">Resume</a></li>
+                </ul>
+            </nav>
+        </header>
+
+        <div class="content group">
+            <h3><a href="https://github.com/cdelorme/dot-files">dot-files</a></h3>
+
+<p>As I find myself inside the terminal more often than not, I realized that the default shell is kind of crummy.</p>
+
+<p>I tried using the common enhancements others suggested, but found them to be too heavy-handed, so I wrote my own and borrowed only the bare-minimum from others.</p>
+
+<p>The result is an incredibly enhanced bash shell with almost no footprint.</p>
+
+<p><strong><em>written on 2017-04-13</em></strong></p>
+
+        </div>
+
+        <footer class="group">
+            <a href='https://www.facebook.com/CaseyRDeLorme' class='link facebook'></a>
+            <a href='https://www.linkedin.com/in/cdelorme' class='link linkedin'></a>
+            <a href='https://www.youtube.com/user/LordOfElm' class='link youtube'></a>
+            <a href='https://github.com/cdelorme' class='link github'></a>
+            <a href='skype:casey.delorme?chat' class='link skype'></a>
+            <div class="scripts">
+                <script type="text/javascript" src="/js/main.js#9682a1d" async></script>
+            </div>
+        </footer>
+
+    </body>
+</html>

+ 64 - 0
public/projects/glog.html

@@ -0,0 +1,64 @@
+<!doctype html>
+<html lang="en">
+    <head>
+        <meta charset="utf-8">
+        <meta http-equiv="X-UA-Compatible" content="IE=edge">
+        <meta name="viewport" content="width=device-width, initial-scale=1">
+        <meta name="description" content="">
+        <title>glog | Casey DeLorme's Portfolio / caseydelorme.com</title>
+        <link rel="icon" type="image/x-icon" href="https://d2xxklvztqk0jd.cloudfront.net/favicon.ico" />
+        <link rel="stylesheet" type="text/css" href="/css/main.css#9682a1d">
+    </head>
+    <body>
+        <header class="group">
+            <h1><a href='/'>Casey DeLorme</a></h1>
+            <nav>
+                <ul>
+                    <li><a href="/projects">Projects</a></li>
+                    <li><a href="/resume.html">Resume</a></li>
+                </ul>
+            </nav>
+        </header>
+
+        <div class="content group">
+            <h3><a href="https://github.com/cdelorme/glog">glog</a></h3>
+
+<p>I wrote this some time ago when I realized that the default <a href="https://golang.org/pkg/log/">log</a> package forced the software to exit when you called the Error functions.  <em>It also does not include any context; the package, file, or line number which are immensely helpful when troubleshooting.</em></p>
+
+<p>While there are other packages that provide the functionality I would want, some mirror the default package&rsquo;s behavior, and most are relatively large or have additional dependencies.</p>
+
+<p>So I decided to write my own, which was so simple I was amazed how big some of the other packages are.</p>
+
+<p>Instead of the myriad of conflicting behaviors that a developer could embed into their application for configuration (eg. <code>-s</code> or <code>--silent</code>, <code>-q</code> or <code>--quiet</code>, literally every full or partial log level name, or a log level with severity as a value, I&rsquo;ve seen it all).  <strong>Developers can ignore all that now, just let the user set <code>LOG_LEVEL</code> environment variable.</strong></p>
+
+<p>It provides standardized severities which defaults to &ldquo;Error&rdquo;.  <em>I generally only use around 3~4 of them, but all of them are included.</em></p>
+
+<p>It can determine color support in the terminal and will log in color (disabled if output is redirected).</p>
+
+<p>It offers context, so you can easily debug code by tracking down the file and line number the error occurred.</p>
+
+<p>All output goes to stderr, <em>which is the optimal sane default to avoid messing with expected application output.</em></p>
+
+<p>It is concurrently safe, using a package level mutex.</p>
+
+<p>It comes with comprehensive tests, and benchmarks.</p>
+
+<p><strong>I highly recommend <a href="https://github.com/cdelorme/glog">trying it out</a>.</strong></p>
+
+<p><strong><em>written on 2017-04-13</em></strong></p>
+
+        </div>
+
+        <footer class="group">
+            <a href='https://www.facebook.com/CaseyRDeLorme' class='link facebook'></a>
+            <a href='https://www.linkedin.com/in/cdelorme' class='link linkedin'></a>
+            <a href='https://www.youtube.com/user/LordOfElm' class='link youtube'></a>
+            <a href='https://github.com/cdelorme' class='link github'></a>
+            <a href='skype:casey.delorme?chat' class='link skype'></a>
+            <div class="scripts">
+                <script type="text/javascript" src="/js/main.js#9682a1d" async></script>
+            </div>
+        </footer>
+
+    </body>
+</html>

+ 61 - 0
public/projects/gonf.html

@@ -0,0 +1,61 @@
+<!doctype html>
+<html lang="en">
+    <head>
+        <meta charset="utf-8">
+        <meta http-equiv="X-UA-Compatible" content="IE=edge">
+        <meta name="viewport" content="width=device-width, initial-scale=1">
+        <meta name="description" content="">
+        <title>gonf | Casey DeLorme's Portfolio / caseydelorme.com</title>
+        <link rel="icon" type="image/x-icon" href="https://d2xxklvztqk0jd.cloudfront.net/favicon.ico" />
+        <link rel="stylesheet" type="text/css" href="/css/main.css#9682a1d">
+    </head>
+    <body>
+        <header class="group">
+            <h1><a href='/'>Casey DeLorme</a></h1>
+            <nav>
+                <ul>
+                    <li><a href="/projects">Projects</a></li>
+                    <li><a href="/resume.html">Resume</a></li>
+                </ul>
+            </nav>
+        </header>
+
+        <div class="content group">
+            <h3><a href="https://github.com/cdelorme/gonf">gonf</a></h3>
+
+<p>I actually started with three separate configuration packages, and a package to make working with <code>map[string]interface{}</code> easier:</p>
+
+<ul>
+<li><a href="https://github.com/cdelorme/go-option">go-option</a></li>
+<li><a href="https://github.com/cdelorme/go-config">go-config</a></li>
+<li><a href="https://github.com/cdelorme/go-env">go-env</a></li>
+<li><a href="https://github.com/cdelorme/go-maps">go-maps</a></li>
+</ul>
+
+<p>After over a year of using each, I realized that I always followed exactly the same patterns, and never leveraged maps due to the additional complexity.</p>
+
+<p>So I decided to write a consolidated configuration package.</p>
+
+<p>It currently provides POSIX compliant command line option support using an implementation with an explicit greedy character, environment variables, casting from string inputs to the supplied structure, loading and saving to and from a json file, and is completely concurrently safe.</p>
+
+<p>I made a lot of decisions that not everyone will agree with, <em>but for me this package solves every configuration problem I could want without importing a single third party dependency.</em></p>
+
+<p>However, even with the tests provided, because this is still fairly new I can&rsquo;t guarantee the stability just yet.  Once I have used it in more projects I will be able to say for sure.</p>
+
+<p><strong><em>written on 2017-04-13</em></strong></p>
+
+        </div>
+
+        <footer class="group">
+            <a href='https://www.facebook.com/CaseyRDeLorme' class='link facebook'></a>
+            <a href='https://www.linkedin.com/in/cdelorme' class='link linkedin'></a>
+            <a href='https://www.youtube.com/user/LordOfElm' class='link youtube'></a>
+            <a href='https://github.com/cdelorme' class='link github'></a>
+            <a href='skype:casey.delorme?chat' class='link skype'></a>
+            <div class="scripts">
+                <script type="text/javascript" src="/js/main.js#9682a1d" async></script>
+            </div>
+        </footer>
+
+    </body>
+</html>

+ 72 - 19
public/projects/index.html

@@ -7,40 +7,93 @@
         <meta name="description" content="">
         <title>index | Casey DeLorme's Portfolio / caseydelorme.com</title>
         <link rel="icon" type="image/x-icon" href="https://d2xxklvztqk0jd.cloudfront.net/favicon.ico" />
-        <link rel="stylesheet" type="text/css" href="/css/main.css#2df346a">
+        <link rel="stylesheet" type="text/css" href="/css/main.css#9682a1d">
     </head>
     <body>
         <header class="group">
             <h1><a href='/'>Casey DeLorme</a></h1>
-            
             <nav>
                 <ul>
-                
-                    <li><a href='/index.html'>index</a></li>
-                
-                    <li><a href='/projects/'>projects</a></li>
-                
-                    <li><a href='/resume.html'>resume</a></li>
-                
+                    <li><a href="/projects">Projects</a></li>
+                    <li><a href="/resume.html">Resume</a></li>
                 </ul>
             </nav>
-            
         </header>
 
         <div class="content group">
-            <h2>Table of Contents:</h2>
+            <h1>projects</h1>
+
+<p>This section is for detailed information on projects I wrote or participated in.</p>
+
+<p>Select a project from the list:</p>
 
 <ul>
-<li><a href="/projects/caseydelorme.com.html">caseydelorme.com</a></li>
-<li><a href="/projects/level6.html">level6</a></li>
-<li><a href="/projects/staticmd.html">staticmd</a></li>
-</ul>
+<li><a href="appinator.html">appinator</a>
 
-<h1>projects</h1>
+<ul>
+<li>a go utility to turn any binary into an osx bundle.</li>
+</ul></li>
+<li><a href="modernizer.html">modernizer</a>
 
-<p>This section is for detailed information on projects I wrote or participated in.</p>
+<ul>
+<li>A go package that automatically update applications.</li>
+</ul></li>
+<li><a href="rathena-docker.html">rathena docker</a>
+
+<ul>
+<li>run the open-sourced ragnarok online server inside docker.</li>
+</ul></li>
+<li><a href="serial.html">serial</a>
+
+<ul>
+<li>A test case for the smallest possible binary format.</li>
+</ul></li>
+<li><a href="gonf.html">gonf</a>
+
+<ul>
+<li>a consolidated configuration package for go.</li>
+</ul></li>
+<li><a href="glog.html">glog</a>
+
+<ul>
+<li>a standard-compliant logger for go that does not forcefully exit the application and writes to stderr.</li>
+</ul></li>
+<li><a href="serve.html">serve</a>
 
-<p>Select a project from the list!</p>
+<ul>
+<li>instantly launch a file-based web server in the current directory.</li>
+</ul></li>
+<li><a href="system-setup.html">system-setup</a>
+
+<ul>
+<li>several years worth of documentation on operating system installation, configuration, and automation.</li>
+</ul></li>
+<li><a href="dot-files.html">dot-files</a>
+
+<ul>
+<li>a minimal stack of files to make your bash terminal amazing.</li>
+</ul></li>
+<li><a href="accelerator.html">accelerator</a>
+
+<ul>
+<li>deduplication of files by byte-comparison.</li>
+</ul></li>
+<li><a href="smd.html">smd</a>
+
+<ul>
+<li>a tiny static markdown generator.</li>
+</ul></li>
+<li><a href="caseydelorme.com.html">caseydelorme.com</a>
+
+<ul>
+<li>my portfolio website, as a repository.</li>
+</ul></li>
+<li><a href="jslideshow.html">jslideshow</a>
+
+<ul>
+<li>an image slideshow with preloading and realtime rendering, written in vanilla javascript.</li>
+</ul></li>
+</ul>
 
         </div>
 
@@ -51,7 +104,7 @@
             <a href='https://github.com/cdelorme' class='link github'></a>
             <a href='skype:casey.delorme?chat' class='link skype'></a>
             <div class="scripts">
-                <script type="text/javascript" src="/js/main.js#2df346a" async></script>
+                <script type="text/javascript" src="/js/main.js#9682a1d" async></script>
             </div>
         </footer>
 

+ 48 - 0
public/projects/jslideshow.html

@@ -0,0 +1,48 @@
+<!doctype html>
+<html lang="en">
+    <head>
+        <meta charset="utf-8">
+        <meta http-equiv="X-UA-Compatible" content="IE=edge">
+        <meta name="viewport" content="width=device-width, initial-scale=1">
+        <meta name="description" content="">
+        <title>jslideshow | Casey DeLorme's Portfolio / caseydelorme.com</title>
+        <link rel="icon" type="image/x-icon" href="https://d2xxklvztqk0jd.cloudfront.net/favicon.ico" />
+        <link rel="stylesheet" type="text/css" href="/css/main.css#9682a1d">
+    </head>
+    <body>
+        <header class="group">
+            <h1><a href='/'>Casey DeLorme</a></h1>
+            <nav>
+                <ul>
+                    <li><a href="/projects">Projects</a></li>
+                    <li><a href="/resume.html">Resume</a></li>
+                </ul>
+            </nav>
+        </header>
+
+        <div class="content group">
+            <h3><a href="https://github.com/cdelorme/jslideshow">jslideshow</a></h3>
+
+<p>I&rsquo;ve always been fascinated with image transitions and slideshows using the web browser.  Some time ago I wrote a <a href="https://github.com/cdelorme/jquery_slideshow_plugin">slideshow using jquery</a>.</p>
+
+<p>After reading an <a href="http://jlongster.com/Removing-User-Interface-Complexity,-or-Why-React-is-Awesome">excellent article</a> on real-time rendering, I decided to try rewriting this in vanilla (eg. raw, with zero dependencies) javascript to leverage this approach.</p>
+
+<p>It turned out to be pretty clean, and the demo includes logic to load the javascript directly from github.</p>
+
+<p><strong><em>written on 2017-04-13</em></strong></p>
+
+        </div>
+
+        <footer class="group">
+            <a href='https://www.facebook.com/CaseyRDeLorme' class='link facebook'></a>
+            <a href='https://www.linkedin.com/in/cdelorme' class='link linkedin'></a>
+            <a href='https://www.youtube.com/user/LordOfElm' class='link youtube'></a>
+            <a href='https://github.com/cdelorme' class='link github'></a>
+            <a href='skype:casey.delorme?chat' class='link skype'></a>
+            <div class="scripts">
+                <script type="text/javascript" src="/js/main.js#9682a1d" async></script>
+            </div>
+        </footer>
+
+    </body>
+</html>

+ 0 - 86
public/projects/level6.html

@@ -1,86 +0,0 @@
-<!doctype html>
-<html lang="en">
-    <head>
-        <meta charset="utf-8">
-        <meta http-equiv="X-UA-Compatible" content="IE=edge">
-        <meta name="viewport" content="width=device-width, initial-scale=1">
-        <meta name="description" content="">
-        <title>level6 | Casey DeLorme's Portfolio / caseydelorme.com</title>
-        <link rel="icon" type="image/x-icon" href="https://d2xxklvztqk0jd.cloudfront.net/favicon.ico" />
-        <link rel="stylesheet" type="text/css" href="/css/main.css#2df346a">
-    </head>
-    <body>
-        <header class="group">
-            <h1><a href='/'>Casey DeLorme</a></h1>
-            
-            <nav>
-                <ul>
-                
-                    <li><a href='/index.html'>index</a></li>
-                
-                    <li><a href='/projects/'>projects</a></li>
-                
-                    <li><a href='/resume.html'>resume</a></li>
-                
-                </ul>
-            </nav>
-            
-        </header>
-
-        <div class="content group">
-            <h1><a href="https://github.com/cdelorme/level6">level6</a></h1>
-
-<p>This was a fun and amusing project I chose to build for a variety of reasons.  I myself have roughly 6 terrabytes of personal data files, a lot of which includes images, videos, and of course copious amounts of text files from project source code.</p>
-
-<p>While my scale is perhaps a bit larger, my problem is no different than that which my family and friends face regularly.  There are no free or simple tools out there that will handle file deduplication flexibly and efficiently.</p>
-
-<p>My goal with this project was to create a free and open source software that could handle file deduplication on personal computers.  Ideally at break-neck speed, but with a high degree of accuracy.</p>
-
-<p>The name of the project came about from the concept of destroying cloned files.  As an avid anime fan I decided to name it after a particular project in a series I enjoyed, although the connotation of the project in that series is certainly darker than the purpose of this project.</p>
-
-<h2>design considerations</h2>
-
-<p>Originally I wanted to simply go with sha256 hash comparison.  My first implementation simply created a list of hashes for every file in a single threaded loop and printed out sets of results by hash.</p>
-
-<p>Then, as I read more about comparison, I realized that file size is relevant.  I took the single core file walk and grouped files by their size, then created sha256 hashes.  I proceeded to add options to delete or move the files, and json support for output such that it could be consumed and used by other applications in an easier way.</p>
-
-<p>My next stage was adding concurrency, which was my first attempt at golangs concurrency model.  It was actually quite refreshing once I understood how it worked, and I managed to improve the performance of the software quite a bit.</p>
-
-<p>I showed it to a few friends who gave me some suggestions, including adding summary data such as how many files were scanned, how many hashes were generated, and how long the operation took.  Another suggestion was to use a lighter hashing algorithm as a stop-gap before generating sha256 hashes.  This turned out to be another boon to performance, since sha256 is an expensive algorithm compared to something like crc32, so I added crc32 as a first-measure before running sha256 hashing.  I implemented full counts of how many hashes were generated, plus how many duplicates were found.</p>
-
-<p>The end result is roughly 600 lines of code, which can provide a very fast way to identify and manage duplicate files.  There is still a lot of room for improvement, but I&rsquo;m pretty happy with how quickly I was able to put it together.</p>
-
-<h2>future plans</h2>
-
-<ul>
-<li>dodgy windows compatibility</li>
-<li>byte-comparison for large files and 100%-accuracy going a step beyond sha256</li>
-<li>core library, cli &amp; gui repositories</li>
-<li>detailed multimedia comparison</li>
-</ul>
-
-<p>Tests on Windows Vista 32 bit have crashed, but Windows 8.1 64 bit work.  However, on Windows it seems that resource-exhaustion occurs during which the OS forces the program to close.  This problem stems from its less-than-frugal use of ram to store contents when generating sha256 hashes.  One solution is to set a max-size, and simply omit them from comparison.  This seems to have worked well in my test cases, but it&rsquo;s obviously not perfect.</p>
-
-<p>I would like to implement byte-by-byte comparison for a more detailed approach to comparing two files.  While the odds of sha256 conflict are absurd, this would give us a 100% trust option for identifying duplicates.  Similarly it would allow us to assume a safe arbitrary max file size, reducing necessary cli arguments, and still being capable of parsing very large files.</p>
-
-<p>I already worked to separate the code into its own library folder, but in the future I want to separate that as its own repository, then import and use it with both a cli and gui implementation.  This would allow something like <code>level6-sdl</code> to provide a graphical interface, stacked ontop of the same source as the cli implementation.</p>
-
-<p>I would like to use more detailed comparison methods against images, videos, and audio.  Algorithms that identify key-points in similar files, and can draw conclusions such as altered contrast, brightness, cropping, rotation, etc and still manage to match similar items.  These small changes may barely be visible in the files themselves but would cause hash or byte comparison to fail.</p>
-
-<h5><em>written on 2014-12-22</em></h5>
-
-        </div>
-
-        <footer class="group">
-            <a href='https://www.facebook.com/CaseyRDeLorme' class='link facebook'></a>
-            <a href='https://www.linkedin.com/in/cdelorme' class='link linkedin'></a>
-            <a href='https://www.youtube.com/user/LordOfElm' class='link youtube'></a>
-            <a href='https://github.com/cdelorme' class='link github'></a>
-            <a href='skype:casey.delorme?chat' class='link skype'></a>
-            <div class="scripts">
-                <script type="text/javascript" src="/js/main.js#2df346a" async></script>
-            </div>
-        </footer>
-
-    </body>
-</html>

+ 52 - 0
public/projects/modernizer.html

@@ -0,0 +1,52 @@
+<!doctype html>
+<html lang="en">
+    <head>
+        <meta charset="utf-8">
+        <meta http-equiv="X-UA-Compatible" content="IE=edge">
+        <meta name="viewport" content="width=device-width, initial-scale=1">
+        <meta name="description" content="">
+        <title>modernizer | Casey DeLorme's Portfolio / caseydelorme.com</title>
+        <link rel="icon" type="image/x-icon" href="https://d2xxklvztqk0jd.cloudfront.net/favicon.ico" />
+        <link rel="stylesheet" type="text/css" href="/css/main.css#9682a1d">
+    </head>
+    <body>
+        <header class="group">
+            <h1><a href='/'>Casey DeLorme</a></h1>
+            <nav>
+                <ul>
+                    <li><a href="/projects">Projects</a></li>
+                    <li><a href="/resume.html">Resume</a></li>
+                </ul>
+            </nav>
+        </header>
+
+        <div class="content group">
+            <h3><a href="https://github.com/cdelorme/modernizer">modernizer</a></h3>
+
+<p>I only found one alternative, and they put a ton of effort into supporting binary delta updates, which I think are a waste of time and code.</p>
+
+<p>As usual, I decided to write my own.  In roughly a weekend I was able to create a tool that downloads a version file, compares versions, downloads and replaces the binary in a cross-platform compatible way, and launches the new executable while retaining the default file descriptors.</p>
+
+<p>Windows has two minor glitches that required a bit of extra cleanup work.  First it does not offer <code>Exec</code>, so the process id changes, but it somehow inherits the same streams (stdin/stdout/stderr all continue to work correctly).  Second in order to eliminate the previous binary a rename and cleanup process is required since windows locks the binary file during execution (<em>I assume due to mmap calls?</em>).</p>
+
+<p>While it isn&rsquo;t a perfect solution for all use-cases, it works great and is damn small (less than 200 lines of code).</p>
+
+<p>For complex situations where you need to cleanup the existing runtime, or want to carry over an open network connection (eg. keep a service active) then you probably want something more complex and tailor-made.</p>
+
+<p><strong><em>written on 2017-04-13</em></strong></p>
+
+        </div>
+
+        <footer class="group">
+            <a href='https://www.facebook.com/CaseyRDeLorme' class='link facebook'></a>
+            <a href='https://www.linkedin.com/in/cdelorme' class='link linkedin'></a>
+            <a href='https://www.youtube.com/user/LordOfElm' class='link youtube'></a>
+            <a href='https://github.com/cdelorme' class='link github'></a>
+            <a href='skype:casey.delorme?chat' class='link skype'></a>
+            <div class="scripts">
+                <script type="text/javascript" src="/js/main.js#9682a1d" async></script>
+            </div>
+        </footer>
+
+    </body>
+</html>

+ 54 - 0
public/projects/rathena-docker.html

@@ -0,0 +1,54 @@
+<!doctype html>
+<html lang="en">
+    <head>
+        <meta charset="utf-8">
+        <meta http-equiv="X-UA-Compatible" content="IE=edge">
+        <meta name="viewport" content="width=device-width, initial-scale=1">
+        <meta name="description" content="">
+        <title>rathena-docker | Casey DeLorme's Portfolio / caseydelorme.com</title>
+        <link rel="icon" type="image/x-icon" href="https://d2xxklvztqk0jd.cloudfront.net/favicon.ico" />
+        <link rel="stylesheet" type="text/css" href="/css/main.css#9682a1d">
+    </head>
+    <body>
+        <header class="group">
+            <h1><a href='/'>Casey DeLorme</a></h1>
+            <nav>
+                <ul>
+                    <li><a href="/projects">Projects</a></li>
+                    <li><a href="/resume.html">Resume</a></li>
+                </ul>
+            </nav>
+        </header>
+
+        <div class="content group">
+            <h3><a href="https://github.com/cdelorme/rathena-docker">rathena-docker</a></h3>
+
+<p>I am an avid gamer, and one of the games I enjoyed was ragnarok online.</p>
+
+<p>The <a href="https://rathena.org/">rathena project</a> is an effort to provide an open-source implementation of the ragnarok online service, based on reverse engineering efforts with Aegis, the official server.</p>
+
+<p>I enjoy that it runs on linux, <em>but sadly there is no open-source renewal client solution yet so we can&rsquo;t enjoy ragnarok on linux without <a href="https://www.winehq.org/">WINE</a>.</em></p>
+
+<p>While experimenting with <a href="https://www.docker.com/">docker</a> for work, I decided to try writing a Dockerfile that would generate a docker image that could run an entire rathena server.</p>
+
+<p>Originally I had planned to use docker to create a distributed networked example, <em>but because docker immutable state complicates runtime configuration I gave up.</em></p>
+
+<p><strong>In the future I may pursue <a href="https://docs.docker.com/compose/">docker-compose</a> to orchestrate a distributed configuration to demonstrate multiple components of the rathena server in action.</strong></p>
+
+<p><strong><em>written on 2017-04-13</em></strong></p>
+
+        </div>
+
+        <footer class="group">
+            <a href='https://www.facebook.com/CaseyRDeLorme' class='link facebook'></a>
+            <a href='https://www.linkedin.com/in/cdelorme' class='link linkedin'></a>
+            <a href='https://www.youtube.com/user/LordOfElm' class='link youtube'></a>
+            <a href='https://github.com/cdelorme' class='link github'></a>
+            <a href='skype:casey.delorme?chat' class='link skype'></a>
+            <div class="scripts">
+                <script type="text/javascript" src="/js/main.js#9682a1d" async></script>
+            </div>
+        </footer>
+
+    </body>
+</html>

+ 58 - 0
public/projects/serial.html

@@ -0,0 +1,58 @@
+<!doctype html>
+<html lang="en">
+    <head>
+        <meta charset="utf-8">
+        <meta http-equiv="X-UA-Compatible" content="IE=edge">
+        <meta name="viewport" content="width=device-width, initial-scale=1">
+        <meta name="description" content="">
+        <title>serial | Casey DeLorme's Portfolio / caseydelorme.com</title>
+        <link rel="icon" type="image/x-icon" href="https://d2xxklvztqk0jd.cloudfront.net/favicon.ico" />
+        <link rel="stylesheet" type="text/css" href="/css/main.css#9682a1d">
+    </head>
+    <body>
+        <header class="group">
+            <h1><a href='/'>Casey DeLorme</a></h1>
+            <nav>
+                <ul>
+                    <li><a href="/projects">Projects</a></li>
+                    <li><a href="/resume.html">Resume</a></li>
+                </ul>
+            </nav>
+        </header>
+
+        <div class="content group">
+            <h3><a href="https://github.com/cdelorme/serial">serial</a></h3>
+
+<p>I began reading some interesting articles by <a href="http://gafferongames.com/">Glenn Fiedler</a>, who had a particular series about writing a custom UDP protocol.</p>
+
+<p>At one point he expressed the concern for sending data over the network, stating that json is massive, and a binary serialization pattern that exposes a bidirectional workflow for both reading and writing works best.</p>
+
+<p>I decided to give a try writing it in go, and at first I followed strict syntax rules, but since the binary documentation is very good I eventually went back to a much simpler project implementation with no attempt to handle variable sized types.</p>
+
+<p>I also created a set of benchmarks to compare both the performance, memory management, and byte size between this system, <a href="https://github.com/tinylib/msgp">msgp</a>, and the <a href="https://golang.org/pkg/encoding/gob/">gob package</a>.  _This is a proof-of-concept, so I am not attempting to <a href="https://github.com/alecthomas/go_serialization_benchmarks">compete</a>._</p>
+
+<p>While mine is not the fastest, it is by far the smallest, which proves that a very simple thin wrapper to abstract read and write behavior, and extra effort to write your own byte conversion logic, can be extremely beneficial in situations where every byte counts.</p>
+
+<p><em>I also concluded that while the gain is significant, for a first-draft msgp is substantially easier to wield and might be worth the trade-off if you are dealing with a large number of structures and don&rsquo;t have time to write binary serialization for each.</em></p>
+
+<p>One major complexity with the go implementation that I couldn&rsquo;t quite deal with was variable-sized data.  Anytime an nondeterministic slice or string are written, extra effort must be made to keep tabs on the size when restoring it.  <em>While I had written a solution to do this, it was crappy and limited to strings only.</em></p>
+
+<p>This project also helped me realize the significance between big and little endian encoding, as well as 32 vs 64 bit consistency.  The fact that go abstracts endianness and optimizes little endian is awesome, but abstracted <code>int</code> types with variable size make for a hell of a mess when trying to connect a 32-bit client to a 64-bit server without having to add a myriad of casting for any case where you used a generic <code>int</code> (<em>since data loss can occur when sending an <code>int</code> from a 64 bit service to a 32 bit service</em>).</p>
+
+<p><strong><em>written on 2017-04-13</em></strong></p>
+
+        </div>
+
+        <footer class="group">
+            <a href='https://www.facebook.com/CaseyRDeLorme' class='link facebook'></a>
+            <a href='https://www.linkedin.com/in/cdelorme' class='link linkedin'></a>
+            <a href='https://www.youtube.com/user/LordOfElm' class='link youtube'></a>
+            <a href='https://github.com/cdelorme' class='link github'></a>
+            <a href='skype:casey.delorme?chat' class='link skype'></a>
+            <div class="scripts">
+                <script type="text/javascript" src="/js/main.js#9682a1d" async></script>
+            </div>
+        </footer>
+
+    </body>
+</html>

+ 52 - 0
public/projects/serve.html

@@ -0,0 +1,52 @@
+<!doctype html>
+<html lang="en">
+    <head>
+        <meta charset="utf-8">
+        <meta http-equiv="X-UA-Compatible" content="IE=edge">
+        <meta name="viewport" content="width=device-width, initial-scale=1">
+        <meta name="description" content="">
+        <title>serve | Casey DeLorme's Portfolio / caseydelorme.com</title>
+        <link rel="icon" type="image/x-icon" href="https://d2xxklvztqk0jd.cloudfront.net/favicon.ico" />
+        <link rel="stylesheet" type="text/css" href="/css/main.css#9682a1d">
+    </head>
+    <body>
+        <header class="group">
+            <h1><a href='/'>Casey DeLorme</a></h1>
+            <nav>
+                <ul>
+                    <li><a href="/projects">Projects</a></li>
+                    <li><a href="/resume.html">Resume</a></li>
+                </ul>
+            </nav>
+        </header>
+
+        <div class="content group">
+            <h3><a href="https://github.com/cdelorme/serve">serve</a></h3>
+
+<p>I often found myself working with folks who had limited back-end development knowledge.</p>
+
+<p>Regularly these folks would complain about the difficulties of setting up a web server, such as apache or nginx, to test front-end code locally.</p>
+
+<p>I spent roughly 30 minutes and wrote the first draft of a file server written for the sole purpose of locally testing.</p>
+
+<p>The current version is under 30 lines of code (&lt;80 if you count tests), allows the port to be changed via an environment variable, and will launch the site in the web browser.</p>
+
+<p>This is by far the coolest tiny utility I have written, and while it certainly does not compete with something like nginx, it&rsquo;s something you can just run and it works with literally zero configuration.</p>
+
+<p><strong><em>written on 2017-04-13</em></strong></p>
+
+        </div>
+
+        <footer class="group">
+            <a href='https://www.facebook.com/CaseyRDeLorme' class='link facebook'></a>
+            <a href='https://www.linkedin.com/in/cdelorme' class='link linkedin'></a>
+            <a href='https://www.youtube.com/user/LordOfElm' class='link youtube'></a>
+            <a href='https://github.com/cdelorme' class='link github'></a>
+            <a href='skype:casey.delorme?chat' class='link skype'></a>
+            <div class="scripts">
+                <script type="text/javascript" src="/js/main.js#9682a1d" async></script>
+            </div>
+        </footer>
+
+    </body>
+</html>

+ 16 - 28
public/projects/staticmd.html → public/projects/smd.html

@@ -5,30 +5,23 @@
         <meta http-equiv="X-UA-Compatible" content="IE=edge">
         <meta name="viewport" content="width=device-width, initial-scale=1">
         <meta name="description" content="">
-        <title>staticmd | Casey DeLorme's Portfolio / caseydelorme.com</title>
+        <title>smd | Casey DeLorme's Portfolio / caseydelorme.com</title>
         <link rel="icon" type="image/x-icon" href="https://d2xxklvztqk0jd.cloudfront.net/favicon.ico" />
-        <link rel="stylesheet" type="text/css" href="/css/main.css#2df346a">
+        <link rel="stylesheet" type="text/css" href="/css/main.css#9682a1d">
     </head>
     <body>
         <header class="group">
             <h1><a href='/'>Casey DeLorme</a></h1>
-            
             <nav>
                 <ul>
-                
-                    <li><a href='/index.html'>index</a></li>
-                
-                    <li><a href='/projects/'>projects</a></li>
-                
-                    <li><a href='/resume.html'>resume</a></li>
-                
+                    <li><a href="/projects">Projects</a></li>
+                    <li><a href="/resume.html">Resume</a></li>
                 </ul>
             </nav>
-            
         </header>
 
         <div class="content group">
-            <h1><a href="https://github.com/cdelorme/staticmd">staticmd</a></h1>
+            <h3><a href="https://github.com/cdelorme/static/tree/master/cmd/smd">static / smd</a></h3>
 
 <p>I looked at some alternatives such as <a href="http://harpjs.com/">harpjs</a> and <a href="http://gohugo.io/">hugo</a>, and while both of them are fantastic tools, I wanted something much more basic.</p>
 
@@ -36,38 +29,33 @@
 
 <p>My goal with this code was not just a basic static site generator, but the ability to compile many files into a single <em>&ldquo;book&rdquo;</em>.  Ideally the ability to do so using a single template file, and with nothing more complicated than a handful of variables inside it.</p>
 
-<h2>design considerations</h2>
+<h4>design considerations</h4>
 
 <p>The code needed two paths, one for making a single page book, and one for making a multi page site.  There also needed to be a split in the path for multi page generation that allowed for relative paths, so it could be used/accessed like locally generated documentation.</p>
 
 <p>I was also creating this as a <a href="https://www.youtube.com/watch?v=gsPabU09FFM">work-project</a>, and had a deadline to meet.  So I dropped some of the objectives from the original design, such as multiple index support, and some of the navigation logic was changed when I looked at how some others were doing it, like <a href="http://stevelosh.com/">Steve Losh</a>.</p>
 
-<h2>future plans</h2>
+<p>As I learned more about go, I made many changes, including separating the command from the package, and overall the layout and naming sense.</p>
 
-<p>I have a few things I&rsquo;d like to refactor, features to add, and components to rebuild:</p>
+<p>I also removed some features, like navigation which was too complicated to be useful in a generic sense, and relative paths which were meaningless when markdown itself is readable.</p>
 
-<ul>
-<li>moving the core logic to a separate library, and making a <code>staticmd-cli</code> repository</li>
-<li>rewriting the index generator for single page and multiple page more intelligently</li>
-<li>revisit and cleanup the process of building list of files, and filters</li>
-<li>addition of optional configuration file support</li>
-</ul>
+<h4>future plans</h4>
 
-<p>The core of the system which currently accepts cli inputs could be adjusted such that the cli logic is independent.  This would allow me to, in the future, create a graphical interface version (ex. <code>staticmd-sdl</code>).  It&rsquo;s something I&rsquo;ve experimented with in my <a href="level6.html"><code>level6</code> project</a>.</p>
+<p>At this point I have no further plans to modify or refactor the code.</p>
 
-<p>I have several concerns with the current implementation that generates indexes or table-of-contents.  For the single page code I never created a means to sort the contents (it assumes file system order which should be alphabetical).  This also means the title of the section, which should point to the index, is not a link because the order it lists the content is not controlled (linking would potentially put you in the middle of that sub-section of content).  The multi page index generation currently has to go through extra rounds when using relative links, and like before control over order is only by name.  Ideally I want to be able to sort via folders-first for multi-page generation, and some alternative for single-page that allows more control over the order.  Fixing how the content builds when using single page such that index contents are the first loaded in sub-sections, and being able to link to them would be ideal.</p>
+<p>One beneficial change might be to add stat logic to get the modified time of a file and compare it to the output file.  This would allow me to only replace modified files, which could reduce the overall load of execution when running in web mode.</p>
 
-<p>I want to revisit and cleanup how I create the list of files, folders, and apply filters such as the accepted markdown file types, or which paths to ignore.  Right now the code and the way the logic is split does not feel efficient.  I&rsquo;d like to make it more readable, without killing performance.</p>
+<p>Another option is exposing the package-global list and allowing replacement or additional file extensions to be supported.</p>
 
-<p>While my original concept was to avoid configuration files, I am seeing where the need arises.  If filtered paths, accepted file types, and a bunch of other properties become flagged options, the command to insert all of this becomes just as complicated as a configuration file.  I would like to do what I can to allow configuration file support, with flags for the same set of options, and fallback to a set of <em>sane</em> default values otherwise.</p>
+<p><em>However, I am considering moving to hugo instead for a variety of reasons.</em>  That would make any additional effort here quite wasteful.</p>
 
-<h2>references</h2>
+<h4>references</h4>
 
 <p>I&rsquo;ve been fond of reading about game development lately, and came across <a href="http://gameprogrammingpatterns.com/">gameprogrammingpatterns.com/</a>, which was written using markdown.  This is primarily because the best practices we use in our field today so greatly conflict with game developments version of best practices where performance far outweighs the value of things like object-oriented-design.</p>
 
 <p>Another great resource I found was <a href="http://www.golang-book.com/">the golang book</a>, which is also written in markdown.  I find great beauty in the simplest of aesthetics, and this is a perfect example of that.</p>
 
-<h5><em>written on 2014-12-22</em></h5>
+<p><strong><em>updated on 2017-04-13</em></strong></p>
 
         </div>
 
@@ -78,7 +66,7 @@
             <a href='https://github.com/cdelorme' class='link github'></a>
             <a href='skype:casey.delorme?chat' class='link skype'></a>
             <div class="scripts">
-                <script type="text/javascript" src="/js/main.js#2df346a" async></script>
+                <script type="text/javascript" src="/js/main.js#9682a1d" async></script>
             </div>
         </footer>
 

+ 58 - 0
public/projects/system-setup.html

@@ -0,0 +1,58 @@
+<!doctype html>
+<html lang="en">
+    <head>
+        <meta charset="utf-8">
+        <meta http-equiv="X-UA-Compatible" content="IE=edge">
+        <meta name="viewport" content="width=device-width, initial-scale=1">
+        <meta name="description" content="">
+        <title>system-setup | Casey DeLorme's Portfolio / caseydelorme.com</title>
+        <link rel="icon" type="image/x-icon" href="https://d2xxklvztqk0jd.cloudfront.net/favicon.ico" />
+        <link rel="stylesheet" type="text/css" href="/css/main.css#9682a1d">
+    </head>
+    <body>
+        <header class="group">
+            <h1><a href='/'>Casey DeLorme</a></h1>
+            <nav>
+                <ul>
+                    <li><a href="/projects">Projects</a></li>
+                    <li><a href="/resume.html">Resume</a></li>
+                </ul>
+            </nav>
+        </header>
+
+        <div class="content group">
+            <h3><a href="https://github.com/cdelorme/system-setup">system-setup</a></h3>
+
+<p>This is possibly the oldest repository that I have continued to make regular changes to.</p>
+
+<p>Originally I used it to keep track of configuration and automation of various systems.  I then referenced it when I was trying to reconfigure a system.</p>
+
+<p>At one point I converted it into a full bash automation system.</p>
+
+<p>I tried several different forms of automation, and dozens of different configurations before settling on putting the entire process into a single file and copying configuration files from the repository.</p>
+
+<p><strong>I made an effort to make it something you can run from the command line of a freshly installed system.</strong></p>
+
+<p>I also documented a handful of alternative linux distributions, and also windows and osx.  However, I stopped using windows, and decided to stick with just one linux distribution, which keeps the repository thinner and lets me get some sleep once in a while.</p>
+
+<p>I favor bash scripts because they are identical to what you would do in the terminal, and validating each step is a simple matter of copying and pasting the command.  <em>It has no dependencies and is far less complex than the made-up syntax used by various configuration management software.</em>  Just remember, if you aren&rsquo;t specifying the package manager, chances are someone else had to, and if it ever changes you&rsquo;ll have to hope they fix what they wrote for you.</p>
+
+<p><strong>There is no such thing as a free lunch.</strong></p>
+
+<p><strong><em>written on 2017-04-13</em></strong></p>
+
+        </div>
+
+        <footer class="group">
+            <a href='https://www.facebook.com/CaseyRDeLorme' class='link facebook'></a>
+            <a href='https://www.linkedin.com/in/cdelorme' class='link linkedin'></a>
+            <a href='https://www.youtube.com/user/LordOfElm' class='link youtube'></a>
+            <a href='https://github.com/cdelorme' class='link github'></a>
+            <a href='skype:casey.delorme?chat' class='link skype'></a>
+            <div class="scripts">
+                <script type="text/javascript" src="/js/main.js#9682a1d" async></script>
+            </div>
+        </footer>
+
+    </body>
+</html>

+ 6 - 13
public/resume.html

@@ -7,24 +7,17 @@
         <meta name="description" content="">
         <title>resume | Casey DeLorme's Portfolio / caseydelorme.com</title>
         <link rel="icon" type="image/x-icon" href="https://d2xxklvztqk0jd.cloudfront.net/favicon.ico" />
-        <link rel="stylesheet" type="text/css" href="/css/main.css#2df346a">
+        <link rel="stylesheet" type="text/css" href="/css/main.css#9682a1d">
     </head>
     <body>
         <header class="group">
             <h1><a href='/'>Casey DeLorme</a></h1>
-            
             <nav>
                 <ul>
-                
-                    <li><a href='/index.html'>index</a></li>
-                
-                    <li><a href='/projects/'>projects</a></li>
-                
-                    <li><a href='/resume.html'>resume</a></li>
-                
+                    <li><a href="/projects">Projects</a></li>
+                    <li><a href="/resume.html">Resume</a></li>
                 </ul>
             </nav>
-            
         </header>
 
         <div class="content group">
@@ -35,9 +28,9 @@
 <li><a href="mailto:cdelorme@gmail.com">email</a></li>
 </ul>
 
-<h2>objective</h2>
+<h2>objectives</h2>
 
-<p>Automate repetitive tasks and write efficient well formatted code that both challenges and forges tomorrows best practices.</p>
+<p>Emphasize simplicity, automate repetitive tasks, write efficient well formatted code, and challenge todays best practices to forge tomorrows.</p>
 
 <h2>skills</h2>
 
@@ -188,7 +181,7 @@
             <a href='https://github.com/cdelorme' class='link github'></a>
             <a href='skype:casey.delorme?chat' class='link skype'></a>
             <div class="scripts">
-                <script type="text/javascript" src="/js/main.js#2df346a" async></script>
+                <script type="text/javascript" src="/js/main.js#9682a1d" async></script>
             </div>
         </footer>
 

+ 8 - 2
readme.md

@@ -1,5 +1,11 @@
 
-# caseydelorme.com
+# [caseydelorme.com](https://www.caseydelorme.com)
 
-This repository contains the source that makes up myi personal website, which consists of static content generated from markdown files.
+This repository contains the source that makes up my personal website, which consists of static content generated from markdown files.
 
+
+## rebuild
+
+To rebuild the public html install [smd](https://github.com/cdelorme/static/tree/master/cmd/smd) then run:
+
+	smd -w -t caseydelorme.com -v $(git rev-parse --short HEAD) --template=template.tmpl -i src -o public

+ 4 - 3
src/index.md

@@ -1,9 +1,10 @@
 
 Welcome to my portfolio website.
 
-I'm a **Software developer, systems administrator, and technology enthusiast.**
+I am a **Software developer, systems administrator, devops engineer, and technology enthusiast.**
 
-My life objectives are to challenge conventions by looking at new ways of employing all the wild new technologies that continue to evolve around us.  This is what leads us to major breakthroughts in software design and architecture, which allows our field to continue improving and building best practices.
+My life objectives are to challenge conventions by looking at new ways of employing all the wild new technologies that continue to evolve around us.  This is what leads us to major breakthroughs in software design and architecture, which allows our field to continue improving and building best practices.
 
-Interested in my skills?  Checkout my [resume](/resume.html), or my [github account](https://github.com/cdelorme) for projects.  Looking to contact me?  Feel free to shoot me an [email](mailto:cdelorme@gmail.com).
+I am currently employed by [ellucian](https://www.ellucian.com/), a higher education software company, where I write infrastructure, automation, tools, and services in [go](https://golang.org/) and [node](https://nodejs.org/en/) that live in [AWS (Amazon Web Services)](https://aws.amazon.com/) for my own team and others under the title of "Devops Engineer Principal".
 
+Interested in my skills?  Checkout my [resume](/resume.html), or my [github account](https://github.com/cdelorme) for [projects](/projects).  Looking to contact me?  Feel free to send me an [email](mailto:cdelorme@gmail.com).

+ 56 - 0
src/projects/accelerator.md

@@ -0,0 +1,56 @@
+
+### [accelerator](https://github.com/cdelorme/level/tree/master/cmd/accelerator)
+
+This was a fun and amusing project I chose to build for a variety of reasons.
+
+There are few free utilities that provide file deduplication, even on open sourced platforms.  _There are some complex features as part of modern file systems, but they generally don't resolve the underlying problem and are not portable._
+
+I myself have roughly 6 terrabytes of personal data files, a lot of which includes images, videos, and of course copious amounts of text files from project source code.  While this may differ from the average user to some degree, I have found that many suffer from the same problem of redundant copies, often due to the lack of a good backup strategy.  _This problem is compounding, and exists long after you have found a good backup strategy._
+
+The objective was to produce a relatively simple command line tool that could handle file deduplication on personal computers.  _Ideally, it would run fast, and with a high degree of reliability/accuracy._
+
+**The tools naming is loosely based on events during a storyline in an [anime](https://myanimelist.net/anime/6213/Toaru_Kagaku_no_Railgun).**
+
+
+#### iterations
+
+This project has undergone several iterations to reach its current state.
+
+The first iteration was based almost entirely around sha256 hash comparisons, under the assumption that:
+
+[![sha256 is preferred](http://i.stack.imgur.com/46Vwb.jpg)](http://crypto.stackexchange.com/questions/1170/best-way-to-reduce-chance-of-hash-collisions-multiple-hashes-or-larger-hash)
+
+After realizing that for duplicate data the files must be the same size, a second iteration grouped the files by size.
+
+A third iteration added the concurrency model using channels, _which was my first taste of concurrency in go and appeared to boost the speed significantly._  By concurrently comparing each group on its own thread, I was able to parallelize the process, which mainly improved the hash generation.
+
+A friend suggested leading with crc32 since the computation was faster than sha256, which would allow for early identification of unmatched files.  This led to the fourth iteration where crc32 was introduced.
+
+After encountering a strange and poorly documented windows behavior, where resource exhaustion would terminate a process, I realized that loading entire files into memory was probably not a wise choice and a fifth iteration introduced buffered hashing.
+
+I began to question scenarios that could yield sha256 collisions, and decided that I would rather add byte-by-byte comparison as a final check.  This led to a sixth iteration.
+
+With the buffering now in place, I tried moving towards mutex-based concurrency due to the complex appearance of the channel based model, but during the process noticed that eliminating concurrency resulted in faster execution times.  Thus the seventh iteration was the removal of concurrency and converting the code to a pipeline system with placeholders for expected functionality.
+
+The eighth iteration came from the desire to clean the syntax to match other projects and the "publicly accepted standard", add [godocs](http://godoc.org/github.com/cdelorme/level), and eliminate YAGNI artifacts.  I ended up renaming the repository and library, gave the command line a better name, dropped features that would have reduced the accuracy of the system or relied heavily on external tools, and consolidated the code into a single simple structure.
+
+The current, ninth iteration, involved minimizing the exposed behaviors from the library, fixing placement of various components, separating metrics into its own library as a dependency, and removing the hashing behavior after realizing the cost of hashing was not only significantly greater than byte-by-byte comparison but was also thrashing the disk.  **This is 232 lines of library, 40 lines of command line, and 109 lines of tests with over 90% coverage, omitting tests that would require mocking a file system.**
+
+
+#### lessons
+
+Attempting to test every possible file system behavior by abstracting and overriding (or by mocking) is a fools errand, and you can simply rely on basic error handling for that remaining 10% coverage.
+
+Even with buffering, hashing still requires the entire file to be read, whereas byte-by-byte comparison can terminate as early as the first 4k read.  **This is why you should always approach the problem with the simplest solution first.**
+
+I had originally planned to introduce alternative comparison behavior, such as content comparison to find partial-matching files, and multimedia comparison which would have relied on separate tools.  **Instead I chose to do one thing well.**
+
+I spent some time considering reimplementation of parallelism and attempting to optimize the file comparison algorithm reducing the total number of times file comparison is run.  Theoretically neither of these implementations would have worked well; the file system is not able to operate in parallel, and you cannot take advantage of disk cache when you are bouncing the read head between 4k reads across a large number of files.  **Understanding the foundations of the problem as well as what your code is actually doing on a system is essential to writing a good application.**
+
+
+#### future
+
+I considered a web interface to make it more usable, but introducing a method of canceling a scan, reporting or requesting the status, and pause behavior would require significant amounts of complexity and re-work and it isn't a priority.
+
+
+**_updated on 2017-07-18_**

+ 10 - 0
src/projects/appinator.md

@@ -0,0 +1,10 @@
+
+### [appinator](https://github.com/cdelorme/appinator)
+
+This is another whimsical utility I wrote to make testing applications on OSX easier.
+
+In particular, I was writing go applications that use [opengl](https://github.com/go-gl/gl) and [glfw](https://github.com/go-gl/glfw), which when run directly launch a terminal.
+
+_By creating an OSX bundle I am able to hide the terminal, which works wonderfully._
+
+**_written on 2017-04-13_**

+ 15 - 16
src/projects/caseydelorme.com.md

@@ -1,36 +1,35 @@
 
-# [caseydelorme.com](https://github.com/cdelorme/caseydelorme.com)
+### [caseydelorme.com](https://github.com/cdelorme/caseydelorme.com)
 
-This site began with the concept of a simplified static site generator.  As a result I built [staticmd](staticmd.html) first.
+This site began with the concept of a simplified static site generator, which resulted in writing [accelerator](accelerator.html) first.
 
-The goal of this site was to replace a traditional dynamic system with raw static content.  I would then replace (and redirect) my [old site](http://www.cdelorme.com) with this one.
+The goal of this site was to replace a traditional dynamic system with raw static content and redirect the domain after.
 
 
-## design considerations
+#### design considerations
 
 One major consideration was taking advantage of content delivery using AWS S3 and CloudFront services for any static or binary contents.  This provides a significantly greater degree of scalability, in that I can create as many servers as necessary to deliver the websites static content, while binary/static files all come from one place.
 
-Right now that includes images, fonts, and some static third-party css and javascript.  Because my own css and javascript are still under construction it made sense to include them using git-hash-versioning.  This ensures the browser won't cache incorrectly.  _In the future I could use that versioning to minify, name, and upload my content to S3 and use the CDN exclusively for all versions._
+Right now that includes images, fonts, and some static third-party css and javascript.  Because my own css and javascript are still under construction it made sense to include them using git-hash-versioning to ensure the browser won't cache incorrectly.  _In the future I could continue to version but also minify and upload the changed files to S3 so I could benefit from using it for all "static" files._
 
 Another advantage to moving away from a dynamic website is that when dealing with basic static html we can enable simple caching directly through nginx without concern for other layers; there is no CMS to contend with or concern for "immediately up-to-date" contents.
 
-I decided to implement `https` because I intend to use the domain for experiments from time to time, and also [because it's free](https://www.startssl.com/).
+I decided to implement `https` because I intend to use the domain for experiments from time to time, _and also [because it's free](https://letsencrypt.org/)._
 
-Finally, I am using git, as well as github, as a means of version control for my website now.  This allows me to enable a simple cronjob to pull changes hourly, and know that I can update my site from any computer by simply pushing new static html to the github repository.  This also means I have a backup, and a means of distribution/deployment in a way that is scalable.
+Finally, I am using git, as well as github, as a means of version control for my website now.  This allows me to enable a simple cronjob to pull changes hourly, and know that I can update my site from any computer by simply pushing new static html to the github repository.  This also means I have a backup, and a very simple distribution and deployment method.
 
 
-## future plans
+#### future plans
 
-I have a list of enhancements I'd like to add in the future, which may involve changes to my `staticmd` project as well:
+I have two considerations for the next steps:
 
-- move css and javascript to cdn
-- implement date tracking
-- improved indexing, navigation, and primary index file identification
+- possibly switch to [hugo](https://gohugo.io/)
+- generate the site on the server after pulling changes and remove html from the repository
 
-For any binary file or large file it would make sense to keep it out of the repository and to use a content delivery network.  However, for the builtin css and javascript, being so small, there isn't a problem having as many copies as there are machines with the content.  Further, if I needed to scale the deployment mechanism uses the repository and should always have the latest copy of content.  That said, using some sort of task automator, like [grunt](http://gruntjs.com/), would allow me to minify, name, and upload my javascript and css to the same AWS CloudFront I use for other files.  If anything it would be good practice for any future sites I choose to work on.
+The custom tool I built was more of a proof-of-concept, and while neat it isn't the best option out there.  Another tool built in go with much greater stability is available, and might be worth trying.
 
-I would like to be able to identify when a file was created and last updated, and provide these either below the first header, or at the bottom of the content.  For now, the date created and updated is technically accessible in the repository, but readers won't want to be bothered to look that far, so I can manually add dates for the time being.  The concerns here include whether the file system will correctly track the date created and modified of a file, especially if the files consist of a fresh clone.
+Right now I commit the parsed html directly to the repository, and while this means deployment is a simple `git pull`, it also means that the compiled version of every file is taking space up in the repository redundantly.
 
-I took shortcuts with the current implementation of staticmd's index builder and identification.  Ideally I wanted to go the github route and work with `readme.md` as the **primary** index file.  However, to conditionally pick between two possible index files adds a bunch more complication, so I ended up sticking with one.  In the future I would like to correct this, and improve how I generate the indexes and main navigation as well.  Things like sort-by-date-order, folders-first, and intelligently ignoring index pages (again complications if two files could both potentially be an index page).
+_Finally, I might move the css and javascript to the same S3 CDN that I use for images._
 
-##### _written on 2014-12-22_
+**_updated on 2017-07-18_**

+ 10 - 0
src/projects/dot-files.md

@@ -0,0 +1,10 @@
+
+### [dot-files](https://github.com/cdelorme/dot-files)
+
+As I find myself inside the terminal more often than not, I realized that the default shell is kind of crummy.
+
+I tried using the common enhancements others suggested, but found them to be too heavy-handed, so I wrote my own and borrowed only the bare-minimum from others.
+
+The result is an incredibly enhanced bash shell with almost no footprint.
+
+**_written on 2017-04-13_**

+ 26 - 0
src/projects/glog.md

@@ -0,0 +1,26 @@
+
+### [glog](https://github.com/cdelorme/glog)
+
+I wrote this some time ago when I realized that the default [log](https://golang.org/pkg/log/) package forced the software to exit when you called the Error functions.  _It also does not include any context; the package, file, or line number which are immensely helpful when troubleshooting._
+
+While there are other packages that provide the functionality I would want, some mirror the default package's behavior, and most are relatively large or have additional dependencies.
+
+So I decided to write my own, which was so simple I was amazed how big some of the other packages are.
+
+Instead of the myriad of conflicting behaviors that a developer could embed into their application for configuration (eg. `-s` or `--silent`, `-q` or `--quiet`, literally every full or partial log level name, or a log level with severity as a value, I've seen it all).  **Developers can ignore all that now, just let the user set `LOG_LEVEL` environment variable.**
+
+It provides standardized severities which defaults to "Error".  _I generally only use around 3~4 of them, but all of them are included._
+
+It can determine color support in the terminal and will log in color (disabled if output is redirected).
+
+It offers context, so you can easily debug code by tracking down the file and line number the error occurred.
+
+All output goes to stderr, _which is the optimal sane default to avoid messing with expected application output._
+
+It is concurrently safe, using a package level mutex.
+
+It comes with comprehensive tests, and benchmarks.
+
+**I highly recommend [trying it out](https://github.com/cdelorme/glog).**
+
+**_written on 2017-04-13_**

+ 21 - 0
src/projects/gonf.md

@@ -0,0 +1,21 @@
+
+### [gonf](https://github.com/cdelorme/gonf)
+
+I actually started with three separate configuration packages, and a package to make working with `map[string]interface{}` easier:
+
+- [go-option](https://github.com/cdelorme/go-option)
+- [go-config](https://github.com/cdelorme/go-config)
+- [go-env](https://github.com/cdelorme/go-env)
+- [go-maps](https://github.com/cdelorme/go-maps)
+
+After over a year of using each, I realized that I always followed exactly the same patterns, and never leveraged maps due to the additional complexity.
+
+So I decided to write a consolidated configuration package.
+
+It currently provides POSIX compliant command line option support using an implementation with an explicit greedy character, environment variables, casting from string inputs to the supplied structure, loading and saving to and from a json file, and is completely concurrently safe.
+
+I made a lot of decisions that not everyone will agree with, _but for me this package solves every configuration problem I could want without importing a single third party dependency._
+
+However, even with the tests provided, because this is still fairly new I can't guarantee the stability just yet.  Once I have used it in more projects I will be able to say for sure.
+
+**_written on 2017-04-13_**

+ 27 - 1
src/projects/index.md

@@ -3,5 +3,31 @@
 
 This section is for detailed information on projects I wrote or participated in.
 
-Select a project from the list!
+Select a project from the list:
 
+- [appinator](appinator.html)
+	- a go utility to turn any binary into an osx bundle.
+- [modernizer](modernizer.html)
+	- A go package that automatically update applications.
+- [rathena docker](rathena-docker.html)
+	- run the open-sourced ragnarok online server inside docker.
+- [serial](serial.html)
+	- A test case for the smallest possible binary format.
+- [gonf](gonf.html)
+	- a consolidated configuration package for go.
+- [glog](glog.html)
+	- a standard-compliant logger for go that does not forcefully exit the application and writes to stderr.
+- [serve](serve.html)
+	- instantly launch a file-based web server in the current directory.
+- [system-setup](system-setup.html)
+	- several years worth of documentation on operating system installation, configuration, and automation.
+- [dot-files](dot-files.html)
+	- a minimal stack of files to make your bash terminal amazing.
+- [accelerator](accelerator.html)
+	- deduplication of files by byte-comparison.
+- [smd](smd.html)
+	- a tiny static markdown generator.
+- [caseydelorme.com](caseydelorme.com.html)
+	- my portfolio website, as a repository.
+- [jslideshow](jslideshow.html)
+	- an image slideshow with preloading and realtime rendering, written in vanilla javascript.

+ 10 - 0
src/projects/jslideshow.md

@@ -0,0 +1,10 @@
+
+### [jslideshow](https://github.com/cdelorme/jslideshow)
+
+I've always been fascinated with image transitions and slideshows using the web browser.  Some time ago I wrote a [slideshow using jquery](https://github.com/cdelorme/jquery_slideshow_plugin).
+
+After reading an [excellent article](http://jlongster.com/Removing-User-Interface-Complexity,-or-Why-React-is-Awesome) on real-time rendering, I decided to try rewriting this in vanilla (eg. raw, with zero dependencies) javascript to leverage this approach.
+
+It turned out to be pretty clean, and the demo includes logic to load the javascript directly from github.
+
+**_written on 2017-04-13_**

+ 0 - 41
src/projects/level6.md

@@ -1,41 +0,0 @@
-
-# [level6](https://github.com/cdelorme/level6)
-
-This was a fun and amusing project I chose to build for a variety of reasons.  I myself have roughly 6 terrabytes of personal data files, a lot of which includes images, videos, and of course copious amounts of text files from project source code.
-
-While my scale is perhaps a bit larger, my problem is no different than that which my family and friends face regularly.  There are no free or simple tools out there that will handle file deduplication flexibly and efficiently.
-
-My goal with this project was to create a free and open source software that could handle file deduplication on personal computers.  Ideally at break-neck speed, but with a high degree of accuracy.
-
-The name of the project came about from the concept of destroying cloned files.  As an avid anime fan I decided to name it after a particular project in a series I enjoyed, although the connotation of the project in that series is certainly darker than the purpose of this project.
-
-
-## design considerations
-
-Originally I wanted to simply go with sha256 hash comparison.  My first implementation simply created a list of hashes for every file in a single threaded loop and printed out sets of results by hash.
-
-Then, as I read more about comparison, I realized that file size is relevant.  I took the single core file walk and grouped files by their size, then created sha256 hashes.  I proceeded to add options to delete or move the files, and json support for output such that it could be consumed and used by other applications in an easier way.
-
-My next stage was adding concurrency, which was my first attempt at golangs concurrency model.  It was actually quite refreshing once I understood how it worked, and I managed to improve the performance of the software quite a bit.
-
-I showed it to a few friends who gave me some suggestions, including adding summary data such as how many files were scanned, how many hashes were generated, and how long the operation took.  Another suggestion was to use a lighter hashing algorithm as a stop-gap before generating sha256 hashes.  This turned out to be another boon to performance, since sha256 is an expensive algorithm compared to something like crc32, so I added crc32 as a first-measure before running sha256 hashing.  I implemented full counts of how many hashes were generated, plus how many duplicates were found.
-
-The end result is roughly 600 lines of code, which can provide a very fast way to identify and manage duplicate files.  There is still a lot of room for improvement, but I'm pretty happy with how quickly I was able to put it together.
-
-
-## future plans
-
-- dodgy windows compatibility
-- byte-comparison for large files and 100%-accuracy going a step beyond sha256
-- core library, cli & gui repositories
-- detailed multimedia comparison
-
-Tests on Windows Vista 32 bit have crashed, but Windows 8.1 64 bit work.  However, on Windows it seems that resource-exhaustion occurs during which the OS forces the program to close.  This problem stems from its less-than-frugal use of ram to store contents when generating sha256 hashes.  One solution is to set a max-size, and simply omit them from comparison.  This seems to have worked well in my test cases, but it's obviously not perfect.
-
-I would like to implement byte-by-byte comparison for a more detailed approach to comparing two files.  While the odds of sha256 conflict are absurd, this would give us a 100% trust option for identifying duplicates.  Similarly it would allow us to assume a safe arbitrary max file size, reducing necessary cli arguments, and still being capable of parsing very large files.
-
-I already worked to separate the code into its own library folder, but in the future I want to separate that as its own repository, then import and use it with both a cli and gui implementation.  This would allow something like `level6-sdl` to provide a graphical interface, stacked ontop of the same source as the cli implementation.
-
-I would like to use more detailed comparison methods against images, videos, and audio.  Algorithms that identify key-points in similar files, and can draw conclusions such as altered contrast, brightness, cropping, rotation, etc and still manage to match similar items.  These small changes may barely be visible in the files themselves but would cause hash or byte comparison to fail.
-
-##### _written on 2014-12-22_

+ 14 - 0
src/projects/modernizer.md

@@ -0,0 +1,14 @@
+
+### [modernizer](https://github.com/cdelorme/modernizer)
+
+I only found one alternative, and they put a ton of effort into supporting binary delta updates, which I think are a waste of time and code.
+
+As usual, I decided to write my own.  In roughly a weekend I was able to create a tool that downloads a version file, compares versions, downloads and replaces the binary in a cross-platform compatible way, and launches the new executable while retaining the default file descriptors.
+
+Windows has two minor glitches that required a bit of extra cleanup work.  First it does not offer `Exec`, so the process id changes, but it somehow inherits the same streams (stdin/stdout/stderr all continue to work correctly).  Second in order to eliminate the previous binary a rename and cleanup process is required since windows locks the binary file during execution (_I assume due to mmap calls?_).
+
+While it isn't a perfect solution for all use-cases, it works great and is damn small (less than 200 lines of code).
+
+For complex situations where you need to cleanup the existing runtime, or want to carry over an open network connection (eg. keep a service active) then you probably want something more complex and tailor-made.
+
+**_written on 2017-04-13_**

+ 16 - 0
src/projects/rathena-docker.md

@@ -0,0 +1,16 @@
+
+### [rathena-docker](https://github.com/cdelorme/rathena-docker)
+
+I am an avid gamer, and one of the games I enjoyed was ragnarok online.
+
+The [rathena project](https://rathena.org/) is an effort to provide an open-source implementation of the ragnarok online service, based on reverse engineering efforts with Aegis, the official server.
+
+I enjoy that it runs on linux, _but sadly there is no open-source renewal client solution yet so we can't enjoy ragnarok on linux without [WINE](https://www.winehq.org/)._
+
+While experimenting with [docker](https://www.docker.com/) for work, I decided to try writing a Dockerfile that would generate a docker image that could run an entire rathena server.
+
+Originally I had planned to use docker to create a distributed networked example, _but because docker immutable state complicates runtime configuration I gave up._
+
+**In the future I may pursue [docker-compose](https://docs.docker.com/compose/) to orchestrate a distributed configuration to demonstrate multiple components of the rathena server in action.**
+
+**_written on 2017-04-13_**

+ 20 - 0
src/projects/serial.md

@@ -0,0 +1,20 @@
+
+### [serial](https://github.com/cdelorme/serial)
+
+I began reading some interesting articles by [Glenn Fiedler](http://gafferongames.com/), who had a particular series about writing a custom UDP protocol.
+
+At one point he expressed the concern for sending data over the network, stating that json is massive, and a binary serialization pattern that exposes a bidirectional workflow for both reading and writing works best.
+
+I decided to give a try writing it in go, and at first I followed strict syntax rules, but since the binary documentation is very good I eventually went back to a much simpler project implementation with no attempt to handle variable sized types.
+
+I also created a set of benchmarks to compare both the performance, memory management, and byte size between this system, [msgp](https://github.com/tinylib/msgp), and the [gob package](https://golang.org/pkg/encoding/gob/).  _This is a proof-of-concept, so I am not attempting to [compete](https://github.com/alecthomas/go_serialization_benchmarks)._
+
+While mine is not the fastest, it is by far the smallest, which proves that a very simple thin wrapper to abstract read and write behavior, and extra effort to write your own byte conversion logic, can be extremely beneficial in situations where every byte counts.
+
+_I also concluded that while the gain is significant, for a first-draft msgp is substantially easier to wield and might be worth the trade-off if you are dealing with a large number of structures and don't have time to write binary serialization for each._
+
+One major complexity with the go implementation that I couldn't quite deal with was variable-sized data.  Anytime an nondeterministic slice or string are written, extra effort must be made to keep tabs on the size when restoring it.  _While I had written a solution to do this, it was crappy and limited to strings only._
+
+This project also helped me realize the significance between big and little endian encoding, as well as 32 vs 64 bit consistency.  The fact that go abstracts endianness and optimizes little endian is awesome, but abstracted `int` types with variable size make for a hell of a mess when trying to connect a 32-bit client to a 64-bit server without having to add a myriad of casting for any case where you used a generic `int` (_since data loss can occur when sending an `int` from a 64 bit service to a 32 bit service_).
+
+**_written on 2017-04-13_**

+ 14 - 0
src/projects/serve.md

@@ -0,0 +1,14 @@
+
+### [serve](https://github.com/cdelorme/serve)
+
+I often found myself working with folks who had limited back-end development knowledge.
+
+Regularly these folks would complain about the difficulties of setting up a web server, such as apache or nginx, to test front-end code locally.
+
+I spent roughly 30 minutes and wrote the first draft of a file server written for the sole purpose of locally testing.
+
+The current version is under 30 lines of code (<80 if you count tests), allows the port to be changed via an environment variable, and will launch the site in the web browser.
+
+This is by far the coolest tiny utility I have written, and while it certainly does not compete with something like nginx, it's something you can just run and it works with literally zero configuration.
+
+**_written on 2017-04-13_**

+ 39 - 0
src/projects/smd.md

@@ -0,0 +1,39 @@
+
+### [static / smd](https://github.com/cdelorme/static/tree/master/cmd/smd)
+
+I looked at some alternatives such as [harpjs](http://harpjs.com/) and [hugo](http://gohugo.io/), and while both of them are fantastic tools, I wanted something much more basic.
+
+I feel that the moment the content for a website has the need for configuration files, you are no longer building a basic static site but a dynamic site with a print release system.  While there is nothing inherently wrong with this approach, it seems overkill for a number of projects I'd like to build.
+
+My goal with this code was not just a basic static site generator, but the ability to compile many files into a single _"book"_.  Ideally the ability to do so using a single template file, and with nothing more complicated than a handful of variables inside it.
+
+
+#### design considerations
+
+The code needed two paths, one for making a single page book, and one for making a multi page site.  There also needed to be a split in the path for multi page generation that allowed for relative paths, so it could be used/accessed like locally generated documentation.
+
+I was also creating this as a [work-project](https://www.youtube.com/watch?v=gsPabU09FFM), and had a deadline to meet.  So I dropped some of the objectives from the original design, such as multiple index support, and some of the navigation logic was changed when I looked at how some others were doing it, like [Steve Losh](http://stevelosh.com/).
+
+As I learned more about go, I made many changes, including separating the command from the package, and overall the layout and naming sense.
+
+I also removed some features, like navigation which was too complicated to be useful in a generic sense, and relative paths which were meaningless when markdown itself is readable.
+
+
+#### future plans
+
+At this point I have no further plans to modify or refactor the code.
+
+One beneficial change might be to add stat logic to get the modified time of a file and compare it to the output file.  This would allow me to only replace modified files, which could reduce the overall load of execution when running in web mode.
+
+Another option is exposing the package-global list and allowing replacement or additional file extensions to be supported.
+
+_However, I am considering moving to hugo instead for a variety of reasons._  That would make any additional effort here quite wasteful.
+
+
+#### references
+
+I've been fond of reading about game development lately, and came across [gameprogrammingpatterns.com/](http://gameprogrammingpatterns.com/), which was written using markdown.  This is primarily because the best practices we use in our field today so greatly conflict with game developments version of best practices where performance far outweighs the value of things like object-oriented-design.
+
+Another great resource I found was [the golang book](http://www.golang-book.com/), which is also written in markdown.  I find great beauty in the simplest of aesthetics, and this is a perfect example of that.
+
+**_updated on 2017-04-13_**

+ 0 - 42
src/projects/staticmd.md

@@ -1,42 +0,0 @@
-
-# [staticmd](https://github.com/cdelorme/staticmd)
-
-I looked at some alternatives such as [harpjs](http://harpjs.com/) and [hugo](http://gohugo.io/), and while both of them are fantastic tools, I wanted something much more basic.
-
-I feel that the moment the content for a website has the need for configuration files, you are no longer building a basic static site but a dynamic site with a print release system.  While there is nothing inherently wrong with this approach, it seems overkill for a number of projects I'd like to build.
-
-My goal with this code was not just a basic static site generator, but the ability to compile many files into a single _"book"_.  Ideally the ability to do so using a single template file, and with nothing more complicated than a handful of variables inside it.
-
-
-## design considerations
-
-The code needed two paths, one for making a single page book, and one for making a multi page site.  There also needed to be a split in the path for multi page generation that allowed for relative paths, so it could be used/accessed like locally generated documentation.
-
-I was also creating this as a [work-project](https://www.youtube.com/watch?v=gsPabU09FFM), and had a deadline to meet.  So I dropped some of the objectives from the original design, such as multiple index support, and some of the navigation logic was changed when I looked at how some others were doing it, like [Steve Losh](http://stevelosh.com/).
-
-
-## future plans
-
-I have a few things I'd like to refactor, features to add, and components to rebuild:
-
-- moving the core logic to a separate library, and making a `staticmd-cli` repository
-- rewriting the index generator for single page and multiple page more intelligently
-- revisit and cleanup the process of building list of files, and filters
-- addition of optional configuration file support
-
-The core of the system which currently accepts cli inputs could be adjusted such that the cli logic is independent.  This would allow me to, in the future, create a graphical interface version (ex. `staticmd-sdl`).  It's something I've experimented with in my [`level6` project](level6.html).
-
-I have several concerns with the current implementation that generates indexes or table-of-contents.  For the single page code I never created a means to sort the contents (it assumes file system order which should be alphabetical).  This also means the title of the section, which should point to the index, is not a link because the order it lists the content is not controlled (linking would potentially put you in the middle of that sub-section of content).  The multi page index generation currently has to go through extra rounds when using relative links, and like before control over order is only by name.  Ideally I want to be able to sort via folders-first for multi-page generation, and some alternative for single-page that allows more control over the order.  Fixing how the content builds when using single page such that index contents are the first loaded in sub-sections, and being able to link to them would be ideal.
-
-I want to revisit and cleanup how I create the list of files, folders, and apply filters such as the accepted markdown file types, or which paths to ignore.  Right now the code and the way the logic is split does not feel efficient.  I'd like to make it more readable, without killing performance.
-
-While my original concept was to avoid configuration files, I am seeing where the need arises.  If filtered paths, accepted file types, and a bunch of other properties become flagged options, the command to insert all of this becomes just as complicated as a configuration file.  I would like to do what I can to allow configuration file support, with flags for the same set of options, and fallback to a set of _sane_ default values otherwise.
-
-
-## references
-
-I've been fond of reading about game development lately, and came across [gameprogrammingpatterns.com/](http://gameprogrammingpatterns.com/), which was written using markdown.  This is primarily because the best practices we use in our field today so greatly conflict with game developments version of best practices where performance far outweighs the value of things like object-oriented-design.
-
-Another great resource I found was [the golang book](http://www.golang-book.com/), which is also written in markdown.  I find great beauty in the simplest of aesthetics, and this is a perfect example of that.
-
-##### _written on 2014-12-22_

+ 20 - 0
src/projects/system-setup.md

@@ -0,0 +1,20 @@
+
+### [system-setup](https://github.com/cdelorme/system-setup)
+
+This is possibly the oldest repository that I have continued to make regular changes to.
+
+Originally I used it to keep track of configuration and automation of various systems.  I then referenced it when I was trying to reconfigure a system.
+
+At one point I converted it into a full bash automation system.
+
+I tried several different forms of automation, and dozens of different configurations before settling on putting the entire process into a single file and copying configuration files from the repository.
+
+**I made an effort to make it something you can run from the command line of a freshly installed system.**
+
+I also documented a handful of alternative linux distributions, and also windows and osx.  However, I stopped using windows, and decided to stick with just one linux distribution, which keeps the repository thinner and lets me get some sleep once in a while.
+
+I favor bash scripts because they are identical to what you would do in the terminal, and validating each step is a simple matter of copying and pasting the command.  _It has no dependencies and is far less complex than the made-up syntax used by various configuration management software._  Just remember, if you aren't specifying the package manager, chances are someone else had to, and if it ever changes you'll have to hope they fix what they wrote for you.
+
+**There is no such thing as a free lunch.**
+
+**_written on 2017-04-13_**

+ 2 - 2
src/resume.md

@@ -5,9 +5,9 @@
 - [email](mailto:cdelorme@gmail.com)
 
 
-## objective
+## objectives
 
-Automate repetitive tasks and write efficient well formatted code that both challenges and forges tomorrows best practices.
+Emphasize simplicity, automate repetitive tasks, write efficient well formatted code, and challenge todays best practices to forge tomorrows.
 
 
 ## skills

+ 6 - 9
template.tmpl

@@ -1,26 +1,23 @@
 <!doctype html>
 <html lang="en">
-    <head>{{/* depth stored for access inside navigation loop */}}{{$depth := .Depth}}
+    <head>
         <meta charset="utf-8">
         <meta http-equiv="X-UA-Compatible" content="IE=edge">
         <meta name="viewport" content="width=device-width, initial-scale=1">
         <meta name="description" content="">
-        <title>{{if .Name}}{{.Name}} | {{end}}Casey DeLorme's Portfolio / caseydelorme.com</title>
+        <title>{{if .Name}}{{.Name}} | {{end}}Casey DeLorme's Portfolio / {{.Title}}</title>
         <link rel="icon" type="image/x-icon" href="https://d2xxklvztqk0jd.cloudfront.net/favicon.ico" />
-        <link rel="stylesheet" type="text/css" href="{{$depth}}/css/main.css#{{.Version}}">
+        <link rel="stylesheet" type="text/css" href="/css/main.css#{{.Version}}">
     </head>
     <body>
         <header class="group">
             <h1><a href='/'>Casey DeLorme</a></h1>
-            {{if .Nav}}
             <nav>
                 <ul>
-                {{range .Nav}}
-                    <li><a href='{{$depth}}{{.Link}}'>{{.Title}}</a></li>
-                {{end}}
+                    <li><a href="/projects">Projects</a></li>
+                    <li><a href="/resume.html">Resume</a></li>
                 </ul>
             </nav>
-            {{end}}
         </header>
 
         <div class="content group">
@@ -34,7 +31,7 @@
             <a href='https://github.com/cdelorme' class='link github'></a>
             <a href='skype:casey.delorme?chat' class='link skype'></a>
             <div class="scripts">
-                <script type="text/javascript" src="{{$depth}}/js/main.js#{{.Version}}" async></script>
+                <script type="text/javascript" src="/js/main.js#{{.Version}}" async></script>
             </div>
         </footer>