minimal website rewrite

This commit is contained in:
Nicholas Orlowsky 2023-07-30 18:11:02 -05:00
parent 10b2cc429c
commit a3bc0de320
No known key found for this signature in database
GPG key ID: 24C84C4DDAD95065
110 changed files with 1117 additions and 56040 deletions

View file

@ -1,18 +1,9 @@
# build environment
FROM node:13.12.0-alpine as build
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY package.json ./
COPY package-lock.json ./
RUN npm install
FROM nginx:alpine
RUN npm install react-scripts@3.4.1 -g --silent
COPY . ./
RUN npm run build
WORKDIR /site
# production environment
FROM nginx:stable-alpine
COPY --from=build /app/build /usr/share/nginx/html
COPY --from=build /app/nginx/nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
COPY . .
RUN ls
RUN /bin/sh compile.sh
RUN cp -r ./out/* /usr/share/nginx/html

56
compile.sh Executable file
View file

@ -0,0 +1,56 @@
#!/bin/bash
# Check if the src directory exists
if [ ! -d "src" ]; then
echo "Error: 'src' directory not found."
exit 1
fi
# Create the out directory if it doesn't exist
mkdir -p "out"
# Define the template file and search pattern
template_file="src/structure.template.html"
filler_pattern="src/**/*.filler.html"
# Function to process the filler file and insert its content into the structure file
process_filler_file() {
local filler_file="$1"
local output_file="$2"
# Read the contents of the template file
template_content=$(<"$template_file")
# Read the contents of the filler file
filler_content=$(<"$filler_file")
# Replace "{{ body_area }}" in the template with filler content
modified_content="${template_content/\{\{ body_area \}\}/$filler_content}"
# Write the modified content to the output file in the 'out' directory
echo "$modified_content" > "out/$output_file"
echo "Created: out/$output_file"
}
# Loop through each filler file in the src directory and its subdirectories
shopt -s globstar
for filler_file in $filler_pattern; do
# Check if the filler file exists
if [ ! -e "$filler_file" ]; then
echo "Error: $filler_file not found."
exit 1
fi
# Get the relative path of the filler file (removing the "src/" prefix)
relative_path="${filler_file#src/}"
# Extract the filename (excluding the extension)
filename="${relative_path%.filler.html}"
# Create the output file name in the 'out' directory
output_file="${filename}.html"
# Process the filler file and insert its content into the structure file
process_filler_file "$filler_file" "$output_file"
done

View file

@ -1,30 +0,0 @@
server {
gzip on;
gzip_types
application/atom+xml
application/geo+json
application/javascript
application/x-javascript
application/json
application/ld+json
application/manifest+json
application/rdf+xml
application/rss+xml
application/xhtml+xml
application/xml
font/eot
font/otf
font/ttf
image/svg+xml
text/css
text/javascript
text/plain
text/xml;
gzip_min_length 256;
listen 80;
location / {
root /usr/share/nginx/html;
try_files $uri /200.html;
}
}

View file

Before

Width:  |  Height:  |  Size: 252 KiB

After

Width:  |  Height:  |  Size: 252 KiB

View file

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 1.2 MiB

View file

Before

Width:  |  Height:  |  Size: 622 KiB

After

Width:  |  Height:  |  Size: 622 KiB

32
out/blog.html Normal file
View file

