initial commit

This commit is contained in:
Youwen Wu 2024-12-31 19:17:37 -08:00
commit 4779c0142b
Signed by: youwen5
GPG key ID: 865658ED1FE61EC3
6 changed files with 584 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
result*

BIN
cv.pdf Normal file

Binary file not shown.

120
cv.typ Normal file
View file

@ -0,0 +1,120 @@
#import "./template.typ": *
#show: moderner-cv.with(
name: "Youwen Wu",
lang: "en",
subtitle: [Curriculum Vitæ],
social: (
// predefined socials: phone, email, github, linkedin, x, bluesky
email: "youwen@ucsb.edu",
github: "youwen5",
linkedin: "Youwen Wu",
// custom socials: (icon, link, body)
// any fontawesome icon can be used: https://fontawesome.com/search
website: ("link", "https://youwen.dev", "youwen.dev"),
),
)
= Education
#cv-entry(
date: [2024 -- 2028],
title: [B.S. Mathematics],
employer: [University of California, Santa Barbara],
)[4.0/4.0]
#cv-entry(
date: [2024 -- 2028],
title: [B.S. Computer Science],
employer: [University of California, Santa Barbara],
)[4.0/4.0]
= Experience
#cv-entry(
date: [4/2022 -- 7/2023],
employer: [UCSB Robotics Lab],
title: [Systems programmer],
[#linebreak()#text(
10pt,
[
Designed reproducible and purely functional hermetic build systems.
Creating 3D simulacrums of laboratory experiments that are reproduced in
real life, using C++, React, and Three.js.
],
)],
)
#cv-entry(
date: [09/2022 -- 06/2024],
employer: [FIRST Robotics Team 1280],
title: [Artificial Intelligence Lead],
[#linebreak()#text(
10pt,
[
Worked on autonomous decision making and path planning algorithms.
Replaced the venerable _BozoAuto_ autonomous subroutine with the
_DeepBozo_ autonomous suite. Designed a novel robot control dashboard
with 3D visualization using Rust, Tauri, and Svelte.
],
)],
)
= Skills
#cv-line[
Languages
][
Haskell, Rust, TypeScript, Bash, Python, Nu, Nix, C++.
]
#cv-double-item[
Development
][
Tauri, React, Svelte, Linux.
][Deployment][
Nix and NixOS, Docker and NixOS based service deployment and system administration.
]
#cv-line[Other][
Git and Mercurial Version Control.
]
= Papers
== Preprints
#cv-paper-item(
name: "The DeepBozo Report",
date: [1/2024],
journal: [
#link("https://www.eexiv.org/document/view/deepbozo-report")[eeXiv:10j4yyvp4so9.]
],
)
#cv-paper-item(
name: "eeXiv Whitepaper",
date: [3/2024],
journal: [
#link("https://www.eexiv.org/document/view/eexiv-white-paper")[eeXiv:gc3lso8s9tyb]
],
)
#cv-paper-item(
name: "The LiDAR Whitepaper",
date: [2/2024],
journal: [
#link("https://www.eexiv.org/document/view/lidar-whitepaper")[eeXiv:my8nruhlzjsq]
],
)
= Research Projects
#cv-line(
[5/2024],
[Split Cycle: A New Condorcet Consistent Voting Method Independent of Clones and Immune to Spoilers],
)
= Languages
#cv-double-item[English][Native][Chinese][Fluent]

116
flake.lock Normal file
View file

