aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXe Iaso <me@christine.website>2022-11-24 22:48:23 -0500
committerXe Iaso <me@christine.website>2022-11-24 22:48:23 -0500
commita5351b91cf2b3642456481add468e46df4a15782 (patch)
treebe01f2d6ae5ea510add3f81b4e4f6fec9509728e
parent85fc298d11239dbc69b70ac95888f03cf22a3008 (diff)
downloadxesite-a5351b91cf2b3642456481add468e46df4a15782.tar.xz
xesite-a5351b91cf2b3642456481add468e46df4a15782.zip
move resume to be generated by nix
Signed-off-by: Xe Iaso <me@christine.website>
-rw-r--r--blog/site-update-v3.markdown6
-rw-r--r--dhall/latex/.gitignore5
-rw-r--r--dhall/latex/resume.dhall110
-rw-r--r--dhall/resume.dhall64
-rw-r--r--flake.nix33
-rw-r--r--src/app/mod.rs6
-rw-r--r--src/handlers/mod.rs8
-rw-r--r--src/post/mod.rs14
-rw-r--r--src/post/schemaorg.rs14
-rw-r--r--src/tmpl/blog.rs7
-rw-r--r--src/tmpl/mod.rs12
-rw-r--r--static/resume/.gitignore1
-rw-r--r--static/resume/resume.md171
13 files changed, 261 insertions, 190 deletions
diff --git a/blog/site-update-v3.markdown b/blog/site-update-v3.markdown
new file mode 100644
index 0000000..e266960
--- /dev/null
+++ b/blog/site-update-v3.markdown
@@ -0,0 +1,6 @@
+---
+title: "Site Update: Version 3.0"
+date: 2022-11-26
+---
+
+
diff --git a/dhall/latex/.gitignore b/dhall/latex/.gitignore
new file mode 100644
index 0000000..19b9311
--- /dev/null
+++ b/dhall/latex/.gitignore
@@ -0,0 +1,5 @@
+resume.tex
+resume.pdf
+resume.aux
+resume.out
+resume.log
diff --git a/dhall/latex/resume.dhall b/dhall/latex/resume.dhall
new file mode 100644
index 0000000..e9318f6
--- /dev/null
+++ b/dhall/latex/resume.dhall
@@ -0,0 +1,110 @@
+let xesite = ../types/package.dhall
+
+let Link = xesite.Link
+
+let Location = xesite.Location
+
+let Job = xesite.Job
+
+let Prelude = ../Prelude.dhall
+
+let xe = ../authors/xe.dhall
+
+let resume = ../resume.dhall
+
+let buzzwords =
+ let doer = \(item : Text) -> item
+
+ in Prelude.Text.concatMapSep ", " Text doer resume.buzzwords
+
+let jobHistory =
+ let showDate =
+ \(job : Job.Type) ->
+ let endDate =
+ merge
+ { Some = \(t : Text) -> t, None = "current" }
+ job.endDate
+
+ in "${job.startDate} - ${endDate}"
+
+ let showLoc =
+ \(l : Location.Type) ->
+ "${l.city}, ${l.stateOrProvince}, ${l.country}"
+
+ let workedLocs =
+ \(j : Job.Type) ->
+ let doer =
+ \(l : Location.Type) -> "\\item Work location: ${showLoc l}"
+
+ in Prelude.Text.concatMapSep "\n" Location.Type doer j.locations
+
+ let highlights =
+ \(j : Job.Type) ->
+ let doer = \(t : Text) -> "\\item ${t}"
+
+ in Prelude.Text.concatMapSep "\n" Text doer j.highlights
+
+ let doer =
+ \(job : Job.Type) ->
+ ''
+ \begin{rSubsection}{${job.company.name}}{${showDate
+ job}}{${job.title}}{${showLoc
+ job.company.location}}
+
+ ${workedLocs job}
+ ${highlights job}
+
+ \end{rSubsection}
+ ''
+
+ in Prelude.Text.concatMapSep "\n" Job.Type doer resume.jobs
+
+let publications =
+ let doer =
+ \(link : Link.Type) ->
+ ''
+ \begin{rSubsection}{\href{${link.url}}{${link.title}}}{}{}{}
+
+ \item ${link.description}
+
+ \end{rSubsection}
+ ''
+
+ in Prelude.Text.concatMapSep
+ "\n"
+ Link.Type
+ doer
+ resume.notablePublications
+
+in ''
+ \documentclass{resume}
+
+ \usepackage[left=0.75in,top=0.6in,right=0.75in,bottom=0.6in]{geometry} % Document margins
+ \usepackage{hyperref}
+ \newcommand{\tab}[1]{\hspace{.2667\textwidth}\rlap{#1}}
+ \newcommand{\itab}[1]{\hspace{0em}\rlap{#1}}
+ \name{${xe.name}}
+ \address{https://xeiaso.net \\ me@xeiaso.net}
+
+ \begin{document}
+
+ \begin{rSection}{Technical Strengths}
+
+ ${buzzwords}
+
+ \end{rSection}
+
+ \begin{rSection}{Experience}
+
+ ${jobHistory}
+
+ \end{rSection}
+
+ \begin{rSection}{Notable Publications}
+
+ ${publications}
+
+ \end{rSection}
+
+ \end{document}
+ ''
diff --git a/dhall/resume.dhall b/dhall/resume.dhall
index ffac204..6290404 100644
--- a/dhall/resume.dhall
+++ b/dhall/resume.dhall
@@ -33,5 +33,67 @@ in Resume::{
, "Continuous Delivery"
]
, jobs = ./jobHistory.dhall
- , notablePublications = [] : List Link.Type
+ , notablePublications =
+ [ Link::{
+ , url = "https://blog.heroku.com/how-to-make-progressive-web-app"
+ , title = "How to Make a Progressive Web App From Your Existing Website"
+ , description =
+ "An article summarizing how easy it is to make a webpage into an installable Progressive Web App."
+ }
+ , Link::{
+ , url =
+ "https://web.archive.org/web/20210318102148/https://tech.lightspeedhq.com/palisade-version-bumping-at-scale-in-ci/"
+ , title = "Palisade: Version Bumping at Scale in CI"
+ , description =
+ "The release post for Palisade, a tool to automate version bumping, release tagging and more."
+ }
+ , Link::{
+ , url = "https://tailscale.com/blog/grafana-auth/"
+ , title = "How To Seamlessly Authenticate to Grafana using Tailscale"
+ , description =
+ "The release post for grafana-auth, a tool that lets Grafana users automagically authenticate to Grafana using Tailscale."
+ }
+ , Link::{
+ , url = "https://tailscale.com/blog/tailscale-auth-minecraft/"
+ , title = "Tailscale Authentication for Minecraft"
+ , description =
+ "A post explaining how Tailscale as an authentication mechanism can be used in absurd places, such as making authentication for Minecraft servers."
+ }
+ , Link::{
+ , url = "https://tailscale.com/blog/tailscale-auth-nginx/"
+ , title = "Tailscale Authentication for NGINX"
+ , description =
+ "The release post for nginx-auth, a tool that uses Tailscale's knowledge of IP address to person mappings to provide a weak authentication factor."
+ }
+ , Link::{
+ , url = "https://tailscale.com/blog/steam-deck/"
+ , title = "Putting Tailscale on the Steam Deck"
+ , description =
+ "An engineering log of all the steps taken to run Tailscale on the Valve Steam Deck and the tradeoffs between the various methods you could use to do this."
+ }
+ , Link::{
+ , url = "https://tailscale.com/blog/gitops-acls/"
+ , title = "GitOps for Tailscale ACLs"
+ , description =
+ "The release post of the Sync Tailscale ACLs GitHub Action, allowing administrators to automatically sync Tailscale ACLs from a GitHub repository."
+ }
+ , Link::{
+ , url = "https://tailscale.com/blog/hamachi/"
+ , title = "Tailscale: A modern replacement for Hamachi"
+ , description =
+ "A nostalgic piece recalling the magic of Hamachi (a product that did a similar thing to Tailscale), and how Tailscale builds on top of that to do even better things."
+ }
+ , Link::{
+ , url = "https://tailscale.com/blog/magicdns-why-name/"
+ , title = "An epic treatise on DNS, magical and otherwise"
+ , description =
+ "A deep dive into all of the problems that DNS has at scale and how Tailscale makes most of those problems go away, with the rest of them being easier in comparison."
+ }
+ , Link::{
+ , url = "https://tailscale.com/blog/tsnet-virtual-private-services/"
+ , title = "Virtual private services with tsnet"
+ , description =
+ "Tailscale lets you connect to your network from anywhere, but you have to set it up on individual computers for it to work. In this article Xe covers how to use tsnet to get all of the goodness of Tailscale in userspace so that you can have your services join your tailnet like they were separate computers."
+ }
+ ]
}
diff --git a/flake.nix b/flake.nix
index 4dcda34..ce28231 100644
--- a/flake.nix
+++ b/flake.nix
@@ -20,6 +20,9 @@
pkgs = import nixpkgs { inherit system; };
naersk-lib = naersk.lib."${system}";
src = ./.;
+
+ tex = with pkgs;
+ texlive.combine { inherit (texlive) scheme-medium bitter titlesec; };
in rec {
packages = rec {
bin = naersk-lib.buildPackage {
@@ -43,14 +46,36 @@
phases = "installPhase";
installPhase = ''
- set -x
mkdir -p $out
cp -rf ${pkgs.dhallPackages.Prelude}/.cache .cache
chmod -R u+w .cache
export XDG_CACHE_HOME=.cache
export DHALL_PRELUDE=${pkgs.dhallPackages.Prelude}/binary.dhall;
dhall resolve --file $src/config.dhall >> $out/config.dhall
- set +x
+ '';
+ };
+
+ resumePDF = pkgs.stdenv.mkDerivation {
+ pname = "xesite-resume-pdf";
+ inherit (bin) version;
+ inherit src;
+ buildInputs = with pkgs; [ dhall dhallPackages.Prelude tex pandoc ];
+
+ phases = "installPhase";
+
+ installPhase = ''
+ mkdir -p $out/static/resume
+ cp -rf ${pkgs.dhallPackages.Prelude}/.cache .cache
+ chmod -R u+w .cache
+ export XDG_CACHE_HOME=.cache
+ export DHALL_PRELUDE=${pkgs.dhallPackages.Prelude}/binary.dhall;
+
+ ln -s $src/dhall/latex/resume.cls
+ dhall text --file $src/dhall/latex/resume.dhall > resume.tex
+
+ xelatex ./resume.tex
+ cp resume.pdf $out/static/resume/resume.pdf
+
'';
};
@@ -105,7 +130,7 @@
default = pkgs.symlinkJoin {
name = "xesite-${bin.version}";
- paths = [ config posts static bin frontend ];
+ paths = [ config posts static bin frontend resumePDF ];
};
docker = pkgs.dockerTools.buildLayeredImage {
@@ -137,6 +162,8 @@
dhall
dhall-json
dhall-lsp-server
+ tex
+ pandoc
# frontend
deno
diff --git a/src/app/mod.rs b/src/app/mod.rs
index 8c7cc4e..6753ff0 100644
--- a/src/app/mod.rs
+++ b/src/app/mod.rs
@@ -1,7 +1,7 @@
use crate::{post::Post, signalboost::Person};
use chrono::prelude::*;
use color_eyre::eyre::Result;
-use std::{fs, path::PathBuf, sync::Arc};
+use std::{path::PathBuf, sync::Arc};
use tracing::{error, instrument};
pub mod config;
@@ -48,7 +48,6 @@ pub const ICON: &'static str = "https://xeiaso.net/static/img/avatar.png";
pub struct State {
pub cfg: Arc<Config>,
pub signalboost: Vec<Person>,
- pub resume: String,
pub blog: Vec<Post>,
pub gallery: Vec<Post>,
pub talks: Vec<Post>,
@@ -62,8 +61,6 @@ pub struct State {
pub async fn init(cfg: PathBuf) -> Result<State> {
let cfg: Arc<Config> = Arc::new(serde_dhall::from_file(cfg).parse()?);
let sb = cfg.signalboost.clone();
- let resume = fs::read_to_string(cfg.clone().resume_fname.clone())?;
- let resume: String = xesite_markdown::render(&resume)?;
let mi = mi::Client::new(
cfg.clone().mi_token.clone(),
crate::APPLICATION_NAME.to_string(),
@@ -141,7 +138,6 @@ pub async fn init(cfg: PathBuf) -> Result<State> {
mi,
cfg,
signalboost: sb,
- resume,
blog,
gallery,
talks,
diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs
index 0bcebe7..a20d654 100644
--- a/src/handlers/mod.rs
+++ b/src/handlers/mod.rs
@@ -7,7 +7,7 @@ use axum::{
};
use chrono::{Datelike, Timelike, Utc, Weekday};
use lazy_static::lazy_static;
-use maud::{Markup, PreEscaped};
+use maud::Markup;
use prometheus::{opts, register_int_counter_vec, IntCounterVec};
use std::sync::Arc;
use tracing::instrument;
@@ -105,12 +105,10 @@ pub async fn salary_transparency(Extension(state): Extension<Arc<State>>) -> Res
}
#[axum_macros::debug_handler]
-#[instrument(skip(state))]
-pub async fn resume(Extension(state): Extension<Arc<State>>) -> Result<Markup> {
+pub async fn resume() -> Markup {
HIT_COUNTER.with_label_values(&["resume"]).inc();
- let state = state.clone();
- Ok(tmpl::resume(PreEscaped(&state.resume)))
+ tmpl::resume()
}
#[instrument(skip(state))]
diff --git a/src/post/mod.rs b/src/post/mod.rs
index 2046a89..65c859e 100644
--- a/src/post/mod.rs
+++ b/src/post/mod.rs
@@ -6,6 +6,7 @@ use std::{borrow::Borrow, cmp::Ordering, path::PathBuf};
use tokio::fs;
pub mod frontmatter;
+pub mod schemaorg;
#[derive(Eq, PartialEq, Debug, Clone, Serialize, Deserialize)]
pub struct Post {
@@ -26,6 +27,19 @@ pub struct NewPost {
pub link: String,
}
+impl Into<schemaorg::Article> for &Post {
+ fn into(self) -> schemaorg::Article {
+ schemaorg::Article {
+ context: "https://schema.org".to_string(),
+ r#type: "Article".to_string(),
+ headline: self.front_matter.title.clone(),
+ image: "https://xeiaso.net/static/img/avatar.png".to_string(),
+ url: format!("https://xeiaso.net/{}", self.link),
+ date_published: self.date.format("%Y-%m-%d").to_string(),
+ }
+ }
+}
+
impl Into<xe_jsonfeed::Item> for Post {
fn into(self) -> xe_jsonfeed::Item {
let mut result = xe_jsonfeed::Item::builder()
diff --git a/src/post/schemaorg.rs b/src/post/schemaorg.rs
new file mode 100644
index 0000000..18c238a
--- /dev/null
+++ b/src/post/schemaorg.rs
@@ -0,0 +1,14 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Eq, PartialEq, Debug, Clone, Serialize, Deserialize)]
+pub struct Article {
+ #[serde(rename = "@context")]
+ pub context: String,
+ #[serde(rename = "@type")]
+ pub r#type: String,
+ pub headline: String,
+ pub image: String,
+ pub url: String,
+ #[serde(rename = "datePublished")]
+ pub date_published: String,
+}
diff --git a/src/tmpl/blog.rs b/src/tmpl/blog.rs
index 0187ad6..4f76784 100644
--- a/src/tmpl/blog.rs
+++ b/src/tmpl/blog.rs
@@ -1,8 +1,11 @@
use super::{base, nag};
-use crate::post::Post;
+use crate::post::{schemaorg::Article, Post};
use maud::{html, Markup, PreEscaped};
fn post_metadata(post: &Post) -> Markup {
+ let art: Article = post.into();
+ let json = PreEscaped(serde_json::to_string(&art).unwrap());
+
html! {
meta name="twitter:card" content="summary";
meta name="twitter:site" content="@theprincessxena";
@@ -19,6 +22,8 @@ fn post_metadata(post: &Post) -> Markup {
} @else {
link rel="canonical" href={"https://xeiaso.net/" (post.link)};
}
+
+ script type="application/ld+json" {(json)}
}
}
diff --git a/src/tmpl/mod.rs b/src/tmpl/mod.rs
index 29a0a93..79b8196 100644
--- a/src/tmpl/mod.rs
+++ b/src/tmpl/mod.rs
@@ -360,22 +360,26 @@ pub fn gitea(pkg_name: &str, git_repo: &str, branch: &str) -> Markup {
}
}
-pub fn resume(data: impl Render) -> Markup {
+pub fn resume() -> Markup {
base(
Some("Resume"),
None,
html! {
- (data)
+ h1 {"Resume"}
+
+ p {"This resume is automatically generated when the website gets deployed."}
+
+ iframe src="/static/resume/resume.pdf" width="100%" height="900px" {}
hr;
- a href="/static/resume/resume.md" { "Plain-text version" }
+ a href="/static/resume/resume.pdf" { "PDF version" }
},
)
}
fn schema_person(a: &Author) -> Markup {
- let data = PreEscaped(serde_json::to_string_pretty(&a).unwrap());
+ let data = PreEscaped(serde_json::to_string(&a).unwrap());
html! {
script type="application/ld+json" { (data) }
diff --git a/static/resume/.gitignore b/static/resume/.gitignore
new file mode 100644
index 0000000..ce0acdb
--- /dev/null
+++ b/static/resume/.gitignore
@@ -0,0 +1 @@
+resume.pdf
diff --git a/static/resume/resume.md b/static/resume/resume.md
deleted file mode 100644
index ec1a2ca..0000000
--- a/static/resume/resume.md
+++ /dev/null
@@ -1,171 +0,0 @@
-# Xe Iaso
-
-#### Full-stack Engineer
-
-##### Ottawa, ON &emsp; [xeiaso.net][homepage]
-
-`Docker`, `Git`, `Go`, `Rust`, `C`, `Stenography`, `DevOps`, `Heroku`, `Continuous
-Integration/Delivery`, `WebAssembly`, `Lua`, `Mindfulness`, `HTTP/2`, `Alpine
-Linux`, `Ubuntu`, `Linux`, `GraphViz`, `Progressive Web Apps`, `yaml`, `SQL`,
-`Postgres`, `MySQL`, `SQLite`, `Ordained Minister`, `Dudeism`, `Tech Writing`,
-`Kubernetes`, `Command Line Apps`
-
-## Experience
-
-### Tailscale - Software Designer &emsp; <small>*2020 - present*</small>
-
-> [Tailscale][tailscale] is a zero config VPN for building secure networks.
-> Install on any device in minutes. Remote access from any network or physical
-> location.
-
-#### Highlights
-
-- Go programming
-- Nix and NixOS
-- SQL integrations
-- End-user facing blog content and customer support
-
-### Lightspeed - Expert principal en fiabilité du site &emsp; <small>*2019 - 2020*</small>
-
-(Senior Site Reliability Expert)
-
-> [Lightspeed][lightspeedhq] is a provider of retail, ecommerce and
-> point-of-sale solutions for small and medium scale businesses.
-
-#### Highlights
-
-- Migration from cloud to cloud
-- Work on the cloud platform initiative
-- Crafting reliable infrastructure for clients of customers
-- Creation of an internally consistent and extensible command line interface for
- internal tooling
-
-### Heroku - Senior Software Engineer &emsp; <small>*2017 - 2019*</small>
-
-> [Heroku][heroku] is a cloud Platform-as-a-Service (PaaS) that created the term
-> "platform as a service". Heroku currently supports several programming
-> languages that are commonly used on the web. Heroku, one of the first cloud
-> platforms, has been in development since June 2007, when it supported only the
-> Ruby programming language, but now supports Java, Node.js, Scala, Clojure,
-> Python, PHP, and Go.
-
-#### Highlights
-
-- [JVM Application Metrics](https://devcenter.heroku.com/changelog-items/1133)
-- [Go Runtime Metrics
- Agent](https://github.com/heroku/x/tree/8572eb9d3d69016dabefd342506fe9951830c358/runtime-metrics)
-- Other backend fixes and improvements on [Threshold
- Autoscaling](https://blog.heroku.com/heroku-autoscaling) and [Threshold
- Alerting](https://devcenter.heroku.com/articles/metrics#threshold-alerting)
-- [How to Make a Progressive Web App From Your Existing
- Website](https://blog.heroku.com/how-to-make-progressive-web-app)
-
-### Backplane.io - Software Engineer &emsp; <small>*2016 - 2016*</small>
-
-> [Backplane](https://backplane.io) (now defunct) was an innovative reverse reverse proxy that
-> helps administrators and startups simplify their web application routing.
-
-#### Highlights
-
-- Performance monitoring of production servers
-- Continuous deployment and development in Go
-- Learning a lot about HTTP/2 and load balancing
-
-### Pure Storage - Member of Technical Staff &emsp; <small>*2016 - 2016*</small>
-
-> Pure Storage is a Mountain View, California-based enterprise data flash storage
-> company founded in 2009. It is traded on the NYSE (PSTG).
-
-#### Highlights
-
-- Code maintenance
-
-### IMVU - Site Reliability Engineer &emsp; <small>*2015 - 2016*</small>
-
-> IMVU, inc is a company whose mission is to help people find and communicate
-> with eachother. Their main product is a 3D avatar-based chat client and its
-> surrounding infrastructure allowing creators to make content for the avatars
-> to wear.
-
-#### Highlights
-
-- Wrote up technical designs
-- Implemented technical designs on an over 800 machine cluster
-- Continuous learning of a lot of very powerful systems and improving upon them
- when it is needed
-
-### VTCSecure - Deis Consultant (contract) &emsp; <small>*2014 - 2015*</small>
-
-> VTCSecure is a company dedicated to helping with custom and standard
-> audio/video conferencing solutions. They specialize in helping the deaf and
-> blind communicate over today's infrastructure without any trouble on their end.
-
-#### Highlights
-
-- Started groundwork for a dynamically scalable infrastructure on a project for
- helping the blind see things
-- Developed a prototype of a new website for VTCSecure
-- Education on best practices using Docker and CoreOS
-- Learning Freeswitch
-
-### Crowdflower - Deis Consultant (Contract) &emsp; <small>*2014 - 2014*</small>
-
-> Crowdflower is a company that uses crowdsourcing to have its customers submit
-> tasks to be done, similar to Amazon's Mechanical Turk. CrowdFlower has over 50
-> labor channel partners, and its network has more than 5 million contributors
-> worldwide.
-
-#### Highlights
-
-- Research and development on scalable Linux deployments on AWS via CoreOS and
- Docker
-- Development of in-house tools to speed instance creation
-- Laid groundwork on the creation and use of better tools for managing large
- clusters of CoreOS and Fleet machines
-
-### OpDemand - Software Engineering Intern &emsp; <small>*2014 - 2014*</small>
-
-> OpDemand is the company behind the open source project Deis, a distributed
-> platform-as-a-service (PaaS) designed from the ground up to emulate Heroku but
-> on privately owned servers.
-
-#### Highlights
-
-- Built new base image for Deis components
-- Research and development on a new builder component
-
-## Writing
-
-> Articles listed below will be either personal or professional and do not
-> reflect the views of any company or group I am affiliated with. The writing is
-> my own, with the help of others to make things legible.
-
-- [My Blog](https://xeiaso.net/blog)
-- [NAS 101: An intro chat about Network Attached
- Storage](https://tailscale.com/blog/nas-101/)
-- [The Sisyphean Task Of DNS Client Config on
- Linux](https://tailscale.com/blog/sisyphean-dns-client-linux/)
-
-I have gotten to the front page of [Hacker News](https://news.ycombinator.com) several times. Here are a few of the comment threads:
-
-- ["Open Source" is Broken](https://news.ycombinator.com/item?id=29522941)
-- [The Surreal Horror of PAM](https://news.ycombinator.com/item?id=29167560)
-- [Systemd: The Good Parts](https://news.ycombinator.com/item?id=27175960)
-- [I Implemented /dev/printerfact in
- Rust](https://news.ycombinator.com/item?id=26845355)
-- [A Model for Identity in Software](https://news.ycombinator.com/item?id=25978511)
-- [I Put Words on This Webpage so You Have to Listen to Me now](https://news.ycombinator.com/item?id=18577758)
-- [TempleOS: 1 - Installation](https://news.ycombinator.com/item?id=19961082)
-- [WebAssembly on the Server: How System Calls Work](https://news.ycombinator.com/item?id=20066204)
-- [Olin: Defining a New Primitive for Event-Driven Services](https://news.ycombinator.com/item?id=17896307)
-
-## Ordination
-
-I am an ordained minister with the [Church of the Latter-day Dude](https://dudeism.com). This allows me to officiate religious ceremonies in at least the United States. I would be honored if you were to choose me to officiate anything for any reason. Please [contact](/contact) me if you have any questions.
-
-[homepage]: https://xeiaso.net
-[twitter]: https://twitter.com/theprincessxena
-[twit]: http://cdn-careers.sstatic.net/careers/Img/icon-twitter.png?v=b1bd58ad2034
-[heroku]: https://www.heroku.com
-[lightspeedhq]: https://www.lightspeedhq.com
-[tailscale]: https://tailscale.com/