@ -0,0 +1,32 @@
<head>
<title>Nicholas Orlowsky</title>
<link rel="stylesheet" href="/style.css">
<link rel="icon" type="image/x-icon" href="/favicon.ico">
</head>
<body>
<nav>
<a href="/">[ Home ]</a>
<a href="/blog.html">[ Blog ]</a>
<a href="/projects.html">[ Projects ]</a>
<a href="/extra.html">[ Extra ]</a>
<hr/>
</nav>
<div>
<h1 style="margin-bottom: 0px;">Blog</h1>
<p style="margin-top: 0px;">A collection of my thoughts, some of them may be interesting</p>
<p><a href="./blogs/side-project-7-12-23.html">[ Side Project Log 7/12/23 ]</a> - July 12th, 2023</p>
<p><a href="./blogs/side-project-4-29-23.html">[ Side Project Log 4/29/23 ]</a> - April 29th, 2023</p>
<p><a href="./blogs/side-project-3-27-23.html">[ Side Project Log 3/27/23 ]</a> - March 27th, 2023</p>
<p><a href="./blogs/side-project-3-20-23.html">[ Side Project Log 3/20/23 ]</a> - March 20th, 2023</p>
<p><a href="./blogs/spring-break-2023.html">[ Spring Break 2023 ]</a> - January 20th, 2023</p>
<p><a href="./blogs/doing-c-assignments-in-csharp.html">[ Doing C assignments in C# ]</a> - March 18th, 2022</p>
</div>
<footer>
<hr />
<p style="margin-bottom: 0px;">Copyright &#169; Nicholas Orlowsky 2023</p>
<p style="margin-top: 0px;">Hosting provided by <a href="https://nws.nickorlow.com">NWS</a></p>
</footer>
</body>

View file

@ -0,0 +1,73 @@
<head>
<title>Nicholas Orlowsky</title>
<link rel="stylesheet" href="/style.css">
<link rel="icon" type="image/x-icon" href="/favicon.ico">
</head>
<body>
<nav>
<a href="/">[ Home ]</a>
<a href="/blog.html">[ Blog ]</a>
<a href="/projects.html">[ Projects ]</a>
<a href="/extra.html">[ Extra ]</a>
<hr/>
</nav>
<h1>Doing C assignments in C#</h1>
<p>Thanks to Arpan Dhatt for doing most of the work on this (his blog here: <a href="https://arpan.one/posts/messing-with-gradescope/">https://arpan.one/posts/messing-with-gradescope/</a>)</p>
<p>At the end, he made this comment:</p>
<blockquote>
<p>And so, that&#39;s the end of this post. To whom it may concern, don&#39;t try doing your C assignment in C# (you know who you are).</p>
</blockquote>
<p>The reason for this comment (besides the fact that I talk about C# a lot) is due to the fact that C# requires a runtime to be installed for it to work. This is because C# does not compile to native bytecode but rather compiles to an intermediary language (dubbed CIL by Microsoft) and is then translated &#39;Just In Time&#39; by the runtime. </p>
<p>This makes running assignments in a docker container where the runtime is not already installed considerably hard. One option we have is that we could just include the runtime in our submission. Sounds easy, right? Well it would be non-trivial to do but due to the fact that the .NET runtime is very large, I wouldn&#39;t consider this a good idea (Not to mention it&#39;s super boring). </p>
<p>The better solution is to use .NET&#39;s (experimental) AOT compilation feature (formerly called CoreRT). C# has had a number of attempts at an AOT compiler such as :</p>
<ul>
<li><a href="https://www.mono-project.com/docs/advanced/aot/">AOT</a> by Mono</li>
<li>LLD2CPP built by Unity</li>
<li><a href="https://docs.microsoft.com/en-us/dotnet/core/deploying/ready-to-run">Ready2Run</a> by Microsoft</li>
</ul>
<p>We&#39;ll be using the official Ready2Run AOT compilation built by Microsoft. In order to use it, all you have to do is add the following to your <code>nuget.config</code>:</p>
<pre><code class="lang-xml">&lt;<span class="hljs-keyword">add</span> key=<span class="hljs-string">"nuget.org"</span> <span class="hljs-keyword">value</span>=<span class="hljs-string">"https://api.nuget.org/v3/index.json"</span> protocolVersion=<span class="hljs-string">"3"</span> /&gt;
</code></pre>
<p>and then install the package: <code>Microsoft.DotNet.ILCompiler</code>. After doing that if you run the command: <code>dotnet publish -r [Runtime] -c [Config]</code> and after waiting a considerable amount of time, you&#39;ll have a full-fledged C# application compiled directly to your target runtime&#39;s bytecode!</p>
<p>Compiling my simple Hello, Wold test to linux-x64 (<code>dotnet publish -r linux-x64 -c Release</code>) and adding it to my project files should let me run it using the same method Arpan used in his blog.</p>
<p>After doing that, we can follow the instructions followed by Arpan and viola! C# runs on Gradescope!</p>
<p>I don&#39;t recommend this but it was fun to do and I needed stuff to write in a blog. </p>
<h2 id="other-interesting-low-level-c-net-features">Other Interesting (Low Level) C#/.NET Features</h2>
<p>C# actually has many lower level features people don&#39;t expect it to have. Some of these include pointers and direct memory management. Pointers can be enabled by encasing your code in an unsafe code block.</p>
<p>Example (Written by <a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/unsafe-code">Microsoft</a>)</p>
<pre><code class="lang-csharp">
<span class="hljs-comment">// Normal pointer to an object.</span>
<span class="hljs-keyword">int</span>[] a = <span class="hljs-keyword">new</span> <span class="hljs-keyword">int</span>[<span class="hljs-number">5</span>] { <span class="hljs-number">10</span>, <span class="hljs-number">20</span>, <span class="hljs-number">30</span>, <span class="hljs-number">40</span>, <span class="hljs-number">50</span> };
<span class="hljs-comment">// Must be in unsafe code to use interior pointers.</span>
unsafe
{
<span class="hljs-comment">// Must pin object on heap so that it doesn't move while using interior pointers.</span>
fixed (<span class="hljs-keyword">int</span>* p = &amp;a[<span class="hljs-number">0</span>])
{
<span class="hljs-comment">// p is pinned as well as object, so create another pointer to show incrementing it.</span>
<span class="hljs-keyword">int</span>* p2 = p;
<span class="hljs-built_in">Console</span>.WriteLine(*p2);
<span class="hljs-comment">// Incrementing p2 bumps the pointer by four bytes due to its type ...</span>
p2 += <span class="hljs-number">1</span>;
<span class="hljs-built_in">Console</span>.WriteLine(*p2);
p2 += <span class="hljs-number">1</span>;
<span class="hljs-built_in">Console</span>.WriteLine(*p2);
<span class="hljs-built_in">Console</span>.WriteLine(<span class="hljs-string">"--------"</span>);
<span class="hljs-built_in">Console</span>.WriteLine(*p);
<span class="hljs-comment">// Dereferencing p and incrementing changes the value of a[0] ...</span>
*p += <span class="hljs-number">1</span>;
<span class="hljs-built_in">Console</span>.WriteLine(*p);
*p += <span class="hljs-number">1</span>;
<span class="hljs-built_in">Console</span>.WriteLine(*p);
}
}
</code></pre>
<p>In .NET 6, the <code>NativeMemory</code> class was introduced which you can read about <a href="https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.nativememory.alloc?view=net-6.0">here</a>. It allows for malloc-like memory allocation and freeing which can be important for high-performance workloads.</p>
<footer>
<hr />
<p style="margin-bottom: 0px;">Copyright &#169; Nicholas Orlowsky 2023</p>
<p style="margin-top: 0px;">Hosting provided by <a href="https://nws.nickorlow.com">NWS</a></p>
</footer>
</body>

View file

@ -0,0 +1,38 @@
<head>
<title>Nicholas Orlowsky</title>
<link rel="stylesheet" href="/style.css">
<link rel="icon" type="image/x-icon" href="/favicon.ico">
</head>
<body>
<nav>
<a href="/">[ Home ]</a>
<a href="/blog.html">[ Blog ]</a>
<a href="/projects.html">[ Projects ]</a>
<a href="/extra.html">[ Extra ]</a>
<hr/>
</nav>
<h1>Side Project Log 3/20/2023</h1>
<p>Spring break just wrapped up. I wrote a <a href="">blog</a> last week about the side projects that I was planning on
doing. I wanted to provide an update on what I got done, and figured I&#39;d turn it into a recurring thing.</p>
<p>This side project log covers work done from 3/13/2023 - 3/20/2023</p>
<h2 id="-personal-website-facelift-https-github-com-nickorlow-personal-site-"><a href="https://github.com/nickorlow/personal-site">Personal Website Facelift</a></h2>
<p>I managed to move my website over to tab-based navigation pretty early on in the break. It just involved setting
up a navbar component and then using react-navigation to navigate between pages. I also managed to
update my projects page to be more compact and readable. </p>
<p>There is still work to be done on making it look better, but I mostly believe that
it&#39;s just going to be somewhat minor tweaks.</p>
<h2 id="-mahantongo-https-github-com-nickorlow-mahantongo-"><a href="https://github.com/nickorlow/mahantongo">Mahantongo</a></h2>
<p>I managed to finish this one. I learned a lot about Rust and I&#39;ve gained an appreciation for
Rust&#39;s enforcement of good programming habits, and I really like how error handling is done.</p>
<p>Working with Serenity was pretty easy as it mirrored some of the other Discord SDKs I&#39;ve used
before.</p>
<hr>
<p><strong>The below projects had minimal/no work done on them:</strong> RingGold, NWS Container Deployment Service, and VerifiedBot </p>
<footer>
<hr />
<p style="margin-bottom: 0px;">Copyright &#169; Nicholas Orlowsky 2023</p>
<p style="margin-top: 0px;">Hosting provided by <a href="https://nws.nickorlow.com">NWS</a></p>
</footer>
</body>

View file

@ -0,0 +1,38 @@
<head>
<title>Nicholas Orlowsky</title>
<link rel="stylesheet" href="/style.css">
<link rel="icon" type="image/x-icon" href="/favicon.ico">
</head>
<body>
<nav>
<a href="/">[ Home ]</a>
<a href="/blog.html">[ Blog ]</a>
<a href="/projects.html">[ Projects ]</a>
<a href="/extra.html">[ Extra ]</a>
<hr/>
</nav>
<h1>Side Project Log 3/27/2023</h1>
<p>This side project log covers work done from 3/20/2023 - 3/27/2023</p>
<h2 id="septa-site">SEPTA Site</h2>
<p>I started a new project that aimed to recreate parts of SEPTA&#39;s website with a more elegant UI, and using
SEPTA&#39;s new &quot;SEPTA Metro&quot; wayfinding. The main goal with this project was to help me learn Svelte. I also had
to reverse-engineer the APIs on septakey.org in order to authenticate a user and get their trip history. </p>
<p>In terms of Svelte, I really enjoyed working with it and overall I found it much more elegant and easier to work
with than React. I didn&#39;t like the way it handled client-server interaction with its serverside functions. </p>
<p>I have not made this open source yet and do not intend to until it&#39;s more polished.</p>
<h2 id="-verified-bot-https-github-com-benaubin-verified-bot-"><a href="https://github.com/benaubin/verified-bot">Verified Bot</a></h2>
<p>I made all the necessary changes and tests to get VerifiedBot working. It is now waiting on my friend Ben
to merge my PR with the changes outlined in my <a href="https://nickorlow.com/blog/spring-break-2023">spring break blog</a>.</p>
<h2 id="-mahantongo-https-github-com-nickorlow-mahantongo-"><a href="https://github.com/nickorlow/mahantongo">Mahantongo</a></h2>
<p>I created some QoL features, such as using Discord&#39;s embeds instead of sending regular text messages, showing which board
a post was on, and fixing some bugs.</p>
<hr>
<p><strong>The below projects had minimal/no work done on them:</strong> RingGold, and NWS Container Deployment Service </p>
<footer>
<hr />
<p style="margin-bottom: 0px;">Copyright &#169; Nicholas Orlowsky 2023</p>
<p style="margin-top: 0px;">Hosting provided by <a href="https://nws.nickorlow.com">NWS</a></p>
</footer>
</body>

View file

@ -0,0 +1,46 @@
<head>
<title>Nicholas Orlowsky</title>
<link rel="stylesheet" href="/style.css">
<link rel="icon" type="image/x-icon" href="/favicon.ico">
</head>
<body>
<nav>
<a href="/">[ Home ]</a>
<a href="/blog.html">[ Blog ]</a>
<a href="/projects.html">[ Projects ]</a>
<a href="/extra.html">[ Extra ]</a>
<hr/>
</nav>
<h1>Side Project Log 4/29/2023</h1>
<p>This side project log covers work done from 3/27/2023 - 4/29/2023</p>
<p>This side project log is a bit late due to it being a busy month of school, but today is my last day!</p>
<h2 id="septa-site">SEPTA Site</h2>
<p>This week, I published SEPTA Site on Github, you can find it here: <a href="https://github.com/nickorlow/septa-site">github.com/nickorlow/septa-site</a>.</p>
<p>I made a few tweaks to it in terms of styling and also wrote a descriptive README to give people instructions on how to run it as I don&#39;t want
to host it myself since it handles credentials from another service.</p>
<h2 id="squirrel">SQUIRREL</h2>
<p>SQUIRREL, short for SQL Query Util-Izing Rust&#39;s Reliable and Efficient Logic, is a SQL database that I am writing in Rust. Currently, it can
parse CREATE TABLE commands, and works with the data types varchar and int. I plan to implement basic CRUD operations, then add JOINs, and
then try to make it wire-compatible with Postgres.</p>
<p>This project is currently not open-sourced as I am waiting to add more features and polish it up more.</p>
<h2 id="swole-control">Swole Control</h2>
<p>This one isn&#39;t a <em>personal</em> project, however it is a project that I worked on with a group. We began working on it in February as a part of a
club at UT called Texas Convergent. We recently presented it at the club&#39;s demo day and won the prize for having the best business.</p>
<p>Swole Control is an app that monitors machine usage at a gym on a machine-by-machine level, providing gym goers with information about what machines
are free (this is a major pain point as a gym goer myself). It also provides gym owners with statistics on which machines are most popular, providing
them valuable insights into their business.</p>
<p>To achieve this, we built hardware that consisted of an ESP-32 micro controller and an ultrasonic distance sensor. This hardware is mounted on a gym machine
and it measures the distance to the nearest object. It then sends this measurement to a Rust backend which stores it in a Firestore database (although we had
a fork of it that worked with Postgres). The backend then uses these measurements and compares them to a baseline to determine if there is a user at a machine.
Our mobile app then reads this from the Firestore database (it&#39;s planned to have it read this from the API to have a better-defined application boundary). The
frontend is written in React Native.</p>
<hr>
<p><strong>These projects had minimal/no work done on them:</strong> RingGold, and NWS Container Deployment Service</p>
<footer>
<hr />
<p style="margin-bottom: 0px;">Copyright &#169; Nicholas Orlowsky 2023</p>
<p style="margin-top: 0px;">Hosting provided by <a href="https://nws.nickorlow.com">NWS</a></p>
</footer>
</body>

View file

@ -0,0 +1,91 @@
<head>
<title>Nicholas Orlowsky</title>
<link rel="stylesheet" href="/style.css">
<link rel="icon" type="image/x-icon" href="/favicon.ico">
</head>
<body>
<nav>
<a href="/">[ Home ]</a>
<a href="/blog.html">[ Blog ]</a>
<a href="/projects.html">[ Projects ]</a>
<a href="/extra.html">[ Extra ]</a>
<hr/>
</nav>
<h1>Side Project Log 7/12/2023</h1>
<p>This side project log covers work done from 4/29/2023 - 7/12/2023</p>
<p>This side project log is more than a bit late due to working a busy summer internship at <a href="https://futo.org">FUTO</a>!</p>
<h2 id="nws-container-deployment-service">NWS Container Deployment Service</h2>
<p>I have finally added SSL to NWS CDS. This was challenging, as it required handling ACME challenges and certificate
distribution across a set of geo-distributed Kubernetes clusters. I detail the complexities of this in a <a href="http://nickorlow.com/blog/ssl-in-nws-cds">previous blog
I wrote</a>. In order to implement auto-created/auto-renewing SSL, I implemented the below solution:</p>
<p><img src="/blog-images/NWS_SSL_Diagram.png" alt="Diagram of NWS SSL Architecture"></p>
<p>First, a user creates a request to add SSL to their NWS CDS service through the web UI which calls the NWS API (not pictured)</p>
<p>Then, the NWS API calls SSLiaison (in-house written software) which adds the domain to Caddy&#39;s list of domains. Caddy will then attempt to create
an SSL certificate from an ACME server (not pictured).</p>
<p>The ACME server will query NWS for the challenge response by requesting a file at <code>/.well-known/acme-challenge</code> on the
domain to be verified (this is the green arrows). </p>
<p>HAProxy will re-route these requests to NWS Hill Country, which is where the NWS Management Engine (NWSME) lives (this is
the orange arrows). <em>(NWSME controls what&#39;s deployed on each k8s cluster on NWS)</em></p>
<p>HAProxy in NWS Hill Country will then route this request to Caddy, which will solve the <a href="https://letsencrypt.org/docs/challenge-types/">http-01 challenge</a>, and then get the certificate
from the ACME server. Once it does this, it will write the certificate to a directory that is bind-mounted to both Caddy
and SSLiaison. </p>
<p>SSLiaison will detect this new file, parse it into a k8s manifest file, and then add it to our GitOps repo which is
hosted in GitHub.</p>
<p>From here, the certificate will be added to all the k8s clusters via Rancher Fleet.</p>
<hr>
<p>For next steps, I&#39;d like to revise this solution such that it doesn&#39;t have a single point of failure.
Currently, if NWS Hill Country is down (which it is about 0.025% of the time), then SSL certificates
won&#39;t be able to be created or renewed. </p>
<p>To do this, I will have SSLiaison implement the ACME client specification so that it can create and respond do ACME HTTP challenges.
SSLiaison will run on NWS CDS (so that it&#39;s running on all of our k8s clusters and is HA) instead of running as a standalone docker container.
I&#39;ll have SSLiaison use some distributed database (probably CockroachDB) to store the HTTP challenges so that it doesn&#39;t matter
which k8s cluster the challenge request from the ACME server is routed to.</p>
<h2 id="next-steps-for-nws">Next Steps for NWS</h2>
<ul>
<li><strong>HA NWS Management Engine:</strong> Currently (as somewhat discussed above), the NWSME will go down when NWS Hill Country goes down. I&#39;d like to
make it so that this isn&#39;t the case. This would likely just require that each NWS cluster runs its own instance of Rancher Fleet instead
of one central Rancher Fleet that manages all the clusters. It would also require the HA SSLiaison.</li>
</ul>
<ul>
<li><strong>IaC for Everything:</strong> Currently, all NWS CDS services are defined in yaml files in a git repo, however the underlying infrastructure that
it runs on is not. Ideally, I&#39;d like every NWS machine to run Proxmox and then have Terraform &amp; Ansible configs to define how to set up
vms on proxmox that will run the k8s clusters that support CDS services. This should eliminate my headaches of sshing into each machine
to apply config changes and make sure everything is standardized. It should also make the process of setting up new servers easy.</li>
</ul>
<ul>
<li><strong>Monitoring:</strong> I&#39;ve been working on setting up monitoring on a lot of our services at my current internship using the TIG stack (Telegraf,
InfluxDB, and Grafana). Now that I&#39;ve been exposed to the usefulness of having a bunch of metrics on hand, I think it would be nice to have
some dashboards setup for NWS to monitor speed, resource usage, uptime, and traffic. Doing this would also make it possible to expose resource usage in the
NWS dashboard.</li>
</ul>
<ul>
<li><p><strong>Enhanced Infrastructure:</strong> This is kind of a blanket one for things I want to do that don&#39;t fit into other categories. It includes making
hardware upgrades (mostly adding more storage), make management more accessible (such as Dell IDRAC&#39;s WebSerial), some load testing to
identify painpoints, run an NWS machine in a cloud VM so I can say it&#39;s cross cloud (although my friends have told me this is cheating at creating
my own cloud), and trying to figure out how to set up an Anycast network. I don&#39;t think I can setup an Anycast network without selling
a kidney first. Renting a /24 CIDR alone would be more than I want to spend on a side project. I may look into setting it up with ipv6 only,
however I&#39;d still have to jump through hoops to get an Autonomous System number from an RIR. I&#39;ll probably write a whole blog about Anycast
in the coming weeks.</p>
</li>
<li><p><strong>Reduced External Dependence:</strong> The main goal of NWS is to have no external dependence. In theory, everything but core internet infrastructure
should </p>
</li>
</ul>
<h2 id="olney">Olney</h2>
<p><code>Rust, ActixWeb, PostgreSQL</code></p>
<p>Olney is a new project I am starting with my friend <a href="https://sridharnandigam.com/">Sridhar Nandigam</a>. It aims to make
tracking your job applications easier. Most of my friends either use spreadsheets or Trello to track their job applications, I
think that we can make something that&#39;s a bit better for the job. Some features I&#39;d like to have are: resume version attached to
your application, job posting notifications from job boards such as <a href="github.com/pittcsc/summer2024-internships">pittcsc</a>, and watching
your email for emails from recruiters. Currently, I have part of the backend setup with basic CRUD operations. Now that I&#39;m done with
the latest batch of NWS work, this is next on my list to work on.</p>
<hr>
<p><strong>These projects had minimal/no work done on them:</strong> RingGold, SQUIRREL</p>
<footer>
<hr />
<p style="margin-bottom: 0px;">Copyright &#169; Nicholas Orlowsky 2023</p>
<p style="margin-top: 0px;">Hosting provided by <a href="https://nws.nickorlow.com">NWS</a></p>
</footer>
</body>

View file

@ -0,0 +1,78 @@
<head>
<title>Nicholas Orlowsky</title>
<link rel="stylesheet" href="/style.css">
<link rel="icon" type="image/x-icon" href="/favicon.ico">
</head>
<body>
<nav>
<a href="/">[ Home ]</a>
<a href="/blog.html">[ Blog ]</a>
<a href="/projects.html">[ Projects ]</a>
<a href="/extra.html">[ Extra ]</a>
<hr/>
</nav>
<h1>Spring Break 2023</h1>
<p>It&#39;s Spring Break, and that means I finally have time to spend all day working on side projects without having to worry about school.</p>
<p>I figured I should write out the side projects I plan to work on over the break</p>
<h2 id="ringgold">RingGold</h2>
<p><code>Rust, Swift, PostgreSQL</code></p>
<p>Last week, me and my cousin wanted to try out Apple&#39;s fitness competition feature that works with Apple Watch. It works
by giving you 1 point for every percent you complete of your move, exercise, and stand goals with a point cap of 600
per day. The issue with it was that it didn&#39;t work at all, not syncing on time if at all. I want to build a clone of it
with some additional features such as:</p>
<ul>
<li><p><strong>Notifications:</strong> I didn&#39;t like how it was possible to workout and gain a bunch of points and just completely blindside your opponent. Hopefully this would encourage users to workout even more.</p>
</li>
<li><p><strong>Widget/Watch Complication:</strong> Similar to the above, adding a homescreen widget or a watch complication would make it easier to keep up with your competitor&#39;s progress. </p>
</li>
<li><p><strong>Custom Competitions:</strong> I think it&#39;d be nice to have competitions with custom rules and lengths so that you&#39;re not stuck with only one setting. Settings could include custom duration and custom caps on points.</p>
</li>
</ul>
<p>I&#39;m building the web API for it in Rust and the mobile app in Swift. I chose these languages to gain more exposure to them, also
Swift was a good choice since the app is going to be platform specific to iOS due to its need to integrate with Apple Watch.
<em>(this is named after New Ringgold, PA)</em></p>
<h2 id="nws-container-deployment-service">NWS Container Deployment Service</h2>
<p><code>C#, Rancher</code></p>
<p>I&#39;ve created my own hosting/cloud service called <a href="https://nws.nickorlow.com">Nick Web Services</a>. It currently allows people to deploy
dockerized applications on my geo-distributed k8s clusters running on Dell Poweredge servers. In order to actually deploy this, I
had to manually create the Kubernetes manifest files and then ssh into each individual server and apply them. I&#39;ve setup
Rancher Fleet to automate this process by pulling the manifest from a git repo (this is something called gitops). I also
wrote an API to generate the manifest files and then upload them to a git repo. I have a video demo of this working that
you can watch <a href="https://youtu.be/WHdXWMFHuqA">here</a>.</p>
<p>Currently, the service works for deployment but only if you don&#39;t want to use SSL or you use Cloudflare&#39;s flexible SSL
technology. I wrote a separate blog post <a href="http://nickorlow.com/blog/ssl-in-nws-cds">here</a> about the challenges of doing this and how I plan on implementing it.
I&#39;d like to complete part of this implementation during the break.</p>
<h2 id="verifiedbot">VerifiedBot</h2>
<p><code>JavaScript, Rust</code></p>
<p>This project isn&#39;t a personal project, as a lot of it was built by my friends <a href="https://arpan.one">Arpan</a> and <a href="https://benaubin.com/">Ben</a>.
A little over a year ago, we wanted to make a Discord bot to verify that people on some Discord servers we ran
went to the University of Texas. Initially, it worked by verifying you had a utexas.edu email address and then verifying
some additional information via LDAP. A few months ago Ben found out that using the SaaS survey software that the university uses
(qualtrics), we could have users verify themselves by using the university&#39;s SSO system. This works because qualtrics can send
data to a webhook when a survey is complete, and it can also require signing in with the university&#39;s SSO before filling out a survey.
It required that I write a <a href="https://github.com/Verified-Bot/aes-gcm-siv-wasm">wasm wrapper for an encryption library</a>. I wrote almost all the code for this function last year, but
due to a bug in qualtrics, it wasn&#39;t working properly. It seems that this bug has been fixed and we can start rolling it out.</p>
<h2 id="personal-website-facelift">Personal Website Facelift</h2>
<p><code>Typescript, React</code></p>
<p>My personal website (this one) is a little overdue for some design updates. My main focus will be making it more mobile
friendly. Last year, I made some improvements to make it usable on mobile but it still doesn&#39;t feel quite right. I also
think that it has some information overload in some areas such as the projects section. I think that to mitigate this I
might just have a small summary of each project and then you can click into each to learn more about it, similar to my
friend <a href="https://raulhigareda.com">Raul&#39;s Website</a>. I&#39;m also considering a move to tab-based navigation so that I can have
more information in each section. Further down the line, I think I might re-write it using Svelte as I&#39;m seeing it being used more and more
and would like to get some exposure to it.</p>
<h2 id="mahantongo">Mahantongo</h2>
<p><code>Rust, PostgreSQL</code></p>
<p>I&#39;m one of the members of the Community Team that runs some UT Computer Science community Discord servers.
Currently, a Discord bot called Carlbot provides us a star-board, which is a specific channel where messages that 5 or more people
react to with a star emoji get posted. It&#39;s supposed to be a collection of the funniest and best messages sent on the server.
One of the things our server members have wanted is the addition of more &#39;*-board&#39; channels where you can create multiple star-board
like channels but with custom emojis. I&#39;m writing it in Rust and I&#39;m just hoping to use this project to get more acquainted with the language.</p>
<footer>
<hr />
<p style="margin-bottom: 0px;">Copyright &#169; Nicholas Orlowsky 2023</p>
<p style="margin-top: 0px;">Hosting provided by <a href="https://nws.nickorlow.com">NWS</a></p>
</footer>
</body>

77
out/extra.html Normal file
View file

@ -0,0 +1,77 @@
<head>
<title>Nicholas Orlowsky</title>
<link rel="stylesheet" href="/style.css">
<link rel="icon" type="image/x-icon" href="/favicon.ico">
</head>
<body>
<nav>
<a href="/">[ Home ]</a>
<a href="/blog.html">[ Blog ]</a>
<a href="/projects.html">[ Projects ]</a>
<a href="/extra.html">[ Extra ]</a>
<hr/>
</nav>
<div>
<h1 style="margin-bottom: 0px;">Extra</h1>
<p style="margin-top: 0px;">Extra bits of information about me</p>
<h2>Personal Records</h2>
<table style="width: 100%;">
<tr>
<th>Activity</th>
<th>Effort</th>
<th>Date</th>
<th>Location</th>
</tr>
<tr>
<td>1600m (1 mile)</td>
<td>4:34</td>
<td>November 14th, 2020</td>
<td>Williamson County Park</td>
</tr>
<tr>
<td>Milk Mile</td>
<td>5:41</td>
<td>May 20th, 2021</td>
<td>Lake Travis High School</td>
</tr>
<tr>
<td>3200m (2 mile)</td>
<td>10:11</td>
<td>March 20th, 2021</td>
<td>Carroll High School</td>
</tr>
<tr>
<td>5000m XC</td>
<td>16:43</td>
<td>September 26th, 2020</td>
<td>Old Settler's Park</td>
</tr>
<tr>
<td>Bench Press</td>
<td>275 Lbs</td>
<td>2023</td>
<td>Gregory Gym</td>
</tr>
<tr>
<td>Squat</td>
<td>405 Lbs</td>
<td>2023</td>
<td>Gregory Gym</td>
</tr>
<tr>
<td>Deadlift</td>
<td>405 Lbs</td>
<td>2023</td>
<td>Gregory Gym</td>
</tr>
</table>
</div>
<footer>
<hr />
<p style="margin-bottom: 0px;">Copyright &#169; Nicholas Orlowsky 2023</p>
<p style="margin-top: 0px;">Hosting provided by <a href="https://nws.nickorlow.com">NWS</a></p>
</footer>
</body>

BIN
out/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

52
out/index.html Normal file
View file

@ -0,0 +1,52 @@
<head>
<title>Nicholas Orlowsky</title>
<link rel="stylesheet" href="/style.css">
<link rel="icon" type="image/x-icon" href="/favicon.ico">
</head>
<body>
<nav>
<a href="/">[ Home ]</a>
<a href="/blog.html">[ Blog ]</a>
<a href="/projects.html">[ Projects ]</a>
<a href="/extra.html">[ Extra ]</a>
<hr/>
</nav>
<div>
<h1 style="margin-bottom: 0px;">Nicholas Orlowsky</h1>
<p style="margin-top: 0px;">Software Engineer - Austin, TX</p>
<p>
<a href="https://github.com/nickorlow">[ GitHub ]</a>
<a href="https://www.linkedin.com/in/nickorlow/">[ LinkedIn ]</a>
<a href="mailto:nickorlow@nickorlow.com">[ E-Mail ]</a>
<a href="https://github.com/nickorlow/resume/releases/download/latest/resume-nickorlow.pdf">[ Resume ]</a>
<!-- <a href="https://old.nickorlow.com">[ Old Website ]</a> -->
</p>
<p>
<a href="https://open.spotify.com/episode/7f0lB2alMuvpfsQfwtRpJB?si=a55a62f6921a4671">[ Listen to me on the Azure DevOps podcast! ]</a>
</p>
<p>
I'm a computer science student at the University of Texas at Austin. I'm particularly
interested in infrastructure, distributed systems, and systems programming.
</p>
<p>
I run <a href="https://nws.nickorlow.com">Nick Web Services (NWS)</a>, a side project
that provides geo-distributed container hosting using Kubernetes on bare metal servers.
It currently has 100% uptime YTD, surpassing the uptime percentage of competitor GitHub pages.
</p>
<p>
Outside of computers, I enjoy biking and weightlifting. I'm also a public transit enthusiast
and I take pictures of trains that I see, especially rare or special ones.
</p>
</div>
<footer>
<hr />
<p style="margin-bottom: 0px;">Copyright &#169; Nicholas Orlowsky 2023</p>
<p style="margin-top: 0px;">Hosting provided by <a href="https://nws.nickorlow.com">NWS</a></p>
</footer>
</body>

85
out/projects.html Normal file
View file

@ -0,0 +1,85 @@
<head>
<title>Nicholas Orlowsky</title>
<link rel="stylesheet" href="/style.css">
<link rel="icon" type="image/x-icon" href="/favicon.ico">
</head>
<body>
<nav>
<a href="/">[ Home ]</a>
<a href="/blog.html">[ Blog ]</a>
<a href="/projects.html">[ Projects ]</a>
<a href="/extra.html">[ Extra ]</a>
<hr/>
</nav>
<div>
<h1 style="margin-bottom: 0px;">Projects</h1>
<div>
<h2>Nick Web Services (NWS)</h2>
<a href="https://nws.nickorlow.com">[ Project Website ]</a>
<p>
Nick Web Services is a cloud infrastructure provider service that I created and run.
It allows people to deploy containerized versions of their web apps across our multiple
servers. It provides geo-distributed high availability by default with no extra configuration
needed from users hosting their webapp with us.
</p>
<p>
Hardware-wise we use old Dell PowerEdge servers running Proxmox. We then have VMs running
in Proxmox that run Kubernetes clusters. We have 4 clusters currently: Austin, Hill Country,
Schuylkill, and Philadelphia. The deployments are managed through GitOps with Rancher Fleet.
</p>
</div>
<div>
<h2>CavCash</h2>
<a href="https://cavcash.com">[ Project Website ]</a>
<p>
CavCash was a company that I founded which built a debit-based payment system similar to
PayPal and Venmo. I assembled a 5 person team and took on a technical role in the company,
writing most of our backend codebase. Our backend used C#, ASP.NET, Microsoft SQL Server,
and MongoDB. Our infrastructure changed throughout the lifetime of the company, initially
it was on Microsoft Azure using Azure App Service. We then pivoted to AWS using Elastic
Beanstalk. We also ran on Google Cloud Platform using Compute Engine. Finally, we setup our
own servers in-house and managed our deployments with Kubernetes.
</p>
<p>
We launched in 2021, with the ability to send money between real banks using the ACH network.
We ended up processing a few hundred dollars in transaction volume before ultimately shutting
down due to a lack of funding. The website is now back up and everything works as it did in
2021, except adding funds from a bank account is not supported.
</p>
</div>
<div>
<h2>SQUIRREL</h2>
<p>
SQUIRREL stands for SQL Query Util-Izing Rust's Reliable and Efficient Logic. It is a SQL database
that I am writing in Rust. Currently, it can parse CREATE TABLE commands, and works with the
data types varchar and int. I plan to implement basic CRUD operations, then add JOINs, and then
try to make it wire-compatible with Postgres.
</p>
</div>
<div>
<h2>SEPTA Site</h2>
<a href="https://github.com/nickorlow/septa-site">[ GitHub Repo ]</a>
<p>
SEPTA Site is a website that I created which can get your trip history, SEPTA Key balance,
and ridership statistics for your SEPTA Key. It utilizes SEPTA's new metro wayfinding instead
of their current wayfinding. I wrote the project to get a basic introduction to Svelte and
so that I could try to improve upon the UX of SEPTA's current website and mobile app.
</p>
</div>
<div style="width: 100%; display: flex; justify-content: center; padding: 5px;">
<a href="https://github.com/nickorlow">[ See more projects on GitHub ]</a>
</div>
</div>
<footer>
<hr />
<p style="margin-bottom: 0px;">Copyright &#169; Nicholas Orlowsky 2023</p>
<p style="margin-top: 0px;">Hosting provided by <a href="https://nws.nickorlow.com">NWS</a></p>
</footer>
</body>

22
out/style.css Normal file
View file

@ -0,0 +1,22 @@
* {
font-family: serif;
}
td {
text-align: center;
}
body {
background-color: #fefeaa;
margin: 20px auto;
max-width: 750px;
}
a {
text-decoration: none;
color: #114488;
}
img {
max-width: 100%;
}

40029
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,69 +0,0 @@
{
"name": "personal-site",
"version": "0.1.0",
"private": true,
"dependencies": {
"@material-ui/core": "^4.11.4",
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"@types/jest": "^26.0.15",
"@types/node": "^12.0.0",
"@types/react": "^17.0.0",
"@types/react-animate-on-scroll": "^2.1.2",
"@types/react-dom": "^17.0.0",
"@types/react-modal": "^3.13.1",
"@types/react-router-dom": "^5.3.3",
"@types/react-slick": "^0.23.4",
"@types/react-syntax-highlighter": "^13.5.2",
"@types/react-tabs": "^2.3.2",
"@types/react-typing-animation": "^1.6.2",
"bootstrap": "^4.6.0",
"pure-react-carousel": "^1.27.6",
"react": "^17.0.2",
"react-animate-on-scroll": "^2.1.5",
"react-bootstrap": "^1.6.1",
"react-dom": "^17.0.2",
"react-markdown": "^8.0.3",
"react-modal": "^3.16.1",
"react-responsive-carousel": "^3.2.23",
"react-router-dom": "^6.3.0",
"react-scripts": "4.0.3",
"react-slick": "^0.28.1",
"react-snapshot": "^1.3.0",
"react-syntax-highlighter": "^15.5.0",
"react-tabs": "^3.2.2",
"react-typing-animation": "^1.6.2",
"remarkable": "^2.0.1",
"style-loader": "^3.3.1",
"typescript": "^4.1.2",
"web-vitals": "^1.0.1"
},
"scripts": {
"start": "react-scripts --openssl-legacy-provider start",
"build": "react-scripts build && react-snapshot",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@types/react-snapshot": "^1.3.0"
}
}

View file

@ -1,26 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css"
integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l"
crossorigin="anonymous"
/>
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Nicholas Orlowsky's personal website"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<title>Nicholas Orlowsky</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app. (are you using an outdated browser or just very privacy focused?) <!-- or are you looking at the source?--></noscript>
<div id="root"></div>
</body>
</html>

View file

@ -1,8 +0,0 @@
{
"short_name": "personal-site",
"name": "My personal website",
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

View file

@ -1,3 +0,0 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

View file

@ -1,148 +0,0 @@
.App {
text-align: center;
background-color: black;
min-height: 100vh;
width: 100vw !important;
max-width: 100vw !important;
font-size: calc(20px);
color: white;
}
.row {
margin: 0 !important;
}
html {
background-color: black;
}
.fade-down-d3s {
opacity: 0;
animation: fade-down-anim 2s forwards 3s;
}
h1 {
font-weight: bolder;
}
@keyframes fade-up-anim {
0% {
opacity: 0;
transform: translateY(40px);
}
100% {
opacity:1;
transform: translateY(0px);
}
}
@keyframes fade-down-anim {
0% {
opacity: 0;
transform: translateY(-40px);
}
100% {
opacity:1;
transform: translateY(0px);
}
}
@media only screen and (max-width: 993px) {
.fade-up-md {
opacity: 0;
animation: fade-up-anim 2s forwards 200ms !important;
}
.fade-up-md-2 {
opacity: 0;
animation: fade-up-anim 2s forwards 400ms !important;
}
.fade-up-md-3 {
opacity: 0;
animation: fade-up-anim 2s forwards 600ms !important;
}
}
@media only screen and (min-width: 768px) {
.fade-up {
opacity: 0;
animation: fade-up-anim 2s forwards 200ms;
}
.fade-up-2 {
opacity: 0;
animation: fade-up-anim 2s forwards 400ms;
}
.fade-up-3 {
opacity: 0;
animation: fade-up-anim 2s forwards 600ms;
}
}
.fade-up {
opacity: 0;
animation: fade-up-anim 2s forwards 200ms;
}
.fade-up-d3s {
opacity: 0;
animation: fade-up-anim 2s forwards 3s;
}
@keyframes fade-in-tx-anim {
0% {
opacity: 0;
}
100% {
opacity:1;
}
}
.fade-in-tx {
animation: fade-in-tx-anim 1s ease-in;
}
@keyframes fade-out{
0% {
opacity: 1;
z-index: 500;
}
99% {
opacity: .1;
z-index: 500;
}
100% {
opacity:0;
z-index: -500;
display: none;
visibility: hidden;
}
}
.fade-out {
animation: fade-out 1s ease-in forwards;
opacity: 0;
}
@keyframes move-left-atx-anim {
0% {
margin-left: 0;
}
100% {
margin-left: -17px;
}
}
.move-left-atx {
animation: move-left-atx-anim 1s forwards;
}
.pfp {
border-radius: 100%;
width: 25%
}

View file

@ -1,9 +0,0 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import App from './App';
test('renders learn react link', () => {
render(<App />);
const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});

View file

@ -1,14 +0,0 @@
import React, {useState} from 'react';
import './App.css';
import Main from "./Main";
function App() {
return (
<div className="App">
<Main/>
</div>
);
}
export default App;

View file

@ -1,45 +0,0 @@
import React from 'react';
import { Routes, Route } from 'react-router-dom';
import Home from './pages/Home';
import SingleBlog from "./pages/SingleBlog";
import Navbar from "./components/navbar/Navbar";
import Hero from "./components/hero/Hero";
import AboutMe from "./components/about-me/AboutMe";
import Contact from "./components/contact/Contact";
import Hobbies from "./components/hobbies/Hobbies";
import Projects from "./components/projects/Projects";
import Blogs from "./components/blogs/Blogs";
const NavBarView = (props: {children: any}) => {
return (
<div>
<Navbar/>
<div style={{height: "95vh"}}>
{props.children}
</div>
</div>
)
}
const Main = () => {
return (
<div>
<Routes>
<Route element={<NavBarView><Hero/></NavBarView>} path='/'/>
<Route element={<NavBarView><Hero/></NavBarView>} path='/home'/>
<Route element={<NavBarView><AboutMe/></NavBarView>} path='/about'/>
<Route element={<NavBarView><Contact/></NavBarView>} path='/contact'/>
<Route element={<NavBarView><Hobbies/></NavBarView>} path='/hobbies'/>
<Route element={<NavBarView><Projects/></NavBarView>} path='/projects'/>
<Route element={<NavBarView><Blogs/></NavBarView>} path='/blogs'/>
<Route element={<SingleBlog/>} path='/blog/*'/>
</Routes>
</div>
);
}
export default Main;

11
src/blog.filler.html Normal file
View file

@ -0,0 +1,11 @@
<div>
<h1 style="margin-bottom: 0px;">Blog</h1>
<p style="margin-top: 0px;">A collection of my thoughts, some of them may be interesting</p>
<p><a href="./blogs/side-project-7-12-23.html">[ Side Project Log 7/12/23 ]</a> - July 12th, 2023</p>
<p><a href="./blogs/side-project-4-29-23.html">[ Side Project Log 4/29/23 ]</a> - April 29th, 2023</p>
<p><a href="./blogs/side-project-3-27-23.html">[ Side Project Log 3/27/23 ]</a> - March 27th, 2023</p>
<p><a href="./blogs/side-project-3-20-23.html">[ Side Project Log 3/20/23 ]</a> - March 20th, 2023</p>
<p><a href="./blogs/spring-break-2023.html">[ Spring Break 2023 ]</a> - January 20th, 2023</p>
<p><a href="./blogs/doing-c-assignments-in-csharp.html">[ Doing C assignments in C# ]</a> - March 18th, 2022</p>
</div>

View file

@ -0,0 +1,52 @@
<h1>Doing C assignments in C#</h1>
<p>Thanks to Arpan Dhatt for doing most of the work on this (his blog here: <a href="https://arpan.one/posts/messing-with-gradescope/">https://arpan.one/posts/messing-with-gradescope/</a>)</p>
<p>At the end, he made this comment:</p>
<blockquote>
<p>And so, that&#39;s the end of this post. To whom it may concern, don&#39;t try doing your C assignment in C# (you know who you are).</p>
</blockquote>
<p>The reason for this comment (besides the fact that I talk about C# a lot) is due to the fact that C# requires a runtime to be installed for it to work. This is because C# does not compile to native bytecode but rather compiles to an intermediary language (dubbed CIL by Microsoft) and is then translated &#39;Just In Time&#39; by the runtime. </p>
<p>This makes running assignments in a docker container where the runtime is not already installed considerably hard. One option we have is that we could just include the runtime in our submission. Sounds easy, right? Well it would be non-trivial to do but due to the fact that the .NET runtime is very large, I wouldn&#39;t consider this a good idea (Not to mention it&#39;s super boring). </p>
<p>The better solution is to use .NET&#39;s (experimental) AOT compilation feature (formerly called CoreRT). C# has had a number of attempts at an AOT compiler such as :</p>
<ul>
<li><a href="https://www.mono-project.com/docs/advanced/aot/">AOT</a> by Mono</li>
<li>LLD2CPP built by Unity</li>
<li><a href="https://docs.microsoft.com/en-us/dotnet/core/deploying/ready-to-run">Ready2Run</a> by Microsoft</li>
</ul>
<p>We&#39;ll be using the official Ready2Run AOT compilation built by Microsoft. In order to use it, all you have to do is add the following to your <code>nuget.config</code>:</p>
<pre><code class="lang-xml">&lt;<span class="hljs-keyword">add</span> key=<span class="hljs-string">"nuget.org"</span> <span class="hljs-keyword">value</span>=<span class="hljs-string">"https://api.nuget.org/v3/index.json"</span> protocolVersion=<span class="hljs-string">"3"</span> /&gt;
</code></pre>
<p>and then install the package: <code>Microsoft.DotNet.ILCompiler</code>. After doing that if you run the command: <code>dotnet publish -r [Runtime] -c [Config]</code> and after waiting a considerable amount of time, you&#39;ll have a full-fledged C# application compiled directly to your target runtime&#39;s bytecode!</p>
<p>Compiling my simple Hello, Wold test to linux-x64 (<code>dotnet publish -r linux-x64 -c Release</code>) and adding it to my project files should let me run it using the same method Arpan used in his blog.</p>
<p>After doing that, we can follow the instructions followed by Arpan and viola! C# runs on Gradescope!</p>
<p>I don&#39;t recommend this but it was fun to do and I needed stuff to write in a blog. </p>
<h2 id="other-interesting-low-level-c-net-features">Other Interesting (Low Level) C#/.NET Features</h2>
<p>C# actually has many lower level features people don&#39;t expect it to have. Some of these include pointers and direct memory management. Pointers can be enabled by encasing your code in an unsafe code block.</p>
<p>Example (Written by <a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/unsafe-code">Microsoft</a>)</p>
<pre><code class="lang-csharp">
<span class="hljs-comment">// Normal pointer to an object.</span>
<span class="hljs-keyword">int</span>[] a = <span class="hljs-keyword">new</span> <span class="hljs-keyword">int</span>[<span class="hljs-number">5</span>] { <span class="hljs-number">10</span>, <span class="hljs-number">20</span>, <span class="hljs-number">30</span>, <span class="hljs-number">40</span>, <span class="hljs-number">50</span> };
<span class="hljs-comment">// Must be in unsafe code to use interior pointers.</span>
unsafe
{
<span class="hljs-comment">// Must pin object on heap so that it doesn't move while using interior pointers.</span>
fixed (<span class="hljs-keyword">int</span>* p = &amp;a[<span class="hljs-number">0</span>])
{
<span class="hljs-comment">// p is pinned as well as object, so create another pointer to show incrementing it.</span>
<span class="hljs-keyword">int</span>* p2 = p;
<span class="hljs-built_in">Console</span>.WriteLine(*p2);
<span class="hljs-comment">// Incrementing p2 bumps the pointer by four bytes due to its type ...</span>
p2 += <span class="hljs-number">1</span>;
<span class="hljs-built_in">Console</span>.WriteLine(*p2);
p2 += <span class="hljs-number">1</span>;
<span class="hljs-built_in">Console</span>.WriteLine(*p2);
<span class="hljs-built_in">Console</span>.WriteLine(<span class="hljs-string">"--------"</span>);
<span class="hljs-built_in">Console</span>.WriteLine(*p);
<span class="hljs-comment">// Dereferencing p and incrementing changes the value of a[0] ...</span>
*p += <span class="hljs-number">1</span>;
<span class="hljs-built_in">Console</span>.WriteLine(*p);
*p += <span class="hljs-number">1</span>;
<span class="hljs-built_in">Console</span>.WriteLine(*p);
}
}
</code></pre>
<p>In .NET 6, the <code>NativeMemory</code> class was introduced which you can read about <a href="https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.nativememory.alloc?view=net-6.0">here</a>. It allows for malloc-like memory allocation and freeing which can be important for high-performance workloads.</p>

View file

@ -0,0 +1,17 @@
<h1>Side Project Log 3/20/2023</h1>
<p>Spring break just wrapped up. I wrote a <a href="">blog</a> last week about the side projects that I was planning on
doing. I wanted to provide an update on what I got done, and figured I&#39;d turn it into a recurring thing.</p>
<p>This side project log covers work done from 3/13/2023 - 3/20/2023</p>
<h2 id="-personal-website-facelift-https-github-com-nickorlow-personal-site-"><a href="https://github.com/nickorlow/personal-site">Personal Website Facelift</a></h2>
<p>I managed to move my website over to tab-based navigation pretty early on in the break. It just involved setting
up a navbar component and then using react-navigation to navigate between pages. I also managed to
update my projects page to be more compact and readable. </p>
<p>There is still work to be done on making it look better, but I mostly believe that
it&#39;s just going to be somewhat minor tweaks.</p>
<h2 id="-mahantongo-https-github-com-nickorlow-mahantongo-"><a href="https://github.com/nickorlow/mahantongo">Mahantongo</a></h2>
<p>I managed to finish this one. I learned a lot about Rust and I&#39;ve gained an appreciation for
Rust&#39;s enforcement of good programming habits, and I really like how error handling is done.</p>
<p>Working with Serenity was pretty easy as it mirrored some of the other Discord SDKs I&#39;ve used
before.</p>
<hr>
<p><strong>The below projects had minimal/no work done on them:</strong> RingGold, NWS Container Deployment Service, and VerifiedBot </p>

View file

@ -0,0 +1,17 @@
<h1>Side Project Log 3/27/2023</h1>
<p>This side project log covers work done from 3/20/2023 - 3/27/2023</p>
<h2 id="septa-site">SEPTA Site</h2>
<p>I started a new project that aimed to recreate parts of SEPTA&#39;s website with a more elegant UI, and using
SEPTA&#39;s new &quot;SEPTA Metro&quot; wayfinding. The main goal with this project was to help me learn Svelte. I also had
to reverse-engineer the APIs on septakey.org in order to authenticate a user and get their trip history. </p>
<p>In terms of Svelte, I really enjoyed working with it and overall I found it much more elegant and easier to work
with than React. I didn&#39;t like the way it handled client-server interaction with its serverside functions. </p>
<p>I have not made this open source yet and do not intend to until it&#39;s more polished.</p>
<h2 id="-verified-bot-https-github-com-benaubin-verified-bot-"><a href="https://github.com/benaubin/verified-bot">Verified Bot</a></h2>
<p>I made all the necessary changes and tests to get VerifiedBot working. It is now waiting on my friend Ben
to merge my PR with the changes outlined in my <a href="https://nickorlow.com/blog/spring-break-2023">spring break blog</a>.</p>
<h2 id="-mahantongo-https-github-com-nickorlow-mahantongo-"><a href="https://github.com/nickorlow/mahantongo">Mahantongo</a></h2>
<p>I created some QoL features, such as using Discord&#39;s embeds instead of sending regular text messages, showing which board
a post was on, and fixing some bugs.</p>
<hr>
<p><strong>The below projects had minimal/no work done on them:</strong> RingGold, and NWS Container Deployment Service </p>

View file

@ -0,0 +1,25 @@
<h1>Side Project Log 4/29/2023</h1>
<p>This side project log covers work done from 3/27/2023 - 4/29/2023</p>
<p>This side project log is a bit late due to it being a busy month of school, but today is my last day!</p>
<h2 id="septa-site">SEPTA Site</h2>
<p>This week, I published SEPTA Site on Github, you can find it here: <a href="https://github.com/nickorlow/septa-site">github.com/nickorlow/septa-site</a>.</p>
<p>I made a few tweaks to it in terms of styling and also wrote a descriptive README to give people instructions on how to run it as I don&#39;t want
to host it myself since it handles credentials from another service.</p>
<h2 id="squirrel">SQUIRREL</h2>
<p>SQUIRREL, short for SQL Query Util-Izing Rust&#39;s Reliable and Efficient Logic, is a SQL database that I am writing in Rust. Currently, it can
parse CREATE TABLE commands, and works with the data types varchar and int. I plan to implement basic CRUD operations, then add JOINs, and
then try to make it wire-compatible with Postgres.</p>
<p>This project is currently not open-sourced as I am waiting to add more features and polish it up more.</p>
<h2 id="swole-control">Swole Control</h2>
<p>This one isn&#39;t a <em>personal</em> project, however it is a project that I worked on with a group. We began working on it in February as a part of a
club at UT called Texas Convergent. We recently presented it at the club&#39;s demo day and won the prize for having the best business.</p>
<p>Swole Control is an app that monitors machine usage at a gym on a machine-by-machine level, providing gym goers with information about what machines
are free (this is a major pain point as a gym goer myself). It also provides gym owners with statistics on which machines are most popular, providing
them valuable insights into their business.</p>
<p>To achieve this, we built hardware that consisted of an ESP-32 micro controller and an ultrasonic distance sensor. This hardware is mounted on a gym machine
and it measures the distance to the nearest object. It then sends this measurement to a Rust backend which stores it in a Firestore database (although we had
a fork of it that worked with Postgres). The backend then uses these measurements and compares them to a baseline to determine if there is a user at a machine.
Our mobile app then reads this from the Firestore database (it&#39;s planned to have it read this from the API to have a better-defined application boundary). The
frontend is written in React Native.</p>
<hr>
<p><strong>These projects had minimal/no work done on them:</strong> RingGold, and NWS Container Deployment Service</p>

View file

@ -0,0 +1,70 @@
<h1>Side Project Log 7/12/2023</h1>
<p>This side project log covers work done from 4/29/2023 - 7/12/2023</p>
<p>This side project log is more than a bit late due to working a busy summer internship at <a href="https://futo.org">FUTO</a>!</p>
<h2 id="nws-container-deployment-service">NWS Container Deployment Service</h2>
<p>I have finally added SSL to NWS CDS. This was challenging, as it required handling ACME challenges and certificate
distribution across a set of geo-distributed Kubernetes clusters. I detail the complexities of this in a <a href="http://nickorlow.com/blog/ssl-in-nws-cds">previous blog
I wrote</a>. In order to implement auto-created/auto-renewing SSL, I implemented the below solution:</p>
<p><img src="/blog-images/NWS_SSL_Diagram.png" alt="Diagram of NWS SSL Architecture"></p>
<p>First, a user creates a request to add SSL to their NWS CDS service through the web UI which calls the NWS API (not pictured)</p>
<p>Then, the NWS API calls SSLiaison (in-house written software) which adds the domain to Caddy&#39;s list of domains. Caddy will then attempt to create
an SSL certificate from an ACME server (not pictured).</p>
<p>The ACME server will query NWS for the challenge response by requesting a file at <code>/.well-known/acme-challenge</code> on the
domain to be verified (this is the green arrows). </p>
<p>HAProxy will re-route these requests to NWS Hill Country, which is where the NWS Management Engine (NWSME) lives (this is
the orange arrows). <em>(NWSME controls what&#39;s deployed on each k8s cluster on NWS)</em></p>
<p>HAProxy in NWS Hill Country will then route this request to Caddy, which will solve the <a href="https://letsencrypt.org/docs/challenge-types/">http-01 challenge</a>, and then get the certificate
from the ACME server. Once it does this, it will write the certificate to a directory that is bind-mounted to both Caddy
and SSLiaison. </p>
<p>SSLiaison will detect this new file, parse it into a k8s manifest file, and then add it to our GitOps repo which is
hosted in GitHub.</p>
<p>From here, the certificate will be added to all the k8s clusters via Rancher Fleet.</p>
<hr>
<p>For next steps, I&#39;d like to revise this solution such that it doesn&#39;t have a single point of failure.
Currently, if NWS Hill Country is down (which it is about 0.025% of the time), then SSL certificates
won&#39;t be able to be created or renewed. </p>
<p>To do this, I will have SSLiaison implement the ACME client specification so that it can create and respond do ACME HTTP challenges.
SSLiaison will run on NWS CDS (so that it&#39;s running on all of our k8s clusters and is HA) instead of running as a standalone docker container.
I&#39;ll have SSLiaison use some distributed database (probably CockroachDB) to store the HTTP challenges so that it doesn&#39;t matter
which k8s cluster the challenge request from the ACME server is routed to.</p>
<h2 id="next-steps-for-nws">Next Steps for NWS</h2>
<ul>
<li><strong>HA NWS Management Engine:</strong> Currently (as somewhat discussed above), the NWSME will go down when NWS Hill Country goes down. I&#39;d like to
make it so that this isn&#39;t the case. This would likely just require that each NWS cluster runs its own instance of Rancher Fleet instead
of one central Rancher Fleet that manages all the clusters. It would also require the HA SSLiaison.</li>
</ul>
<ul>
<li><strong>IaC for Everything:</strong> Currently, all NWS CDS services are defined in yaml files in a git repo, however the underlying infrastructure that
it runs on is not. Ideally, I&#39;d like every NWS machine to run Proxmox and then have Terraform &amp; Ansible configs to define how to set up
vms on proxmox that will run the k8s clusters that support CDS services. This should eliminate my headaches of sshing into each machine
to apply config changes and make sure everything is standardized. It should also make the process of setting up new servers easy.</li>
</ul>
<ul>
<li><strong>Monitoring:</strong> I&#39;ve been working on setting up monitoring on a lot of our services at my current internship using the TIG stack (Telegraf,
InfluxDB, and Grafana). Now that I&#39;ve been exposed to the usefulness of having a bunch of metrics on hand, I think it would be nice to have
some dashboards setup for NWS to monitor speed, resource usage, uptime, and traffic. Doing this would also make it possible to expose resource usage in the
NWS dashboard.</li>
</ul>
<ul>
<li><p><strong>Enhanced Infrastructure:</strong> This is kind of a blanket one for things I want to do that don&#39;t fit into other categories. It includes making
hardware upgrades (mostly adding more storage), make management more accessible (such as Dell IDRAC&#39;s WebSerial), some load testing to
identify painpoints, run an NWS machine in a cloud VM so I can say it&#39;s cross cloud (although my friends have told me this is cheating at creating
my own cloud), and trying to figure out how to set up an Anycast network. I don&#39;t think I can setup an Anycast network without selling
a kidney first. Renting a /24 CIDR alone would be more than I want to spend on a side project. I may look into setting it up with ipv6 only,
however I&#39;d still have to jump through hoops to get an Autonomous System number from an RIR. I&#39;ll probably write a whole blog about Anycast
in the coming weeks.</p>
</li>
<li><p><strong>Reduced External Dependence:</strong> The main goal of NWS is to have no external dependence. In theory, everything but core internet infrastructure
should </p>
</li>
</ul>
<h2 id="olney">Olney</h2>
<p><code>Rust, ActixWeb, PostgreSQL</code></p>
<p>Olney is a new project I am starting with my friend <a href="https://sridharnandigam.com/">Sridhar Nandigam</a>. It aims to make
tracking your job applications easier. Most of my friends either use spreadsheets or Trello to track their job applications, I
think that we can make something that&#39;s a bit better for the job. Some features I&#39;d like to have are: resume version attached to
your application, job posting notifications from job boards such as <a href="github.com/pittcsc/summer2024-internships">pittcsc</a>, and watching
your email for emails from recruiters. Currently, I have part of the backend setup with basic CRUD operations. Now that I&#39;m done with
the latest batch of NWS work, this is next on my list to work on.</p>
<hr>
<p><strong>These projects had minimal/no work done on them:</strong> RingGold, SQUIRREL</p>

View file

@ -0,0 +1,57 @@
<h1>Spring Break 2023</h1>
<p>It&#39;s Spring Break, and that means I finally have time to spend all day working on side projects without having to worry about school.</p>
<p>I figured I should write out the side projects I plan to work on over the break</p>
<h2 id="ringgold">RingGold</h2>
<p><code>Rust, Swift, PostgreSQL</code></p>
<p>Last week, me and my cousin wanted to try out Apple&#39;s fitness competition feature that works with Apple Watch. It works
by giving you 1 point for every percent you complete of your move, exercise, and stand goals with a point cap of 600
per day. The issue with it was that it didn&#39;t work at all, not syncing on time if at all. I want to build a clone of it
with some additional features such as:</p>
<ul>
<li><p><strong>Notifications:</strong> I didn&#39;t like how it was possible to workout and gain a bunch of points and just completely blindside your opponent. Hopefully this would encourage users to workout even more.</p>
</li>
<li><p><strong>Widget/Watch Complication:</strong> Similar to the above, adding a homescreen widget or a watch complication would make it easier to keep up with your competitor&#39;s progress. </p>
</li>
<li><p><strong>Custom Competitions:</strong> I think it&#39;d be nice to have competitions with custom rules and lengths so that you&#39;re not stuck with only one setting. Settings could include custom duration and custom caps on points.</p>
</li>
</ul>
<p>I&#39;m building the web API for it in Rust and the mobile app in Swift. I chose these languages to gain more exposure to them, also
Swift was a good choice since the app is going to be platform specific to iOS due to its need to integrate with Apple Watch.
<em>(this is named after New Ringgold, PA)</em></p>
<h2 id="nws-container-deployment-service">NWS Container Deployment Service</h2>
<p><code>C#, Rancher</code></p>
<p>I&#39;ve created my own hosting/cloud service called <a href="https://nws.nickorlow.com">Nick Web Services</a>. It currently allows people to deploy
dockerized applications on my geo-distributed k8s clusters running on Dell Poweredge servers. In order to actually deploy this, I
had to manually create the Kubernetes manifest files and then ssh into each individual server and apply them. I&#39;ve setup
Rancher Fleet to automate this process by pulling the manifest from a git repo (this is something called gitops). I also
wrote an API to generate the manifest files and then upload them to a git repo. I have a video demo of this working that
you can watch <a href="https://youtu.be/WHdXWMFHuqA">here</a>.</p>
<p>Currently, the service works for deployment but only if you don&#39;t want to use SSL or you use Cloudflare&#39;s flexible SSL
technology. I wrote a separate blog post <a href="http://nickorlow.com/blog/ssl-in-nws-cds">here</a> about the challenges of doing this and how I plan on implementing it.
I&#39;d like to complete part of this implementation during the break.</p>
<h2 id="verifiedbot">VerifiedBot</h2>
<p><code>JavaScript, Rust</code></p>
<p>This project isn&#39;t a personal project, as a lot of it was built by my friends <a href="https://arpan.one">Arpan</a> and <a href="https://benaubin.com/">Ben</a>.
A little over a year ago, we wanted to make a Discord bot to verify that people on some Discord servers we ran
went to the University of Texas. Initially, it worked by verifying you had a utexas.edu email address and then verifying
some additional information via LDAP. A few months ago Ben found out that using the SaaS survey software that the university uses
(qualtrics), we could have users verify themselves by using the university&#39;s SSO system. This works because qualtrics can send
data to a webhook when a survey is complete, and it can also require signing in with the university&#39;s SSO before filling out a survey.
It required that I write a <a href="https://github.com/Verified-Bot/aes-gcm-siv-wasm">wasm wrapper for an encryption library</a>. I wrote almost all the code for this function last year, but
due to a bug in qualtrics, it wasn&#39;t working properly. It seems that this bug has been fixed and we can start rolling it out.</p>
<h2 id="personal-website-facelift">Personal Website Facelift</h2>
<p><code>Typescript, React</code></p>
<p>My personal website (this one) is a little overdue for some design updates. My main focus will be making it more mobile
friendly. Last year, I made some improvements to make it usable on mobile but it still doesn&#39;t feel quite right. I also
think that it has some information overload in some areas such as the projects section. I think that to mitigate this I
might just have a small summary of each project and then you can click into each to learn more about it, similar to my
friend <a href="https://raulhigareda.com">Raul&#39;s Website</a>. I&#39;m also considering a move to tab-based navigation so that I can have
more information in each section. Further down the line, I think I might re-write it using Svelte as I&#39;m seeing it being used more and more
and would like to get some exposure to it.</p>
<h2 id="mahantongo">Mahantongo</h2>
<p><code>Rust, PostgreSQL</code></p>
<p>I&#39;m one of the members of the Community Team that runs some UT Computer Science community Discord servers.
Currently, a Discord bot called Carlbot provides us a star-board, which is a specific channel where messages that 5 or more people
react to with a star emoji get posted. It&#39;s supposed to be a collection of the funniest and best messages sent on the server.
One of the things our server members have wanted is the addition of more &#39;*-board&#39; channels where you can create multiple star-board
like channels but with custom emojis. I&#39;m writing it in Rust and I&#39;m just hoping to use this project to get more acquainted with the language.</p>

View file

@ -1,32 +0,0 @@
import React from "react";
export default function AboutMe() {
return (
<div style={{
display: "flex",
flexDirection:"column",
alignItems: "center",
alignContent: "center",
justifyContent: "center",
height: "95vh"
}}>
<div style={{maxWidth: 600}}>
<h1>About</h1>
<p>
I'm from Austin, Texas. I've been writing code for nearly 9 years and I'm
currently going to <b>The University of Texas at Austin</b>
</p>
<p>
I'm interested in infra and backend engineering.
</p>
<p className={"mb-0"}>If you would like to contact me, you can reach me at:</p>
<a href={"mailto:nickorlow@nickorlow.com"}>nickorlow@nickorlow.com</a>
<p style={{color: "grey"}} className={"mb-0 mt-4 small"}>Website originally created by Nicholas Orlowsky - Licensed under GNU General Public License v3 - Original source available <a href={"https://github.com/nickorlow/personal-site"}>here</a></p>
<p className={"small"}>Hosting provided by <a href={"https://nws.nickorlow.com"}>Nick Web Services (NWS)</a></p>
</div>
</div>
);
}

View file

@ -1,38 +0,0 @@
@media only screen and (max-width: 768px) {
.blog-card {
margin-top: 10px;
}
}
.blog-card {
padding: 10px;
}
.blog-card-img {
background-color: #FFFFFF;
padding: 20px;
width: 100%;
height: 100%;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
}
.blog-card-info {
padding-bottom: 5px;
padding-top: 10px;
}
.blog-card-int {
border-radius: 7px;
font-family: monospace;
transition: 1s;
color: #FFFFFF;
}
.blog-card-int:hover {
color: #F38020;
transition: .5s;
cursor: pointer;
text-decoration: none;
}

View file

@ -1,19 +0,0 @@
import ScrollAnimation from "react-animate-on-scroll";
import React from "react";
import {Link} from "react-router-dom";
import Job from "../../types/Job";
import "./BlogCard.css";
import Blog from "../../types/Blog";
export default function BlogCard(props: {style?: any, className?: string, blog: Blog}){
return (
<div className={"blog-card "+(props.className || "")} style={props.style}>
<Link to={"/blog/"+props.blog.uri} className={"blog-card-int"}>
<div className={"blog-card-info"}>
<h4 className={"font-weight-bold"}>{props.blog.title}</h4>
<p className={"font-weight-lighter"}>{props.blog.date.toLocaleDateString()}</p>
</div>
</Link>
</div>
);
}

View file

@ -1,24 +0,0 @@
.react-tabs__tab--selected {
transition: 1s;
border-top: 1px #00AA00 solid;
}
.tab-btn {
background-color: #121212;
transition: 1s;
border-bottom: 1px #FFFFFF solid;
}
.btn-beg {
border-bottom-left-radius: 10px;
border-top-left-radius: 10px;
border-left: 1px #FFFFFF solid;
}
.btn-end {
border-bottom-right-radius: 10px;
border-top-right-radius: 10px;
border-right: 1px #FFFFFF solid;
}

View file

@ -1,21 +0,0 @@
import React, {useState} from "react";
import "./Blogs.css";
import BlogCard from "../blog-card/BlogCard";
import {AllBlogs} from "../../static/data/Blogs";
export default function Blogs() {
return (
<div className={"h-100 d-md-flex justify-content-center align-items-center"}>
<div>
<h1 className={"mt-4"}>Blogs</h1>
<div className={"row"} style={{alignContent: "center"}}>
{AllBlogs.sort((a, b)=> b.date.getTime() - a.date.getTime()).map((blog) => {
if(blog.private) return;
return <BlogCard className={"col-md-4"} blog={blog}/>
})}
</div>
</div>
</div>
)
}

View file

@ -1,15 +0,0 @@
import React from "react";
export default function Contact() {
return (
<div style={{minHeight: "90vh"}}>
<div style={{minHeight: "90vh", display: "flex", alignItems: "center", justifyContent: "center"}}>
<div>
<h1>Contact</h1>
<p style={{maxWidth: 500}}>If you need: startup advice, tech/programming help, an employee (me!), or just someone to talk to, feel free to email me at:</p>
<a href={"mailto:nickorlow@nickorlow.com"}>nickorlow@nickorlow.com</a>
</div>
</div>
</div>
)
}

View file

@ -1,12 +0,0 @@
import React from "react";
export default function Footer() {
return (
<footer>
<div style={{height: 12, marginTop: -50}}>
<p style={{color: "grey"}} className={"m-0 small"}>Originally created by Nicholas Orlowsky - Licensed under GNU General Public License v3 - Original source available <a href={"https://github.com/nickorlow/personal-site"}>here</a></p>
<p className={"small"}>Hosting provided by <a href={"https://nws.nickorlow.com"}>Nick Web Services (NWS)</a></p>
</div>
</footer>
)
}

View file

@ -1,28 +0,0 @@
import TexasIcon from "../../static/images/texas-icon.png";
import SocialBar from "../social-bar/SocialBar";
import React from "react";
export default function Hero() {
return (
<div>
<div style={{
height: "95vh",
display: "flex",
alignContent: "center",
justifyContent: "center",
flexDirection: "column",
alignItems: "center"
}}>
<img alt="github profile picture" src={"https://avatars.githubusercontent.com/u/56371027?v=4"}
style={{height: "30vh", width: "auto"}} className={"pfp"}/>
<h1 className={"m-0 font-weight-bold"}>Nicholas Orlowsky</h1>
<h4 className={"m-0"}>Software Engineer</h4>
<div className={"row"}>
<img alt={"github profile"} className={"fade-in-tx"} src={TexasIcon} style={{height: 50}}/>
<p className={"move-left-atx"} style={{marginTop: 11}}>Austin, Texas</p>
</div>
<SocialBar style={{justifyContent: "center", width: "60vmin"}}/>
</div>
</div>
);
}

View file

@ -1,18 +0,0 @@
import {AllHobbies} from "../../static/data/Hobbies";
import InfoCard from "../info-card/InfoCard";
import React, {useState} from "react";
import {AllJobs} from "../../static/data/Jobs";
import {Carousel} from "react-bootstrap";
import JobCard from "../job-card/JobCard";
export default function Hobbies () {
const [cur, setCur] = useState(1);
return (
<div style={{minHeight: "100vh"}}>
<div>
{AllHobbies.map((hobby) => <InfoCard style={{textAlign: "left", maxWidth: "50vmax", margin: 50}}
info={hobby}/>)}
</div>
</div>
)
}

View file

@ -1,22 +0,0 @@
import React from "react";
import InfoCardProps from "../../types/InfoCardProps";
export default function InfoCard(props: {style?: any, className?: string, info: InfoCardProps}) {
return (
<div style={props.style} className={props.className}>
<div style={{maxWidth: "100vw"}}>
<h3>{props.info.title}</h3>
<p>
{props.info.description}
</p>
<div>
<h4>{props.info.listTitle}</h4>
<div className={"row"} style={{color: "green", fontFamily: "monospace"}}>
{props.info.list.map(s => <p className={"col-4"} style={{fontSize: 16}}>{s}</p>)}
</div>
</div>
{props.info.link != null && <a href={props.info.link}>{props.info.linkTitle || "Relevant Link"}</a>}
</div>
</div>
);
}

View file

@ -1,7 +0,0 @@
@media only screen and (max-width: 768px) {
.job-card {
margin-top: 100px;
}
}

View file

@ -1,27 +0,0 @@
import ScrollAnimation from "react-animate-on-scroll";
import React from "react";
import Job from "../../types/Job";
import "./JobCard.css";
export default function JobCard(props: {style?: any, className?: string, job: Job}){
return (
<ScrollAnimation className={"job-card "+(props.className || "")} style={props.style} animateIn={"no-fade-up"} initiallyVisible={true} duration={2} animateOnce={true} offset={50} delay={200}>
<div className={"row"} style={{paddingTop: 40}}>
<div className={"col-md-4"}>
<img className={"float-left float-md-none"} alt={props.job.company+" company logo"} src={props.job.image} style={{objectFit: "contain" ,height: "auto", width: "auto", maxHeight: 100, maxWidth: '300px'}}/>
</div>
<div className={"col-md-8 row"}>
<div className={"col-md-6 text-left"}>
<h2>{props.job.title}</h2>
{props.job.uri == null && <h5>{props.job.company}</h5>}
{props.job.uri != null && <a href={props.job.uri}><h5>{props.job.company}</h5></a>}
<p>{props.job.timespan}</p>
</div>
<div className={"col-md-6 text-left"}>
{props.job.items.map((s) => <li>{s}</li>)}
</div>
</div>
</div>
</ScrollAnimation>
);
}

View file

@ -1,24 +0,0 @@
.react-tabs__tab--selected {
transition: 1s;
border-top: 1px #00AA00 solid;
}
.tab-btn {
background-color: #121212;
transition: 1s;
border-bottom: 1px #FFFFFF solid;
}
.btn-beg {
border-bottom-left-radius: 10px;
border-top-left-radius: 10px;
border-left: 1px #FFFFFF solid;
}
.btn-end {
border-bottom-right-radius: 10px;
border-top-right-radius: 10px;
border-right: 1px #FFFFFF solid;
}

View file

@ -1,30 +0,0 @@
import {AllJobs} from "../../static/data/Jobs";
import JobCard from "../job-card/JobCard";
import React, {useState} from "react";
import "./Jobs.css";
import {Carousel} from "react-bootstrap";
export default function Jobs() {
const [cur, setCur] = useState(1);
return (
<div style={{minHeight: "100vh"}}>
<div className={"align-content-center d-md-block d-none"}>
<h1 style={{marginBottom: 40}}>Work</h1>
{AllJobs.map((job, i) =><JobCard job={job}/>)}
</div>
<div className={"align-content-center d-md-none"}>
<h1 className={"mb-4"}>Work</h1>
<p>{cur}/{AllJobs.length}</p>
<Carousel controls={false} interval={null} onSlide={(e)=>{setCur(e+1)}} indicators={false} wrap={false}>
{AllJobs.map((job, i) =>
<Carousel.Item>
<JobCard job={job}/>
</Carousel.Item>
)}
</Carousel>
</div>
</div>
)
}

View file

@ -1,21 +0,0 @@
.navbar-selected-pill {
background-color: white;
width: 40px;
height: 3px;
border-radius: 5px;
transition-duration: .5s;
}
.navbar-unselected-pill {
width: 0px;
}
.no-blue-link {
color: white;
}
.no-blue-link:hover {
transition-duration: .5s;
color: grey;
text-decoration: none;
}

View file

@ -1,35 +0,0 @@
import React from "react";
import "./Navbar.css";
import {Link, useLocation} from "react-router-dom";
export default function Navbar() {
const location = useLocation();
return (
<div style={{maxWidth:"100%", marginTop: 10, maxHeight: "5vh"}} className={"d-flex justify-content-center align-items-center " + (location.pathname === "/" ? "fade-down-d3s" : "")} >
<div className={"d-flex flex-row justify-content-around"} style={{width: 700}}>
<div className={"d-flex flex-column justify-content-center align-items-center"}>
<Link to={"/home"} className={"mb-0 no-blue-link"}>Home</Link>
<div className={"navbar-selected-pill " + ((location.pathname === "/" || location.pathname === "/home") ? "" : "navbar-unselected-pill")}/>
</div>
<div className={"d-flex flex-column justify-content-center align-items-center"}>
<Link to={"/about"} className={"mb-0 no-blue-link"}>About</Link>
<div className={"navbar-selected-pill " + (location.pathname === "/about" ? "" : "navbar-unselected-pill")}/>
</div>
<div className={"d-flex flex-column justify-content-center align-items-center"}>
<Link to={"/blogs"} className={"mb-0 no-blue-link"}>Blog</Link>
<div className={"navbar-selected-pill " + (location.pathname === "/blogs" ? "" : "navbar-unselected-pill")}/>
</div>
<div className={"d-flex flex-column justify-content-center align-items-center"}>
<Link to={"/projects"} className={"mb-0 no-blue-link"}>Projects</Link>
<div className={"navbar-selected-pill " + (location.pathname === "/projects" ? "" : "navbar-unselected-pill")}/>
</div>
{/*Disabling this page for now*/}
{/*<div className={"d-flex flex-column justify-content-center align-items-center"}>*/}
{/* <Link to={"/hobbies"} className={"mb-0 no-blue-link"}>Hobbies</Link>*/}
{/* <div className={"navbar-selected-pill " + (location.pathname === "/hobbies" ? "" : "navbar-unselected-pill")}/>*/}
{/*</div>*/}
</div>
</div>
)
}

View file

@ -1,178 +0,0 @@
.project-card {
padding: 3px;
}
.project-card-int {
font-family: monospace;
padding: 2px;
background-size: cover;
background-position: center;
transition: .5s;
}
.project-card-int:hover {
color: #F38020;
cursor: pointer;
}
.project-card-modal {
background-color: #000000;
color: #FFFFFF;
width: 100vmin;
height: max-content;
position: absolute;
left: 50%;
top: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
outline: none;
padding: 5vmin;
}
.ReactModal__Overlay {
background-color: rgba(20,20,20,.8) !important;
backdrop-filter: blur(5px);
}
.back-button {
color: #2F74C0;
}
.back-button:hover {
cursor: pointer;
}
.lang-card {
color: white;
border-radius: 5px;
font-family: monospace;
background-color: #00AA00;
}
.lang-card-modal {
border-radius: 5px;
font-family: monospace;
align-content: center;
justify-content: center;
display: flex;
margin: 2px;
width: max-content;
padding-left: 10px;
padding-right: 10px;
background-color: #00AA00;
}
.kubernetes {
background-color: #326ce5;
}
.c\# {
background-color: #800080FF;
}
.html {
background-color: #e34c26;
}
.react {
background-color: #0cc4f6;
}
.typescript {
background-color: #2F74C0;
}
.bootstrap {
background-color: #7952B3;
}
.nws {
background-color: #DB4437;
}
.docker {
background-color: #2496ED;
}
.dotnet {
background-color: #5C2D91;
}
.nosql {
background-color: #4EA94B;
}
.nginx {
background-color: #269539;
}
.react-native {
background-color: #61DBFB;
}
.cloudflare {
background-color: #F38020;
}
.html {
background-color: #E44D26;
}
.javascript {
background-color: #b9a617;
}
.css {
background-color: #1572B6;
}
.xenhtmlframework {
background-color: #3A6A81;
}
.xeninfoapi {
background-color: #3E4E57;
}
.java {
background-color: #007396;
}
.applescript {
background-color: #a8a8a8;
}
.spotifyapi {
background-color: #1DB954;
}
.node\.js {
background-color: #339933;
}
.rancher {
background-color: #0075A8;
}
.azuredevops {
background-color: #0078D7;
}
.mongodb {
background-color: #47A248;
}
.mssql {
background-color: #CC2927;
}
.rust {
background-color: #CE412B;
}
.discordapi {
background-color: #7289DA;
}

View file

@ -1,44 +0,0 @@
import React, {useState} from "react";
import "./ProjectCard.css";
import ProjectCardProps from "../../types/ProjectCardProps";
import Modal from "react-modal";
export default function ProjectCard(props: {info: ProjectCardProps}) {
const [isModalOpen, setModalOpen] = useState(false);
return (
<div className={"project-card col-md-4 p-2"}>
<div className={"project-card-int pb-2 justify-content-center align-items-center d-flex flex-column"} style={{backgroundImage: "linear-gradient(to bottom, rgba(0, 0, 0, .60) 50%, rgba(0, 0, 0, 0.75) 100%), url(\""+props.info.imageUrl+"\")"}} onClick={()=>{setModalOpen(true)}}>
<h4 className={"font-weight-bold"}>{props.info.title}</h4>
<p className={"font-weight-lighter w-75"}>{props.info.shortDescription}</p>
{/*<div>*/}
{/* <div className={"row"} style={{fontFamily: "monospace"}}>*/}
{/* {props.info.techUsed.slice(0, 3).map(s =>*/}
{/* <div className={"col-md-4 col-12 mt-2"}>*/}
{/* <div className={"lang-card "+s.toLowerCase().replace(" ", "")}>*/}
{/* <p style={{fontSize: 16, margin: 0}}>{s}</p>*/}
{/* </div>*/}
{/* </div>*/}
{/* )}*/}
{/* </div>*/}
{/*</div>*/}
</div>
<Modal className={"project-card-modal"} isOpen={isModalOpen}>
<p className={"back-button"} onClick={()=>{setModalOpen(false)}}>Back</p>
<h1>{props.info.title}</h1>
<a href={props.info.link}>{props.info.linkTitle}</a>
<p>{props.info.description}</p>
<h3>All technologies used:</h3>
<div className={"d-flex flex-wrap mw-100"}>
{props.info.techUsed.map(s =>
<div className={""}>
<div className={"lang-card-modal "+s.toLowerCase().replace(" ", "")}>
<p style={{fontSize: 16, margin: 0}}>{s}</p>
</div>
</div>
)}
</div>
</Modal>
</div>
);
}

View file

@ -1,34 +0,0 @@
import {AllProjects} from "../../static/data/Projects";
import InfoCard from "../info-card/InfoCard";
import React, {useState} from "react";
import {AllHobbies} from "../../static/data/Hobbies";
import {Carousel} from "react-bootstrap";
import ProjectCard from "../project-card/ProjectCard";
export default function Projects() {
const [cur, setCur] = useState(1);
return (
<div style={{minHeight: "100vh"}}>
<div style={{
display: "flex",
justifyContent: "center",
flexDirection: "column",
width: "100vw",
minHeight: "100vh",
alignContent: "center",
alignItems: "center"
}}>
<div className={"align-content-center mb-4 mt-4"}>
<h1>Projects</h1>
<p>Click to learn more about each project</p>
<div className={"row m-0"} style={{justifyContent: "center", padding: 50}}>
{AllProjects.map((project) => <ProjectCard info={project}/>)}
</div>
<a href={"https://github.com/nickorlow"}>More on GitHub</a>
</div>
</div>
</div>
)
}

View file

@ -1,31 +0,0 @@
.icon {
transition: 1s !important;
fill: #FFFFFF;
height: 50px;
}
.icon:hover {
transform: translateY(-2px);
cursor: pointer;
}
.insta-icon:hover {
fill: #DD2A7B;
}
.twitter-icon:hover {
fill: #1DA1F2;
}
.github-icon:hover {
fill: #F1502F;
}
.linkedin-icon:hover {
fill: #0077B5;
}
.mail-icon:hover {
fill: #EA4335;
}

View file

@ -1,28 +0,0 @@
import React from "react";
import './SocialBar.css';
export default function SocialBar(props: {style: any}) {
return (
<div className={"row"} style={props.style}>
<div className={"col-md-2 col-4 fade-up-3 fade-up-md-2"} style={{display: "flex", justifyContent: "center"}}>
<svg onClick={ () => window.location.href="https://instagram.com/nickorlow"} className={"insta-icon icon"} viewBox="0 0 50 50" width="100px" height="100px"> <path d="M 16 3 C 8.83 3 3 8.83 3 16 L 3 34 C 3 41.17 8.83 47 16 47 L 34 47 C 41.17 47 47 41.17 47 34 L 47 16 C 47 8.83 41.17 3 34 3 L 16 3 z M 37 11 C 38.1 11 39 11.9 39 13 C 39 14.1 38.1 15 37 15 C 35.9 15 35 14.1 35 13 C 35 11.9 35.9 11 37 11 z M 25 14 C 31.07 14 36 18.93 36 25 C 36 31.07 31.07 36 25 36 C 18.93 36 14 31.07 14 25 C 14 18.93 18.93 14 25 14 z M 25 16 C 20.04 16 16 20.04 16 25 C 16 29.96 20.04 34 25 34 C 29.96 34 34 29.96 34 25 C 34 20.04 29.96 16 25 16 z"/></svg>
</div>
<div className={"col-md-2 col-4 fade-up-2 fade-up-md"} style={{display: "flex", justifyContent: "center"}}>
<svg onClick={ () => window.location.href="https://twitter.com/nickorIow"} className={"twitter-icon icon"} viewBox="0 0 50 50" width="100px" height="100px"><path d="M 50.0625 10.4375 C 48.214844 11.257813 46.234375 11.808594 44.152344 12.058594 C 46.277344 10.785156 47.910156 8.769531 48.675781 6.371094 C 46.691406 7.546875 44.484375 8.402344 42.144531 8.863281 C 40.269531 6.863281 37.597656 5.617188 34.640625 5.617188 C 28.960938 5.617188 24.355469 10.21875 24.355469 15.898438 C 24.355469 16.703125 24.449219 17.488281 24.625 18.242188 C 16.078125 17.8125 8.503906 13.71875 3.429688 7.496094 C 2.542969 9.019531 2.039063 10.785156 2.039063 12.667969 C 2.039063 16.234375 3.851563 19.382813 6.613281 21.230469 C 4.925781 21.175781 3.339844 20.710938 1.953125 19.941406 C 1.953125 19.984375 1.953125 20.027344 1.953125 20.070313 C 1.953125 25.054688 5.5 29.207031 10.199219 30.15625 C 9.339844 30.390625 8.429688 30.515625 7.492188 30.515625 C 6.828125 30.515625 6.183594 30.453125 5.554688 30.328125 C 6.867188 34.410156 10.664063 37.390625 15.160156 37.472656 C 11.644531 40.230469 7.210938 41.871094 2.390625 41.871094 C 1.558594 41.871094 0.742188 41.824219 -0.0585938 41.726563 C 4.488281 44.648438 9.894531 46.347656 15.703125 46.347656 C 34.617188 46.347656 44.960938 30.679688 44.960938 17.09375 C 44.960938 16.648438 44.949219 16.199219 44.933594 15.761719 C 46.941406 14.3125 48.683594 12.5 50.0625 10.4375 Z"/></svg>
</div>
<div className={"col-md-2 col-4 fade-up fade-up-md-2"} style={{display: "flex", justifyContent: "center"}}>
<svg onClick={ () => window.location.href="https://github.com/nickorlow"} className={"github-icon icon"} viewBox="0 0 50 50" width="100px" height="100px"> <path d="M17.791,46.836C18.502,46.53,19,45.823,19,45v-5.4c0-0.197,0.016-0.402,0.041-0.61C19.027,38.994,19.014,38.997,19,39 c0,0-3,0-3.6,0c-1.5,0-2.8-0.6-3.4-1.8c-0.7-1.3-1-3.5-2.8-4.7C8.9,32.3,9.1,32,9.7,32c0.6,0.1,1.9,0.9,2.7,2c0.9,1.1,1.8,2,3.4,2 c2.487,0,3.82-0.125,4.622-0.555C21.356,34.056,22.649,33,24,33v-0.025c-5.668-0.182-9.289-2.066-10.975-4.975 c-3.665,0.042-6.856,0.405-8.677,0.707c-0.058-0.327-0.108-0.656-0.151-0.987c1.797-0.296,4.843-0.647,8.345-0.714 c-0.112-0.276-0.209-0.559-0.291-0.849c-3.511-0.178-6.541-0.039-8.187,0.097c-0.02-0.332-0.047-0.663-0.051-0.999 c1.649-0.135,4.597-0.27,8.018-0.111c-0.079-0.5-0.13-1.011-0.13-1.543c0-1.7,0.6-3.5,1.7-5c-0.5-1.7-1.2-5.3,0.2-6.6 c2.7,0,4.6,1.3,5.5,2.1C21,13.4,22.9,13,25,13s4,0.4,5.6,1.1c0.9-0.8,2.8-2.1,5.5-2.1c1.5,1.4,0.7,5,0.2,6.6c1.1,1.5,1.7,3.2,1.6,5 c0,0.484-0.045,0.951-0.11,1.409c3.499-0.172,6.527-0.034,8.204,0.102c-0.002,0.337-0.033,0.666-0.051,0.999 c-1.671-0.138-4.775-0.28-8.359-0.089c-0.089,0.336-0.197,0.663-0.325,0.98c3.546,0.046,6.665,0.389,8.548,0.689 c-0.043,0.332-0.093,0.661-0.151,0.987c-1.912-0.306-5.171-0.664-8.879-0.682C35.112,30.873,31.557,32.75,26,32.969V33 c2.6,0,5,3.9,5,6.6V45c0,0.823,0.498,1.53,1.209,1.836C41.37,43.804,48,35.164,48,25C48,12.318,37.683,2,25,2S2,12.318,2,25 C2,35.164,8.63,43.804,17.791,46.836z"/></svg>
</div>
<div className={"col-md-2 col-4 fade-up-2 fade-up-md-3"} style={{display: "flex", justifyContent: "center"}}>
<svg onClick={ () => window.location.href="https://www.linkedin.com/in/nickorlow"} className={"linkedin-icon icon"} viewBox="0 0 50 50" width="100px" height="100px"> <path d="M41,4H9C6.24,4,4,6.24,4,9v32c0,2.76,2.24,5,5,5h32c2.76,0,5-2.24,5-5V9C46,6.24,43.76,4,41,4z M17,20v19h-6V20H17z M11,14.47c0-1.4,1.2-2.47,3-2.47s2.93,1.07,3,2.47c0,1.4-1.12,2.53-3,2.53C12.2,17,11,15.87,11,14.47z M39,39h-6c0,0,0-9.26,0-10 c0-2-1-4-3.5-4.04h-0.08C27,24.96,26,27.02,26,29c0,0.91,0,10,0,10h-6V20h6v2.56c0,0,1.93-2.56,5.81-2.56 c3.97,0,7.19,2.73,7.19,8.26V39z"/></svg>
</div>
<div className={"col-md-2 col-4 fade-up-3 fade-up-md-3"} style={{display: "flex", justifyContent: "center"}}>
<svg onClick={ () => window.location.href="mailto:nickorlow@nickorlow.com"} className={"mail-icon icon"} viewBox="0 0 100 100" width="100px" height="100px"><g id="surface12014155"><path d="M 28 8 C 16.976562 8 8 16.976562 8 28 L 8 72 C 8 83.023438 16.976562 92 28 92 L 72 92 C 83.023438 92 92 83.023438 92 72 L 92 28 C 92 16.976562 83.023438 8 72 8 Z M 26 32 L 74 32 C 74.359375 32 74.699219 32.039062 75.019531 32.140625 L 55.359375 51.78125 C 52.398438 54.742188 47.582031 54.742188 44.621094 51.78125 L 24.980469 32.140625 C 25.300781 32.039062 25.640625 32 26 32 Z M 22.140625 34.980469 L 37.179688 50 L 22.140625 65.019531 C 22.039062 64.699219 22 64.359375 22 64 L 22 36 C 22 35.640625 22.039062 35.300781 22.140625 34.980469 Z M 77.859375 34.980469 C 77.960938 35.300781 78 35.640625 78 36 L 78 64 C 78 64.359375 77.960938 64.699219 77.859375 65.019531 L 62.800781 50 Z M 40 52.820312 L 41.78125 54.621094 C 44.042969 56.882812 47.019531 58 49.980469 58 C 52.960938 58 55.917969 56.882812 58.179688 54.621094 L 59.980469 52.820312 L 75.019531 67.859375 C 74.699219 67.960938 74.359375 68 74 68 L 26 68 C 25.640625 68 25.300781 67.960938 24.980469 67.859375 Z M 40 52.820312 "/></g></svg>
</div>
</div>
);
}

View file

@ -1,34 +0,0 @@
import Typing from "react-typing-animation";
import React, {Dispatch} from "react";
export default function Terminal(props: {isTerminalVisible: boolean, setIsTerminalVisible: Dispatch<boolean>}) {
return (
<div className={props.isTerminalVisible ? "" : "fade-out"} style={{position: "fixed", top: 0, left: 0, width: "99vw", height: "100vh", backgroundColor: "black",textAlign: "left"}}>
<p className={"d-inline"}>nickorlow@macbook ~# </p>
<Typing speed={20} className={"d-inline"} onFinishedTyping={() => props.setIsTerminalVisible(false)}>
<p className={"d-inline"}>git clone <p className={"d-inline"} style={{color: "#00aaee"}}>https://github.com/nickorlow/personal-site</p></p>
<Typing.Speed ms={0} />
<p/>
<p className={"m-0"}>Cloning into 'personal-site'...</p>
<p className={"m-0"}>remote: Enumerating objects: 334, done.</p>
<p className={"m-0"}>remote: Counting objects: 100% (334/334), done.</p>
<p className={"m-0"}>remote: Compressing objects: 100% (185/185), done.</p>
<p className={"m-0"}>remote: Total 334 (delta 132), reused 324 (delta 127), pack-reused 0</p>
<p className={"m-0"}>Receiving objects: 100% (334/334), 29.68 MiB | 5.50 MiB/s, done.</p>
<p className={"m-0"}>Resolving deltas: 100% (132/132), done.</p>
<p/>
<p className={"d-inline"}>nickorlow@macbook ~# </p>
<Typing.Speed ms={10} />
<p className={"d-inline"}>cd persona-site</p>
<Typing.Backspace speed={10} count={5}/>
<p className={"d-inline"}>l-site</p>
<p/>
<Typing.Speed ms={0} />
<p className={"d-inline"}>nickorlow@macbook ~# </p>
<Typing.Delay ms={200}/>
<Typing.Speed ms={100} />
<p className={"d-inline"}>npm run start</p>
</Typing>
</div>
)
}

View file

@ -1 +0,0 @@
declare module '*.md'

56
src/extra.filler.html Normal file
View file

@ -0,0 +1,56 @@
<div>
<h1 style="margin-bottom: 0px;">Extra</h1>
<p style="margin-top: 0px;">Extra bits of information about me</p>
<h2>Personal Records</h2>
<table style="width: 100%;">
<tr>
<th>Activity</th>
<th>Effort</th>
<th>Date</th>
<th>Location</th>
</tr>
<tr>
<td>1600m (1 mile)</td>
<td>4:34</td>
<td>November 14th, 2020</td>
<td>Williamson County Park</td>
</tr>
<tr>
<td>Milk Mile</td>
<td>5:41</td>
<td>May 20th, 2021</td>
<td>Lake Travis High School</td>
</tr>
<tr>
<td>3200m (2 mile)</td>
<td>10:11</td>
<td>March 20th, 2021</td>
<td>Carroll High School</td>
</tr>
<tr>
<td>5000m XC</td>
<td>16:43</td>
<td>September 26th, 2020</td>
<td>Old Settler's Park</td>
</tr>
<tr>
<td>Bench Press</td>
<td>275 Lbs</td>
<td>2023</td>
<td>Gregory Gym</td>
</tr>
<tr>
<td>Squat</td>
<td>405 Lbs</td>
<td>2023</td>
<td>Gregory Gym</td>
</tr>
<tr>
<td>Deadlift</td>
<td>405 Lbs</td>
<td>2023</td>
<td>Gregory Gym</td>
</tr>
</table>
</div>

View file

@ -1,13 +0,0 @@
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}

31
src/index.filler.html Normal file
View file

@ -0,0 +1,31 @@
<div>
<h1 style="margin-bottom: 0px;">Nicholas Orlowsky</h1>
<p style="margin-top: 0px;">Software Engineer - Austin, TX</p>
<p>
<a href="https://github.com/nickorlow">[ GitHub ]</a>
<a href="https://www.linkedin.com/in/nickorlow/">[ LinkedIn ]</a>
<a href="mailto:nickorlow@nickorlow.com">[ E-Mail ]</a>
<a href="https://github.com/nickorlow/resume/releases/download/latest/resume-nickorlow.pdf">[ Resume ]</a>
<a href="https://nickorlow.com">[ Old Website ]</a>
</p>
<p>
<a href="https://open.spotify.com/episode/7f0lB2alMuvpfsQfwtRpJB?si=a55a62f6921a4671">[ Listen to me on the Azure DevOps podcast! ]</a>
</p>
<p>
I'm a computer science student at the University of Texas at Austin. I'm particularly
interested in infrastructure, distributed systems, and systems programming.
</p>
<p>
I run <a href="https://nws.nickorlow.com">Nick Web Services (NWS)</a>, a side project
that provides geo-distributed container hosting using Kubernetes on bare metal servers.
It currently has 100% uptime YTD, surpassing the uptime percentage of competitor GitHub pages.
</p>
<p>
Outside of computers, I enjoy biking and weightlifting. I'm also a public transit enthusiast
and I take pictures of trains that I see, especially rare or special ones.
</p>
</div>

View file

@ -1,19 +0,0 @@
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { render } from 'react-snapshot';
import { BrowserRouter } from 'react-router-dom';
ReactDOM.render((
<BrowserRouter>
<App /> {/* The various pages will be displayed by the `Main` component. */}
</BrowserRouter>
), document.getElementById('root')
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3"><g fill="#61DAFB"><path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/><circle cx="420.9" cy="296.5" r="45.7"/><path d="M520.5 78.1z"/></g></svg>

Before

Width:  |  Height:  |  Size: 2.6 KiB

View file

@ -1,144 +0,0 @@
img[alt=cavcash-newsroom] {
width: 49.5%
}
.App {
text-align: center;
background-color: black;
min-height: 100vh;
width: 100vw !important;
max-width: 100vw !important;
font-size: calc(20px);
color: white;
}
.row {
margin: 0 !important;
}
html {
background-color: black;
}
h1 {
font-weight: bolder;
}
@keyframes fade-up-anim {
0% {
opacity: 0;
transform: translateY(40px);
}
100% {
opacity:1;
transform: translateY(0px);
}
}
@media only screen and (max-width: 993px) {
.fade-up-md {
opacity: 0;
animation: fade-up-anim 2s forwards 200ms !important;
}
.fade-up-md-2 {
opacity: 0;
animation: fade-up-anim 2s forwards 400ms !important;
}
.fade-up-md-3 {
opacity: 0;
animation: fade-up-anim 2s forwards 600ms !important;
}
}
@media only screen and (min-width: 768px) {
.fade-up {
opacity: 0;
animation: fade-up-anim 2s forwards 200ms;
}
.fade-up-2 {
opacity: 0;
animation: fade-up-anim 2s forwards 400ms;
}
.fade-up-3 {
opacity: 0;
animation: fade-up-anim 2s forwards 600ms;
}
}
.fade-up {
opacity: 0;
animation: fade-up-anim 2s forwards 200ms;
}
.fade-up-d3s {
opacity: 0;
animation: fade-up-anim 2s forwards 3s;
}
@keyframes fade-in-tx-anim {
0% {
opacity: 0;
}
100% {
opacity:1;
}
}
.fade-in-tx {
animation: fade-in-tx-anim 1s ease-in;
}
@keyframes fade-out{
0% {
opacity: 1;
z-index: 500;
}
99% {
opacity: .1;
z-index: 500;
}
100% {
opacity:0;
z-index: -500;
display: none;
visibility: hidden;
}
}
.fade-out {
animation: fade-out 1s ease-in forwards;
opacity: 0;
}
@keyframes move-left-atx-anim {
0% {
margin-left: 0;
}
100% {
margin-left: -17px;
}
}
.move-left-atx {
animation: move-left-atx-anim 1s forwards;
}
ul {
list-style-type: none;
margin-left: -35px;
}
.pfp {
border-radius: 100%;
width: 25%
}

View file

@ -1,39 +0,0 @@
import React, {useState} from 'react';
import './Home.css';
import Footer from "../components/footer/Footer";
import Hero from "../components/hero/Hero";
import AboutMe from "../components/about-me/AboutMe";
import Jobs from "../components/jobs/Jobs";
import Projects from "../components/projects/Projects";
import Hobbies from "../components/hobbies/Hobbies";
import Contact from "../components/contact/Contact";
import Terminal from "../components/terminal/Terminal";
function Home() {
const showTerm: boolean = new URLSearchParams(window.location.search).get("showTerm") === 'true';
const [isTerminalVisible, setIsTerminalVisible] = useState(showTerm);
return (
<div className="Home">
{showTerm && <Terminal isTerminalVisible={isTerminalVisible} setIsTerminalVisible={setIsTerminalVisible}/>}
{!isTerminalVisible &&
<div>
<div className={"w-100 d-flex justify-content-center align-content-center text-center p-1"} style={{backgroundColor: "#004C54", height: 40, position: "absolute", top: 0}} >
<p className={"text-white fw-bold"}>Fly Eagles Fly</p>
<img src={"https://logos-world.net/wp-content/uploads/2020/05/Philadelphia-Eagles-Logo.png"} style={{maxHeight: "100%", maxWidth: "100%"}}/>
</div>
<Hero/>
<AboutMe/>
<Jobs/>
<Projects/>
<Hobbies/>
<Contact/>
<Footer/>
</div>
}
</div>
);
}
export default Home;

View file

@ -1,113 +0,0 @@
import React, {useEffect, useState} from 'react';
import './Home.css';
import ReactMarkdown from 'react-markdown'
import {AllBlogs} from "../static/data/Blogs";
import {Prism as SyntaxHighlighter} from 'react-syntax-highlighter'
import {a11yDark as theme} from "react-syntax-highlighter/dist/esm/styles/prism";
import {Link} from "react-router-dom";
import Blog from "../types/Blog";
function SingleBlog() {
const [blog, setBlog] = useState<Blog | undefined>(undefined);
const [blogText, setBlogText] = useState<string>('');
useEffect(()=> {
let pathParts = window.location.pathname.split('/');
let blogName = pathParts[pathParts.length - 1];
setBlog(AllBlogs.find(b => b.uri == blogName));
}, [])
useEffect(()=> {
if(blog === undefined) return;
fetch(blog.mdfile)
.then(response => {
return response.text()
})
.then(text => {
setBlogText(text)
})
}, [blog]);
return (
blog === undefined ? <div></div> :
<div className="Blog" style={{paddingTop: 30}}>
<h1>{blog.title}</h1>
<p>{blog.date.toLocaleDateString()}</p>
<p><Link to={"/blogs"}>Back</Link></p>
<div style={{width: "100%", display: 'flex', justifyContent: 'center'}}>
<div className={"d-md-none d-block"} style={{textAlign: "left", margin: 20}}>
<ReactMarkdown
components={{
code({node, inline, className, children, ...props}) {
const match = /language-(\w+)/.exec(className || '')
return !inline && match ? (
<SyntaxHighlighter
children={String(children).replace(/\n$/, '')}
style={theme}
language={match[1]}
PreTag="div"
{...props}
/>
) : (
<code className={className} {...props}>
{children}
</code>
)
},
img({node, ...props}){
console.log(node.properties)
return (
<img
alt={node!.properties!.alt!.toString()}
src={node!.properties!.src!.toString()}
style={{ maxWidth: "100%" }} />)
}
}}
>
{blogText}
</ReactMarkdown>
</div>
<div className={"d-none d-md-block"} style={{textAlign: "left", margin: 20, maxWidth: "80vw"}}>
<ReactMarkdown
components={{
code({node, inline, className, children, ...props}) {
const match = /language-(\w+)/.exec(className || '')
return !inline && match ? (
<SyntaxHighlighter
children={String(children).replace(/\n$/, '')}
style={theme}
language={match[1]}
PreTag="div"
{...props}
/>
) : (
<code className={className} {...props}>
{children}
</code>
)
},
img({node, ...props}){
console.log(node.properties)
return (
<img
alt={node!.properties!.alt!.toString()}
src={node!.properties!.src!.toString()}
style={{ maxWidth: "100%" }} />)
}
}}
>
{blogText}
</ReactMarkdown>
</div>
</div>
</div>
);
}
export default SingleBlog;

64
src/projects.filler.html Normal file
View file

@ -0,0 +1,64 @@
<div>
<h1 style="margin-bottom: 0px;">Projects</h1>
<div>
<h2>Nick Web Services (NWS)</h2>
<a href="https://nws.nickorlow.com">[ Project Website ]</a>
<p>
Nick Web Services is a cloud infrastructure provider service that I created and run.
It allows people to deploy containerized versions of their web apps across our multiple
servers. It provides geo-distributed high availability by default with no extra configuration
needed from users hosting their webapp with us.
</p>
<p>
Hardware-wise we use old Dell PowerEdge servers running Proxmox. We then have VMs running
in Proxmox that run Kubernetes clusters. We have 4 clusters currently: Austin, Hill Country,
Schuylkill, and Philadelphia. The deployments are managed through GitOps with Rancher Fleet.
</p>
</div>
<div>
<h2>CavCash</h2>
<a href="https://cavcash.com">[ Project Website ]</a>
<p>
CavCash was a company that I founded which built a debit-based payment system similar to
PayPal and Venmo. I assembled a 5 person team and took on a technical role in the company,
writing most of our backend codebase. Our backend used C#, ASP.NET, Microsoft SQL Server,
and MongoDB. Our infrastructure changed throughout the lifetime of the company, initially
it was on Microsoft Azure using Azure App Service. We then pivoted to AWS using Elastic
Beanstalk. We also ran on Google Cloud Platform using Compute Engine. Finally, we setup our
own servers in-house and managed our deployments with Kubernetes.
</p>
<p>
We launched in 2021, with the ability to send money between real banks using the ACH network.
We ended up processing a few hundred dollars in transaction volume before ultimately shutting
down due to a lack of funding. The website is now back up and everything works as it did in
2021, except adding funds from a bank account is not supported.
</p>
</div>
<div>
<h2>SQUIRREL</h2>
<p>
SQUIRREL stands for SQL Query Util-Izing Rust's Reliable and Efficient Logic. It is a SQL database
that I am writing in Rust. Currently, it can parse CREATE TABLE commands, and works with the
data types varchar and int. I plan to implement basic CRUD operations, then add JOINs, and then
try to make it wire-compatible with Postgres.
</p>
</div>
<div>
<h2>SEPTA Site</h2>
<a href="https://github.com/nickorlow/septa-site">[ GitHub Repo ]</a>
<p>
SEPTA Site is a website that I created which can get your trip history, SEPTA Key balance,
and ridership statistics for your SEPTA Key. It utilizes SEPTA's new metro wayfinding instead
of their current wayfinding. I wrote the project to get a basic introduction to Svelte and
so that I could try to improve upon the UX of SEPTA's current website and mobile app.
</p>
</div>
<div style="width: 100%; display: flex; justify-content: center; padding: 5px;">
<a href="https://github.com/nickorlow">[ See more projects on GitHub ]</a>
</div>
</div>

View file

@ -1 +0,0 @@
/// <reference types="react-scripts" />

View file

@ -1,15 +0,0 @@
import { ReportHandler } from 'web-vitals';
const reportWebVitals = (onPerfEntry?: ReportHandler) => {
if (onPerfEntry && onPerfEntry instanceof Function) {
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry);
getFID(onPerfEntry);
getFCP(onPerfEntry);
getLCP(onPerfEntry);
getTTFB(onPerfEntry);
});
}
};
export default reportWebVitals;

View file

@ -1,5 +0,0 @@
// jest-dom adds custom jest matchers for asserting on DOM nodes.
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom';

View file

@ -1,95 +0,0 @@
import VrboImage from "../images/vrbo-logo-min.png";
import Blog from "../../types/Blog";
import CSMD from "./blogs/c-sharp-c-assignment.md";
import TAB from "./blogs/there-is-a-blog.md";
import HID from "./blogs/hidden-blog.md";
import NWSSSL from "./blogs/nws-how-to-do-ssl.md";
import SP2023 from "./blogs/spring-break-projects-2023.md";
import SPLG1 from "./blogs/side-project-log-3-20-2023.md";
import SPLG2 from "./blogs/side-project-log-3-27-2023.md";
import SPLG3 from "./blogs/side-project-log-4-29-2023.md";
import SPLG4 from "./blogs/side-project-log-7-12-2023.md";
const CSharpBlog: Blog = {
uri: "c-assignments-in-csharp",
title: "Doing C assignments in C#",
date: new Date(2022, 2, 18, 14, 15, 0),
image: VrboImage,
mdfile: CSMD,
private: false
}
const TestBlog: Blog = {
uri: "there-is-a-blog",
title: "There's a Blog!",
date: new Date(2022, 7, 6, 12, 0, 0),
image: VrboImage,
mdfile: TAB,
private: false
}
const PrivateBlog: Blog = {
uri: "private-blog",
title: "This blog can only be accessed via the direct URI",
date: new Date(2022, 7, 6, 12, 0, 0),
image: VrboImage,
mdfile: HID,
private: true
}
const NWSSSLBlog: Blog = {
uri: "ssl-in-nws-cds",
title: "Implementing SSL in NWS CDS",
date: new Date(2023, 0, 20, 12, 0, 0),
image: VrboImage,
mdfile: NWSSSL,
private: false
}
const SpringBreak2023Blog: Blog = {
uri: "spring-break-2023",
title: "Spring Break 2023",
date: new Date(2023, 2, 11, 12, 0, 0),
image: VrboImage,
mdfile: SP2023,
private: false
}
const SideProjectLogOne: Blog = {
uri: "side-project-log-3-20-2023",
title: "Side Project Log 3/20/23",
date: new Date(2023, 2, 20, 12, 0, 0),
image: VrboImage,
mdfile: SPLG1,
private: false
}
const SideProjectLogTwo: Blog = {
uri: "side-project-log-3-27-2023",
title: "Side Project Log 3/27/23",
date: new Date(2023, 2, 27, 12, 0, 0),
image: VrboImage,
mdfile: SPLG2,
private: false
}
const SideProjectLogThree: Blog = {
uri: "side-project-log-4-29-2023",
title: "Side Project Log 4/29/23",
date: new Date(2023, 3, 29, 12, 0, 0),
image: VrboImage,
mdfile: SPLG3,
private: false
}
const SideProjectLogFour: Blog = {
uri: "side-project-log-7-12-2023",
title: "Side Project Log 7/12/23",
date: new Date(2023, 7, 12, 12, 0, 0),
image: VrboImage,
mdfile: SPLG4,
private: false
}
export const AllBlogs: Blog[] = [CSharpBlog, PrivateBlog, TestBlog, NWSSSLBlog, SpringBreak2023Blog, SideProjectLogOne, SideProjectLogTwo, SideProjectLogThree, SideProjectLogFour];

View file

@ -1,29 +0,0 @@
import InfoCardProps from "../../types/InfoCardProps";
const RunningHobby: InfoCardProps = {
title: "Running",
description: "I started running cross country in 7th grade after wanting to beat my friend in the mile. I kept running all the way through to my senior year of high school. I made varsity my sophomore year. Today, I just run with friends casually along with other physical activity like lifting, biking, and kayaking.",
listTitle: "Personal Records",
list:["1600 - 4:34", "3200 - 10:11", "5K XC - 16:43"],
link: "https://tx.milesplit.com/athletes/7325388-nicholas-orlowsky/stats",
linkTitle: "Milesplit Profile",
listClassName: "col-12"
}
const Lifting: InfoCardProps = {
title: "Lifting",
description: "I started lifting as a break from my 6 years and 10,000 miles of running and really liked it.",
listTitle: "Personal Records",
list:["Bench - 270lbs", "Squat - 405lbs", "Deadlift - 405lbs"],
listClassName: "col-12"
}
const VideogameHobby: InfoCardProps = {
title: "Video Games",
description: "Video games are what got me interested in programming in the first place. I tend to play them a lot less now in favor of programming though, I'll occasionally sink a couple hours into a game.",
listTitle: "Favorites",
list: ["Galaga", "Clone Hero", "Minecraft"]
}
export const AllHobbies: InfoCardProps[] = [RunningHobby, Lifting];

View file

@ -1,74 +0,0 @@
import Job from "../../types/Job";
import VrboImage from "../images/vrbo-logo-min.png";
import CavImage from "../images/cavcash-logo-min.png";
import ChicksImage from "../images/chicks-logo.png";
import CompImage from "../images/compwallet-logo.png";
import THDImage from "../images/homdepot-logo.png";
const VrboJob: Job = {
title: "Data Science Intern",
company: "Vrbo, a part of Expedia Group",
uri: "https://vrbo.com",
timespan: "August 2019 - January 2021",
items: [
"Worked on Natural Language Processing chatbot",
"Worked with team to identify dataset patterns",
"Helped reduce wait times",
"Reduced offsite booking attempts"
],
image: VrboImage
}
const CavCashJob: Job = {
title: "CEO & Software Engineer",
company: "CavCash",
timespan: "May 2017 - April 2021",
items: [
"Founded the company",
"Wrote a C# webAPI",
"Managed mongoDB and MSSQL databases",
"Deployed and maintained k8s clusters on bare metal on in-house datacenter",
],
image: CavImage
}
const ChicksJob: Job = {
title: "Software Engineer",
company: "Chicks Gold",
uri: "https://chicksgold.com",
timespan: "April 2021 - October 2021",
items: [
"Added features & bugfixes to .NET 5 API",
"Added features & bugfixes to Aurelia website",
"Worked with team to create new feature & bug tickets",
"Deployed code to k8s cluster"
],
image: ChicksImage
}
const CompWalletJob: Job = {
title: "Chief Technology Officer",
company: "Casino CompWallet",
timespan: "October 2021 - Present",
items: [
"Architected & built in-house advertising platform",
"Work on Ruby-On-Rails API",
"Updated a React Native mobile app used with ~15,000 users"
],
image: CompImage
}
const HomeDepotJob: Job = {
title: "Software Engineering Intern",
company: "The Home Depot",
uri: "https://homedepot.com",
timespan: "May 2022 - August 2022",
items: [
"Developed functionality using React.js, Node.js, and Github CI/CD Pipelines for internal tooling saving 500+ engineering hours annually",
"Optimized automotive section of HomeDepot website. Removed unnecessary code, reducing Javascript sent to clients by ~10%"
],
image: THDImage
}
export const AllJobs: Job[] = [HomeDepotJob, CompWalletJob, CavCashJob, ChicksJob, VrboJob];

View file

@ -1,75 +0,0 @@
import InfoCardProps from "../../types/InfoCardProps";
import ProjectCardProps from "../../types/ProjectCardProps";
const WebsiteProject: ProjectCardProps = {
title: "Personal Site",
description: "As a primarily backend guy, I wrote my last website as a JSON file (imitating a webAPI). Feedback showed that that was a bad idea so I made this pretty neat site (in my opinion). If you like it, feel free to use it yourself! The backend is run in a homemade datacenter (a few Dell Poweredges on a rack) running on Kubernetes.",
shortDescription: "My personal website.",
techUsed:["React", "Typescript", "Bootstrap", "NWS", "Docker", "Kubernetes"],
link: "https://github.com/nickorlow/personal-site",
linkTitle: "GitHub Repo",
imageUrl: ""
}
const RoomyProject: ProjectCardProps = {
title: "Roomy Sentry",
description: "Built software to monitor the presence of a person based on sniffing the wi-fi packets of their mobile devices. Practically used in order to tell if my roommate is home.",
shortDescription: "Find out when your roommate is home",
techUsed: ["C#", ".NET 6", "NoSQL", "Docker", "nginx", "React Native", "Cloudflare"],
link: "https://github.com/nickorlow/roomy-sentry",
linkTitle: "Github Repo",
imageUrl: ""
}
const CavCashProject: ProjectCardProps = {
title: "CavCash",
description: "CavCash started as a project in 2017 as a way to pay with flashdrives. After recruiting a few friends to help me, we build ourselves into a PayPal competitor but shutdown due to funding. I continued to re-write the platform as a cryptocurrency.",
shortDescription: "Like Venmo, but better",
techUsed: ["C#", "Kubernetes", "mongoDB", "MSSQL", "Docker", "nginx", "Azure DevOps", "React", "Cloudflare"],
link: "https://cavcash.com",
linkTitle: "Project Website",
imageUrl: ""
}
const XenMapProject: ProjectCardProps = {
title: "XenMap",
description: "I wanted to use an old iPad as a HUD in my car similar to tesla and it needed a map to complete it. I made this widget to show your current location as a XenHTML widget.",
shortDescription: "Your live location as an iPhone wallpaper",
techUsed: ["HTML", "JavaScript", "CSS", "XenHTML Framework", "XenInfo API"],
link: "https://github.com/nickorlow/MapXenHTML",
linkTitle: "GitHub Repo",
imageUrl: ""
}
const SPONODEProject: ProjectCardProps = {
title: "SPONODE",
description: "App for Android & macOS that added songs people sent you to a playlist. Made so we could have a jukebox type setup during track workouts.",
shortDescription: "Spotify queue management via iMessage",
techUsed: ["Java", "Apple Script", "Spotify API", "node.js"],
link: "https://github.com/nickorlow/sponode",
linkTitle: "GitHub Repo",
imageUrl: ""
}
const NWSProject: ProjectCardProps = {
title: "Nick Web Services",
description: "Nick Web Services is a cloud hosting provider that I created. It was originally one server I got from goodwill in a garage, but now it's 4 servers across 2 states (PA & TX).",
shortDescription: "My own cloud provider",
techUsed: ["Kubernetes", "Rancher", "C#"],
link: "https://nws.nickorlow.com",
linkTitle: "Project Website",
imageUrl: ""
}
const Mahantongo: ProjectCardProps = {
title: "Mahantongo",
description: "I'm one of the members of the Community Team that runs some UT Computer Science community Discord servers. Currently, a Discord bot called Carlbot provides us a star-board, which is a specific channel where messages that 5 or more people react to with a star emoji get posted. It's supposed to be a collection of the funniest and best messages sent on the server. One of the things our server members have wanted is the addition of more '*-board' channels where you can create multiple star-board like channels but with custom emojis. \n\n I wrote this bot in Rust using Serenity to interact with the Discord API and it helped me gain a better understanding of Rust. It is hosted on NWS.",
shortDescription: "A Discord bot to show off the best (or worst) of your server.",
link: "https://github.com/nickorlow/mahantongo",
linkTitle: "Github Repo",
techUsed: ["Discord API", "Rust"],
imageUrl: ""
}
export const AllProjects: ProjectCardProps[] = [WebsiteProject, NWSProject, Mahantongo, RoomyProject, XenMapProject, CavCashProject, SPONODEProject];

View file

@ -1,63 +0,0 @@
Thanks to Arpan Dhatt for doing most of the work on this (his blog here: [https://arpan.one/posts/messing-with-gradescope/](https://arpan.one/posts/messing-with-gradescope/))
At the end, he made this comment:
>And so, that's the end of this post. To whom it may concern, don't try doing your C assignment in C# (you know who you are).
The reason for this comment (besides the fact that I talk about C# a lot) is due to the fact that C# requires a runtime to be installed for it to work. This is because C# does not compile to native bytecode but rather compiles to an intermediary language (dubbed CIL by Microsoft) and is then translated 'Just In Time' by the runtime.
This makes running assignments in a docker container where the runtime is not already installed considerably hard. One option we have is that we could just include the runtime in our submission. Sounds easy, right? Well it would be non-trivial to do but due to the fact that the .NET runtime is very large, I wouldn't consider this a good idea (Not to mention it's super boring).
The better solution is to use .NET's (experimental) AOT compilation feature (formerly called CoreRT). C# has had a number of attempts at an AOT compiler such as :
- [AOT](https://www.mono-project.com/docs/advanced/aot/) by Mono
- LLD2CPP built by Unity
- [Ready2Run](https://docs.microsoft.com/en-us/dotnet/core/deploying/ready-to-run) by Microsoft
We'll be using the official Ready2Run AOT compilation built by Microsoft. In order to use it, all you have to do is add the following to your `nuget.config`:
```xml
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
```
and then install the package: `Microsoft.DotNet.ILCompiler`. After doing that if you run the command: `dotnet publish -r [Runtime] -c [Config]` and after waiting a considerable amount of time, you'll have a full-fledged C# application compiled directly to your target runtime's bytecode!
Compiling my simple Hello, Wold test to linux-x64 (`dotnet publish -r linux-x64 -c Release`) and adding it to my project files should let me run it using the same method Arpan used in his blog.
After doing that, we can follow the instructions followed by Arpan and viola! C# runs on Gradescope!
I don't recommend this but it was fun to do and I needed stuff to write in a blog.
## Other Interesting (Low Level) C#/.NET Features
C# actually has many lower level features people don't expect it to have. Some of these include pointers and direct memory management. Pointers can be enabled by encasing your code in an unsafe code block.
Example (Written by [Microsoft](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/unsafe-code))
```csharp
// Normal pointer to an object.
int[] a = new int[5] { 10, 20, 30, 40, 50 };
// Must be in unsafe code to use interior pointers.
unsafe
{
// Must pin object on heap so that it doesn't move while using interior pointers.
fixed (int* p = &a[0])
{
// p is pinned as well as object, so create another pointer to show incrementing it.
int* p2 = p;
Console.WriteLine(*p2);
// Incrementing p2 bumps the pointer by four bytes due to its type ...
p2 += 1;
Console.WriteLine(*p2);
p2 += 1;
Console.WriteLine(*p2);
Console.WriteLine("--------");
Console.WriteLine(*p);
// Dereferencing p and incrementing changes the value of a[0] ...
*p += 1;
Console.WriteLine(*p);
*p += 1;
Console.WriteLine(*p);
}
}
```
In .NET 6, the `NativeMemory` class was introduced which you can read about [here](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.nativememory.alloc?view=net-6.0). It allows for malloc-like memory allocation and freeing which can be important for high-performance workloads.

View file

@ -1,3 +0,0 @@
This blog is unique because it is hidden.
Congratulations on finding it! Did you get here by trying out a bunch of URLs or from my [There is a Blog](http://nickorlow.com/blog?id=2) Blog?

View file

@ -1,21 +0,0 @@
##### Background
NWS has a service that is tentatively called "Container Deployment Service (CDS)" (It was previously called "Cruise"). This service allows people to deploy a docker container to our cluster of kubernetes clusters. In it's current (read: early) form, NWS will add a GitHub Actions pipeline yaml file to the repo which a user wants to deploy. This yaml file will create a dockerfile, and build it into a docker container with 2 tags: an autogenerated semver, and the name of the branch. From here, the NWS API will store metadata about the application in a database and then add the kubernetes deployment manifests to a gitrepo (this is a newish thing that I learned about called gitops). [Rancher Fleet](https://fleet.rancher.io/) periodically scans this repo, and when it sees the new yaml file, it deploys it to all kubernetes clusters on the NWS network. Then, we use DNS loadbalancing to balance the load between all of the clusters. Formerly, we used HAProxy to balance requests, we no longer do but HAProxy is still running on the servers (this detail will be important later).
##### The Issue
In order to provide a secure connection for end-users of applications hosted on NWS (and so that browsers won't spit out warning messages that the site is insecure), it is important to have [SSL](https://www.websecurity.digicert.com/security-topics/what-is-ssl-tls-https) setup. This is rather complicated to do since we want:
1. Each application to have it's own certificate
2. Certificates to be able to auto-renew
3. Certificates to be able to auto-generate
We have 3 (main) options for enabling SSL on NWS:
1. We have people who host on NWS upload their own SSL certificates. This can be a pain since SSL certificates aren't super easy to generate, and the user would have to remember to upload new certificates.
2. (This is what applications on NWS currently do) Proxy traffic through Cloudflare, which uses it's "Flexible" SSL option to allow for the connection between the client and CF to be encrypted while the connection between CF and NWS is not. This is insecure as traffic between CF and NWS is not encrypted. This is not ideal but currently since it's just personal sites, it's not a _huge_ deal. Additionally, this would require everyone who wants to host on NWS to use Cloudflare
3. We use a tool to autogenerate certificates. This would be very hard to do with NWS' load balancing, but ultimately may be the best option.
Getting auto generated SSL certificates is easy enough to do on a traditional webserver by using a tool such as `certbot`. However, since we have many instances of a single application running *and* we have multiple clusters running them, it would be hard to properly route requests to the pod that is running certbot. Additionally, trying to have all of the pods run `certbot` at once would not work since they would all generate unique certificate requests.
##### The Solution
The way NWS will work around this will be by having HAProxy to route all requests to the path `.well-known/acme-challenge/*` to an SSL generation server running on NWS. This server will run software that at some arbitrary time during the day will check the expiry of all SSL certificates, and any expiring within the next week will be renewed by certbot. Once renewed, they will be committed to the aforementioned git repo with the k8s manifest files. In the case of new applications, they will have their certificate request made automatically after creation.

View file

@ -1,36 +0,0 @@
This blog is also avaliable to read on the [NWS blog]().
The NWS website got a facelift recently and with it came some technical changes.
I also figured that I would take this time to explain how some of NWS' services work
and how I plan to expand upon them in the future.
## Addition of new API Features
With this update, the NWS API got 3 new features: Uptime Monitoring, Incident Reporting,
and Blogging.
###Uptime Monitoring
Uptime Monitoring has been a part of the NWS website since its creation, however
it was achieved by calling the API of the uptime monitoring service we use directly. This
came with issues such as rate limiting if too many people visited the NWS website and
we exposed the API key to clients, making it so that an attack in which someone
causes our API key to be ratelimited would be possible.
In this update, Uptime Monitoring was baked into the NWS API itself. The API still calls
out to the aforementioned uptime monitoring service however, now the NWS website
gets all of it's information from the NWS API. This fixes both of the problems above and
allows for us to add more data to the endpoint in the future.
There were two approaches I tried for this and ultimately decided on one. The first
approach was to store the uptime data in a static variable in the API and whenever a
user requested the data and the data was stale, we would fetch new data and return that.
This was seen as a potential solution as it prevents API calls from being made when people aren't
visiting the NWS website a lot.
//TODO: FINISH
### Incident reporting
### Blogging
Blogging is not yet incorporated into the NWS website, however the backend is built out.
The Blogging part of this
## NWS Website Redesign

View file

@ -1,28 +0,0 @@
Spring break just wrapped up. I wrote a [blog]() last week about the side projects that I was planning on
doing. I wanted to provide an update on what I got done, and figured I'd turn it into a recurring thing.
This side project log covers work done from 3/13/2023 - 3/20/2023
## [Personal Website Facelift](https://github.com/nickorlow/personal-site)
I managed to move my website over to tab-based navigation pretty early on in the break. It just involved setting
up a navbar component and then using react-navigation to navigate between pages. I also managed to
update my projects page to be more compact and readable.
There is still work to be done on making it look better, but I mostly believe that
it's just going to be somewhat minor tweaks.
## [Mahantongo](https://github.com/nickorlow/mahantongo)
I managed to finish this one. I learned a lot about Rust and I've gained an appreciation for
Rust's enforcement of good programming habits, and I really like how error handling is done.
Working with Serenity was pretty easy as it mirrored some of the other Discord SDKs I've used
before.
---
**The below projects had minimal/no work done on them:** RingGold, NWS Container Deployment Service, and VerifiedBot

View file

@ -1,29 +0,0 @@
This side project log covers work done from 3/20/2023 - 3/27/2023
## SEPTA Site
I started a new project that aimed to recreate parts of SEPTA's website with a more elegant UI, and using
SEPTA's new "SEPTA Metro" wayfinding. The main goal with this project was to help me learn Svelte. I also had
to reverse-engineer the APIs on septakey.org in order to authenticate a user and get their trip history.
In terms of Svelte, I really enjoyed working with it and overall I found it much more elegant and easier to work
with than React. I didn't like the way it handled client-server interaction with its serverside functions.
I have not made this open source yet and do not intend to until it's more polished.
## [Verified Bot](https://github.com/benaubin/verified-bot)
I made all the necessary changes and tests to get VerifiedBot working. It is now waiting on my friend Ben
to merge my PR with the changes outlined in my [spring break blog](https://nickorlow.com/blog/spring-break-2023).
## [Mahantongo](https://github.com/nickorlow/mahantongo)
I created some QoL features, such as using Discord's embeds instead of sending regular text messages, showing which board
a post was on, and fixing some bugs.
---
**The below projects had minimal/no work done on them:** RingGold, and NWS Container Deployment Service

View file

@ -1,36 +0,0 @@
This side project log covers work done from 3/27/2023 - 4/29/2023
This side project log is a bit late due to it being a busy month of school, but today is my last day!
## SEPTA Site
This week, I published SEPTA Site on Github, you can find it here: [github.com/nickorlow/septa-site](https://github.com/nickorlow/septa-site).
I made a few tweaks to it in terms of styling and also wrote a descriptive README to give people instructions on how to run it as I don't want
to host it myself since it handles credentials from another service.
## SQUIRREL
SQUIRREL, short for SQL Query Util-Izing Rust's Reliable and Efficient Logic, is a SQL database that I am writing in Rust. Currently, it can
parse CREATE TABLE commands, and works with the data types varchar and int. I plan to implement basic CRUD operations, then add JOINs, and
then try to make it wire-compatible with Postgres.
This project is currently not open-sourced as I am waiting to add more features and polish it up more.
## Swole Control
This one isn't a *personal* project, however it is a project that I worked on with a group. We began working on it in February as a part of a
club at UT called Texas Convergent. We recently presented it at the club's demo day and won the prize for having the best business.
Swole Control is an app that monitors machine usage at a gym on a machine-by-machine level, providing gym goers with information about what machines
are free (this is a major pain point as a gym goer myself). It also provides gym owners with statistics on which machines are most popular, providing
them valuable insights into their business.
To achieve this, we built hardware that consisted of an ESP-32 micro controller and an ultrasonic distance sensor. This hardware is mounted on a gym machine
and it measures the distance to the nearest object. It then sends this measurement to a Rust backend which stores it in a Firestore database (although we had
a fork of it that worked with Postgres). The backend then uses these measurements and compares them to a baseline to determine if there is a user at a machine.
Our mobile app then reads this from the Firestore database (it's planned to have it read this from the API to have a better-defined application boundary). The
frontend is written in React Native.
---
**These projects had minimal/no work done on them:** RingGold, and NWS Container Deployment Service

View file

@ -1,87 +0,0 @@
This side project log covers work done from 4/29/2023 - 7/12/2023
This side project log is more than a bit late due to working a busy summer internship at [FUTO](https://futo.org)!
## NWS Container Deployment Service
I have finally added SSL to NWS CDS. This was challenging, as it required handling ACME challenges and certificate
distribution across a set of geo-distributed Kubernetes clusters. I detail the complexities of this in a [previous blog
I wrote](http://nickorlow.com/blog/ssl-in-nws-cds). In order to implement auto-created/auto-renewing SSL, I implemented the below solution:
![Diagram of NWS SSL Architecture](/blog-images/NWS_SSL_Diagram.png)
First, a user creates a request to add SSL to their NWS CDS service through the web UI which calls the NWS API (not pictured)
Then, the NWS API calls SSLiaison (in-house written software) which adds the domain to Caddy's list of domains. Caddy will then attempt to create
an SSL certificate from an ACME server (not pictured).
The ACME server will query NWS for the challenge response by requesting a file at `/.well-known/acme-challenge` on the
domain to be verified (this is the green arrows).
HAProxy will re-route these requests to NWS Hill Country, which is where the NWS Management Engine (NWSME) lives (this is
the orange arrows). *(NWSME controls what's deployed on each k8s cluster on NWS)*
HAProxy in NWS Hill Country will then route this request to Caddy, which will solve the [http-01 challenge](https://letsencrypt.org/docs/challenge-types/), and then get the certificate
from the ACME server. Once it does this, it will write the certificate to a directory that is bind-mounted to both Caddy
and SSLiaison.
SSLiaison will detect this new file, parse it into a k8s manifest file, and then add it to our GitOps repo which is
hosted in GitHub.
From here, the certificate will be added to all the k8s clusters via Rancher Fleet.
---
For next steps, I'd like to revise this solution such that it doesn't have a single point of failure.
Currently, if NWS Hill Country is down (which it is about 0.025% of the time), then SSL certificates
won't be able to be created or renewed.
To do this, I will have SSLiaison implement the ACME client specification so that it can create and respond do ACME HTTP challenges.
SSLiaison will run on NWS CDS (so that it's running on all of our k8s clusters and is HA) instead of running as a standalone docker container.
I'll have SSLiaison use some distributed database (probably CockroachDB) to store the HTTP challenges so that it doesn't matter
which k8s cluster the challenge request from the ACME server is routed to.
## Next Steps for NWS
- **HA NWS Management Engine:** Currently (as somewhat discussed above), the NWSME will go down when NWS Hill Country goes down. I'd like to
make it so that this isn't the case. This would likely just require that each NWS cluster runs its own instance of Rancher Fleet instead
of one central Rancher Fleet that manages all the clusters. It would also require the HA SSLiaison.
- **IaC for Everything:** Currently, all NWS CDS services are defined in yaml files in a git repo, however the underlying infrastructure that
it runs on is not. Ideally, I'd like every NWS machine to run Proxmox and then have Terraform & Ansible configs to define how to set up
vms on proxmox that will run the k8s clusters that support CDS services. This should eliminate my headaches of sshing into each machine
to apply config changes and make sure everything is standardized. It should also make the process of setting up new servers easy.
- **Monitoring:** I've been working on setting up monitoring on a lot of our services at my current internship using the TIG stack (Telegraf,
InfluxDB, and Grafana). Now that I've been exposed to the usefulness of having a bunch of metrics on hand, I think it would be nice to have
some dashboards setup for NWS to monitor speed, resource usage, uptime, and traffic. Doing this would also make it possible to expose resource usage in the
NWS dashboard.
- **Enhanced Infrastructure:** This is kind of a blanket one for things I want to do that don't fit into other categories. It includes making
hardware upgrades (mostly adding more storage), make management more accessible (such as Dell IDRAC's WebSerial), some load testing to
identify painpoints, run an NWS machine in a cloud VM so I can say it's cross cloud (although my friends have told me this is cheating at creating
my own cloud), and trying to figure out how to set up an Anycast network. I don't think I can setup an Anycast network without selling
a kidney first. Renting a /24 CIDR alone would be more than I want to spend on a side project. I may look into setting it up with ipv6 only,
however I'd still have to jump through hoops to get an Autonomous System number from an RIR. I'll probably write a whole blog about Anycast
in the coming weeks.
- **Reduced External Dependence:** The main goal of NWS is to have no external dependence. In theory, everything but core internet infrastructure
should
## Olney
`Rust, ActixWeb, PostgreSQL`
Olney is a new project I am starting with my friend [Sridhar Nandigam](https://sridharnandigam.com/). It aims to make
tracking your job applications easier. Most of my friends either use spreadsheets or Trello to track their job applications, I
think that we can make something that's a bit better for the job. Some features I'd like to have are: resume version attached to
your application, job posting notifications from job boards such as [pittcsc](github.com/pittcsc/summer2024-internships), and watching
your email for emails from recruiters. Currently, I have part of the backend setup with basic CRUD operations. Now that I'm done with
the latest batch of NWS work, this is next on my list to work on.
---
**These projects had minimal/no work done on them:** RingGold, SQUIRREL

View file

@ -1,68 +0,0 @@
It's Spring Break, and that means I finally have time to spend all day working on side projects without having to worry about school.
I figured I should write out the side projects I plan to work on over the break
## RingGold
`Rust, Swift, PostgreSQL`
Last week, me and my cousin wanted to try out Apple's fitness competition feature that works with Apple Watch. It works
by giving you 1 point for every percent you complete of your move, exercise, and stand goals with a point cap of 600
per day. The issue with it was that it didn't work at all, not syncing on time if at all. I want to build a clone of it
with some additional features such as:
- **Notifications:** I didn't like how it was possible to workout and gain a bunch of points and just completely blindside your opponent. Hopefully this would encourage users to workout even more.
- **Widget/Watch Complication:** Similar to the above, adding a homescreen widget or a watch complication would make it easier to keep up with your competitor's progress.
- **Custom Competitions:** I think it'd be nice to have competitions with custom rules and lengths so that you're not stuck with only one setting. Settings could include custom duration and custom caps on points.
I'm building the web API for it in Rust and the mobile app in Swift. I chose these languages to gain more exposure to them, also
Swift was a good choice since the app is going to be platform specific to iOS due to its need to integrate with Apple Watch.
*(this is named after New Ringgold, PA)*
## NWS Container Deployment Service
`C#, Rancher`
I've created my own hosting/cloud service called [Nick Web Services](https://nws.nickorlow.com). It currently allows people to deploy
dockerized applications on my geo-distributed k8s clusters running on Dell Poweredge servers. In order to actually deploy this, I
had to manually create the Kubernetes manifest files and then ssh into each individual server and apply them. I've setup
Rancher Fleet to automate this process by pulling the manifest from a git repo (this is something called gitops). I also
wrote an API to generate the manifest files and then upload them to a git repo. I have a video demo of this working that
you can watch [here](https://youtu.be/WHdXWMFHuqA).
Currently, the service works for deployment but only if you don't want to use SSL or you use Cloudflare's flexible SSL
technology. I wrote a separate blog post [here](http://nickorlow.com/blog/ssl-in-nws-cds) about the challenges of doing this and how I plan on implementing it.
I'd like to complete part of this implementation during the break.
## VerifiedBot
`JavaScript, Rust`
This project isn't a personal project, as a lot of it was built by my friends [Arpan](https://arpan.one) and [Ben](https://benaubin.com/).
A little over a year ago, we wanted to make a Discord bot to verify that people on some Discord servers we ran
went to the University of Texas. Initially, it worked by verifying you had a utexas.edu email address and then verifying
some additional information via LDAP. A few months ago Ben found out that using the SaaS survey software that the university uses
(qualtrics), we could have users verify themselves by using the university's SSO system. This works because qualtrics can send
data to a webhook when a survey is complete, and it can also require signing in with the university's SSO before filling out a survey.
It required that I write a [wasm wrapper for an encryption library](https://github.com/Verified-Bot/aes-gcm-siv-wasm). I wrote almost all the code for this function last year, but
due to a bug in qualtrics, it wasn't working properly. It seems that this bug has been fixed and we can start rolling it out.
## Personal Website Facelift
`Typescript, React`
My personal website (this one) is a little overdue for some design updates. My main focus will be making it more mobile
friendly. Last year, I made some improvements to make it usable on mobile but it still doesn't feel quite right. I also
think that it has some information overload in some areas such as the projects section. I think that to mitigate this I
might just have a small summary of each project and then you can click into each to learn more about it, similar to my
friend [Raul's Website](https://raulhigareda.com). I'm also considering a move to tab-based navigation so that I can have
more information in each section. Further down the line, I think I might re-write it using Svelte as I'm seeing it being used more and more
and would like to get some exposure to it.
## Mahantongo
`Rust, PostgreSQL`
I'm one of the members of the Community Team that runs some UT Computer Science community Discord servers.
Currently, a Discord bot called Carlbot provides us a star-board, which is a specific channel where messages that 5 or more people
react to with a star emoji get posted. It's supposed to be a collection of the funniest and best messages sent on the server.
One of the things our server members have wanted is the addition of more '*-board' channels where you can create multiple star-board
like channels but with custom emojis. I'm writing it in Rust and I'm just hoping to use this project to get more acquainted with the language.

View file

@ -1,80 +0,0 @@
My Website now has a blog! I've always wanted to write a blog and I've been keeping a collection of writings in Google Docs that I'll eventually move over here.
In this blog, I'm going to discuss how I built this blog and the differences it has with the other blogs I've built. As a point of comparison to this blog, I'm going
to be using the [CavCash Newsroom](https://cavcash.com/newsroom) which I also built.
## How I built this blog
This blog has no real backend. Blogs are written in Markdown files that are hosted with this website, which itself is a React webapp. I then have a file that adds metadata
to the blogs such as a title and a date. The metadata file looks like this:
```typescript
import BlogImage from "../images/blog-img-min.png";
import Blog from "../../types/Blog";
import CSMD from "./blogs/c-sharp-c-assignment.md";
import TAB from "./blogs/there-is-a-blog.md";
const CSharpBlog: Blog = {
title: "Doing C assignments in C#",
date: new Date(2022, 2, 18, 14, 15, 0),
image: BlogImage,
mdfile: CSMD,
private: false
}
const TestBlog: Blog = {
title: "There's a Blog!",
date: new Date(2022, 7, 6, 12, 0, 0),
image: BlogImage,
mdfile: TAB,
private: false
}
const PrivateBlog: Blog = {
title: "This blog can only be accessed via the direct URI",
date: new Date(2022, 7, 6, 12, 0, 0),
image: BlogImage,
mdfile: TAB,
private: true
}
export const AllBlogs: Blog[] = [CSharpBlog, PrivateBlog, TestBlog];
```
This metadata then gets converted into a list and whenever you view a blog, it fetches the associated markdown file and parses it to show you here.
I decided to add an option to hide some blogs from the 'All blogs' page (Notice how you don't see [This Blog](http://nickorlow.com/blog?id=1) there?)
It's intended to be used so I can host things like Privacy Policies and Terms of Services for apps I write without cluttering up my blog.
You may have noticed that there's an unused Image option. This option would provide a thumbnail, but I decided to remove them for now in favor of a cleaner look.
## How I built the CavCash Newsroom
The CavCash Newsroom does have a backend. The backend is a part of the larger CavCashAPI which also manages the rest of the backend code for CavCash.
It simply stores blog details in a MongoDB collection and returns them to the React frontend. It also supports 'private' blogs, however, it filters
out the private blogs in the backend which makes it harder to find a private blog. An entry for a CavCash Newsroom entry looks like this:
```json
{
"_id" : ObjectId("60ecc0b23eae899e4e46616f"),
"BlogID" : NumberInt(3),
"Title" : "CavCash acquires Apple Inc",
"Author" : "nickorlow",
"CreatedDate" : ISODate("2021-07-12T22:22:41.000+0000"),
"HideBlog": false,
"Content" : "*AUSTIN, TX* - CavCash Inc has finalized a deal to buy Apple Inc (NASDAQ: AAPL) for 3.3 trillion dollars. This marks the 3rd 'FAANG' company CavCash has acquired, with the others being Google and Amazon. CavCash CEO Nicholas Orlowsky has been quoted as saying: \"We are pleased to welcome Apple to the CavCash family.\"\n\nApple CEO Tim Cook was enthused about the deal, expressing excitement for Apple's integration into the overall CavCash ecosystem. Tim will remain CEO of Apple for at least the next two years. \n\nSome have expressed antitrust concerns about CavCash becoming a monopoly.\"\n",
"CoverImage" : "data:image/jpeg;base64,/9j/4AAQS...GMvWWXtB1/9k="
}
```
This blog looks like the following:
![cavcash-newsroom](/blog-images/example-blog-list.png)
![cavcash-newsroom](/blog-images/example-blog-content.png)
_Screenshot of CavCash Newsroom_
## Comparison of CavCash Newsroom and this Blog
CavCash Newsroom needed to be able to be published to without pushing new code to the frontend. We also already had an API written for other things that I could just add
blog functionality to, so I chose to write it with a C# backend and a React frontend. The CavCash Newsroom also has some features not present in this blog such as author information and cover images. These features were left out because I am the only author on this blog, and I decided that cover images wouldn't be necessary.
This blog does not have a backend api associated with it and using a blog API seemed like more trouble than building the feature myself. In order to ship blogs quickly and not create unnecessary complexities in my codebase, I decided to just have markdown files that were included in the frontend as my blogs. As I write more blogs this may prove to be a poor idea for performance but that's a bridge I can cross when I get there (Maybe build my own [NWS](https://nws.nickorlow.com) Blogging service?).

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

View file

@ -1,30 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" id="Chicks_Logo" width="152.29" height="31.163" viewBox="0 0 152.29 31.163">
<defs>
<style>
.cls-1{fill:#b2b3b8}
</style>
</defs>
<g id="Group_3877" transform="translate(-34.915 -20.729)">
<g id="Group_3879" transform="translate(223.269 -273.021)">
<g id="Group_3878" transform="translate(-80.713 293.75)">
<g id="Group_3928">
<path id="Rectangle_287" d="M0 0H8.855V1.373H0z" class="cls-1" transform="translate(3.777 14.783)"/>
<path id="Rectangle_288" d="M0 0H8.855V0.635H0z" class="cls-1" transform="translate(3.777 13.84)"/>
<path id="Path_3334" d="M468.273 297.634a.532.532 0 0 0-.212 1.019l-2.968 5.539h-.661l.876-7.74a.608.608 0 1 0-.14-.014l-2.332 7.7h-.652l-1.032-8.891a.757.757 0 1 0-.206 0l-.908 8.89h-.652l-2.408-7.727a.6.6 0 1 0-.209.039.615.615 0 0 0 .126-.013l.844 7.855h-.669l-3.324-5.652a.529.529 0 1 0-.231.054.509.509 0 0 0 .08-.008l3.166 8.488h8.855l2.578-8.488a.521.521 0 0 0 .079.008.532.532 0 0 0 0-1.064z" class="cls-1" transform="translate(-452.982 -293.75)"/>
</g>
</g>
</g>
<g id="Group_3881" transform="translate(35.915 38.821)">
<path id="Path_3324" d="M-184.283 393.354a6.466 6.466 0 0 1 2.3.346 8.281 8.281 0 0 1 1.6.808q.423.266.646.062a1.66 1.66 0 0 0 .307-.968h.487q-.043.675-.064 1.625t-.021 2.531h-.487q-.148-.781-.286-1.279a3.235 3.235 0 0 0-.36-.852 3.223 3.223 0 0 0-.6-.693 3.539 3.539 0 0 0-1.5-.924 6.159 6.159 0 0 0-1.884-.284 3.9 3.9 0 0 0-1.905.453 3.95 3.95 0 0 0-1.387 1.287 6.4 6.4 0 0 0-.857 1.971 9.836 9.836 0 0 0-.3 2.486 9.262 9.262 0 0 0 .317 2.513 5.847 5.847 0 0 0 .921 1.936 4.151 4.151 0 0 0 1.461 1.243 4.171 4.171 0 0 0 1.916.435 5.988 5.988 0 0 0 1.8-.293 3.291 3.291 0 0 0 1.482-.9 2.8 2.8 0 0 0 .815-1.2 10.014 10.014 0 0 0 .37-1.82h.487q0 1.634.021 2.637t.064 1.7h-.487a1.75 1.75 0 0 0-.286-.959q-.2-.2-.667.053a11.757 11.757 0 0 1-1.662.808 6.219 6.219 0 0 1-2.254.346 8.265 8.265 0 0 1-3.662-.764 5.675 5.675 0 0 1-2.434-2.2 6.578 6.578 0 0 1-.868-3.463 6.605 6.605 0 0 1 .9-3.48 6.257 6.257 0 0 1 2.466-2.327 7.583 7.583 0 0 1 3.611-.834z" class="cls-1" transform="translate(190.269 -393.354)"/>
<path id="Path_3325" d="M-98.578 407.437v-.354a4.523 4.523 0 0 0 1.033-.142.657.657 0 0 0 .456-.425 3.1 3.1 0 0 0 .111-.957v-8.786a3.081 3.081 0 0 0-.111-.965.685.685 0 0 0-.466-.425 3.826 3.826 0 0 0-1.023-.133v-.354q.465.018 1.2.035t1.59.018q.77 0 1.509-.018t1.225-.035v.354a3.7 3.7 0 0 0-1.013.133.713.713 0 0 0-.466.425 2.833 2.833 0 0 0-.122.965v8.786a2.847 2.847 0 0 0 .122.957.685.685 0 0 0 .466.425 4.43 4.43 0 0 0 1.013.142v.354q-.486-.035-1.225-.044t-1.509-.009q-.851 0-1.59.009t-1.2.044zm3.017-6.129v-.354h8v.354zm5.488 6.129v-.354a4.524 4.524 0 0 0 1.033-.142.657.657 0 0 0 .456-.425 3.1 3.1 0 0 0 .111-.957v-8.786a3.081 3.081 0 0 0-.111-.965.685.685 0 0 0-.466-.425 3.827 3.827 0 0 0-1.023-.133v-.354q.506.018 1.266.035t1.509.018q.851 0 1.579-.018t1.175-.035v.354a3.7 3.7 0 0 0-1.013.133.713.713 0 0 0-.466.425 2.833 2.833 0 0 0-.122.965v8.786a2.847 2.847 0 0 0 .122.957.685.685 0 0 0 .466.425 4.428 4.428 0 0 0 1.013.142v.354q-.446-.035-1.175-.044t-1.579-.009q-.749 0-1.509.009t-1.265.044z" class="cls-1" transform="translate(113.581 -394.631)"/>
<path id="Path_3326" d="M9.551 394.895v.354a3.927 3.927 0 0 0-1.044.133.728.728 0 0 0-.481.425 2.753 2.753 0 0 0-.125.965v8.786a2.766 2.766 0 0 0 .125.957.7.7 0 0 0 .481.425 4.7 4.7 0 0 0 1.044.142v.354q-.5-.035-1.264-.044t-1.556-.009q-.877 0-1.64.009t-1.243.044v-.354a4.8 4.8 0 0 0 1.065-.142.67.67 0 0 0 .47-.425 3.006 3.006 0 0 0 .115-.957v-8.786a2.992 2.992 0 0 0-.115-.965.7.7 0 0 0-.48-.425 4.062 4.062 0 0 0-1.055-.133v-.354q.48.018 1.243.035t1.64.018q.794 0 1.556-.018t1.264-.035z" class="cls-1" transform="translate(27.92 -394.631)"/>
<path id="Path_3327" d="M66.723 393.354a5.757 5.757 0 0 1 2.161.346 7.627 7.627 0 0 1 1.5.808q.4.266.608.062a1.728 1.728 0 0 0 .289-.968h.458q-.04.675-.06 1.625t-.02 2.531H71.2q-.14-.781-.269-1.279a3.347 3.347 0 0 0-.339-.852 3.175 3.175 0 0 0-.568-.693 3.3 3.3 0 0 0-1.414-.924 5.482 5.482 0 0 0-1.773-.284 3.5 3.5 0 0 0-1.793.453 3.815 3.815 0 0 0-1.3 1.287 6.613 6.613 0 0 0-.807 1.971 10.423 10.423 0 0 0-.279 2.486 9.811 9.811 0 0 0 .3 2.513 6.012 6.012 0 0 0 .867 1.936 3.979 3.979 0 0 0 1.374 1.243 3.735 3.735 0 0 0 1.8.435 5.331 5.331 0 0 0 1.693-.293 3.072 3.072 0 0 0 1.394-.9 2.818 2.818 0 0 0 .767-1.2 10.582 10.582 0 0 0 .348-1.82h.458q0 1.634.02 2.637t.06 1.7h-.458a1.828 1.828 0 0 0-.269-.959q-.189-.2-.627.053a10.8 10.8 0 0 1-1.564.808 5.539 5.539 0 0 1-2.121.346 7.39 7.39 0 0 1-3.446-.764 5.471 5.471 0 0 1-2.291-2.2 7.663 7.663 0 0 1 .03-6.943 6.055 6.055 0 0 1 2.32-2.327 6.793 6.793 0 0 1 3.41-.834z" class="cls-1" transform="translate(-19.589 -393.354)"/>
<path id="Path_3328" d="M158.438 394.895v.354a3.787 3.787 0 0 0-1.025.133.719.719 0 0 0-.472.425 2.8 2.8 0 0 0-.123.965v8.786a2.815 2.815 0 0 0 .123.957.69.69 0 0 0 .472.425 4.534 4.534 0 0 0 1.025.142v.354q-.492-.035-1.24-.044t-1.527-.009q-.861 0-1.609.009t-1.22.044v-.354a4.632 4.632 0 0 0 1.045-.142.662.662 0 0 0 .461-.425 3.06 3.06 0 0 0 .113-.957v-8.786a3.046 3.046 0 0 0-.113-.965.691.691 0 0 0-.471-.425 3.917 3.917 0 0 0-1.035-.133v-.354q.471.018 1.22.035t1.609.018q.779 0 1.527-.018t1.24-.035zm6.724 0v.354a4.354 4.354 0 0 0-1.3.4 4.461 4.461 0 0 0-1.3 1.019l-3.936 4.251.7-1.081 4.92 6.165a2.918 2.918 0 0 0 .707.673 3.372 3.372 0 0 0 .974.407v.354q-.554-.035-1.333-.044t-1.374-.009q-.369 0-.912.009t-1.363.044v-.354a1.611 1.611 0 0 0 .933-.212q.174-.177-.154-.585l-2.973-3.986a5.2 5.2 0 0 0-.656-.753 1.442 1.442 0 0 0-.594-.337 3.651 3.651 0 0 0-.759-.1v-.372a3.387 3.387 0 0 0 1.486-.337 4.722 4.722 0 0 0 1.179-.868l1.7-1.86a4.328 4.328 0 0 0 .923-1.3.7.7 0 0 0-.1-.824 1.786 1.786 0 0 0-1.148-.3v-.354l1.281.035q.646.018 1.3.018 1.143 0 1.799-.053z" class="cls-1" transform="translate(-97.077 -394.631)"/>
<path id="Path_3329" d="M250.861 393.574a4.308 4.308 0 0 1 1.537.213 5.947 5.947 0 0 1 .93.461q.228.125.37.186a.683.683 0 0 0 .275.062q.3 0 .418-.781h.437q-.019.319-.048.754t-.038 1.145q-.01.71-.009 1.864h-.433a5.089 5.089 0 0 0-.408-1.687 3.272 3.272 0 0 0-1.025-1.332 2.749 2.749 0 0 0-1.718-.515 2.387 2.387 0 0 0-1.6.542 1.785 1.785 0 0 0-.636 1.429 2.025 2.025 0 0 0 .418 1.3 4.428 4.428 0 0 0 1.148.977q.73.453 1.661 1 .949.569 1.708 1.128a4.764 4.764 0 0 1 1.2 1.234 2.943 2.943 0 0 1 .437 1.634 3.046 3.046 0 0 1-.579 1.909 3.472 3.472 0 0 1-1.547 1.128 5.872 5.872 0 0 1-2.126.373 5.406 5.406 0 0 1-1.689-.213 7.37 7.37 0 0 1-1.063-.444 1.432 1.432 0 0 0-.645-.249q-.3 0-.418.781h-.437q.038-.39.047-.914t.019-1.376q.009-.852.009-2.148h.437a7.439 7.439 0 0 0 .427 2.06 3.389 3.389 0 0 0 1.082 1.536 3.05 3.05 0 0 0 1.945.577 2.787 2.787 0 0 0 1.689-.542 1.96 1.96 0 0 0 .74-1.7 2.315 2.315 0 0 0-.807-1.8 12.483 12.483 0 0 0-2.116-1.465q-.892-.532-1.67-1.065a4.485 4.485 0 0 1-1.243-1.243 3.007 3.007 0 0 1-.465-1.687 2.8 2.8 0 0 1 .541-1.776 3.237 3.237 0 0 1 1.4-1.03 5.042 5.042 0 0 1 1.845-.326z" class="cls-1" transform="translate(-173.97 -393.536)"/>
<path id="Path_3330" d="M374.908 393.354a5.04 5.04 0 0 1 2.031.346 8.087 8.087 0 0 1 1.424.808.759.759 0 0 0 .38.178q.36 0 .474-1.083h.437q-.038.675-.057 1.625t-.019 2.531h-.437a11.9 11.9 0 0 0-.351-1.581 2.834 2.834 0 0 0-.75-1.243 3.432 3.432 0 0 0-1.338-.888 4.615 4.615 0 0 0-1.68-.32 3.343 3.343 0 0 0-1.746.453 3.822 3.822 0 0 0-1.281 1.287 6.647 6.647 0 0 0-.8 1.962 10.447 10.447 0 0 0-.275 2.477 8.192 8.192 0 0 0 1.053 4.68 3.641 3.641 0 0 0 3.179 1.483 3.126 3.126 0 0 0 1.053-.16 4.082 4.082 0 0 0 .712-.319 1.127 1.127 0 0 0 .418-.417 1.3 1.3 0 0 0 .095-.542v-1.723a3.31 3.31 0 0 0-.142-1.128.833.833 0 0 0-.56-.5 4.558 4.558 0 0 0-1.215-.151v-.355q.361.018.854.027l1.034.018q.541.009.978.009.683 0 1.243-.018t.92-.036v.355a.963.963 0 0 0-.759.284 2.715 2.715 0 0 0-.171 1.243v3.516h-.38a2.508 2.508 0 0 0-.142-.657q-.124-.355-.37-.355a.783.783 0 0 0-.275.053 3.315 3.315 0 0 0-.484.266 6.792 6.792 0 0 1-1.386.684 4.845 4.845 0 0 1-1.632.257 6.4 6.4 0 0 1-4.745-1.678 6.316 6.316 0 0 1-1.671-4.662 7.329 7.329 0 0 1 .826-3.569 5.9 5.9 0 0 1 2.259-2.335 6.478 6.478 0 0 1 3.296-.822z" class="cls-1" transform="translate(-277.349 -393.354)"/>
<path id="Path_3331" d="M471.6 393.354a8.208 8.208 0 0 1 3.633.764 5.671 5.671 0 0 1 2.432 2.193 6.6 6.6 0 0 1 .863 3.472 6.7 6.7 0 0 1-.885 3.48 6.131 6.131 0 0 1-2.464 2.327 7.59 7.59 0 0 1-3.6.835 8.186 8.186 0 0 1-3.643-.764 5.655 5.655 0 0 1-2.422-2.2 7.293 7.293 0 0 1 .032-6.943 6.238 6.238 0 0 1 2.454-2.329 7.512 7.512 0 0 1 3.6-.835zm-.084.32a3.464 3.464 0 0 0-2.275.8 5.1 5.1 0 0 0-1.5 2.2 9.222 9.222 0 0 0-.526 3.25 8.367 8.367 0 0 0 .589 3.276 5.064 5.064 0 0 0 1.6 2.149 3.674 3.674 0 0 0 2.253.755 3.424 3.424 0 0 0 2.264-.8 5.222 5.222 0 0 0 1.5-2.211 9.077 9.077 0 0 0 .537-3.241 8.22 8.22 0 0 0-.6-3.285 5.191 5.191 0 0 0-1.6-2.14 3.634 3.634 0 0 0-2.242-.753z" class="cls-1" transform="translate(-357.18 -393.354)"/>
<path id="Path_3332" d="M569.04 394.895v.354a3.823 3.823 0 0 0-1.031.133.71.71 0 0 0-.47.425 2.863 2.863 0 0 0-.12.965v8.857a2.79 2.79 0 0 0 .11.9.627.627 0 0 0 .44.4 3.552 3.552 0 0 0 .951.1h1.3a3.777 3.777 0 0 0 1.841-.381 2.469 2.469 0 0 0 1.041-1.16 6.976 6.976 0 0 0 .52-1.984h.46a14.694 14.694 0 0 0-.06 1.488q0 .355.03 1.036t.11 1.408q-1.02-.035-2.3-.044t-2.281-.009h-1.651q-1.031 0-2.2.009t-2.191.044v-.354a4.421 4.421 0 0 0 1.021-.142.652.652 0 0 0 .45-.425 3.124 3.124 0 0 0 .11-.957v-8.786a3.109 3.109 0 0 0-.11-.965.68.68 0 0 0-.46-.425 3.736 3.736 0 0 0-1.01-.133v-.354q.46.018 1.191.035t1.571.018q.76 0 1.511-.018t1.227-.035z" class="cls-1" transform="translate(-438.334 -394.631)"/>
<path id="Path_3333" d="M652.231 394.895q3.652 0 5.429 1.585a5.772 5.772 0 0 1 1.777 4.544 6.419 6.419 0 0 1-.869 3.375 5.793 5.793 0 0 1-2.517 2.241 9.12 9.12 0 0 1-4 .8q-.435 0-1.293-.027t-1.51-.027q-.75 0-1.471.009t-1.175.044v-.354a4.306 4.306 0 0 0 1.007-.142.647.647 0 0 0 .444-.425 3.154 3.154 0 0 0 .109-.957v-8.786a3.14 3.14 0 0 0-.109-.965.674.674 0 0 0-.454-.425 3.641 3.641 0 0 0-1-.133v-.354l1.175.044q.721.027 1.431.009t1.589-.036q.885-.015 1.437-.02zm-.336.319a1.65 1.65 0 0 0-1.185.3 1.9 1.9 0 0 0-.276 1.222v8.857a1.847 1.847 0 0 0 .286 1.222 1.69 1.69 0 0 0 1.194.3 5.786 5.786 0 0 0 3.1-.7 3.749 3.749 0 0 0 1.559-2.046 10.332 10.332 0 0 0 .454-3.277 7.1 7.1 0 0 0-1.145-4.429q-1.144-1.449-3.982-1.449z" class="cls-1" transform="translate(-508.147 -394.631)"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

View file

@ -1 +0,0 @@
All of these .svg files are not used directly, instead the svg information is copied inline so we can apply CSS classes to them.

View file

@ -1 +0,0 @@
<svg fill="#000000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="100px" height="100px"><path d="M 20 9 L 20 14 L 10 14 L 10 19 L 5 19 L 5 24 L 1.125 24 C 0.640625 24 0.242188 24.335938 0.15625 24.8125 C 0.148438 24.847656 0 25.683594 0 26.75 C 0 27.449219 0.0664063 28.210938 0.1875 28.96875 C 1.332031 28.695313 3.429688 28.285156 3.0625 26.9375 C 5.035156 29.222656 9.769531 28.53125 10.96875 27.40625 C 12.308594 29.347656 20.113281 28.605469 20.65625 27.09375 C 22.335938 29.0625 27.542969 29.0625 29.21875 27.09375 C 29.761719 28.605469 37.535156 29.347656 38.875 27.40625 C 39.300781 27.804688 40.1875 28.136719 41.21875 28.3125 C 41.566406 27.652344 41.886719 26.988281 42.1875 26.28125 C 48.539063 26.203125 49.910156 21.636719 49.96875 21.4375 C 50.078125 21.054688 49.929688 20.660156 49.625 20.40625 C 49.519531 20.316406 47.175781 18.414063 43.375 19.0625 C 42.308594 15.589844 39.5625 14.007813 39.4375 13.9375 C 39.078125 13.734375 38.632813 13.765625 38.3125 14.03125 C 38.210938 14.113281 35.847656 16.117188 36.21875 20.21875 C 36.3125 21.25 36.582031 22.160156 37 22.96875 C 36.179688 23.425781 34.769531 24 32.5 24 L 32 24 L 32 19 L 27 19 L 27 9 Z M 41.21875 28.3125 C 41.097656 28.546875 40.941406 28.773438 40.8125 29 L 49.84375 29 C 48.757813 28.726563 46.425781 28.359375 46.8125 26.9375 C 45.535156 28.414063 43.109375 28.632813 41.21875 28.3125 Z M 40.8125 29 L 0.1875 29 C 0.429688 30.46875 0.929688 32.007813 1.6875 33.5 C 7.117188 34.777344 12.816406 32.832031 12.875 32.8125 C 13.398438 32.628906 13.945313 32.917969 14.125 33.4375 C 14.308594 33.957031 14.050781 34.539063 13.53125 34.71875 C 13.339844 34.785156 9.90625 35.9375 5.6875 35.9375 C 4.851563 35.9375 3.972656 35.890625 3.09375 35.78125 C 5.71875 39.261719 10.167969 42 17 42 C 27.804688 42 36.113281 37.410156 40.8125 29 Z M 0.1875 29 C 0.183594 28.984375 0.191406 28.984375 0.1875 28.96875 C 0.121094 28.984375 0.0585938 28.984375 0 29 Z M 22 11 L 25 11 L 25 14 L 22 14 Z M 12 16 L 15 16 L 15 19 L 12 19 Z M 17 16 L 20 16 L 20 19 L 17 19 Z M 22 16 L 25 16 L 25 19 L 22 19 Z M 7 21 L 10 21 L 10 24 L 7 24 Z M 12 21 L 15 21 L 15 24 L 12 24 Z M 17 21 L 20 21 L 20 24 L 17 24 Z M 22 21 L 25 21 L 25 24 L 22 24 Z M 27 21 L 30 21 L 30 24 L 27 24 Z M 16 31 C 16.128906 31 16.261719 31.019531 16.375 31.0625 C 16.253906 31.132813 16.15625 31.253906 16.15625 31.40625 C 16.15625 31.632813 16.335938 31.84375 16.5625 31.84375 C 16.714844 31.84375 16.867188 31.75 16.9375 31.625 C 16.988281 31.742188 17 31.863281 17 32 C 17 32.550781 16.550781 33 16 33 C 15.449219 33 15 32.550781 15 32 C 15 31.449219 15.449219 31 16 31 Z"/></svg>

Before

Width:  |  Height:  |  Size: 2.6 KiB

View file

@ -1 +0,0 @@
<?xml version="1.0"?><svg fill="#000000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="100px" height="100px"> <path d="M17.791,46.836C18.502,46.53,19,45.823,19,45v-5.4c0-0.197,0.016-0.402,0.041-0.61C19.027,38.994,19.014,38.997,19,39 c0,0-3,0-3.6,0c-1.5,0-2.8-0.6-3.4-1.8c-0.7-1.3-1-3.5-2.8-4.7C8.9,32.3,9.1,32,9.7,32c0.6,0.1,1.9,0.9,2.7,2c0.9,1.1,1.8,2,3.4,2 c2.487,0,3.82-0.125,4.622-0.555C21.356,34.056,22.649,33,24,33v-0.025c-5.668-0.182-9.289-2.066-10.975-4.975 c-3.665,0.042-6.856,0.405-8.677,0.707c-0.058-0.327-0.108-0.656-0.151-0.987c1.797-0.296,4.843-0.647,8.345-0.714 c-0.112-0.276-0.209-0.559-0.291-0.849c-3.511-0.178-6.541-0.039-8.187,0.097c-0.02-0.332-0.047-0.663-0.051-0.999 c1.649-0.135,4.597-0.27,8.018-0.111c-0.079-0.5-0.13-1.011-0.13-1.543c0-1.7,0.6-3.5,1.7-5c-0.5-1.7-1.2-5.3,0.2-6.6 c2.7,0,4.6,1.3,5.5,2.1C21,13.4,22.9,13,25,13s4,0.4,5.6,1.1c0.9-0.8,2.8-2.1,5.5-2.1c1.5,1.4,0.7,5,0.2,6.6c1.1,1.5,1.7,3.2,1.6,5 c0,0.484-0.045,0.951-0.11,1.409c3.499-0.172,6.527-0.034,8.204,0.102c-0.002,0.337-0.033,0.666-0.051,0.999 c-1.671-0.138-4.775-0.28-8.359-0.089c-0.089,0.336-0.197,0.663-0.325,0.98c3.546,0.046,6.665,0.389,8.548,0.689 c-0.043,0.332-0.093,0.661-0.151,0.987c-1.912-0.306-5.171-0.664-8.879-0.682C35.112,30.873,31.557,32.75,26,32.969V33 c2.6,0,5,3.9,5,6.6V45c0,0.823,0.498,1.53,1.209,1.836C41.37,43.804,48,35.164,48,25C48,12.318,37.683,2,25,2S2,12.318,2,25 C2,35.164,8.63,43.804,17.791,46.836z"/></svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -1 +0,0 @@
<?xml version="1.0"?><svg fill="#000000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="100px" height="100px"> <path d="M 5 4 C 4.448 4 4 4.447 4 5 L 4 45 C 4 45.553 4.448 46 5 46 L 24 46 C 24.552 46 25 45.553 25 45 L 25 35.5 L 25 14.5 L 25 5 C 25 4.447 24.552 4 24 4 L 5 4 z M 25 14.5 C 25 20.29 29.71 25 35.5 25 C 41.29 25 46 20.29 46 14.5 C 46 8.71 41.29 4 35.5 4 C 29.71 4 25 8.71 25 14.5 z M 35.5 25 C 29.71 25 25 29.71 25 35.5 C 25 41.29 29.71 46 35.5 46 C 41.29 46 46 41.29 46 35.5 C 46 29.71 41.29 25 35.5 25 z"/></svg>

Before

Width:  |  Height:  |  Size: 546 B

View file

@ -1 +0,0 @@
<?xml version="1.0"?><svg fill="#000000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="100px" height="100px"> <path d="M 16 3 C 8.83 3 3 8.83 3 16 L 3 34 C 3 41.17 8.83 47 16 47 L 34 47 C 41.17 47 47 41.17 47 34 L 47 16 C 47 8.83 41.17 3 34 3 L 16 3 z M 37 11 C 38.1 11 39 11.9 39 13 C 39 14.1 38.1 15 37 15 C 35.9 15 35 14.1 35 13 C 35 11.9 35.9 11 37 11 z M 25 14 C 31.07 14 36 18.93 36 25 C 36 31.07 31.07 36 25 36 C 18.93 36 14 31.07 14 25 C 14 18.93 18.93 14 25 14 z M 25 16 C 20.04 16 16 20.04 16 25 C 16 29.96 20.04 34 25 34 C 29.96 34 34 29.96 34 25 C 34 20.04 29.96 16 25 16 z"/></svg>

Before

Width:  |  Height:  |  Size: 614 B

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 10 KiB

View file

@ -1 +0,0 @@
<?xml version="1.0"?><svg fill="#000000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="100px" height="100px"> <path d="M41,4H9C6.24,4,4,6.24,4,9v32c0,2.76,2.24,5,5,5h32c2.76,0,5-2.24,5-5V9C46,6.24,43.76,4,41,4z M17,20v19h-6V20H17z M11,14.47c0-1.4,1.2-2.47,3-2.47s2.93,1.07,3,2.47c0,1.4-1.12,2.53-3,2.53C12.2,17,11,15.87,11,14.47z M39,39h-6c0,0,0-9.26,0-10 c0-2-1-4-3.5-4.04h-0.08C27,24.96,26,27.02,26,29c0,0.91,0,10,0,10h-6V20h6v2.56c0,0,1.93-2.56,5.81-2.56 c3.97,0,7.19,2.73,7.19,8.26V39z"/></svg>

Before

Width:  |  Height:  |  Size: 518 B

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100" width="100px" height="100px">
<g id="surface12014155">
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 28 8 C 16.976562 8 8 16.976562 8 28 L 8 72 C 8 83.023438 16.976562 92 28 92 L 72 92 C 83.023438 92 92 83.023438 92 72 L 92 28 C 92 16.976562 83.023438 8 72 8 Z M 26 32 L 74 32 C 74.359375 32 74.699219 32.039062 75.019531 32.140625 L 55.359375 51.78125 C 52.398438 54.742188 47.582031 54.742188 44.621094 51.78125 L 24.980469 32.140625 C 25.300781 32.039062 25.640625 32 26 32 Z M 22.140625 34.980469 L 37.179688 50 L 22.140625 65.019531 C 22.039062 64.699219 22 64.359375 22 64 L 22 36 C 22 35.640625 22.039062 35.300781 22.140625 34.980469 Z M 77.859375 34.980469 C 77.960938 35.300781 78 35.640625 78 36 L 78 64 C 78 64.359375 77.960938 64.699219 77.859375 65.019531 L 62.800781 50 Z M 40 52.820312 L 41.78125 54.621094 C 44.042969 56.882812 47.019531 58 49.980469 58 C 52.960938 58 55.917969 56.882812 58.179688 54.621094 L 59.980469 52.820312 L 75.019531 67.859375 C 74.699219 67.960938 74.359375 68 74 68 L 26 68 C 25.640625 68 25.300781 67.960938 24.980469 67.859375 Z M 40 52.820312 "/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.4 KiB

View file

@ -1 +0,0 @@
<svg fill="#000000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="100px" height="100px"><path d="M 50.0625 10.4375 C 48.214844 11.257813 46.234375 11.808594 44.152344 12.058594 C 46.277344 10.785156 47.910156 8.769531 48.675781 6.371094 C 46.691406 7.546875 44.484375 8.402344 42.144531 8.863281 C 40.269531 6.863281 37.597656 5.617188 34.640625 5.617188 C 28.960938 5.617188 24.355469 10.21875 24.355469 15.898438 C 24.355469 16.703125 24.449219 17.488281 24.625 18.242188 C 16.078125 17.8125 8.503906 13.71875 3.429688 7.496094 C 2.542969 9.019531 2.039063 10.785156 2.039063 12.667969 C 2.039063 16.234375 3.851563 19.382813 6.613281 21.230469 C 4.925781 21.175781 3.339844 20.710938 1.953125 19.941406 C 1.953125 19.984375 1.953125 20.027344 1.953125 20.070313 C 1.953125 25.054688 5.5 29.207031 10.199219 30.15625 C 9.339844 30.390625 8.429688 30.515625 7.492188 30.515625 C 6.828125 30.515625 6.183594 30.453125 5.554688 30.328125 C 6.867188 34.410156 10.664063 37.390625 15.160156 37.472656 C 11.644531 40.230469 7.210938 41.871094 2.390625 41.871094 C 1.558594 41.871094 0.742188 41.824219 -0.0585938 41.726563 C 4.488281 44.648438 9.894531 46.347656 15.703125 46.347656 C 34.617188 46.347656 44.960938 30.679688 44.960938 17.09375 C 44.960938 16.648438 44.949219 16.199219 44.933594 15.761719 C 46.941406 14.3125 48.683594 12.5 50.0625 10.4375 Z"/></svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -1 +0,0 @@
<svg fill="#000000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="100px" height="100px"><path d="M45,4H5C4.447,4,4,4.448,4,5v40c0,0.552,0.447,1,1,1h40c0.553,0,1-0.448,1-1V5C46,4.448,45.553,4,45,4z M29,26.445h-5V42h-4 V26.445h-5V23h14V26.445z M30.121,41.112v-4.158c0,0,2.271,1.712,4.996,1.712c2.725,0,2.62-1.782,2.62-2.026 c0-2.586-7.721-2.586-7.721-8.315c0-7.791,11.25-4.717,11.25-4.717l-0.14,3.704c0,0-1.887-1.258-4.018-1.258s-2.9,1.013-2.9,2.096 c0,2.795,7.791,2.516,7.791,8.141C42,44.955,30.121,41.112,30.121,41.112z"/></svg>

Before

Width:  |  Height:  |  Size: 545 B

Some files were not shown because too many files have changed in this diff Show more