diff --git a/build/assets/include/linalg.hpp b/build/assets/include/linalg.hpp
new file mode 100644
index 0000000..b5d9848
--- /dev/null
+++ b/build/assets/include/linalg.hpp
@@ -0,0 +1,669 @@
+// linalg.h - 2.2 - Single-header public domain linear algebra library
+//
+// The intent of this library is to provide the bulk of the functionality
+// you need to write programs that frequently use small, fixed-size vectors
+// and matrices, in domains such as computational geometry or computer
+// graphics. It strives for terse, readable source code.
+//
+// The original author of this software is Sterling Orsten, and its permanent
+// home is . If you find this software
+// useful, an acknowledgement in your source text and/or product documentation
+// is appreciated, but not required.
+//
+// The author acknowledges significant insights and contributions by:
+// Stan Melax
+// Dimitri Diakopoulos
+//
+// Some features are deprecated. Define LINALG_FORWARD_COMPATIBLE to remove them.
+
+
+
+// This is free and unencumbered software released into the public domain.
+//
+// Anyone is free to copy, modify, publish, use, compile, sell, or
+// distribute this software, either in source code form or as a compiled
+// binary, for any purpose, commercial or non-commercial, and by any
+// means.
+//
+// In jurisdictions that recognize copyright laws, the author or authors
+// of this software dedicate any and all copyright interest in the
+// software to the public domain. We make this dedication for the benefit
+// of the public at large and to the detriment of our heirs and
+// successors. We intend this dedication to be an overt act of
+// relinquishment in perpetuity of all present and future rights to this
+// software under copyright law.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+// For more information, please refer to
+
+
+
+#pragma once
+#ifndef LINALG_H
+#define LINALG_H
+
+#include
+#include
+#include
+
+namespace linalg
+{
+ // Small, fixed-length vector type, consisting of exactly M elements of type T, and presumed to be a column-vector unless otherwise noted.
+ template struct vec;
+
+ // Small, fixed-size matrix type, consisting of exactly M rows and N columns of type T, stored in column-major order.
+ template struct mat;
+
+ // Specialize converter with a function application operator that converts type U to type T to enable implicit conversions
+ template struct converter {};
+ namespace detail
+ {
+ template using conv_t = typename std::enable_if::value, decltype(converter{}(std::declval()))>::type;
+
+ // Trait for retrieving scalar type of any linear algebra object
+ template struct scalar_type {};
+ template struct scalar_type> { using type = T; };
+ template struct scalar_type> { using type = T; };
+
+ // Type returned by the compare(...) function which supports all six comparison operators against 0
+ template struct ord { T a,b; };
+ template constexpr bool operator == (const ord & o, std::nullptr_t) { return o.a == o.b; }
+ template constexpr bool operator != (const ord & o, std::nullptr_t) { return !(o.a == o.b); }
+ template constexpr bool operator < (const ord & o, std::nullptr_t) { return o.a < o.b; }
+ template constexpr bool operator > (const ord & o, std::nullptr_t) { return o.b < o.a; }
+ template constexpr bool operator <= (const ord & o, std::nullptr_t) { return !(o.b < o.a); }
+ template constexpr bool operator >= (const ord & o, std::nullptr_t) { return !(o.a < o.b); }
+
+ // Patterns which can be used with the compare(...) function
+ template struct any_compare {};
+ template struct any_compare,vec> { using type=ord; constexpr ord operator() (const vec & a, const vec & b) const { return ord{a.x,b.x}; } };
+ template struct any_compare,vec> { using type=ord; constexpr ord operator() (const vec & a, const vec & b) const { return !(a.x==b.x) ? ord{a.x,b.x} : ord{a.y,b.y}; } };
+ template struct any_compare,vec> { using type=ord; constexpr ord operator() (const vec & a, const vec & b) const { return !(a.x==b.x) ? ord{a.x,b.x} : !(a.y==b.y) ? ord{a.y,b.y} : ord{a.z,b.z}; } };
+ template struct any_compare,vec> { using type=ord; constexpr ord operator() (const vec & a, const vec & b) const { return !(a.x==b.x) ? ord{a.x,b.x} : !(a.y==b.y) ? ord{a.y,b.y} : !(a.z==b.z) ? ord{a.z,b.z} : ord{a.w,b.w}; } };
+ template struct any_compare,mat> { using type=ord; constexpr ord operator() (const mat & a, const mat & b) const { return compare(a.x,b.x); } };
+ template struct any_compare,mat> { using type=ord; constexpr ord operator() (const mat & a, const mat & b) const { return a.x!=b.x ? compare(a.x,b.x) : compare(a.y,b.y); } };
+ template struct any_compare,mat> { using type=ord; constexpr ord operator() (const mat & a, const mat & b) const { return a.x!=b.x ? compare(a.x,b.x) : a.y!=b.y ? compare(a.y,b.y) : compare(a.z,b.z); } };
+ template struct any_compare,mat> { using type=ord; constexpr ord operator() (const mat & a, const mat & b) const { return a.x!=b.x ? compare(a.x,b.x) : a.y!=b.y ? compare(a.y,b.y) : a.z!=b.z ? compare(a.z,b.z) : compare(a.w,b.w); } };
+
+ // Helper for compile-time index-based access to members of vector and matrix types
+ template struct getter;
+ template<> struct getter<0> { template constexpr auto operator() (A & a) const -> decltype(a.x) { return a.x; } };
+ template<> struct getter<1> { template constexpr auto operator() (A & a) const -> decltype(a.y) { return a.y; } };
+ template<> struct getter<2> { template constexpr auto operator() (A & a) const -> decltype(a.z) { return a.z; } };
+ template<> struct getter<3> { template constexpr auto operator() (A & a) const -> decltype(a.w) { return a.w; } };
+
+ // Stand-in for std::integer_sequence/std::make_integer_sequence
+ template struct seq {};
+ template struct make_seq_impl;
+ template struct make_seq_impl { using type=seq<>; };
+ template struct make_seq_impl { using type=seq; };
+ template struct make_seq_impl { using type=seq; };
+ template struct make_seq_impl { using type=seq; };
+ template struct make_seq_impl { using type=seq; };
+ template using make_seq = typename make_seq_impl::type;
+ template vec constexpr swizzle(const vec & v, seq i [[maybe_unused]]) { return {getter{}(v)...}; }
+ template mat constexpr swizzle(const mat & m, seq i, seq j [[maybe_unused]]) { return {swizzle(getter{}(m),i)...}; }
+
+ // SFINAE helpers to determine result of function application
+ template using ret_t = decltype(std::declval()(std::declval()...));
+
+ // SFINAE helper which is defined if all provided types are scalars
+ struct empty {};
+ template struct scalars;
+ template<> struct scalars<> { using type=void; };
+ template struct scalars : std::conditional::value, scalars, empty>::type {};
+ template using scalars_t = typename scalars::type;
+
+ // Helpers which indicate how apply(F, ...) should be called for various arguments
+ template struct apply {}; // Patterns which contain only vectors or scalars
+ template struct apply, vec > { using type=vec,M>; enum {size=M, mm=0}; template static constexpr type impl(seq, F f, const vec & a ) { return {f(getter{}(a) )...}; } };
+ template struct apply, vec, vec > { using type=vec,M>; enum {size=M, mm=0}; template static constexpr type impl(seq, F f, const vec & a, const vec & b ) { return {f(getter{}(a), getter{}(b) )...}; } };
+ template struct apply, vec, B > { using type=vec,M>; enum {size=M, mm=0}; template static constexpr type impl(seq, F f, const vec & a, B b ) { return {f(getter{}(a), b )...}; } };
+ template struct apply, A, vec > { using type=vec,M>; enum {size=M, mm=0}; template static constexpr type impl(seq, F f, A a, const vec & b ) { return {f(a, getter{}(b) )...}; } };
+ template struct apply, vec, vec, vec> { using type=vec,M>; enum {size=M, mm=0}; template static constexpr type impl(seq, F f, const vec & a, const vec & b, const vec & c) { return {f(getter{}(a), getter{}(b), getter{}(c))...}; } };
+ template struct apply, vec, vec, C > { using type=vec,M>; enum {size=M, mm=0}; template static constexpr type impl(seq, F f, const vec & a, const vec & b, C c) { return {f(getter{}(a), getter{}(b), c )...}; } };
+ template struct apply, vec, B, vec> { using type=vec,M>; enum {size=M, mm=0}; template static constexpr type impl(seq, F f, const vec & a, B b, const vec & c) { return {f(getter{}(a), b, getter{}(c))...}; } };
+ template struct apply, vec, B, C > { using type=vec,M>; enum {size=M, mm=0}; template static constexpr type impl(seq, F f, const vec & a, B b, C c) { return {f(getter{}(a), b, c )...}; } };
+ template struct apply, A, vec, vec> { using type=vec,M>; enum {size=M, mm=0}; template static constexpr type impl(seq, F f, A a, const vec & b, const vec & c) { return {f(a, getter{}(b), getter{}(c))...}; } };
+ template struct apply, A, vec, C > { using type=vec,M>; enum {size=M, mm=0}; template static constexpr type impl(seq, F f, A a, const vec & b, C c) { return {f(a, getter{}(b), c )...}; } };
+ template struct apply, A, B, vec> { using type=vec,M>; enum {size=M, mm=0}; template static constexpr type impl(seq, F f, A a, B b, const vec & c) { return {f(a, b, getter{}(c))...}; } };
+ template struct apply, mat > { using type=mat,M,N>; enum {size=N, mm=0}; template static constexpr type impl(seq, F f, const mat & a ) { return {apply >::impl(make_seq<0,M>{}, f, getter{}(a) )...}; } };
+ template struct apply, mat, mat