2G+@crQb1?M%`V#)rIqF}5r>ky#XyxW@do!I6Xfxh=k-PM^d-c@v
zpaoGZ4D4Iq{mSRMub4GW>LWs0No4{}xuO
z9)<@KSgnnW%}lv3cZ>tbC(5t32wD^uh#A~6bWC*oZI*=k;x#n>bkxECFjJC?$-X|^Ehc(x&aS(m=1^perYzkobz)vS8k)m;@rmgJvY{K&T(LvF$rAmd(GH$<3r`g
z{SMIzRX3JsoZw|?(46^OC;8)XRo6h9AG2i_dMjjbyGZVR<-;+o#yMc*?)D
zXU;zF%b}edAjiuxZejJ4V@x>nW!--ttvl7O%fl}E_pHrGFS{~Z^0PyO*;;`Di}>|{
zU1o|b4TihGjl>J*9)tQdffEc_6&Yl~B@G{|up@(naMZs5x9ER9lh^~l7_S0l8x1Ze
zb7`iq4DLBROa~+`d}@#Tgo!?6d?)~-4Bs6X%4r|)UG
zzh^Eu49_YLeh4yXZTs+P<-Bk4;tOII=+=ksoVaZFH*q!P7Y@-6DlReyD0bBaXnmNr
zf0YiT5Hgfyd~xl>=hUvIRqhNcIJ)gm9l7)=T(qm{!eLNbIank_cN>G&0%a|+`Y9Hb
z{|mSD+GPd?%u`t{!n*LZjjQ9;WF~_}yU)+p5%nz6aj<^(tKa2+jOU~)+*T$R+_al>
zSH$&gbjX&O!O-IXYPjszbFdcsKk=eihtVxDi|MJQx0qHtGDryN)@v*V6<}8v=nAB6
z(fyD%?c+8tRt^T|1yA{HRV};gTQj&__-Avw`*SiXD>3k_xcSL^vh1cGi)WuKj{0}3
zVVlF0jh7e3b~U*Y0&774O
zcp9eJPg(RLUCGY#vhG4%fmm?1v5;BE_^or1{1nYM8NbdRUmxtl;Oh9|;hu@lS8rkE
zYh$>;E>=Iq=+m38d*AXNbP;5_z?|F2oW%V=YRjL6?UTzri&c6#FK=_0oGQJAbrCm6
zj;WwE?6iFO-;14#Q8=)A@Iemm2ag}NWISQ^Z}nRDsZ?>JKzyKm?I&mIr9m}lRfZN{=kXaR3-<6c3A
zsHpP4=Byd+r{{;~Em`@^$Y7--doK5%KS%9!*TwE&(-8T)Kt{K|ZjlCu?FF$Ls=pXE
zB)B^tTjtDoYsR7@fn`S
zPW=}_F)rv3{Xl;aFT<@*=99gA8_L!$l8-v_r##Jl?@kU^#}^m47~4fyU8NW@emZML
z{cHLRO5TP?nHg_^n`E+HPZn`AZ27aWXWO5dD)$pU@}IxCcdok#>%!T*jN0*gZuD1i
z$%Ha2c*?)`No!8v7h%0yOcxKQopE&xWNp|PeN(a9eplw{`F&lij*E2#QonFjtWi{$
z#jxSSr4L6)S7>col#*Z#L&8UQNm459SeuHby)=~d19KKz>-+F=!)czkX4B;Wzew$&9ydyu6UN!qxF0OT+B#
zn`ZsJ6fLx1?%!3LfA3*u`tmR*w|e?Ehmy;ypKR~{R;Fs;$ik5ObMyWWb=FpaUz!y!
zh;A=Kiveyv!@DknEGyxsA--|)e6
z-cuQ=AAXy}e%l#wW;Z8;ZoS6QNBxEuw;i}6vCQkm0&vy)eW&h))eH`&9fIhp5j@0po;PmHxv7!)}Ep64F*Z_JL9qW^2WM}6TgJ<{o+aaPa`b}Fj0;My*9SM0ZTXYf1}4pZezxBSw_1ptXAfX8C&x}^{vLQ#>1fD6_sNF
z0d0KiwzFE9GG5sIuX2(cSGWDGjXw?-f<`wM=?dJ{yTx=g@Ei+6S6x8cH2WV-+Z?7`
z+;#vo{CC9BkEH=p*FI^@+4$qI_!ibh?Y`pOO>;OHisz^5{M)faql-QN+P3+e4+L*9
z1-h-@vRjO4SsllPf8s%lU$9RP_`-bt=En7QiayPnR!_>LK9uF&?rgBQ3X2einn}x6
zC!JZzko#s)^@8ngM;L==GhF!8Ze(S3bzLbVlS80DRly?N0xiY{cx~IzkO9dTRmQh=
zToAMPsLLQ*yWz)Uq1>OBCu#~vsR4cU2ci1
zGiAS~9kUTw;H%9dbMAU}@Jv2m9flZ@zZ}U1TNXd%pLk)BLNb>VgB7^k@O^r?LJ4H~
zl#A2sCqI$a`PXq2so=Pr!7Wn_E;TYv-@m!)cYYdk=q2rS;H+ZhyGOU+4I`|^-SS5<
zEj|18?k%i~ZZEmbbX45=HqZzDrC4e%@
zcX{`D47V~sb*>2O!rOm#bT?_uWw=xOFJ&dTrCNAhe#f+bf2OFc43_LEi;~Q-pEvDz
z;FPeNEQkuXeu4fL)YdY{fU;7RSCLqK
zf&<7sXImF9pW4nJHLHUwsIdwfFqd7bTkrt6C}GfY=WyUx-pb0ih1KD-e3eDzbQAZf496U9Gx<)-
zy&%@1r@WQ*n=NC;)<2Nk!>IP`+{JrdNj$CDFAQ>`6XJy#_P(C4{&L}lAB$zX?F|A!
z+2>Sm;;lBm!`oQnq(RXn8TGH>%CM0c~c7%`e)I%BN=hWL~zc^6E5D%bi`5
zYnKtjnc8U^e>|SFNJH+zCw8CdZ4A4=|6a?G`(;7he#Hgp3>*IQXZ$>z`fc^&vw!Eh
zGbOybw-(5p
zup(tg_acQa1*y>q?hFwdl$n!*n;GW%#jVfP=VnM3WD0PzX6kZF-nvHj!*k?f1ys2(
z6i7jut$S}V&1Q6n{+AZClJmm4&@aXryG0saT5Mi?FQ#RYLPlB{>! s~$Q
zS%vgnXG;GwDJtkxDTPd`nYu`xLFO0VIfwLJlV1O0jhn&cGtEBXBm063Zk`hY>ATkP
zGIWVAV@mwq`sV*Mb|wbhEv#$_CyZljSs9LU2hUslg580C3u{$Qi*fArd5kZP&6`-C
zv#UOb`OZ292mbD_xBmE7)}5);ukWc^mi>TX!MlAo>Qlt0-sirP{^aKC>f1KoSRO>l
z{QA}%+ivbwxo7Qr-G;I^l9i92#7-(IV|IxDa-n>liU@1vg0AV&?XwtGJlmmh`qj7p
zF+w}qcmKP%^Yh*LVw+9ontN`VAz_^Vspj4mt@!Rk|4NnqtH}R8~R>W
zoh<5I*7p5;nR3C&kU!}gepD#Dx$^J--`DKPeq7Q5bw4J(UTnDY^QV_-K_aG&(ONba
zY=amA-bn6r#OrCkvo@dvC`d_PS_HMoL|Cmqtqq21e541Jyf1!@5x3lyK!-9&$Q?hDjr)&QDcpEe_>^bTFjn=ZG{}^Kh+fC(pwY%)a$e@8o|
zcW^MCTk+@VH7}-yOSa0tomcyD%#hpte7Ebx{`n;r&08b4|NioeXZ!T}wpq8?TtDh2
zD%jWv+Na+7G=0hGQ2Tpfksv4f3cA|g%k2GLpa1{N8t;Vm%u=I(CqK96b1pf!L2<#m
zUoKi6$u^fmGZ_N*7?`r^{ENG|{_hcqw-+O(9}umYaG|Yn&&40g!HoM0KWB3tt68x7
z6T^ZV#}xzZLb*CmxWj643I$lI%-_NGBf8*D?9<|(IJ@>wy|97)9EiZhr+g@+a9jmRN
zh}#wP)Zad-;?4Knj`1=&QoX$ASaPx!6*va73@cWHY`6S81(|oOupDXdTWtelTRqwjMfrElk|6~@c|9vYz
zfw{4GRy%WgdVl@exnByV$^9~0roeLI_%!?Ld?o&0c^r1%;P3N!^wRx{zyDly*N?pi
zN}uyuXZ?HV{qN2Woo~+f*X_Gw^_BAg>s@1`$ZdkJ=S|%9XXB6E3oXB;fBb&*PtK$(
zGg)@{?yq@!{@ZaOW$T-N3)9kKWuEvj1e~>9yl6&-_$KaIy7k$&&$9$ykNG3{`*&KM
znkS#7@Ploex4wtY_K=No@nHUBU3!T(}%j}jKh=Pg;e@1wx+
zC6}9xW6!ZNi26n==+>XRFiC#zbNxBrzK1~?fq(K}XxM&{b&g&z@1>FFzK6dW^VFFe
zxc;_k%C>I&vD@)=?b)1jw*MJ2{12Sfsn#e6`}{0?5{oQTjpgO1ISc{29N2cHmwfv7
zSc8XeN2T`ajX&5^CvRuIBlb!7qutz>MOF+e9>mSKRJ(A?M#qc&(ox*4lhsQMZT22L
zsNIyuy-D}NX5-j%>=-3qtkr&$*++wn|x%||Xfg|z!iPq)v
zAG@EOu2Wmd*>u%P-z+Lc`W1hzc5Mr
zfc*R=E6on>vNhy=;;`L#JtN=Yr{c@LygY6$e_2OnVd#F>Niy6?rFqA<{y!ud^L^(Z
zs~ivg?NyeHJ0855H*sRR&cAn=p?{U)J{QXuZL7B_D134I=9LE4LJQ!LB~P!i)SsW
zDkPpRyD28|>GaxzEDWY=w>eA}Kezw4jP|~Nfo+-%^~goz}z6^9Q}Y(xBlJb
zbM=ht%+Dt}*!M2hHP|*ix|yG0)m5<{UT#l+UhWU{Jd@Azf;pV&Z)j$8LW}-(H$jFg
zC#u~TZT?Dd|6TO>gZ!_h(XKLVU&23M*nT3TeV?-JWl>)SiOlmI)9lyJIF!R>(6EzV
z-i-C$rMiEK^E>)~`h=S>I`D2zU!v~hJ1O|fW8q`}C8ikukAJWgG$zSr_eJ*S>9v8Z
z45lyU1$y|~A8Yt%-mTKE4&*(Hn)Uw2Ks~j{TSDQnX=vd`kV1<>jxNGngA*-2~0K*
z-F+S{l29VU;sWA19eN=qIy2WqjJ1P-ks;9_EwF*B=1`=NOA|wbLIE>Fs3ync4i-iR
zM*|rKm(ZS{>5NJa3=RT03=tv=m|O$@#6$Qym^xOe{E2f?;b8c1PwD!$fQ3!E3@)JA
z=D*GQW(*P%j0_A79D)oF_HMbDz|^3n%O$|b#IR?&q%#9U1EU}V14D-ZBg4PhGc83K
z4mfZyFkE;U(!e1A6~Fg8
z)EGeST=;{ZaaF>Zm0$^u))VopE1Ux7fNg7~<6-_A7`Pae5$l#b!%2*&Opsd-|bl({ya8Sb~
zj?-XPI1?zK5>#9d{t#1s$i|T5#Nc3HR9BH~^1Occ{?A?w9skJ=?#vZ(qpI;B4gT
zI8$Vi6N5uQ(J}^!Nq_f#_G#!4U=WzHMB|^%0RcOaquPv0AnCO9G(HxIDHDUa8U&=7
z7@8KFzZhBn5?!TfN3j<4g
zE(6btsSJWj3<@51*c|qMTJq7IQOSkDVZs+PhNTWW`sRsO?*5g(oXMqwp+UiPJ7d?Q
zjSS(QUCfM1t_%(vimVt5M3tAPf8S>(pb*5u!1DU-t81F=j2F8n&e>b<(#z1W;ASpE
z-HFFWzrX%ZHuC;%zsQZj;lh_zhh+>qRP^`R#@~H3K?5ZAVFuHJ=D)wrr`ySJ2v{;P
zG#wXVcw6#*{_1)LMuv$RmrA@D{Qfc9D>Eo?RVh2%;OdZ5|KAu7T9#3((ouGxL-gqU
zpTF4a92p!;w#XWYCu%DM{XEki%lN^ViDA*FwA|m4>`clj+v_cUu$L$?C|Fe~Ojz5{
zAz@itTmM{|@j@d*!wVCB7AZcKV@m!~tC=1MF)=JEDa(I8@h;boFo7+LG~^6^v7ZuT
z5Lhdnxl8-l9IittPac4~w+loV87^LmW>h1XgJx_U#hIt$e9k*^ykDs4%
zY(oIc5edudwe@np8P~ZnIDENx@Aq9s-NuI}xNj!im){}B$gttdEQxj|=7i=sWwsm*
z*@6rW)1EDKm?+#h|IMTGwe<_?-5CDlY>b=zU-Nwb+oVkzAKLu#-%S6%jNyf}Fv9}h
z&wCqGBA-?*u#foD_|Sln!RyY->td5_)*EvcNO#*C*f23%U{*YktMl(b#tkNhste}K
zvu-oW@Ran${*mAOgL$zc14H-)fe)UuvN#@O&D6Gw`+8fHK{=6|;l*Wf_v-r{hV=qI
zy>{=M_uB{XGBFr5?AHHY)_urE#An*X;K@&<(^toDmSqlUVPN2S0a}6RI!ms|qQJ-}
z@Q>>3pBp^)>IdjDF&MNw<89Qr?0H~ULQYis-y84Qk2Nqb^fVMRCMUW7^Nh>+`}W^C
zZAJqz7KQ|uFRUTn`+wbE{?gp$Id_jZBg2XgKjt38{oA>3>`5r7`N}Np%D|wtYlYSYMY=#KCYt;?MrYd#BoXX610l^a}qw@I`>3!Eo2_PcN6<
z75c&KxL~s0pKtBw&3k@BmYF#S{OD+vFJNb6n4!SSH0k;5R>S=hJ2re^ey7O55WFCr
z#VFa#*-j^;XO4K~#~Fuf8)kDb91wZAw$bE#xYJCo7mM^OKZfu7#`s;3fx-QU6q}w{
zt>>g>`N>Zt<9|2Eb1*bC>m7246VY}%+>qSP{+7RQ|1+iamljogyKii)uJfy*o`a!*
z-9+F_+RaPs6Q?fGn5JU*KT2eBrcBP;r~i-osrseAS@b_X^H&$E{0DhPh7VKhymOW_
ze|A;!u1pl`ohx+1{=(<7g>hTDzuAA47MR6dqxe7b|L5gFCo<>F_e|6thQ+pjM0rMPx#fw{9)0dm=u^*(;)78&qol`;+
E04|ZG%m4rY
literal 0
HcmV?d00001
diff --git a/manifest.json b/manifest.json
new file mode 100644
index 00000000..491d3a79
--- /dev/null
+++ b/manifest.json
@@ -0,0 +1,20 @@
+{
+ "background_color": "#ffffff",
+ "theme_color": "#333333",
+ "name": "Upptime",
+ "short_name": "Upptime",
+ "display": "minimal-ui",
+ "start_url": "/",
+ "icons": [
+ {
+ "src": "logo-192.png",
+ "sizes": "192x192",
+ "type": "image/png"
+ },
+ {
+ "src": "logo-512.png",
+ "sizes": "512x512",
+ "type": "image/png"
+ }
+ ]
+}
diff --git a/service-worker-index.html b/service-worker-index.html
new file mode 100644
index 00000000..d1782d9b
--- /dev/null
+++ b/service-worker-index.html
@@ -0,0 +1,26 @@
+
\ No newline at end of file
diff --git a/service-worker.js b/service-worker.js
new file mode 100644
index 00000000..28aec59f
--- /dev/null
+++ b/service-worker.js
@@ -0,0 +1 @@
+!function(){"use strict";self.addEventListener("install",(function(){self.skipWaiting()})),self.addEventListener("activate",(function(){self.registration.unregister().then((function(){return self.clients.matchAll()})).then((function(t){t.forEach((t=>t.navigate(t.url)))})).catch((function(){}))}))}();
diff --git a/themes/dark.css b/themes/dark.css
new file mode 100644
index 00000000..f98f57e7
--- /dev/null
+++ b/themes/dark.css
@@ -0,0 +1,26 @@
+:root {
+ --body-background-color: #001716;
+ --body-text-color: #f0ffff;
+ --card-background-color: #002b29;
+ --nav-background-color: #002b29;
+ --nav-border-bottom-color: #015450;
+ --nav-current-border-bottom-color: #1abc9c;
+ --card-border-color: #015450;
+ --down-border-left-color: #eb3b5a;
+ --down-background-color: #6b1020;
+ --degraded-border-left-color: #f7b731;
+ --up-border-left-color: #20bf6b;
+ --tag-color: #002b29;
+ --tag-up-background-color: #20bf6b;
+ --tag-down-background-color: #eb3b5a;
+ --tag-degraded-background-color: #f7b731;
+ --change-background-color: #f7b731;
+ --error-button-border-color: #1a46ad;
+ --error-button-background-color: #3867d6;
+ --error-button-color: #ffffff;
+ --submit-button-border-color: #1a46ad;
+ --submit-button-background-color: #3867d6;
+ --submit-button-color: #ffffff;
+ --graph-opacity: 1;
+ --graph-filter: none;
+}
diff --git a/themes/light.css b/themes/light.css
new file mode 100644
index 00000000..a9f32a87
--- /dev/null
+++ b/themes/light.css
@@ -0,0 +1,26 @@
+:root {
+ --body-background-color: #f0f7f7;
+ --body-text-color: #002626;
+ --card-background-color: #ffffff;
+ --nav-background-color: #ffffff;
+ --nav-border-bottom-color: #d8e8e4;
+ --nav-current-border-bottom-color: #1abc9c;
+ --card-border-color: #d8e8e4;
+ --down-border-left-color: #eb3b5a;
+ --down-background-color: #ffd0d2;
+ --degraded-border-left-color: #f7b731;
+ --up-border-left-color: #20bf6b;
+ --tag-color: #ffffff;
+ --tag-up-background-color: #20bf6b;
+ --tag-down-background-color: #eb3b5a;
+ --tag-degraded-background-color: #f7b731;
+ --change-background-color: #f7b731;
+ --error-button-border-color: #1a46ad;
+ --error-button-background-color: #3867d6;
+ --error-button-color: #ffffff;
+ --submit-button-border-color: #1a46ad;
+ --submit-button-background-color: #3867d6;
+ --submit-button-color: #ffffff;
+ --graph-opacity: 1;
+ --graph-filter: none;
+}
diff --git a/themes/night.css b/themes/night.css
new file mode 100644
index 00000000..f4090079
--- /dev/null
+++ b/themes/night.css
@@ -0,0 +1,26 @@
+:root {
+ --body-background-color: #0d1117;
+ --body-text-color: #c9d1d9;
+ --card-background-color: #30363D;
+ --nav-background-color: #161b22;
+ --nav-border-bottom-color: #161b22;
+ --nav-current-border-bottom-color: #1abc9c;
+ --card-border-color: #30363D;
+ --down-border-left-color: #eb3b5a;
+ --down-background-color: #6b1020;
+ --degraded-border-left-color: #f7b731;
+ --up-border-left-color: #22993D;
+ --tag-color: #0d1117;
+ --tag-up-background-color: #22993D;
+ --tag-down-background-color: #F03A17;
+ --tag-degraded-background-color: #f7b731;
+ --change-background-color: #f7b731;
+ --error-button-border-color: #1a46ad;
+ --error-button-background-color: #3867d6;
+ --error-button-color: #ffffff;
+ --submit-button-border-color: #1a46ad;
+ --submit-button-background-color: #3867d6;
+ --submit-button-color: #ffffff;
+ --graph-opacity: 1;
+ /* --graph-filter: brightness(0.35) sepia(1) hue-rotate(88deg) saturate(8); */
+}
diff --git a/themes/ocean.css b/themes/ocean.css
new file mode 100644
index 00000000..b32ba63d
--- /dev/null
+++ b/themes/ocean.css
@@ -0,0 +1,26 @@
+:root {
+ --body-background-color: #011945;
+ --body-text-color: #f0ffff;
+ --card-background-color: #0d2f6e;
+ --nav-background-color: #0d2f6e;
+ --nav-border-bottom-color: #002d80;
+ --nav-current-border-bottom-color: #1abc9c;
+ --card-border-color: #002d80;
+ --down-border-left-color: #eb3b5a;
+ --down-background-color: #6b1020;
+ --degraded-border-left-color: #f7b731;
+ --up-border-left-color: #20bf6b;
+ --tag-color: #0d2f6e;
+ --tag-up-background-color: #20bf6b;
+ --tag-down-background-color: #eb3b5a;
+ --tag-degraded-background-color: #f7b731;
+ --change-background-color: #f7b731;
+ --error-button-border-color: #1a46ad;
+ --error-button-background-color: #3867d6;
+ --error-button-color: #ffffff;
+ --submit-button-border-color: #1a46ad;
+ --submit-button-background-color: #3867d6;
+ --submit-button-color: #ffffff;
+ --graph-opacity: 1;
+ --graph-filter: none;
+}
diff --git a/upptime-icon.svg b/upptime-icon.svg
new file mode 100644
index 00000000..f909d51a
--- /dev/null
+++ b/upptime-icon.svg
@@ -0,0 +1,4 @@
+
|