st

Mahdi's build of st
git clone git://mahdi.pw/st.git
Log | Files | Refs | README | LICENSE

commit fb6924eb9dda65d10bef4ecd51de60168e4ab453
parent 60b4ed87ca58638c3cce20e0fb88a45be77a5b18
Author: Mahdi Mirzade <me@mahdi.pw>
Date:   Sun, 22 May 2022 19:14:14 +0430

Add anysize, externalpipe patches, other tweaks.

Diffstat:
MMakefile | 4++++
Mconfig.h | 25++++++++++++++++---------
Apatches/st-anysize-0.8.4.diff | 152+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apatches/st-externalpipe-0.8.4.diff | 92+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apatches/st-externalpipe-eternal-0.8.3.diff | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ast-copyout | 13+++++++++++++
Ast-urlhandler | 1521+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mst.c | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Mst.h | 2++
Mx.c | 81++++++++++++++++++++++++++++++++++++++++++-------------------------------------
10 files changed, 1997 insertions(+), 49 deletions(-)

diff --git a/Makefile b/Makefile @@ -43,7 +43,11 @@ dist: clean install: st mkdir -p $(DESTDIR)$(PREFIX)/bin cp -f st $(DESTDIR)$(PREFIX)/bin + cp -f st-copyout $(DESTDIR)$(PREFIX)/bin + cp -f st-urlhandler $(DESTDIR)$(PREFIX)/bin chmod 755 $(DESTDIR)$(PREFIX)/bin/st + chmod 755 $(DESTDIR)$(PREFIX)/bin/st-copyout + chmod 755 $(DESTDIR)$(PREFIX)/bin/st-urlhandler mkdir -p $(DESTDIR)$(MANPREFIX)/man1 sed "s/VERSION/$(VERSION)/g" < st.1 > $(DESTDIR)$(MANPREFIX)/man1/st.1 chmod 644 $(DESTDIR)$(MANPREFIX)/man1/st.1 diff --git a/config.h b/config.h @@ -5,12 +5,11 @@ * * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html */ -static char *font = "monospace:pixelsize=12"; +static char *font = "monospace:size=9"; /* Spare fonts */ static char *font2[] = { - "Vazir:pixelsize=12", - "JoyPixels:pixelsize=10", -}; + "Vazir:pixelsize=9", + "emoji:size=9", }; static int borderpx = 2; /* @@ -99,7 +98,7 @@ char *termname = "st-256color"; unsigned int tabspaces = 8; /* bg opacity */ -float alpha = 0.98, alphaUnfocused = 0.96; +float alpha = 0.95, alphaUnfocused = 0.9; /* Terminal colors (16 first used in escape sequence) */ static const char *colorname[] = { @@ -189,10 +188,10 @@ static uint forcemousemod = ShiftMask; static MouseShortcut mshortcuts[] = { /* mask button function argument release */ { XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 }, - //{ XK_ANY_MOD, Button4, ttysend, {.s = "\031"} }, - //{ XK_ANY_MOD, Button5, ttysend, {.s = "\005"} }, - { XK_ANY_MOD, Button4, kscrollup, {.i = 1} }, - { XK_ANY_MOD, Button5, kscrolldown, {.i = 1} }, + { ControlMask, Button4, kscrollup, {.i = 1} }, + { ControlMask, Button5, kscrolldown, {.i = 1} }, + { XK_ANY_MOD, Button4, ttysend, {.s = "\031"} }, + { XK_ANY_MOD, Button5, ttysend, {.s = "\005"} }, { ShiftMask, Button4, ttysend, {.s = "\033[5;2~"} }, { ShiftMask, Button5, ttysend, {.s = "\033[6;2~"} }, }; @@ -201,6 +200,10 @@ static MouseShortcut mshortcuts[] = { #define MODKEY Mod1Mask #define TERMMOD (ControlMask|ShiftMask) +static char *openurlcmd[] = { "/bin/sh", "-c", "st-urlhandler -o", "externalpipe", NULL }; +static char *copyurlcmd[] = { "/bin/sh", "-c", "st-urlhandler -c", "externalpipe", NULL }; +static char *copyoutput[] = { "/bin/sh", "-c", "st-copyout", "externalpipe", NULL }; + static Shortcut shortcuts[] = { /* mask keysym function argument */ { XK_ANY_MOD, XK_Break, sendbreak, {.i = 0} }, @@ -208,6 +211,9 @@ static Shortcut shortcuts[] = { { ShiftMask, XK_Print, printscreen, {.i = 0} }, { XK_ANY_MOD, XK_Print, printsel, {.i = 0} }, { ControlMask, XK_equal, zoomreset, {.f = 0} }, + { MODKEY, XK_l, externalpipe, {.v = openurlcmd } }, + { MODKEY, XK_y, externalpipe, {.v = copyurlcmd } }, + { MODKEY, XK_o, externalpipe, {.v = copyoutput } }, { TERMMOD, XK_plus, zoom, {.f = +1} }, { TERMMOD, XK_underscore, zoom, {.f = -1} }, { TERMMOD, XK_C, clipcopy, {.i = 0} }, @@ -488,3 +494,4 @@ static char ascii_printable[] = " !\"#$%&'()*+,-./0123456789:;<=>?" "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" "`abcdefghijklmnopqrstuvwxyz{|}~"; + diff --git a/patches/st-anysize-0.8.4.diff b/patches/st-anysize-0.8.4.diff @@ -0,0 +1,152 @@ +diff --git a/x.c b/x.c +index 8bf998e..e2cda07 100644 +--- a/x.c ++++ b/x.c +@@ -81,6 +81,7 @@ typedef XftGlyphFontSpec GlyphFontSpec; + typedef struct { + int tw, th; /* tty width and height */ + int w, h; /* window width and height */ ++ int hborderpx, vborderpx; + int ch; /* char height */ + int cw; /* char width */ + int mode; /* window state/mode flags */ +@@ -331,7 +332,7 @@ ttysend(const Arg *arg) + int + evcol(XEvent *e) + { +- int x = e->xbutton.x - borderpx; ++ int x = e->xbutton.x - win.hborderpx; + LIMIT(x, 0, win.tw - 1); + return x / win.cw; + } +@@ -339,7 +340,7 @@ evcol(XEvent *e) + int + evrow(XEvent *e) + { +- int y = e->xbutton.y - borderpx; ++ int y = e->xbutton.y - win.vborderpx; + LIMIT(y, 0, win.th - 1); + return y / win.ch; + } +@@ -723,6 +724,9 @@ cresize(int width, int height) + col = MAX(1, col); + row = MAX(1, row); + ++ win.hborderpx = (win.w - col * win.cw) / 2; ++ win.vborderpx = (win.h - row * win.ch) / 2; ++ + tresize(col, row); + xresize(col, row); + ttyresize(win.tw, win.th); +@@ -840,8 +844,8 @@ xhints(void) + sizeh->flags = PSize | PResizeInc | PBaseSize | PMinSize; + sizeh->height = win.h; + sizeh->width = win.w; +- sizeh->height_inc = win.ch; +- sizeh->width_inc = win.cw; ++ sizeh->height_inc = 1; ++ sizeh->width_inc = 1; + sizeh->base_height = 2 * borderpx; + sizeh->base_width = 2 * borderpx; + sizeh->min_height = win.ch + 2 * borderpx; +@@ -1123,8 +1127,8 @@ xinit(int cols, int rows) + xloadcols(); + + /* adjust fixed window geometry */ +- win.w = 2 * borderpx + cols * win.cw; +- win.h = 2 * borderpx + rows * win.ch; ++ win.w = 2 * win.hborderpx + 2 * borderpx + cols * win.cw; ++ win.h = 2 * win.vborderpx + 2 * borderpx + rows * win.ch; + if (xw.gm & XNegative) + xw.l += DisplayWidth(xw.dpy, xw.scr) - win.w - 2; + if (xw.gm & YNegative) +@@ -1213,7 +1217,7 @@ xinit(int cols, int rows) + int + xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y) + { +- float winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, xp, yp; ++ float winx = win.hborderpx + x * win.cw, winy = win.vborderpx + y * win.ch, xp, yp; + ushort mode, prevmode = USHRT_MAX; + Font *font = &dc.font; + int frcflags = FRC_NORMAL; +@@ -1346,7 +1350,7 @@ void + xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y) + { + int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1); +- int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, ++ int winx = win.hborderpx + x * win.cw, winy = win.vborderpx + y * win.ch, + width = charlen * win.cw; + Color *fg, *bg, *temp, revfg, revbg, truefg, truebg; + XRenderColor colfg, colbg; +@@ -1436,17 +1440,17 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i + + /* Intelligent cleaning up of the borders. */ + if (x == 0) { +- xclear(0, (y == 0)? 0 : winy, borderpx, ++ xclear(0, (y == 0)? 0 : winy, win.vborderpx, + winy + win.ch + +- ((winy + win.ch >= borderpx + win.th)? win.h : 0)); ++ ((winy + win.ch >= win.vborderpx + win.th)? win.h : 0)); + } +- if (winx + width >= borderpx + win.tw) { ++ if (winx + width >= win.hborderpx + win.tw) { + xclear(winx + width, (y == 0)? 0 : winy, win.w, +- ((winy + win.ch >= borderpx + win.th)? win.h : (winy + win.ch))); ++ ((winy + win.ch >= win.vborderpx + win.th)? win.h : (winy + win.ch))); + } + if (y == 0) +- xclear(winx, 0, winx + width, borderpx); +- if (winy + win.ch >= borderpx + win.th) ++ xclear(winx, 0, winx + width, win.vborderpx); ++ if (winy + win.ch >= win.vborderpx + win.th) + xclear(winx, winy + win.ch, winx + width, win.h); + + /* Clean up the region we want to draw to. */ +@@ -1540,35 +1544,35 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) + case 3: /* Blinking Underline */ + case 4: /* Steady Underline */ + XftDrawRect(xw.draw, &drawcol, +- borderpx + cx * win.cw, +- borderpx + (cy + 1) * win.ch - \ ++ win.hborderpx + cx * win.cw, ++ win.vborderpx + (cy + 1) * win.ch - \ + cursorthickness, + win.cw, cursorthickness); + break; + case 5: /* Blinking bar */ + case 6: /* Steady bar */ + XftDrawRect(xw.draw, &drawcol, +- borderpx + cx * win.cw, +- borderpx + cy * win.ch, ++ win.hborderpx + cx * win.cw, ++ win.vborderpx + cy * win.ch, + cursorthickness, win.ch); + break; + } + } else { + XftDrawRect(xw.draw, &drawcol, +- borderpx + cx * win.cw, +- borderpx + cy * win.ch, ++ win.hborderpx + cx * win.cw, ++ win.vborderpx + cy * win.ch, + win.cw - 1, 1); + XftDrawRect(xw.draw, &drawcol, +- borderpx + cx * win.cw, +- borderpx + cy * win.ch, ++ win.hborderpx + cx * win.cw, ++ win.vborderpx + cy * win.ch, + 1, win.ch - 1); + XftDrawRect(xw.draw, &drawcol, +- borderpx + (cx + 1) * win.cw - 1, +- borderpx + cy * win.ch, ++ win.hborderpx + (cx + 1) * win.cw - 1, ++ win.vborderpx + cy * win.ch, + 1, win.ch - 1); + XftDrawRect(xw.draw, &drawcol, +- borderpx + cx * win.cw, +- borderpx + (cy + 1) * win.ch - 1, ++ win.hborderpx + cx * win.cw, ++ win.vborderpx + (cy + 1) * win.ch - 1, + win.cw, 1); + } + } diff --git a/patches/st-externalpipe-0.8.4.diff b/patches/st-externalpipe-0.8.4.diff @@ -0,0 +1,92 @@ +diff --git a/st.c b/st.c +index 76b7e0d..0e9a614 100644 +--- a/st.c ++++ b/st.c +@@ -723,8 +723,14 @@ sigchld(int a) + if ((p = waitpid(pid, &stat, WNOHANG)) < 0) + die("waiting for pid %hd failed: %s\n", pid, strerror(errno)); + +- if (pid != p) ++ if (pid != p) { ++ if (p == 0 && wait(&stat) < 0) ++ die("wait: %s\n", strerror(errno)); ++ ++ /* reinstall sigchld handler */ ++ signal(SIGCHLD, sigchld); + return; ++ } + + if (WIFEXITED(stat) && WEXITSTATUS(stat)) + die("child exited with status %d\n", WEXITSTATUS(stat)); +@@ -1926,6 +1932,59 @@ strparse(void) + } + } + ++void ++externalpipe(const Arg *arg) ++{ ++ int to[2]; ++ char buf[UTF_SIZ]; ++ void (*oldsigpipe)(int); ++ Glyph *bp, *end; ++ int lastpos, n, newline; ++ ++ if (pipe(to) == -1) ++ return; ++ ++ switch (fork()) { ++ case -1: ++ close(to[0]); ++ close(to[1]); ++ return; ++ case 0: ++ dup2(to[0], STDIN_FILENO); ++ close(to[0]); ++ close(to[1]); ++ execvp(((char **)arg->v)[0], (char **)arg->v); ++ fprintf(stderr, "st: execvp %s\n", ((char **)arg->v)[0]); ++ perror("failed"); ++ exit(0); ++ } ++ ++ close(to[0]); ++ /* ignore sigpipe for now, in case child exists early */ ++ oldsigpipe = signal(SIGPIPE, SIG_IGN); ++ newline = 0; ++ for (n = 0; n < term.row; n++) { ++ bp = term.line[n]; ++ lastpos = MIN(tlinelen(n) + 1, term.col) - 1; ++ if (lastpos < 0) ++ break; ++ end = &bp[lastpos + 1]; ++ for (; bp < end; ++bp) ++ if (xwrite(to[1], buf, utf8encode(bp->u, buf)) < 0) ++ break; ++ if ((newline = term.line[n][lastpos].mode & ATTR_WRAP)) ++ continue; ++ if (xwrite(to[1], "\n", 1) < 0) ++ break; ++ newline = 0; ++ } ++ if (newline) ++ (void)xwrite(to[1], "\n", 1); ++ close(to[1]); ++ /* restore */ ++ signal(SIGPIPE, oldsigpipe); ++} ++ + void + strdump(void) + { +diff --git a/st.h b/st.h +index 3d351b6..392b64e 100644 +--- a/st.h ++++ b/st.h +@@ -81,6 +81,7 @@ void die(const char *, ...); + void redraw(void); + void draw(void); + ++void externalpipe(const Arg *); + void printscreen(const Arg *); + void printsel(const Arg *); + void sendbreak(const Arg *); diff --git a/patches/st-externalpipe-eternal-0.8.3.diff b/patches/st-externalpipe-eternal-0.8.3.diff @@ -0,0 +1,74 @@ +From 2228468a6db1e648c69849860d30867c0e77650e Mon Sep 17 00:00:00 2001 +From: AtomToast <reg-2@t-online.de> +Date: Wed, 29 Apr 2020 02:31:29 +0200 +Subject: [PATCH] apply Luke Smiths external pipe eternal patch + +Enables external pipe to work on the entire scrollback history. + +Source: https://github.com/LukeSmithxyz/st/commit/da13ef12463d1870caed94584db464d68c6b3182 +Made to work on semi-vanilla st. + +This patch requires both externalpipe and scrollback patch in order to work +--- + st.c | 25 +++++++++++++++++++++---- + 1 file changed, 21 insertions(+), 4 deletions(-) + +diff --git a/st.c b/st.c +index d4c88a2..2716f44 100644 +--- a/st.c ++++ b/st.c +@@ -46,6 +46,7 @@ + #define TLINE(y) ((y) < term.scr ? term.hist[((y) + term.histi - \ + term.scr + HISTSIZE + 1) % HISTSIZE] : \ + term.line[(y) - term.scr]) ++#define TLINE_HIST(y) ((y) <= HISTSIZE-term.row+2 ? term.hist[(y)] : term.line[(y-HISTSIZE+term.row-3)]) + + enum term_mode { + MODE_WRAP = 1 << 0, +@@ -431,6 +432,20 @@ tlinelen(int y) + return i; + } + ++int ++tlinehistlen(int y) ++{ ++ int i = term.col; ++ ++ if (TLINE_HIST(y)[i - 1].mode & ATTR_WRAP) ++ return i; ++ ++ while (i > 0 && TLINE_HIST(y)[i - 1].u == ' ') ++ --i; ++ ++ return i; ++} ++ + void + selstart(int col, int row, int snap) + { +@@ -2025,16 +2040,18 @@ externalpipe(const Arg *arg) + /* ignore sigpipe for now, in case child exists early */ + oldsigpipe = signal(SIGPIPE, SIG_IGN); + newline = 0; +- for (n = 0; n < term.row; n++) { +- bp = term.line[n]; +- lastpos = MIN(tlinelen(n) + 1, term.col) - 1; ++ for (n = 0; n <= HISTSIZE + 2; n++) { ++ bp = TLINE_HIST(n); ++ lastpos = MIN(tlinehistlen(n) + 1, term.col) - 1; + if (lastpos < 0) + break; ++ if (lastpos == 0) ++ continue; + end = &bp[lastpos + 1]; + for (; bp < end; ++bp) + if (xwrite(to[1], buf, utf8encode(bp->u, buf)) < 0) + break; +- if ((newline = term.line[n][lastpos].mode & ATTR_WRAP)) ++ if ((newline = TLINE_HIST(n)[lastpos].mode & ATTR_WRAP)) + continue; + if (xwrite(to[1], "\n", 1) < 0) + break; +-- +2.26.2 + diff --git a/st-copyout b/st-copyout @@ -0,0 +1,13 @@ +#!/bin/sh +# Using external pipe with st, give a dmenu prompt of recent commands, +# allowing the user to copy the output of one. +# xclip required for this script. +# By Jaywalker and Luke +tmpfile=$(mktemp /tmp/st-cmd-output.XXXXXX) +trap 'rm "$tmpfile"' 0 1 15 +sed -n "w $tmpfile" +sed -i 's/\x0//g' "$tmpfile" +ps1="$(grep "\S" "$tmpfile" | tail -n 1 | sed 's/^\s*//' | cut -d' ' -f1)" +chosen="$(grep -F "$ps1" "$tmpfile" | sed '$ d' | tac | dmenu -p "Copy which command's output?" -i -l 10 | sed 's/[^^]/[&]/g; s/\^/\\^/g')" +eps1="$(echo "$ps1" | sed 's/[^^]/[&]/g; s/\^/\\^/g')" +awk "/^$chosen$/{p=1;print;next} p&&/$eps1/{p=0};p" "$tmpfile" | xclip -selection clipboard diff --git a/st-urlhandler b/st-urlhandler @@ -0,0 +1,1521 @@ + + + + + + + +<!DOCTYPE html> +<html lang="en" data-color-mode="auto" data-light-theme="light" data-dark-theme="dark" data-a11y-animated-images="system"> + <head> + <meta charset="utf-8"> + <link rel="dns-prefetch" href="https://github.githubassets.com"> + <link rel="dns-prefetch" href="https://avatars.githubusercontent.com"> + <link rel="dns-prefetch" href="https://github-cloud.s3.amazonaws.com"> + <link rel="dns-prefetch" href="https://user-images.githubusercontent.com/"> + <link rel="preconnect" href="https://github.githubassets.com" crossorigin> + <link rel="preconnect" href="https://avatars.githubusercontent.com"> + + + + <link crossorigin="anonymous" media="all" integrity="sha512-ksfTgQOOnE+FFXf+yNfVjKSlEckJAdufFIYGK7ZjRhWcZgzAGcmZqqArTgMLpu90FwthqcCX4ldDgKXbmVMeuQ==" rel="stylesheet" href="https://github.githubassets.com/assets/light-92c7d381038e.css" /><link crossorigin="anonymous" media="all" integrity="sha512-1KkMNn8M/al/dtzBLupRwkIOgnA9MWkm8oxS+solP87jByEvY/g4BmoxLihRogKcX1obPnf4Yp7dI0ZTWO+ljg==" rel="stylesheet" href="https://github.githubassets.com/assets/dark-d4a90c367f0c.css" /><link data-color-theme="dark_dimmed" crossorigin="anonymous" media="all" integrity="sha512-cZa7DZqvMBwD236uzEunO/G1dvw8/QftyT2UtLWKQFEy0z0eq0R5WPwqVME+3NSZG1YaLJAaIqtU+m0zWf/6SQ==" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_dimmed-7196bb0d9aaf.css" /><link data-color-theme="dark_high_contrast" crossorigin="anonymous" media="all" integrity="sha512-WVoKqJ4y1nLsdNH4RkRT5qrM9+n9RFe1RHSiTnQkBf5TSZkJEc9GpLpTIS7T15EQaUQBJ8BwmKvwFPVqfpTEIQ==" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_high_contrast-595a0aa89e32.css" /><link data-color-theme="dark_colorblind" crossorigin="anonymous" media="all" integrity="sha512-XpAMBMSRZ6RTXgepS8LjKiOeNK3BilRbv8qEiA/M3m+Q4GoqxtHedOI5BAZRikCzfBL4KWYvVzYZSZ8Gp/UnUg==" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_colorblind-5e900c04c491.css" /><link data-color-theme="light_colorblind" crossorigin="anonymous" media="all" integrity="sha512-3HF2HZ4LgEIQm77yOzoeR20CX1n2cUQlcywscqF4s+5iplolajiHV7E5ranBwkX65jN9TNciHEVSYebQ+8xxEw==" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_colorblind-dc71761d9e0b.css" /><link data-color-theme="light_high_contrast" crossorigin="anonymous" media="all" integrity="sha512-+J8j3T0kbK9/sL3zbkCfPtgYcRD4qQfRbT6xnfOrOTjvz4zhr0M7AXPuE642PpaxGhHs1t77cTtieW9hI2K6Gw==" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_high_contrast-f89f23dd3d24.css" /><link data-color-theme="light_tritanopia" crossorigin="anonymous" media="all" integrity="sha512-AQeAx5wHQAXNf0DmkvVlHYwA3f6BkxunWTI0GGaRN57GqD+H9tW8RKIKlopLS0qGaC54seFsPc601GDlqIuuHg==" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_tritanopia-010780c79c07.css" /><link data-color-theme="dark_tritanopia" crossorigin="anonymous" media="all" integrity="sha512-+u5pmgAE0T03d/yI6Ha0NWwz6Pk0W6S6WEfIt8veDVdK8NTjcMbZmQB9XUCkDlrBoAKkABva8HuGJ+SzEpV1Uw==" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_tritanopia-faee699a0004.css" /> + + <link crossorigin="anonymous" media="all" integrity="sha512-hWiFpaVJG+3wHAdSwdg6RIbFZLU0r8cRNf89903QbJzJ/hhybi/ng6xSLFKySsz0n8AJ5IoQUnoD4K+rnO8qZg==" rel="stylesheet" href="https://github.githubassets.com/assets/primer-856885a5a549.css" /> + <link crossorigin="anonymous" media="all" integrity="sha512-m+INOiXmzglOe98h1DUpOJ/cczwJhT8Mh7nf7LgR6WzRo9ldMz52dlc3uCof0dvfm+vsxQ1skpP7mwvzHOuXaA==" rel="stylesheet" href="https://github.githubassets.com/assets/global-9be20d3a25e6.css" /> + <link crossorigin="anonymous" media="all" integrity="sha512-7IJmKQ+UuHbW0jikn65NK7GPXj4nX7QVv6KbQEhEFS1mypjAOdJ9IvwVUrcrthT1CES6o6xbG8RnDiBlY/rbDQ==" rel="stylesheet" href="https://github.githubassets.com/assets/blob-ec8266290f94.css" /> +<link crossorigin="anonymous" media="all" integrity="sha512-hHbHxm/XzrCO6gujNDIGH7TFPwaHSdTNoE8unl9fGxGDnMKwoNNoZlp4lbEG0spdOPZYirnR/gMqQ0lDZ1PwNg==" rel="stylesheet" href="https://github.githubassets.com/assets/github-8476c7c66fd7.css" /> + + <meta name="optimizely-datafile" content="{&quot;groups&quot;: [], &quot;environmentKey&quot;: &quot;production&quot;, &quot;rollouts&quot;: [], &quot;typedAudiences&quot;: [], &quot;projectId&quot;: &quot;16737760170&quot;, &quot;variables&quot;: [], &quot;featureFlags&quot;: [], &quot;experiments&quot;: [{&quot;status&quot;: &quot;Running&quot;, &quot;audienceIds&quot;: [], &quot;variations&quot;: [{&quot;variables&quot;: [], &quot;id&quot;: &quot;20667381018&quot;, &quot;key&quot;: &quot;control&quot;}, {&quot;variables&quot;: [], &quot;id&quot;: &quot;20680930759&quot;, &quot;key&quot;: &quot;treatment&quot;}], &quot;id&quot;: &quot;20652570897&quot;, &quot;key&quot;: &quot;project_genesis&quot;, &quot;layerId&quot;: &quot;20672300363&quot;, &quot;trafficAllocation&quot;: [{&quot;entityId&quot;: &quot;20667381018&quot;, &quot;endOfRange&quot;: 5000}, {&quot;entityId&quot;: &quot;20680930759&quot;, &quot;endOfRange&quot;: 10000}], &quot;forcedVariations&quot;: {&quot;83356e17066d336d1803024138ecb683&quot;: &quot;treatment&quot;, &quot;18e31c8a9b2271332466133162a4aa0d&quot;: &quot;treatment&quot;, &quot;10f8ab3fbc5ebe989a36a05f79d48f32&quot;: &quot;treatment&quot;, &quot;1686089f6d540cd2deeaec60ee43ecf7&quot;: &quot;treatment&quot;}}, {&quot;status&quot;: &quot;Running&quot;, &quot;audienceIds&quot;: [], &quot;variations&quot;: [{&quot;variables&quot;: [], &quot;id&quot;: &quot;21440190065&quot;, &quot;key&quot;: &quot;control_b&quot;}, {&quot;variables&quot;: [], &quot;id&quot;: &quot;21439580309&quot;, &quot;key&quot;: &quot;treatment_d&quot;}], &quot;id&quot;: &quot;21435481980&quot;, &quot;key&quot;: &quot;_260_contact_sales_redesign&quot;, &quot;layerId&quot;: &quot;21431681200&quot;, &quot;trafficAllocation&quot;: [{&quot;entityId&quot;: &quot;21440190065&quot;, &quot;endOfRange&quot;: 5000}, {&quot;entityId&quot;: &quot;21439580309&quot;, &quot;endOfRange&quot;: 10000}], &quot;forcedVariations&quot;: {}}, {&quot;status&quot;: &quot;Running&quot;, &quot;audienceIds&quot;: [], &quot;variations&quot;: [{&quot;variables&quot;: [], &quot;id&quot;: &quot;21427950901&quot;, &quot;key&quot;: &quot;control&quot;}, {&quot;variables&quot;: [], &quot;id&quot;: &quot;21429710665&quot;, &quot;key&quot;: &quot;beginner&quot;}, {&quot;variables&quot;: [], &quot;id&quot;: &quot;21437291543&quot;, &quot;key&quot;: &quot;upstart&quot;}], &quot;id&quot;: &quot;21445030708&quot;, &quot;key&quot;: &quot;_259_zero_user_dashboard&quot;, &quot;layerId&quot;: &quot;21434011841&quot;, &quot;trafficAllocation&quot;: [{&quot;entityId&quot;: &quot;21427950901&quot;, &quot;endOfRange&quot;: 3334}, {&quot;entityId&quot;: &quot;21427950901&quot;, &quot;endOfRange&quot;: 5000}, {&quot;entityId&quot;: &quot;21427950901&quot;, &quot;endOfRange&quot;: 8333}, {&quot;entityId&quot;: &quot;21427950901&quot;, &quot;endOfRange&quot;: 10000}], &quot;forcedVariations&quot;: {&quot;3c64268131793aa297119a343c19e345&quot;: &quot;beginner&quot;, &quot;95b24126db31ea8693c0fe5ea9f53b65&quot;: &quot;beginner&quot;, &quot;086e2abe64e9101112af53b95d2d90b9&quot;: &quot;upstart&quot;, &quot;bae688df9d297afac98e2d254e912ada&quot;: &quot;control&quot;, &quot;6c2cfda7c41396fcc31a4db759a42b94&quot;: &quot;beginner&quot;, &quot;16ed2b4ff7de02663b7c606309695916&quot;: &quot;control&quot;, &quot;1971768911.1635962195&quot;: &quot;beginner&quot;, &quot;830bf802470ec6c9c5800c99d8e57445&quot;: &quot;beginner&quot;}}], &quot;version&quot;: &quot;4&quot;, &quot;audiences&quot;: [{&quot;conditions&quot;: &quot;[\&quot;or\&quot;, {\&quot;match\&quot;: \&quot;exact\&quot;, \&quot;name\&quot;: \&quot;$opt_dummy_attribute\&quot;, \&quot;type\&quot;: \&quot;custom_attribute\&quot;, \&quot;value\&quot;: \&quot;$opt_dummy_value\&quot;}]&quot;, &quot;id&quot;: &quot;$opt_dummy_audience&quot;, &quot;name&quot;: &quot;Optimizely-Generated Audience for Backwards Compatibility&quot;}], &quot;anonymizeIP&quot;: true, &quot;sdkKey&quot;: &quot;WTc6awnGuYDdG98CYRban&quot;, &quot;attributes&quot;: [{&quot;id&quot;: &quot;16822470375&quot;, &quot;key&quot;: &quot;user_id&quot;}, {&quot;id&quot;: &quot;17143601254&quot;, &quot;key&quot;: &quot;spammy&quot;}, {&quot;id&quot;: &quot;18175660309&quot;, &quot;key&quot;: &quot;organization_plan&quot;}, {&quot;id&quot;: &quot;18813001570&quot;, &quot;key&quot;: &quot;is_logged_in&quot;}, {&quot;id&quot;: &quot;19073851829&quot;, &quot;key&quot;: &quot;geo&quot;}, {&quot;id&quot;: &quot;20175462351&quot;, &quot;key&quot;: &quot;requestedCurrency&quot;}, {&quot;id&quot;: &quot;20785470195&quot;, &quot;key&quot;: &quot;country_code&quot;}], &quot;botFiltering&quot;: false, &quot;accountId&quot;: &quot;16737760170&quot;, &quot;events&quot;: [{&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;17911811441&quot;, &quot;key&quot;: &quot;hydro_click.dashboard.teacher_toolbox_cta&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;18124116703&quot;, &quot;key&quot;: &quot;submit.organizations.complete_sign_up&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;18145892387&quot;, &quot;key&quot;: &quot;no_metric.tracked_outside_of_optimizely&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;18178755568&quot;, &quot;key&quot;: &quot;click.org_onboarding_checklist.add_repo&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;18180553241&quot;, &quot;key&quot;: &quot;submit.repository_imports.create&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;18186103728&quot;, &quot;key&quot;: &quot;click.help.learn_more_about_repository_creation&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;18188530140&quot;, &quot;key&quot;: &quot;test_event&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;18191963644&quot;, &quot;key&quot;: &quot;click.empty_org_repo_cta.transfer_repository&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;18195612788&quot;, &quot;key&quot;: &quot;click.empty_org_repo_cta.import_repository&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;18210945499&quot;, &quot;key&quot;: &quot;click.org_onboarding_checklist.invite_members&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;18211063248&quot;, &quot;key&quot;: &quot;click.empty_org_repo_cta.create_repository&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;18215721889&quot;, &quot;key&quot;: &quot;click.org_onboarding_checklist.update_profile&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;18224360785&quot;, &quot;key&quot;: &quot;click.org_onboarding_checklist.dismiss&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;18234832286&quot;, &quot;key&quot;: &quot;submit.organization_activation.complete&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;18252392383&quot;, &quot;key&quot;: &quot;submit.org_repository.create&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;18257551537&quot;, &quot;key&quot;: &quot;submit.org_member_invitation.create&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;18259522260&quot;, &quot;key&quot;: &quot;submit.organization_profile.update&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;18564603625&quot;, &quot;key&quot;: &quot;view.classroom_select_organization&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;18568612016&quot;, &quot;key&quot;: &quot;click.classroom_sign_in_click&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;18572592540&quot;, &quot;key&quot;: &quot;view.classroom_name&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;18574203855&quot;, &quot;key&quot;: &quot;click.classroom_create_organization&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;18582053415&quot;, &quot;key&quot;: &quot;click.classroom_select_organization&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;18589463420&quot;, &quot;key&quot;: &quot;click.classroom_create_classroom&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;18591323364&quot;, &quot;key&quot;: &quot;click.classroom_create_first_classroom&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;18591652321&quot;, &quot;key&quot;: &quot;click.classroom_grant_access&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;18607131425&quot;, &quot;key&quot;: &quot;view.classroom_creation&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;18831680583&quot;, &quot;key&quot;: &quot;upgrade_account_plan&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;19064064515&quot;, &quot;key&quot;: &quot;click.signup&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;19075373687&quot;, &quot;key&quot;: &quot;click.view_account_billing_page&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;19077355841&quot;, &quot;key&quot;: &quot;click.dismiss_signup_prompt&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;19079713938&quot;, &quot;key&quot;: &quot;click.contact_sales&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;19120963070&quot;, &quot;key&quot;: &quot;click.compare_account_plans&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;19151690317&quot;, &quot;key&quot;: &quot;click.upgrade_account_cta&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;19424193129&quot;, &quot;key&quot;: &quot;click.open_account_switcher&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;19520330825&quot;, &quot;key&quot;: &quot;click.visit_account_profile&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;19540970635&quot;, &quot;key&quot;: &quot;click.switch_account_context&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;19730198868&quot;, &quot;key&quot;: &quot;submit.homepage_signup&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;19820830627&quot;, &quot;key&quot;: &quot;click.homepage_signup&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;19988571001&quot;, &quot;key&quot;: &quot;click.create_enterprise_trial&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20036538294&quot;, &quot;key&quot;: &quot;click.create_organization_team&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20040653299&quot;, &quot;key&quot;: &quot;click.input_enterprise_trial_form&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20062030003&quot;, &quot;key&quot;: &quot;click.continue_with_team&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20068947153&quot;, &quot;key&quot;: &quot;click.create_organization_free&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20086636658&quot;, &quot;key&quot;: &quot;click.signup_continue.username&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20091648988&quot;, &quot;key&quot;: &quot;click.signup_continue.create_account&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20103637615&quot;, &quot;key&quot;: &quot;click.signup_continue.email&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20111574253&quot;, &quot;key&quot;: &quot;click.signup_continue.password&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20120044111&quot;, &quot;key&quot;: &quot;view.pricing_page&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20152062109&quot;, &quot;key&quot;: &quot;submit.create_account&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20165800992&quot;, &quot;key&quot;: &quot;submit.upgrade_payment_form&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20171520319&quot;, &quot;key&quot;: &quot;submit.create_organization&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20222645674&quot;, &quot;key&quot;: &quot;click.recommended_plan_in_signup.discuss_your_needs&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20227443657&quot;, &quot;key&quot;: &quot;submit.verify_primary_user_email&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20234607160&quot;, &quot;key&quot;: &quot;click.recommended_plan_in_signup.try_enterprise&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20238175784&quot;, &quot;key&quot;: &quot;click.recommended_plan_in_signup.team&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20239847212&quot;, &quot;key&quot;: &quot;click.recommended_plan_in_signup.continue_free&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20251097193&quot;, &quot;key&quot;: &quot;recommended_plan&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20438619534&quot;, &quot;key&quot;: &quot;click.pricing_calculator.1_member&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20456699683&quot;, &quot;key&quot;: &quot;click.pricing_calculator.15_members&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20467868331&quot;, &quot;key&quot;: &quot;click.pricing_calculator.10_members&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20476267432&quot;, &quot;key&quot;: &quot;click.trial_days_remaining&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20476357660&quot;, &quot;key&quot;: &quot;click.discover_feature&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20479287901&quot;, &quot;key&quot;: &quot;click.pricing_calculator.custom_members&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20481107083&quot;, &quot;key&quot;: &quot;click.recommended_plan_in_signup.apply_teacher_benefits&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20483089392&quot;, &quot;key&quot;: &quot;click.pricing_calculator.5_members&quot;}, {&quot;experimentIds&quot;: [&quot;20652570897&quot;], &quot;id&quot;: &quot;20484283944&quot;, &quot;key&quot;: &quot;click.onboarding_task&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20484996281&quot;, &quot;key&quot;: &quot;click.recommended_plan_in_signup.apply_student_benefits&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20486713726&quot;, &quot;key&quot;: &quot;click.onboarding_task_breadcrumb&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20490791319&quot;, &quot;key&quot;: &quot;click.upgrade_to_enterprise&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20491786766&quot;, &quot;key&quot;: &quot;click.talk_to_us&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20494144087&quot;, &quot;key&quot;: &quot;click.dismiss_enterprise_trial&quot;}, {&quot;experimentIds&quot;: [&quot;20652570897&quot;], &quot;id&quot;: &quot;20499722759&quot;, &quot;key&quot;: &quot;completed_all_tasks&quot;}, {&quot;experimentIds&quot;: [&quot;20652570897&quot;], &quot;id&quot;: &quot;20500710104&quot;, &quot;key&quot;: &quot;completed_onboarding_tasks&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20513160672&quot;, &quot;key&quot;: &quot;click.read_doc&quot;}, {&quot;experimentIds&quot;: [&quot;20652570897&quot;], &quot;id&quot;: &quot;20516196762&quot;, &quot;key&quot;: &quot;actions_enabled&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20518980986&quot;, &quot;key&quot;: &quot;click.dismiss_trial_banner&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20535446721&quot;, &quot;key&quot;: &quot;click.issue_actions_prompt.dismiss_prompt&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20557002247&quot;, &quot;key&quot;: &quot;click.issue_actions_prompt.setup_workflow&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20595070227&quot;, &quot;key&quot;: &quot;click.pull_request_setup_workflow&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20626600314&quot;, &quot;key&quot;: &quot;click.seats_input&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20642310305&quot;, &quot;key&quot;: &quot;click.decrease_seats_number&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20662990045&quot;, &quot;key&quot;: &quot;click.increase_seats_number&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20679620969&quot;, &quot;key&quot;: &quot;click.public_product_roadmap&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20761240940&quot;, &quot;key&quot;: &quot;click.dismiss_survey_banner&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20767210721&quot;, &quot;key&quot;: &quot;click.take_survey&quot;}, {&quot;experimentIds&quot;: [&quot;20652570897&quot;], &quot;id&quot;: &quot;20795281201&quot;, &quot;key&quot;: &quot;click.archive_list&quot;}, {&quot;experimentIds&quot;: [&quot;21435481980&quot;], &quot;id&quot;: &quot;20966790249&quot;, &quot;key&quot;: &quot;contact_sales.submit&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20996500333&quot;, &quot;key&quot;: &quot;contact_sales.existing_customer&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;20996890162&quot;, &quot;key&quot;: &quot;contact_sales.blank_message_field&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;21000470317&quot;, &quot;key&quot;: &quot;contact_sales.personal_email&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;21002790172&quot;, &quot;key&quot;: &quot;contact_sales.blank_phone_field&quot;}, {&quot;experimentIds&quot;: [&quot;21445030708&quot;], &quot;id&quot;: &quot;21354412592&quot;, &quot;key&quot;: &quot;click.dismiss_create_readme&quot;}, {&quot;experimentIds&quot;: [&quot;21445030708&quot;], &quot;id&quot;: &quot;21366102546&quot;, &quot;key&quot;: &quot;click.dismiss_zero_user_content&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;21370252505&quot;, &quot;key&quot;: &quot;account_did_downgrade&quot;}, {&quot;experimentIds&quot;: [&quot;21445030708&quot;], &quot;id&quot;: &quot;21370840408&quot;, &quot;key&quot;: &quot;click.cta_create_readme&quot;}, {&quot;experimentIds&quot;: [&quot;21445030708&quot;], &quot;id&quot;: &quot;21375451068&quot;, &quot;key&quot;: &quot;click.cta_create_new_repository&quot;}, {&quot;experimentIds&quot;: [&quot;21445030708&quot;], &quot;id&quot;: &quot;21385390948&quot;, &quot;key&quot;: &quot;click.zero_user_content&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;21467712175&quot;, &quot;key&quot;: &quot;click.downgrade_keep&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;21484112202&quot;, &quot;key&quot;: &quot;click.downgrade&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;21495292213&quot;, &quot;key&quot;: &quot;click.downgrade_survey_exit&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;21508241468&quot;, &quot;key&quot;: &quot;click.downgrade_survey_submit&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;21512030356&quot;, &quot;key&quot;: &quot;click.downgrade_support&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;21539090022&quot;, &quot;key&quot;: &quot;click.downgrade_exit&quot;}, {&quot;experimentIds&quot;: [], &quot;id&quot;: &quot;21543640644&quot;, &quot;key&quot;: &quot;click_fetch_upstream&quot;}], &quot;revision&quot;: &quot;1246&quot;}" /> + + + <script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-mQVLR0r/nqpYkfyTdCeoros0ZK5lyv/2BkIGxj9Bn8vEmZqz5IVJT0TP81XAzQEhiH6pm5hW6ldNrIfbQIUq9Q==" src="https://github.githubassets.com/assets/runtime-99054b474aff.js"></script> +<script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-PER5ezPyhyNo+ogF2YHanXpKiMe5hjTAzexy0Cxn6mKM7JBlATvC/9uHQcd33qlz7SHDy7c3pqLWMZEVKaTunQ==" src="https://github.githubassets.com/assets/environment-3c44797b33f2.js"></script> +<script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-ZAKZQWCEc6bs9LSQOCPRWq3wqRDkQxG2bPL/pW9Lj/Seap0PV0kF/yKCHske8mW3Zytde9n1Im83jxrCmpaMrA==" src="https://github.githubassets.com/assets/5724-640299416084.js"></script> +<script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-yIsmzjyBs6Mu12a5shTZVT0Jr80it7wV2yjZs77L3GmHoFP5SPNsWY9P+Swu7lPaWMXMtyaxceBQGP/7/Kyl8w==" src="https://github.githubassets.com/assets/93-c88b26ce3c81.js"></script> +<script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-WtABWNDgj+0Z+nTC8dZsMxFYSujm/s9SJTsHmFnzg73joAek4tmQ1zXCSLBvgAsgdPE8EQuOuOOW0NNP97Y7UA==" src="https://github.githubassets.com/assets/8630-5ad00158d0e0.js"></script> +<script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-7ocxdRbeEIuk5x86ryHnbc5GBupcna8GP7PEtAqWS0+sMjp4CX10GV5P0XsN7Grx1XTum3BG1FFOwwpccenxkw==" src="https://github.githubassets.com/assets/5157-ee87317516de.js"></script> +<script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-0Eo1tvk2fS3TaBkpCcX1DHb0QadEpOrHoZhK08d+D7bRyJDo8RjvmwQhFirTGfqxPBNpBSGkbm3qpdTIDNy32A==" src="https://github.githubassets.com/assets/9207-d04a35b6f936.js"></script> +<script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-3+T9M5jBxW6mEQj7X/rrF/MsLxMGrTuDz52aisu5x98tsd5HNWhDpD60gvr2sxFe7Qr4XPRXIgbjepk9l10JVw==" src="https://github.githubassets.com/assets/github-elements-dfe4fd3398c1.js"></script> +<script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-dJVwdrT1IxEhSpdU4ZQJWNk7a9dYwDffOEt5pelviXEyLZkGBAYWZM2qOidKrzuQFq/YmjxPsM5GwHKnstmgfA==" src="https://github.githubassets.com/assets/element-registry-74957076b4f5.js"></script> +<script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-4t8sE+qs6MzzsebMDr3ZpEin+nTu54+SC40fUL9VSHeDNKkWJW9vMiH07js5RVxEcEzFHk2gIgLREL8ko/NcnQ==" src="https://github.githubassets.com/assets/6162-e2df2c13eaac.js"></script> +<script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-JPHg6lXC/kVMbA05VoaD5W739fMUF/ObaJ4NrZWLi91OWI9xEhJ9NtwbGROmxjCm5FGwNOVohY+DXILkO19dtA==" src="https://github.githubassets.com/assets/8932-24f1e0ea55c2.js"></script> +<script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-EIceiRH5/XsS9RPMOGlnx37yFBM2TbSNcVWgTjKPmRwjdl/lfKNdColL/PLunshA/attRqdYJVnNNGXNyhx6Zw==" src="https://github.githubassets.com/assets/7077-10871e8911f9.js"></script> +<script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-AYRLCV5AATlaRqQWBDJSEP98krkMeoHKuVom5qo8TJpToCunN1xv1exiPRqoTB39NIE/ydjJeBxSd0222FSJwg==" src="https://github.githubassets.com/assets/6262-01844b095e40.js"></script> +<script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-TiAubwgcDgCeTqQEjsybLJp8L9kKpEHxLQgN6I39+2JDrrrmr9GAeAIS9W3O3amds62fksBOEKkzfTQYExD6Jg==" src="https://github.githubassets.com/assets/8994-4e202e6f081c.js"></script> +<script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-FBQyV0AyntQx89AqRm5XkfzloiXK2K99s0uKP9Qr96M7ko8H2m9L5OC/wxEUqIW4Yhuo6/YQHeGsye5mOAnliw==" src="https://github.githubassets.com/assets/4887-141432574032.js"></script> +<script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-0aq2ZLf9hZewJpYpt9grmgApFDciZTURCICGfD8kVZGNLP8wlGwoZs8YnJuJuL0+6Bv9bQZ1yJIjX8Mjhi91CQ==" src="https://github.githubassets.com/assets/8483-d1aab664b7fd.js"></script> +<script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-Zj3js1gWERCf+NwXLmZSyO7eyqr2d8LHZ0ACEl2FQfTD1KvuilvrOi4ORxAOTOmzbYW+4CJUn9VPxtxOhD+15Q==" src="https://github.githubassets.com/assets/behaviors-663de3b35816.js"></script> +<script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-sMHaqugxxdo9+GIN3yKtDbgXKx2LtVOg3gN8y709BIIumhCqpuTd7+LRqXn/rHArmeaxKDyAorh59K8kL7sdwQ==" src="https://github.githubassets.com/assets/7749-b0c1daaae831.js"></script> +<script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-QDWNlhBimyMzi1ZHr5DNlV+UKfkbocax181wKEKPQzaNFu4d/IlmQ62T+hFdB+SI0YdJttdZteCs0kFzXd7SUg==" src="https://github.githubassets.com/assets/notifications-global-40358d961062.js"></script> +<script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-77k3PD6yYzGTavH0wX2ptFsn3B+4mdsyVMlC9uxmT8LsoWH65NF0KCtwsC7+KsyH7eWY/F/3BEApTugN3uq92Q==" src="https://github.githubassets.com/assets/4978-efb9373c3eb2.js"></script> +<script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-EBfuTzLRgEa3V/5Pm2IlNnAqzO6+G7olJDpT8BlzglUceQaVsjuPsisHUvTd6KeBLD0ELjnpOo7a7kZMCaG4XQ==" src="https://github.githubassets.com/assets/optimizely-1017ee4f32d1.js"></script> +<script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-xyGHYwjeMuGHmOdgy9Kb/p7zpSxjrw197tH6c+PzJj3L9zUCmjXBRbPky6B3Dqc/dN0x6OPF7n2Uh5u5MdbVUw==" src="https://github.githubassets.com/assets/90-c721876308de.js"></script> +<script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-ZSFwlLEfCHi+qMlyabT/x1hgegM31ywDLEVDPSNpNv5/bxbnTVHBhPvLTkSf+Yie8nohu1/RkuXr8PMIkVhO9w==" src="https://github.githubassets.com/assets/2734-65217094b11f.js"></script> +<script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-u8r8UO/bHE8/YPL9N2X0L6nMIkQcItDfE4Yk2OXciXzzEILnPjRg3I2JrrWpQ2F91UAkptNyDZ0xjVSte65jig==" src="https://github.githubassets.com/assets/6637-bbcafc50efdb.js"></script> +<script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-zElKd+pdebfRBvLm82PINFB+VBWZK74UlxOJyYH1J3yl4hB+NkD8wToFPhVUR4+2zRW/R5QH1oSJZQL03Jh4eQ==" src="https://github.githubassets.com/assets/6609-cc494a77ea5d.js"></script> +<script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-Pnw/EuGXisuqgX1wYiEWOGdt3yV2OGn7pwhsfUGbCaDnYlEQjkHbkrsSKTD1TRw1MoxixNPK5x9MUhxbaDjiRg==" src="https://github.githubassets.com/assets/repositories-3e7c3f12e197.js"></script> +<script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-T2V7jZINzAZtVXQs+N/Udsqf/NnEdRpBX9SakGQ5TqYV4Lx3Ms2m4x0xDQmXDG3w6/24UuW8GhBKrNMDk0vVaw==" src="https://github.githubassets.com/assets/diffs-4f657b8d920d.js"></script> + + + <title>st/st-urlhandler at master · LukeSmithxyz/st · GitHub</title> + + + + + + <meta name="request-id" content="D406:F9A2:C25F7:D63D5:628A4BCA" data-pjax-transient="true"/><meta name="html-safe-nonce" content="f637b75dca25aed2d62293cf82d1642c66d4a93a74d541d197ab8fb10ca05076" data-pjax-transient="true"/><meta name="visitor-payload" content="eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJENDA2OkY5QTI6QzI1Rjc6RDYzRDU6NjI4QTRCQ0EiLCJ2aXNpdG9yX2lkIjoiNDE1Nzk1MjUyMzc0MTMxODA5MCIsInJlZ2lvbl9lZGdlIjoiZnJhIiwicmVnaW9uX3JlbmRlciI6ImZyYSJ9" data-pjax-transient="true"/><meta name="visitor-hmac" content="1a9a7e65ee203c698cf86d59536393e7f2127c4c9383681682a0c55373cdb63a" data-pjax-transient="true"/> + + <meta name="hovercard-subject-tag" content="repository:117944122" data-pjax-transient> + + + <meta name="github-keyboard-shortcuts" content="repository,source-code" data-pjax-transient="true" /> + + + <meta name="selected-link" value="repo_source" data-pjax-transient> + + <meta name="google-site-verification" content="c1kuD-K2HIVF635lypcsWPoD4kilo5-jA_wBFyT4uMY"> + <meta name="google-site-verification" content="KT5gs8h0wvaagLKAVWq8bbeNwnZZK1r1XQysX3xurLU"> + <meta name="google-site-verification" content="ZzhVyEFwb7w3e0-uOTltm8Jsck2F5StVihD0exw2fsA"> + <meta name="google-site-verification" content="GXs5KoUUkNCoaAZn7wPN-t01Pywp9M3sEjnt_3_ZWPc"> + +<meta name="octolytics-url" content="https://collector.github.com/github/collect" /> + + <meta name="analytics-location" content="/&lt;user-name&gt;/&lt;repo-name&gt;/blob/show" data-pjax-transient="true" /> + + + + + + + + + <meta name="user-login" content=""> + + <meta name="viewport" content="width=device-width"> + + <meta name="description" content="Luke&#39;s fork of the suckless simple terminal (st) with vim bindings and Xresource compatibility. - st/st-urlhandler at master · LukeSmithxyz/st"> + <link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="GitHub"> + <link rel="fluid-icon" href="https://github.com/fluidicon.png" title="GitHub"> + <meta property="fb:app_id" content="1401488693436528"> + <meta name="apple-itunes-app" content="app-id=1477376905" /> + <meta name="twitter:image:src" content="https://opengraph.githubassets.com/8a32f7b92ccd100059ba3db8066d15af227d941b5d37f1e43eb62d93d936dc9d/LukeSmithxyz/st" /><meta name="twitter:site" content="@github" /><meta name="twitter:card" content="summary_large_image" /><meta name="twitter:title" content="st/st-urlhandler at master · LukeSmithxyz/st" /><meta name="twitter:description" content="Luke&#39;s fork of the suckless simple terminal (st) with vim bindings and Xresource compatibility. - st/st-urlhandler at master · LukeSmithxyz/st" /> + <meta property="og:image" content="https://opengraph.githubassets.com/8a32f7b92ccd100059ba3db8066d15af227d941b5d37f1e43eb62d93d936dc9d/LukeSmithxyz/st" /><meta property="og:image:alt" content="Luke&#39;s fork of the suckless simple terminal (st) with vim bindings and Xresource compatibility. - st/st-urlhandler at master · LukeSmithxyz/st" /><meta property="og:image:width" content="1200" /><meta property="og:image:height" content="600" /><meta property="og:site_name" content="GitHub" /><meta property="og:type" content="object" /><meta property="og:title" content="st/st-urlhandler at master · LukeSmithxyz/st" /><meta property="og:url" content="https://github.com/LukeSmithxyz/st" /><meta property="og:description" content="Luke&#39;s fork of the suckless simple terminal (st) with vim bindings and Xresource compatibility. - st/st-urlhandler at master · LukeSmithxyz/st" /> + + <link rel="assets" href="https://github.githubassets.com/"> + + + + <meta name="hostname" content="github.com"> + + + + <meta name="expected-hostname" content="github.com"> + + + <meta name="enabled-features" content="ACESSIBILITY_CONTROL_AUTOPLAY_OF_ANIMATED_IMAGES,ACTIONS_INHERIT_SECRETS_REUSABLE_WORKFLOWS"> + + + <meta http-equiv="x-pjax-version" content="78542c931ae9c6f5c17aa5a70c32d7b0b4ade3c89f4a154989f9a9451e5d39a9" data-turbo-track="reload"> + <meta http-equiv="x-pjax-csp-version" content="ca8f28be2f02ebc697029bdc0646515d9017cf770c4c1ff8414eccd96f6b5a2a" data-turbo-track="reload"> + <meta http-equiv="x-pjax-css-version" content="b66538b7e8649bb4f220b30cb97067092d7bc3ee6156cc8fd2c0258e9d442d2f" data-turbo-track="reload"> + <meta http-equiv="x-pjax-js-version" content="522262a7f15f1f850723ce176e8e780ecae4d308d684a89d955408e56a398d02" data-turbo-track="reload"> + <meta name="turbo-cache-control" content="no-preview"> + + + + <meta name="go-import" content="github.com/LukeSmithxyz/st git https://github.com/LukeSmithxyz/st.git"> + + <meta name="octolytics-dimension-user_id" content="29150857" /><meta name="octolytics-dimension-user_login" content="LukeSmithxyz" /><meta name="octolytics-dimension-repository_id" content="117944122" /><meta name="octolytics-dimension-repository_nwo" content="LukeSmithxyz/st" /><meta name="octolytics-dimension-repository_public" content="true" /><meta name="octolytics-dimension-repository_is_fork" content="false" /><meta name="octolytics-dimension-repository_network_root_id" content="117944122" /><meta name="octolytics-dimension-repository_network_root_nwo" content="LukeSmithxyz/st" /> + + + + <link rel="canonical" href="https://github.com/LukeSmithxyz/st/blob/master/st-urlhandler" data-pjax-transient> + + + <meta name="browser-stats-url" content="https://api.github.com/_private/browser/stats"> + + <meta name="browser-errors-url" content="https://api.github.com/_private/browser/errors"> + + <meta name="browser-optimizely-client-errors-url" content="https://api.github.com/_private/browser/optimizely_client/errors"> + + <link rel="mask-icon" href="https://github.githubassets.com/pinned-octocat.svg" color="#000000"> + <link rel="alternate icon" class="js-site-favicon" type="image/png" href="https://github.githubassets.com/favicons/favicon.png"> + <link rel="icon" class="js-site-favicon" type="image/svg+xml" href="https://github.githubassets.com/favicons/favicon.svg"> + +<meta name="theme-color" content="#1e2327"> +<meta name="color-scheme" content="light dark" /> + + + <link rel="manifest" href="/manifest.json" crossOrigin="use-credentials"> + + </head> + + <body class="logged-out env-production page-responsive page-blob" style="word-wrap: break-word;"> + + + <div class="position-relative js-header-wrapper "> + <a href="#start-of-content" class="px-2 py-4 color-bg-accent-emphasis color-fg-on-emphasis show-on-focus js-skip-to-content">Skip to content</a> + <span data-view-component="true" class="progress-pjax-loader js-pjax-loader-bar Progress position-fixed width-full"> + <span style="width: 0%;" data-view-component="true" class="Progress-item progress-pjax-loader-bar left-0 top-0 color-bg-accent-emphasis"></span> +</span> + + + + + + <header class="Header-old header-logged-out js-details-container Details position-relative f4 py-2" role="banner"> + <div class="container-xl d-lg-flex flex-items-center p-responsive"> + <div class="d-flex flex-justify-between flex-items-center"> + <a class="mr-4 color-fg-inherit" href="https://github.com/" aria-label="Homepage" data-ga-click="(Logged out) Header, go to homepage, icon:logo-wordmark"> + <svg height="32" aria-hidden="true" viewBox="0 0 16 16" version="1.1" width="32" data-view-component="true" class="octicon octicon-mark-github"> + <path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"></path> +</svg> + </a> + + <div class="d-lg-none css-truncate css-truncate-target width-fit p-2"> + + + </div> + + <div class="d-flex flex-items-center"> + <a href="/signup?ref_cta=Sign+up&amp;ref_loc=header+logged+out&amp;ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fblob%2Fshow&amp;source=header-repo" + class="d-inline-block d-lg-none f5 no-underline border color-border-default rounded-2 px-2 py-1 mr-3 mr-sm-5 color-fg-inherit" + data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;site header&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;SIGN_UP&quot;,&quot;originating_url&quot;:&quot;https://github.com/LukeSmithxyz/st/blob/master/st-urlhandler&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="30d2e835d817e891528ce392462bcb0ed6e4cdd3ecb293c229dd588654589904" + > + Sign&nbsp;up + </a> + + <button aria-label="Toggle navigation" aria-expanded="false" type="button" data-view-component="true" class="js-details-target btn-link d-lg-none mt-1 color-fg-inherit"> <svg aria-hidden="true" height="24" viewBox="0 0 16 16" version="1.1" width="24" data-view-component="true" class="octicon octicon-three-bars"> + <path fill-rule="evenodd" d="M1 2.75A.75.75 0 011.75 2h12.5a.75.75 0 110 1.5H1.75A.75.75 0 011 2.75zm0 5A.75.75 0 011.75 7h12.5a.75.75 0 110 1.5H1.75A.75.75 0 011 7.75zM1.75 12a.75.75 0 100 1.5h12.5a.75.75 0 100-1.5H1.75z"></path> +</svg> + +</button> </div> + </div> + + <div class="HeaderMenu HeaderMenu--logged-out position-fixed top-0 right-0 bottom-0 height-fit position-lg-relative d-lg-flex flex-justify-between flex-items-center flex-auto"> + <div class="d-flex d-lg-none flex-justify-end border-bottom color-bg-subtle p-3"> + <button aria-label="Toggle navigation" aria-expanded="false" type="button" data-view-component="true" class="js-details-target btn-link"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-x color-fg-muted"> + <path fill-rule="evenodd" d="M5.72 5.72a.75.75 0 011.06 0L12 10.94l5.22-5.22a.75.75 0 111.06 1.06L13.06 12l5.22 5.22a.75.75 0 11-1.06 1.06L12 13.06l-5.22 5.22a.75.75 0 01-1.06-1.06L10.94 12 5.72 6.78a.75.75 0 010-1.06z"></path> +</svg> + +</button> </div> + + <nav class="mt-0 px-3 px-lg-0 mb-5 mb-lg-0" aria-label="Global"> + <ul class="d-lg-flex list-style-none"> + <li class="mr-0 mr-lg-3 position-relative flex-wrap flex-justify-between flex-items-center border-bottom border-lg-bottom-0 d-block d-lg-flex flex-lg-nowrap flex-lg-items-center"> + <details class="HeaderMenu-details details-overlay details-reset width-full"> + <summary class="HeaderMenu-summary HeaderMenu-link px-0 py-3 border-0 no-wrap d-block d-lg-inline-block"> + Product + <svg x="0" y="0" viewBox="0 0 14 8" xml:space="preserve" fill="none" class="icon-chevon-down-mktg position-absolute position-lg-relative"><path d="M1,1l6.2,6L13,1"></path></svg> + </summary> + <div class="dropdown-menu flex-auto rounded px-0 mt-0 pb-4 p-lg-4 position-relative position-lg-absolute left-0 left-lg-n4"> + <ul class="list-style-none f5 pb-1"> + <li> + <a class="lh-condensed-ultra d-block no-underline position-relative Link--primary text-bold py-2" data-analytics-event="{&quot;category&quot;:&quot;Header dropdown (logged out), Product&quot;,&quot;action&quot;:&quot;click to go to Features&quot;,&quot;label&quot;:&quot;ref_page:/LukeSmithxyz/st/blob/master/st-urlhandler;ref_cta:Features;&quot;}" href="/features"> + Features +</a> </li> + + <li> + <a class="lh-condensed-ultra d-block no-underline position-relative Link--secondary py-2" data-analytics-event="{&quot;category&quot;:&quot;Header dropdown (logged out), Product&quot;,&quot;action&quot;:&quot;click to go to Mobile&quot;,&quot;label&quot;:&quot;ref_page:/LukeSmithxyz/st/blob/master/st-urlhandler;ref_cta:Mobile;&quot;}" href="/mobile"> + Mobile +</a> </li> + + <li> + <a class="lh-condensed-ultra d-block no-underline position-relative Link--secondary py-2" data-analytics-event="{&quot;category&quot;:&quot;Header dropdown (logged out), Product&quot;,&quot;action&quot;:&quot;click to go to Actions&quot;,&quot;label&quot;:&quot;ref_page:/LukeSmithxyz/st/blob/master/st-urlhandler;ref_cta:Actions;&quot;}" href="/features/actions"> + Actions +</a> </li> + + <li> + <a class="lh-condensed-ultra d-block no-underline position-relative Link--secondary py-2" data-analytics-event="{&quot;category&quot;:&quot;Header dropdown (logged out), Product&quot;,&quot;action&quot;:&quot;click to go to Codespaces&quot;,&quot;label&quot;:&quot;ref_page:/LukeSmithxyz/st/blob/master/st-urlhandler;ref_cta:Codespaces;&quot;}" href="/features/codespaces"> + Codespaces +</a> </li> + + + <li> + <a class="lh-condensed-ultra d-block no-underline position-relative Link--secondary py-2" data-analytics-event="{&quot;category&quot;:&quot;Header dropdown (logged out), Product&quot;,&quot;action&quot;:&quot;click to go to Packages&quot;,&quot;label&quot;:&quot;ref_page:/LukeSmithxyz/st/blob/master/st-urlhandler;ref_cta:Packages;&quot;}" href="/features/packages"> + Packages +</a> </li> + + <li> + <a class="lh-condensed-ultra d-block no-underline position-relative Link--secondary py-2" data-analytics-event="{&quot;category&quot;:&quot;Header dropdown (logged out), Product&quot;,&quot;action&quot;:&quot;click to go to Security&quot;,&quot;label&quot;:&quot;ref_page:/LukeSmithxyz/st/blob/master/st-urlhandler;ref_cta:Security;&quot;}" href="/features/security"> + Security +</a> </li> + + <li> + <a class="lh-condensed-ultra d-block no-underline position-relative Link--secondary py-2" data-analytics-event="{&quot;category&quot;:&quot;Header dropdown (logged out), Product&quot;,&quot;action&quot;:&quot;click to go to Code review&quot;,&quot;label&quot;:&quot;ref_page:/LukeSmithxyz/st/blob/master/st-urlhandler;ref_cta:Code review;&quot;}" href="/features/code-review"> + Code review +</a> </li> + + <li> + <a class="lh-condensed-ultra d-block no-underline position-relative Link--secondary py-2" data-analytics-event="{&quot;category&quot;:&quot;Header dropdown (logged out), Product&quot;,&quot;action&quot;:&quot;click to go to Issues&quot;,&quot;label&quot;:&quot;ref_page:/LukeSmithxyz/st/blob/master/st-urlhandler;ref_cta:Issues;&quot;}" href="/features/issues"> + Issues +</a> </li> + + <li> + <a class="lh-condensed-ultra d-block no-underline position-relative Link--secondary py-2" data-analytics-event="{&quot;category&quot;:&quot;Header dropdown (logged out), Product&quot;,&quot;action&quot;:&quot;click to go to Integrations&quot;,&quot;label&quot;:&quot;ref_page:/LukeSmithxyz/st/blob/master/st-urlhandler;ref_cta:Integrations;&quot;}" href="/features/integrations"> + Integrations +</a> </li> + + <li> + <a class="lh-condensed-ultra d-block no-underline position-relative Link--primary text-bold border-top pt-4 pb-2 mt-3" data-analytics-event="{&quot;category&quot;:&quot;Header dropdown (logged out), Product&quot;,&quot;action&quot;:&quot;click to go to GitHub Sponsors&quot;,&quot;label&quot;:&quot;ref_page:/LukeSmithxyz/st/blob/master/st-urlhandler;ref_cta:GitHub Sponsors;&quot;}" href="/sponsors"> + GitHub Sponsors +</a> </li> + + <li> + <a class="lh-condensed-ultra d-block no-underline position-relative Link--primary text-bold py-2" data-analytics-event="{&quot;category&quot;:&quot;Header dropdown (logged out), Product&quot;,&quot;action&quot;:&quot;click to go to Customer stories&quot;,&quot;label&quot;:&quot;ref_page:/LukeSmithxyz/st/blob/master/st-urlhandler;ref_cta:Customer stories;&quot;}" href="/customer-stories"> + Customer stories +</a> </li> + + </ul> + </div> + </details> +</li> + + + <li class="mr-0 mr-lg-3 position-relative flex-wrap flex-justify-between flex-items-center border-bottom border-lg-bottom-0 d-block d-lg-flex flex-lg-nowrap flex-lg-items-center"> + <a class="HeaderMenu-link no-underline py-3 d-block d-lg-inline-block" data-analytics-event="{&quot;category&quot;:&quot;Header menu top item (logged out)&quot;,&quot;action&quot;:&quot;click to go to Team&quot;,&quot;label&quot;:&quot;ref_page:/LukeSmithxyz/st/blob/master/st-urlhandler;ref_cta:Team;&quot;}" href="/team">Team</a> +</li> + + <li class="mr-0 mr-lg-3 position-relative flex-wrap flex-justify-between flex-items-center border-bottom border-lg-bottom-0 d-block d-lg-flex flex-lg-nowrap flex-lg-items-center"> + <a class="HeaderMenu-link no-underline py-3 d-block d-lg-inline-block" data-analytics-event="{&quot;category&quot;:&quot;Header menu top item (logged out)&quot;,&quot;action&quot;:&quot;click to go to Enterprise&quot;,&quot;label&quot;:&quot;ref_page:/LukeSmithxyz/st/blob/master/st-urlhandler;ref_cta:Enterprise;&quot;}" href="/enterprise">Enterprise</a> +</li> + + + <li class="mr-0 mr-lg-3 position-relative flex-wrap flex-justify-between flex-items-center border-bottom border-lg-bottom-0 d-block d-lg-flex flex-lg-nowrap flex-lg-items-center"> + <details class="HeaderMenu-details details-overlay details-reset width-full"> + <summary class="HeaderMenu-summary HeaderMenu-link px-0 py-3 border-0 no-wrap d-block d-lg-inline-block"> + Explore + <svg x="0" y="0" viewBox="0 0 14 8" xml:space="preserve" fill="none" class="icon-chevon-down-mktg position-absolute position-lg-relative"><path d="M1,1l6.2,6L13,1"></path></svg> + </summary> + <div class="dropdown-menu flex-auto rounded px-0 mt-0 pb-4 p-lg-4 position-relative position-lg-absolute left-0 left-lg-n4"> + <ul class="list-style-none f5 pb-1"> + <li> + <a class="lh-condensed-ultra d-block no-underline position-relative Link--primary text-bold py-2" data-analytics-event="{&quot;category&quot;:&quot;Header dropdown (logged out), Explore&quot;,&quot;action&quot;:&quot;click to go to Explore GitHub&quot;,&quot;label&quot;:&quot;ref_page:/LukeSmithxyz/st/blob/master/st-urlhandler;ref_cta:Explore GitHub;&quot;}" href="/explore"> + Explore GitHub +</a> </li> + + <li class="color-fg-muted text-normal f6 text-mono mb-1 border-top pt-3 mt-3 mb-1">Learn and contribute</li> + + <li> + <a class="lh-condensed-ultra d-block no-underline position-relative Link--secondary py-2" data-analytics-event="{&quot;category&quot;:&quot;Header dropdown (logged out), Explore&quot;,&quot;action&quot;:&quot;click to go to Topics&quot;,&quot;label&quot;:&quot;ref_page:/LukeSmithxyz/st/blob/master/st-urlhandler;ref_cta:Topics;&quot;}" href="/topics"> + Topics +</a> </li> + + <li> + <a class="lh-condensed-ultra d-block no-underline position-relative Link--secondary py-2" data-analytics-event="{&quot;category&quot;:&quot;Header dropdown (logged out), Explore&quot;,&quot;action&quot;:&quot;click to go to Collections&quot;,&quot;label&quot;:&quot;ref_page:/LukeSmithxyz/st/blob/master/st-urlhandler;ref_cta:Collections;&quot;}" href="/collections"> + Collections +</a> </li> + + <li> + <a class="lh-condensed-ultra d-block no-underline position-relative Link--secondary py-2" data-analytics-event="{&quot;category&quot;:&quot;Header dropdown (logged out), Explore&quot;,&quot;action&quot;:&quot;click to go to Trending&quot;,&quot;label&quot;:&quot;ref_page:/LukeSmithxyz/st/blob/master/st-urlhandler;ref_cta:Trending;&quot;}" href="/trending"> + Trending +</a> </li> + + <li> + <a class="lh-condensed-ultra d-block no-underline position-relative Link--secondary py-2" data-analytics-event="{&quot;category&quot;:&quot;Header dropdown (logged out), Explore&quot;,&quot;action&quot;:&quot;click to go to Learning Lab&quot;,&quot;label&quot;:&quot;ref_page:/LukeSmithxyz/st/blob/master/st-urlhandler;ref_cta:Learning Lab;&quot;}" href="https://lab.github.com/"> + Learning Lab +</a> </li> + + <li> + <a class="lh-condensed-ultra d-block no-underline position-relative Link--secondary py-2" data-analytics-event="{&quot;category&quot;:&quot;Header dropdown (logged out), Explore&quot;,&quot;action&quot;:&quot;click to go to Open source guides&quot;,&quot;label&quot;:&quot;ref_page:/LukeSmithxyz/st/blob/master/st-urlhandler;ref_cta:Open source guides;&quot;}" href="https://opensource.guide"> + Open source guides +</a> </li> + + <li class="color-fg-muted text-normal f6 text-mono mb-1 border-top pt-3 mt-3 mb-1">Connect with others</li> + + <li> + <a class="lh-condensed-ultra d-block no-underline position-relative Link--secondary py-2" data-analytics-event="{&quot;category&quot;:&quot;Header dropdown (logged out), Explore&quot;,&quot;action&quot;:&quot;click to go to The ReadME Project&quot;,&quot;label&quot;:&quot;ref_page:/LukeSmithxyz/st/blob/master/st-urlhandler;ref_cta:The ReadME Project;&quot;}" href="/readme"> + The ReadME Project +</a> </li> + + <li> + <a class="lh-condensed-ultra d-block no-underline position-relative Link--secondary py-2" data-analytics-event="{&quot;category&quot;:&quot;Header dropdown (logged out), Explore&quot;,&quot;action&quot;:&quot;click to go to Events&quot;,&quot;label&quot;:&quot;ref_page:/LukeSmithxyz/st/blob/master/st-urlhandler;ref_cta:Events;&quot;}" href="/events"> + Events +</a> </li> + + <li> + <a class="lh-condensed-ultra d-block no-underline position-relative Link--secondary py-2" data-analytics-event="{&quot;category&quot;:&quot;Header dropdown (logged out), Explore&quot;,&quot;action&quot;:&quot;click to go to Community forum&quot;,&quot;label&quot;:&quot;ref_page:/LukeSmithxyz/st/blob/master/st-urlhandler;ref_cta:Community forum;&quot;}" href="https://github.community"> + Community forum +</a> </li> + + <li> + <a class="lh-condensed-ultra d-block no-underline position-relative Link--secondary py-2" data-analytics-event="{&quot;category&quot;:&quot;Header dropdown (logged out), Explore&quot;,&quot;action&quot;:&quot;click to go to GitHub Education&quot;,&quot;label&quot;:&quot;ref_page:/LukeSmithxyz/st/blob/master/st-urlhandler;ref_cta:GitHub Education;&quot;}" href="https://education.github.com"> + GitHub Education +</a> </li> + + <li> + <a class="lh-condensed-ultra d-block no-underline position-relative Link--secondary py-2" data-analytics-event="{&quot;category&quot;:&quot;Header dropdown (logged out), Explore&quot;,&quot;action&quot;:&quot;click to go to GitHub Stars program&quot;,&quot;label&quot;:&quot;ref_page:/LukeSmithxyz/st/blob/master/st-urlhandler;ref_cta:GitHub Stars program;&quot;}" href="https://stars.github.com"> + GitHub Stars program +</a> </li> + + </ul> + </div> + </details> +</li> + + + <li class="mr-0 mr-lg-3 position-relative flex-wrap flex-justify-between flex-items-center border-bottom border-lg-bottom-0 d-block d-lg-flex flex-lg-nowrap flex-lg-items-center"> + <a class="HeaderMenu-link no-underline py-3 d-block d-lg-inline-block" data-analytics-event="{&quot;category&quot;:&quot;Header menu top item (logged out)&quot;,&quot;action&quot;:&quot;click to go to Marketplace&quot;,&quot;label&quot;:&quot;ref_page:/LukeSmithxyz/st/blob/master/st-urlhandler;ref_cta:Marketplace;&quot;}" href="/marketplace">Marketplace</a> +</li> + + + <li class="mr-0 mr-lg-3 position-relative flex-wrap flex-justify-between flex-items-center border-bottom border-lg-bottom-0 d-block d-lg-flex flex-lg-nowrap flex-lg-items-center"> + <details class="HeaderMenu-details details-overlay details-reset width-full"> + <summary class="HeaderMenu-summary HeaderMenu-link px-0 py-3 border-0 no-wrap d-block d-lg-inline-block"> + Pricing + <svg x="0" y="0" viewBox="0 0 14 8" xml:space="preserve" fill="none" class="icon-chevon-down-mktg position-absolute position-lg-relative"><path d="M1,1l6.2,6L13,1"></path></svg> + </summary> + <div class="dropdown-menu flex-auto rounded px-0 mt-0 pb-4 p-lg-4 position-relative position-lg-absolute left-0 left-lg-n4"> + <ul class="list-style-none f5 pb-1"> + <li> + <a class="lh-condensed-ultra d-block no-underline position-relative Link--primary text-bold py-2" data-analytics-event="{&quot;category&quot;:&quot;Header dropdown (logged out), Pricing&quot;,&quot;action&quot;:&quot;click to go to Plans&quot;,&quot;label&quot;:&quot;ref_page:/LukeSmithxyz/st/blob/master/st-urlhandler;ref_cta:Plans;&quot;}" href="/pricing"> + Plans +</a> </li> + + <li> + <a class="lh-condensed-ultra d-block no-underline position-relative Link--secondary py-2" data-analytics-event="{&quot;category&quot;:&quot;Header dropdown (logged out), Pricing&quot;,&quot;action&quot;:&quot;click to go to Compare plans&quot;,&quot;label&quot;:&quot;ref_page:/LukeSmithxyz/st/blob/master/st-urlhandler;ref_cta:Compare plans;&quot;}" href="/pricing#compare-features"> + Compare plans +</a> </li> + + <li> + <a class="lh-condensed-ultra d-block no-underline position-relative Link--secondary py-2" data-analytics-event="{&quot;category&quot;:&quot;Header dropdown (logged out), Pricing&quot;,&quot;action&quot;:&quot;click to go to Contact Sales&quot;,&quot;label&quot;:&quot;ref_page:/LukeSmithxyz/st/blob/master/st-urlhandler;ref_cta:Contact Sales;&quot;}" href="https://github.com/enterprise/contact"> + Contact Sales +</a> </li> + + <li> + <a class="lh-condensed-ultra d-block no-underline position-relative Link--primary text-bold border-top pt-4 pb-2 mt-3" data-analytics-event="{&quot;category&quot;:&quot;Header dropdown (logged out), Pricing&quot;,&quot;action&quot;:&quot;click to go to Education&quot;,&quot;label&quot;:&quot;ref_page:/LukeSmithxyz/st/blob/master/st-urlhandler;ref_cta:Education;&quot;}" href="https://education.github.com"> + Education +</a> </li> + + </ul> + </div> + </details> +</li> + + </ul> + </nav> + + <div class="d-lg-flex flex-items-center px-3 px-lg-0 text-center text-lg-left"> + <div class="d-lg-flex min-width-0 mb-3 mb-lg-0"> + + + + +<div class="header-search flex-auto js-site-search position-relative flex-self-stretch flex-md-self-auto mb-3 mb-md-0 mr-0 mr-md-3 scoped-search site-scoped-search js-jump-to" +> + <div class="position-relative"> + <!-- '"` --><!-- </textarea></xmp> --></option></form><form class="js-site-search-form" role="search" aria-label="Site" data-scope-type="Repository" data-scope-id="117944122" data-scoped-search-url="/LukeSmithxyz/st/search" data-owner-scoped-search-url="/users/LukeSmithxyz/search" data-unscoped-search-url="/search" data-turbo="false" action="/LukeSmithxyz/st/search" accept-charset="UTF-8" method="get"> + <label class="form-control input-sm header-search-wrapper p-0 js-chromeless-input-container header-search-wrapper-jump-to position-relative d-flex flex-justify-between flex-items-center"> + <input type="text" + class="form-control input-sm header-search-input jump-to-field js-jump-to-field js-site-search-focus js-site-search-field is-clearable" + data-hotkey=s,/ + name="q" + data-test-selector="nav-search-input" + placeholder="Search" + data-unscoped-placeholder="Search GitHub" + data-scoped-placeholder="Search" + autocapitalize="off" + role="combobox" + aria-haspopup="listbox" + aria-expanded="false" + aria-autocomplete="list" + aria-controls="jump-to-results" + aria-label="Search" + data-jump-to-suggestions-path="/_graphql/GetSuggestedNavigationDestinations" + spellcheck="false" + autocomplete="off" + > + <input type="hidden" data-csrf="true" class="js-data-jump-to-suggestions-path-csrf" value="hxE/TSeiJmrfH9ljAymW9edrYG2iLT7xYtL8uRbr92HYfg/PvK2kUYxiiK0G8EN1f8urXARvvoCfyn0Q/7ykPA==" /> + <input type="hidden" class="js-site-search-type-field" name="type" > + <svg xmlns="http://www.w3.org/2000/svg" width="22" height="20" aria-hidden="true" class="mr-1 header-search-key-slash"><path fill="none" stroke="#979A9C" opacity=".4" d="M3.5.5h12c1.7 0 3 1.3 3 3v13c0 1.7-1.3 3-3 3h-12c-1.7 0-3-1.3-3-3v-13c0-1.7 1.3-3 3-3z"></path><path fill="#979A9C" d="M11.8 6L8 15.1h-.9L10.8 6h1z"></path></svg> + + + <div class="Box position-absolute overflow-hidden d-none jump-to-suggestions js-jump-to-suggestions-container"> + +<ul class="d-none js-jump-to-suggestions-template-container"> + + +<li class="d-flex flex-justify-start flex-items-center p-0 f5 navigation-item js-navigation-item js-jump-to-suggestion" role="option"> + <a tabindex="-1" class="no-underline d-flex flex-auto flex-items-center jump-to-suggestions-path js-jump-to-suggestion-path js-navigation-open p-2" href="" data-item-type="suggestion"> + <div class="jump-to-octicon js-jump-to-octicon flex-shrink-0 mr-2 text-center d-none"> + <svg title="Repository" aria-label="Repository" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo js-jump-to-octicon-repo d-none flex-shrink-0"> + <path fill-rule="evenodd" d="M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z"></path> +</svg> + <svg title="Project" aria-label="Project" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-project js-jump-to-octicon-project d-none flex-shrink-0"> + <path fill-rule="evenodd" d="M1.75 0A1.75 1.75 0 000 1.75v12.5C0 15.216.784 16 1.75 16h12.5A1.75 1.75 0 0016 14.25V1.75A1.75 1.75 0 0014.25 0H1.75zM1.5 1.75a.25.25 0 01.25-.25h12.5a.25.25 0 01.25.25v12.5a.25.25 0 01-.25.25H1.75a.25.25 0 01-.25-.25V1.75zM11.75 3a.75.75 0 00-.75.75v7.5a.75.75 0 001.5 0v-7.5a.75.75 0 00-.75-.75zm-8.25.75a.75.75 0 011.5 0v5.5a.75.75 0 01-1.5 0v-5.5zM8 3a.75.75 0 00-.75.75v3.5a.75.75 0 001.5 0v-3.5A.75.75 0 008 3z"></path> +</svg> + <svg title="Search" aria-label="Search" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-search js-jump-to-octicon-search d-none flex-shrink-0"> + <path fill-rule="evenodd" d="M11.5 7a4.499 4.499 0 11-8.998 0A4.499 4.499 0 0111.5 7zm-.82 4.74a6 6 0 111.06-1.06l3.04 3.04a.75.75 0 11-1.06 1.06l-3.04-3.04z"></path> +</svg> + </div> + + <img class="avatar mr-2 flex-shrink-0 js-jump-to-suggestion-avatar d-none" alt="" aria-label="Team" src="" width="28" height="28"> + + <div class="jump-to-suggestion-name js-jump-to-suggestion-name flex-auto overflow-hidden text-left no-wrap css-truncate css-truncate-target"> + </div> + + <div class="border rounded-2 flex-shrink-0 color-bg-subtle px-1 color-fg-muted ml-1 f6 d-none js-jump-to-badge-search"> + <span class="js-jump-to-badge-search-text-default d-none" aria-label="in this repository"> + In this repository + </span> + <span class="js-jump-to-badge-search-text-global d-none" aria-label="in all of GitHub"> + All GitHub + </span> + <span aria-hidden="true" class="d-inline-block ml-1 v-align-middle">↵</span> + </div> + + <div aria-hidden="true" class="border rounded-2 flex-shrink-0 color-bg-subtle px-1 color-fg-muted ml-1 f6 d-none d-on-nav-focus js-jump-to-badge-jump"> + Jump to + <span class="d-inline-block ml-1 v-align-middle">↵</span> + </div> + </a> +</li> + +</ul> + +<ul class="d-none js-jump-to-no-results-template-container"> + <li class="d-flex flex-justify-center flex-items-center f5 d-none js-jump-to-suggestion p-2"> + <span class="color-fg-muted">No suggested jump to results</span> + </li> +</ul> + +<ul id="jump-to-results" role="listbox" class="p-0 m-0 js-navigation-container jump-to-suggestions-results-container js-jump-to-suggestions-results-container"> + + +<li class="d-flex flex-justify-start flex-items-center p-0 f5 navigation-item js-navigation-item js-jump-to-scoped-search d-none" role="option"> + <a tabindex="-1" class="no-underline d-flex flex-auto flex-items-center jump-to-suggestions-path js-jump-to-suggestion-path js-navigation-open p-2" href="" data-item-type="scoped_search"> + <div class="jump-to-octicon js-jump-to-octicon flex-shrink-0 mr-2 text-center d-none"> + <svg title="Repository" aria-label="Repository" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo js-jump-to-octicon-repo d-none flex-shrink-0"> + <path fill-rule="evenodd" d="M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z"></path> +</svg> + <svg title="Project" aria-label="Project" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-project js-jump-to-octicon-project d-none flex-shrink-0"> + <path fill-rule="evenodd" d="M1.75 0A1.75 1.75 0 000 1.75v12.5C0 15.216.784 16 1.75 16h12.5A1.75 1.75 0 0016 14.25V1.75A1.75 1.75 0 0014.25 0H1.75zM1.5 1.75a.25.25 0 01.25-.25h12.5a.25.25 0 01.25.25v12.5a.25.25 0 01-.25.25H1.75a.25.25 0 01-.25-.25V1.75zM11.75 3a.75.75 0 00-.75.75v7.5a.75.75 0 001.5 0v-7.5a.75.75 0 00-.75-.75zm-8.25.75a.75.75 0 011.5 0v5.5a.75.75 0 01-1.5 0v-5.5zM8 3a.75.75 0 00-.75.75v3.5a.75.75 0 001.5 0v-3.5A.75.75 0 008 3z"></path> +</svg> + <svg title="Search" aria-label="Search" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-search js-jump-to-octicon-search d-none flex-shrink-0"> + <path fill-rule="evenodd" d="M11.5 7a4.499 4.499 0 11-8.998 0A4.499 4.499 0 0111.5 7zm-.82 4.74a6 6 0 111.06-1.06l3.04 3.04a.75.75 0 11-1.06 1.06l-3.04-3.04z"></path> +</svg> + </div> + + <img class="avatar mr-2 flex-shrink-0 js-jump-to-suggestion-avatar d-none" alt="" aria-label="Team" src="" width="28" height="28"> + + <div class="jump-to-suggestion-name js-jump-to-suggestion-name flex-auto overflow-hidden text-left no-wrap css-truncate css-truncate-target"> + </div> + + <div class="border rounded-2 flex-shrink-0 color-bg-subtle px-1 color-fg-muted ml-1 f6 d-none js-jump-to-badge-search"> + <span class="js-jump-to-badge-search-text-default d-none" aria-label="in this repository"> + In this repository + </span> + <span class="js-jump-to-badge-search-text-global d-none" aria-label="in all of GitHub"> + All GitHub + </span> + <span aria-hidden="true" class="d-inline-block ml-1 v-align-middle">↵</span> + </div> + + <div aria-hidden="true" class="border rounded-2 flex-shrink-0 color-bg-subtle px-1 color-fg-muted ml-1 f6 d-none d-on-nav-focus js-jump-to-badge-jump"> + Jump to + <span class="d-inline-block ml-1 v-align-middle">↵</span> + </div> + </a> +</li> + + + +<li class="d-flex flex-justify-start flex-items-center p-0 f5 navigation-item js-navigation-item js-jump-to-owner-scoped-search d-none" role="option"> + <a tabindex="-1" class="no-underline d-flex flex-auto flex-items-center jump-to-suggestions-path js-jump-to-suggestion-path js-navigation-open p-2" href="" data-item-type="owner_scoped_search"> + <div class="jump-to-octicon js-jump-to-octicon flex-shrink-0 mr-2 text-center d-none"> + <svg title="Repository" aria-label="Repository" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo js-jump-to-octicon-repo d-none flex-shrink-0"> + <path fill-rule="evenodd" d="M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z"></path> +</svg> + <svg title="Project" aria-label="Project" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-project js-jump-to-octicon-project d-none flex-shrink-0"> + <path fill-rule="evenodd" d="M1.75 0A1.75 1.75 0 000 1.75v12.5C0 15.216.784 16 1.75 16h12.5A1.75 1.75 0 0016 14.25V1.75A1.75 1.75 0 0014.25 0H1.75zM1.5 1.75a.25.25 0 01.25-.25h12.5a.25.25 0 01.25.25v12.5a.25.25 0 01-.25.25H1.75a.25.25 0 01-.25-.25V1.75zM11.75 3a.75.75 0 00-.75.75v7.5a.75.75 0 001.5 0v-7.5a.75.75 0 00-.75-.75zm-8.25.75a.75.75 0 011.5 0v5.5a.75.75 0 01-1.5 0v-5.5zM8 3a.75.75 0 00-.75.75v3.5a.75.75 0 001.5 0v-3.5A.75.75 0 008 3z"></path> +</svg> + <svg title="Search" aria-label="Search" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-search js-jump-to-octicon-search d-none flex-shrink-0"> + <path fill-rule="evenodd" d="M11.5 7a4.499 4.499 0 11-8.998 0A4.499 4.499 0 0111.5 7zm-.82 4.74a6 6 0 111.06-1.06l3.04 3.04a.75.75 0 11-1.06 1.06l-3.04-3.04z"></path> +</svg> + </div> + + <img class="avatar mr-2 flex-shrink-0 js-jump-to-suggestion-avatar d-none" alt="" aria-label="Team" src="" width="28" height="28"> + + <div class="jump-to-suggestion-name js-jump-to-suggestion-name flex-auto overflow-hidden text-left no-wrap css-truncate css-truncate-target"> + </div> + + <div class="border rounded-2 flex-shrink-0 color-bg-subtle px-1 color-fg-muted ml-1 f6 d-none js-jump-to-badge-search"> + <span class="js-jump-to-badge-search-text-default d-none" aria-label="in this user"> + In this user + </span> + <span class="js-jump-to-badge-search-text-global d-none" aria-label="in all of GitHub"> + All GitHub + </span> + <span aria-hidden="true" class="d-inline-block ml-1 v-align-middle">↵</span> + </div> + + <div aria-hidden="true" class="border rounded-2 flex-shrink-0 color-bg-subtle px-1 color-fg-muted ml-1 f6 d-none d-on-nav-focus js-jump-to-badge-jump"> + Jump to + <span class="d-inline-block ml-1 v-align-middle">↵</span> + </div> + </a> +</li> + + + +<li class="d-flex flex-justify-start flex-items-center p-0 f5 navigation-item js-navigation-item js-jump-to-global-search d-none" role="option"> + <a tabindex="-1" class="no-underline d-flex flex-auto flex-items-center jump-to-suggestions-path js-jump-to-suggestion-path js-navigation-open p-2" href="" data-item-type="global_search"> + <div class="jump-to-octicon js-jump-to-octicon flex-shrink-0 mr-2 text-center d-none"> + <svg title="Repository" aria-label="Repository" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo js-jump-to-octicon-repo d-none flex-shrink-0"> + <path fill-rule="evenodd" d="M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z"></path> +</svg> + <svg title="Project" aria-label="Project" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-project js-jump-to-octicon-project d-none flex-shrink-0"> + <path fill-rule="evenodd" d="M1.75 0A1.75 1.75 0 000 1.75v12.5C0 15.216.784 16 1.75 16h12.5A1.75 1.75 0 0016 14.25V1.75A1.75 1.75 0 0014.25 0H1.75zM1.5 1.75a.25.25 0 01.25-.25h12.5a.25.25 0 01.25.25v12.5a.25.25 0 01-.25.25H1.75a.25.25 0 01-.25-.25V1.75zM11.75 3a.75.75 0 00-.75.75v7.5a.75.75 0 001.5 0v-7.5a.75.75 0 00-.75-.75zm-8.25.75a.75.75 0 011.5 0v5.5a.75.75 0 01-1.5 0v-5.5zM8 3a.75.75 0 00-.75.75v3.5a.75.75 0 001.5 0v-3.5A.75.75 0 008 3z"></path> +</svg> + <svg title="Search" aria-label="Search" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-search js-jump-to-octicon-search d-none flex-shrink-0"> + <path fill-rule="evenodd" d="M11.5 7a4.499 4.499 0 11-8.998 0A4.499 4.499 0 0111.5 7zm-.82 4.74a6 6 0 111.06-1.06l3.04 3.04a.75.75 0 11-1.06 1.06l-3.04-3.04z"></path> +</svg> + </div> + + <img class="avatar mr-2 flex-shrink-0 js-jump-to-suggestion-avatar d-none" alt="" aria-label="Team" src="" width="28" height="28"> + + <div class="jump-to-suggestion-name js-jump-to-suggestion-name flex-auto overflow-hidden text-left no-wrap css-truncate css-truncate-target"> + </div> + + <div class="border rounded-2 flex-shrink-0 color-bg-subtle px-1 color-fg-muted ml-1 f6 d-none js-jump-to-badge-search"> + <span class="js-jump-to-badge-search-text-default d-none" aria-label="in this repository"> + In this repository + </span> + <span class="js-jump-to-badge-search-text-global d-none" aria-label="in all of GitHub"> + All GitHub + </span> + <span aria-hidden="true" class="d-inline-block ml-1 v-align-middle">↵</span> + </div> + + <div aria-hidden="true" class="border rounded-2 flex-shrink-0 color-bg-subtle px-1 color-fg-muted ml-1 f6 d-none d-on-nav-focus js-jump-to-badge-jump"> + Jump to + <span class="d-inline-block ml-1 v-align-middle">↵</span> + </div> + </a> +</li> + + +</ul> + + </div> + </label> +</form> </div> +</div> + + </div> + + <div class="position-relative mr-3 mb-4 mb-lg-0 d-inline-block"> + <a href="/login?return_to=https%3A%2F%2Fgithub.com%2FLukeSmithxyz%2Fst%2Fblob%2Fmaster%2Fst-urlhandler" + class="HeaderMenu-link flex-shrink-0 no-underline" + data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;site header menu&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;SIGN_UP&quot;,&quot;originating_url&quot;:&quot;https://github.com/LukeSmithxyz/st/blob/master/st-urlhandler&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="b3a4640b8bf31bb87687dd4385cc1fa85288369fdf13cb1aedbf8df3d9089262" + data-ga-click="(Logged out) Header, clicked Sign in, text:sign-in"> + Sign in + </a> + </div> + + <a href="/signup?ref_cta=Sign+up&amp;ref_loc=header+logged+out&amp;ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fblob%2Fshow&amp;source=header-repo&amp;source_repo=LukeSmithxyz%2Fst" + class="HeaderMenu-link flex-shrink-0 d-inline-block no-underline border color-border-default rounded px-2 py-1" + data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;site header menu&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;SIGN_UP&quot;,&quot;originating_url&quot;:&quot;https://github.com/LukeSmithxyz/st/blob/master/st-urlhandler&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="b3a4640b8bf31bb87687dd4385cc1fa85288369fdf13cb1aedbf8df3d9089262" + data-analytics-event="{&quot;category&quot;:&quot;Sign up&quot;,&quot;action&quot;:&quot;click to sign up for account&quot;,&quot;label&quot;:&quot;ref_page:/&lt;user-name&gt;/&lt;repo-name&gt;/blob/show;ref_cta:Sign up;ref_loc:header logged out&quot;}" + > + Sign up + </a> + </div> + </div> + </div> +</header> + + </div> + + <div id="start-of-content" class="show-on-focus"></div> + + + + + + + + <div data-pjax-replace id="js-flash-container"> + + + <template class="js-flash-template"> + <div class="flash flash-full {{ className }}"> + <div class="px-2" > + <button class="flash-close js-flash-close" type="button" aria-label="Dismiss this message"> + <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x"> + <path fill-rule="evenodd" d="M3.72 3.72a.75.75 0 011.06 0L8 6.94l3.22-3.22a.75.75 0 111.06 1.06L9.06 8l3.22 3.22a.75.75 0 11-1.06 1.06L8 9.06l-3.22 3.22a.75.75 0 01-1.06-1.06L6.94 8 3.72 4.78a.75.75 0 010-1.06z"></path> +</svg> + </button> + + <div>{{ message }}</div> + + </div> +</div> + </template> +</div> + + + + + <include-fragment class="js-notification-shelf-include-fragment" data-base-src="https://github.com/notifications/beta/shelf"></include-fragment> + + + + + + <div + class="application-main " + data-commit-hovercards-enabled + data-discussion-hovercards-enabled + data-issue-and-pr-hovercards-enabled + > + <div itemscope itemtype="http://schema.org/SoftwareSourceCode" class=""> + <main id="js-repo-pjax-container" data-pjax-container > + + + + + + + + + + + <div id="repository-container-header" class="pt-3 hide-full-screen" style="background-color: var(--color-page-header-bg);" data-pjax-replace> + + <div class="d-flex mb-3 px-3 px-md-4 px-lg-5"> + + <div class="flex-auto min-width-0 width-fit mr-3"> + <h2 class=" d-flex flex-wrap flex-items-center wb-break-word f3 text-normal"> + <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo color-fg-muted mr-2"> + <path fill-rule="evenodd" d="M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z"></path> +</svg> + <span class="author flex-self-stretch" itemprop="author"> + <a class="url fn" rel="author" data-hovercard-type="user" data-hovercard-url="/users/LukeSmithxyz/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="/LukeSmithxyz">LukeSmithxyz</a> + </span> + <span class="mx-1 flex-self-stretch color-fg-muted">/</span> + <strong itemprop="name" class="mr-2 flex-self-stretch"> + <a data-pjax="#repo-content-pjax-container" href="/LukeSmithxyz/st">st</a> + </strong> + + <span></span><span class="Label Label--secondary v-align-middle mr-1">Public</span> +</h2> + + </div> + + <ul class="pagehead-actions flex-shrink-0 d-none d-md-inline" style="padding: 2px 0;"> + <li> + <include-fragment src="/LukeSmithxyz/st/sponsor_button"></include-fragment> + </li> + + + + <li> + <a href="/login?return_to=%2FLukeSmithxyz%2Fst" rel="nofollow" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;notification subscription menu watch&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/LukeSmithxyz/st/blob/master/st-urlhandler&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="0b86c214b907479f5c6258bc133c157c6ae4cd63aa437324991dcfaafbe85045" aria-label="You must be signed in to change notification settings" data-view-component="true" class="tooltipped tooltipped-s btn-sm btn"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-bell mr-2"> + <path d="M8 16a2 2 0 001.985-1.75c.017-.137-.097-.25-.235-.25h-3.5c-.138 0-.252.113-.235.25A2 2 0 008 16z"></path><path fill-rule="evenodd" d="M8 1.5A3.5 3.5 0 004.5 5v2.947c0 .346-.102.683-.294.97l-1.703 2.556a.018.018 0 00-.003.01l.001.006c0 .002.002.004.004.006a.017.017 0 00.006.004l.007.001h10.964l.007-.001a.016.016 0 00.006-.004.016.016 0 00.004-.006l.001-.007a.017.017 0 00-.003-.01l-1.703-2.554a1.75 1.75 0 01-.294-.97V5A3.5 3.5 0 008 1.5zM3 5a5 5 0 0110 0v2.947c0 .05.015.098.042.139l1.703 2.555A1.518 1.518 0 0113.482 13H2.518a1.518 1.518 0 01-1.263-2.36l1.703-2.554A.25.25 0 003 7.947V5z"></path> +</svg>Notifications + +</a> + </li> + + <li> + <a href="/login?return_to=%2FLukeSmithxyz%2Fst" rel="nofollow" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;repo details fork button&quot;,&quot;repository_id&quot;:117944122,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/LukeSmithxyz/st/blob/master/st-urlhandler&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="84e77b7cda5c4af466cd985dbccb49324be63d1ea42371589e559a663321565c" aria-label="You must be signed in to fork a repository" data-view-component="true" class="tooltipped tooltipped-s btn-sm btn"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo-forked mr-2"> + <path fill-rule="evenodd" d="M5 3.25a.75.75 0 11-1.5 0 .75.75 0 011.5 0zm0 2.122a2.25 2.25 0 10-1.5 0v.878A2.25 2.25 0 005.75 8.5h1.5v2.128a2.251 2.251 0 101.5 0V8.5h1.5a2.25 2.25 0 002.25-2.25v-.878a2.25 2.25 0 10-1.5 0v.878a.75.75 0 01-.75.75h-4.5A.75.75 0 015 6.25v-.878zm3.75 7.378a.75.75 0 11-1.5 0 .75.75 0 011.5 0zm3-8.75a.75.75 0 100-1.5.75.75 0 000 1.5z"></path> +</svg>Fork + <span id="repo-network-counter" data-pjax-replace="true" title="915" data-view-component="true" class="Counter">915</span> + +</a> + </li> + + <li> + <div data-view-component="true" class="BtnGroup d-flex"> + <a href="/login?return_to=%2FLukeSmithxyz%2Fst" rel="nofollow" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;star button&quot;,&quot;repository_id&quot;:117944122,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/LukeSmithxyz/st/blob/master/st-urlhandler&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="6c18c456e24772ceed62d64198b6d69f48c4632030c20eb01dfc4d658fdbabd8" aria-label="You must be signed in to star a repository" data-view-component="true" class="tooltipped tooltipped-s btn-sm btn BtnGroup-item"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-star v-align-text-bottom d-inline-block mr-2"> + <path fill-rule="evenodd" d="M8 .25a.75.75 0 01.673.418l1.882 3.815 4.21.612a.75.75 0 01.416 1.279l-3.046 2.97.719 4.192a.75.75 0 01-1.088.791L8 12.347l-3.766 1.98a.75.75 0 01-1.088-.79l.72-4.194L.818 6.374a.75.75 0 01.416-1.28l4.21-.611L7.327.668A.75.75 0 018 .25zm0 2.445L6.615 5.5a.75.75 0 01-.564.41l-3.097.45 2.24 2.184a.75.75 0 01.216.664l-.528 3.084 2.769-1.456a.75.75 0 01.698 0l2.77 1.456-.53-3.084a.75.75 0 01.216-.664l2.24-2.183-3.096-.45a.75.75 0 01-.564-.41L8 2.694v.001z"></path> +</svg><span data-view-component="true" class="d-inline"> + Star +</span> <span id="repo-stars-counter-star" aria-label="1370 users starred this repository" data-singular-suffix="user starred this repository" data-plural-suffix="users starred this repository" data-pjax-replace="true" title="1,370" data-view-component="true" class="Counter js-social-count">1.4k</span> + +</a> <button disabled="disabled" aria-label="You must be signed in to add this repository to a list" type="button" data-view-component="true" class="btn-sm btn BtnGroup-item px-2"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-triangle-down"> + <path d="M4.427 7.427l3.396 3.396a.25.25 0 00.354 0l3.396-3.396A.25.25 0 0011.396 7H4.604a.25.25 0 00-.177.427z"></path> +</svg> + +</button></div> + </li> + + + +</ul> + + </div> + + <div id="responsive-meta-container" data-pjax-replace> +</div> + + + +<nav data-pjax="#js-repo-pjax-container" aria-label="Repository" data-view-component="true" class="js-repo-nav js-sidenav-container-pjax js-responsive-underlinenav overflow-hidden UnderlineNav px-3 px-md-4 px-lg-5"> + + <ul data-view-component="true" class="UnderlineNav-body list-style-none"> + <li data-view-component="true" class="d-inline-flex"> + <a id="code-tab" href="/LukeSmithxyz/st" data-tab-item="i0code-tab" data-selected-links="repo_source repo_downloads repo_commits repo_releases repo_tags repo_branches repo_packages repo_deployments /LukeSmithxyz/st" data-pjax="#repo-content-pjax-container" data-hotkey="g c" data-ga-click="Repository, Navigation click, Code tab" aria-current="page" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item selected"> + + <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-code UnderlineNav-octicon d-none d-sm-inline"> + <path fill-rule="evenodd" d="M4.72 3.22a.75.75 0 011.06 1.06L2.06 8l3.72 3.72a.75.75 0 11-1.06 1.06L.47 8.53a.75.75 0 010-1.06l4.25-4.25zm6.56 0a.75.75 0 10-1.06 1.06L13.94 8l-3.72 3.72a.75.75 0 101.06 1.06l4.25-4.25a.75.75 0 000-1.06l-4.25-4.25z"></path> +</svg> + <span data-content="Code">Code</span> + <span id="code-repo-tab-count" data-pjax-replace="" title="Not available" data-view-component="true" class="Counter"></span> + + + +</a></li> + <li data-view-component="true" class="d-inline-flex"> + <a id="issues-tab" href="/LukeSmithxyz/st/issues" data-tab-item="i1issues-tab" data-selected-links="repo_issues repo_labels repo_milestones /LukeSmithxyz/st/issues" data-pjax="#repo-content-pjax-container" data-hotkey="g i" data-ga-click="Repository, Navigation click, Issues tab" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item"> + + <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-issue-opened UnderlineNav-octicon d-none d-sm-inline"> + <path d="M8 9.5a1.5 1.5 0 100-3 1.5 1.5 0 000 3z"></path><path fill-rule="evenodd" d="M8 0a8 8 0 100 16A8 8 0 008 0zM1.5 8a6.5 6.5 0 1113 0 6.5 6.5 0 01-13 0z"></path> +</svg> + <span data-content="Issues">Issues</span> + <span id="issues-repo-tab-count" data-pjax-replace="" title="5" data-view-component="true" class="Counter">5</span> + + + +</a></li> + <li data-view-component="true" class="d-inline-flex"> + <a id="pull-requests-tab" href="/LukeSmithxyz/st/pulls" data-tab-item="i2pull-requests-tab" data-selected-links="repo_pulls checks /LukeSmithxyz/st/pulls" data-pjax="#repo-content-pjax-container" data-hotkey="g p" data-ga-click="Repository, Navigation click, Pull requests tab" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item"> + + <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-git-pull-request UnderlineNav-octicon d-none d-sm-inline"> + <path fill-rule="evenodd" d="M7.177 3.073L9.573.677A.25.25 0 0110 .854v4.792a.25.25 0 01-.427.177L7.177 3.427a.25.25 0 010-.354zM3.75 2.5a.75.75 0 100 1.5.75.75 0 000-1.5zm-2.25.75a2.25 2.25 0 113 2.122v5.256a2.251 2.251 0 11-1.5 0V5.372A2.25 2.25 0 011.5 3.25zM11 2.5h-1V4h1a1 1 0 011 1v5.628a2.251 2.251 0 101.5 0V5A2.5 2.5 0 0011 2.5zm1 10.25a.75.75 0 111.5 0 .75.75 0 01-1.5 0zM3.75 12a.75.75 0 100 1.5.75.75 0 000-1.5z"></path> +</svg> + <span data-content="Pull requests">Pull requests</span> + <span id="pull-requests-repo-tab-count" data-pjax-replace="" title="0" hidden="hidden" data-view-component="true" class="Counter">0</span> + + + +</a></li> + <li data-view-component="true" class="d-inline-flex"> + <a id="actions-tab" href="/LukeSmithxyz/st/actions" data-tab-item="i3actions-tab" data-selected-links="repo_actions /LukeSmithxyz/st/actions" data-pjax="#repo-content-pjax-container" data-hotkey="g a" data-analytics-event="{&quot;category&quot;:&quot;Actions&quot;,&quot;action&quot;:&quot;clicked&quot;,&quot;label&quot;:&quot;ref_cta:Actions;ref_loc:navigation_helper&quot;}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item"> + + <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-play UnderlineNav-octicon d-none d-sm-inline"> + <path fill-rule="evenodd" d="M1.5 8a6.5 6.5 0 1113 0 6.5 6.5 0 01-13 0zM8 0a8 8 0 100 16A8 8 0 008 0zM6.379 5.227A.25.25 0 006 5.442v5.117a.25.25 0 00.379.214l4.264-2.559a.25.25 0 000-.428L6.379 5.227z"></path> +</svg> + <span data-content="Actions">Actions</span> + <span id="actions-repo-tab-count" data-pjax-replace="" title="Not available" data-view-component="true" class="Counter"></span> + + + +</a></li> + <li data-view-component="true" class="d-inline-flex"> + <a id="projects-tab" href="/LukeSmithxyz/st/projects?type=beta" data-tab-item="i4projects-tab" data-selected-links="repo_projects new_repo_project repo_project /LukeSmithxyz/st/projects?type=beta" data-pjax="#repo-content-pjax-container" data-hotkey="g b" data-ga-click="Repository, Navigation click, Projects tab" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item"> + + <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-table UnderlineNav-octicon d-none d-sm-inline"> + <path fill-rule="evenodd" d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v3.585a.746.746 0 010 .83v8.085A1.75 1.75 0 0114.25 16H6.309a.748.748 0 01-1.118 0H1.75A1.75 1.75 0 010 14.25V6.165a.746.746 0 010-.83V1.75zM1.5 6.5v7.75c0 .138.112.25.25.25H5v-8H1.5zM5 5H1.5V1.75a.25.25 0 01.25-.25H5V5zm1.5 1.5v8h7.75a.25.25 0 00.25-.25V6.5h-8zm8-1.5h-8V1.5h7.75a.25.25 0 01.25.25V5z"></path> +</svg> + <span data-content="Projects">Projects</span> + <span id="projects-repo-tab-count" data-pjax-replace="" title="0" hidden="hidden" data-view-component="true" class="Counter">0</span> + + + +</a></li> + <li data-view-component="true" class="d-inline-flex"> + <a id="wiki-tab" href="/LukeSmithxyz/st/wiki" data-tab-item="i5wiki-tab" data-selected-links="repo_wiki /LukeSmithxyz/st/wiki" data-pjax="#repo-content-pjax-container" data-hotkey="g w" data-ga-click="Repository, Navigation click, Wikis tab" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item"> + + <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-book UnderlineNav-octicon d-none d-sm-inline"> + <path fill-rule="evenodd" d="M0 1.75A.75.75 0 01.75 1h4.253c1.227 0 2.317.59 3 1.501A3.744 3.744 0 0111.006 1h4.245a.75.75 0 01.75.75v10.5a.75.75 0 01-.75.75h-4.507a2.25 2.25 0 00-1.591.659l-.622.621a.75.75 0 01-1.06 0l-.622-.621A2.25 2.25 0 005.258 13H.75a.75.75 0 01-.75-.75V1.75zm8.755 3a2.25 2.25 0 012.25-2.25H14.5v9h-3.757c-.71 0-1.4.201-1.992.572l.004-7.322zm-1.504 7.324l.004-5.073-.002-2.253A2.25 2.25 0 005.003 2.5H1.5v9h3.757a3.75 3.75 0 011.994.574z"></path> +</svg> + <span data-content="Wiki">Wiki</span> + <span id="wiki-repo-tab-count" data-pjax-replace="" title="Not available" data-view-component="true" class="Counter"></span> + + + +</a></li> + <li data-view-component="true" class="d-inline-flex"> + <a id="security-tab" href="/LukeSmithxyz/st/security" data-tab-item="i6security-tab" data-selected-links="security overview alerts policy token_scanning code_scanning /LukeSmithxyz/st/security" data-pjax="#repo-content-pjax-container" data-hotkey="g s" data-ga-click="Repository, Navigation click, Security tab" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item"> + + <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-shield UnderlineNav-octicon d-none d-sm-inline"> + <path fill-rule="evenodd" d="M7.467.133a1.75 1.75 0 011.066 0l5.25 1.68A1.75 1.75 0 0115 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.7 1.7 0 01-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 011.217-1.667l5.25-1.68zm.61 1.429a.25.25 0 00-.153 0l-5.25 1.68a.25.25 0 00-.174.238V7c0 1.358.275 2.666 1.057 3.86.784 1.194 2.121 2.34 4.366 3.297a.2.2 0 00.154 0c2.245-.956 3.582-2.104 4.366-3.298C13.225 9.666 13.5 8.36 13.5 7V3.48a.25.25 0 00-.174-.237l-5.25-1.68zM9 10.5a1 1 0 11-2 0 1 1 0 012 0zm-.25-5.75a.75.75 0 10-1.5 0v3a.75.75 0 001.5 0v-3z"></path> +</svg> + <span data-content="Security">Security</span> + <include-fragment src="/LukeSmithxyz/st/security/overall-count" accept="text/fragment+html"></include-fragment> + + +</a></li> + <li data-view-component="true" class="d-inline-flex"> + <a id="insights-tab" href="/LukeSmithxyz/st/pulse" data-tab-item="i7insights-tab" data-selected-links="repo_graphs repo_contributors dependency_graph dependabot_updates pulse people community /LukeSmithxyz/st/pulse" data-pjax="#repo-content-pjax-container" data-ga-click="Repository, Navigation click, Insights tab" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item"> + + <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-graph UnderlineNav-octicon d-none d-sm-inline"> + <path fill-rule="evenodd" d="M1.5 1.75a.75.75 0 00-1.5 0v12.5c0 .414.336.75.75.75h14.5a.75.75 0 000-1.5H1.5V1.75zm14.28 2.53a.75.75 0 00-1.06-1.06L10 7.94 7.53 5.47a.75.75 0 00-1.06 0L3.22 8.72a.75.75 0 001.06 1.06L7 7.06l2.47 2.47a.75.75 0 001.06 0l5.25-5.25z"></path> +</svg> + <span data-content="Insights">Insights</span> + <span id="insights-repo-tab-count" data-pjax-replace="" title="Not available" data-view-component="true" class="Counter"></span> + + + +</a></li> +</ul> + <div style="visibility:hidden;" data-view-component="true" class="UnderlineNav-actions js-responsive-underlinenav-overflow position-absolute pr-3 pr-md-4 pr-lg-5 right-0"> <details data-view-component="true" class="details-overlay details-reset position-relative"> + <summary role="button" data-view-component="true"> <div class="UnderlineNav-item mr-0 border-0"> + <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-kebab-horizontal"> + <path d="M8 9a1.5 1.5 0 100-3 1.5 1.5 0 000 3zM1.5 9a1.5 1.5 0 100-3 1.5 1.5 0 000 3zm13 0a1.5 1.5 0 100-3 1.5 1.5 0 000 3z"></path> +</svg> + <span class="sr-only">More</span> + </div> +</summary> + <div data-view-component="true"> <details-menu role="menu" data-view-component="true" class="dropdown-menu dropdown-menu-sw"> + + <ul> + <li data-menu-item="i0code-tab" hidden> + <a role="menuitem" class="js-selected-navigation-item selected dropdown-item" aria-current="page" data-selected-links="repo_source repo_downloads repo_commits repo_releases repo_tags repo_branches repo_packages repo_deployments /LukeSmithxyz/st" href="/LukeSmithxyz/st"> + Code +</a> </li> + <li data-menu-item="i1issues-tab" hidden> + <a role="menuitem" class="js-selected-navigation-item dropdown-item" data-selected-links="repo_issues repo_labels repo_milestones /LukeSmithxyz/st/issues" href="/LukeSmithxyz/st/issues"> + Issues +</a> </li> + <li data-menu-item="i2pull-requests-tab" hidden> + <a role="menuitem" class="js-selected-navigation-item dropdown-item" data-selected-links="repo_pulls checks /LukeSmithxyz/st/pulls" href="/LukeSmithxyz/st/pulls"> + Pull requests +</a> </li> + <li data-menu-item="i3actions-tab" hidden> + <a role="menuitem" class="js-selected-navigation-item dropdown-item" data-selected-links="repo_actions /LukeSmithxyz/st/actions" href="/LukeSmithxyz/st/actions"> + Actions +</a> </li> + <li data-menu-item="i4projects-tab" hidden> + <a role="menuitem" class="js-selected-navigation-item dropdown-item" data-selected-links="repo_projects new_repo_project repo_project /LukeSmithxyz/st/projects?type=beta" href="/LukeSmithxyz/st/projects?type=beta"> + Projects +</a> </li> + <li data-menu-item="i5wiki-tab" hidden> + <a role="menuitem" class="js-selected-navigation-item dropdown-item" data-selected-links="repo_wiki /LukeSmithxyz/st/wiki" href="/LukeSmithxyz/st/wiki"> + Wiki +</a> </li> + <li data-menu-item="i6security-tab" hidden> + <a role="menuitem" class="js-selected-navigation-item dropdown-item" data-selected-links="security overview alerts policy token_scanning code_scanning /LukeSmithxyz/st/security" href="/LukeSmithxyz/st/security"> + Security +</a> </li> + <li data-menu-item="i7insights-tab" hidden> + <a role="menuitem" class="js-selected-navigation-item dropdown-item" data-selected-links="repo_graphs repo_contributors dependency_graph dependabot_updates pulse people community /LukeSmithxyz/st/pulse" href="/LukeSmithxyz/st/pulse"> + Insights +</a> </li> + </ul> + +</details-menu></div> +</details></div> +</nav> + </div> + + + +<div id="repo-content-pjax-container" class="repository-content " > + + + + + + + <div class="clearfix container-xl px-3 px-md-4 px-lg-5 mt-4"> + + +<div> + + + + + + + + +<a class="d-none js-permalink-shortcut" data-hotkey="y" href="/LukeSmithxyz/st/blob/3144a61c180b678f6b1c23f06e4b434090199fcb/st-urlhandler">Permalink</a> + +<div class="d-flex flex-items-start flex-shrink-0 pb-3 flex-wrap flex-md-nowrap flex-justify-between flex-md-justify-start"> + +<div class="position-relative"> + <details class="details-reset details-overlay mr-0 mb-0 " id="branch-select-menu"> + <summary class="btn css-truncate" + data-hotkey="w" + title="Switch branches or tags"> + <svg text="gray" aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-git-branch"> + <path fill-rule="evenodd" d="M11.75 2.5a.75.75 0 100 1.5.75.75 0 000-1.5zm-2.25.75a2.25 2.25 0 113 2.122V6A2.5 2.5 0 0110 8.5H6a1 1 0 00-1 1v1.128a2.251 2.251 0 11-1.5 0V5.372a2.25 2.25 0 111.5 0v1.836A2.492 2.492 0 016 7h4a1 1 0 001-1v-.628A2.25 2.25 0 019.5 3.25zM4.25 12a.75.75 0 100 1.5.75.75 0 000-1.5zM3.5 3.25a.75.75 0 111.5 0 .75.75 0 01-1.5 0z"></path> +</svg> + <span class="css-truncate-target" data-menu-button>master</span> + <span class="dropdown-caret"></span> + </summary> + + +<div class="SelectMenu"> + <div class="SelectMenu-modal"> + <header class="SelectMenu-header"> + <span class="SelectMenu-title">Switch branches/tags</span> + <button class="SelectMenu-closeButton" type="button" data-toggle-for="branch-select-menu"><svg aria-label="Close menu" aria-hidden="false" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x"> + <path fill-rule="evenodd" d="M3.72 3.72a.75.75 0 011.06 0L8 6.94l3.22-3.22a.75.75 0 111.06 1.06L9.06 8l3.22 3.22a.75.75 0 11-1.06 1.06L8 9.06l-3.22 3.22a.75.75 0 01-1.06-1.06L6.94 8 3.72 4.78a.75.75 0 010-1.06z"></path> +</svg></button> + </header> + + <input-demux data-action="tab-container-change:input-demux#storeInput tab-container-changed:input-demux#updateInput"> + <tab-container class="d-flex flex-column js-branches-tags-tabs" style="min-height: 0;"> + <div class="SelectMenu-filter"> + <input data-target="input-demux.source" + id="context-commitish-filter-field" + class="SelectMenu-input form-control" + aria-owns="ref-list-branches" + data-controls-ref-menu-id="ref-list-branches" + autofocus + autocomplete="off" + aria-label="Filter branches/tags" + placeholder="Filter branches/tags" + type="text" + > + </div> + + <div class="SelectMenu-tabs" role="tablist" data-target="input-demux.control" > + <button class="SelectMenu-tab" type="button" role="tab" aria-selected="true">Branches</button> + <button class="SelectMenu-tab" type="button" role="tab">Tags</button> + </div> + + <div role="tabpanel" id="ref-list-branches" data-filter-placeholder="Filter branches/tags" tabindex="" class="d-flex flex-column flex-auto overflow-auto"> + <ref-selector + type="branch" + data-targets="input-demux.sinks" + data-action=" + input-entered:ref-selector#inputEntered + tab-selected:ref-selector#tabSelected + focus-list:ref-selector#focusFirstListMember + " + query-endpoint="/LukeSmithxyz/st/refs" + + cache-key="v0:1557334078.0" + current-committish="bWFzdGVy" + default-branch="bWFzdGVy" + name-with-owner="THVrZVNtaXRoeHl6L3N0" + prefetch-on-mouseover + > + + <template data-target="ref-selector.fetchFailedTemplate"> + <div class="SelectMenu-message" data-index="{{ index }}">Could not load branches</div> + </template> + + <template data-target="ref-selector.noMatchTemplate"> + <div class="SelectMenu-message">Nothing to show</div> +</template> + + + <div data-target="ref-selector.listContainer" role="menu" class="SelectMenu-list " data-pjax="#repo-content-pjax-container"> + <div class="SelectMenu-loading pt-3 pb-0 overflow-hidden" aria-label="Menu is loading"> + <svg style="box-sizing: content-box; color: var(--color-icon-primary);" width="32" height="32" viewBox="0 0 16 16" fill="none" data-view-component="true" class="anim-rotate"> + <circle cx="8" cy="8" r="7" stroke="currentColor" stroke-opacity="0.25" stroke-width="2" vector-effect="non-scaling-stroke" /> + <path d="M15 8a7.002 7.002 0 00-7-7" stroke="currentColor" stroke-width="2" stroke-linecap="round" vector-effect="non-scaling-stroke" /> +</svg> + </div> + </div> + + <template data-target="ref-selector.itemTemplate"> + <a href="https://github.com/LukeSmithxyz/st/blob/{{ urlEncodedRefName }}/st-urlhandler" class="SelectMenu-item" role="menuitemradio" rel="nofollow" aria-checked="{{ isCurrent }}" data-index="{{ index }}"> + <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check SelectMenu-icon SelectMenu-icon--check"> + <path fill-rule="evenodd" d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"></path> +</svg> + <span class="flex-1 css-truncate css-truncate-overflow {{ isFilteringClass }}">{{ refName }}</span> + <span hidden="{{ isNotDefault }}" class="Label Label--secondary flex-self-start">default</span> + </a> +</template> + + + <footer class="SelectMenu-footer"><a href="/LukeSmithxyz/st/branches">View all branches</a></footer> + </ref-selector> + + </div> + + <div role="tabpanel" id="tags-menu" data-filter-placeholder="Find a tag" tabindex="" hidden class="d-flex flex-column flex-auto overflow-auto"> + <ref-selector + type="tag" + data-action=" + input-entered:ref-selector#inputEntered + tab-selected:ref-selector#tabSelected + focus-list:ref-selector#focusFirstListMember + " + data-targets="input-demux.sinks" + query-endpoint="/LukeSmithxyz/st/refs" + cache-key="v0:1557334078.0" + current-committish="bWFzdGVy" + default-branch="bWFzdGVy" + name-with-owner="THVrZVNtaXRoeHl6L3N0" + > + + <template data-target="ref-selector.fetchFailedTemplate"> + <div class="SelectMenu-message" data-index="{{ index }}">Could not load tags</div> + </template> + + <template data-target="ref-selector.noMatchTemplate"> + <div class="SelectMenu-message" data-index="{{ index }}">Nothing to show</div> + </template> + + <template data-target="ref-selector.itemTemplate"> + <a href="https://github.com/LukeSmithxyz/st/blob/{{ urlEncodedRefName }}/st-urlhandler" class="SelectMenu-item" role="menuitemradio" rel="nofollow" aria-checked="{{ isCurrent }}" data-index="{{ index }}"> + <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check SelectMenu-icon SelectMenu-icon--check"> + <path fill-rule="evenodd" d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"></path> +</svg> + <span class="flex-1 css-truncate css-truncate-overflow {{ isFilteringClass }}">{{ refName }}</span> + <span hidden="{{ isNotDefault }}" class="Label Label--secondary flex-self-start">default</span> + </a> +</template> + + + <div data-target="ref-selector.listContainer" role="menu" class="SelectMenu-list" data-pjax="#repo-content-pjax-container"> + <div class="SelectMenu-loading pt-3 pb-0 overflow-hidden" aria-label="Menu is loading"> + <svg style="box-sizing: content-box; color: var(--color-icon-primary);" width="32" height="32" viewBox="0 0 16 16" fill="none" data-view-component="true" class="anim-rotate"> + <circle cx="8" cy="8" r="7" stroke="currentColor" stroke-opacity="0.25" stroke-width="2" vector-effect="non-scaling-stroke" /> + <path d="M15 8a7.002 7.002 0 00-7-7" stroke="currentColor" stroke-width="2" stroke-linecap="round" vector-effect="non-scaling-stroke" /> +</svg> + </div> + </div> + <footer class="SelectMenu-footer"><a href="/LukeSmithxyz/st/tags">View all tags</a></footer> + </ref-selector> + </div> + </tab-container> + </input-demux> + </div> +</div> + + </details> + +</div> + + <h2 id="blob-path" class="breadcrumb flex-auto flex-self-center min-width-0 text-normal mx-2 width-full width-md-auto flex-order-1 flex-md-order-none mt-3 mt-md-0"> + <span class="js-repo-root text-bold"><span class="js-path-segment d-inline-block wb-break-all"><a data-pjax="#repo-content-pjax-container" href="/LukeSmithxyz/st"><span>st</span></a></span></span><span class="separator">/</span><strong class="final-path">st-urlhandler</strong> + </h2> + <a href="/LukeSmithxyz/st/find/master" data-pjax="" data-hotkey="t" data-view-component="true" class="btn mr-2 d-none d-md-block"> Go to file + +</a> + <details id="blob-more-options-details" data-view-component="true" class="details-overlay details-reset position-relative"> + <summary role="button" data-view-component="true" class="btn"> <svg aria-label="More options" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-kebab-horizontal"> + <path d="M8 9a1.5 1.5 0 100-3 1.5 1.5 0 000 3zM1.5 9a1.5 1.5 0 100-3 1.5 1.5 0 000 3zm13 0a1.5 1.5 0 100-3 1.5 1.5 0 000 3z"></path> +</svg> + +</summary> + <div data-view-component="true"> <ul class="dropdown-menu dropdown-menu-sw"> + <li class="d-block d-md-none"> + <a class="dropdown-item d-flex flex-items-baseline" data-hydro-click="{&quot;event_type&quot;:&quot;repository.click&quot;,&quot;payload&quot;:{&quot;target&quot;:&quot;FIND_FILE_BUTTON&quot;,&quot;repository_id&quot;:117944122,&quot;originating_url&quot;:&quot;https://github.com/LukeSmithxyz/st/blob/master/st-urlhandler&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="d3871c50678862a9d38b5ef55d843dd3c0cf08b3b59baddaefb37fa9047010bc" data-ga-click="Repository, find file, location:repo overview" data-hotkey="t" data-pjax="true" href="/LukeSmithxyz/st/find/master"> + <span class="flex-auto">Go to file</span> + <span class="text-small color-fg-muted" aria-hidden="true">T</span> +</a> </li> + <li data-toggle-for="blob-more-options-details"> + <button data-toggle-for="jumpto-line-details-dialog" type="button" data-view-component="true" class="dropdown-item btn-link"> <span class="d-flex flex-items-baseline"> + <span class="flex-auto">Go to line</span> + <span class="text-small color-fg-muted" aria-hidden="true">L</span> + </span> + +</button> </li> + <li class="dropdown-divider" role="none"></li> + <li> + <clipboard-copy data-toggle-for="blob-more-options-details" aria-label="Copy path" value="st-urlhandler" data-view-component="true" class="dropdown-item cursor-pointer"> + + Copy path + +</clipboard-copy> </li> + <li> + <clipboard-copy data-toggle-for="blob-more-options-details" aria-label="Copy permalink" value="https://github.com/LukeSmithxyz/st/blob/3144a61c180b678f6b1c23f06e4b434090199fcb/st-urlhandler" data-view-component="true" class="dropdown-item cursor-pointer"> + + <span class="d-flex flex-items-baseline"> + <span class="flex-auto">Copy permalink</span> + </span> + +</clipboard-copy> </li> + </ul> +</div> +</details></div> + + + + + + <div id="spoof-warning" class="mt-0 pb-3" hidden aria-hidden> + <div data-view-component="true" class="flash flash-warn mt-0 clearfix"> + + + <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert float-left mt-1"> + <path fill-rule="evenodd" d="M8.22 1.754a.25.25 0 00-.44 0L1.698 13.132a.25.25 0 00.22.368h12.164a.25.25 0 00.22-.368L8.22 1.754zm-1.763-.707c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0114.082 15H1.918a1.75 1.75 0 01-1.543-2.575L6.457 1.047zM9 11a1 1 0 11-2 0 1 1 0 012 0zm-.25-5.25a.75.75 0 00-1.5 0v2.5a.75.75 0 001.5 0v-2.5z"></path> +</svg> + + <div class="overflow-hidden">This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.</div> + + + +</div></div> + + <include-fragment src="/LukeSmithxyz/st/spoofed_commit_check/3144a61c180b678f6b1c23f06e4b434090199fcb" data-test-selector="spoofed-commit-check"></include-fragment> + + <div class="Box d-flex flex-column flex-shrink-0 mb-3"> + <include-fragment src="/LukeSmithxyz/st/contributors/master/st-urlhandler" class="commit-loader"> + <div class="Box-header d-flex flex-items-center"> + <div class="Skeleton avatar avatar-user flex-shrink-0 ml-n1 mr-n1 mt-n1 mb-n1" style="width:24px;height:24px;"></div> + <div class="Skeleton Skeleton--text col-5 ml-2">&nbsp;</div> + </div> + + <div class="Box-body d-flex flex-items-center" > + <div class="Skeleton Skeleton--text col-1">&nbsp;</div> + <span class="color-fg-danger h6 loader-error">Cannot retrieve contributors at this time</span> + </div> +</include-fragment></div> + + + + + + + + + <div data-target="readme-toc.content" class="Box mt-3 position-relative"> + + <div + class="Box-header js-blob-header py-2 pr-2 d-flex flex-shrink-0 flex-md-row flex-items-center" + + > + + + <div class="text-mono f6 flex-auto pr-3 flex-order-2 flex-md-order-1"> + + <span class="file-mode" title="File mode">executable file</span> + <span class="file-info-divider"></span> + 19 lines (15 sloc) + <span class="file-info-divider"></span> + 925 Bytes + </div> + + <div class="d-flex py-1 py-md-0 flex-auto flex-order-1 flex-md-order-2 flex-sm-grow-0 flex-justify-between hide-sm hide-md"> + + + <div class="BtnGroup"> + <a data-permalink-href="/LukeSmithxyz/st/raw/3144a61c180b678f6b1c23f06e4b434090199fcb/st-urlhandler" href="/LukeSmithxyz/st/raw/master/st-urlhandler" id="raw-url" data-view-component="true" class="js-permalink-replaceable-link btn-sm btn BtnGroup-item"> Raw + +</a> <a data-permalink-href="/LukeSmithxyz/st/blame/3144a61c180b678f6b1c23f06e4b434090199fcb/st-urlhandler" href="/LukeSmithxyz/st/blame/master/st-urlhandler" data-hotkey="b" data-view-component="true" class="js-update-url-with-hash js-permalink-replaceable-link btn-sm btn BtnGroup-item"> Blame + +</a> </div> + + <div> + <a class="btn-octicon tooltipped tooltipped-nw js-remove-unless-platform" + data-platforms="windows,mac" + href="https://desktop.github.com" + aria-label="Open this file in GitHub Desktop" + data-ga-click="Repository, open with desktop"> + <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-device-desktop"> + <path fill-rule="evenodd" d="M1.75 2.5h12.5a.25.25 0 01.25.25v7.5a.25.25 0 01-.25.25H1.75a.25.25 0 01-.25-.25v-7.5a.25.25 0 01.25-.25zM14.25 1H1.75A1.75 1.75 0 000 2.75v7.5C0 11.216.784 12 1.75 12h3.727c-.1 1.041-.52 1.872-1.292 2.757A.75.75 0 004.75 16h6.5a.75.75 0 00.565-1.243c-.772-.885-1.193-1.716-1.292-2.757h3.727A1.75 1.75 0 0016 10.25v-7.5A1.75 1.75 0 0014.25 1zM9.018 12H6.982a5.72 5.72 0 01-.765 2.5h3.566a5.72 5.72 0 01-.765-2.5z"></path> +</svg> + </a> + + + <button class="btn-octicon disabled tooltipped tooltipped-nw" disabled + aria-label="You must be signed in to make or propose changes" type="button"> + <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-pencil"> + <path fill-rule="evenodd" d="M11.013 1.427a1.75 1.75 0 012.474 0l1.086 1.086a1.75 1.75 0 010 2.474l-8.61 8.61c-.21.21-.47.364-.756.445l-3.251.93a.75.75 0 01-.927-.928l.929-3.25a1.75 1.75 0 01.445-.758l8.61-8.61zm1.414 1.06a.25.25 0 00-.354 0L10.811 3.75l1.439 1.44 1.263-1.263a.25.25 0 000-.354l-1.086-1.086zM11.189 6.25L9.75 4.81l-6.286 6.287a.25.25 0 00-.064.108l-.558 1.953 1.953-.558a.249.249 0 00.108-.064l6.286-6.286z"></path> +</svg> + </button> + <button class="btn-octicon btn-octicon-danger disabled tooltipped tooltipped-nw" disabled + aria-label="You must be signed in to make or propose changes" type="button"> + <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-trash"> + <path fill-rule="evenodd" d="M6.5 1.75a.25.25 0 01.25-.25h2.5a.25.25 0 01.25.25V3h-3V1.75zm4.5 0V3h2.25a.75.75 0 010 1.5H2.75a.75.75 0 010-1.5H5V1.75C5 .784 5.784 0 6.75 0h2.5C10.216 0 11 .784 11 1.75zM4.496 6.675a.75.75 0 10-1.492.15l.66 6.6A1.75 1.75 0 005.405 15h5.19c.9 0 1.652-.681 1.741-1.576l.66-6.6a.75.75 0 00-1.492-.149l-.66 6.6a.25.25 0 01-.249.225h-5.19a.25.25 0 01-.249-.225l-.66-6.6z"></path> +</svg> + </button> + </div> + </div> + + <div class="d-flex hide-lg hide-xl flex-order-2 flex-grow-0"> + <details class="dropdown details-reset details-overlay d-inline-block"> + <summary class="btn-octicon" aria-haspopup="true" aria-label="possible actions"> + <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-kebab-horizontal"> + <path d="M8 9a1.5 1.5 0 100-3 1.5 1.5 0 000 3zM1.5 9a1.5 1.5 0 100-3 1.5 1.5 0 000 3zm13 0a1.5 1.5 0 100-3 1.5 1.5 0 000 3z"></path> +</svg> + </summary> + + <ul class="dropdown-menu dropdown-menu-sw" style="width: 175px"> + <li> + <a class="dropdown-item tooltipped tooltipped-nw js-remove-unless-platform" + data-platforms="windows,mac" + href="https://desktop.github.com" + data-ga-click="Repository, open with desktop"> + Open with Desktop + </a> + </li> + <li> + <a class="dropdown-item" href="/LukeSmithxyz/st/raw/master/st-urlhandler"> + View raw + </a> + </li> + <li> + </li> + <li> + <a class="dropdown-item" href="/LukeSmithxyz/st/blame/master/st-urlhandler"> + View blame + </a> + </li> + + </ul> + </details> + </div> +</div> + + + + <div itemprop="text" class="Box-body p-0 blob-wrapper data type-shell gist-border-0"> + + +<div class="js-check-bidi js-blob-code-container blob-code-content"> + + <template class="js-file-alert-template"> + <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center"> + <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert"> + <path fill-rule="evenodd" d="M8.22 1.754a.25.25 0 00-.44 0L1.698 13.132a.25.25 0 00.22.368h12.164a.25.25 0 00.22-.368L8.22 1.754zm-1.763-.707c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0114.082 15H1.918a1.75 1.75 0 01-1.543-2.575L6.457 1.047zM9 11a1 1 0 11-2 0 1 1 0 012 0zm-.25-5.25a.75.75 0 00-1.5 0v2.5a.75.75 0 001.5 0v-2.5z"></path> +</svg> + + <span> + This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. + <a href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a> + </span> + + + <div data-view-component="true" class="flash-action"> <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn"> Show hidden characters + +</a> +</div> +</div></template> +<template class="js-line-alert-template"> + <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"> + <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert"> + <path fill-rule="evenodd" d="M8.22 1.754a.25.25 0 00-.44 0L1.698 13.132a.25.25 0 00.22.368h12.164a.25.25 0 00.22-.368L8.22 1.754zm-1.763-.707c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0114.082 15H1.918a1.75 1.75 0 01-1.543-2.575L6.457 1.047zM9 11a1 1 0 11-2 0 1 1 0 012 0zm-.25-5.25a.75.75 0 00-1.5 0v2.5a.75.75 0 001.5 0v-2.5z"></path> +</svg> +</span></template> + + <table class="highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file" data-tab-size="8" data-paste-markdown-skip data-tagsearch-lang="Shell" data-tagsearch-path="st-urlhandler"> + <tr> + <td id="L1" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="1"></td> + <td id="LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">#!</span>/bin/sh</span></td> + </tr> + <tr> + <td id="L2" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="2"></td> + <td id="LC2" class="blob-code blob-code-inner js-file-line"> +</td> + </tr> + <tr> + <td id="L3" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="3"></td> + <td id="LC3" class="blob-code blob-code-inner js-file-line">urlregex=<span class="pl-s"><span class="pl-pds">&quot;</span>(((http|https|gopher|gemini|ftp|ftps|git)://|www<span class="pl-cce">\\</span>.)[a-zA-Z0-9.]*[:]?[a-zA-Z0-9./@$&amp;%?$\#=_~-]*)|((magnet:<span class="pl-cce">\\</span>?xt=urn:btih:)[a-zA-Z0-9]*)<span class="pl-pds">&quot;</span></span></td> + </tr> + <tr> + <td id="L4" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="4"></td> + <td id="LC4" class="blob-code blob-code-inner js-file-line"> +</td> + </tr> + <tr> + <td id="L5" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="5"></td> + <td id="LC5" class="blob-code blob-code-inner js-file-line">urls=<span class="pl-s"><span class="pl-pds">&quot;</span><span class="pl-s"><span class="pl-pds">$(</span>sed <span class="pl-s"><span class="pl-pds">&#39;</span>s/.*│//g<span class="pl-pds">&#39;</span></span> <span class="pl-k">|</span> tr -d <span class="pl-s"><span class="pl-pds">&#39;</span>\n<span class="pl-pds">&#39;</span></span> <span class="pl-k">|</span> <span class="pl-c"><span class="pl-c">#</span> First remove linebreaks and mutt sidebars:</span></span></span></td> + </tr> + <tr> + <td id="L6" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="6"></td> + <td id="LC6" class="blob-code blob-code-inner js-file-line"><span class="pl-s"><span class="pl-s"> grep -aEo <span class="pl-s"><span class="pl-pds">&quot;</span><span class="pl-smi">$urlregex</span><span class="pl-pds">&quot;</span></span> <span class="pl-k">|</span> <span class="pl-c"><span class="pl-c">#</span> grep only urls as defined above.</span></span></span></td> + </tr> + <tr> + <td id="L7" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="7"></td> + <td id="LC7" class="blob-code blob-code-inner js-file-line"><span class="pl-s"><span class="pl-s"> uniq <span class="pl-k">|</span> <span class="pl-c"><span class="pl-c">#</span> Ignore neighboring duplicates.</span></span></span></td> + </tr> + <tr> + <td id="L8" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="8"></td> + <td id="LC8" class="blob-code blob-code-inner js-file-line"><span class="pl-s"><span class="pl-s"> sed <span class="pl-s"><span class="pl-pds">&quot;</span>s/\(\.\|,\|;\|\!<span class="pl-cce">\\</span>|\?\)$//;</span></span></span></td> + </tr> + <tr> + <td id="L9" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="9"></td> + <td id="LC9" class="blob-code blob-code-inner js-file-line"><span class="pl-s"><span class="pl-s"><span class="pl-s"> s/^www./http:\/\/www\./<span class="pl-pds">&quot;</span></span><span class="pl-pds">)</span></span><span class="pl-pds">&quot;</span></span> <span class="pl-c"><span class="pl-c">#</span> xdg-open will not detect url without http</span></td> + </tr> + <tr> + <td id="L10" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="10"></td> + <td id="LC10" class="blob-code blob-code-inner js-file-line"> +</td> + </tr> + <tr> + <td id="L11" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="11"></td> + <td id="LC11" class="blob-code blob-code-inner js-file-line">[ <span class="pl-k">-z</span> <span class="pl-s"><span class="pl-pds">&quot;</span><span class="pl-smi">$urls</span><span class="pl-pds">&quot;</span></span> ] <span class="pl-k">&amp;&amp;</span> <span class="pl-c1">exit</span> 1</td> + </tr> + <tr> + <td id="L12" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="12"></td> + <td id="LC12" class="blob-code blob-code-inner js-file-line"> +</td> + </tr> + <tr> + <td id="L13" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="13"></td> + <td id="LC13" class="blob-code blob-code-inner js-file-line"><span class="pl-k">while</span> <span class="pl-c1">getopts</span> <span class="pl-s"><span class="pl-pds">&quot;</span>hoc<span class="pl-pds">&quot;</span></span> o<span class="pl-k">;</span> <span class="pl-k">do</span> <span class="pl-k">case</span> <span class="pl-s"><span class="pl-pds">&quot;</span><span class="pl-smi">${o}</span><span class="pl-pds">&quot;</span></span> <span class="pl-k">in</span></td> + </tr> + <tr> + <td id="L14" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="14"></td> + <td id="LC14" class="blob-code blob-code-inner js-file-line"> h) <span class="pl-c1">printf</span> <span class="pl-s"><span class="pl-pds">&quot;</span>Optional arguments for custom use:<span class="pl-cce">\\</span>n -c: copy<span class="pl-cce">\\</span>n -o: xdg-open<span class="pl-cce">\\</span>n -h: Show this message<span class="pl-cce">\\</span>n<span class="pl-pds">&quot;</span></span> <span class="pl-k">&amp;&amp;</span> <span class="pl-c1">exit</span> 1 ;;</td> + </tr> + <tr> + <td id="L15" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="15"></td> + <td id="LC15" class="blob-code blob-code-inner js-file-line"> o) chosen=<span class="pl-s"><span class="pl-pds">&quot;</span><span class="pl-s"><span class="pl-pds">$(</span>echo <span class="pl-s"><span class="pl-pds">&quot;</span><span class="pl-smi">$urls</span><span class="pl-pds">&quot;</span></span> <span class="pl-k">|</span> dmenu -i -p <span class="pl-s"><span class="pl-pds">&#39;</span>Follow which url?<span class="pl-pds">&#39;</span></span> -l 10<span class="pl-pds">)</span></span><span class="pl-pds">&quot;</span></span></td> + </tr> + <tr> + <td id="L16" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="16"></td> + <td id="LC16" class="blob-code blob-code-inner js-file-line"> setsid xdg-open <span class="pl-s"><span class="pl-pds">&quot;</span><span class="pl-smi">$chosen</span><span class="pl-pds">&quot;</span></span> <span class="pl-k">&gt;</span>/dev/null <span class="pl-k">2&gt;&amp;1</span> <span class="pl-k">&amp;</span> ;;</td> + </tr> + <tr> + <td id="L17" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="17"></td> + <td id="LC17" class="blob-code blob-code-inner js-file-line"> c) <span class="pl-c1">echo</span> <span class="pl-s"><span class="pl-pds">&quot;</span><span class="pl-smi">$urls</span><span class="pl-pds">&quot;</span></span> <span class="pl-k">|</span> dmenu -i -p <span class="pl-s"><span class="pl-pds">&#39;</span>Copy which url?<span class="pl-pds">&#39;</span></span> -l 10 <span class="pl-k">|</span> tr -d <span class="pl-s"><span class="pl-pds">&#39;</span>\n<span class="pl-pds">&#39;</span></span> <span class="pl-k">|</span> xclip -selection clipboard ;;</td> + </tr> + <tr> + <td id="L18" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="18"></td> + <td id="LC18" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">*</span>) <span class="pl-c1">printf</span> <span class="pl-s"><span class="pl-pds">&quot;</span>Invalid option: -%s<span class="pl-cce">\\</span>n<span class="pl-pds">&quot;</span></span> <span class="pl-s"><span class="pl-pds">&quot;</span><span class="pl-smi">$OPTARG</span><span class="pl-pds">&quot;</span></span> <span class="pl-k">&amp;&amp;</span> <span class="pl-c1">exit</span> 1 ;;</td> + </tr> + <tr> + <td id="L19" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="19"></td> + <td id="LC19" class="blob-code blob-code-inner js-file-line"><span class="pl-k">esac</span> <span class="pl-k">done</span></td> + </tr> + </table> +</div> + + <details class="details-reset details-overlay BlobToolbar position-absolute js-file-line-actions dropdown d-none" aria-hidden="true"> + <summary class="btn-octicon ml-0 px-2 p-0 color-bg-default border color-border-default rounded-2" aria-label="Inline file action toolbar"> + <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-kebab-horizontal"> + <path d="M8 9a1.5 1.5 0 100-3 1.5 1.5 0 000 3zM1.5 9a1.5 1.5 0 100-3 1.5 1.5 0 000 3zm13 0a1.5 1.5 0 100-3 1.5 1.5 0 000 3z"></path> +</svg> + </summary> + <details-menu> + + <ul class="BlobToolbar-dropdown dropdown-menu dropdown-menu-se ml-2 mt-2" + style="width:185px" + > + <li> + <clipboard-copy role="menuitem" class="dropdown-item" id="js-copy-lines" style="cursor:pointer;" aria-label="Copy lines"> + Copy lines + </clipboard-copy> + </li> + <li> + <clipboard-copy role="menuitem" class="dropdown-item" id="js-copy-permalink" style="cursor:pointer;" aria-label="Copy permalink"> + Copy permalink + </clipboard-copy> + </li> + <li><a class="dropdown-item js-update-url-with-hash" id="js-view-git-blame" role="menuitem" href="/LukeSmithxyz/st/blame/3144a61c180b678f6b1c23f06e4b434090199fcb/st-urlhandler">View git blame</a></li> + <li><a class="dropdown-item" id="js-new-issue" role="menuitem" href="/LukeSmithxyz/st/issues/new">Reference in new issue</a></li> + </ul> + </details-menu> + </details> + + </div> + + </div> + + + + + <details class="details-reset details-overlay details-overlay-dark" id="jumpto-line-details-dialog"> + <summary data-hotkey="l" aria-label="Jump to line"></summary> + <details-dialog class="Box Box--overlay d-flex flex-column anim-fade-in fast linejump" aria-label="Jump to line"> + <!-- '"` --><!-- </textarea></xmp> --></option></form><form class="js-jump-to-line-form Box-body d-flex" data-turbo="false" action="" accept-charset="UTF-8" method="get"> + <input class="form-control flex-auto mr-3 linejump-input js-jump-to-line-field" type="text" placeholder="Jump to line&hellip;" aria-label="Jump to line" autofocus> + <button data-close-dialog="" type="submit" data-view-component="true" class="btn"> Go + +</button> +</form> </details-dialog> + </details> + + +</div> + + </div> + + +</div> + + + </main> + </div> + + </div> + + <footer class="footer width-full container-xl p-responsive" role="contentinfo"> + + + <div class="position-relative d-flex flex-items-center pb-2 f6 color-fg-muted border-top color-border-muted flex-column-reverse flex-lg-row flex-wrap flex-lg-nowrap mt-6 pt-6"> + <ul class="list-style-none d-flex flex-wrap col-0 col-lg-2 flex-justify-start flex-lg-justify-between mb-2 mb-lg-0"> + <li class="mt-2 mt-lg-0 d-flex flex-items-center"> + <a aria-label="Homepage" title="GitHub" class="footer-octicon mr-2" href="https://github.com"> + <svg aria-hidden="true" height="24" viewBox="0 0 16 16" version="1.1" width="24" data-view-component="true" class="octicon octicon-mark-github"> + <path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"></path> +</svg> +</a> <span> + &copy; 2022 GitHub, Inc. + </span> + </li> + </ul> + <ul class="list-style-none d-flex flex-wrap col-12 col-lg-8 flex-justify-center flex-lg-justify-between mb-2 mb-lg-0"> + <li class="mr-3 mr-lg-0"><a href="https://docs.github.com/en/github/site-policy/github-terms-of-service" data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to terms&quot;,&quot;label&quot;:&quot;text:terms&quot;}">Terms</a></li> + <li class="mr-3 mr-lg-0"><a href="https://docs.github.com/en/github/site-policy/github-privacy-statement" data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to privacy&quot;,&quot;label&quot;:&quot;text:privacy&quot;}">Privacy</a></li> + <li class="mr-3 mr-lg-0"><a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to security&quot;,&quot;label&quot;:&quot;text:security&quot;}" href="https://github.com/security">Security</a></li> + <li class="mr-3 mr-lg-0"><a href="https://www.githubstatus.com/" data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to status&quot;,&quot;label&quot;:&quot;text:status&quot;}">Status</a></li> + <li class="mr-3 mr-lg-0"><a data-ga-click="Footer, go to help, text:Docs" href="https://docs.github.com">Docs</a></li> + <li class="mr-3 mr-lg-0"><a href="https://support.github.com?tags=dotcom-footer" data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to contact&quot;,&quot;label&quot;:&quot;text:contact&quot;}">Contact GitHub</a></li> + <li class="mr-3 mr-lg-0"><a href="https://github.com/pricing" data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to Pricing&quot;,&quot;label&quot;:&quot;text:Pricing&quot;}">Pricing</a></li> + <li class="mr-3 mr-lg-0"><a href="https://docs.github.com" data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to api&quot;,&quot;label&quot;:&quot;text:api&quot;}">API</a></li> + <li class="mr-3 mr-lg-0"><a href="https://services.github.com" data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to training&quot;,&quot;label&quot;:&quot;text:training&quot;}">Training</a></li> + <li class="mr-3 mr-lg-0"><a href="https://github.blog" data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to blog&quot;,&quot;label&quot;:&quot;text:blog&quot;}">Blog</a></li> + <li><a data-ga-click="Footer, go to about, text:about" href="https://github.com/about">About</a></li> + </ul> + </div> + <div class="d-flex flex-justify-center pb-6"> + <span class="f6 color-fg-muted"></span> + </div> +</footer> + + + + + <div id="ajax-error-message" class="ajax-error-message flash flash-error" hidden> + <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert"> + <path fill-rule="evenodd" d="M8.22 1.754a.25.25 0 00-.44 0L1.698 13.132a.25.25 0 00.22.368h12.164a.25.25 0 00.22-.368L8.22 1.754zm-1.763-.707c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0114.082 15H1.918a1.75 1.75 0 01-1.543-2.575L6.457 1.047zM9 11a1 1 0 11-2 0 1 1 0 012 0zm-.25-5.25a.75.75 0 00-1.5 0v2.5a.75.75 0 001.5 0v-2.5z"></path> +</svg> + <button type="button" class="flash-close js-ajax-error-dismiss" aria-label="Dismiss error"> + <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x"> + <path fill-rule="evenodd" d="M3.72 3.72a.75.75 0 011.06 0L8 6.94l3.22-3.22a.75.75 0 111.06 1.06L9.06 8l3.22 3.22a.75.75 0 11-1.06 1.06L8 9.06l-3.22 3.22a.75.75 0 01-1.06-1.06L6.94 8 3.72 4.78a.75.75 0 010-1.06z"></path> +</svg> + </button> + You can’t perform that action at this time. + </div> + + <div class="js-stale-session-flash flash flash-warn flash-banner" hidden + > + <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert"> + <path fill-rule="evenodd" d="M8.22 1.754a.25.25 0 00-.44 0L1.698 13.132a.25.25 0 00.22.368h12.164a.25.25 0 00.22-.368L8.22 1.754zm-1.763-.707c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0114.082 15H1.918a1.75 1.75 0 01-1.543-2.575L6.457 1.047zM9 11a1 1 0 11-2 0 1 1 0 012 0zm-.25-5.25a.75.75 0 00-1.5 0v2.5a.75.75 0 001.5 0v-2.5z"></path> +</svg> + <span class="js-stale-session-flash-signed-in" hidden>You signed in with another tab or window. <a href="">Reload</a> to refresh your session.</span> + <span class="js-stale-session-flash-signed-out" hidden>You signed out in another tab or window. <a href="">Reload</a> to refresh your session.</span> + </div> + <template id="site-details-dialog"> + <details class="details-reset details-overlay details-overlay-dark lh-default color-fg-default hx_rsm" open> + <summary role="button" aria-label="Close dialog"></summary> + <details-dialog class="Box Box--overlay d-flex flex-column anim-fade-in fast hx_rsm-dialog hx_rsm-modal"> + <button class="Box-btn-octicon m-0 btn-octicon position-absolute right-0 top-0" type="button" aria-label="Close dialog" data-close-dialog> + <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x"> + <path fill-rule="evenodd" d="M3.72 3.72a.75.75 0 011.06 0L8 6.94l3.22-3.22a.75.75 0 111.06 1.06L9.06 8l3.22 3.22a.75.75 0 11-1.06 1.06L8 9.06l-3.22 3.22a.75.75 0 01-1.06-1.06L6.94 8 3.72 4.78a.75.75 0 010-1.06z"></path> +</svg> + </button> + <div class="octocat-spinner my-6 js-details-dialog-spinner"></div> + </details-dialog> + </details> +</template> + + <div class="Popover js-hovercard-content position-absolute" style="display: none; outline: none;" tabindex="0"> + <div class="Popover-message Popover-message--bottom-left Popover-message--large Box color-shadow-large" style="width:360px;"> + </div> +</div> + + <template id="snippet-clipboard-copy-button"> + <div class="zeroclipboard-container position-absolute right-0 top-0"> + <clipboard-copy aria-label="Copy" class="ClipboardButton btn js-clipboard-copy m-2 p-0 tooltipped-no-delay" data-copy-feedback="Copied!" data-tooltip-direction="w"> + <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon m-2"> + <path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path> +</svg> + <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check js-clipboard-check-icon color-fg-success d-none m-2"> + <path fill-rule="evenodd" d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"></path> +</svg> + </clipboard-copy> + </div> +</template> + + + + + </body> +</html> + diff --git a/st.c b/st.c @@ -51,6 +51,8 @@ term.scr + HISTSIZE + 1) % HISTSIZE] : \ term.line[(y) - term.scr]) +#define TLINE_HIST(y) ((y) <= HISTSIZE-term.row+2 ? term.hist[(y)] : term.line[(y-HISTSIZE+term.row-3)]) + #define TLINEABS(y) ((y) < 0 ? term.hist[(term.histi + (y) \ + 1 + HISTSIZE) % HISTSIZE] : term.line[(y)]) @@ -487,6 +489,20 @@ tgetline(char *buf, const Glyph *fgp) return ptr - buf; } +int +tlinehistlen(int y) +{ + int i = term.col; + + if (TLINE_HIST(y)[i - 1].mode & ATTR_WRAP) + return i; + + while (i > 0 && TLINE_HIST(y)[i - 1].u == ' ') + --i; + + return i; +} + void selstart(int col, int row, int snap) { @@ -791,8 +807,14 @@ sigchld(int a) if ((p = waitpid(pid, &stat, WNOHANG)) < 0) die("waiting for pid %hd failed: %s\n", pid, strerror(errno)); - if (pid != p) + if (pid != p) { + if (p == 0 && wait(&stat) < 0) + die("wait: %s\n", strerror(errno)); + + /* reinstall sigchld handler */ + signal(SIGCHLD, sigchld); return; + } if (WIFEXITED(stat) && WEXITSTATUS(stat)) die("child exited with status %d\n", WEXITSTATUS(stat)); @@ -1936,7 +1958,7 @@ csihandle(void) } /* vte does this: tscrollup(0, term.row-1, term.row, SCROLL_SAVEHIST); */ - + /* alacritty does this: */ for (n = term.row-1; n >= 0 && tlinelen(term.line[n]) == 0; n--); if (n >= 0) @@ -2245,6 +2267,61 @@ strparse(void) } void +externalpipe(const Arg *arg) +{ + int to[2]; + char buf[UTF_SIZ]; + void (*oldsigpipe)(int); + Glyph *bp, *end; + int lastpos, n, newline; + + if (pipe(to) == -1) + return; + + switch (fork()) { + case -1: + close(to[0]); + close(to[1]); + return; + case 0: + dup2(to[0], STDIN_FILENO); + close(to[0]); + close(to[1]); + execvp(((char **)arg->v)[0], (char **)arg->v); + fprintf(stderr, "st: execvp %s\n", ((char **)arg->v)[0]); + perror("failed"); + exit(0); + } + + close(to[0]); + /* ignore sigpipe for now, in case child exists early */ + oldsigpipe = signal(SIGPIPE, SIG_IGN); + newline = 0; + for (n = 0; n <= HISTSIZE + 2; n++) { + bp = TLINE_HIST(n); + lastpos = MIN(tlinehistlen(n) + 1, term.col) - 1; + if (lastpos < 0) + break; + if (lastpos == 0) + continue; + end = &bp[lastpos + 1]; + for (; bp < end; ++bp) + if (xwrite(to[1], buf, utf8encode(bp->u, buf)) < 0) + break; + if ((newline = TLINE_HIST(n)[lastpos].mode & ATTR_WRAP)) + continue; + if (xwrite(to[1], "\n", 1) < 0) + break; + newline = 0; + } + if (newline) + (void)xwrite(to[1], "\n", 1); + close(to[1]); + /* restore */ + signal(SIGPIPE, oldsigpipe); +} + +void strdump(void) { size_t i; @@ -3102,3 +3179,4 @@ redraw(void) tfulldirt(); draw(); } + diff --git a/st.h b/st.h @@ -84,6 +84,7 @@ void redraw(void); void tfulldirt(void); void draw(void); +void externalpipe(const Arg *); void kscrolldown(const Arg *); void kscrollup(const Arg *); void printscreen(const Arg *); @@ -133,3 +134,4 @@ extern unsigned int defaultfg; extern unsigned int defaultbg; extern unsigned int defaultcs; extern float alpha, alphaUnfocused; + diff --git a/x.c b/x.c @@ -82,6 +82,7 @@ typedef XftGlyphFontSpec GlyphFontSpec; typedef struct { int tw, th; /* tty width and height */ int w, h; /* window width and height */ + int hborderpx, vborderpx; int ch; /* char height */ int cw; /* char width */ int mode; /* window state/mode flags */ @@ -345,7 +346,7 @@ ttysend(const Arg *arg) int evcol(XEvent *e) { - int x = e->xbutton.x - borderpx; + int x = e->xbutton.x - win.hborderpx; LIMIT(x, 0, win.tw - 1); return x / win.cw; } @@ -353,7 +354,7 @@ evcol(XEvent *e) int evrow(XEvent *e) { - int y = e->xbutton.y - borderpx; + int y = e->xbutton.y - win.vborderpx; LIMIT(y, 0, win.th - 1); return y / win.ch; } @@ -760,6 +761,9 @@ cresize(int width, int height) col = MAX(1, col); row = MAX(1, row); + win.hborderpx = (win.w - col * win.cw) / 2; + win.vborderpx = (win.h - row * win.ch) / 2; + tresize(col, row); xresize(col, row); ttyresize(win.tw, win.th); @@ -900,8 +904,8 @@ xhints(void) sizeh->flags = PSize | PResizeInc | PBaseSize | PMinSize; sizeh->height = win.h; sizeh->width = win.w; - sizeh->height_inc = win.ch; - sizeh->width_inc = win.cw; + sizeh->height_inc = 1; + sizeh->width_inc = 1; sizeh->base_height = 2 * borderpx; sizeh->base_width = 2 * borderpx; sizeh->min_height = win.ch + 2 * borderpx; @@ -1086,7 +1090,7 @@ xloadsparefont(FcPattern *pattern, int flags) { FcPattern *match; FcResult result; - + match = FcFontMatch(NULL, pattern, &result); if (!match) { return 1; @@ -1128,50 +1132,50 @@ xloadsparefonts(void) } for (fp = font2; fp - font2 < fc; ++fp) { - + if (**fp == '-') pattern = XftXlfdParse(*fp, False, False); else pattern = FcNameParse((FcChar8 *)*fp); - + if (!pattern) die("can't open spare font %s\n", *fp); - + if (defaultfontsize > 0) { sizeshift = usedfontsize - defaultfontsize; if (sizeshift != 0 && FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &fontval) == - FcResultMatch) { + FcResultMatch) { fontval += sizeshift; FcPatternDel(pattern, FC_PIXEL_SIZE); FcPatternDel(pattern, FC_SIZE); FcPatternAddDouble(pattern, FC_PIXEL_SIZE, fontval); } } - + FcPatternAddBool(pattern, FC_SCALABLE, 1); - + FcConfigSubstitute(NULL, pattern, FcMatchPattern); XftDefaultSubstitute(xw.dpy, xw.scr, pattern); - + if (xloadsparefont(pattern, FRC_NORMAL)) die("can't open spare font %s\n", *fp); - + FcPatternDel(pattern, FC_SLANT); FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC); if (xloadsparefont(pattern, FRC_ITALIC)) die("can't open spare font %s\n", *fp); - + FcPatternDel(pattern, FC_WEIGHT); FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD); if (xloadsparefont(pattern, FRC_ITALICBOLD)) die("can't open spare font %s\n", *fp); - + FcPatternDel(pattern, FC_SLANT); FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN); if (xloadsparefont(pattern, FRC_BOLD)) die("can't open spare font %s\n", *fp); - + FcPatternDestroy(pattern); } } @@ -1293,8 +1297,8 @@ xinit(int cols, int rows) xloadcols(); /* adjust fixed window geometry */ - win.w = 2 * borderpx + cols * win.cw; - win.h = 2 * borderpx + rows * win.ch; + win.w = 2 * win.hborderpx + 2 * borderpx + cols * win.cw; + win.h = 2 * win.vborderpx + 2 * borderpx + rows * win.ch; if (xw.gm & XNegative) xw.l += DisplayWidth(xw.dpy, xw.scr) - win.w - 2; if (xw.gm & YNegative) @@ -1383,7 +1387,7 @@ xinit(int cols, int rows) int xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y) { - float winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, xp, yp; + float winx = win.hborderpx + x * win.cw, winy = win.vborderpx + y * win.ch, xp, yp; ushort mode, prevmode = USHRT_MAX; Font *font = &dc.font; int frcflags = FRC_NORMAL; @@ -1516,7 +1520,7 @@ void xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y) { int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1); - int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, + int winx = win.hborderpx + x * win.cw, winy = win.vborderpx + y * win.ch, width = charlen * win.cw; Color *fg, *bg, *temp, revfg, revbg, truefg, truebg; XRenderColor colfg, colbg; @@ -1606,17 +1610,17 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i /* Intelligent cleaning up of the borders. */ if (x == 0) { - xclear(0, (y == 0)? 0 : winy, borderpx, + xclear(0, (y == 0)? 0 : winy, win.vborderpx, winy + win.ch + - ((winy + win.ch >= borderpx + win.th)? win.h : 0)); + ((winy + win.ch >= win.vborderpx + win.th)? win.h : 0)); } - if (winx + width >= borderpx + win.tw) { + if (winx + width >= win.hborderpx + win.tw) { xclear(winx + width, (y == 0)? 0 : winy, win.w, - ((winy + win.ch >= borderpx + win.th)? win.h : (winy + win.ch))); + ((winy + win.ch >= win.vborderpx + win.th)? win.h : (winy + win.ch))); } if (y == 0) - xclear(winx, 0, winx + width, borderpx); - if (winy + win.ch >= borderpx + win.th) + xclear(winx, 0, winx + width, win.vborderpx); + if (winy + win.ch >= win.vborderpx + win.th) xclear(winx, winy + win.ch, winx + width, win.h); /* Clean up the region we want to draw to. */ @@ -1729,8 +1733,8 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) /* FALLTHROUGH */ case 4: /* steady underline */ XftDrawRect(xw.draw, &drawcol, - borderpx + cx * win.cw, - borderpx + (cy + 1) * win.ch - \ + win.hborderpx + cx * win.cw, + win.vborderpx + (cy + 1) * win.ch - \ cursorthickness, win.cw, cursorthickness); break; @@ -1740,8 +1744,8 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) /* FALLTHROUGH */ case 6: /* steady bar */ XftDrawRect(xw.draw, &drawcol, - borderpx + cx * win.cw, - borderpx + cy * win.ch, + win.hborderpx + cx * win.cw, + win.vborderpx + cy * win.ch, cursorthickness, win.ch); break; case 7: /* blinking st cursor */ @@ -1755,20 +1759,20 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) } } else { XftDrawRect(xw.draw, &drawcol, - borderpx + cx * win.cw, - borderpx + cy * win.ch, + win.hborderpx + cx * win.cw, + win.vborderpx + cy * win.ch, win.cw - 1, 1); XftDrawRect(xw.draw, &drawcol, - borderpx + cx * win.cw, - borderpx + cy * win.ch, + win.hborderpx + cx * win.cw, + win.vborderpx + cy * win.ch, 1, win.ch - 1); XftDrawRect(xw.draw, &drawcol, - borderpx + (cx + 1) * win.cw - 1, - borderpx + cy * win.ch, + win.hborderpx + (cx + 1) * win.cw - 1, + win.vborderpx + cy * win.ch, 1, win.ch - 1); XftDrawRect(xw.draw, &drawcol, - borderpx + cx * win.cw, - borderpx + (cy + 1) * win.ch - 1, + win.hborderpx + cx * win.cw, + win.vborderpx + (cy + 1) * win.ch - 1, win.cw, 1); } } @@ -2420,3 +2424,4 @@ run: return 0; } +