@ -0,0 +1,116 @@
{
"nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"font-awesome": {
"flake": false,
"locked": {
"lastModified": 1734384716,
"narHash": "sha256-MaJG96kYj8ukJVyqOTDpkHH/eWr/ZlbVKk9AvJM7ub4=",
"owner": "FortAwesome",
"repo": "Font-Awesome",
"rev": "af620534bfc3c2d4cbefcfeec29603bbe7809e64",
"type": "github"
},
"original": {
"owner": "FortAwesome",
"repo": "Font-Awesome",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1735471104,
"narHash": "sha256-0q9NGQySwDQc7RhAV2ukfnu7Gxa5/ybJ2ANT8DQrQrs=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "88195a94f390381c6afcdaa933c2f6ff93959cb4",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"font-awesome": "font-awesome",
"nixpkgs": "nixpkgs",
"typix": "typix",
"typst-packages": "typst-packages"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"typix": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1735477665,
"narHash": "sha256-Te7CauUV4NbcKurJpARZ+lwZvN5oqcmzeyVjLX59SXg=",
"owner": "loqusion",
"repo": "typix",
"rev": "fae09f6c69a9e441bfed863a7ba9867f296e8fed",
"type": "github"
},
"original": {
"owner": "loqusion",
"repo": "typix",
"type": "github"
}
},
"typst-packages": {
"flake": false,
"locked": {
"lastModified": 1734773545,
"narHash": "sha256-xpjaqcgLLvTyxDaFDWrHxAlvJCXFisELZNrpdHYGV9o=",
"owner": "typst",
"repo": "packages",
"rev": "b6c3c7cfffda6661dc8eb5de38602fcec5aa72d3",
"type": "github"
},
"original": {
"owner": "typst",
"repo": "packages",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

127
flake.nix Normal file
View file

@ -0,0 +1,127 @@
{
description = "A Typst project";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
typix = {
url = "github:loqusion/typix";
inputs.nixpkgs.follows = "nixpkgs";
};
flake-utils.url = "github:numtide/flake-utils";
font-awesome = {
url = "github:FortAwesome/Font-Awesome";
flake = false;
};
typst-packages = {
url = "github:typst/packages";
flake = false;
};
};
outputs =
inputs@{
nixpkgs,
typix,
flake-utils,
self,
...
}:
flake-utils.lib.eachDefaultSystem (
system:
let
pkgs = nixpkgs.legacyPackages.${system};
inherit (pkgs) lib;
typixLib = typix.lib.${system};
src = typixLib.cleanTypstSource ./.;
commonArgs = {
typstSource = "cv.typ";
fontPaths = [
# Add paths to fonts here
# "${pkgs.roboto}/share/fonts/truetype"
"${inputs.font-awesome}/otfs"
];
virtualPaths = [
# Add paths that must be locally accessible to typst here
{
dest = "icons";
src = "${inputs.font-awesome}/svgs/regular";
}
];
XDG_CACHE_HOME = typstPackagesCache;
SOURCE_DATE_EPOCH = builtins.toString self.lastModified;
};
typstPackagesSrc = "${inputs.typst-packages}/packages";
typstPackagesCache = pkgs.stdenvNoCC.mkDerivation {
name = "typst-packages-cache";
src = typstPackagesSrc;
dontBuild = true;
installPhase = ''
mkdir -p "$out/typst/packages"
cp -LR --reflink=auto --no-preserve=mode -t "$out/typst/packages" "$src"/*
'';
};
# Compile a Typst project, *without* copying the result
# to the current directory
build-drv = typixLib.buildTypstProject (
commonArgs
// {
inherit src;
}
);
# Compile a Typst project, and then copy the result
# to the current directory
build-script = typixLib.buildTypstProjectLocal (
commonArgs
// {
inherit src;
}
);
# Watch a project and recompile on changes
watch-script = typixLib.watchTypstProject commonArgs;
in
{
checks = {
inherit build-drv build-script watch-script;
};
packages.default = build-drv;
apps = rec {
default = watch;
build = flake-utils.lib.mkApp {
drv = build-script;
};
watch = flake-utils.lib.mkApp {
drv = watch-script;
};
};
devShells.default = typixLib.devShell {
inherit (commonArgs) fontPaths virtualPaths;
packages = [
# WARNING: Don't run `typst-build` directly, instead use `nix run .#build`
# See https://github.com/loqusion/typix/issues/2
# build-script
watch-script
# More packages can be added here, like typstfmt
# pkgs.typstfmt
];
};
}
);
}

220
template.typ Normal file
View file

@ -0,0 +1,220 @@
#import "@preview/fontawesome:0.5.0": *
#let _cv-line(left, right, ..args) = {
set block(below: 0pt)
table(
columns: (1fr, 5fr),
stroke: none,
..args.named(),
left,
right,
)
}
#let moderncv-blue = rgb("#3973AF")
#let _header(
title: [],
subtitle: [],
socials: (:),
) = {
let titleStack = stack(
dir: ttb,
spacing: 4.2em,
text(size: 30pt, title),
text(size: 16pt, subtitle),
)
let social(icon, link_prefix, username) = [
#stack(
dir: ltr,
spacing: 0.5em,
fa-icon(icon),
link(link_prefix + username)[#username],
)
]
let custom-social(icon, dest, body) = [
#stack(
dir: ltr,
spacing: 0.6em,
fa-icon(icon),
link(dest, body),
)
]
let socialsDict = (
// key: (faIcon, linkPrefix)
phone: ("phone", "tel:"),
email: ("envelope", "mailto:"),
github: ("github", "https://github.com/"),
linkedin: ("linkedin", "https://linkedin.com/in/"),
x: ("x-twitter", "https://twitter.com/"),
bluesky: ("bluesky", "https://bsky.app/profile/"),
)
let socialsList = ()
for entry in socials {
assert(type(entry) == array, message: "Invalid social entry type.")
assert(entry.len() == 2, message: "Invalid social entry length.")
let (key, value) = entry
if type(value) == str {
if key not in socialsDict {
panic("Unknown social key: " + key)
}
let (icon, linkPrefix) = socialsDict.at(key)
socialsList.push(social(icon, linkPrefix, value))
} else if type(value) == array {
assert(value.len() == 3, message: "Invalid social entry: " + key)
let (icon, dest, body) = value
socialsList.push(custom-social(icon, dest, body))
} else {
panic("Invalid social entry: " + entry)
}
}
let socialStack = stack(
dir: ttb,
spacing: 0.5em,
..socialsList,
)
stack(
dir: ltr,
titleStack,
align(
right + top,
socialStack,
),
)
}
#let moderner-cv(
name: [],
subtitle: [CV],
social: (:),
color: moderncv-blue,
lang: "en",
font: "New Computer Modern",
show-footer: true,
body,
) = [
#set page(
paper: "a4",
margin: (
top: 10mm,
bottom: 15mm,
left: 15mm,
right: 15mm,
),
)
#set text(
font: font,
lang: lang,
)
#show heading: it => {
set text(weight: "regular")
set text(color)
set block(above: 0pt)
_cv-line(
[],
[#it.body],
)
}
#show heading.where(level: 1): it => {
set text(weight: "regular")
set text(color)
_cv-line(
align: horizon,
[#box(fill: color, width: 28mm, height: 0.25em)],
[#it.body],
)
}
#show heading.where(level: 2): it => {
set text(weight: "regular", size: 13pt)
pad(left: 6.9em, [#it.body])
}
#_header(title: name, subtitle: subtitle, socials: social)
#body
#if show-footer [
#v(1fr, weak: false)
#name\
#datetime.today().display("[month repr:long] [day], [year]")
]
]
#let cv-line(left-side, right-side) = {
_cv-line(
align(right, left-side),
par(right-side, justify: true),
)
}
#let cv-entry(
date: [],
title: [],
employer: [],
..description,
) = {
let elements = (
strong(title),
emph(employer),
..description.pos(),
)
cv-line(
date,
elements.join(", "),
)
}
#let cv-language(name: [], level: [], comment: []) = {
_cv-line(
align(right, name),
stack(dir: ltr, level, align(right, emph(comment))),
)
}
#let cv-paper-item(name: [], date: [], journal: []) = {
show link: it => [
#set text(red)
#it
]
_cv-line(
align(right, date),
stack(
dir: ttb,
spacing: 1em,
[*#name*],
journal,
),
)
}
#let cv-double-item(left-1, right-1, left-2, right-2) = {
set block(below: 0pt)
table(
columns: (1fr, 2fr, 1fr, 2fr),
stroke: none,
align(right, left-1), right-1, align(right, left-2), right-2,
)
}
#let cv-list-item(item) = {
_cv-line(
[],
list(item),
)
}
#let cv-list-double-item(item1, item2) = {
set block(below: 0pt)
table(
columns: (1fr, 2.5fr, 2.5fr),
stroke: none,
[], list(item1), list(item2),
)
}