Handcrafted theme for those who have not found syntax highlighting useful for themself.
body {
height: 100vh;
margin: 0;
}
.person, .person::before, .person::after, .person *, .person *::after, .person *::before {
position: absolute;
content: '';
}
.grid {
height: 100%;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
.portrait {
position: relative;
overflow: hidden;
--black: #00202a;
--grey: #003444;
--light-grey: #547d8f;
--white: #f8f8f8;
--blue: #2348cd;
--dark-blue: #013344;
--light-blue: #0ef3bd;
--skin: #f77676;
--dark-skin: #cc3c40;
--light-skin: #f3af9f;
--yellow: #f6d359;
--dark-yellow: #e9a964;
--red: #f44d5f;
--dark-red: #cc3040;
--light-red: #eab1ae;
}
.portrait:nth-child(1) {
background-color: #fcd2c7;
}
.portrait:nth-child(2) {
background-color: #fcf8db;
}
.portrait:nth-child(3) {
background-color: #f8e8d9;
}
/* LEFT PERSON */
/* neck */
.person_left {
top: 50%; left: 50%;
width: 88px; height: 276px;
background: linear-gradient(86deg, var(--light-skin) 90%, transparent 91%);
translate: -42px -100px;
--animation: 6s ease infinite;
}
/* body */
.person_left::before {
top: 147px; left: -106px;
width: 313px; height: 129px;
background:
/* dark lines */
linear-gradient(-8deg, transparent 108px, var(--dark-red) 109px, var(--dark-red) 110px, transparent 111px) 198px 0 no-repeat,
linear-gradient(-39deg, transparent 60px, var(--dark-red) 61px, var(--dark-red) 62px, transparent 63px),
linear-gradient(-102deg, transparent 74px, var(--dark-red) 75px, var(--dark-red) 76px, transparent 77px),
linear-gradient(-80deg, transparent 106px, var(--dark-red) 107px, var(--dark-red) 108px, transparent 109px),
/* armpit */
conic-gradient(from 3rad, var(--red) 22deg, transparent 0) 25px 49px / 50px 80px no-repeat,
/* coat */
linear-gradient(-79deg, var(--red) 126px, transparent 11px),
/* light lines */
linear-gradient(-8deg, transparent 97px, var(--light-red) 98px, var(--light-red) 99px, transparent 100px),
linear-gradient(108deg, transparent 149px, var(--light-red) 150px, var(--light-red) 151px, transparent 152px) 0 9px no-repeat,
/* shirt */
linear-gradient(-15deg, var(--white) 155px, transparent 125px),
var(--light-skin);
-webkit-mask-image: conic-gradient(from 126deg at 50% -21%, black 109deg, transparent 0);
}
/* top of the head */
.person_left .person__head {
top: -62px; left: 24px;
width: 74px; height: 74px;
background: var(--light-skin);
border-radius: 50%;
transform-origin: bottom center;
animation: leftPersonHead var(--animation);
}
@keyframes leftPersonHead {
0%, 18%, 85%, 100% { rotate: 0deg; }
23% { rotate: -5deg; }
35%, 75% { rotate: 10deg; }
}
/* ear */
.person_left .person__head::before {
top: 37px; left: -78px;
width: 20px; height: 21px;
background: var(--dark-skin);
border-radius: 13px 0 0 0;
transform-origin: top left;
transform: skewX(41deg);
}
/* brows */
.person_left .person__head::after {
top: 24px; left: -64px;
width: 87px; height: 13px;
background:
/* light lines */
linear-gradient(0deg, var(--light-grey) 2px, transparent 3px) 0 0 / 28px 7px no-repeat,
linear-gradient(0deg, var(--light-grey) 2px, transparent 3px) 46px 0 / 41px 7px no-repeat,
/* brows */
linear-gradient(100deg, var(--grey) 31px, transparent 3px) 5px 0 / 32px 100% no-repeat,
linear-gradient(var(--grey) 100%, transparent 3px) 50px 0 / 32px 100% no-repeat;
animation: leftPersonBrows var(--animation);
}
@keyframes leftPersonBrows {
0%, 18%, 85%, 100% { translate: 0; }
23% { translate: 0 5px; }
26%, 75% { translate: 0 -3px; }
}
/* beard */
.person_left .person__beard {
top: 64px; left: -76px;
width: 131px; height: 153px;
background:
/* shadows */
conic-gradient(from 0.2rad at 13% 41%, var(--black) 7%, transparent calc(7% + 0.2%)),
conic-gradient(from -1rad at 93% 36%, var(--black) 14%, transparent calc(14% + 0.2%)),
/* beard shape */
linear-gradient(284deg, var(--grey) 77%, transparent 0) 0 0 / 100px 100% no-repeat,
linear-gradient(83deg, var(--grey) 62.7%, transparent 0) 40px 0 no-repeat;
border-radius: 0 0 15px 24px;
transform-origin: top left;
animation: leftPersonBeard var(--animation);
}
@keyframes leftPersonBeard {
0%, 25%, 85%, 100% { rotate: 7deg; }
35%, 75% { rotate: 0deg; }
}
.person_left .person__beard::before {
top: 42px; left: 31px;
width: 55px; height: 27px;
background:
/* lips */
linear-gradient(-16deg, transparent 18px, var(--dark-skin) 18px, var(--dark-skin) 19px, transparent 20px) 8px 0 / 38px 100% no-repeat,
/* shadows */
conic-gradient(from 190deg at 60% 41%, var(--skin) 18%, transparent 0),
linear-gradient(107deg, var(--skin) 35%, transparent calc(35% + 1px)),
/* skin */
linear-gradient(58deg, var(--light-skin) 81%, transparent calc(81% + 1px));
transform-origin: top left;
border-radius: 0 0 5px 6px;
-webkit-mask-image: conic-gradient(from 83deg at 14% 15%, black 34%, transparent 0);
animation: leftPersonLips var(--animation);
}
@keyframes leftPersonLips {
0%, 25%, 85%, 100% { rotate: -14deg; translate: 0; }
35%, 75% { rotate: -18deg; translate: 0 7px; }
}
/* beard lines */
.person_left .person__beard::after {
top: 0px; left: 0px;
width: 100%; height: 162px;
background:
linear-gradient(79deg, transparent 111px, var(--light-grey) 111px, var(--light-grey) 113px, transparent 113px) 0px 53px / 100% 71px no-repeat,
linear-gradient(87deg, transparent 82px, var(--light-grey) 82px, var(--light-grey) 84px, transparent 84px) 0px 88px / 100% 74px no-repeat,
linear-gradient(89deg, transparent 62px, var(--light-grey) 62px, var(--light-grey) 64px, transparent 64px) 0px 70px / 100% 24px no-repeat,
linear-gradient(95deg, transparent 48px, var(--light-grey) 48px, var(--light-grey) 50px, transparent 50px) 0px 82px / 100% 54px no-repeat,
linear-gradient(97deg, transparent 26px, var(--light-grey) 26px, var(--light-grey) 28px, transparent 28px) 0px 64px / 100% 96px no-repeat;
}
.person_left .person__face {
top: 46px; left: -3px;
width: 50px; height: 45px;
background:
/* undereye circle */
linear-gradient(157deg, transparent 27px, var(--skin) 28px, var(--skin) 29px, transparent 30px) 0 0 / 37px 100% no-repeat,
/* background */
var(--light-skin);
border-radius: 0 0 8px;
transform-origin: top left;
rotate: 23deg;
}
/* nose */
.person_left .person__face::before {
top: 2px; left: -58px;
width: 80px; height: 82px;
background:
/* undereye circle */
linear-gradient(194deg, transparent 55px, var(--dark-skin) 56px, var(--dark-skin) 57px, transparent 58px) 0px 0px / 18px 100% no-repeat,
/* shadows */
linear-gradient(5deg, var(--skin) 24%, transparent calc(22% + 1px)) 0 0 / 40px 100% no-repeat,
linear-gradient(93deg, var(--skin) 33%, transparent calc(33% + 1px)) 0px 9px no-repeat,
/* skin */
linear-gradient(104deg, var(--light-skin) 73px, transparent 74px);
transform-origin: top left;
border-radius: 0 0 0 9px;
rotate: -15deg;
transform: skewY(-23deg);
}
/* eyes */
.person_left .person__face::after {
top: 27px; left: -38px;
width: 8px; height: 8px;
background: var(--grey);
border-radius: 50%;
box-shadow: 46px 0 var(--grey);
rotate: -23deg;
animation: leftPersonEyes var(--animation);
}
@keyframes leftPersonEyes {
0%, 20%, 26%, 100% { scale: 1; }
23% { scale: 1 0.1; }
}
/* CENTER PERSON */
/* body */
.person_center {
top: 50%; left: 50%;
width: 200px; height: 100px;
background:
/* collarbone */
linear-gradient(var(--skin), var(--skin)) 45px 35px / 95px 2px no-repeat,
/* skin */
radial-gradient(var(--light-skin) 70%, transparent 0) 0 -50px / 100% 130% no-repeat;
border-radius: 50%;
translate: -90px 60px;
--animation: 6s ease infinite;
}
/* neck */
.person_center::before {
top: -90px; left: 60px;
width: 80px; height: 100px;
background:
linear-gradient(140deg, var(--skin) 50%, transparent calc(50% + 1px)) no-repeat,
var(--light-skin);
-webkit-mask-image: linear-gradient(80deg, black 80%, transparent calc(80% + 1px));
animation: centerPersonNeck var(--animation);
}
@keyframes centerPersonNeck {
0%, 20%, 80%, 100% { background-position: 0 0; }
30% { background-position: 0 7px; }
40%, 70% { background-position: 0 -5px; }
}
/* ear and hair */
.person_center .person__head {
top: -145px; left: 5px;
width: 50px; height: 50px;
background: var(--dark-skin);
border-radius: 50%;
box-shadow:
/* ear */
135px 0 var(--light-skin),
/* front hair */
120px -40px 0 10px var(--yellow),
80px -60px var(--yellow),
30px -100px 0 15px var(--yellow),
/* back hair */
25px -50px 0 10px var(--dark-yellow),
80px -70px 0 10px var(--dark-yellow);
animation: centerPersonHead var(--animation),
centerPersonHair var(--animation);
}
@keyframes centerPersonHead {
0%, 20%, 80%, 100% { translate: 0 0; }
30% { translate: -2px 10px; }
40%, 70% { translate: -2px -7px; }
}
@keyframes centerPersonHair {
0%, 30%, 80%, 100% {
box-shadow:
/* ear */
135px 0 var(--light-skin),
/* front hair */
120px -40px 0 10px var(--yellow),
80px -60px var(--yellow),
30px -100px 0 15px var(--yellow),
/* back hair */
25px -50px 0 10px var(--dark-yellow),
80px -70px 0 10px var(--dark-yellow);
}
40%, 70% {
box-shadow:
/* ear */
130px 0 var(--light-skin),
/* front hair */
120px -30px 0 10px var(--yellow),
85px -55px var(--yellow),
33px -100px 0 15px var(--yellow),
/* back hair */
20px -45px 0 10px var(--dark-yellow),
75px -55px 0 10px var(--dark-yellow);
}
}
/* head */
.person_center .person__head::before {
top: -30px; left: 25px;
width: 130px; aspect-ratio: 1/1;
background:
/* hair */
linear-gradient(-150deg, var(--yellow) 29%, transparent 0) no-repeat,
/* nose */
linear-gradient(100deg, var(--skin) 45%, transparent calc(45% + 1px)) 0 70px no-repeat,
linear-gradient(100deg, var(--skin) 45%, transparent calc(45% + 1px)) no-repeat,
/* skin */
var(--light-skin);
border-radius: 50%;
animation: centerPersonFace var(--animation),
centerPersonNose var(--animation);
}
@keyframes centerPersonFace {
0%, 30%, 80%, 100% { translate: 0 0; }
40%, 70% { translate: 4px 0; }
}
@keyframes centerPersonNose {
0%, 20%, 80%, 100% {
background-position: 0 0, -13px 70px, -13px 0, 0 0;
}
30% {
background-position: 0 0, -13px 75px, -13px 5px, 0 0;
}
40%, 70% {
background-position: 0 0, -5px 70px, -5px 0, 0 0;
}
}
/* smile */
.person_center .person__head::after {
top: 45px; left: 40px;
width: 60px; height: 23px;
border-radius: 0 0 50% 50%;
box-shadow: inset 0 -13px 0 -10px var(--dark-skin);
animation: centerPersonSmile var(--animation)
}
@keyframes centerPersonSmile {
0%, 20%, 80%, 100% {
transform: translate(0, 0) scale(1) rotate(0);
}
30% {
transform: translate(0px, 5px) scale(1) rotate(0deg);
}
40%, 70% {
transform: translate(15px, -5px) scale(0.8) rotate(-15deg);
}
}
/* eyes */
.person_center .person__face {
top: 15px; left: 35px;
width: 8px; aspect-ratio: 1/1;
background: var(--black);
border-radius: 50%;
box-shadow: 65px 0 var(--black);
animation: centerPersonEyes var(--animation);
}
@keyframes centerPersonEyes {
0%, 20%, 80%, 100% { translate: 0 0; }
30% { translate: 2px 5px; }
40%, 70% { translate: 15px -10px; }
}
/* hair */
.person_center .person__face::before {
top: -85px; left: -20px;
width: 330px; height: 120px;
border-radius: 0 0 0 100%;
box-shadow: inset 120px 0 0 -50px var(--yellow);
animation: centerPersonForelock var(--animation);
}
@keyframes centerPersonForelock {
0%, 20%, 80%, 100% { translate: 0 0; }
30% { translate: 0 -5px; }
40%, 70% { translate: -12px -2px; }
}
/* glasses */
.person_center .person__face::after {
top: -25px; left: -28px;
width: 60px; aspect-ratio: 1/1;
border: 2px solid var(--blue);
border-radius: 50%;
filter: drop-shadow(75px 0 var(--blue));
animation: centerPersonGlasses var(--animation);
}
@keyframes centerPersonGlasses {
0%, 30%, 80%, 100% { translate: 0 0; }
40%, 70% { translate: -5px 5px; }
}
/* RIGHT PERSON */
/* coat */
.person_right {
top: 50%; left: 50%;
width: 224px; height: 69px;
background:
/* line */
linear-gradient(125deg, transparent 120px, var(--light-blue) 121px, var(--light-blue) 122px, transparent 123px) 0 21px no-repeat,
/* fabric */
conic-gradient(from 141deg at 75% 0%, var(--blue) 107deg, transparent 0);
translate: -85px 60px;
--animation-slow: 6s ease infinite;
--animation-fast: 1.5s ease infinite;
}
/* collar */
.person_right::before {
top: 68px; left: -1px;
width: 198px; height: 51px;
background: linear-gradient(196deg, var(--white) 54%, transparent 0);
border-radius: 0 20px 31px 0;
transform-origin: top left;
rotate: -38deg;
z-index: 1;
}
/* line */
.person_right::after {
top: 42px; left: 46px;
width: 154px; height: 2px;
background: var(--light-red);
transform-origin: top left;
rotate: -28deg;
z-index: 1;
}
/* neck */
.person_right .person__neck {
top: -94px; right: 126px;
width: 104px; height: 87px;
background:
/* line */
linear-gradient(120deg, transparent calc(55% - 1px), var(--dark-skin) 55%, var(--dark-skin) calc(55% + 1px), transparent calc(55% + 2px)) 0 9px / 100% 63px no-repeat,
/* skin */
conic-gradient(from 20deg at 13% 58%, var(--dark-skin) 8%, var(--skin) 8% 50%, transparent 0);
transform-origin: top right;
rotate: -30deg;
animation: rightPersonNeck var(--animation-fast);
}
@keyframes rightPersonNeck {
0%, 100% {
background-position: 0 9px, 0 0;
}
50% {
background-position: 0 9px, 0 8px;
}
}
/* hair */
.person_right .person__neck::before {
top: -177px; left: 38px;
width: 110px; height: 110px;
background: var(--dark-blue);
border-radius: 50%;
box-shadow: inset 5px 40px 0 -10px var(--blue);
animation: rightPersonHair var(--animation-fast);
animation-delay: 0.08s;
}
@keyframes rightPersonHair {
0%, 100% { translate: 0 0; }
50% { translate: -15px 8px; }
}
/* ear */
.person_right .person__neck::after {
top: -39px; left: 89px;
width: 48px; height: 48px;
background:
/* pinna */
conic-gradient(from 180deg, var(--skin) 90deg, transparent 0),
radial-gradient(transparent 8px, var(--dark-skin) 9px, var(--dark-skin) 10px, transparent 11px),
/* skin */
linear-gradient(90deg, var(--skin) 59%, var(--light-skin) calc(59% + 1px));
border-radius: 50%;
rotate: 30deg;
}
/* head */
.person_right .person__head {
top: -114px; left: -17px;
width: 150px; height: 106px;
/* shadow */
background: radial-gradient(circle, var(--skin) 70%, transparent 0) -11px 59px / 160px 160px no-repeat, var(--light-skin);
border-radius: 60% 40% 20% 20% / 70% 70% 20% 20%;
transform-origin: bottom right;
animation: rightPersonHead var(--animation-fast);
}
@keyframes rightPersonHead {
0%, 100% {
rotate: -15deg;
translate: -3px 3px;
}
50% {
rotate: -20deg;
translate: 0 0;
}
}
/* hair */
.person_right .person__head::before {
top: 42px; left: 82px;
width: 76px; height: 71px;
background:
/* line */
linear-gradient(93deg, transparent 63px, var(--blue) 64px, var(--blue) 65px, transparent 66px) 0 0 / 100% 57px no-repeat,
/* hair */
conic-gradient(from 59deg at 2% 60%, var(--dark-blue) 63deg, transparent 64deg);
border-radius: 0 0 17px 0;
transform-origin: top left;
rotate: -15deg;
}
/* smile */
.person_right .person__head::after {
top: 27px; left: 13px;
width: 30px; height: 13px;
border-radius: 0 0 60% 0 / 0 0 100% 0;
border-color: var(--grey);
border-width: 0 2px 2px 0;
border-style: solid;
transform-origin: top left;
rotate: 45deg;
animation: rightPersonSmile var(--animation-slow);
}
@keyframes rightPersonSmile {
0%, 50%, 100% {
border-radius: 0 0 60% 0 / 0 0 100% 0;
scale: 1;
translate: 0 0;
rotate: 45deg;
}
55%, 95% {
border-radius: 0 0 100% 0 / 0 0 100% 0;
scale: 0.8;
translate: -1px 8px;
rotate: 35deg;
}
}
/* brow */
.person_right .person__face {
top: 26px; left: 63px;
width: 51px; height: 5px;
background: var(--dark-blue);
rotate: 45deg;
}
/* eye */
.person_right .person__face::before {
top: 11px; left: 0px;
width: 25px; height: 12px;
background: linear-gradient(90deg, var(--black) 50%, var(--white) 50%) 50% 0 / 200% 100%;
border-radius: 0 0 99em 99em;
animation: rightPersonEye var(--animation-slow);
}
@keyframes rightPersonEye {
0%, 50%, 100% {
background-position: 50% 0;
border-radius: 0 0 99em 99em;
scale: 1;
}
52%, 98% {
background-position: 0 0;
border-radius: 0;
scale: 1 0.2;
}
}
/* nose */
.person_right .person__face::after {
top: 16px; left: -34px;
width: 24px; height: 36px;
background: conic-gradient(from 170deg at 73% 0%, var(--dark-skin) 38deg, transparent 0);
border-radius: 0 0 0 4px;
}#
# NOTE: THIS DOCKERFILE IS GENERATED VIA "update.sh"
#
# PLEASE DO NOT EDIT IT DIRECTLY.
#
FROM nginx:1.24.0-alpine-slim
ENV NJS_VERSION 0.8.0
RUN set -x \
&& apkArch="$(cat /etc/apk/arch)" \
&& nginxPackages=" \
nginx=${NGINX_VERSION}-r${PKG_RELEASE} \
nginx-module-xslt=${NGINX_VERSION}-r${PKG_RELEASE} \
nginx-module-geoip=${NGINX_VERSION}-r${PKG_RELEASE} \
nginx-module-image-filter=${NGINX_VERSION}-r${PKG_RELEASE} \
nginx-module-njs=${NGINX_VERSION}.${NJS_VERSION}-r${PKG_RELEASE} \
" \
# install prerequisites for public key and pkg-oss checks
&& apk add --no-cache --virtual .checksum-deps \
openssl \
&& case "$apkArch" in \
x86_64|aarch64) \
# arches officially built by upstream
set -x \
&& KEY_SHA512="e09fa32f0a0eab2b879ccbbc4d0e4fb9751486eedda75e35fac65802cc9faa266425edf83e261137a2f4d16281ce2c1a5f4502930fe75154723da014214f0655" \
&& wget -O /tmp/nginx_signing.rsa.pub https://nginx.org/keys/nginx_signing.rsa.pub \
&& if echo "$KEY_SHA512 */tmp/nginx_signing.rsa.pub" | sha512sum -c -; then \
echo "key verification succeeded!"; \
mv /tmp/nginx_signing.rsa.pub /etc/apk/keys/; \
else \
echo "key verification failed!"; \
exit 1; \
fi \
&& apk add -X "https://nginx.org/packages/alpine/v$(egrep -o '^[0-9]+\.[0-9]+' /etc/alpine-release)/main" --no-cache $nginxPackages \
;; \
*) \
# we're on an architecture upstream doesn't officially build for
# let's build binaries from the published packaging sources
set -x \
&& tempDir="$(mktemp -d)" \
&& chown nobody:nobody $tempDir \
&& apk add --no-cache --virtual .build-deps \
gcc \
libc-dev \
make \
openssl-dev \
pcre2-dev \
zlib-dev \
linux-headers \
libxslt-dev \
gd-dev \
geoip-dev \
libedit-dev \
bash \
alpine-sdk \
findutils \
&& su nobody -s /bin/sh -c " \
export HOME=${tempDir} \
&& cd ${tempDir} \
&& curl -f -O https://hg.nginx.org/pkg-oss/archive/e5d85b3424bb.tar.gz \
&& PKGOSSCHECKSUM=\"4f33347bf05e7d7dd42a52b6e7af7ec21e3ed71df05a8ec16dd1228425f04e4318d88b1340370ccb6ad02cde590fc102094ddffbb1fc86d2085295a43f02f67b *e5d85b3424bb.tar.gz\" \
&& if [ \"\$(openssl sha512 -r e5d85b3424bb.tar.gz)\" = \"\$PKGOSSCHECKSUM\" ]; then \
echo \"pkg-oss tarball checksum verification succeeded!\"; \
else \
echo \"pkg-oss tarball checksum verification failed!\"; \
exit 1; \
fi \
&& tar xzvf e5d85b3424bb.tar.gz \
&& cd pkg-oss-e5d85b3424bb \
&& cd alpine \
&& make module-geoip module-image-filter module-njs module-xslt \
&& apk index -o ${tempDir}/packages/alpine/${apkArch}/APKINDEX.tar.gz ${tempDir}/packages/alpine/${apkArch}/*.apk \
&& abuild-sign -k ${tempDir}/.abuild/abuild-key.rsa ${tempDir}/packages/alpine/${apkArch}/APKINDEX.tar.gz \
" \
&& cp ${tempDir}/.abuild/abuild-key.rsa.pub /etc/apk/keys/ \
&& apk del --no-network .build-deps \
&& apk add -X ${tempDir}/packages/alpine/ --no-cache $nginxPackages \
;; \
esac \
# remove checksum deps
&& apk del --no-network .checksum-deps \
# if we have leftovers from building, let's purge them (including extra, unnecessary build deps)
&& if [ -n "$tempDir" ]; then rm -rf "$tempDir"; fi \
&& if [ -f "/etc/apk/keys/abuild-key.rsa.pub" ]; then rm -f /etc/apk/keys/abuild-key.rsa.pub; fi \
&& if [ -f "/etc/apk/keys/nginx_signing.rsa.pub" ]; then rm -f /etc/apk/keys/nginx_signing.rsa.pub; fi \
# Bring in curl and ca-certificates to make registering on DNS SD easier
&& apk add --no-cache curl ca-certificates
function fisher --argument-names cmd --description "A plugin manager for Fish"
set --query fisher_path || set --local fisher_path $__fish_config_dir
set --local fisher_version 4.4.4
set --local fish_plugins $__fish_config_dir/fish_plugins
switch "$cmd"
case -v --version
echo "fisher, version $fisher_version"
case "" -h --help
echo "Usage: fisher install <plugins...> Install plugins"
echo " fisher remove <plugins...> Remove installed plugins"
echo " fisher update <plugins...> Update installed plugins"
echo " fisher update Update all installed plugins"
echo " fisher list [<regex>] List installed plugins matching regex"
echo "Options:"
echo " -v, --version Print version"
echo " -h, --help Print this help message"
echo "Variables:"
echo " \$fisher_path Plugin installation path. Default: $__fish_config_dir" | string replace --regex -- $HOME \~
case ls list
string match --entire --regex -- "$argv[2]" $_fisher_plugins
case install update remove
isatty || read --local --null --array stdin && set --append argv $stdin
set --local install_plugins
set --local update_plugins
set --local remove_plugins
set --local arg_plugins $argv[2..-1]
set --local old_plugins $_fisher_plugins
set --local new_plugins
test -e $fish_plugins && set --local file_plugins (string match --regex -- '^[^\s]+$' <$fish_plugins)
if ! set --query argv[2]
if test "$cmd" != update
echo "fisher: Not enough arguments for command: \"$cmd\"" >&2 && return 1
else if ! set --query file_plugins
echo "fisher: \"$fish_plugins\" file not found: \"$cmd\"" >&2 && return 1
end
set arg_plugins $file_plugins
end
for plugin in $arg_plugins
set plugin (test -e "$plugin" && realpath $plugin || string lower -- $plugin)
contains -- "$plugin" $new_plugins || set --append new_plugins $plugin
end
if set --query argv[2]
for plugin in $new_plugins
if contains -- "$plugin" $old_plugins
test "$cmd" = remove &&
set --append remove_plugins $plugin ||
set --append update_plugins $plugin
else if test "$cmd" = install
set --append install_plugins $plugin
else
echo "fisher: Plugin not installed: \"$plugin\"" >&2 && return 1
end
end
else
for plugin in $new_plugins
contains -- "$plugin" $old_plugins &&
set --append update_plugins $plugin ||
set --append install_plugins $plugin
end
for plugin in $old_plugins
contains -- "$plugin" $new_plugins || set --append remove_plugins $plugin
end
end
set --local pid_list
set --local source_plugins
set --local fetch_plugins $update_plugins $install_plugins
set --local fish_path (status fish-path)
echo (set_color --bold)fisher $cmd version $fisher_version(set_color normal)
for plugin in $fetch_plugins
set --local source (command mktemp -d)
set --append source_plugins $source
command mkdir -p $source/{completions,conf.d,themes,functions}
$fish_path --command "
if test -e $plugin
command cp -Rf $plugin/* $source
else
set temp (command mktemp -d)
set repo (string split -- \@ $plugin) || set repo[2] HEAD
if set path (string replace --regex -- '^(https://)?gitlab.com/' '' \$repo[1])
set name (string split -- / \$path)[-1]
set url https://gitlab.com/\$path/-/archive/\$repo[2]/\$name-\$repo[2].tar.gz
else
set url https://api.github.com/repos/\$repo[1]/tarball/\$repo[2]
end
echo Fetching (set_color --underline)\$url(set_color normal)
if command curl -q --silent -L \$url | command tar -xzC \$temp -f - 2>/dev/null
command cp -Rf \$temp/*/* $source
else
echo fisher: Invalid plugin name or host unavailable: \\\"$plugin\\\" >&2
command rm -rf $source
end
command rm -rf \$temp
end
set files $source/* && string match --quiet --regex -- .+\.fish\\\$ \$files
" &
set --append pid_list (jobs --last --pid)
end
wait $pid_list 2>/dev/null
for plugin in $fetch_plugins
if set --local source $source_plugins[(contains --index -- "$plugin" $fetch_plugins)] && test ! -e $source
if set --local index (contains --index -- "$plugin" $install_plugins)
set --erase install_plugins[$index]
else
set --erase update_plugins[(contains --index -- "$plugin" $update_plugins)]
end
end
end
for plugin in $update_plugins $remove_plugins
if set --local index (contains --index -- "$plugin" $_fisher_plugins)
set --local plugin_files_var _fisher_(string escape --style=var -- $plugin)_files
if contains -- "$plugin" $remove_plugins
for name in (string replace --filter --regex -- '.+/conf\.d/([^/]+)\.fish$' '$1' $$plugin_files_var)
emit {$name}_uninstall
end
printf "%s\n" Removing\ (set_color red --bold)$plugin(set_color normal) " "$$plugin_files_var | string replace -- \~ ~
set --erase _fisher_plugins[$index]
end
command rm -rf (string replace -- \~ ~ $$plugin_files_var)
functions --erase (string replace --filter --regex -- '.+/functions/([^/]+)\.fish$' '$1' $$plugin_files_var)
for name in (string replace --filter --regex -- '.+/completions/([^/]+)\.fish$' '$1' $$plugin_files_var)
complete --erase --command $name
end
set --erase $plugin_files_var
end
end
if set --query update_plugins[1] || set --query install_plugins[1]
command mkdir -p $fisher_path/{functions,themes,conf.d,completions}
end
for plugin in $update_plugins $install_plugins
set --local source $source_plugins[(contains --index -- "$plugin" $fetch_plugins)]
set --local files $source/{functions,themes,conf.d,completions}/*
if set --local index (contains --index -- $plugin $install_plugins)
set --local user_files $fisher_path/{functions,themes,conf.d,completions}/*
set --local conflict_files
for file in (string replace -- $source/ $fisher_path/ $files)
contains -- $file $user_files && set --append conflict_files $file
end
if set --query conflict_files[1] && set --erase install_plugins[$index]
echo -s "fisher: Cannot install \"$plugin\": please remove or move conflicting files first:" \n" "$conflict_files >&2
continue
end
end
for file in (string replace -- $source/ "" $files)
command cp -RLf $source/$file $fisher_path/$file
end
set --local plugin_files_var _fisher_(string escape --style=var -- $plugin)_files
set --query files[1] && set --universal $plugin_files_var (string replace -- $source $fisher_path $files | string replace -- ~ \~)
contains -- $plugin $_fisher_plugins || set --universal --append _fisher_plugins $plugin
contains -- $plugin $install_plugins && set --local event install || set --local event update
printf "%s\n" Installing\ (set_color --bold)$plugin(set_color normal) " "$$plugin_files_var | string replace -- \~ ~
for file in (string match --regex -- '.+/[^/]+\.fish$' $$plugin_files_var | string replace -- \~ ~)
source $file
if set --local name (string replace --regex -- '.+conf\.d/([^/]+)\.fish$' '$1' $file)
emit {$name}_$event
end
end
end
command rm -rf $source_plugins
if set --query _fisher_plugins[1]
set --local commit_plugins
for plugin in $file_plugins
contains -- (string lower -- $plugin) (string lower -- $_fisher_plugins) && set --append commit_plugins $plugin
end
for plugin in $_fisher_plugins
contains -- (string lower -- $plugin) (string lower -- $commit_plugins) || set --append commit_plugins $plugin
end
printf "%s\n" $commit_plugins >$fish_plugins
else
set --erase _fisher_plugins
command rm -f $fish_plugins
end
set --local total (count $install_plugins) (count $update_plugins) (count $remove_plugins)
test "$total" != "0 0 0" && echo (string join ", " (
test $total[1] = 0 || echo "Installed $total[1]") (
test $total[2] = 0 || echo "Updated $total[2]") (
test $total[3] = 0 || echo "Removed $total[3]")
) plugin/s
case \*
echo "fisher: Unknown command: \"$cmd\"" >&2 && return 1
end
end
if ! set --query _fisher_upgraded_to_4_4
set --universal _fisher_upgraded_to_4_4
if functions --query _fisher_list
set --query XDG_DATA_HOME[1] || set --local XDG_DATA_HOME ~/.local/share
command rm -rf $XDG_DATA_HOME/fisher
functions --erase _fisher_{list,plugin_parse}
fisher update >/dev/null 2>/dev/null
else
for var in (set --names | string match --entire --regex '^_fisher_.+_files$')
set $var (string replace -- ~ \~ $$var)
end
functions --erase _fisher_fish_postexec
end
end
package kong
import (
"errors"
"fmt"
"io"
"os"
"path/filepath"
"reflect"
"regexp"
"strings"
)
var (
callbackReturnSignature = reflect.TypeOf((*error)(nil)).Elem()
)
func failField(parent reflect.Value, field reflect.StructField, format string, args ...interface{}) error {
name := parent.Type().Name()
if name == "" {
name = "<anonymous struct>"
}
return fmt.Errorf("%s.%s: %s", name, field.Name, fmt.Sprintf(format, args...))
}
// Must creates a new Parser or panics if there is an error.
func Must(ast interface{}, options ...Option) *Kong {
k, err := New(ast, options...)
if err != nil {
panic(err)
}
return k
}
type usageOnError int
const (
shortUsage usageOnError = iota + 1
fullUsage
)
// Kong is the main parser type.
type Kong struct {
// Grammar model.
Model *Application
// Termination function (defaults to os.Exit)
Exit func(int)
Stdout io.Writer
Stderr io.Writer
bindings bindings
loader ConfigurationLoader
resolvers []Resolver
registry *Registry
ignoreFields []*regexp.Regexp
noDefaultHelp bool
usageOnError usageOnError
help HelpPrinter
shortHelp HelpPrinter
helpFormatter HelpValueFormatter
helpOptions HelpOptions
helpFlag *Flag
groups []Group
vars Vars
flagNamer func(string) string
// Set temporarily by Options. These are applied after build().
postBuildOptions []Option
embedded []embedded
dynamicCommands []*dynamicCommand
}
// New creates a new Kong parser on grammar.
//
// See the README (https://github.com/alecthomas/kong) for usage instructions.
func New(grammar interface{}, options ...Option) (*Kong, error) {
k := &Kong{
Exit: os.Exit,
Stdout: os.Stdout,
Stderr: os.Stderr,
registry: NewRegistry().RegisterDefaults(),
vars: Vars{},
bindings: bindings{},
helpFormatter: DefaultHelpValueFormatter,
ignoreFields: make([]*regexp.Regexp, 0),
flagNamer: func(s string) string {
return strings.ToLower(dashedString(s))
},
}
options = append(options, Bind(k))
for _, option := range options {
if err := option.Apply(k); err != nil {
return nil, err
}
}
if k.help == nil {
k.help = DefaultHelpPrinter
}
if k.shortHelp == nil {
k.shortHelp = DefaultShortHelpPrinter
}
model, err := build(k, grammar)
if err != nil {
return k, err
}
model.Name = filepath.Base(os.Args[0])
k.Model = model
k.Model.HelpFlag = k.helpFlag
// Embed any embedded structs.
for _, embed := range k.embedded {
tag, err := parseTagString(strings.Join(embed.tags, " ")) //nolint:govet
if err != nil {
return nil, err
}
tag.Embed = true
v := reflect.Indirect(reflect.ValueOf(embed.strct))
node, err := buildNode(k, v, CommandNode, tag, map[string]bool{})
if err != nil {
return nil, err
}
for _, child := range node.Children {
child.Parent = k.Model.Node
k.Model.Children = append(k.Model.Children, child)
}
k.Model.Flags = append(k.Model.Flags, node.Flags...)
}
// Synthesise command nodes.
for _, dcmd := range k.dynamicCommands {
tag, terr := parseTagString(strings.Join(dcmd.tags, " "))
if terr != nil {
return nil, terr
}
tag.Name = dcmd.name
tag.Help = dcmd.help
tag.Group = dcmd.group
tag.Cmd = true
v := reflect.Indirect(reflect.ValueOf(dcmd.cmd))
err = buildChild(k, k.Model.Node, CommandNode, reflect.Value{}, reflect.StructField{
Name: dcmd.name,
Type: v.Type(),
}, v, tag, dcmd.name, map[string]bool{})
if err != nil {
return nil, err
}
}
for _, option := range k.postBuildOptions {
if err = option.Apply(k); err != nil {
return nil, err
}
}
k.postBuildOptions = nil
if err = k.interpolate(k.Model.Node); err != nil {
return nil, err
}
k.bindings.add(k.vars)
return k, nil
}
type varStack []Vars
func (v *varStack) head() Vars { return (*v)[len(*v)-1] }
func (v *varStack) pop() { *v = (*v)[:len(*v)-1] }
func (v *varStack) push(vars Vars) Vars {
if len(*v) != 0 {
vars = (*v)[len(*v)-1].CloneWith(vars)
}
*v = append(*v, vars)
return vars
}
// Interpolate variables into model.
func (k *Kong) interpolate(node *Node) (err error) {
stack := varStack{}
return Visit(node, func(node Visitable, next Next) error {
switch node := node.(type) {
case *Node:
vars := stack.push(node.Vars())
node.Help, err = interpolate(node.Help, vars, nil)
if err != nil {
return fmt.Errorf("help for %s: %s", node.Path(), err)
}
err = next(nil)
stack.pop()
return err
case *Value:
return next(k.interpolateValue(node, stack.head()))
}
return next(nil)
})
}
func (k *Kong) interpolateValue(value *Value, vars Vars) (err error) {
if len(value.Tag.Vars) > 0 {
vars = vars.CloneWith(value.Tag.Vars)
}
if varsContributor, ok := value.Mapper.(VarsContributor); ok {
vars = vars.CloneWith(varsContributor.Vars(value))
}
if value.Enum, err = interpolate(value.Enum, vars, nil); err != nil {
return fmt.Errorf("enum for %s: %s", value.Summary(), err)
}
updatedVars := map[string]string{
"default": value.Default,
"enum": value.Enum,
}
if value.Default, err = interpolate(value.Default, vars, nil); err != nil {
return fmt.Errorf("default value for %s: %s", value.Summary(), err)
}
if value.Enum, err = interpolate(value.Enum, vars, nil); err != nil {
return fmt.Errorf("enum value for %s: %s", value.Summary(), err)
}
if value.Flag != nil {
for i, env := range value.Flag.Envs {
if value.Flag.Envs[i], err = interpolate(env, vars, nil); err != nil {
return fmt.Errorf("env value for %s: %s", value.Summary(), err)
}
}
value.Tag.Envs = value.Flag.Envs
updatedVars["env"] = ""
if len(value.Flag.Envs) != 0 {
updatedVars["env"] = value.Flag.Envs[0]
}
}
value.Help, err = interpolate(value.Help, vars, updatedVars)
if err != nil {
return fmt.Errorf("help for %s: %s", value.Summary(), err)
}
return nil
}
// Provide additional builtin flags, if any.
func (k *Kong) extraFlags() []*Flag {
if k.noDefaultHelp {
return nil
}
var helpTarget helpValue
value := reflect.ValueOf(&helpTarget).Elem()
helpFlag := &Flag{
Short: 'h',
Value: &Value{
Name: "help",
Help: "Show context-sensitive help.",
OrigHelp: "Show context-sensitive help.",
Target: value,
Tag: &Tag{},
Mapper: k.registry.ForValue(value),
DefaultValue: reflect.ValueOf(false),
},
}
helpFlag.Flag = helpFlag
k.helpFlag = helpFlag
return []*Flag{helpFlag}
}
// Parse arguments into target.
//
// The return Context can be used to further inspect the parsed command-line, to format help, to find the
// selected command, to run command Run() methods, and so on. See Context and README for more information.
//
// Will return a ParseError if a *semantically* invalid command-line is encountered (as opposed to a syntactically
// invalid one, which will report a normal error).
func (k *Kong) Parse(args []string) (ctx *Context, err error) {
ctx, err = Trace(k, args)
if err != nil {
return nil, err
}
if ctx.Error != nil {
return nil, &ParseError{error: ctx.Error, Context: ctx}
}
if err = k.applyHook(ctx, "BeforeReset"); err != nil {
return nil, &ParseError{error: err, Context: ctx}
}
if err = ctx.Reset(); err != nil {
return nil, &ParseError{error: err, Context: ctx}
}
if err = k.applyHook(ctx, "BeforeResolve"); err != nil {
return nil, &ParseError{error: err, Context: ctx}
}
if err = ctx.Resolve(); err != nil {
return nil, &ParseError{error: err, Context: ctx}
}
if err = k.applyHook(ctx, "BeforeApply"); err != nil {
return nil, &ParseError{error: err, Context: ctx}
}
if _, err = ctx.Apply(); err != nil {
return nil, &ParseError{error: err, Context: ctx}
}
if err = ctx.Validate(); err != nil {
return nil, &ParseError{error: err, Context: ctx}
}
if err = k.applyHook(ctx, "AfterApply"); err != nil {
return nil, &ParseError{error: err, Context: ctx}
}
return ctx, nil
}
func (k *Kong) applyHook(ctx *Context, name string) error {
for _, trace := range ctx.Path {
var value reflect.Value
switch {
case trace.App != nil:
value = trace.App.Target
case trace.Argument != nil:
value = trace.Argument.Target
case trace.Command != nil:
value = trace.Command.Target
case trace.Positional != nil:
value = trace.Positional.Target
case trace.Flag != nil:
value = trace.Flag.Value.Target
default:
panic("unsupported Path")
}
method := getMethod(value, name)
if !method.IsValid() {
continue
}
binds := k.bindings.clone()
binds.add(ctx, trace)
binds.add(trace.Node().Vars().CloneWith(k.vars))
binds.merge(ctx.bindings)
if err := callFunction(method, binds); err != nil {
return err
}
}
// Path[0] will always be the app root.
return k.applyHookToDefaultFlags(ctx, ctx.Path[0].Node(), name)
}
// Call hook on any unset flags with default values.
func (k *Kong) applyHookToDefaultFlags(ctx *Context, node *Node, name string) error {
if node == nil {
return nil
}
return Visit(node, func(n Visitable, next Next) error {
node, ok := n.(*Node)
if !ok {
return next(nil)
}
binds := k.bindings.clone().add(ctx).add(node.Vars().CloneWith(k.vars))
for _, flag := range node.Flags {
if !flag.HasDefault || ctx.values[flag.Value].IsValid() || !flag.Target.IsValid() {
continue
}
method := getMethod(flag.Target, name)
if !method.IsValid() {
continue
}
path := &Path{Flag: flag}
if err := callFunction(method, binds.clone().add(path)); err != nil {
return next(err)
}
}
return next(nil)
})
}
func formatMultilineMessage(w io.Writer, leaders []string, format string, args ...interface{}) {
lines := strings.Split(fmt.Sprintf(format, args...), "\n")
leader := ""
for _, l := range leaders {
if l == "" {
continue
}
leader += l + ": "
}
fmt.Fprintf(w, "%s%s\n", leader, lines[0])
for _, line := range lines[1:] {
fmt.Fprintf(w, "%*s%s\n", len(leader), " ", line)
}
}
// Printf writes a message to Kong.Stdout with the application name prefixed.
func (k *Kong) Printf(format string, args ...interface{}) *Kong {
formatMultilineMessage(k.Stdout, []string{k.Model.Name}, format, args...)
return k
}
// Errorf writes a message to Kong.Stderr with the application name prefixed.
func (k *Kong) Errorf(format string, args ...interface{}) *Kong {
formatMultilineMessage(k.Stderr, []string{k.Model.Name, "error"}, format, args...)
return k
}
// Fatalf writes a message to Kong.Stderr with the application name prefixed then exits with a non-zero status.
func (k *Kong) Fatalf(format string, args ...interface{}) {
k.Errorf(format, args...)
k.Exit(1)
}
// FatalIfErrorf terminates with an error message if err != nil.
func (k *Kong) FatalIfErrorf(err error, args ...interface{}) {
if err == nil {
return
}
msg := err.Error()
if len(args) > 0 {
msg = fmt.Sprintf(args[0].(string), args[1:]...) + ": " + err.Error() //nolint
}
// Maybe display usage information.
var parseErr *ParseError
if errors.As(err, &parseErr) {
switch k.usageOnError {
case fullUsage:
_ = k.help(k.helpOptions, parseErr.Context)
fmt.Fprintln(k.Stdout)
case shortUsage:
_ = k.shortHelp(k.helpOptions, parseErr.Context)
fmt.Fprintln(k.Stdout)
}
}
k.Fatalf("%s", msg)
}
// LoadConfig from path using the loader configured via Configuration(loader).
//
// "path" will have ~ and any variables expanded.
func (k *Kong) LoadConfig(path string) (Resolver, error) {
var err error
path = ExpandPath(path)
path, err = interpolate(path, k.vars, nil)
if err != nil {
return nil, err
}
r, err := os.Open(path) //nolint: gas
if err != nil {
return nil, err
}
defer r.Close()
return k.loader(r)
}
module github.com/maaslalani/invoice
go 1.20
require (
github.com/signintech/gopdf v0.18.0
github.com/spf13/cobra v1.7.0
github.com/spf13/viper v1.16.0
gopkg.in/yaml.v3 v3.0.1
)
require (
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/phpdave11/gofpdi v1.0.14-0.20211212211723-1f10f9844311 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/spf13/afero v1.9.5 // indirect
github.com/spf13/cast v1.5.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
golang.org/x/sys v0.8.0 // indirect
golang.org/x/text v0.9.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
)
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
github.com/phpdave11/gofpdi v1.0.14-0.20211212211723-1f10f9844311 h1:zyWXQ6vu27ETMpYsEMAsisQ+GqJ4e1TPvSNfdOPF0no=
github.com/phpdave11/gofpdi v1.0.14-0.20211212211723-1f10f9844311/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/signintech/gopdf v0.18.0 h1:ktQSrhoeQSImPBIIH9Z3vnTJZXCfiGYzgYW2Vy5Ff+c=
github.com/signintech/gopdf v0.18.0/go.mod h1:wrLtZoWaRNrS4hphED0oflFoa6IWkOu6M3nJjm4VbO4=
github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM=
github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA=
github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48=
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc=
github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
<!DOCTYPE html>
<html class="page" lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Flexbox — Two columns</title>
<link rel="stylesheet" href="page.css">
<link rel="stylesheet" href="news.css">
<style>
/* Columns */
.columns {
display: flex;
justify-content: space-between;
}
.columns__item {
width: calc(50% - 10px);
}
</style>
</head>
<body class="page__body page__body--reasonable">
<div class="columns">
<div class="columns__item">
<article class="news news--first">
<h2 class="news__title">Crop circles have been discovered in England. But they are circles of cuddling Labrador puppies!</h2>
<p class="news__lead">In the English town of Bradstone in the county of Devon, eight Labrador puppies lay down in a circle, huddled together. Alas, one of the pups was too late. He had to climb right on top of his siblings and sleep on their backs. However, it was even softer and warmer!</p>
</article>
</div>
<div class="columns__item">
<article class="news news--second">
<h2 class="news__title">In Kamchatka, a fox stole a tourist’s camera. So now you will see a live feed from its mouth</h2>
<p class="news__lead">Finally, we found a video that would make Emmanuel Lubetsky, who worked on Survivor, Birdman, and Gravity, jealous of the camerawork! Let’s not keep you in suspense: in Kamchatka, a fox stole a camera from an inattentive tourist and made off with it. Accordingly, the view turned out to be literally from inside the fox, with ASMR soundtrack in the form of its loud puffing.</p>
</article>
</div>
</div>
</body>
</html>
[SectionOne]
key = value
integer = 1234
real = 3.14
string1 = 'Case 1'
string2 = "Case 2"
[SectionTwo]
; comment line
key = new value
integer = 5678
real = 3.14
string1 = 'Case 1'
string2 = "Case 2"
string3 = 'Case 3'
import { dequal } from 'dequal';
import { compare, lines } from 'uvu/diff';
function dedent(str) {
str = str.replace(/\r?\n/g, '\n');
let arr = str.match(/^[ \t]*(?=\S)/gm);
let i = 0, min = 1/0, len = (arr||[]).length;
for (; i < len; i++) min = Math.min(min, arr[i].length);
return len && min ? str.replace(new RegExp(`^[ \\t]{${min}}`, 'gm'), '') : str;
}
export class Assertion extends Error {
constructor(opts={}) {
super(opts.message);
this.name = 'Assertion';
this.code = 'ERR_ASSERTION';
if (Error.captureStackTrace) {
Error.captureStackTrace(this, this.constructor);
}
this.details = opts.details || false;
this.generated = !!opts.generated;
this.operator = opts.operator;
this.expects = opts.expects;
this.actual = opts.actual;
}
}
function assert(bool, actual, expects, operator, detailer, backup, msg) {
if (bool) return;
let message = msg || backup;
if (msg instanceof Error) throw msg;
let details = detailer && detailer(actual, expects);
throw new Assertion({ actual, expects, operator, message, details, generated: !msg });
}
export function ok(val, msg) {
assert(!!val, false, true, 'ok', false, 'Expected value to be truthy', msg);
}
export function is(val, exp, msg) {
assert(val === exp, val, exp, 'is', compare, 'Expected values to be strictly equal:', msg);
}
export function equal(val, exp, msg) {
assert(dequal(val, exp), val, exp, 'equal', compare, 'Expected values to be deeply equal:', msg);
}
export function unreachable(msg) {
assert(false, true, false, 'unreachable', false, 'Expected not to be reached!', msg);
}
export function type(val, exp, msg) {
let tmp = typeof val;
assert(tmp === exp, tmp, exp, 'type', false, `Expected "${tmp}" to be "${exp}"`, msg);
}
export function instance(val, exp, msg) {
let name = '`' + (exp.name || exp.constructor.name) + '`';
assert(val instanceof exp, val, exp, 'instance', false, `Expected value to be an instance of ${name}`, msg);
}
export function match(val, exp, msg) {
if (typeof exp === 'string') {
assert(val.includes(exp), val, exp, 'match', false, `Expected value to include "${exp}" substring`, msg);
} else {
assert(exp.test(val), val, exp, 'match', false, `Expected value to match \`${String(exp)}\` pattern`, msg);
}
}
export function snapshot(val, exp, msg) {
val=dedent(val); exp=dedent(exp);
assert(val === exp, val, exp, 'snapshot', lines, 'Expected value to match snapshot:', msg);
}
const lineNums = (x, y) => lines(x, y, 1);
export function fixture(val, exp, msg) {
val=dedent(val); exp=dedent(exp);
assert(val === exp, val, exp, 'fixture', lineNums, 'Expected value to match fixture:', msg);
}
export function throws(blk, exp, msg) {
if (!msg && typeof exp === 'string') {
msg = exp; exp = null;
}
try {
blk();
assert(false, false, true, 'throws', false, 'Expected function to throw', msg);
} catch (err) {
if (err instanceof Assertion) throw err;
if (typeof exp === 'function') {
assert(exp(err), false, true, 'throws', false, 'Expected function to throw matching exception', msg);
} else if (exp instanceof RegExp) {
assert(exp.test(err.message), false, true, 'throws', false, `Expected function to throw exception matching \`${String(exp)}\` pattern`, msg);
}
}
}
// ---
export function not(val, msg) {
assert(!val, true, false, 'not', false, 'Expected value to be falsey', msg);
}
not.ok = not;
is.not = function (val, exp, msg) {
assert(val !== exp, val, exp, 'is.not', false, 'Expected values not to be strictly equal', msg);
}
not.equal = function (val, exp, msg) {
assert(!dequal(val, exp), val, exp, 'not.equal', false, 'Expected values not to be deeply equal', msg);
}
not.type = function (val, exp, msg) {
let tmp = typeof val;
assert(tmp !== exp, tmp, exp, 'not.type', false, `Expected "${tmp}" not to be "${exp}"`, msg);
}
not.instance = function (val, exp, msg) {
let name = '`' + (exp.name || exp.constructor.name) + '`';
assert(!(val instanceof exp), val, exp, 'not.instance', false, `Expected value not to be an instance of ${name}`, msg);
}
not.snapshot = function (val, exp, msg) {
val=dedent(val); exp=dedent(exp);
assert(val !== exp, val, exp, 'not.snapshot', false, 'Expected value not to match snapshot', msg);
}
not.fixture = function (val, exp, msg) {
val=dedent(val); exp=dedent(exp);
assert(val !== exp, val, exp, 'not.fixture', false, 'Expected value not to match fixture', msg);
}
not.match = function (val, exp, msg) {
if (typeof exp === 'string') {
assert(!val.includes(exp), val, exp, 'not.match', false, `Expected value not to include "${exp}" substring`, msg);
} else {
assert(!exp.test(val), val, exp, 'not.match', false, `Expected value not to match \`${String(exp)}\` pattern`, msg);
}
}
not.throws = function (blk, exp, msg) {
if (!msg && typeof exp === 'string') {
msg = exp; exp = null;
}
try {
blk();
} catch (err) {
if (typeof exp === 'function') {
assert(!exp(err), true, false, 'not.throws', false, 'Expected function not to throw matching exception', msg);
} else if (exp instanceof RegExp) {
assert(!exp.test(err.message), true, false, 'not.throws', false, `Expected function not to throw exception matching \`${String(exp)}\` pattern`, msg);
} else if (!exp) {
assert(false, true, false, 'not.throws', false, 'Expected function not to throw', msg);
}
}
}
{
"name": "json-server",
"version": "0.17.4",
"description": "Get a full fake REST API with zero coding in less than 30 seconds",
"main": "./lib/server/index.js",
"bin": "./lib/cli/bin.js",
"files": [
"lib",
"public"
],
"scripts": {
"prepare": "husky install",
"test": "npm run build && cross-env NODE_ENV=test jest",
"start": "babel-node -- src/cli/bin db.json -r routes.json",
"lint": "eslint . --ignore-path .gitignore",
"fix": "npm run lint -- --fix",
"build": "babel src -d lib",
"toc": "markdown-toc -i README.md",
"postversion": "git push && git push --tags",
"prepublish": "npm test && npm run build"
},
"dependencies": {
"body-parser": "^1.19.0",
"chalk": "^4.1.2",
"compression": "^1.7.4",
"connect-pause": "^0.1.1",
"cors": "^2.8.5",
"errorhandler": "^1.5.1",
"express": "^4.17.1",
"express-urlrewrite": "^1.4.0",
"json-parse-helpfulerror": "^1.0.3",
"lodash": "^4.17.21",
"lodash-id": "^0.14.1",
"lowdb": "^1.0.0",
"method-override": "^3.0.0",
"morgan": "^1.10.0",
"nanoid": "^3.1.23",
"please-upgrade-node": "^3.2.0",
"pluralize": "^8.0.0",
"server-destroy": "^1.0.1",
"yargs": "^17.0.1"
},
"devDependencies": {
"@babel/cli": "^7.12.1",
"@babel/core": "^7.12.3",
"@babel/node": "^7.12.6",
"@babel/preset-env": "^7.12.1",
"cross-env": "^7.0.2",
"eslint": "^7.13.0",
"eslint-config-prettier": "^8.3.0",
"eslint-config-standard": "^16.0.1",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^3.1.4",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.1.0",
"husky": "^6.0.0",
"jest": "^26.6.3",
"markdown-toc": "^1.2.0",
"mkdirp": "^1.0.4",
"npm-run-all": "^4.1.5",
"os-tmpdir": "^2.0.0",
"prettier": "^2.3.2",
"rimraf": "^3.0.2",
"server-ready": "^0.3.1",
"standard": "^17.1.0",
"supertest": "^6.0.1",
"temp-write": "^4.0.0"
},
"repository": {
"type": "git",
"url": "git://github.com/typicode/json-server.git"
},
"keywords": [
"JSON",
"server",
"fake",
"REST",
"API",
"prototyping",
"mock",
"mocking",
"test",
"testing",
"rest",
"data",
"dummy",
"sandbox"
],
"author": "Typicode <[email protected]>",
"license": "MIT",
"bugs": {
"url": "https://github.com/typicode/json-server/issues"
},
"homepage": "https://github.com/typicode/json-server",
"engines": {
"node": ">=12"
},
"jest": {
"testURL": "http://localhost/"
}
}
{
"name": "json-server",
"version": "0.17.4",
"description": "Get a full fake REST API with zero coding in less than 30 seconds",
"main": "./lib/server/index.js",
"bin": "./lib/cli/bin.js",
"files": [
"lib",
"public"
],
"scripts": {
"prepare": "husky install",
"test": "npm run build && cross-env NODE_ENV=test jest",
"start": "babel-node -- src/cli/bin db.json -r routes.json",
"lint": "eslint . --ignore-path .gitignore",
"fix": "npm run lint -- --fix",
"build": "babel src -d lib",
"toc": "markdown-toc -i README.md",
"postversion": "git push && git push --tags",
"prepublish": "npm test && npm run build"
},
"dependencies": {
"body-parser": "^1.19.0",
"chalk": "^4.1.2",
"compression": "^1.7.4",
"connect-pause": "^0.1.1",
"cors": "^2.8.5",
"errorhandler": "^1.5.1",
"express": "^4.17.1",
"express-urlrewrite": "^1.4.0",
"json-parse-helpfulerror": "^1.0.3",
"lodash": "^4.17.21",
"lodash-id": "^0.14.1",
"lowdb": "^1.0.0",
"method-override": "^3.0.0",
"morgan": "^1.10.0",
"nanoid": "^3.1.23",
"please-upgrade-node": "^3.2.0",
"pluralize": "^8.0.0",
"server-destroy": "^1.0.1",
"yargs": "^17.0.1"
},
"devDependencies": {
"@babel/cli": "^7.12.1",
"@babel/core": "^7.12.3",
"@babel/node": "^7.12.6",
"@babel/preset-env": "^7.12.1",
"cross-env": "^7.0.2",
"eslint": "^7.13.0",
"eslint-config-prettier": "^8.3.0",
"eslint-config-standard": "^16.0.1",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^3.1.4",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.1.0",
"husky": "^6.0.0",
"jest": "^26.6.3",
"markdown-toc": "^1.2.0",
"mkdirp": "^1.0.4",
"npm-run-all": "^4.1.5",
"os-tmpdir": "^2.0.0",
"prettier": "^2.3.2",
"rimraf": "^3.0.2",
"server-ready": "^0.3.1",
"standard": "^17.1.0",
"supertest": "^6.0.1",
"temp-write": "^4.0.0"
},
"repository": {
"type": "git",
"url": "git://github.com/typicode/json-server.git"
},
"keywords": [
"JSON",
"server",
"fake",
"REST",
"API",
"prototyping",
"mock",
"mocking",
"test",
"testing",
"rest",
"data",
"dummy",
"sandbox"
],
"author": "Typicode <[email protected]>",
"license": "MIT",
"bugs": {
"url": "https://github.com/typicode/json-server/issues"
},
"homepage": "https://github.com/typicode/json-server",
"engines": {
"node": ">=12"
},
"jest": {
"testURL": "http://localhost/"
}
}
{
"name": "json-server",
"version": "0.17.4",
"description": "Get a full fake REST API with zero coding in less than 30 seconds",
"main": "./lib/server/index.js",
"bin": "./lib/cli/bin.js",
"files": [
"lib",
"public"
],
"scripts": {
"prepare": "husky install",
"test": "npm run build && cross-env NODE_ENV=test jest",
"start": "babel-node -- src/cli/bin db.json -r routes.json",
"lint": "eslint . --ignore-path .gitignore",
"fix": "npm run lint -- --fix",
"build": "babel src -d lib",
"toc": "markdown-toc -i README.md",
"postversion": "git push && git push --tags",
"prepublish": "npm test && npm run build"
},
"dependencies": {
"body-parser": "^1.19.0",
"chalk": "^4.1.2",
"compression": "^1.7.4",
"connect-pause": "^0.1.1",
"cors": "^2.8.5",
"errorhandler": "^1.5.1",
"express": "^4.17.1",
"express-urlrewrite": "^1.4.0",
"json-parse-helpfulerror": "^1.0.3",
"lodash": "^4.17.21",
"lodash-id": "^0.14.1",
"lowdb": "^1.0.0",
"method-override": "^3.0.0",
"morgan": "^1.10.0",
"nanoid": "^3.1.23",
"please-upgrade-node": "^3.2.0",
"pluralize": "^8.0.0",
"server-destroy": "^1.0.1",
"yargs": "^17.0.1"
},
"devDependencies": {
"@babel/cli": "^7.12.1",
"@babel/core": "^7.12.3",
"@babel/node": "^7.12.6",
"@babel/preset-env": "^7.12.1",
"cross-env": "^7.0.2",
"eslint": "^7.13.0",
"eslint-config-prettier": "^8.3.0",
"eslint-config-standard": "^16.0.1",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^3.1.4",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.1.0",
"husky": "^6.0.0",
"jest": "^26.6.3",
"markdown-toc": "^1.2.0",
"mkdirp": "^1.0.4",
"npm-run-all": "^4.1.5",
"os-tmpdir": "^2.0.0",
"prettier": "^2.3.2",
"rimraf": "^3.0.2",
"server-ready": "^0.3.1",
"standard": "^17.1.0",
"supertest": "^6.0.1",
"temp-write": "^4.0.0"
},
"repository": {
"type": "git",
"url": "git://github.com/typicode/json-server.git"
},
"keywords": [
"JSON",
"server",
"fake",
"REST",
"API",
"prototyping",
"mock",
"mocking",
"test",
"testing",
"rest",
"data",
"dummy",
"sandbox"
],
"author": "Typicode <[email protected]>",
"license": "MIT",
"bugs": {
"url": "https://github.com/typicode/json-server/issues"
},
"homepage": "https://github.com/typicode/json-server",
"engines": {
"node": ">=12"
},
"jest": {
"testURL": "http://localhost/"
}
}
import _ from 'lodash'
import PropTypes from 'prop-types'
import React, { Component, createRef } from 'react'
import { withRouter, withRouteData } from 'react-static'
import { Grid, Header, Icon, Label, Popup } from 'semantic-ui-react'
import DocsLayout from 'docs/src/components/DocsLayout'
import { docTypes, examplePathToHash } from 'docs/src/utils'
import ComponentDocLinks from './ComponentDocLinks'
import ComponentDocSee from './ComponentDocSee'
import ComponentExamples from './ComponentExamples'
import ComponentProps from './ComponentProps'
import ComponentSidebar from './ComponentSidebar'
import ComponentDocContext from './ComponentDocContext'
const exampleEndStyle = {
textAlign: 'center',
opacity: 0.5,
paddingTop: '50vh',
}
class ComponentDoc extends Component {
state = {}
examplesRef = createRef()
static getDerivedStateFromProps(props, state) {
const resetOccurred = props.displayName !== state.displayName
return {
displayName: props.displayName,
exampleStates: resetOccurred ? {} : state.exampleStates,
}
}
handleExampleVisibility = (examplePath, visible) =>
this.setState((prevState) => ({
exampleStates: {
...prevState.exampleStates,
[examplePath]: visible,
},
}))
handleSidebarItemClick = (e, { examplePath }) => {
const { history, location } = this.props
history.replace(`${location.pathname}#${examplePathToHash(examplePath)}`)
}
render() {
const { componentsInfo, displayName, deprecated, seeTags, sidebarSections } = this.props
const activePath = _.findKey(this.state.exampleStates)
const componentInfo = componentsInfo[displayName]
const contextValue = { ...this.props, onVisibilityChange: this.handleExampleVisibility }
return (
/* TODO: use `title` from context */
<DocsLayout additionalTitle={displayName} sidebar title='Semantic UI React'>
<Grid padded>
<Grid.Row>
<Grid.Column>
<Header
as='h1'
content={
<>
<span>{displayName}</span>
{deprecated && (
<Popup trigger={<Label color='black'>Deprecated</Label>}>
This component is deprecated and will be removed in the next major release.
</Popup>
)}
</>
}
subheader={_.join(componentInfo.docblock.description, ' ')}
/>
<ComponentDocSee seeTags={seeTags} />
{componentInfo.repoPath && (
<ComponentDocLinks
displayName={displayName}
parentDisplayName={componentInfo.parentDisplayName}
repoPath={componentInfo.repoPath}
type={componentInfo.type}
/>
)}
<ComponentProps componentsInfo={componentsInfo} displayName={displayName} />
</Grid.Column>
</Grid.Row>
<Grid.Row columns='equal'>
<Grid.Column>
<div ref={this.examplesRef}>
<ComponentDocContext.Provider value={contextValue}>
<ComponentExamples
displayName={displayName}
examplesExist={componentInfo.examplesExist}
type={componentInfo.type}
/>
</ComponentDocContext.Provider>
</div>
<div style={exampleEndStyle}>
This is the bottom <Icon name='pointing down' />
</div>
</Grid.Column>
<Grid.Column computer={5} largeScreen={4} widescreen={4}>
<ComponentSidebar
activePath={activePath}
examplesRef={this.examplesRef}
onItemClick={this.handleSidebarItemClick}
sections={sidebarSections}
/>
</Grid.Column>
</Grid.Row>
</Grid>
</DocsLayout>
)
}
}
ComponentDoc.propTypes = {
componentsInfo: PropTypes.objectOf(docTypes.componentInfoShape).isRequired,
displayName: PropTypes.string.isRequired,
deprecated: PropTypes.bool.isRequired,
history: PropTypes.object.isRequired,
location: PropTypes.object.isRequired,
seeTags: docTypes.seeTags.isRequired,
sidebarSections: docTypes.sidebarSections.isRequired,
title: PropTypes.string.isRequired,
}
export default withRouteData(withRouter(ComponentDoc))
# ################################################################
# zstd - Makefile
# Copyright (C) Yann Collet 2014-2015
# All rights reserved.
#
# BSD license
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice, this
# list of conditions and the following disclaimer in the documentation and/or
# other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# You can contact the author at :
# - zstd source repository : https://github.com/Cyan4973/zstd
# - Public forum : https://groups.google.com/forum/#!forum/lz4c
# ################################################################
# Version number
export VERSION := 0.4.2
PRGDIR = programs
ZSTDDIR = lib
# Define nul output
ifneq (,$(filter Windows%,$(OS)))
VOID = nul
else
VOID = /dev/null
endif
.PHONY: default all zstdprogram clean install uninstall travis-install test clangtest gpptest armtest usan asan uasan
default: zstdprogram
all:
$(MAKE) -C $(ZSTDDIR) $@
$(MAKE) -C $(PRGDIR) $@
zstdprogram:
$(MAKE) -C $(PRGDIR)
clean:
@$(MAKE) -C $(ZSTDDIR) $@ > $(VOID)
@$(MAKE) -C $(PRGDIR) $@ > $(VOID)
@echo Cleaning completed
#------------------------------------------------------------------------
#make install is validated only for Linux, OSX, kFreeBSD and Hurd targets
ifneq (,$(filter $(shell uname),Linux Darwin GNU/kFreeBSD GNU))
install:
$(MAKE) -C $(ZSTDDIR) $@
$(MAKE) -C $(PRGDIR) $@
uninstall:
$(MAKE) -C $(ZSTDDIR) $@
$(MAKE) -C $(PRGDIR) $@
travis-install:
$(MAKE) install PREFIX=~/install_test_dir
test:
$(MAKE) -C $(PRGDIR) $@
clangtest: clean
clang -v
$(MAKE) all CC=clang MOREFLAGS="-Werror -Wconversion -Wno-sign-conversion"
gpptest: clean
$(MAKE) all CC=g++ CFLAGS="-O3 -Wall -Wextra -Wundef -Wshadow -Wcast-align -Werror"
armtest: clean
$(MAKE) -C $(ZSTDDIR) -e all CC=arm-linux-gnueabi-gcc MOREFLAGS="-Werror"
$(MAKE) -C $(PRGDIR) -e CC=arm-linux-gnueabi-gcc MOREFLAGS="-Werror"
usan: clean
$(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=undefined"
asan: clean
$(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=address"
uasan: clean
$(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=address -fsanitize=undefined"
endif
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# IceCream - Never use print() to debug again
#
# Ansgar Grunseid
# grunseid.com
# [email protected]
#
# License: MIT
#
from __future__ import print_function
import ast
import inspect
import pprint
import sys
from datetime import datetime
import functools
from contextlib import contextmanager
from os.path import basename, realpath
from textwrap import dedent
import colorama
import executing
from pygments import highlight
# See https://gist.github.com/XVilka/8346728 for color support in various
# terminals and thus whether to use Terminal256Formatter or
# TerminalTrueColorFormatter.
from pygments.formatters import Terminal256Formatter
from pygments.lexers import PythonLexer as PyLexer, Python3Lexer as Py3Lexer
from .coloring import SolarizedDark
PYTHON2 = (sys.version_info[0] == 2)
_absent = object()
def bindStaticVariable(name, value):
def decorator(fn):
setattr(fn, name, value)
return fn
return decorator
@bindStaticVariable('formatter', Terminal256Formatter(style=SolarizedDark))
@bindStaticVariable(
'lexer', PyLexer(ensurenl=False) if PYTHON2 else Py3Lexer(ensurenl=False))
def colorize(s):
self = colorize
return highlight(s, self.lexer, self.formatter)
@contextmanager
def supportTerminalColorsInWindows():
# Filter and replace ANSI escape sequences on Windows with equivalent Win32
# API calls. This code does nothing on non-Windows systems.
colorama.init()
yield
colorama.deinit()
def stderrPrint(*args):
print(*args, file=sys.stderr)
def isLiteral(s):
try:
ast.literal_eval(s)
except Exception:
return False
return True
def colorizedStderrPrint(s):
colored = colorize(s)
with supportTerminalColorsInWindows():
stderrPrint(colored)
DEFAULT_PREFIX = 'ic| '
DEFAULT_LINE_WRAP_WIDTH = 70 # Characters.
DEFAULT_CONTEXT_DELIMITER = '- '
DEFAULT_OUTPUT_FUNCTION = colorizedStderrPrint
DEFAULT_ARG_TO_STRING_FUNCTION = pprint.pformat
class NoSourceAvailableError(OSError):
"""
Raised when icecream fails to find or access source code that's
required to parse and analyze. This can happen, for example, when
- ic() is invoked inside a REPL or interactive shell, e.g. from the
command line (CLI) or with python -i.
- The source code is mangled and/or packaged, e.g. with a project
freezer like PyInstaller.
- The underlying source code changed during execution. See
https://stackoverflow.com/a/33175832.
"""
infoMessage = (
'Failed to access the underlying source code for analysis. Was ic() '
'invoked in a REPL (e.g. from the command line), a frozen application '
'(e.g. packaged with PyInstaller), or did the underlying source code '
'change during execution?')
def callOrValue(obj):
return obj() if callable(obj) else obj
class Source(executing.Source):
def get_text_with_indentation(self, node):
result = self.asttokens().get_text(node)
if '\n' in result:
result = ' ' * node.first_token.start[1] + result
result = dedent(result)
result = result.strip()
return result
def prefixLinesAfterFirst(prefix, s):
lines = s.splitlines(True)
for i in range(1, len(lines)):
lines[i] = prefix + lines[i]
return ''.join(lines)
def indented_lines(prefix, string):
lines = string.splitlines()
return [prefix + lines[0]] + [
' ' * len(prefix) + line
for line in lines[1:]
]
def format_pair(prefix, arg, value):
arg_lines = indented_lines(prefix, arg)
value_prefix = arg_lines[-1] + ': '
looksLikeAString = value[0] + value[-1] in ["''", '""']
if looksLikeAString: # Align the start of multiline strings.
value = prefixLinesAfterFirst(' ', value)
value_lines = indented_lines(value_prefix, value)
lines = arg_lines[:-1] + value_lines
return '\n'.join(lines)
def singledispatch(func):
if "singledispatch" not in dir(functools):
def unsupport_py2(*args, **kwargs):
raise NotImplementedError(
"functools.singledispatch is missing in " + sys.version
)
func.register = func.unregister = unsupport_py2
return func
func = functools.singledispatch(func)
# add unregister based on https://stackoverflow.com/a/25951784
closure = dict(zip(func.register.__code__.co_freevars,
func.register.__closure__))
registry = closure['registry'].cell_contents
dispatch_cache = closure['dispatch_cache'].cell_contents
def unregister(cls):
del registry[cls]
dispatch_cache.clear()
func.unregister = unregister
return func
@singledispatch
def argumentToString(obj):
s = DEFAULT_ARG_TO_STRING_FUNCTION(obj)
s = s.replace('\\n', '\n') # Preserve string newlines in output.
return s
class IceCreamDebugger:
_pairDelimiter = ', ' # Used by the tests in tests/.
lineWrapWidth = DEFAULT_LINE_WRAP_WIDTH
contextDelimiter = DEFAULT_CONTEXT_DELIMITER
def __init__(self, prefix=DEFAULT_PREFIX,
outputFunction=DEFAULT_OUTPUT_FUNCTION,
argToStringFunction=argumentToString, includeContext=False,
contextAbsPath=False):
self.enabled = True
self.prefix = prefix
self.includeContext = includeContext
self.outputFunction = outputFunction
self.argToStringFunction = argToStringFunction
self.contextAbsPath = contextAbsPath
def __call__(self, *args):
if self.enabled:
callFrame = inspect.currentframe().f_back
try:
out = self._format(callFrame, *args)
except NoSourceAvailableError as err:
prefix = callOrValue(self.prefix)
out = prefix + 'Error: ' + err.infoMessage
self.outputFunction(out)
if not args: # E.g. ic().
passthrough = None
elif len(args) == 1: # E.g. ic(1).
passthrough = args[0]
else: # E.g. ic(1, 2, 3).
passthrough = args
return passthrough
def format(self, *args):
callFrame = inspect.currentframe().f_back
out = self._format(callFrame, *args)
return out
def _format(self, callFrame, *args):
prefix = callOrValue(self.prefix)
callNode = Source.executing(callFrame).node
if callNode is None:
raise NoSourceAvailableError()
context = self._formatContext(callFrame, callNode)
if not args:
time = self._formatTime()
out = prefix + context + time
else:
if not self.includeContext:
context = ''
out = self._formatArgs(
callFrame, callNode, prefix, context, args)
return out
def _formatArgs(self, callFrame, callNode, prefix, context, args):
source = Source.for_frame(callFrame)
sanitizedArgStrs = [
source.get_text_with_indentation(arg)
for arg in callNode.args]
pairs = list(zip(sanitizedArgStrs, args))
out = self._constructArgumentOutput(prefix, context, pairs)
return out
def _constructArgumentOutput(self, prefix, context, pairs):
def argPrefix(arg):
return '%s: ' % arg
pairs = [(arg, self.argToStringFunction(val)) for arg, val in pairs]
# For cleaner output, if <arg> is a literal, eg 3, "string", b'bytes',
# etc, only output the value, not the argument and the value, as the
# argument and the value will be identical or nigh identical. Ex: with
# ic("hello"), just output
#
# ic| 'hello',
#
# instead of
#
# ic| "hello": 'hello'.
#
pairStrs = [
val if isLiteral(arg) else (argPrefix(arg) + val)
for arg, val in pairs]
allArgsOnOneLine = self._pairDelimiter.join(pairStrs)
multilineArgs = len(allArgsOnOneLine.splitlines()) > 1
contextDelimiter = self.contextDelimiter if context else ''
allPairs = prefix + context + contextDelimiter + allArgsOnOneLine
firstLineTooLong = len(allPairs.splitlines()[0]) > self.lineWrapWidth
if multilineArgs or firstLineTooLong:
# ic| foo.py:11 in foo()
# multilineStr: 'line1
# line2'
#
# ic| foo.py:11 in foo()
# a: 11111111111111111111
# b: 22222222222222222222
if context:
lines = [prefix + context] + [
format_pair(len(prefix) * ' ', arg, value)
for arg, value in pairs
]
# ic| multilineStr: 'line1
# line2'
#
# ic| a: 11111111111111111111
# b: 22222222222222222222
else:
arg_lines = [
format_pair('', arg, value)
for arg, value in pairs
]
lines = indented_lines(prefix, '\n'.join(arg_lines))
# ic| foo.py:11 in foo()- a: 1, b: 2
# ic| a: 1, b: 2, c: 3
else:
lines = [prefix + context + contextDelimiter + allArgsOnOneLine]
return '\n'.join(lines)
def _formatContext(self, callFrame, callNode):
filename, lineNumber, parentFunction = self._getContext(
callFrame, callNode)
if parentFunction != '<module>':
parentFunction = '%s()' % parentFunction
context = '%s:%s in %s' % (filename, lineNumber, parentFunction)
return context
def _formatTime(self):
now = datetime.now()
formatted = now.strftime('%H:%M:%S.%f')[:-3]
return ' at %s' % formatted
def _getContext(self, callFrame, callNode):
lineNumber = callNode.lineno
frameInfo = inspect.getframeinfo(callFrame)
parentFunction = frameInfo.function
filepath = (realpath if self.contextAbsPath else basename)(frameInfo.filename)
return filepath, lineNumber, parentFunction
def enable(self):
self.enabled = True
def disable(self):
self.enabled = False
def configureOutput(self, prefix=_absent, outputFunction=_absent,
argToStringFunction=_absent, includeContext=_absent,
contextAbsPath=_absent):
noParameterProvided = all(
v is _absent for k,v in locals().items() if k != 'self')
if noParameterProvided:
raise TypeError('configureOutput() missing at least one argument')
if prefix is not _absent:
self.prefix = prefix
if outputFunction is not _absent:
self.outputFunction = outputFunction
if argToStringFunction is not _absent:
self.argToStringFunction = argToStringFunction
if includeContext is not _absent:
self.includeContext = includeContext
if contextAbsPath is not _absent:
self.contextAbsPath = contextAbsPath
ic = IceCreamDebugger()
# frozen_string_literal: true
require 'uri'
require 'stringio'
require 'time'
module URI
# Allows the opening of various resources including URIs.
#
# If the first argument responds to the 'open' method, 'open' is called on
# it with the rest of the arguments.
#
# If the first argument is a string that begins with <code>(protocol)://</code>, it is parsed by
# URI.parse. If the parsed object responds to the 'open' method,
# 'open' is called on it with the rest of the arguments.
#
# Otherwise, Kernel#open is called.
#
# OpenURI::OpenRead#open provides URI::HTTP#open, URI::HTTPS#open and
# URI::FTP#open, Kernel#open.
#
# We can accept URIs and strings that begin with http://, https:// and
# ftp://. In these cases, the opened file object is extended by OpenURI::Meta.
def self.open(name, *rest, &block)
if name.respond_to?(:open)
name.open(*rest, &block)
elsif name.respond_to?(:to_str) &&
%r{\A[A-Za-z][A-Za-z0-9+\-\.]*://} =~ name &&
(uri = URI.parse(name)).respond_to?(:open)
uri.open(*rest, &block)
else
super
end
end
singleton_class.send(:ruby2_keywords, :open) if respond_to?(:ruby2_keywords, true)
end
# OpenURI is an easy-to-use wrapper for Net::HTTP, Net::HTTPS and Net::FTP.
#
# == Example
#
# It is possible to open an http, https or ftp URL as though it were a file:
#
# URI.open("http://www.ruby-lang.org/") {|f|
# f.each_line {|line| p line}
# }
#
# The opened file has several getter methods for its meta-information, as
# follows, since it is extended by OpenURI::Meta.
#
# URI.open("http://www.ruby-lang.org/en") {|f|
# f.each_line {|line| p line}
# p f.base_uri # <URI::HTTP:0x40e6ef2 URL:http://www.ruby-lang.org/en/>
# p f.content_type # "text/html"
# p f.charset # "iso-8859-1"
# p f.content_encoding # []
# p f.last_modified # Thu Dec 05 02:45:02 UTC 2002
# }
#
# Additional header fields can be specified by an optional hash argument.
#
# URI.open("http://www.ruby-lang.org/en/",
# "User-Agent" => "Ruby/#{RUBY_VERSION}",
# "From" => "[email protected]",
# "Referer" => "http://www.ruby-lang.org/") {|f|
# # ...
# }
#
# The environment variables such as http_proxy, https_proxy and ftp_proxy
# are in effect by default. Here we disable proxy:
#
# URI.open("http://www.ruby-lang.org/en/", :proxy => nil) {|f|
# # ...
# }
#
# See OpenURI::OpenRead.open and URI.open for more on available options.
#
# URI objects can be opened in a similar way.
#
# uri = URI.parse("http://www.ruby-lang.org/en/")
# uri.open {|f|
# # ...
# }
#
# URI objects can be read directly. The returned string is also extended by
# OpenURI::Meta.
#
# str = uri.read
# p str.base_uri
#
# Author:: Tanaka Akira <[email protected]>
module OpenURI
VERSION = "0.4.1"
Options = {
:proxy => true,
:proxy_http_basic_authentication => true,
:progress_proc => true,
:content_length_proc => true,
:http_basic_authentication => true,
:read_timeout => true,
:open_timeout => true,
:ssl_ca_cert => nil,
:ssl_verify_mode => nil,
:ssl_min_version => nil,
:ssl_max_version => nil,
:ftp_active_mode => false,
:redirect => true,
:encoding => nil,
:max_redirects => 64,
}
def OpenURI.check_options(options) # :nodoc:
options.each {|k, v|
next unless Symbol === k
unless Options.include? k
raise ArgumentError, "unrecognized option: #{k}"
end
}
end
def OpenURI.scan_open_optional_arguments(*rest) # :nodoc:
if !rest.empty? && (String === rest.first || Integer === rest.first)
mode = rest.shift
if !rest.empty? && Integer === rest.first
perm = rest.shift
end
end
return mode, perm, rest
end
def OpenURI.open_uri(name, *rest) # :nodoc:
uri = URI::Generic === name ? name : URI.parse(name)
mode, _, rest = OpenURI.scan_open_optional_arguments(*rest)
options = rest.shift if !rest.empty? && Hash === rest.first
raise ArgumentError.new("extra arguments") if !rest.empty?
options ||= {}
OpenURI.check_options(options)
if /\Arb?(?:\Z|:([^:]+))/ =~ mode
encoding, = $1,Encoding.find($1) if $1
mode = nil
end
if options.has_key? :encoding
if !encoding.nil?
raise ArgumentError, "encoding specified twice"
end
encoding = Encoding.find(options[:encoding])
end
unless mode == nil ||
mode == 'r' || mode == 'rb' ||
mode == File::RDONLY
raise ArgumentError.new("invalid access mode #{mode} (#{uri.class} resource is read only.)")
end
io = open_loop(uri, options)
io.set_encoding(encoding) if encoding
if block_given?
begin
yield io
ensure
if io.respond_to? :close!
io.close! # Tempfile
else
io.close if !io.closed?
end
end
else
io
end
end
def OpenURI.open_loop(uri, options) # :nodoc:
proxy_opts = []
proxy_opts << :proxy_http_basic_authentication if options.include? :proxy_http_basic_authentication
proxy_opts << :proxy if options.include? :proxy
proxy_opts.compact!
if 1 < proxy_opts.length
raise ArgumentError, "multiple proxy options specified"
end
case proxy_opts.first
when :proxy_http_basic_authentication
opt_proxy, proxy_user, proxy_pass = options.fetch(:proxy_http_basic_authentication)
proxy_user = proxy_user.to_str
proxy_pass = proxy_pass.to_str
if opt_proxy == true
raise ArgumentError.new("Invalid authenticated proxy option: #{options[:proxy_http_basic_authentication].inspect}")
end
when :proxy
opt_proxy = options.fetch(:proxy)
proxy_user = nil
proxy_pass = nil
when nil
opt_proxy = true
proxy_user = nil
proxy_pass = nil
end
case opt_proxy
when true
find_proxy = lambda {|u| pxy = u.find_proxy; pxy ? [pxy, nil, nil] : nil}
when nil, false
find_proxy = lambda {|u| nil}
when String
opt_proxy = URI.parse(opt_proxy)
find_proxy = lambda {|u| [opt_proxy, proxy_user, proxy_pass]}
when URI::Generic
find_proxy = lambda {|u| [opt_proxy, proxy_user, proxy_pass]}
else
raise ArgumentError.new("Invalid proxy option: #{opt_proxy}")
end
uri_set = {}
max_redirects = options[:max_redirects]
buf = nil
while true
redirect = catch(:open_uri_redirect) {
buf = Buffer.new
uri.buffer_open(buf, find_proxy.call(uri), options)
nil
}
if redirect
if redirect.relative?
# Although it violates RFC2616, Location: field may have relative
# URI. It is converted to absolute URI using uri as a base URI.
redirect = uri + redirect
end
if !options.fetch(:redirect, true)
raise HTTPRedirect.new(buf.io.status.join(' '), buf.io, redirect)
end
unless OpenURI.redirectable?(uri, redirect)
raise "redirection forbidden: #{uri} -> #{redirect}"
end
if options.include? :http_basic_authentication
# send authentication only for the URI directly specified.
options = options.dup
options.delete :http_basic_authentication
end
uri = redirect
raise "HTTP redirection loop: #{uri}" if uri_set.include? uri.to_s
uri_set[uri.to_s] = true
raise TooManyRedirects.new("Too many redirects", buf.io) if max_redirects && uri_set.size > max_redirects
else
break
end
end
io = buf.io
io.base_uri = uri
io
end
def OpenURI.redirectable?(uri1, uri2) # :nodoc:
# This test is intended to forbid a redirection from http://... to
# file:///etc/passwd, file:///dev/zero, etc. CVE-2011-1521
# https to http redirect is also forbidden intentionally.
# It avoids sending secure cookie or referer by non-secure HTTP protocol.
# (RFC 2109 4.3.1, RFC 2965 3.3, RFC 2616 15.1.3)
# However this is ad hoc. It should be extensible/configurable.
uri1.scheme.downcase == uri2.scheme.downcase ||
(/\A(?:http|ftp)\z/i =~ uri1.scheme && /\A(?:https?|ftp)\z/i =~ uri2.scheme)
end
def OpenURI.open_http(buf, target, proxy, options) # :nodoc:
if proxy
proxy_uri, proxy_user, proxy_pass = proxy
raise "Non-HTTP proxy URI: #{proxy_uri}" if proxy_uri.class != URI::HTTP
end
if target.userinfo
raise ArgumentError, "userinfo not supported. [RFC3986]"
end
header = {}
options.each {|k, v| header[k] = v if String === k }
require 'net/http'
klass = Net::HTTP
if URI::HTTP === target
# HTTP or HTTPS
if proxy
unless proxy_user && proxy_pass
proxy_user, proxy_pass = proxy_uri.userinfo.split(':') if proxy_uri.userinfo
end
if proxy_user && proxy_pass
klass = Net::HTTP::Proxy(proxy_uri.hostname, proxy_uri.port, proxy_user, proxy_pass)
else
klass = Net::HTTP::Proxy(proxy_uri.hostname, proxy_uri.port)
end
end
target_host = target.hostname
target_port = target.port
request_uri = target.request_uri
else
# FTP over HTTP proxy
target_host = proxy_uri.hostname
target_port = proxy_uri.port
request_uri = target.to_s
if proxy_user && proxy_pass
header["Proxy-Authorization"] =
'Basic ' + ["#{proxy_user}:#{proxy_pass}"].pack('m0')
end
end
http = proxy ? klass.new(target_host, target_port) : klass.new(target_host, target_port, nil)
if target.class == URI::HTTPS
require 'net/https'
http.use_ssl = true
http.verify_mode = options[:ssl_verify_mode] || OpenSSL::SSL::VERIFY_PEER
http.min_version = options[:ssl_min_version]
http.max_version = options[:ssl_max_version]
store = OpenSSL::X509::Store.new
if options[:ssl_ca_cert]
Array(options[:ssl_ca_cert]).each do |cert|
if File.directory? cert
store.add_path cert
else
store.add_file cert
end
end
else
store.set_default_paths
end
http.cert_store = store
end
if options.include? :read_timeout
http.read_timeout = options[:read_timeout]
end
if options.include? :open_timeout
http.open_timeout = options[:open_timeout]
end
resp = nil
http.start {
req = Net::HTTP::Get.new(request_uri, header)
if options.include? :http_basic_authentication
user, pass = options[:http_basic_authentication]
req.basic_auth user, pass
end
http.request(req) {|response|
resp = response
if options[:content_length_proc] && Net::HTTPSuccess === resp
if resp.key?('Content-Length')
options[:content_length_proc].call(resp['Content-Length'].to_i)
else
options[:content_length_proc].call(nil)
end
end
resp.read_body {|str|
buf << str
if options[:progress_proc] && Net::HTTPSuccess === resp
options[:progress_proc].call(buf.size)
end
str.clear
}
}
}
io = buf.io
io.rewind
io.status = [resp.code, resp.message]
resp.each_name {|name| buf.io.meta_add_field2 name, resp.get_fields(name) }
case resp
when Net::HTTPSuccess
when Net::HTTPMovedPermanently, # 301
Net::HTTPFound, # 302
Net::HTTPSeeOther, # 303
Net::HTTPTemporaryRedirect, # 307
Net::HTTPPermanentRedirect # 308
begin
loc_uri = URI.parse(resp['location'])
rescue URI::InvalidURIError
raise OpenURI::HTTPError.new(io.status.join(' ') + ' (Invalid Location URI)', io)
end
throw :open_uri_redirect, loc_uri
else
raise OpenURI::HTTPError.new(io.status.join(' '), io)
end
end
class HTTPError < StandardError
def initialize(message, io)
super(message)
@io = io
end
attr_reader :io
end
# Raised on redirection,
# only occurs when +redirect+ option for HTTP is +false+.
class HTTPRedirect < HTTPError
def initialize(message, io, uri)
super(message, io)
@uri = uri
end
attr_reader :uri
end
class TooManyRedirects < HTTPError
end
class Buffer # :nodoc: all
def initialize
@io = StringIO.new
@size = 0
end
attr_reader :size
StringMax = 10240
def <<(str)
@io << str
@size += str.length
if StringIO === @io && StringMax < @size
require 'tempfile'
io = Tempfile.new('open-uri')
io.binmode
Meta.init io, @io if Meta === @io
io << @io.string
@io = io
end
end
def io
Meta.init @io unless Meta === @io
@io
end
end
# :stopdoc:
RE_LWS = /[\r\n\t ]+/n
RE_TOKEN = %r{[^\x00- ()<>@,;:\\"/\[\]?={}\x7f]+}n
RE_QUOTED_STRING = %r{"(?:[\r\n\t !#-\[\]-~\x80-\xff]|\\[\x00-\x7f])*"}n
RE_PARAMETERS = %r{(?:;#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?=#{RE_LWS}?(?:#{RE_TOKEN}|#{RE_QUOTED_STRING})#{RE_LWS}?)*}n
# :startdoc:
# Mixin for holding meta-information.
module Meta
def Meta.init(obj, src=nil) # :nodoc:
obj.extend Meta
obj.instance_eval {
@base_uri = nil
@meta = {} # name to string. legacy.
@metas = {} # name to array of strings.
}
if src
obj.status = src.status
obj.base_uri = src.base_uri
src.metas.each {|name, values|
obj.meta_add_field2(name, values)
}
end
end
# returns an Array that consists of status code and message.
attr_accessor :status
# returns a URI that is the base of relative URIs in the data.
# It may differ from the URI supplied by a user due to redirection.
attr_accessor :base_uri
# returns a Hash that represents header fields.
# The Hash keys are downcased for canonicalization.
# The Hash values are a field body.
# If there are multiple field with same field name,
# the field values are concatenated with a comma.
attr_reader :meta
# returns a Hash that represents header fields.
# The Hash keys are downcased for canonicalization.
# The Hash value are an array of field values.
attr_reader :metas
def meta_setup_encoding # :nodoc:
charset = self.charset
enc = nil
if charset
begin
enc = Encoding.find(charset)
rescue ArgumentError
end
end
enc = Encoding::ASCII_8BIT unless enc
if self.respond_to? :force_encoding
self.force_encoding(enc)
elsif self.respond_to? :string
self.string.force_encoding(enc)
else # Tempfile
self.set_encoding enc
end
end
def meta_add_field2(name, values) # :nodoc:
name = name.downcase
@metas[name] = values
@meta[name] = values.join(', ')
meta_setup_encoding if name == 'content-type'
end
def meta_add_field(name, value) # :nodoc:
meta_add_field2(name, [value])
end
# returns a Time that represents the Last-Modified field.
def last_modified
if vs = @metas['last-modified']
v = vs.join(', ')
Time.httpdate(v)
else
nil
end
end
def content_type_parse # :nodoc:
vs = @metas['content-type']
# The last (?:;#{RE_LWS}?)? matches extra ";" which violates RFC2045.
if vs && %r{\A#{RE_LWS}?(#{RE_TOKEN})#{RE_LWS}?/(#{RE_TOKEN})#{RE_LWS}?(#{RE_PARAMETERS})(?:;#{RE_LWS}?)?\z}no =~ vs.join(', ')
type = $1.downcase
subtype = $2.downcase
parameters = []
$3.scan(/;#{RE_LWS}?(#{RE_TOKEN})#{RE_LWS}?=#{RE_LWS}?(?:(#{RE_TOKEN})|(#{RE_QUOTED_STRING}))/no) {|att, val, qval|
if qval
val = qval[1...-1].gsub(/[\r\n\t !#-\[\]-~\x80-\xff]+|(\\[\x00-\x7f])/n) { $1 ? $1[1,1] : $& }
end
parameters << [att.downcase, val]
}
["#{type}/#{subtype}", *parameters]
else
nil
end
end
# returns "type/subtype" which is MIME Content-Type.
# It is downcased for canonicalization.
# Content-Type parameters are stripped.
def content_type
type, *_ = content_type_parse
type || 'application/octet-stream'
end
# returns a charset parameter in Content-Type field.
# It is downcased for canonicalization.
#
# If charset parameter is not given but a block is given,
# the block is called and its result is returned.
# It can be used to guess charset.
#
# If charset parameter and block is not given,
# nil is returned except text type.
# In that case, "utf-8" is returned as defined by RFC6838 4.2.1
def charset
type, *parameters = content_type_parse
if pair = parameters.assoc('charset')
pair.last.downcase
elsif block_given?
yield
elsif type && %r{\Atext/} =~ type
"utf-8" # RFC6838 4.2.1
else
nil
end
end
# Returns a list of encodings in Content-Encoding field as an array of
# strings.
#
# The encodings are downcased for canonicalization.
def content_encoding
vs = @metas['content-encoding']
if vs && %r{\A#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?(?:,#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?)*}o =~ (v = vs.join(', '))
v.scan(RE_TOKEN).map {|content_coding| content_coding.downcase}
else
[]
end
end
end
# Mixin for HTTP and FTP URIs.
module OpenRead
# OpenURI::OpenRead#open provides `open' for URI::HTTP and URI::FTP.
#
# OpenURI::OpenRead#open takes optional 3 arguments as:
#
# OpenURI::OpenRead#open([mode [, perm]] [, options]) [{|io| ... }]
#
# OpenURI::OpenRead#open returns an IO-like object if block is not given.
# Otherwise it yields the IO object and return the value of the block.
# The IO object is extended with OpenURI::Meta.
#
# +mode+ and +perm+ are the same as Kernel#open.
#
# However, +mode+ must be read mode because OpenURI::OpenRead#open doesn't
# support write mode (yet).
# Also +perm+ is ignored because it is meaningful only for file creation.
#
# +options+ must be a hash.
#
# Each option with a string key specifies an extra header field for HTTP.
# I.e., it is ignored for FTP without HTTP proxy.
#
# The hash may include other options, where keys are symbols:
#
# [:proxy]
# Synopsis:
# :proxy => "http://proxy.foo.com:8000/"
# :proxy => URI.parse("http://proxy.foo.com:8000/")
# :proxy => true
# :proxy => false
# :proxy => nil
#
# If :proxy option is specified, the value should be String, URI,
# boolean or nil.
#
# When String or URI is given, it is treated as proxy URI.
#
# When true is given or the option itself is not specified,
# environment variable `scheme_proxy' is examined.
# `scheme' is replaced by `http', `https' or `ftp'.
#
# When false or nil is given, the environment variables are ignored and
# connection will be made to a server directly.
#
# [:proxy_http_basic_authentication]
# Synopsis:
# :proxy_http_basic_authentication =>
# ["http://proxy.foo.com:8000/", "proxy-user", "proxy-password"]
# :proxy_http_basic_authentication =>
# [URI.parse("http://proxy.foo.com:8000/"),
# "proxy-user", "proxy-password"]
#
# If :proxy option is specified, the value should be an Array with 3
# elements. It should contain a proxy URI, a proxy user name and a proxy
# password. The proxy URI should be a String, an URI or nil. The proxy
# user name and password should be a String.
#
# If nil is given for the proxy URI, this option is just ignored.
#
# If :proxy and :proxy_http_basic_authentication is specified,
# ArgumentError is raised.
#
# [:http_basic_authentication]
# Synopsis:
# :http_basic_authentication=>[user, password]
#
# If :http_basic_authentication is specified,
# the value should be an array which contains 2 strings:
# username and password.
# It is used for HTTP Basic authentication defined by RFC 2617.
#
# [:content_length_proc]
# Synopsis:
# :content_length_proc => lambda {|content_length| ... }
#
# If :content_length_proc option is specified, the option value procedure
# is called before actual transfer is started.
# It takes one argument, which is expected content length in bytes.
#
# If two or more transfers are performed by HTTP redirection, the
# procedure is called only once for the last transfer.
#
# When expected content length is unknown, the procedure is called with
# nil. This happens when the HTTP response has no Content-Length header.
#
# [:progress_proc]
# Synopsis:
# :progress_proc => lambda {|size| ...}
#
# If :progress_proc option is specified, the proc is called with one
# argument each time when `open' gets content fragment from network.
# The argument +size+ is the accumulated transferred size in bytes.
#
# If two or more transfer is done by HTTP redirection, the procedure
# is called only one for a last transfer.
#
# :progress_proc and :content_length_proc are intended to be used for
# progress bar.
# For example, it can be implemented as follows using Ruby/ProgressBar.
#
# pbar = nil
# open("http://...",
# :content_length_proc => lambda {|t|
# if t && 0 < t
# pbar = ProgressBar.new("...", t)
# pbar.file_transfer_mode
# end
# },
# :progress_proc => lambda {|s|
# pbar.set s if pbar
# }) {|f| ... }
#
# [:read_timeout]
# Synopsis:
# :read_timeout=>nil (no timeout)
# :read_timeout=>10 (10 second)
#
# :read_timeout option specifies a timeout of read for http connections.
#
# [:open_timeout]
# Synopsis:
# :open_timeout=>nil (no timeout)
# :open_timeout=>10 (10 second)
#
# :open_timeout option specifies a timeout of open for http connections.
#
# [:ssl_ca_cert]
# Synopsis:
# :ssl_ca_cert=>filename or an Array of filenames
#
# :ssl_ca_cert is used to specify CA certificate for SSL.
# If it is given, default certificates are not used.
#
# [:ssl_verify_mode]
# Synopsis:
# :ssl_verify_mode=>mode
#
# :ssl_verify_mode is used to specify openssl verify mode.
#
# [:ssl_min_version]
# Synopsis:
# :ssl_min_version=>:TLS1_2
#
# :ssl_min_version option specifies the minimum allowed SSL/TLS protocol
# version. See also OpenSSL::SSL::SSLContext#min_version=.
#
# [:ssl_max_version]
# Synopsis:
# :ssl_max_version=>:TLS1_2
#
# :ssl_max_version option specifies the maximum allowed SSL/TLS protocol
# version. See also OpenSSL::SSL::SSLContext#max_version=.
#
# [:ftp_active_mode]
# Synopsis:
# :ftp_active_mode=>bool
#
# <tt>:ftp_active_mode => true</tt> is used to make ftp active mode.
# Ruby 1.9 uses passive mode by default.
# Note that the active mode is default in Ruby 1.8 or prior.
#
# [:redirect]
# Synopsis:
# :redirect=>bool
#
# +:redirect+ is true by default. <tt>:redirect => false</tt> is used to
# disable all HTTP redirects.
#
# OpenURI::HTTPRedirect exception raised on redirection.
# Using +true+ also means that redirections between http and ftp are
# permitted.
#
def open(*rest, &block)
OpenURI.open_uri(self, *rest, &block)
end
# OpenURI::OpenRead#read([ options ]) reads a content referenced by self and
# returns the content as string.
# The string is extended with OpenURI::Meta.
# The argument +options+ is same as OpenURI::OpenRead#open.
def read(options={})
self.open(options) {|f|
str = f.read
Meta.init str, f
str
}
end
end
end
module URI
class HTTP
def buffer_open(buf, proxy, options) # :nodoc:
OpenURI.open_http(buf, self, proxy, options)
end
include OpenURI::OpenRead
end
class FTP
def buffer_open(buf, proxy, options) # :nodoc:
if proxy
OpenURI.open_http(buf, self, proxy, options)
return
end
begin
require 'net/ftp'
rescue LoadError
abort "net/ftp is not found. You may need to `gem install net-ftp` to install net/ftp."
end
path = self.path
path = path.sub(%r{\A/}, '%2F') # re-encode the beginning slash because uri library decodes it.
directories = path.split(%r{/}, -1)
directories.each {|d|
d.gsub!(/%([0-9A-Fa-f][0-9A-Fa-f])/) { [$1].pack("H2") }
}
unless filename = directories.pop
raise ArgumentError, "no filename: #{self.inspect}"
end
directories.each {|d|
if /[\r\n]/ =~ d
raise ArgumentError, "invalid directory: #{d.inspect}"
end
}
if /[\r\n]/ =~ filename
raise ArgumentError, "invalid filename: #{filename.inspect}"
end
typecode = self.typecode
if typecode && /\A[aid]\z/ !~ typecode
raise ArgumentError, "invalid typecode: #{typecode.inspect}"
end
# The access sequence is defined by RFC 1738
ftp = Net::FTP.new
ftp.connect(self.hostname, self.port)
ftp.passive = !options[:ftp_active_mode]
# todo: extract user/passwd from .netrc.
user = 'anonymous'
passwd = nil
user, passwd = self.userinfo.split(/:/) if self.userinfo
ftp.login(user, passwd)
directories.each {|cwd|
ftp.voidcmd("CWD #{cwd}")
}
if typecode
# xxx: typecode D is not handled.
ftp.voidcmd("TYPE #{typecode.upcase}")
end
if options[:content_length_proc]
options[:content_length_proc].call(ftp.size(filename))
end
ftp.retrbinary("RETR #{filename}", 4096) { |str|
buf << str
options[:progress_proc].call(buf.size) if options[:progress_proc]
}
ftp.close
buf.io.rewind
end
include OpenURI::OpenRead
end
end
#![allow(clippy::self_named_module_files)] // false positive in `commands/build.rs`
use cargo::core::shell::Shell;
use cargo::util::network::http::http_handle;
use cargo::util::network::http::needs_custom_http_transport;
use cargo::util::{self, closest_msg, command_prelude, CargoResult};
use cargo_util::{ProcessBuilder, ProcessError};
use cargo_util_schemas::manifest::StringOrVec;
use std::collections::BTreeMap;
use std::env;
use std::ffi::OsStr;
use std::fs;
use std::path::{Path, PathBuf};
mod cli;
mod commands;
use crate::command_prelude::*;
fn main() {
let _guard = setup_logger();
let mut gctx = match GlobalContext::default() {
Ok(gctx) => gctx,
Err(e) => {
let mut shell = Shell::new();
cargo::exit_with_error(e.into(), &mut shell)
}
};
let result = if let Some(lock_addr) = cargo::ops::fix_get_proxy_lock_addr() {
cargo::ops::fix_exec_rustc(&gctx, &lock_addr).map_err(|e| CliError::from(e))
} else {
let _token = cargo::util::job::setup();
cli::main(&mut gctx)
};
match result {
Err(e) => cargo::exit_with_error(e, &mut *gctx.shell()),
Ok(()) => {}
}
}
fn setup_logger() -> Option<ChromeFlushGuard> {
use tracing_subscriber::prelude::*;
let env = tracing_subscriber::EnvFilter::from_env("CARGO_LOG");
let fmt_layer = tracing_subscriber::fmt::layer()
.with_timer(tracing_subscriber::fmt::time::Uptime::default())
.with_ansi(std::io::IsTerminal::is_terminal(&std::io::stderr()))
.with_writer(std::io::stderr)
.with_filter(env);
let (profile_layer, profile_guard) = chrome_layer();
let registry = tracing_subscriber::registry()
.with(fmt_layer)
.with(profile_layer);
registry.init();
tracing::trace!(start = humantime::format_rfc3339(std::time::SystemTime::now()).to_string());
profile_guard
}
#[cfg(target_has_atomic = "64")]
type ChromeFlushGuard = tracing_chrome::FlushGuard;
#[cfg(target_has_atomic = "64")]
fn chrome_layer<S>() -> (
Option<tracing_chrome::ChromeLayer<S>>,
Option<ChromeFlushGuard>,
)
where
S: tracing::Subscriber
+ for<'span> tracing_subscriber::registry::LookupSpan<'span>
+ Send
+ Sync,
{
#![allow(clippy::disallowed_methods)]
if env_to_bool(std::env::var_os("CARGO_LOG_PROFILE").as_deref()) {
let capture_args =
env_to_bool(std::env::var_os("CARGO_LOG_PROFILE_CAPTURE_ARGS").as_deref());
let (layer, guard) = tracing_chrome::ChromeLayerBuilder::new()
.include_args(capture_args)
.build();
(Some(layer), Some(guard))
} else {
(None, None)
}
}
#[cfg(not(target_has_atomic = "64"))]
type ChromeFlushGuard = ();
#[cfg(not(target_has_atomic = "64"))]
fn chrome_layer() -> (
Option<tracing_subscriber::layer::Identity>,
Option<ChromeFlushGuard>,
) {
(None, None)
}
#[cfg(target_has_atomic = "64")]
fn env_to_bool(os: Option<&OsStr>) -> bool {
match os.and_then(|os| os.to_str()) {
Some("1") | Some("true") => true,
_ => false,
}
}
/// Table for defining the aliases which come builtin in `Cargo`.
/// The contents are structured as: `(alias, aliased_command, description)`.
const BUILTIN_ALIASES: [(&str, &str, &str); 6] = [
("b", "build", "alias: build"),
("c", "check", "alias: check"),
("d", "doc", "alias: doc"),
("r", "run", "alias: run"),
("t", "test", "alias: test"),
("rm", "remove", "alias: remove"),
];
/// Function which contains the list of all of the builtin aliases and it's
/// corresponding execs represented as &str.
fn builtin_aliases_execs(cmd: &str) -> Option<&(&str, &str, &str)> {
BUILTIN_ALIASES.iter().find(|alias| alias.0 == cmd)
}
/// Resolve the aliased command from the [`GlobalContext`] with a given command string.
///
/// The search fallback chain is:
///
/// 1. Get the aliased command as a string.
/// 2. If an `Err` occurs (missing key, type mismatch, or any possible error),
/// try to get it as an array again.
/// 3. If still cannot find any, finds one insides [`BUILTIN_ALIASES`].
fn aliased_command(gctx: &GlobalContext, command: &str) -> CargoResult<Option<Vec<String>>> {
let alias_name = format!("alias.{}", command);
let user_alias = match gctx.get_string(&alias_name) {
Ok(Some(record)) => Some(
record
.val
.split_whitespace()
.map(|s| s.to_string())
.collect(),
),
Ok(None) => None,
Err(_) => gctx.get::<Option<Vec<String>>>(&alias_name)?,
};
let result = user_alias.or_else(|| {
builtin_aliases_execs(command).map(|command_str| vec![command_str.1.to_string()])
});
Ok(result)
}
/// List all runnable commands
fn list_commands(gctx: &GlobalContext) -> BTreeMap<String, CommandInfo> {
let prefix = "cargo-";
let suffix = env::consts::EXE_SUFFIX;
let mut commands = BTreeMap::new();
for dir in search_directories(gctx) {
let entries = match fs::read_dir(dir) {
Ok(entries) => entries,
_ => continue,
};
for entry in entries.filter_map(|e| e.ok()) {
let path = entry.path();
let Some(filename) = path.file_name().and_then(|s| s.to_str()) else {
continue;
};
let Some(name) = filename
.strip_prefix(prefix)
.and_then(|s| s.strip_suffix(suffix))
else {
continue;
};
if is_executable(entry.path()) {
commands.insert(
name.to_string(),
CommandInfo::External { path: path.clone() },
);
}
}
}
for cmd in commands::builtin() {
commands.insert(
cmd.get_name().to_string(),
CommandInfo::BuiltIn {
about: cmd.get_about().map(|s| s.to_string()),
},
);
}
// Add the builtin_aliases and them descriptions to the
// `commands` `BTreeMap`.
for command in &BUILTIN_ALIASES {
commands.insert(
command.0.to_string(),
CommandInfo::BuiltIn {
about: Some(command.2.to_string()),
},
);
}
// Add the user-defined aliases
if let Ok(aliases) = gctx.get::<BTreeMap<String, StringOrVec>>("alias") {
for (name, target) in aliases.iter() {
commands.insert(
name.to_string(),
CommandInfo::Alias {
target: target.clone(),
},
);
}
}
// `help` is special, so it needs to be inserted separately.
commands.insert(
"help".to_string(),
CommandInfo::BuiltIn {
about: Some("Displays help for a cargo subcommand".to_string()),
},
);
commands
}
fn find_external_subcommand(gctx: &GlobalContext, cmd: &str) -> Option<PathBuf> {
let command_exe = format!("cargo-{}{}", cmd, env::consts::EXE_SUFFIX);
search_directories(gctx)
.iter()
.map(|dir| dir.join(&command_exe))
.find(|file| is_executable(file))
}
fn execute_external_subcommand(gctx: &GlobalContext, cmd: &str, args: &[&OsStr]) -> CliResult {
let path = find_external_subcommand(gctx, cmd);
let command = match path {
Some(command) => command,
None => {
let script_suggestion = if gctx.cli_unstable().script
&& std::path::Path::new(cmd).is_file()
{
let sep = std::path::MAIN_SEPARATOR;
format!("\n\tTo run the file `{cmd}`, provide a relative path like `.{sep}{cmd}`")
} else {
"".to_owned()
};
let err = if cmd.starts_with('+') {
anyhow::format_err!(
"no such command: `{cmd}`\n\n\t\
Cargo does not handle `+toolchain` directives.\n\t\
Did you mean to invoke `cargo` through `rustup` instead?{script_suggestion}",
)
} else {
let suggestions = list_commands(gctx);
let did_you_mean = closest_msg(cmd, suggestions.keys(), |c| c);
anyhow::format_err!(
"no such command: `{cmd}`{did_you_mean}\n\n\t\
View all installed commands with `cargo --list`\n\t\
Find a package to install `{cmd}` with `cargo search cargo-{cmd}`{script_suggestion}",
)
};
return Err(CliError::new(err, 101));
}
};
execute_subcommand(gctx, Some(&command), args)
}
fn execute_internal_subcommand(gctx: &GlobalContext, args: &[&OsStr]) -> CliResult {
execute_subcommand(gctx, None, args)
}
// This function is used to execute a subcommand. It is used to execute both
// internal and external subcommands.
// If `cmd_path` is `None`, then the subcommand is an internal subcommand.
fn execute_subcommand(
gctx: &GlobalContext,
cmd_path: Option<&PathBuf>,
args: &[&OsStr],
) -> CliResult {
let cargo_exe = gctx.cargo_exe()?;
let mut cmd = match cmd_path {
Some(cmd_path) => ProcessBuilder::new(cmd_path),
None => ProcessBuilder::new(&cargo_exe),
};
cmd.env(cargo::CARGO_ENV, cargo_exe).args(args);
if let Some(client) = gctx.jobserver_from_env() {
cmd.inherit_jobserver(client);
}
let err = match cmd.exec_replace() {
Ok(()) => return Ok(()),
Err(e) => e,
};
if let Some(perr) = err.downcast_ref::<ProcessError>() {
if let Some(code) = perr.code {
return Err(CliError::code(code));
}
}
Err(CliError::new(err, 101))
}
#[cfg(unix)]
fn is_executable<P: AsRef<Path>>(path: P) -> bool {
use std::os::unix::prelude::*;
fs::metadata(path)
.map(|metadata| metadata.is_file() && metadata.permissions().mode() & 0o111 != 0)
.unwrap_or(false)
}
#[cfg(windows)]
fn is_executable<P: AsRef<Path>>(path: P) -> bool {
path.as_ref().is_file()
}
fn search_directories(gctx: &GlobalContext) -> Vec<PathBuf> {
let mut path_dirs = if let Some(val) = gctx.get_env_os("PATH") {
env::split_paths(&val).collect()
} else {
vec![]
};
let home_bin = gctx.home().clone().into_path_unlocked().join("bin");
// If any of that PATH elements contains `home_bin`, do not
// add it again. This is so that the users can control priority
// of it using PATH, while preserving the historical
// behavior of preferring it over system global directories even
// when not in PATH at all.
// See https://github.com/rust-lang/cargo/issues/11020 for details.
//
// Note: `p == home_bin` will ignore trailing slash, but we don't
// `canonicalize` the paths.
if !path_dirs.iter().any(|p| p == &home_bin) {
path_dirs.insert(0, home_bin);
};
path_dirs
}
/// Initialize libgit2.
#[tracing::instrument(skip_all)]
fn init_git(gctx: &GlobalContext) {
// Disabling the owner validation in git can, in theory, lead to code execution
// vulnerabilities. However, libgit2 does not launch executables, which is the foundation of
// the original security issue. Meanwhile, issues with refusing to load git repos in
// `CARGO_HOME` for example will likely be very frustrating for users. So, we disable the
// validation.
//
// For further discussion of Cargo's current interactions with git, see
//
// https://github.com/rust-lang/rfcs/pull/3279
//
// and in particular the subsection on "Git support".
//
// Note that we only disable this when Cargo is run as a binary. If Cargo is used as a library,
// this code won't be invoked. Instead, developers will need to explicitly disable the
// validation in their code. This is inconvenient, but won't accidentally open consuming
// applications up to security issues if they use git2 to open repositories elsewhere in their
// code.
unsafe {
git2::opts::set_verify_owner_validation(false)
.expect("set_verify_owner_validation should never fail");
}
init_git_transports(gctx);
}
/// Configure libgit2 to use libcurl if necessary.
///
/// If the user has a non-default network configuration, then libgit2 will be
/// configured to use libcurl instead of the built-in networking support so
/// that those configuration settings can be used.
#[tracing::instrument(skip_all)]
fn init_git_transports(gctx: &GlobalContext) {
match needs_custom_http_transport(gctx) {
Ok(true) => {}
_ => return,
}
let handle = match http_handle(gctx) {
Ok(handle) => handle,
Err(..) => return,
};
// The unsafety of the registration function derives from two aspects:
//
// 1. This call must be synchronized with all other registration calls as
// well as construction of new transports.
// 2. The argument is leaked.
//
// We're clear on point (1) because this is only called at the start of this
// binary (we know what the state of the world looks like) and we're mostly
// clear on point (2) because we'd only free it after everything is done
// anyway
unsafe {
git2_curl::register(handle);
}
}
#!/bin/bash
##===- bolt/utils/bughunter.sh - Help locate BOLT bugs -------*- Script -*-===##
#
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
# details.
#
##===----------------------------------------------------------------------===##
#
# This script attempts to narrow down llvm-bolt bug to a single function in the
# input binary.
#
# If such a function is found, llvm-bolt could be run just on this function
# to mitigate debugging process.
#
# The following envvars are used by this script:
#
# BOLT - path to llvm-bolt
#
# BOLT_OPTIONS - options to be used by llvm-bolt
#
# INPUT_BINARY - input for llvm-bolt
#
# PRE_COMMAND - command to execute prior to running optimized binary
#
# POST_COMMAND - command to filter results of running optimized binary
#
# TIMEOUT_OR_CMD - optional timeout or command on optimized binary command
# if the value is a number with an optional trailing letter
# [smhd] it is considered a paramter to "timeout",
# otherwise it's a shell command that wraps the optimized
# binary command.
#
# COMMAND_LINE - command line options to run optimized binary with
#
# IGNORE_ERROR - ignore error codes returned from optimized binary
#
# GOLD_FILE - file containing expected output from optimized binary
#
# FUNC_NAMES - if set, path to an initial list of function names to
# search. Otherwise, nm is used on the original binary.
#
# OFFLINE - if set, bughunter will produce the binaries but will not
# run them, and will depend on you telling whether it
# succeeded or not.
#
# MAX_FUNCS - if set, use -max-funcs to narrow down the offending
# function. if non-zero, start -max-funcs at $MAX_FUNCS
# otherwise, count the number of symbols in the binary.
#
# MAX_FUNCS_FLAG - BOLT command line option to use for MAX_FUNCS search.
# Default is -max-funcs. Can also be used for relocation
# debugging, e.g. -max-data-relocations.
#
# VERBOSE - if non-empty, set the script to echo mode.
#
##===----------------------------------------------------------------------===##
BOLT=${BOLT:=llvm-bolt}
ulimit -c 0
set -o pipefail
if [[ -n "$VERBOSE" ]]; then
set -x
fi
if [[ ! -x $INPUT_BINARY ]] ; then
echo "INPUT_BINARY must be set to an executable file"
exit 1
fi
if [[ -z "$PRE_COMMAND" ]] ; then
PRE_COMMAND=':'
fi
if [[ -z "$POST_COMMAND" ]] ; then
POST_COMMAND='cat'
fi
if [[ -n "$TIMEOUT_OR_CMD" && $TIMEOUT_OR_CMD =~ ^[0-9]+[smhd]?$ ]] ; then
TIMEOUT_OR_CMD="timeout -s KILL $TIMEOUT_OR_CMD"
fi
if [[ -z "$MAX_FUNCS_FLAG" ]] ; then
MAX_FUNCS_FLAG="-max-funcs"
fi
OPTIMIZED_BINARY=$(mktemp -t -u --suffix=.bolt $(basename ${INPUT_BINARY}).XXX)
OUTPUT_FILE="${OPTIMIZED_BINARY}.out"
BOLT_LOG=$(mktemp -t -u --suffix=.log boltXXX)
if [[ -z $OFFLINE ]]; then
echo "Verify input binary passes"
echo " INPUT_BINARY: $PRE_COMMAND && $TIMEOUT_OR_CMD $INPUT_BINARY $COMMAND_LINE |& $POST_COMMAND >& $OUTPUT_FILE"
($PRE_COMMAND && $TIMEOUT_OR_CMD $INPUT_BINARY $COMMAND_LINE |& $POST_COMMAND >& $OUTPUT_FILE)
STATUS=$?
if [[ "$IGNORE_ERROR" == "1" ]]; then
FAIL=0
else
FAIL=$STATUS
fi
if [[ -e "$GOLD_FILE" ]] ; then
cmp -s "$OUTPUT_FILE" "$GOLD_FILE"
FAIL=$?
fi
if [[ $FAIL -ne "0" ]] ; then
echo " Warning: input binary failed"
else
echo " Input binary passes."
fi
fi
echo "Verify optimized binary fails"
($BOLT $BOLT_OPTIONS $INPUT_BINARY -o $OPTIMIZED_BINARY >& $BOLT_LOG)
FAIL=$?
if [[ $FAIL -eq "0" ]]; then
if [[ -z $OFFLINE ]]; then
echo " OPTIMIZED_BINARY: $PRE_COMMAND && $TIMEOUT_OR_CMD $OPTIMIZED_BINARY $COMMAND_LINE |& $POST_COMMAND >& $OUTPUT_FILE"
($PRE_COMMAND && $TIMEOUT_OR_CMD $OPTIMIZED_BINARY $COMMAND_LINE |& $POST_COMMAND >& $OUTPUT_FILE)
STATUS=$?
if [[ "$IGNORE_ERROR" == "1" ]]; then
FAIL=0
else
FAIL=$STATUS
fi
if [[ -e "$GOLD_FILE" ]] ; then
cmp -s "$OUTPUT_FILE" "$GOLD_FILE"
FAIL=$?
fi
else
echo "Did it pass? Type the return code [0 = pass, 1 = fail]"
read -n1 PASS
fi
if [[ $FAIL -eq "0" ]] ; then
echo " Warning: optimized binary passes."
else
echo " Optimized binary fails as expected."
fi
else
echo " Bolt crashes while generating optimized binary."
fi
# Collect function names
FF=$(mktemp -t -u --suffix=.txt func-names.XXX)
nm --defined-only -p $INPUT_BINARY | grep " [TtWw] " | cut -d ' ' -f 3 | egrep -v "\._" | egrep -v '^$' | sort -u > $FF
# Use function names or numbers
if [[ -z "$MAX_FUNCS" ]] ; then
# Do binary search on function names
if [[ -n "$FUNC_NAMES" ]]; then
FF=$FUNC_NAMES
fi
NUM_FUNCS=$(wc -l $FF | cut -d ' ' -f 1)
HALF=$(expr \( $NUM_FUNCS + 1 \) / 2)
PREFIX=$(mktemp -t -u --suffix=.txt func-names.XXX)
FF0=$PREFIX\aa
FF1=$PREFIX\ab
split -a 2 -l $HALF $FF $PREFIX
FF=$FF0
NUM_FUNCS=$(wc -l $FF | cut -d ' ' -f 1)
CONTINUE=$(expr $NUM_FUNCS \> 0)
else
P=0
if [[ "$MAX_FUNCS" -eq "0" ]]; then
Q=$(wc -l $FF | cut -d ' ' -f 1)
else
Q=$MAX_FUNCS
fi
I=$Q
CONTINUE=$(expr \( $Q - $P \) \> 1)
fi
ITER=0
while [[ "$CONTINUE" -ne "0" ]] ; do
rm -f $OPTIMIZED_BINARY
if [[ -z "$MAX_FUNCS" ]] ; then
echo "Iteration $ITER, trying $FF / $HALF functions"
SEARCH_OPT="-funcs-file-no-regex=$FF"
else
I=$(expr \( $Q + $P \) / 2)
echo "Iteration $ITER, P=$P, Q=$Q, I=$I"
SEARCH_OPT="$MAX_FUNCS_FLAG=$I"
fi
echo " BOLT: $BOLT $BOLT_OPTIONS $INPUT_BINARY $SEARCH_OPT -o $OPTIMIZED_BINARY >& $BOLT_LOG"
($BOLT $BOLT_OPTIONS $INPUT_BINARY $SEARCH_OPT -o $OPTIMIZED_BINARY >& $BOLT_LOG)
FAIL=$?
echo " BOLT failure=$FAIL"
rm -f $OUTPUT_FILE
if [[ $FAIL -eq "0" ]] ; then
if [[ -z $OFFLINE ]]; then
echo " OPTIMIZED_BINARY: $PRE_COMMAND && $TIMEOUT_OR_CMD $OPTIMIZED_BINARY $COMMAND_LINE |& $POST_COMMAND >& $OUTPUT_FILE"
($PRE_COMMAND && $TIMEOUT_OR_CMD $OPTIMIZED_BINARY $COMMAND_LINE |& $POST_COMMAND >& $OUTPUT_FILE)
STATUS=$?
if [[ "$IGNORE_ERROR" == "1" ]]; then
FAIL=0
else
FAIL=$STATUS
fi
if [[ -e "$GOLD_FILE" ]] ; then
cmp -s "$OUTPUT_FILE" "$GOLD_FILE"
FAIL=$?
fi
echo " OPTIMIZED_BINARY failure=$FAIL"
else
echo "Did it pass? Type the return code [0 = pass, 1 = fail]"
read -n1 PASS
fi
else
FAIL=1
fi
if [[ -z "$MAX_FUNCS" ]] ; then
if [[ $FAIL -eq "0" ]] ; then
if [[ "$FF" == "$FF1" ]]; then
NUM_FUNCS=0
break;
fi
FF=$FF1
NUM_FUNCS=$(wc -l $FF | cut -d ' ' -f 1)
else
HALF=$(expr \( $NUM_FUNCS + 1 \) / 2)
PREFIX=$(mktemp -t -u --suffix=.txt func-names.XXX)
split -a 2 -l $HALF $FF $PREFIX
FF0=$PREFIX\aa
FF1=$PREFIX\ab
FF=$FF0
NUM_FUNCS=$(wc -l $FF | cut -d ' ' -f 1)
if [[ $NUM_FUNCS -eq "1" && ! -e $FF1 ]]; then
break;
fi
fi
CONTINUE=$(expr $NUM_FUNCS \> 0)
else
if [[ $FAIL -eq "0" ]] ; then
P=$I
else
Q=$I
fi
FF=$I
HALF=$I
CONTINUE=$(expr \( $Q - $P \) \> 1)
fi
ITER=$(expr $ITER + 1)
done
if [[ -z "$MAX_FUNCS" ]] ; then
if [[ "$NUM_FUNCS" -ne "0" ]] ; then
FAILED="The function(s) that failed are in $FF"
fi
else
if [[ $P -ne $Q ]] ; then
FF=$(grep "processing ending" $BOLT_LOG | sed -e "s/BOLT-INFO: processing ending on \(.*\)/\1/g" | tail -1)
FAILED="The item that failed is $FF @ $Q"
fi
fi
if [[ -n "$FAILED" ]] ; then
echo "$FAILED"
echo "To reproduce, run: $BOLT $BOLT_OPTIONS $INPUT_BINARY $SEARCH_OPT -o $OPTIMIZED_BINARY"
else
echo "Unable to reproduce bug."
fi
rm $OPTIMIZED_BINARY $OUTPUT_FILE $BOLT_LOG
-- https://github.com/prisma/database-schema-examples/tree/master/postgres/basic-twitter#basic-twitter
CREATE TABLE tweet (
id BIGINT NOT NULL PRIMARY KEY,
text TEXT NOT NULL,
is_sent BOOLEAN NOT NULL DEFAULT TRUE,
owner_id BIGINT
);
INSERT INTO tweet(id, text, owner_id)
VALUES (1, '#sqlx is pretty cool!', 1);
--
CREATE TABLE tweet_reply (
id BIGINT NOT NULL PRIMARY KEY,
tweet_id BIGINT NOT NULL,
text TEXT NOT NULL,
owner_id BIGINT,
CONSTRAINT tweet_id_fk FOREIGN KEY (tweet_id) REFERENCES tweet(id)
);
INSERT INTO tweet_reply(id, tweet_id, text, owner_id)
VALUES (1, 1, 'Yeah! #sqlx is indeed pretty cool!', 1);
--
CREATE TABLE accounts (
id INTEGER NOT NULL PRIMARY KEY,
name TEXT NOT NULL,
is_active BOOLEAN
);
INSERT INTO accounts(id, name, is_active)
VALUES (1, 'Herp Derpinson', 1);
CREATE VIEW accounts_view as
SELECT *
FROM accounts;
--
CREATE TABLE products (
product_no INTEGER,
name TEXT,
price NUMERIC,
CONSTRAINT price_greater_than_zero CHECK (price > 0)
);
//
// ControlChoiceViewController.swift
// Lunar
//
// Created by Alin Panaitiu on 01.10.2021.
// Copyright © 2021 Alin. All rights reserved.
//
import Cocoa
import Combine
import Foundation
// MARK: - GradientView
final class GradientView: NSView {
override var wantsDefaultClipping: Bool { false }
@IBInspectable var firstColor: NSColor = .clear {
didSet {
updateView()
}
}
@IBInspectable var secondColor: NSColor = .clear {
didSet {
updateView()
}
}
func updateView() {
let layer = CAGradientLayer()
layer.colors = [firstColor, secondColor].map(\.cgColor)
layer.startPoint = CGPoint(x: 0, y: 0)
layer.endPoint = CGPoint(x: 0.5, y: 0.45)
if let blur = CIFilter(name: "CIGaussianBlur", parameters: ["inputRadius": 20]) {
layer.filters = [blur]
}
layer.masksToBounds = false
self.layer = layer
}
}
// MARK: - LunarTestViewController
final class LunarTestViewController: NSViewController {
@IBOutlet var label: NSTextField!
@objc dynamic var lunarTestText = "Checking Monitor"
var taskKey = "lunarTestHighlighter"
var lunarTestHighlighter: Repeater?
override func viewDidAppear() {
let end = {
for d in DC.displays.values {
d.testWindowController?.close()
d.testWindowController = nil
}
}
lunarTestHighlighter = Repeater(
every: 2,
name: taskKey,
onFinish: end,
onCancel: end
) { [weak self] in
guard let self else {
end()
return
}
label.transition(1.5, easing: .easeInOutCubic)
if label.textColor == .white {
label.textColor = darkMauve
} else {
label.textColor = .white
}
}
}
override func viewDidLoad() {
label.textColor = .white
}
}
// MARK: - ControlReadResult
struct ControlReadResult {
static var onlyBrightnessWorked = ControlReadResult(brightness: true, contrast: false, volume: false)
static var allWorked = ControlReadResult(brightness: true, contrast: true, volume: true)
static var noneWorked = ControlReadResult(brightness: false, contrast: false, volume: false)
let brightness: Bool
let contrast: Bool
let volume: Bool
var all: Bool { brightness && contrast }
}
// MARK: - ControlWriteResult
struct ControlWriteResult {
static var onlyBrightnessWorked = ControlWriteResult(brightness: true, contrast: false, volume: false)
static var allWorked = ControlWriteResult(brightness: true, contrast: true, volume: true)
static var noneWorked = ControlWriteResult(brightness: false, contrast: false, volume: false)
let brightness: Bool
let contrast: Bool
let volume: Bool
var all: Bool { brightness && contrast }
}
// MARK: - ControlResult
struct ControlResult {
static var onlyBrightnessWorked = ControlResult(type: .appleNative, read: .onlyBrightnessWorked, write: .onlyBrightnessWorked)
static var allWorked = ControlResult(type: .ddc, read: .allWorked, write: .allWorked)
static var noneWorked = ControlResult(type: .ddc, read: .noneWorked, write: .noneWorked)
let type: DisplayControl
let read: ControlReadResult
let write: ControlWriteResult
var all: Bool { read.all && write.all }
}
// MARK: - ControlChoiceViewController
final class ControlChoiceViewController: NSViewController {
var cancelled = false
@IBOutlet var displayImage: DisplayImage?
@IBOutlet var _controlButton: NSButton!
@IBOutlet var _ddcBlockersButton: NSButton!
@IBOutlet var actionLabel: NSTextField!
@IBOutlet var actionInfo: NSTextField!
@IBOutlet var displayName: DisplayName!
@IBOutlet var brightnessField: ScrollableTextField!
@IBOutlet var contrastField: ScrollableTextField!
@IBOutlet var brightnessCaption: NSTextField!
@IBOutlet var contrastCaption: NSTextField!
@IBOutlet var brightnessReadResult: NSTextField!
@IBOutlet var contrastReadResult: NSTextField!
@IBOutlet var volumeReadResult: NSTextField!
@IBOutlet var brightnessWriteResult: NSTextField!
@IBOutlet var contrastWriteResult: NSTextField!
@IBOutlet var volumeWriteResult: NSTextField!
@IBOutlet var volumeSlider: VolumeSlider!
@IBOutlet var actionButton: Button!
@IBOutlet var noButton: Button!
@IBOutlet var yesButton: Button!
@IBOutlet var skipButton: Button!
var observers: Set<AnyCancellable> = []
@objc dynamic var progress = 0.0
@objc dynamic var volume: Double = 50
var actionLabelColor = white.blended(withFraction: 0.2, of: lunarYellow)
var actionInfoColor = white
var wakeObserver: Cancellable?
var screenObserver: Cancellable?
var semaphore = DispatchSemaphore(value: 0, name: "Control Choice")
var currentDisplay: Display?
var displayProgressStep: Double = 0
var controlProgressStep: Double = 0
var progressForLastDisplay: Double = 0
var progressForDisplay: Double = 0
var didAppear = false
var controlButton: HelpButton? { _controlButton as? HelpButton }
var ddcBlockersButton: OnboardingHelpButton? { _ddcBlockersButton as? OnboardingHelpButton }
func info(_ text: String, color: NSColor) {
mainThread {
actionLabel.stringValue = text
actionLabel.transition(0.9, easing: .easeOutCubic)
actionLabel.textColor = color
}
mainAsyncAfter(ms: 1000) { [weak self] in
guard let self else { return }
actionLabel.transition(1.0, easing: .easeOutCubic)
actionLabel.textColor = actionLabelColor
}
}
func hideAction() {
mainThread {
if let ddcBlockersButton {
ddcBlockersButton.transition(0.8, easing: .easeOutExpo)
ddcBlockersButton.alphaValue = 0.0
ddcBlockersButton.close()
ddcBlockersButton.isEnabled = false
ddcBlockersButton.isHidden = true
}
actionInfo.transition(0.8, easing: .easeOutExpo)
actionInfo.alphaValue = 0.0
actionButton.transition(0.8, easing: .easeOutExpo)
actionButton.alphaValue = 0.0
actionButton.isEnabled = false
actionButton.onClick = nil
}
}
func hideQuestion() {
mainThread {
if let ddcBlockersButton {
ddcBlockersButton.transition(0.8, easing: .easeOutExpo)
ddcBlockersButton.alphaValue = 0.0
ddcBlockersButton.close()
ddcBlockersButton.isEnabled = false
ddcBlockersButton.isHidden = true
}
actionInfo.transition(0.8, easing: .easeOutExpo)
actionInfo.alphaValue = 0.0
noButton.transition(0.8, easing: .easeOutExpo)
noButton.alphaValue = 0.0
noButton.isEnabled = false
noButton.onClick = nil
yesButton.transition(0.8, easing: .easeOutExpo)
yesButton.alphaValue = 0.0
yesButton.isEnabled = false
yesButton.onClick = nil
}
}
func waitForAction(_ text: String, buttonColor: NSColor, buttonText: NSAttributedString, action: @escaping (() -> Void)) {
mainAsyncAfter(ms: 1100) { [weak self] in
guard let self else { return }
actionInfo.transition(0.5, easing: .easeInOutExpo)
actionInfo.textColor = actionInfoColor
}
mainThread {
actionInfo.stringValue = text
actionInfo.transition(0.8, easing: .easeOutCubic)
actionInfo.alphaValue = 1.0
actionInfo.transition(1.0, easing: .easeOutCubic)
actionInfo.textColor = peach
actionButton.bg = buttonColor
actionButton.attributedTitle = buttonText
actionButton.isEnabled = true
actionButton.transition(0.8, easing: .easeOutCubic)
actionButton.alphaValue = 1.0
}
actionButton.onClick = { [weak self] in
log.info("Clicked '\(buttonText.string)' on '\(text)'")
guard let self else {
self?.semaphore.signal()
return
}
semaphore.signal()
hideAction()
}
semaphore.wait(for: 0)
guard !cancelled else { return }
action()
}
func askQuestion(
_ question: String,
yesButtonText: String = "Yes",
noButtonText: String = "No",
ddcBlockerText: String? = nil,
answer: @escaping ((Bool) -> Void)
) {
mainAsyncAfter(ms: 1100) { [weak self] in
guard let self else { return }
actionInfo.transition(0.8, easing: .easeOutCubic)
actionInfo.textColor = actionInfoColor
}
mainThread {
actionInfo.stringValue = question
actionInfo.transition(0.8, easing: .easeOutCubic)
actionInfo.alphaValue = 1.0
actionInfo.transition(1.0, easing: .easeOutCubic)
actionInfo.textColor = peach
noButton.transition(0.8, easing: .easeOutCubic)
noButton.alphaValue = 1.0
noButton.isEnabled = true
noButton.attributedTitle = noButtonText.withTextColor(white)
yesButton.transition(0.8, easing: .easeOutCubic)
yesButton.alphaValue = 1.0
yesButton.isEnabled = true
yesButton.attributedTitle = yesButtonText.withTextColor(white)
if let ddcBlockerText, let ddcBlockersButton {
ddcBlockersButton.helpText = ddcBlockerText
ddcBlockersButton.isEnabled = true
ddcBlockersButton.isHidden = false
ddcBlockersButton.transition(0.8, easing: .easeOutCubic)
ddcBlockersButton.alphaValue = 1.0
ddcBlockersButton.open(edge: .maxX)
}
}
var answerResult = false
noButton.onClick = { [weak self] in
log.info("Answered 'no' to '\(question)'")
guard let self else {
self?.semaphore.signal()
return
}
answerResult = false
semaphore.signal()
hideQuestion()
}
yesButton.onClick = { [weak self] in
log.info("Answered 'yes' to '\(question)'")
guard let self else {
self?.semaphore.signal()
return
}
answerResult = true
semaphore.signal()
hideQuestion()
}
semaphore.wait(for: 0)
guard !cancelled else { return }
answer(answerResult)
}
func setBrightness(_ brightness: Brightness) {
mainThread {
if brightnessField.alphaValue == 0 {
brightnessField.transition(1.0, easing: .easeOutExpo)
brightnessField.alphaValue = 1.0
brightnessCaption.transition(1.0, easing: .easeOutExpo)
brightnessCaption.alphaValue = 1.0
}
}
for br in stride(
from: brightnessField.integerValue,
through: brightness.i,
by: brightnessField.integerValue < brightness.i ? 1 : -1
) {
mainThread { brightnessField.integerValue = br }
guard wait(0.01) else { return }
}
}
func setContrast(_ contrast: Contrast) {
mainThread {
if contrastField.alphaValue == 0 {
contrastField.transition(1.0, easing: .easeOutExpo)
contrastField.alphaValue = 1.0
contrastCaption.transition(1.0, easing: .easeOutExpo)
contrastCaption.alphaValue = 1.0
}
}
for cr in stride(from: contrastField.integerValue, through: contrast.i, by: contrastField.integerValue < contrast.i ? 1 : -1) {
mainThread { contrastField.integerValue = cr }
guard wait(0.01) else { return }
}
}
func setControl(_ control: DisplayControl, display: Display) {
mainThread {
guard !cancelled, let button = controlButton else { return }
switch control {
case .appleNative:
button.bg = .clear
button.attributedTitle = "Using Apple Native Protocol".withTextColor(green)
button.helpText = NATIVE_CONTROLS_HELP_TEXT
case .ddc:
button.bg = .clear
button.attributedTitle = "Using DDC Protocol".withTextColor(peach)
button.helpText = HARDWARE_CONTROLS_HELP_TEXT
case .network:
button.bg = .clear
button.attributedTitle = "Using DDC-over-Network Protocol".withTextColor(blue.highlight(withLevel: 0.2) ?? blue)
button.helpText = NETWORK_CONTROLS_HELP_TEXT
case .gamma:
display.enabledControls[.gamma] = true
button.bg = .clear
if display.supportsGamma {
button.attributedTitle = "Using Gamma Approximation".withTextColor(red)
button.helpText = SOFTWARE_CONTROLS_HELP_TEXT
} else {
button.attributedTitle = "Using Dark Overlay".withTextColor(red)
button.helpText = SOFTWARE_OVERLAY_HELP_TEXT
}
default:
break
}
button.isEnabled = true
button.isHidden = false
button.transition(1.0, easing: .easeOutExpo)
button.alphaValue = 1.0
}
}
func setVolume(_ volume: UInt16) {
mainThread {
if volumeSlider.alphaValue == 0 {
volumeSlider.isEnabled = true
volumeSlider.isHidden = false
volumeSlider.transition(1.0, easing: .easeOutExpo)
volumeSlider.alphaValue = 1.0
}
}
for vol in stride(from: self.volume.i, through: volume.i, by: self.volume.i < volume.i ? 4 : -4) {
mainThread { self.volume = vol.d }
guard wait(0.02) else { return }
}
}
func setResult(_ resultControl: NSTextField, text: String, color: NSColor, transitionSpeed: TimeInterval = 1.5, alpha: Double = 1.0) {
mainThread {
resultControl.stringValue = text
resultControl.textColor = color
resultControl.transition(transitionSpeed)
resultControl.alphaValue = alpha
}
}
func testControl(_ control: Control, for display: Display) -> ControlResult {
hideDisplayValues()
hideAction()
hideQuestion()
let readWorked = testControlRead(control, for: display)
setControlProgress(0.5)
guard wait(1) else { return .allWorked }
guard readWorked.all else {
info("", color: peach)
// var writeWorked = ControlWriteResult.noneWorked
// waitForAction(
// "Reading didn't work for some values\nWrite the missing values manually and click the Continue button",
// buttonColor: lunarYellow, buttonText: "Continue".withTextColor(mauve)
// ) { [weak self] in
// guard let self else { return }
// writeWorked = self.testControlWrite(control, for: display)
// }
let writeWorked = testControlWrite(control, for: display)
return ControlResult(type: control.displayControl, read: readWorked, write: writeWorked)
}
info("Starting write tests", color: peach)
guard wait(3) else { return .allWorked }
let writeWorked = testControlWrite(control, for: display)
return ControlResult(type: control.displayControl, read: readWorked, write: writeWorked)
}
func testControlWrite(_ control: Control, for display: Display) -> ControlWriteResult {
// #if DEBUG
// return .noneWorked
// #endif
let currentBrightness: UInt16 = brightnessField.integerValue == 0 ? 50 : brightnessField.integerValue.u16
let currentContrast: UInt16 = contrastField.integerValue == 0 ? 50 : contrastField.integerValue.u16
let currentVolume: UInt16 = volume == 0 ? 50 : volume.u16
var brightnessWriteWorked = false
var contrastWriteWorked = false
var volumeWriteWorked = false
if let control = control as? DDCControl {
control.ignoreFaults = true
}
defer {
if let control = control as? DDCControl {
control.ignoreFaults = false
}
}
let setWriteProgress = { value in self.setControlProgress(0.5 + (0.5 * value)) }
info("Writing brightness", color: peach)
setWriteProgress(0.1)
guard wait(1.1) else { return .allWorked }
display.withBrightnessTransition(.slow) {
display.enabledControls[control.displayControl] = true
var newBr: UInt16 = currentBrightness != 0 ? (control.isSoftware ? 25 : 0) : 50
var oldBr: UInt16 = currentBrightness
let write1Worked = control.setBrightness(
newBr,
oldValue: oldBr,
force: true, transition: .smooth,
onChange: { [weak self] br in self?.setBrightness(br) }
)
if control.isSoftware, !display.supportsGamma {
setBrightness(newBr)
}
guard wait(4) else { return }
setWriteProgress(0.15)
oldBr = newBr
newBr = 75
let write2Worked = control.setBrightness(
newBr,
oldValue: oldBr,
force: true, transition: .smooth,
onChange: { [weak self] br in self?.setBrightness(br) }
)
if control.isSoftware, !display.supportsGamma {
setBrightness(newBr)
}
guard wait(4) else { return }
setWriteProgress(0.2)
oldBr = newBr
newBr = control.isSoftware ? 100 : 67
let write3Worked = control.setBrightness(
newBr,
oldValue: oldBr,
force: true, transition: .smooth,
onChange: { [weak self] br in self?.setBrightness(br) }
)
if control.isSoftware, !display.supportsGamma {
setBrightness(newBr)
}
brightnessWriteWorked = (write1Worked.i + write2Worked.i + write3Worked.i) >= 2
setWriteProgress(0.25)
}
guard !control.isSoftware || display.supportsGamma else {
setContrast(100)
setVolume(50)
setResult(contrastWriteResult, text: "Write not supported", color: peach)
setResult(volumeWriteResult, text: "Write not supported", color: peach)
return ControlWriteResult(brightness: true, contrast: false, volume: false)
}
if brightnessWriteWorked {
setResult(brightnessWriteResult, text: "Write seemed to work", color: peach)
askQuestion(
control.isSoftware
? "Was there any change in brightness on the tested display?"
: "Was there any change in brightness on the tested display?\nThe brightness value in the monitor settings should now be set to 67"
) { [weak self] itWorked in
guard let self else { return }
if itWorked {
setResult(brightnessWriteResult, text: "Write worked", color: green)
} else {
brightnessWriteWorked = false
setResult(brightnessWriteResult, text: "Failed to write", color: red)
}
}
} else {
setResult(brightnessWriteResult, text: "Failed to write", color: red)
}
guard wait(1.1) else { return .allWorked }
guard !control.isSoftware else {
setContrast(100)
setVolume(50)
setResult(contrastWriteResult, text: "Write not supported", color: peach)
setResult(volumeWriteResult, text: "Write not supported", color: peach)
return ControlWriteResult(brightness: true, contrast: false, volume: false)
}
setWriteProgress(0.3)
info("Writing contrast", color: peach)
guard wait(1.1) else { return .allWorked }
display.withBrightnessTransition {
setWriteProgress(0.35)
var newCr: UInt16 = currentContrast != 0 ? 0 : 50
var oldCr: UInt16 = currentContrast
let write1Worked = control.setContrast(
newCr,
oldValue: oldCr,
transition: .smooth,
onChange: { [weak self] br in self?.setContrast(br) }
)
guard wait(4) else { return }
setWriteProgress(0.4)
oldCr = newCr
newCr = 75
let write2Worked = control.setContrast(
newCr,
oldValue: oldCr,
transition: .smooth,
onChange: { [weak self] br in self?.setContrast(br) }
)
guard wait(4) else { return }
setWriteProgress(0.45)
oldCr = newCr
newCr = 67
let write3Worked = control.setContrast(
newCr,
oldValue: oldCr,
transition: .smooth,
onChange: { [weak self] br in self?.setContrast(br) }
)
contrastWriteWorked = (write1Worked.i + write2Worked.i + write3Worked.i) >= 2
setWriteProgress(0.5)
}
if contrastWriteWorked {
setResult(contrastWriteResult, text: "Write seemed to work", color: peach)
askQuestion(
"Was there any change in contrast on the tested display?\nThe contrast value in the monitor settings should now be set to 67"
) { [weak self] itWorked in
guard let self else { return }
if itWorked {
setResult(contrastWriteResult, text: "Write worked", color: green)
} else {
contrastWriteWorked = false
setResult(contrastWriteResult, text: "Failed to write", color: red)
}
}
} else {
setResult(contrastWriteResult, text: "Failed to write", color: red)
}
guard wait(1.1) else { return .allWorked }
setWriteProgress(0.55)
info("Writing volume", color: peach)
guard wait(1.1) else { return .allWorked }
setVolume(0)
let write1Worked = control.setVolume(0)
guard wait(1) else { return .allWorked }
setWriteProgress(0.6)
setVolume(75)
let write2Worked = control.setVolume(75)
guard wait(1) else { return .allWorked }
setWriteProgress(0.65)
setVolume(23)
let write3Worked = control.setVolume(23)
volumeWriteWorked = (write1Worked.i + write2Worked.i + write3Worked.i) >= 2
setWriteProgress(0.7)
if volumeWriteWorked {
setResult(volumeWriteResult, text: "Write seemed to work", color: peach)
askQuestion(
"Was there any change in volume on the tested display?\nThe volume value in the monitor settings should now be set to 23"
) { [weak self] itWorked in
guard let self else { return }
if itWorked {
setResult(volumeWriteResult, text: "Write worked", color: white)
} else {
volumeWriteWorked = false
setResult(volumeWriteResult, text: "Failed to write", color: peach)
}
}
} else {
setResult(volumeWriteResult, text: "Failed to write", color: red)
}
guard wait(1.1) else { return .allWorked }
setWriteProgress(0.8)
info("Setting values before test", color: peach)
guard wait(2) else { return .allWorked }
_ = control.setBrightness(currentBrightness, oldValue: nil, force: true, transition: .smooth, onChange: nil)
setBrightness(currentBrightness)
setWriteProgress(0.85)
guard wait(0.5) else { return .allWorked }
_ = control.setContrast(currentContrast, oldValue: nil, transition: .smooth, onChange: nil)
setContrast(currentContrast)
setWriteProgress(0.9)
guard wait(0.5) else { return .allWorked }
_ = control.setVolume(currentVolume)
setVolume(currentVolume)
setWriteProgress(0.95)
guard wait(0.5) else { return .allWorked }
return ControlWriteResult(brightness: brightnessWriteWorked, contrast: contrastWriteWorked, volume: volumeWriteWorked)
}
func wait(_ seconds: TimeInterval) -> Bool {
// #if DEBUG
// return !cancelled
// #endif
Thread.sleep(forTimeInterval: seconds)
return !cancelled
}
func testControlRead(_ control: Control, for _: Display) -> ControlReadResult {
var brightnessReadWorked = false
var contrastReadWorked = false
var volumeReadWorked = false
let setReadProgress = { value in self.setControlProgress(0.5 * value) }
guard !control.isSoftware else {
setBrightness(100)
setContrast(100)
setVolume(50)
setResult(brightnessReadResult, text: "Read not supported", color: peach)
setResult(contrastReadResult, text: "Read not supported", color: peach)
setResult(volumeReadResult, text: "Read not supported", color: peach)
return .allWorked
}
info("Reading brightness", color: peach)
guard wait(1.1) else { return .allWorked }
var brightnessThatWasRead: UInt16 = 0
if let br = (control.getBrightness() ?? control.getBrightness()), !(control is AppleNativeControl) || br <= 100 {
brightnessReadWorked = true
setBrightness(br)
brightnessThatWasRead = br
guard wait(1.1) else { return .allWorked }
setReadProgress(0.15)
setResult(brightnessReadResult, text: "Read worked", color: green)
guard wait(1.1) else { return .allWorked }
let _ = control.setBrightness(br, oldValue: nil, force: true, transition: .instant, onChange: nil)
} else {
setBrightness(0)
guard wait(1.1) else { return .allWorked }
setReadProgress(0.15)
// setResult(brightnessReadResult, text: "Failed to read", color: red)
guard wait(1.1) else { return .allWorked }
}
setReadProgress(0.33)
info("Reading contrast", color: peach)
guard wait(1.1) else { return .allWorked }
if let cr = (control.getContrast() ?? control.getContrast()) {
contrastReadWorked = true
setContrast(cr)
guard wait(1.1) else { return .allWorked }
setReadProgress(0.45)
setResult(contrastReadResult, text: "Read worked", color: green)
guard wait(1.1) else { return .allWorked }
if brightnessReadWorked {
let _ = control.setBrightness(brightnessThatWasRead, oldValue: nil, force: true, transition: .instant, onChange: nil)
} else {
let _ = control.setContrast(cr, oldValue: nil, transition: .instant, onChange: nil)
}
} else {
setContrast(0)
guard wait(1.1) else { return .allWorked }
setReadProgress(0.45)
// setResult(contrastReadResult, text: "Failed to read", color: red)
guard wait(1.1) else { return .allWorked }
}
setReadProgress(0.66)
info("Reading volume", color: peach)
guard wait(1.1) else { return .allWorked }
if let vol = (control.getVolume() ?? control.getVolume()) {
volumeReadWorked = true
setVolume(vol)
guard wait(1.1) else { return .allWorked }
setReadProgress(0.8)
setResult(volumeReadResult, text: "Read worked", color: white)
guard wait(1.1) else { return .allWorked }
} else {
setVolume(0)
guard wait(1.1) else { return .allWorked }
setReadProgress(0.8)
// setResult(volumeReadResult, text: "Failed to read", color: peach)
guard wait(1.1) else { return .allWorked }
}
setReadProgress(0.9)
return ControlReadResult(brightness: brightnessReadWorked, contrast: contrastReadWorked, volume: volumeReadWorked)
}
func hideDisplayValues() {
mainThread {
brightnessField.transition(0.5, easing: .easeOutExpo)
brightnessField.alphaValue = 0
brightnessCaption.transition(0.5, easing: .easeOutExpo)
brightnessCaption.alphaValue = 0
contrastField.transition(0.5, easing: .easeOutExpo)
contrastField.alphaValue = 0
contrastCaption.transition(0.5, easing: .easeOutExpo)
contrastCaption.alphaValue = 0
brightnessReadResult.transition(0.5, easing: .easeOutExpo)
brightnessReadResult.alphaValue = 0
brightnessWriteResult.transition(0.5, easing: .easeOutExpo)
brightnessWriteResult.alphaValue = 0
contrastReadResult.transition(0.5, easing: .easeOutExpo)
contrastReadResult.alphaValue = 0
contrastWriteResult.transition(0.5, easing: .easeOutExpo)
contrastWriteResult.alphaValue = 0
volumeSlider.transition(0.5, easing: .easeOutExpo)
volumeSlider.alphaValue = 0
volumeReadResult.transition(0.5, easing: .easeOutExpo)
volumeReadResult.alphaValue = 0
volumeWriteResult.transition(0.5, easing: .easeOutExpo)
volumeWriteResult.alphaValue = 0
}
}
func queueChange(_ change: @escaping () -> Void) {
mainThread {
guard let wc = view.window?.windowController as? OnboardWindowController else {
return
}
wc.changes.append(change)
}
}
func next() {
guard let wc = view.window?.windowController as? OnboardWindowController else { return }
wc.applyChanges()
wc.pageController?.navigateForward(self)
}
func showTestWindow() {
guard let d = currentDisplay else { return }
mainThread {
createWindow(
"testWindowController",
controller: &d.testWindowController,
screen: d.nsScreen,
show: true,
backgroundColor: .clear,
level: .screenSaver,
fillScreen: false,
stationary: true
)
}
wakeObserver = wakeObserver ?? NSWorkspace.shared.notificationCenter
.publisher(for: NSWorkspace.screensDidWakeNotification, object: nil)
.debounce(for: .seconds(2), scheduler: RunLoop.main)
.sink { [weak self] _ in
self?.showTestWindow()
}
screenObserver = screenObserver ?? NotificationCenter.default
.publisher(for: NSApplication.didChangeScreenParametersNotification, object: nil)
.debounce(for: .seconds(2), scheduler: RunLoop.main)
.sink { [weak self] _ in
self?.showTestWindow()
}
}
func networkProblemText(_ display: Display, control _: NetworkControl) -> String {
var url = "http://<your-rpi-ip>:3485/displays"
if let networkController = NetworkControl.controllersForDisplay[display.serial], let controlURL = networkController.url {
url = controlURL.deletingLastPathComponent().appendingPathComponent("displays").absoluteString
}
let infoDict = display.infoDictionary
let year = (infoDict[kDisplayYearOfManufacture] as? Int64) ?? 2017
let serial = (infoDict[kDisplaySerialNumber] as? Int64) ?? 314_041
let product = (infoDict[kDisplayProductID] as? Int64) ?? 23304
let vendor = (infoDict[kDisplayVendorID] as? Int64)?.s ?? "GSM"
let name = display.edidName
return """
##### If you have technical knowledge about `SSH` and `curl`, you can check the following:
* See if the controller is reachable using this curl command: `curl \(url)`
* You should get a response similar to the one below:
Display 1
I2C bus: /dev/i2c-2
EDID synopsis:
Mfg id: \(vendor)
Model: \(name)
Product code: \(product)
Serial number:
Binary serial number: \(serial)
Manufacture year: \(year)
EDID version: 1.3
VCP version: 2.1
* If you get `Invalid Display` try turning your monitor off then turn it on after a few seconds
* If you get `Display not found`, make sure your Pi is running an OS with a desktop environment, and the desktop is visible when the Pi HDMI input is active
* Check that the server is running
* SSH into your Pi
* Run `sudo systemctl status ddcutil-server`
* Check if `ddcutil` can correctly identify and control your monitor
* SSH into your Pi
* Run `ddcutil detect` _(you should get the same response as for the `curl` command)_
* Cycle through a few brightness values to see if there's any change:
* `ddcutil setvcp 0x10 25`
* `ddcutil setvcp 0x10 100`
* `ddcutil setvcp 0x10 50`
"""
}
func setDisplayProgress(_ value: Double, controlStep: Double) {
mainThread {
progress = progressForLastDisplay + displayProgressStep * value
controlProgressStep = controlStep
progressForDisplay = value
}
}
func setControlProgress(_ value: Double) {
mainThread {
progress = progressForLastDisplay + displayProgressStep * progressForDisplay + value *
(controlProgressStep * displayProgressStep * progressForDisplay)
}
}
func listenForDisplayConnections() {
NotificationCenter.default
.publisher(for: displayListChanged, object: nil)
.debounce(for: .seconds(2), scheduler: RunLoop.main)
.sink { [weak self] _ in
self?.cancelled = true
OnboardPageController.task?.cancel()
log.debug("Restarting Onboarding after display list change")
guard let w = self?.view.window else { return }
_ = askBool(
message: "Display list changed",
info: """
The list of connected displays has changed
and the onboarding process can't continue.
Do you want to restart the onboarding process?
""",
okButton: "Restart Onboarding",
cancelButton: "Skip Onboarding",
window: w,
onCompletion: { [weak self] (restart: Bool) in
guard let self, let w = view.window, let wc = w.windowController as? OnboardWindowController else {
return
}
cancelled = true
OnboardPageController.task?.cancel()
semaphore.signal()
wc.changes = []
w.close()
wc.close()
for d in DC.displays.values {
d.testWindowController?.close()
d.testWindowController = nil
}
if restart {
mainAsyncAfter(ms: 1000) { appDelegate!.onboard() }
}
},
unique: true,
waitTimeout: 5.minutes
)
}.store(in: &observers)
}
override func viewDidAppear() {
guard !didAppear else { return }
didAppear = true
uiCrumb("Control Tester")
cancelled = false
adaptiveModeDisabledByDiagnostics = false
if DC.adaptiveModeKey != .manual {
DC.disable()
adaptiveModeDisabledByDiagnostics = true
}
listenForDisplayConnections()
if let wc = view.window?.windowController as? OnboardWindowController {
wc.setupSkipButton(skipButton, text: useOnboardingForDiagnostics ? "Stop Diagnostics" : nil) { [weak self] in
self?.cancelled = true
for d in DC.displays.values {
d.testWindowController?.close()
d.testWindowController = nil
}
self?.wakeObserver?.cancel()
self?.wakeObserver = nil
self?.screenObserver?.cancel()
self?.screenObserver = nil
self?.semaphore.signal()
guard useOnboardingForDiagnostics else { return }
self?.skipButton.isEnabled = false
self?.skipButton.attributedTitle = "Stopping".withTextColor(.black)
mainAsyncAfter(ms: 1500) {
self?.view.window?.close()
if adaptiveModeDisabledByDiagnostics {
DC.enable()
}
}
}
}
OnboardPageController.task = concurrentQueue.asyncAfter(ms: 10, name: ONBOARDING_TASK_KEY) { [weak self] in
let displays = DC.externalDisplaysForTest
guard let self, !self.cancelled, !OnboardPageController.task.isCancelled, let firstDisplay = displays.first else {
return
}
mainThread {
self.displayName.transition(0.5, easing: .easeOutExpo)
self.displayName.alphaValue = 1.0
self.displayName.display = firstDisplay
self.setControl(firstDisplay.getBestControl(reapply: false).displayControl, display: firstDisplay)
}
waitForAction(
"Lunar will try to read and then change the monitor brightness, contrast and volume\nIf Lunar can't revert the changes, you can do that by using the monitor's physical buttons",
buttonColor: lunarYellow, buttonText: "Continue".withTextColor(mauve)
) {}
displayProgressStep = 1.0 / displays.count.d
for (i, d) in displays.enumerated() {
testDisplay(d, index: i)
}
queueChange {
DC.externalActiveDisplays.forEach { $0.resetControl() }
}
mainThread {
for d in DC.displays.values {
d.testWindowController?.close()
d.testWindowController = nil
}
if useOnboardingForDiagnostics, self.cancelled { return }
self.next()
}
}
}
func testDisplay(_ d: Display, index: Int) {
for d in DC.displays.values {
d.testWindowController?.close()
d.testWindowController = nil
}
guard !cancelled else { return }
progressForLastDisplay = displayProgressStep * index.d
setDisplayProgress(0, controlStep: 0.25)
defer { self.progress = self.displayProgressStep * (index + 1).d }
currentDisplay = d
// showTestWindow()
mainThread {
self.displayName.transition(0.5, easing: .easeOutExpo)
self.displayName.alphaValue = 1.0
self.displayName.display = d
}
let networkControl = NetworkControl(display: d)
let appleNativeControl = AppleNativeControl(display: d)
let ddcControl = DDCControl(display: d)
let gammaControl = GammaControl(display: d)
var result = ControlResult.noneWorked
defer { d.controlResult = result }
if appleNativeControl.isAvailable(), !cancelled {
setControl(.appleNative, display: d)
result = testControl(appleNativeControl, for: d)
setDisplayProgress(0.25, controlStep: 0.25)
if !result.write.brightness, d.isLEDCinema || d.isCinema {
var nextStep = true
askQuestion(
"On Cinema displays, you need to plug in the USB cable to get brightness controls\nYou can try that now and retry the test, or continue to the next step",
yesButtonText: "Next", noButtonText: "Retry"
) { nextStep = $0 }
if nextStep {
queueChange {
d.enabledControls[.appleNative] = false
d.save()
}
} else {
setDisplayProgress(0, controlStep: 0.25)
result = testControl(appleNativeControl, for: d)
setDisplayProgress(0.25, controlStep: 0.25)
}
}
} else { setDisplayProgress(0.25, controlStep: 0.25) }
if result.write.all {
waitForAction(
"The monitor is fully functional and ready to be used with Lunar",
buttonColor: lunarYellow, buttonText: "Next step".withTextColor(mauve)
) {}
return
} else if result.write.brightness {
waitForAction(
"The monitor supports brightness controls and is ready to be used with Lunar",
buttonColor: lunarYellow, buttonText: "Next step".withTextColor(mauve)
) {}
return
}
ddcBlockersButton?.md.code.fontSize = 15
if ddcControl.isAvailable(), !cancelled {
setControl(.ddc, display: d)
result = testControl(ddcControl, for: d)
setDisplayProgress(0.5, controlStep: 0.25)
var nextStep = false
while !result.write.brightness, !nextStep {
askQuestion(
"Some monitor settings can block brightness controls\nYou can try changing the listed settings and then retry the test",
yesButtonText: "Next", noButtonText: "Retry",
ddcBlockerText: d.possibleDDCBlockers()
) { nextStep = $0 }
if nextStep {
// let ddcEnabled = result.write.volume || result.write.contrast
queueChange {
d.enabledControls[.ddc] = false
d.enabledControls[.gamma] = true
d.save()
}
} else {
setDisplayProgress(0.25, controlStep: 0.25)
result = testControl(ddcControl, for: d)
setDisplayProgress(0.5, controlStep: 0.25)
}
}
} else { setDisplayProgress(0.5, controlStep: 0.25) }
if result.write.all {
waitForAction(
"The monitor is fully functional and ready to be used with Lunar",
buttonColor: lunarYellow, buttonText: "Next step".withTextColor(mauve)
) {}
return
} else if result.write.brightness {
waitForAction(
"The monitor supports brightness controls and is ready to be used with Lunar\nUnfortunately, not all monitors support \(result.write.volume ? "contrast" : "volume") controls",
buttonColor: lunarYellow, buttonText: "Next step".withTextColor(mauve)
) {}
return
}
ddcBlockersButton?.md.code.fontSize = 13
if networkControl.isAvailable(), !cancelled {
setControl(.network, display: d)
result = testControl(networkControl, for: d)
setDisplayProgress(0.75, controlStep: 0.25)
var nextStep = false
while !result.write.brightness, !nextStep {
askQuestion(
"The assigned network controller wasn't able to control this monitor",
yesButtonText: "Next", noButtonText: "Retry",
ddcBlockerText: networkProblemText(d, control: networkControl)
) { nextStep = $0 }
if !nextStep {
setDisplayProgress(0.5, controlStep: 0.25)
result = testControl(ddcControl, for: d)
setDisplayProgress(0.75, controlStep: 0.25)
}
}
} else { setDisplayProgress(0.75, controlStep: 0.1) }
if result.write.all {
waitForAction(
"The monitor is fully functional and ready to be used with Lunar",
buttonColor: lunarYellow, buttonText: "Next step".withTextColor(mauve)
) {}
return
} else if result.write.brightness {
waitForAction(
"The monitor supports brightness controls and is ready to be used with Lunar",
buttonColor: lunarYellow, buttonText: "Next step".withTextColor(mauve)
) {}
return
}
setControl(.gamma, display: d)
result = testControl(gammaControl, for: d)
setDisplayProgress(0.8, controlStep: 0.1)
if d.supportsGamma, !result.write.brightness {
d.useOverlay = true
setControl(.gamma, display: d)
result = testControl(gammaControl, for: d)
setDisplayProgress(0.9, controlStep: 0.1)
}
waitForAction(
"The monitor only supports software brightness dimming\nThe monitor's brightness should be set to its highest values manually using its physical buttons",
buttonColor: lunarYellow, buttonText: "Next step".withTextColor(mauve)
) {}
}
override func viewDidLoad() {
super.viewDidLoad()
hideDisplayValues()
hideAction()
hideQuestion()
noButton.bg = red
noButton.attributedTitle = "No".withTextColor(white)
yesButton.bg = green
yesButton.attributedTitle = "Yes".withTextColor(white)
displayImage?.cornerRadius = 16
displayImage?.standColor = peach
displayImage?.screenColor = rouge
actionLabel.textColor = actionLabelColor
actionInfo.alphaValue = 0.0
volumeSlider.minValue = 0
volumeSlider.maxValue = 100
volumeSlider.isEnabled = false
volumeSlider.isHidden = true
if let controlButton {
controlButton.isEnabled = false
controlButton.isHidden = true
}
if let ddcBlockersButton {
ddcBlockersButton.isEnabled = false
ddcBlockersButton.isHidden = true
}
POPOVERS["help"]!?.appearance = NSAppearance(named: .vibrantDark)
}
}
[workspace]
members = ["crates/vfox", "crates/aqua-registry"]
[package]
name = "mise"
version = "2026.1.2"
edition = "2024"
description = "The front-end to your dev env"
authors = ["Jeff Dickey (@jdx)"]
homepage = "https://mise.jdx.dev"
documentation = "https://mise.jdx.dev"
repository = "https://github.com/jdx/mise"
readme = "README.md"
license = "MIT"
keywords = ["mise"]
categories = ["command-line-utilities"]
include = [
"/Cargo.lock",
"/LICENSE",
"/README.md",
"/build.rs",
"/completions/*",
"/minisign.pub",
"/registry.toml",
"/settings.toml",
"/zipsign.pub",
"/src/**/*.rs",
"/src/assets/**",
"/src/plugins/core/assets/**",
]
build = "build.rs"
rust-version = "1.88"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[[bin]]
name = "mise"
path = "src/main.rs"
#[[bench]]
#name = "config_bench"
#harness = false
[profile.release]
# debug = 0 # note that higher levels greatly increase the binary size for linux
[profile.serious]
inherits = "release"
lto = true
[profile.dev.package.backtrace]
opt-level = 3
[dependencies]
age = { version = "0.11", features = ["ssh"] }
anyhow = "1.0.100"
async-backtrace = "0.2"
async-trait = "0.1"
aws-config = { version = "1.5", default-features = false, features = [
"behavior-version-latest",
"rustls",
"rt-tokio",
] }
aws-lc-rs = { version = "1", optional = true, features = [
"bindgen",
] } # TODO: this is only for armv7 currently
aws-sdk-s3 = { version = "1.55", default-features = false, features = [
"behavior-version-latest",
"rustls",
] }
base64 = "0.22"
bzip2 = "0.6"
calm_io = "0.1"
chrono = { version = "0.4", default-features = false, features = [
"std",
"clock",
] }
ci_info = "0.14"
clap = { version = "4", features = ["env", "derive", "string"] }
color-eyre = "0.6"
color-print = "0.3"
comfy-table = "7.1.3"
confique = { version = "0.3", default-features = false }
console = "0.16"
contracts = "0.6"
dashmap = "6"
demand = "1"
digest = "0.10.7"
dotenvy = "0.15"
duct = "0.13"
homedir = "0.3"
eyre = "0.6"
filetime = "0.2"
flate2 = "1"
sigstore-verification = { version = "0.1", default-features = false }
fslock = "0.2.1"
fuzzy-matcher = "0.3"
gix = { version = "<1", features = ["worktree-mutation"] }
glob = "0.3"
globset = "0.4"
ignore = { version = "0.4", features = [] }
heck = "0.5"
humansize = "2"
indenter = "0.3"
indexmap = { version = "2", features = ["serde"] }
indicatif = { version = "0.18", features = ["improved_unicode"] }
indoc = "2"
itertools = "0.14"
jiff = "0.2"
junction = "1"
log = "0.4"
minisign-verify = "0.2"
md-5 = "0.10"
netrc-rs = "0.1"
num_cpus = "1"
number_prefix = "0.4"
once_cell = "1"
openssl = { version = "0.10", optional = true }
os-release = "0.1"
path-absolutize = { version = "3", features = ["unsafe_cache"] }
petgraph = "0.8"
rand = "0.9"
regex = "1"
reqwest = { version = "0.12", default-features = false, features = [
"json",
"gzip",
"zstd",
"charset",
"http2",
"socks",
"macos-system-configuration",
] }
rmcp = { version = "0.3", features = ["server", "transport-io", "schemars"] }
rmcp-macros = "0.3"
rmp-serde = "1"
rops = { version = "0.1", default-features = false, features = [
"aes-gcm",
"sha2",
"yaml",
"json",
"age",
] }
serde = "1"
serde_derive = "1"
serde_ignored = "0.1"
serde_json = "1"
serde_yaml = "0.9"
sha1 = "0.10"
sha2 = "0.10"
blake3 = "1"
shell-escape = "0.1"
shell-words = "1"
signal-hook = "0.3"
siphasher = "1"
strum = { version = "0.27", features = ["derive"] }
sys-info = "0.9"
tabled = { version = "0.20", features = ["ansi"] }
taplo = "0.14"
tar = "0.4"
tempfile = "3"
tera = "1"
terminal_size = "0.4"
thiserror = "2"
tokio = { version = "1", features = ["full"] }
tokio-retry = "0.3"
toml = { version = "0.8", features = ["parse"] }
toml_edit = { version = "0.22", features = ["parse"] }
ubi = { version = "0.8", default-features = false }
url = "2"
urlencoding = "2.1.3"
usage-lib = { version = "2", features = ["clap", "docs"] }
versions = { version = "6", features = ["serde"] }
vfox = { path = "crates/vfox", default-features = false }
aqua-registry = { path = "crates/aqua-registry" }
walkdir = "2"
which = "7"
xx = { version = "2", default-features = false, features = ["glob"] }
xz2 = "0.1"
zip = { version = "3", default-features = false, features = ["deflate"] }
zstd = "0.13"
[target.'cfg(unix)'.dependencies]
exec = "0.3"
nix = { version = "0.30", features = ["signal", "user"] }
self_update = { version = "0.42", optional = true, default-features = false, features = [
"archive-tar",
"compression-flate2",
"signatures",
"rustls",
] }
[target.'cfg(windows)'.dependencies]
self_update = { version = "0.42", optional = true, default-features = false, features = [
"archive-zip",
"compression-zip-deflate",
"signatures",
"rustls",
] }
sevenz-rust = "0.6"
winapi = { version = "0.3.9", features = ["consoleapi", "minwindef"] }
[build-dependencies]
built = { version = "0.8", features = ["chrono"] }
cfg_aliases = "0.2"
heck = "0.5"
toml = "0.8"
indexmap = "2"
serde_yaml = "0.9"
[dev-dependencies]
clap-sort = "1"
ctor = "0.4"
insta = { version = "1", features = ["filters", "json"] }
mockito = "1.6.1"
pretty_assertions = "1"
test-log = "0.2"
[features]
default = ["native-tls", "vfox/vendored-lua", "self_update"]
native-tls = [
"gix/blocking-http-transport-reqwest-native-tls",
"reqwest/native-tls",
"sigstore-verification/native-tls",
"ubi/native-tls",
"vfox/native-tls",
"xx/native-tls",
]
rustls = [
"gix/blocking-http-transport-reqwest-rust-tls",
"reqwest/rustls-tls",
"self_update/rustls",
"sigstore-verification/rustls",
"ubi/rustls-tls",
"vfox/rustls",
"xx/rustls",
]
rustls-native-roots = [
"gix/blocking-http-transport-reqwest-rust-tls",
"reqwest/rustls-tls-native-roots",
"self_update/rustls",
"sigstore-verification/rustls-native-roots",
"ubi/rustls-tls-native-roots",
"vfox/rustls-native-roots",
"xx/rustls-native-roots",
]
[package.metadata.binstall]
bin-dir = "mise/bin/mise"
[package.metadata.binstall.overrides.aarch64-apple-darwin]
pkg-url = "{ repo }/releases/download/v{ version }/mise-v{version}-macos-arm64{ archive-suffix }"
[package.metadata.binstall.overrides.x86_64-apple-darwin]
pkg-url = "{ repo }/releases/download/v{ version }/mise-v{version}-macos-x64{ archive-suffix }"
[package.metadata.binstall.overrides.aarch64-unknown-linux-gnu]
pkg-url = "{ repo }/releases/download/v{ version }/mise-v{version}-linux-arm64{ archive-suffix }"
[package.metadata.binstall.overrides.x86_64-unknown-linux-gnu]
pkg-url = "{ repo }/releases/download/v{ version }/mise-v{version}-linux-x64{ archive-suffix }"
[package.metadata.binstall.overrides.armv7-unknown-linux-gnueabihf]
pkg-url = "{ repo }/releases/download/v{ version }/mise-v{version}-linux-armv7{ archive-suffix }"
[package.metadata.cargo-machete]
ignored = ["aws-lc-rs", "built", "cfg_aliases", "openssl", "rmcp-macros"]
[package.metadata.release]
pre-release-replacements = [
{ file = "docs/installing-mise.md", search = "MISE_VERSION=v[0-9]+\\.[0-9]+\\.[0-9]+", replace = "MISE_VERSION=v{{version}}" },
{ file = "docs/installing-mise.md", search = "/download/v[0-9]+\\.[0-9]+\\.[0-9]+/mise-v[0-9]+\\.[0-9]+\\.[0-9]+-linux-x64", replace = "/download/v{{version}}/mise-v{{version}}-linux-x64" },
]
[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = [
'cfg(coverage,coverage_nightly)',
] }
[lints.clippy]
borrowed_box = "allow"
import { relative } from 'pathe'
import { parseAstAsync } from 'vite'
import { ancestor as walkAst } from 'acorn-walk'
import type { RawSourceMap } from 'vite-node'
import { calculateSuiteHash, generateHash, interpretTaskModes, someTasksAreOnly } from '@vitest/runner/utils'
import type { File, Suite, Test } from '../types'
import type { WorkspaceProject } from '../node/workspace'
interface ParsedFile extends File {
start: number
end: number
}
interface ParsedTest extends Test {
start: number
end: number
}
interface ParsedSuite extends Suite {
start: number
end: number
}
interface LocalCallDefinition {
start: number
end: number
name: string
type: 'suite' | 'test'
mode: 'run' | 'skip' | 'only' | 'todo'
task: ParsedSuite | ParsedFile | ParsedTest
}
export interface FileInformation {
file: File
filepath: string
parsed: string
map: RawSourceMap | null
definitions: LocalCallDefinition[]
}
export async function collectTests(ctx: WorkspaceProject, filepath: string): Promise<null | FileInformation> {
const request = await ctx.vitenode.transformRequest(filepath, filepath)
if (!request)
return null
const ast = await parseAstAsync(request.code)
const testFilepath = relative(ctx.config.root, filepath)
const file: ParsedFile = {
filepath,
type: 'suite',
id: generateHash(`${testFilepath}${ctx.config.name || ''}`),
name: testFilepath,
mode: 'run',
tasks: [],
start: ast.start,
end: ast.end,
projectName: ctx.getName(),
meta: { typecheck: true },
}
const definitions: LocalCallDefinition[] = []
const getName = (callee: any): string | null => {
if (!callee)
return null
if (callee.type === 'Identifier')
return callee.name
if (callee.type === 'MemberExpression') {
// direct call as `__vite_ssr_exports_0__.test()`
if (callee.object?.name?.startsWith('__vite_ssr_'))
return getName(callee.property)
// call as `__vite_ssr__.test.skip()`
return getName(callee.object?.property)
}
return null
}
walkAst(ast as any, {
CallExpression(node) {
const { callee } = node as any
const name = getName(callee)
if (!name)
return
if (!['it', 'test', 'describe', 'suite'].includes(name))
return
const { arguments: [{ value: message }] } = node as any
const property = callee?.property?.name
let mode = (!property || property === name) ? 'run' : property
if (!['run', 'skip', 'todo', 'only', 'skipIf', 'runIf'].includes(mode))
throw new Error(`${name}.${mode} syntax is not supported when testing types`)
// cannot statically analyze, so we always skip it
if (mode === 'skipIf' || mode === 'runIf')
mode = 'skip'
definitions.push({
start: node.start,
end: node.end,
name: message,
type: (name === 'it' || name === 'test') ? 'test' : 'suite',
mode,
} as LocalCallDefinition)
},
})
let lastSuite: ParsedSuite = file
const updateLatestSuite = (index: number) => {
while (lastSuite.suite && lastSuite.end < index)
lastSuite = lastSuite.suite as ParsedSuite
return lastSuite
}
definitions.sort((a, b) => a.start - b.start).forEach((definition) => {
const latestSuite = updateLatestSuite(definition.start)
let mode = definition.mode
if (latestSuite.mode !== 'run') // inherit suite mode, if it's set
mode = latestSuite.mode
if (definition.type === 'suite') {
const task: ParsedSuite = {
type: definition.type,
id: '',
suite: latestSuite,
file,
tasks: [],
mode,
name: definition.name,
end: definition.end,
start: definition.start,
projectName: ctx.getName(),
meta: {
typecheck: true,
},
}
definition.task = task
latestSuite.tasks.push(task)
lastSuite = task
return
}
const task: ParsedTest = {
type: definition.type,
id: '',
suite: latestSuite,
file,
mode,
context: {} as any, // not used in typecheck
name: definition.name,
end: definition.end,
start: definition.start,
meta: {
typecheck: true,
},
}
definition.task = task
latestSuite.tasks.push(task)
})
calculateSuiteHash(file)
const hasOnly = someTasksAreOnly(file)
interpretTaskModes(file, ctx.config.testNamePattern, hasOnly, false, ctx.config.allowOnly)
return {
file,
parsed: request.code,
filepath,
map: request.map as RawSourceMap | null,
definitions,
}
}
<!DOCTYPE html>
<html
lang="en"
data-color-mode="auto" data-light-theme="light" data-dark-theme="dark"
data-a11y-animated-images="system" data-a11y-link-underlines="true"
>
<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" rel="preload" as="script" href="https://github.githubassets.com/assets/global-banner-disable-54e442fb573b.js" />
<link rel="preload" href="https://github.githubassets.com/assets/mona-sans-14595085164a.woff2" as="font" type="font/woff2" crossorigin>
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/light-dac525bbd821.css" /><link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/light_high_contrast-56ccf4057897.css" /><link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/dark-784387e86ac0.css" /><link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/dark_high_contrast-79bd5fd84a86.css" /><link data-color-theme="light" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light-dac525bbd821.css" /><link data-color-theme="light_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_high_contrast-56ccf4057897.css" /><link data-color-theme="light_colorblind" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_colorblind-0e24752a7d2b.css" /><link data-color-theme="light_colorblind_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_colorblind_high_contrast-412af2517363.css" /><link data-color-theme="light_tritanopia" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_tritanopia-6186e83663dc.css" /><link data-color-theme="light_tritanopia_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_tritanopia_high_contrast-9d33c7aea2e7.css" /><link data-color-theme="dark" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark-784387e86ac0.css" /><link data-color-theme="dark_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_high_contrast-79bd5fd84a86.css" /><link data-color-theme="dark_colorblind" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_colorblind-75db11311555.css" /><link data-color-theme="dark_colorblind_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_colorblind_high_contrast-f2c1045899a2.css" /><link data-color-theme="dark_tritanopia" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_tritanopia-f46d293c6ff3.css" /><link data-color-theme="dark_tritanopia_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_tritanopia_high_contrast-e4b5684db29d.css" /><link data-color-theme="dark_dimmed" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_dimmed-72c58078e707.css" /><link data-color-theme="dark_dimmed_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_dimmed_high_contrast-956cb5dfcb85.css" />
<style type="text/css">
:root {
--tab-size-preference: 4;
}
pre, code {
tab-size: var(--tab-size-preference);
}
</style>
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-primitives-c37d781e2da5.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-dc3bfaf4b78e.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/global-b0ea6cebe9c5.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/github-7b2c79a47cf5.css" />
<script type="application/json" id="client-env">{"locale":"en","featureFlags":["a11y_status_checks_ruleset","actions_custom_images_public_preview_visibility","actions_custom_images_storage_billing_ui_visibility","actions_enable_snapshot_keyword","actions_image_version_event","actions_workflow_language_service","allow_react_navs_in_turbo","alternate_user_config_repo","api_insights_show_missing_data_banner","arianotify_comprehensive_migration","arianotify_partial_migration","codespaces_prebuild_region_target_update","coding_agent_model_selection","contentful_lp_footnotes","copilot_3p_agent_hovercards","copilot_agent_cli_public_preview","copilot_agent_sessions_alive_updates","copilot_agent_task_list_v2","copilot_agent_tasks_btn_code_nav","copilot_agent_tasks_btn_code_view","copilot_agent_tasks_btn_code_view_lines","copilot_agent_tasks_btn_repo","copilot_api_agentic_issue_marshal_yaml","copilot_chat_agents_empty_state","copilot_chat_attach_multiple_images","copilot_chat_clear_model_selection_for_default_change","copilot_chat_file_redirect","copilot_chat_input_commands","copilot_chat_opening_thread_switch","copilot_chat_reduce_quota_checks","copilot_chat_search_bar_redirect","copilot_chat_selection_attachments","copilot_chat_vision_in_claude","copilot_chat_vision_preview_gate","copilot_coding_agent_task_response","copilot_custom_copilots","copilot_custom_copilots_feature_preview","copilot_duplicate_thread","copilot_extensions_hide_in_dotcom_chat","copilot_extensions_removal_on_marketplace","copilot_features_raycast_logo","copilot_file_block_ref_matching","copilot_ftp_hyperspace_upgrade_prompt","copilot_icebreakers_experiment_dashboard","copilot_icebreakers_experiment_hyperspace","copilot_immersive_draft_issue_persist_edited_issues_in_session","copilot_immersive_generate_thread_name_async","copilot_immersive_job_result_preview","copilot_immersive_structured_model_picker","copilot_immersive_task_hyperlinking","copilot_immersive_task_within_chat_thread","copilot_org_policy_page_focus_mode","copilot_redirect_header_button_to_agents","copilot_security_alert_assignee_options","copilot_share_active_subthread","copilot_spaces_ga","copilot_spaces_individual_policies_ga","copilot_spaces_public_access_to_user_owned_spaces","copilot_spaces_read_access_to_user_owned_spaces","copilot_spaces_report_abuse","copilot_spark_empty_state","copilot_spark_handle_nil_friendly_name","copilot_spark_loading_webgl","copilot_stable_conversation_view","copilot_swe_agent_progress_commands","copilot_swe_agent_use_subagents","copilot_unconfigured_is_inherited","dashboard_lists_max_age_filter","dashboard_universe_2025_feedback_dialog","dom_node_counts","dotcom_chat_client_side_skills","enterprise_ai_controls","failbot_report_error_react_apps_on_page","fetch_graphql_ignore_fetch_network_errors","fetch_graphql_improved_error_serialization","flex_cta_groups_mvp","global_nav_react_edit_status_dialog","global_nav_react_feature_preview","global_nav_react_teams_settings_page","global_nav_react_top_repos_api_caching","global_nav_repo_picker_debounce","hyperspace_2025_logged_out_batch_1","initial_per_page_pagination_updates","issue_fields_global_search","issue_fields_report_usage","issue_fields_timeline_events","issues_cca_assign_actor_with_agent","issues_check_is_repository_writable","issues_expanded_file_types","issues_lazy_load_comment_box_suggestions","issues_preheating_dependency_issues","issues_preheating_issue_row","issues_preheating_parent_issue","issues_preheating_secondary","issues_preheating_sub_issues","issues_preheating_timeline_issues","issues_react_bots_timeline_pagination","issues_react_chrome_container_query_fix","issues_react_client_side_caching_analytics","issues_react_extended_preheat_analytics","issues_react_label_picker_debounce_filter","issues_react_labelpicker_patch","issues_react_prohibit_title_fallback","issues_react_use_turbo_for_cross_repo_navigation","issues_report_sidebar_interactions","lifecycle_label_name_updates","marketing_pages_search_explore_provider","memex_default_issue_create_repository","memex_grouped_by_edit_route","memex_mwl_filter_field_delimiter","mission_control_retry_on_401","mission_control_safe_token_clearing","mission_control_use_body_html","open_agent_session_in_vscode_insiders","open_agent_session_in_vscode_stable","primer_react_css_has_selector_perf","projects_assignee_max_limit","react_fetch_graphql_ignore_expected_errors","react_profile_user_status_dialog_enabled","react_quality_profiling","repo_insights_all_traffic_endpoint","report_hydro_web_vitals","repos_insights_remove_new_url","ruleset_deletion_confirmation","sample_network_conn_type","scheduled_reminders_updated_limits","site_calculator_actions_2025","site_features_copilot_universe","site_homepage_collaborate_video","site_homepage_contentful","site_homepage_eyebrow_banner","site_homepage_universe_animations","site_msbuild_webgl_hero","spark_prompt_secret_scanning","swe_agent_member_requests","viewscreen_sandbox","webp_support","workbench_store_readonly"],"copilotApiOverrideUrl":"https://api.githubcopilot.com"}</script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/high-contrast-cookie-ff2c933fbe48.js"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/wp-runtime-1d2f772a7e01.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/78298-e2b301acbc0e.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/6488-de87864e6818.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/82075-c5b5bf3f158d.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/environment-fb24decbee45.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/97068-2c8e697c6e8c.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/43784-4652ae97a661.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/4712-6fc930a63a4b.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/81028-5b8c5e07a4fa.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/74911-685dab44ed4d.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/99408-a4ed1d221779.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/78143-31968346cf4c.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/62598-07a9878cbf11.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/github-elements-14c2af6d6bff.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/element-registry-2a031d8f47b9.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/react-core-9b41b6bf6faf.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/react-lib-b492ee0e2c35.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/28546-ee41c9313871.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/17688-a9e16fb5ed13.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/45176-3d9a8d00775d.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/15938-1bc2c363d5ed.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/70191-36bdeb9f5eb6.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/7332-5ea4ccf72018.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/3561-e764c1759fbd.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/24077-adc459723b71.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/51519-d05cf6658c87.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/27376-4ba8ab45cab5.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/96384-750ef5263abe.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/19718-302da6273821.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/behaviors-681abc150f1e.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/37911-b2d07a4c84b0.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/notifications-global-d4747c5b0c07.js" defer="defer"></script>
<title>Page not found · GitHub · GitHub</title>
<meta name="route-pattern" content="/:user_id/:repository/raw/*name(/*path)" data-turbo-transient>
<meta name="route-controller" content="blob" data-turbo-transient>
<meta name="route-action" content="raw" data-turbo-transient>
<meta name="fetch-nonce" content="v2:34f7bc2e-9efa-ec3c-e14b-cdf1cd14b01d">
<meta name="current-catalog-service-hash" content="f3abb0cc802f3d7b95fc8762b94bdcb13bf39634c40c357301c4aa1d67a256fb">
<meta name="request-id" content="83C7:1802EE:2D57B36:2DE2FEF:69683247" data-turbo-transient="true" /><meta name="html-safe-nonce" content="a50952f58bac8c38b5bdb43e97a812646c30e50e8bc95d3308ea919090e6da89" data-turbo-transient="true" /><meta name="visitor-payload" content="eyJyZWZlcnJlciI6bnVsbCwicmVxdWVzdF9pZCI6IjgzQzc6MTgwMkVFOjJENTdCMzY6MkRFMkZFRjo2OTY4MzI0NyIsInZpc2l0b3JfaWQiOiI4NjQ4MjUxMTQ4NjEyNDE2MDcxIiwicmVnaW9uX2VkZ2UiOiJzZWEiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0=" data-turbo-transient="true" /><meta name="visitor-hmac" content="a1d874b7549a05c93712cceaffd7fc4a896dfd953e3caaff113ff5fc544b9581" data-turbo-transient="true" />
<meta name="github-keyboard-shortcuts" content="copilot" data-turbo-transient="true" />
<meta name="selected-link" value="/washingtonpost/wpds-ui-kit/raw/v1.23.1/ui/popover/src/play.stories.tsx" data-turbo-transient>
<link rel="assets" href="https://github.githubassets.com/">
<meta name="google-site-verification" content="Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I">
<meta name="octolytics-url" content="https://collector.github.com/github/collect" />
<meta name="user-login" content="">
<meta name="viewport" content="width=device-width">
<meta name="description" content="GitHub is where people build software. More than 150 million people use GitHub to discover, fork, and contribute to over 420 million projects.">
<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, app-argument=https://github.com/washingtonpost/wpds-ui-kit/raw/v1.23.1/ui/popover/src/play.stories.tsx" />
<meta property="og:url" content="https://github.com">
<meta property="og:site_name" content="GitHub">
<meta property="og:title" content="Build software better, together">
<meta property="og:description" content="GitHub is where people build software. More than 150 million people use GitHub to discover, fork, and contribute to over 420 million projects.">
<meta property="og:image" content="https://github.githubassets.com/assets/github-logo-55c5b9a1fe52.png">
<meta property="og:image:type" content="image/png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="1200">
<meta property="og:image" content="https://github.githubassets.com/assets/github-mark-57519b92ca4e.png">
<meta property="og:image:type" content="image/png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="620">
<meta property="og:image" content="https://github.githubassets.com/assets/github-octocat-13c86b8b336d.png">
<meta property="og:image:type" content="image/png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="620">
<meta property="twitter:site" content="github">
<meta property="twitter:site:id" content="13334762">
<meta property="twitter:creator" content="github">
<meta property="twitter:creator:id" content="13334762">
<meta property="twitter:card" content="summary_large_image">
<meta property="twitter:title" content="GitHub">
<meta property="twitter:description" content="GitHub is where people build software. More than 150 million people use GitHub to discover, fork, and contribute to over 420 million projects.">
<meta property="twitter:image" content="https://github.githubassets.com/assets/github-logo-55c5b9a1fe52.png">
<meta property="twitter:image:width" content="1200">
<meta property="twitter:image:height" content="1200">
<meta name="hostname" content="github.com">
<meta name="expected-hostname" content="github.com">
<meta http-equiv="x-pjax-version" content="d5a32d24543e3da2560ce43292deb78506cd9173e48bdda942f0719ef04a2ff7" data-turbo-track="reload">
<meta http-equiv="x-pjax-csp-version" content="21a43568025709b66240454fc92d4f09335a96863f8ab1c46b4a07f6a5b67102" data-turbo-track="reload">
<meta http-equiv="x-pjax-css-version" content="55b0505ced03db2ce471b1617daeace5e7a81657042cfd93a3d10d1fb8695d21" data-turbo-track="reload">
<meta http-equiv="x-pjax-js-version" content="e25f416bb6d8a5f8624aad6cebc375ab2c50ac58f2175f32a7093325e66e5515" data-turbo-track="reload">
<meta name="turbo-cache-control" content="no-preview" data-turbo-transient="">
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/site-f5cc67eb9a08.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/error-4eb12c8f65b5.css" />
<meta name="is_logged_out_page" content="true">
<meta name="octolytics-page-type" content="marketing">
<link rel="canonical" href="https://github.com/washingtonpost/wpds-ui-kit/raw/v1.23.1/ui/popover/src/play.stories.tsx" data-turbo-transient>
<meta name="turbo-body-classes" content="logged-out env-production page-responsive min-height-full d-flex flex-column">
<meta name="disable-turbo" content="false">
<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="release" content="62f32509ca504f5a4d99dec2769ceeb24353c334">
<meta name="ui-target" content="full">
<link rel="mask-icon" href="https://github.githubassets.com/assets/pinned-octocat-093da3e6fa40.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" data-base-href="https://github.githubassets.com/favicons/favicon">
<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 min-height-full d-flex flex-column" style="word-wrap: break-word;" >
<div data-turbo-body class="logged-out env-production page-responsive min-height-full d-flex flex-column" style="word-wrap: break-word;" >
<div id="__primerPortalRoot__" role="region" style="z-index: 1000; position: absolute; width: 100%;" data-turbo-permanent></div>
<div class="position-relative header-wrapper js-header-wrapper ">
<a href="#start-of-content" data-skip-target-assigned="false" 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 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>
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react.ba8e7c6202eb5114c3af.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/keyboard-shortcuts-dialog.29aaeaafa90f007c6f61.module.css" />
<react-partial
partial-name="keyboard-shortcuts-dialog"
data-ssr="false"
data-attempted-ssr="false"
data-react-profiling="true"
>
<script type="application/json" data-target="react-partial.embeddedData">{"props":{"docsUrl":"https://docs.github.com/get-started/accessibility/keyboard-shortcuts"}}</script>
<div data-target="react-partial.reactRoot"></div>
</react-partial>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/21481-a66c6eab7bbf.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/85110-5c8beb884518.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/sessions-5d437eb5f307.js" defer="defer"></script>
<style>
/* Override primer focus outline color for marketing header dropdown links for better contrast */
[data-color-mode="light"] .HeaderMenu-dropdown-link:focus-visible,
[data-color-mode="light"] .HeaderMenu-trailing-link a:focus-visible {
outline-color: var(--color-accent-fg);
}
</style>
<header class="HeaderMktg header-logged-out js-details-container js-header Details f4 py-3" role="banner" data-is-top="true" data-color-mode=light data-light-theme=light data-dark-theme=dark>
<h2 class="sr-only">Navigation Menu</h2>
<button type="button" class="HeaderMktg-backdrop d-lg-none border-0 position-fixed top-0 left-0 width-full height-full js-details-target" aria-label="Toggle navigation">
<span class="d-none">Toggle navigation</span>
</button>
<div class="d-flex flex-column flex-lg-row flex-items-center px-3 px-md-4 px-lg-5 height-full position-relative z-1">
<div class="d-flex flex-justify-between flex-items-center width-full width-lg-auto">
<div class="flex-1">
<button aria-label="Toggle navigation" aria-expanded="false" type="button" data-view-component="true" class="js-details-target js-nav-padding-recalculate js-header-menu-toggle Button--link Button--medium Button d-lg-none color-fg-inherit p-1"> <span class="Button-content">
<span class="Button-label"><div class="HeaderMenu-toggle-bar rounded my-1"></div>
<div class="HeaderMenu-toggle-bar rounded my-1"></div>
<div class="HeaderMenu-toggle-bar rounded my-1"></div></span>
</span>
</button>
</div>
<a class="mr-lg-3 color-fg-inherit flex-order-2 js-prevent-focus-on-mobile-nav"
href="/"
aria-label="Homepage"
data-analytics-event="{&quot;category&quot;:&quot;Marketing nav&quot;,&quot;action&quot;:&quot;click to go to homepage&quot;,&quot;label&quot;:&quot;ref_page:Marketing;ref_cta:Logomark;ref_loc:Header&quot;}">
<svg height="32" aria-hidden="true" viewBox="0 0 24 24" version="1.1" width="32" data-view-component="true" class="octicon octicon-mark-github">
<path d="M12 1C5.923 1 1 5.923 1 12c0 4.867 3.149 8.979 7.521 10.436.55.096.756-.233.756-.522 0-.262-.013-1.128-.013-2.049-2.764.509-3.479-.674-3.699-1.292-.124-.317-.66-1.293-1.127-1.554-.385-.207-.936-.715-.014-.729.866-.014 1.485.797 1.691 1.128.99 1.663 2.571 1.196 3.204.907.096-.715.385-1.196.701-1.471-2.448-.275-5.005-1.224-5.005-5.432 0-1.196.426-2.186 1.128-2.956-.111-.275-.496-1.402.11-2.915 0 0 .921-.288 3.024 1.128a10.193 10.193 0 0 1 2.75-.371c.936 0 1.871.123 2.75.371 2.104-1.43 3.025-1.128 3.025-1.128.605 1.513.221 2.64.111 2.915.701.77 1.127 1.747 1.127 2.956 0 4.222-2.571 5.157-5.019 5.432.399.344.743 1.004.743 2.035 0 1.471-.014 2.654-.014 3.025 0 .289.206.632.756.522C19.851 20.979 23 16.854 23 12c0-6.077-4.922-11-11-11Z"></path>
</svg>
</a>
<div class="d-flex flex-1 flex-order-2 text-right d-lg-none gap-2 flex-justify-end">
<a
href="/login?return_to=https%3A%2F%2Fgithub.com%2Fwashingtonpost%2Fwpds-ui-kit%2Fraw%2Fv1.23.1%2Fui%2Fpopover%2Fsrc%2Fplay.stories.tsx%2F"
class="HeaderMenu-link HeaderMenu-button d-inline-flex f5 no-underline border color-border-default rounded-2 px-2 py-1 color-fg-inherit js-prevent-focus-on-mobile-nav"
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/washingtonpost/wpds-ui-kit/raw/v1.23.1/ui/popover/src/play.stories.tsx&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="4faa9d0c8ca81fb384f58154f046db4ac8f1e750b847fa8f0b468be87bb93502"
data-analytics-event="{&quot;category&quot;:&quot;Marketing nav&quot;,&quot;action&quot;:&quot;click to Sign in&quot;,&quot;label&quot;:&quot;ref_page:Marketing;ref_cta:Sign in;ref_loc:Header&quot;}"
>
Sign in
</a>
<div class="AppHeader-appearanceSettings">
<react-partial-anchor>
<button data-target="react-partial-anchor.anchor" id="icon-button-4ff2f371-c49b-4f03-af10-80906fa0284d" aria-labelledby="tooltip-5cd5f0cb-bb4a-41c9-8def-2419e86d0cb8" type="button" disabled="disabled" data-view-component="true" class="Button Button--iconOnly Button--invisible Button--medium AppHeader-button HeaderMenu-link border cursor-wait"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-sliders Button-visual">
<path d="M15 2.75a.75.75 0 0 1-.75.75h-4a.75.75 0 0 1 0-1.5h4a.75.75 0 0 1 .75.75Zm-8.5.75v1.25a.75.75 0 0 0 1.5 0v-4a.75.75 0 0 0-1.5 0V2H1.75a.75.75 0 0 0 0 1.5H6.5Zm1.25 5.25a.75.75 0 0 0 0-1.5h-6a.75.75 0 0 0 0 1.5h6ZM15 8a.75.75 0 0 1-.75.75H11.5V10a.75.75 0 1 1-1.5 0V6a.75.75 0 0 1 1.5 0v1.25h2.75A.75.75 0 0 1 15 8Zm-9 5.25v-2a.75.75 0 0 0-1.5 0v1.25H1.75a.75.75 0 0 0 0 1.5H4.5v1.25a.75.75 0 0 0 1.5 0v-2Zm9 0a.75.75 0 0 1-.75.75h-6a.75.75 0 0 1 0-1.5h6a.75.75 0 0 1 .75.75Z"></path>
</svg>
</button><tool-tip id="tooltip-5cd5f0cb-bb4a-41c9-8def-2419e86d0cb8" for="icon-button-4ff2f371-c49b-4f03-af10-80906fa0284d" popover="manual" data-direction="s" data-type="label" data-view-component="true" class="sr-only position-absolute">Appearance settings</tool-tip>
<template data-target="react-partial-anchor.template">
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react.ba8e7c6202eb5114c3af.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/appearance-settings.753d458774a2f782559b.module.css" />
<react-partial
partial-name="appearance-settings"
data-ssr="false"
data-attempted-ssr="false"
data-react-profiling="true"
>
<script type="application/json" data-target="react-partial.embeddedData">{"props":{}}</script>
<div data-target="react-partial.reactRoot"></div>
</react-partial>
</template>
</react-partial-anchor>
</div>
</div>
</div>
<div class="HeaderMenu js-header-menu height-fit position-lg-relative d-lg-flex flex-column flex-auto top-0">
<div class="HeaderMenu-wrapper d-flex flex-column flex-self-start flex-lg-row flex-auto rounded rounded-lg-0">
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react.ba8e7c6202eb5114c3af.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/marketing-navigation.4bd5b20d56a72071b91a.module.css" />
<react-partial
partial-name="marketing-navigation"
data-ssr="true"
data-attempted-ssr="true"
data-react-profiling="true"
>
<script type="application/json" data-target="react-partial.embeddedData">{"props":{"should_use_dotcom_links":true}}</script>
<div data-target="react-partial.reactRoot"><nav class="MarketingNavigation-module__nav--jA9Zq" aria-label="Global"><ul class="MarketingNavigation-module__list--r_vr2"><li><div class="NavDropdown-module__container--bmXM2 js-details-container js-header-menu-item"><button type="button" class="NavDropdown-module__button--Hq9UR js-details-target" aria-expanded="false">Platform<svg aria-hidden="true" focusable="false" class="octicon octicon-chevron-right NavDropdown-module__buttonIcon--SR0Ke" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.22 3.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L9.94 8 6.22 4.28a.75.75 0 0 1 0-1.06Z"></path></svg></button><div class="NavDropdown-module__dropdown--Ig57Y"><ul class="NavDropdown-module__list--RwSSK"><li><div class="NavGroup-module__group--T925n"><span class="NavGroup-module__title--TdKyz">AI CODE CREATION</span><ul class="NavGroup-module__list--M8eGv"><li><a href="https://github.com/features/copilot" data-analytics-event="{&quot;action&quot;:&quot;github_copilot&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_copilot_link_platform_navbar&quot;}" class="NavLink-module__link--n48VB"><div class="NavLink-module__text--SdWkb"><svg aria-hidden="true" focusable="false" class="octicon octicon-copilot NavLink-module__icon--h0sw7" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M23.922 16.992c-.861 1.495-5.859 5.023-11.922 5.023-6.063 0-11.061-3.528-11.922-5.023A.641.641 0 0 1 0 16.736v-2.869a.841.841 0 0 1 .053-.22c.372-.935 1.347-2.292 2.605-2.656.167-.429.414-1.055.644-1.517a10.195 10.195 0 0 1-.052-1.086c0-1.331.282-2.499 1.132-3.368.397-.406.89-.717 1.474-.952 1.399-1.136 3.392-2.093 6.122-2.093 2.731 0 4.767.957 6.166 2.093.584.235 1.077.546 1.474.952.85.869 1.132 2.037 1.132 3.368 0 .368-.014.733-.052 1.086.23.462.477 1.088.644 1.517 1.258.364 2.233 1.721 2.605 2.656a.832.832 0 0 1 .053.22v2.869a.641.641 0 0 1-.078.256ZM12.172 11h-.344a4.323 4.323 0 0 1-.355.508C10.703 12.455 9.555 13 7.965 13c-1.725 0-2.989-.359-3.782-1.259a2.005 2.005 0 0 1-.085-.104L4 11.741v6.585c1.435.779 4.514 2.179 8 2.179 3.486 0 6.565-1.4 8-2.179v-6.585l-.098-.104s-.033.045-.085.104c-.793.9-2.057 1.259-3.782 1.259-1.59 0-2.738-.545-3.508-1.492a4.323 4.323 0 0 1-.355-.508h-.016.016Zm.641-2.935c.136 1.057.403 1.913.878 2.497.442.544 1.134.938 2.344.938 1.573 0 2.292-.337 2.657-.751.384-.435.558-1.15.558-2.361 0-1.14-.243-1.847-.705-2.319-.477-.488-1.319-.862-2.824-1.025-1.487-.161-2.192.138-2.533.529-.269.307-.437.808-.438 1.578v.021c0 .265.021.562.063.893Zm-1.626 0c.042-.331.063-.628.063-.894v-.02c-.001-.77-.169-1.271-.438-1.578-.341-.391-1.046-.69-2.533-.529-1.505.163-2.347.537-2.824 1.025-.462.472-.705 1.179-.705 2.319 0 1.211.175 1.926.558 2.361.365.414 1.084.751 2.657.751 1.21 0 1.902-.394 2.344-.938.475-.584.742-1.44.878-2.497Z"></path><path d="M14.5 14.25a1 1 0 0 1 1 1v2a1 1 0 0 1-2 0v-2a1 1 0 0 1 1-1Zm-5 0a1 1 0 0 1 1 1v2a1 1 0 0 1-2 0v-2a1 1 0 0 1 1-1Z"></path></svg><span class="NavLink-module__title--xw3ok">GitHub Copilot</span><span class="NavLink-module__subtitle--qC15H">Write better code with AI</span></div></a></li><li><a href="https://github.com/features/spark" data-analytics-event="{&quot;action&quot;:&quot;github_spark&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_spark_link_platform_navbar&quot;}" class="NavLink-module__link--n48VB"><div class="NavLink-module__text--SdWkb"><svg aria-hidden="true" focusable="false" class="octicon octicon-sparkle-fill NavLink-module__icon--h0sw7" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M11.296 1.924c.24-.656 1.168-.656 1.408 0l.717 1.958a11.25 11.25 0 0 0 6.697 6.697l1.958.717c.657.24.657 1.168 0 1.408l-1.958.717a11.25 11.25 0 0 0-6.697 6.697l-.717 1.958c-.24.657-1.168.657-1.408 0l-.717-1.958a11.25 11.25 0 0 0-6.697-6.697l-1.958-.717c-.656-.24-.656-1.168 0-1.408l1.958-.717a11.25 11.25 0 0 0 6.697-6.697l.717-1.958Z"></path></svg><span class="NavLink-module__title--xw3ok">GitHub Spark</span><span class="NavLink-module__subtitle--qC15H">Build and deploy intelligent apps</span></div></a></li><li><a href="https://github.com/features/models" data-analytics-event="{&quot;action&quot;:&quot;github_models&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_models_link_platform_navbar&quot;}" class="NavLink-module__link--n48VB"><div class="NavLink-module__text--SdWkb"><svg aria-hidden="true" focusable="false" class="octicon octicon-ai-model NavLink-module__icon--h0sw7" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M19.375 8.5a3.25 3.25 0 1 1-3.163 4h-3a3.252 3.252 0 0 1-4.443 2.509L7.214 17.76a3.25 3.25 0 1 1-1.342-.674l1.672-2.957A3.238 3.238 0 0 1 6.75 12c0-.907.371-1.727.97-2.316L6.117 6.846A3.253 3.253 0 0 1 1.875 3.75a3.25 3.25 0 1 1 5.526 2.32l1.603 2.836A3.25 3.25 0 0 1 13.093 11h3.119a3.252 3.252 0 0 1 3.163-2.5ZM10 10.25a1.75 1.75 0 1 0-.001 3.499A1.75 1.75 0 0 0 10 10.25ZM5.125 2a1.75 1.75 0 1 0 0 3.5 1.75 1.75 0 0 0 0-3.5Zm12.5 9.75a1.75 1.75 0 1 0 3.5 0 1.75 1.75 0 0 0-3.5 0Zm-14.25 8.5a1.75 1.75 0 1 0 3.501-.001 1.75 1.75 0 0 0-3.501.001Z"></path></svg><span class="NavLink-module__title--xw3ok">GitHub Models</span><span class="NavLink-module__subtitle--qC15H">Manage and compare prompts</span></div></a></li><li><a href="https://github.com/mcp" data-analytics-event="{&quot;action&quot;:&quot;mcp_registry&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;mcp_registry_link_platform_navbar&quot;}" class="NavLink-module__link--n48VB"><div class="NavLink-module__text--SdWkb"><svg aria-hidden="true" focusable="false" class="octicon octicon-mcp NavLink-module__icon--h0sw7" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M9.795 1.694a4.287 4.287 0 0 1 6.061 0 4.28 4.28 0 0 1 1.181 3.819 4.282 4.282 0 0 1 3.819 1.181 4.287 4.287 0 0 1 0 6.061l-6.793 6.793a.249.249 0 0 0 0 .353l2.617 2.618a.75.75 0 1 1-1.061 1.061l-2.617-2.618a1.75 1.75 0 0 1 0-2.475l6.793-6.793a2.785 2.785 0 1 0-3.939-3.939l-5.9 5.9a.734.734 0 0 1-.249.165.749.749 0 0 1-.812-1.225l5.9-5.901a2.785 2.785 0 1 0-3.939-3.939L2.931 10.68A.75.75 0 1 1 1.87 9.619l7.925-7.925Z"></path><path d="M12.42 4.069a.752.752 0 0 1 1.061 0 .752.752 0 0 1 0 1.061L7.33 11.28a2.788 2.788 0 0 0 0 3.94 2.788 2.788 0 0 0 3.94 0l6.15-6.151a.752.752 0 0 1 1.061 0 .752.752 0 0 1 0 1.061l-6.151 6.15a4.285 4.285 0 1 1-6.06-6.06l6.15-6.151Z"></path></svg><span class="NavLink-module__title--xw3ok">MCP Registry<sup class="NavLink-module__label--MrIhm">New</sup></span><span class="NavLink-module__subtitle--qC15H">Integrate external tools</span></div></a></li></ul></div></li><li><div class="NavGroup-module__group--T925n"><span class="NavGroup-module__title--TdKyz">DEVELOPER WORKFLOWS</span><ul class="NavGroup-module__list--M8eGv"><li><a href="https://github.com/features/actions" data-analytics-event="{&quot;action&quot;:&quot;actions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;actions_link_platform_navbar&quot;}" class="NavLink-module__link--n48VB"><div class="NavLink-module__text--SdWkb"><svg aria-hidden="true" focusable="false" class="octicon octicon-workflow NavLink-module__icon--h0sw7" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M1 3a2 2 0 0 1 2-2h6.5a2 2 0 0 1 2 2v6.5a2 2 0 0 1-2 2H7v4.063C7 16.355 7.644 17 8.438 17H12.5v-2.5a2 2 0 0 1 2-2H21a2 2 0 0 1 2 2V21a2 2 0 0 1-2 2h-6.5a2 2 0 0 1-2-2v-2.5H8.437A2.939 2.939 0 0 1 5.5 15.562V11.5H3a2 2 0 0 1-2-2Zm2-.5a.5.5 0 0 0-.5.5v6.5a.5.5 0 0 0 .5.5h6.5a.5.5 0 0 0 .5-.5V3a.5.5 0 0 0-.5-.5ZM14.5 14a.5.5 0 0 0-.5.5V21a.5.5 0 0 0 .5.5H21a.5.5 0 0 0 .5-.5v-6.5a.5.5 0 0 0-.5-.5Z"></path></svg><span class="NavLink-module__title--xw3ok">Actions</span><span class="NavLink-module__subtitle--qC15H">Automate any workflow</span></div></a></li><li><a href="https://github.com/features/codespaces" data-analytics-event="{&quot;action&quot;:&quot;codespaces&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;codespaces_link_platform_navbar&quot;}" class="NavLink-module__link--n48VB"><div class="NavLink-module__text--SdWkb"><svg aria-hidden="true" focusable="false" class="octicon octicon-codespaces NavLink-module__icon--h0sw7" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.5 3.75C3.5 2.784 4.284 2 5.25 2h13.5c.966 0 1.75.784 1.75 1.75v7.5A1.75 1.75 0 0 1 18.75 13H5.25a1.75 1.75 0 0 1-1.75-1.75Zm-2 12c0-.966.784-1.75 1.75-1.75h17.5c.966 0 1.75.784 1.75 1.75v4a1.75 1.75 0 0 1-1.75 1.75H3.25a1.75 1.75 0 0 1-1.75-1.75ZM5.25 3.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h13.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Zm-2 12a.25.25 0 0 0-.25.25v4c0 .138.112.25.25.25h17.5a.25.25 0 0 0 .25-.25v-4a.25.25 0 0 0-.25-.25Z"></path><path d="M10 17.75a.75.75 0 0 1 .75-.75h6.5a.75.75 0 0 1 0 1.5h-6.5a.75.75 0 0 1-.75-.75Zm-4 0a.75.75 0 0 1 .75-.75h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1-.75-.75Z"></path></svg><span class="NavLink-module__title--xw3ok">Codespaces</span><span class="NavLink-module__subtitle--qC15H">Instant dev environments</span></div></a></li><li><a href="https://github.com/features/issues" data-analytics-event="{&quot;action&quot;:&quot;issues&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;issues_link_platform_navbar&quot;}" class="NavLink-module__link--n48VB"><div class="NavLink-module__text--SdWkb"><svg aria-hidden="true" focusable="false" class="octicon octicon-issue-opened NavLink-module__icon--h0sw7" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M12 1c6.075 0 11 4.925 11 11s-4.925 11-11 11S1 18.075 1 12 5.925 1 12 1ZM2.5 12a9.5 9.5 0 0 0 9.5 9.5 9.5 9.5 0 0 0 9.5-9.5A9.5 9.5 0 0 0 12 2.5 9.5 9.5 0 0 0 2.5 12Zm9.5 2a2 2 0 1 1-.001-3.999A2 2 0 0 1 12 14Z"></path></svg><span class="NavLink-module__title--xw3ok">Issues</span><span class="NavLink-module__subtitle--qC15H">Plan and track work</span></div></a></li><li><a href="https://github.com/features/code-review" data-analytics-event="{&quot;action&quot;:&quot;code_review&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;code_review_link_platform_navbar&quot;}" class="NavLink-module__link--n48VB"><div class="NavLink-module__text--SdWkb"><svg aria-hidden="true" focusable="false" class="octicon octicon-code NavLink-module__icon--h0sw7" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M15.22 4.97a.75.75 0 0 1 1.06 0l6.5 6.5a.75.75 0 0 1 0 1.06l-6.5 6.5a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L21.19 12l-5.97-5.97a.75.75 0 0 1 0-1.06Zm-6.44 0a.75.75 0 0 1 0 1.06L2.81 12l5.97 5.97a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215l-6.5-6.5a.75.75 0 0 1 0-1.06l6.5-6.5a.75.75 0 0 1 1.06 0Z"></path></svg><span class="NavLink-module__title--xw3ok">Code Review</span><span class="NavLink-module__subtitle--qC15H">Manage code changes</span></div></a></li></ul></div></li><li><div class="NavGroup-module__group--T925n"><span class="NavGroup-module__title--TdKyz">APPLICATION SECURITY</span><ul class="NavGroup-module__list--M8eGv"><li><a href="https://github.com/security/advanced-security" data-analytics-event="{&quot;action&quot;:&quot;github_advanced_security&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_advanced_security_link_platform_navbar&quot;}" class="NavLink-module__link--n48VB"><div class="NavLink-module__text--SdWkb"><svg aria-hidden="true" focusable="false" class="octicon octicon-shield-check NavLink-module__icon--h0sw7" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M16.53 9.78a.75.75 0 0 0-1.06-1.06L11 13.19l-1.97-1.97a.75.75 0 0 0-1.06 1.06l2.5 2.5a.75.75 0 0 0 1.06 0l5-5Z"></path><path d="m12.54.637 8.25 2.675A1.75 1.75 0 0 1 22 4.976V10c0 6.19-3.771 10.704-9.401 12.83a1.704 1.704 0 0 1-1.198 0C5.77 20.705 2 16.19 2 10V4.976c0-.758.489-1.43 1.21-1.664L11.46.637a1.748 1.748 0 0 1 1.08 0Zm-.617 1.426-8.25 2.676a.249.249 0 0 0-.173.237V10c0 5.46 3.28 9.483 8.43 11.426a.199.199 0 0 0 .14 0C17.22 19.483 20.5 15.461 20.5 10V4.976a.25.25 0 0 0-.173-.237l-8.25-2.676a.253.253 0 0 0-.154 0Z"></path></svg><span class="NavLink-module__title--xw3ok">GitHub Advanced Security</span><span class="NavLink-module__subtitle--qC15H">Find and fix vulnerabilities</span></div></a></li><li><a href="https://github.com/security/advanced-security/code-security" data-analytics-event="{&quot;action&quot;:&quot;code_security&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;code_security_link_platform_navbar&quot;}" class="NavLink-module__link--n48VB"><div class="NavLink-module__text--SdWkb"><svg aria-hidden="true" focusable="false" class="octicon octicon-code-square NavLink-module__icon--h0sw7" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.3 8.24a.75.75 0 0 1-.04 1.06L7.352 12l2.908 2.7a.75.75 0 1 1-1.02 1.1l-3.5-3.25a.75.75 0 0 1 0-1.1l3.5-3.25a.75.75 0 0 1 1.06.04Zm3.44 1.06a.75.75 0 1 1 1.02-1.1l3.5 3.25a.75.75 0 0 1 0 1.1l-3.5 3.25a.75.75 0 1 1-1.02-1.1l2.908-2.7-2.908-2.7Z"></path><path d="M2 3.75C2 2.784 2.784 2 3.75 2h16.5c.966 0 1.75.784 1.75 1.75v16.5A1.75 1.75 0 0 1 20.25 22H3.75A1.75 1.75 0 0 1 2 20.25Zm1.75-.25a.25.25 0 0 0-.25.25v16.5c0 .138.112.25.25.25h16.5a.25.25 0 0 0 .25-.25V3.75a.25.25 0 0 0-.25-.25Z"></path></svg><span class="NavLink-module__title--xw3ok">Code security</span><span class="NavLink-module__subtitle--qC15H">Secure your code as you build</span></div></a></li><li><a href="https://github.com/security/advanced-security/secret-protection" data-analytics-event="{&quot;action&quot;:&quot;secret_protection&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;secret_protection_link_platform_navbar&quot;}" class="NavLink-module__link--n48VB"><div class="NavLink-module__text--SdWkb"><svg aria-hidden="true" focusable="false" class="octicon octicon-lock NavLink-module__icon--h0sw7" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6 9V7.25C6 3.845 8.503 1 12 1s6 2.845 6 6.25V9h.5a2.5 2.5 0 0 1 2.5 2.5v8a2.5 2.5 0 0 1-2.5 2.5h-13A2.5 2.5 0 0 1 3 19.5v-8A2.5 2.5 0 0 1 5.5 9Zm-1.5 2.5v8a1 1 0 0 0 1 1h13a1 1 0 0 0 1-1v-8a1 1 0 0 0-1-1h-13a1 1 0 0 0-1 1Zm3-4.25V9h9V7.25c0-2.67-1.922-4.75-4.5-4.75-2.578 0-4.5 2.08-4.5 4.75Z"></path></svg><span class="NavLink-module__title--xw3ok">Secret protection</span><span class="NavLink-module__subtitle--qC15H">Stop leaks before they start</span></div></a></li></ul></div></li><li><div class="NavGroup-module__group--T925n NavGroup-module__hasSeparator--AJeNz"><span class="NavGroup-module__title--TdKyz">EXPLORE</span><ul class="NavGroup-module__list--M8eGv"><li><a href="https://github.com/why-github" data-analytics-event="{&quot;action&quot;:&quot;why_github&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;why_github_link_platform_navbar&quot;}" class="NavLink-module__link--n48VB"><span class="NavLink-module__title--xw3ok">Why GitHub</span></a></li><li><a href="https://docs.github.com" data-analytics-event="{&quot;action&quot;:&quot;documentation&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;documentation_link_platform_navbar&quot;}" class="NavLink-module__link--n48VB" target="_blank" rel="noreferrer"><span class="NavLink-module__title--xw3ok">Documentation</span><svg aria-hidden="true" focusable="false" class="octicon octicon-link-external NavLink-module__externalIcon--JurQ9" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a href="https://github.blog" data-analytics-event="{&quot;action&quot;:&quot;blog&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;blog_link_platform_navbar&quot;}" class="NavLink-module__link--n48VB" target="_blank" rel="noreferrer"><span class="NavLink-module__title--xw3ok">Blog</span><svg aria-hidden="true" focusable="false" class="octicon octicon-link-external NavLink-module__externalIcon--JurQ9" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a href="https://github.blog/changelog" data-analytics-event="{&quot;action&quot;:&quot;changelog&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;changelog_link_platform_navbar&quot;}" class="NavLink-module__link--n48VB" target="_blank" rel="noreferrer"><span class="NavLink-module__title--xw3ok">Changelog</span><svg aria-hidden="true" focusable="false" class="octicon octicon-link-external NavLink-module__externalIcon--JurQ9" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a href="https://github.com/marketplace" data-analytics-event="{&quot;action&quot;:&quot;marketplace&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;marketplace_link_platform_navbar&quot;}" class="NavLink-module__link--n48VB"><span class="NavLink-module__title--xw3ok">Marketplace</span></a></li></ul></div></li></ul><div class="NavDropdown-module__trailingLinkContainer--MNB5T"><a href="https://github.com/features" data-analytics-event="{&quot;action&quot;:&quot;view_all_features&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_features_link_platform_navbar&quot;}" class="NavLink-module__link--n48VB"><span class="NavLink-module__title--xw3ok">View all features</span><svg aria-hidden="true" focusable="false" class="octicon octicon-chevron-right NavLink-module__arrowIcon--g6Lip" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.22 3.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L9.94 8 6.22 4.28a.75.75 0 0 1 0-1.06Z"></path></svg></a></div></div></div></li><li><div class="NavDropdown-module__container--bmXM2 js-details-container js-header-menu-item"><button type="button" class="NavDropdown-module__button--Hq9UR js-details-target" aria-expanded="false">Solutions<svg aria-hidden="true" focusable="false" class="octicon octicon-chevron-right NavDropdown-module__buttonIcon--SR0Ke" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.22 3.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L9.94 8 6.22 4.28a.75.75 0 0 1 0-1.06Z"></path></svg></button><div class="NavDropdown-module__dropdown--Ig57Y"><ul class="NavDropdown-module__list--RwSSK"><li><div class="NavGroup-module__group--T925n"><span class="NavGroup-module__title--TdKyz">BY COMPANY SIZE</span><ul class="NavGroup-module__list--M8eGv"><li><a href="https://github.com/enterprise" data-analytics-event="{&quot;action&quot;:&quot;enterprises&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;enterprises_link_solutions_navbar&quot;}" class="NavLink-module__link--n48VB"><span class="NavLink-module__title--xw3ok">Enterprises</span></a></li><li><a href="https://github.com/team" data-analytics-event="{&quot;action&quot;:&quot;small_and_medium_teams&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;small_and_medium_teams_link_solutions_navbar&quot;}" class="NavLink-module__link--n48VB"><span class="NavLink-module__title--xw3ok">Small and medium teams</span></a></li><li><a href="https://github.com/enterprise/startups" data-analytics-event="{&quot;action&quot;:&quot;startups&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;startups_link_solutions_navbar&quot;}" class="NavLink-module__link--n48VB"><span class="NavLink-module__title--xw3ok">Startups</span></a></li><li><a href="https://github.com/solutions/industry/nonprofits" data-analytics-event="{&quot;action&quot;:&quot;nonprofits&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;nonprofits_link_solutions_navbar&quot;}" class="NavLink-module__link--n48VB"><span class="NavLink-module__title--xw3ok">Nonprofits</span></a></li></ul></div></li><li><div class="NavGroup-module__group--T925n"><span class="NavGroup-module__title--TdKyz">BY USE CASE</span><ul class="NavGroup-module__list--M8eGv"><li><a href="https://github.com/solutions/use-case/app-modernization" data-analytics-event="{&quot;action&quot;:&quot;app_modernization&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;app_modernization_link_solutions_navbar&quot;}" class="NavLink-module__link--n48VB"><span class="NavLink-module__title--xw3ok">App Modernization</span></a></li><li><a href="https://github.com/solutions/use-case/devsecops" data-analytics-event="{&quot;action&quot;:&quot;devsecops&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;devsecops_link_solutions_navbar&quot;}" class="NavLink-module__link--n48VB"><span class="NavLink-module__title--xw3ok">DevSecOps</span></a></li><li><a href="https://github.com/solutions/use-case/devops" data-analytics-event="{&quot;action&quot;:&quot;devops&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;devops_link_solutions_navbar&quot;}" class="NavLink-module__link--n48VB"><span class="NavLink-module__title--xw3ok">DevOps</span></a></li><li><a href="https://github.com/solutions/use-case/ci-cd" data-analytics-event="{&quot;action&quot;:&quot;ci/cd&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;ci/cd_link_solutions_navbar&quot;}" class="NavLink-module__link--n48VB"><span class="NavLink-module__title--xw3ok">CI/CD</span></a></li><li><a href="https://github.com/solutions/use-case" data-analytics-event="{&quot;action&quot;:&quot;view_all_use_cases&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_use_cases_link_solutions_navbar&quot;}" class="NavLink-module__link--n48VB"><span class="NavLink-module__title--xw3ok">View all use cases</span><svg aria-hidden="true" focusable="false" class="octicon octicon-chevron-right NavLink-module__arrowIcon--g6Lip" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.22 3.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L9.94 8 6.22 4.28a.75.75 0 0 1 0-1.06Z"></path></svg></a></li></ul></div></li><li><div class="NavGroup-module__group--T925n"><span class="NavGroup-module__title--TdKyz">BY INDUSTRY</span><ul class="NavGroup-module__list--M8eGv"><li><a href="https://github.com/solutions/industry/healthcare" data-analytics-event="{&quot;action&quot;:&quot;healthcare&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;healthcare_link_solutions_navbar&quot;}" class="NavLink-module__link--n48VB"><span class="NavLink-module__title--xw3ok">Healthcare</span></a></li><li><a href="https://github.com/solutions/industry/financial-services" data-analytics-event="{&quot;action&quot;:&quot;financial_services&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;financial_services_link_solutions_navbar&quot;}" class="NavLink-module__link--n48VB"><span class="NavLink-module__title--xw3ok">Financial services</span></a></li><li><a href="https://github.com/solutions/industry/manufacturing" data-analytics-event="{&quot;action&quot;:&quot;manufacturing&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;manufacturing_link_solutions_navbar&quot;}" class="NavLink-module__link--n48VB"><span class="NavLink-module__title--xw3ok">Manufacturing</span></a></li><li><a href="https://github.com/solutions/industry/government" data-analytics-event="{&quot;action&quot;:&quot;government&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;government_link_solutions_navbar&quot;}" class="NavLink-module__link--n48VB"><span class="NavLink-module__title--xw3ok">Government</span></a></li><li><a href="https://github.com/solutions/industry" data-analytics-event="{&quot;action&quot;:&quot;view_all_industries&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_industries_link_solutions_navbar&quot;}" class="NavLink-module__link--n48VB"><span class="NavLink-module__title--xw3ok">View all industries</span><svg aria-hidden="true" focusable="false" class="octicon octicon-chevron-right NavLink-module__arrowIcon--g6Lip" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.22 3.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L9.94 8 6.22 4.28a.75.75 0 0 1 0-1.06Z"></path></svg></a></li></ul></div></li></ul><div class="NavDropdown-module__trailingLinkContainer--MNB5T"><a href="https://github.com/solutions" data-analytics-event="{&quot;action&quot;:&quot;view_all_solutions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_solutions_link_solutions_navbar&quot;}" class="NavLink-module__link--n48VB"><span class="NavLink-module__title--xw3ok">View all solutions</span><svg aria-hidden="true" focusable="false" class="octicon octicon-chevron-right NavLink-module__arrowIcon--g6Lip" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.22 3.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L9.94 8 6.22 4.28a.75.75 0 0 1 0-1.06Z"></path></svg></a></div></div></div></li><li><div class="NavDropdown-module__container--bmXM2 js-details-container js-header-menu-item"><button type="button" class="NavDropdown-module__button--Hq9UR js-details-target" aria-expanded="false">Resources<svg aria-hidden="true" focusable="false" class="octicon octicon-chevron-right NavDropdown-module__buttonIcon--SR0Ke" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.22 3.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L9.94 8 6.22 4.28a.75.75 0 0 1 0-1.06Z"></path></svg></button><div class="NavDropdown-module__dropdown--Ig57Y"><ul class="NavDropdown-module__list--RwSSK"><li><div class="NavGroup-module__group--T925n"><span class="NavGroup-module__title--TdKyz">EXPLORE BY TOPIC</span><ul class="NavGroup-module__list--M8eGv"><li><a href="https://github.com/resources/articles?topic=ai" data-analytics-event="{&quot;action&quot;:&quot;ai&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;ai_link_resources_navbar&quot;}" class="NavLink-module__link--n48VB"><span class="NavLink-module__title--xw3ok">AI</span></a></li><li><a href="https://github.com/resources/articles?topic=software-development" data-analytics-event="{&quot;action&quot;:&quot;software_development&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;software_development_link_resources_navbar&quot;}" class="NavLink-module__link--n48VB"><span class="NavLink-module__title--xw3ok">Software Development</span></a></li><li><a href="https://github.com/resources/articles?topic=devops" data-analytics-event="{&quot;action&quot;:&quot;devops&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;devops_link_resources_navbar&quot;}" class="NavLink-module__link--n48VB"><span class="NavLink-module__title--xw3ok">DevOps</span></a></li><li><a href="https://github.com/resources/articles?topic=security" data-analytics-event="{&quot;action&quot;:&quot;security&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;security_link_resources_navbar&quot;}" class="NavLink-module__link--n48VB"><span class="NavLink-module__title--xw3ok">Security</span></a></li><li><a href="https://github.com/resources/articles" data-analytics-event="{&quot;action&quot;:&quot;view_all_topics&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_topics_link_resources_navbar&quot;}" class="NavLink-module__link--n48VB"><span class="NavLink-module__title--xw3ok">View all topics</span><svg aria-hidden="true" focusable="false" class="octicon octicon-chevron-right NavLink-module__arrowIcon--g6Lip" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.22 3.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L9.94 8 6.22 4.28a.75.75 0 0 1 0-1.06Z"></path></svg></a></li></ul></div></li><li><div class="NavGroup-module__group--T925n"><span class="NavGroup-module__title--TdKyz">EXPLORE BY TYPE</span><ul class="NavGroup-module__list--M8eGv"><li><a href="https://github.com/customer-stories" data-analytics-event="{&quot;action&quot;:&quot;customer_stories&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;customer_stories_link_resources_navbar&quot;}" class="NavLink-module__link--n48VB"><span class="NavLink-module__title--xw3ok">Customer stories</span></a></li><li><a href="https://github.com/resources/events" data-analytics-event="{&quot;action&quot;:&quot;events__webinars&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;events__webinars_link_resources_navbar&quot;}" class="NavLink-module__link--n48VB"><span class="NavLink-module__title--xw3ok">Events &amp; webinars</span></a></li><li><a href="https://github.com/resources/whitepapers" data-analytics-event="{&quot;action&quot;:&quot;ebooks__reports&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;ebooks__reports_link_resources_navbar&quot;}" class="NavLink-module__link--n48VB"><span class="NavLink-module__title--xw3ok">Ebooks &amp; reports</span></a></li><li><a href="https://github.com/solutions/executive-insights" data-analytics-event="{&quot;action&quot;:&quot;business_insights&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;business_insights_link_resources_navbar&quot;}" class="NavLink-module__link--n48VB"><span class="NavLink-module__title--xw3ok">Business insights</span></a></li><li><a href="https://skills.github.com" data-analytics-event="{&quot;action&quot;:&quot;github_skills&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_skills_link_resources_navbar&quot;}" class="NavLink-module__link--n48VB" target="_blank" rel="noreferrer"><span class="NavLink-module__title--xw3ok">GitHub Skills</span><svg aria-hidden="true" focusable="false" class="octicon octicon-link-external NavLink-module__externalIcon--JurQ9" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li></ul></div></li><li><div class="NavGroup-module__group--T925n"><span class="NavGroup-module__title--TdKyz">SUPPORT &amp; SERVICES</span><ul class="NavGroup-module__list--M8eGv"><li><a href="https://docs.github.com" data-analytics-event="{&quot;action&quot;:&quot;documentation&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;documentation_link_resources_navbar&quot;}" class="NavLink-module__link--n48VB" target="_blank" rel="noreferrer"><span class="NavLink-module__title--xw3ok">Documentation</span><svg aria-hidden="true" focusable="false" class="octicon octicon-link-external NavLink-module__externalIcon--JurQ9" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a href="https://support.github.com" data-analytics-event="{&quot;action&quot;:&quot;customer_support&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;customer_support_link_resources_navbar&quot;}" class="NavLink-module__link--n48VB" target="_blank" rel="noreferrer"><span class="NavLink-module__title--xw3ok">Customer support</span><svg aria-hidden="true" focusable="false" class="octicon octicon-link-external NavLink-module__externalIcon--JurQ9" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a href="https://github.com/orgs/community/discussions" data-analytics-event="{&quot;action&quot;:&quot;community_forum&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;community_forum_link_resources_navbar&quot;}" class="NavLink-module__link--n48VB"><span class="NavLink-module__title--xw3ok">Community forum</span></a></li><li><a href="https://github.com/trust-center" data-analytics-event="{&quot;action&quot;:&quot;trust_center&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;trust_center_link_resources_navbar&quot;}" class="NavLink-module__link--n48VB"><span class="NavLink-module__title--xw3ok">Trust center</span></a></li><li><a href="https://github.com/partners" data-analytics-event="{&quot;action&quot;:&quot;partners&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;partners_link_resources_navbar&quot;}" class="NavLink-module__link--n48VB"><span class="NavLink-module__title--xw3ok">Partners</span></a></li></ul></div></li></ul></div></div></li><li><div class="NavDropdown-module__container--bmXM2 js-details-container js-header-menu-item"><button type="button" class="NavDropdown-module__button--Hq9UR js-details-target" aria-expanded="false">Open Source<svg aria-hidden="true" focusable="false" class="octicon octicon-chevron-right NavDropdown-module__buttonIcon--SR0Ke" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.22 3.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L9.94 8 6.22 4.28a.75.75 0 0 1 0-1.06Z"></path></svg></button><div class="NavDropdown-module__dropdown--Ig57Y"><ul class="NavDropdown-module__list--RwSSK"><li><div class="NavGroup-module__group--T925n"><span class="NavGroup-module__title--TdKyz">COMMUNITY</span><ul class="NavGroup-module__list--M8eGv"><li><a href="https://github.com/sponsors" data-analytics-event="{&quot;action&quot;:&quot;github_sponsors&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_sponsors_link_open_source_navbar&quot;}" class="NavLink-module__link--n48VB"><div class="NavLink-module__text--SdWkb"><svg aria-hidden="true" focusable="false" class="octicon octicon-sponsor-tiers NavLink-module__icon--h0sw7" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M16.004 1.25C18.311 1.25 20 3.128 20 5.75c0 2.292-1.23 4.464-3.295 6.485-.481.47-.98.909-1.482 1.31l.265 1.32 1.375 7.5a.75.75 0 0 1-.982.844l-3.512-1.207a.75.75 0 0 0-.488 0L8.37 23.209a.75.75 0 0 1-.982-.844l1.378-7.512.261-1.309c-.5-.4-1-.838-1.481-1.31C5.479 10.215 4.25 8.043 4.25 5.75c0-2.622 1.689-4.5 3.996-4.5 1.55 0 2.947.752 3.832 1.967l.047.067.047-.067a4.726 4.726 0 0 1 3.612-1.962l.22-.005ZM13.89 14.531c-.418.285-.828.542-1.218.77l-.18.103a.75.75 0 0 1-.734 0l-.071-.04-.46-.272c-.282-.173-.573-.36-.868-.562l-.121.605-1.145 6.239 2.3-.79a2.248 2.248 0 0 1 1.284-.054l.18.053 2.299.79-1.141-6.226-.125-.616ZM16.004 2.75c-1.464 0-2.731.983-3.159 2.459-.209.721-1.231.721-1.44 0-.428-1.476-1.695-2.459-3.16-2.459-1.44 0-2.495 1.173-2.495 3 0 1.811 1.039 3.647 2.844 5.412a19.624 19.624 0 0 0 3.734 2.84l-.019-.011-.184-.111.147-.088a19.81 19.81 0 0 0 3.015-2.278l.37-.352C17.46 9.397 18.5 7.561 18.5 5.75c0-1.827-1.055-3-2.496-3Z"></path></svg><span class="NavLink-module__title--xw3ok">GitHub Sponsors</span><span class="NavLink-module__subtitle--qC15H">Fund open source developers</span></div></a></li></ul></div></li><li><div class="NavGroup-module__group--T925n"><span class="NavGroup-module__title--TdKyz">PROGRAMS</span><ul class="NavGroup-module__list--M8eGv"><li><a href="https://securitylab.github.com" data-analytics-event="{&quot;action&quot;:&quot;security_lab&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;security_lab_link_open_source_navbar&quot;}" class="NavLink-module__link--n48VB" target="_blank" rel="noreferrer"><span class="NavLink-module__title--xw3ok">Security Lab</span><svg aria-hidden="true" focusable="false" class="octicon octicon-link-external NavLink-module__externalIcon--JurQ9" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a href="https://maintainers.github.com" data-analytics-event="{&quot;action&quot;:&quot;maintainer_community&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;maintainer_community_link_open_source_navbar&quot;}" class="NavLink-module__link--n48VB" target="_blank" rel="noreferrer"><span class="NavLink-module__title--xw3ok">Maintainer Community</span><svg aria-hidden="true" focusable="false" class="octicon octicon-link-external NavLink-module__externalIcon--JurQ9" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a href="https://github.com/accelerator" data-analytics-event="{&quot;action&quot;:&quot;accelerator&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;accelerator_link_open_source_navbar&quot;}" class="NavLink-module__link--n48VB"><span class="NavLink-module__title--xw3ok">Accelerator</span></a></li><li><a href="https://archiveprogram.github.com" data-analytics-event="{&quot;action&quot;:&quot;archive_program&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;archive_program_link_open_source_navbar&quot;}" class="NavLink-module__link--n48VB" target="_blank" rel="noreferrer"><span class="NavLink-module__title--xw3ok">Archive Program</span><svg aria-hidden="true" focusable="false" class="octicon octicon-link-external NavLink-module__externalIcon--JurQ9" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li></ul></div></li><li><div class="NavGroup-module__group--T925n"><span class="NavGroup-module__title--TdKyz">REPOSITORIES</span><ul class="NavGroup-module__list--M8eGv"><li><a href="https://github.com/topics" data-analytics-event="{&quot;action&quot;:&quot;topics&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;topics_link_open_source_navbar&quot;}" class="NavLink-module__link--n48VB"><span class="NavLink-module__title--xw3ok">Topics</span></a></li><li><a href="https://github.com/trending" data-analytics-event="{&quot;action&quot;:&quot;trending&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;trending_link_open_source_navbar&quot;}" class="NavLink-module__link--n48VB"><span class="NavLink-module__title--xw3ok">Trending</span></a></li><li><a href="https://github.com/collections" data-analytics-event="{&quot;action&quot;:&quot;collections&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;collections_link_open_source_navbar&quot;}" class="NavLink-module__link--n48VB"><span class="NavLink-module__title--xw3ok">Collections</span></a></li></ul></div></li></ul></div></div></li><li><div class="NavDropdown-module__container--bmXM2 js-details-container js-header-menu-item"><button type="button" class="NavDropdown-module__button--Hq9UR js-details-target" aria-expanded="false">Enterprise<svg aria-hidden="true" focusable="false" class="octicon octicon-chevron-right NavDropdown-module__buttonIcon--SR0Ke" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.22 3.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L9.94 8 6.22 4.28a.75.75 0 0 1 0-1.06Z"></path></svg></button><div class="NavDropdown-module__dropdown--Ig57Y"><ul class="NavDropdown-module__list--RwSSK"><li><div class="NavGroup-module__group--T925n"><span class="NavGroup-module__title--TdKyz">ENTERPRISE SOLUTIONS</span><ul class="NavGroup-module__list--M8eGv"><li><a href="https://github.com/enterprise" data-analytics-event="{&quot;action&quot;:&quot;enterprise_platform&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;enterprise_platform_link_enterprise_navbar&quot;}" class="NavLink-module__link--n48VB"><div class="NavLink-module__text--SdWkb"><svg aria-hidden="true" focusable="false" class="octicon octicon-stack NavLink-module__icon--h0sw7" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M11.063 1.456a1.749 1.749 0 0 1 1.874 0l8.383 5.316a1.751 1.751 0 0 1 0 2.956l-8.383 5.316a1.749 1.749 0 0 1-1.874 0L2.68 9.728a1.751 1.751 0 0 1 0-2.956Zm1.071 1.267a.25.25 0 0 0-.268 0L3.483 8.039a.25.25 0 0 0 0 .422l8.383 5.316a.25.25 0 0 0 .268 0l8.383-5.316a.25.25 0 0 0 0-.422Z"></path><path d="M1.867 12.324a.75.75 0 0 1 1.035-.232l8.964 5.685a.25.25 0 0 0 .268 0l8.964-5.685a.75.75 0 0 1 .804 1.267l-8.965 5.685a1.749 1.749 0 0 1-1.874 0l-8.965-5.685a.75.75 0 0 1-.231-1.035Z"></path><path d="M1.867 16.324a.75.75 0 0 1 1.035-.232l8.964 5.685a.25.25 0 0 0 .268 0l8.964-5.685a.75.75 0 0 1 .804 1.267l-8.965 5.685a1.749 1.749 0 0 1-1.874 0l-8.965-5.685a.75.75 0 0 1-.231-1.035Z"></path></svg><span class="NavLink-module__title--xw3ok">Enterprise platform</span><span class="NavLink-module__subtitle--qC15H">AI-powered developer platform</span></div></a></li></ul></div></li><li><div class="NavGroup-module__group--T925n"><span class="NavGroup-module__title--TdKyz">AVAILABLE ADD-ONS</span><ul class="NavGroup-module__list--M8eGv"><li><a href="https://github.com/security/advanced-security" data-analytics-event="{&quot;action&quot;:&quot;github_advanced_security&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_advanced_security_link_enterprise_navbar&quot;}" class="NavLink-module__link--n48VB"><div class="NavLink-module__text--SdWkb"><svg aria-hidden="true" focusable="false" class="octicon octicon-shield-check NavLink-module__icon--h0sw7" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M16.53 9.78a.75.75 0 0 0-1.06-1.06L11 13.19l-1.97-1.97a.75.75 0 0 0-1.06 1.06l2.5 2.5a.75.75 0 0 0 1.06 0l5-5Z"></path><path d="m12.54.637 8.25 2.675A1.75 1.75 0 0 1 22 4.976V10c0 6.19-3.771 10.704-9.401 12.83a1.704 1.704 0 0 1-1.198 0C5.77 20.705 2 16.19 2 10V4.976c0-.758.489-1.43 1.21-1.664L11.46.637a1.748 1.748 0 0 1 1.08 0Zm-.617 1.426-8.25 2.676a.249.249 0 0 0-.173.237V10c0 5.46 3.28 9.483 8.43 11.426a.199.199 0 0 0 .14 0C17.22 19.483 20.5 15.461 20.5 10V4.976a.25.25 0 0 0-.173-.237l-8.25-2.676a.253.253 0 0 0-.154 0Z"></path></svg><span class="NavLink-module__title--xw3ok">GitHub Advanced Security</span><span class="NavLink-module__subtitle--qC15H">Enterprise-grade security features</span></div></a></li><li><a href="https://github.com/features/copilot/copilot-business" data-analytics-event="{&quot;action&quot;:&quot;copilot_for_business&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;copilot_for_business_link_enterprise_navbar&quot;}" class="NavLink-module__link--n48VB"><div class="NavLink-module__text--SdWkb"><svg aria-hidden="true" focusable="false" class="octicon octicon-copilot NavLink-module__icon--h0sw7" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M23.922 16.992c-.861 1.495-5.859 5.023-11.922 5.023-6.063 0-11.061-3.528-11.922-5.023A.641.641 0 0 1 0 16.736v-2.869a.841.841 0 0 1 .053-.22c.372-.935 1.347-2.292 2.605-2.656.167-.429.414-1.055.644-1.517a10.195 10.195 0 0 1-.052-1.086c0-1.331.282-2.499 1.132-3.368.397-.406.89-.717 1.474-.952 1.399-1.136 3.392-2.093 6.122-2.093 2.731 0 4.767.957 6.166 2.093.584.235 1.077.546 1.474.952.85.869 1.132 2.037 1.132 3.368 0 .368-.014.733-.052 1.086.23.462.477 1.088.644 1.517 1.258.364 2.233 1.721 2.605 2.656a.832.832 0 0 1 .053.22v2.869a.641.641 0 0 1-.078.256ZM12.172 11h-.344a4.323 4.323 0 0 1-.355.508C10.703 12.455 9.555 13 7.965 13c-1.725 0-2.989-.359-3.782-1.259a2.005 2.005 0 0 1-.085-.104L4 11.741v6.585c1.435.779 4.514 2.179 8 2.179 3.486 0 6.565-1.4 8-2.179v-6.585l-.098-.104s-.033.045-.085.104c-.793.9-2.057 1.259-3.782 1.259-1.59 0-2.738-.545-3.508-1.492a4.323 4.323 0 0 1-.355-.508h-.016.016Zm.641-2.935c.136 1.057.403 1.913.878 2.497.442.544 1.134.938 2.344.938 1.573 0 2.292-.337 2.657-.751.384-.435.558-1.15.558-2.361 0-1.14-.243-1.847-.705-2.319-.477-.488-1.319-.862-2.824-1.025-1.487-.161-2.192.138-2.533.529-.269.307-.437.808-.438 1.578v.021c0 .265.021.562.063.893Zm-1.626 0c.042-.331.063-.628.063-.894v-.02c-.001-.77-.169-1.271-.438-1.578-.341-.391-1.046-.69-2.533-.529-1.505.163-2.347.537-2.824 1.025-.462.472-.705 1.179-.705 2.319 0 1.211.175 1.926.558 2.361.365.414 1.084.751 2.657.751 1.21 0 1.902-.394 2.344-.938.475-.584.742-1.44.878-2.497Z"></path><path d="M14.5 14.25a1 1 0 0 1 1 1v2a1 1 0 0 1-2 0v-2a1 1 0 0 1 1-1Zm-5 0a1 1 0 0 1 1 1v2a1 1 0 0 1-2 0v-2a1 1 0 0 1 1-1Z"></path></svg><span class="NavLink-module__title--xw3ok">Copilot for Business</span><span class="NavLink-module__subtitle--qC15H">Enterprise-grade AI features</span></div></a></li><li><a href="https://github.com/premium-support" data-analytics-event="{&quot;action&quot;:&quot;premium_support&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;premium_support_link_enterprise_navbar&quot;}" class="NavLink-module__link--n48VB"><div class="NavLink-module__text--SdWkb"><svg aria-hidden="true" focusable="false" class="octicon octicon-comment-discussion NavLink-module__icon--h0sw7" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M1.75 1h12.5c.966 0 1.75.784 1.75 1.75v9.5A1.75 1.75 0 0 1 14.25 14H8.061l-2.574 2.573A1.458 1.458 0 0 1 3 15.543V14H1.75A1.75 1.75 0 0 1 0 12.25v-9.5C0 1.784.784 1 1.75 1ZM1.5 2.75v9.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h6.5a.25.25 0 0 0 .25-.25v-9.5a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25Z"></path><path d="M22.5 8.75a.25.25 0 0 0-.25-.25h-3.5a.75.75 0 0 1 0-1.5h3.5c.966 0 1.75.784 1.75 1.75v9.5A1.75 1.75 0 0 1 22.25 20H21v1.543a1.457 1.457 0 0 1-2.487 1.03L15.939 20H10.75A1.75 1.75 0 0 1 9 18.25v-1.465a.75.75 0 0 1 1.5 0v1.465c0 .138.112.25.25.25h5.5a.75.75 0 0 1 .53.22l2.72 2.72v-2.19a.75.75 0 0 1 .75-.75h2a.25.25 0 0 0 .25-.25v-9.5Z"></path></svg><span class="NavLink-module__title--xw3ok">Premium Support</span><span class="NavLink-module__subtitle--qC15H">Enterprise-grade 24/7 support</span></div></a></li></ul></div></li></ul></div></div></li><li><a href="https://github.com/pricing" data-analytics-event="{&quot;action&quot;:&quot;pricing&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;pricing&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;pricing_link_pricing_navbar&quot;}" class="NavLink-module__link--n48VB MarketingNavigation-module__navLink--U9Uuk"><span class="NavLink-module__title--xw3ok">Pricing</span></a></li></ul></nav><script type="application/json" id="__PRIMER_DATA__R_0___">{"resolvedServerColorMode":"day"}</script></div>
</react-partial>
<div class="d-flex flex-column flex-lg-row width-full flex-justify-end flex-lg-items-center text-center mt-3 mt-lg-0 text-lg-left ml-lg-3">
<qbsearch-input class="search-input" data-scope="" data-custom-scopes-path="/search/custom_scopes" data-delete-custom-scopes-csrf="HkdqGdNJ8Vs2nUMvR1beSG_3kdmjs2NViFue5UPrHJQq-GeYlGX7GMn4GdollCnftLeNval0YvaY-CycxSxN1Q" data-max-custom-scopes="10" data-header-redesign-enabled="false" data-initial-value="" data-blackbird-suggestions-path="/search/suggestions" data-jump-to-suggestions-path="/_graphql/GetSuggestedNavigationDestinations" data-current-repository="" data-current-org="" data-current-owner="" data-logged-in="false" data-copilot-chat-enabled="false" data-nl-search-enabled="false" data-retain-scroll-position="true">
<div
class="search-input-container search-with-dialog position-relative d-flex flex-row flex-items-center mr-4 rounded"
data-action="click:qbsearch-input#searchInputContainerClicked"
>
<button
type="button"
class="header-search-button placeholder input-button form-control d-flex flex-1 flex-self-stretch flex-items-center no-wrap width-full py-0 pl-2 pr-0 text-left border-0 box-shadow-none"
data-target="qbsearch-input.inputButton"
aria-label="Search or jump to…"
aria-haspopup="dialog"
placeholder="Search or jump to..."
data-hotkey=s,/
autocapitalize="off"
data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;searchbar&quot;,&quot;context&quot;:&quot;global&quot;,&quot;tag&quot;:&quot;input&quot;,&quot;label&quot;:&quot;searchbar_input_global_navbar&quot;}"
data-action="click:qbsearch-input#handleExpand"
>
<div class="mr-2 color-fg-muted">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-search">
<path d="M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z"></path>
</svg>
</div>
<span class="flex-1" data-target="qbsearch-input.inputButtonText">Search or jump to...</span>
<div class="d-flex" data-target="qbsearch-input.hotkeyIndicator">
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="20" aria-hidden="true" class="mr-1"><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>
</button>
<input type="hidden" name="type" class="js-site-search-type-field">
<div class="Overlay--hidden " data-modal-dialog-overlay>
<modal-dialog data-action="close:qbsearch-input#handleClose cancel:qbsearch-input#handleClose" data-target="qbsearch-input.searchSuggestionsDialog" role="dialog" id="search-suggestions-dialog" aria-modal="true" aria-labelledby="search-suggestions-dialog-header" data-view-component="true" class="Overlay Overlay--width-large Overlay--height-auto">
<h1 id="search-suggestions-dialog-header" class="sr-only">Search code, repositories, users, issues, pull requests...</h1>
<div class="Overlay-body Overlay-body--paddingNone">
<div data-view-component="true"> <div class="search-suggestions position-fixed width-full color-shadow-large border color-fg-default color-bg-default overflow-hidden d-flex flex-column query-builder-container"
style="border-radius: 12px;"
data-target="qbsearch-input.queryBuilderContainer"
hidden
>
<!-- '"` --><!-- </textarea></xmp> --></option></form><form id="query-builder-test-form" action="" accept-charset="UTF-8" method="get">
<query-builder data-target="qbsearch-input.queryBuilder" id="query-builder-query-builder-test" data-filter-key=":" data-view-component="true" class="QueryBuilder search-query-builder">
<div class="FormControl FormControl--fullWidth">
<label id="query-builder-test-label" for="query-builder-test" class="FormControl-label sr-only">
Search
</label>
<div
class="QueryBuilder-StyledInput width-fit "
data-target="query-builder.styledInput"
>
<span id="query-builder-test-leadingvisual-wrap" class="FormControl-input-leadingVisualWrap QueryBuilder-leadingVisualWrap">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-search FormControl-input-leadingVisual">
<path d="M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z"></path>
</svg>
</span>
<div data-target="query-builder.styledInputContainer" class="QueryBuilder-StyledInputContainer">
<div
aria-hidden="true"
class="QueryBuilder-StyledInputContent"
data-target="query-builder.styledInputContent"
></div>
<div class="QueryBuilder-InputWrapper">
<div aria-hidden="true" class="QueryBuilder-Sizer" data-target="query-builder.sizer"></div>
<input id="query-builder-test" name="query-builder-test" value="" autocomplete="off" type="text" role="combobox" spellcheck="false" aria-expanded="false" aria-describedby="validation-14e01f62-0c3e-4de6-92cb-a60e492ea132" data-target="query-builder.input" data-action="
input:query-builder#inputChange
blur:query-builder#inputBlur
keydown:query-builder#inputKeydown
focus:query-builder#inputFocus
" data-view-component="true" class="FormControl-input QueryBuilder-Input FormControl-medium" />
</div>
</div>
<span class="sr-only" id="query-builder-test-clear">Clear</span>
<button role="button" id="query-builder-test-clear-button" aria-labelledby="query-builder-test-clear query-builder-test-label" data-target="query-builder.clearButton" data-action="
click:query-builder#clear
focus:query-builder#clearButtonFocus
blur:query-builder#clearButtonBlur
" variant="small" hidden="hidden" type="button" data-view-component="true" class="Button Button--iconOnly Button--invisible Button--medium mr-1 px-2 py-0 d-flex flex-items-center rounded-1 color-fg-muted"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x-circle-fill Button-visual">
<path d="M2.343 13.657A8 8 0 1 1 13.658 2.343 8 8 0 0 1 2.343 13.657ZM6.03 4.97a.751.751 0 0 0-1.042.018.751.751 0 0 0-.018 1.042L6.94 8 4.97 9.97a.749.749 0 0 0 .326 1.275.749.749 0 0 0 .734-.215L8 9.06l1.97 1.97a.749.749 0 0 0 1.275-.326.749.749 0 0 0-.215-.734L9.06 8l1.97-1.97a.749.749 0 0 0-.326-1.275.749.749 0 0 0-.734.215L8 6.94Z"></path>
</svg>
</button>
</div>
<template id="search-icon">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-search">
<path d="M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z"></path>
</svg>
</template>
<template id="code-icon">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-code">
<path d="m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z"></path>
</svg>
</template>
<template id="file-code-icon">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-file-code">
<path d="M4 1.75C4 .784 4.784 0 5.75 0h5.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v8.586A1.75 1.75 0 0 1 14.25 15h-9a.75.75 0 0 1 0-1.5h9a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 10 4.25V1.5H5.75a.25.25 0 0 0-.25.25v2.5a.75.75 0 0 1-1.5 0Zm1.72 4.97a.75.75 0 0 1 1.06 0l2 2a.75.75 0 0 1 0 1.06l-2 2a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734l1.47-1.47-1.47-1.47a.75.75 0 0 1 0-1.06ZM3.28 7.78 1.81 9.25l1.47 1.47a.751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018l-2-2a.75.75 0 0 1 0-1.06l2-2a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Zm8.22-6.218V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z"></path>
</svg>
</template>
<template id="history-icon">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-history">
<path d="m.427 1.927 1.215 1.215a8.002 8.002 0 1 1-1.6 5.685.75.75 0 1 1 1.493-.154 6.5 6.5 0 1 0 1.18-4.458l1.358 1.358A.25.25 0 0 1 3.896 6H.25A.25.25 0 0 1 0 5.75V2.104a.25.25 0 0 1 .427-.177ZM7.75 4a.75.75 0 0 1 .75.75v2.992l2.028.812a.75.75 0 0 1-.557 1.392l-2.5-1A.751.751 0 0 1 7 8.25v-3.5A.75.75 0 0 1 7.75 4Z"></path>
</svg>
</template>
<template id="repo-icon">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo">
<path d="M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 0 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.714 1.7.75.75 0 1 1-1.072 1.05A2.495 2.495 0 0 1 2 11.5Zm10.5-1h-8a1 1 0 0 0-1 1v6.708A2.486 2.486 0 0 1 4.5 9h8ZM5 12.25a.25.25 0 0 1 .25-.25h3.5a.25.25 0 0 1 .25.25v3.25a.25.25 0 0 1-.4.2l-1.45-1.087a.249.249 0 0 0-.3 0L5.4 15.7a.25.25 0 0 1-.4-.2Z"></path>
</svg>
</template>
<template id="bookmark-icon">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-bookmark">
<path d="M3 2.75C3 1.784 3.784 1 4.75 1h6.5c.966 0 1.75.784 1.75 1.75v11.5a.75.75 0 0 1-1.227.579L8 11.722l-3.773 3.107A.751.751 0 0 1 3 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v9.91l3.023-2.489a.75.75 0 0 1 .954 0l3.023 2.49V2.75a.25.25 0 0 0-.25-.25Z"></path>
</svg>
</template>
<template id="plus-circle-icon">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-plus-circle">
<path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm7.25-3.25v2.5h2.5a.75.75 0 0 1 0 1.5h-2.5v2.5a.75.75 0 0 1-1.5 0v-2.5h-2.5a.75.75 0 0 1 0-1.5h2.5v-2.5a.75.75 0 0 1 1.5 0Z"></path>
</svg>
</template>
<template id="circle-icon">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-dot-fill">
<path d="M8 4a4 4 0 1 1 0 8 4 4 0 0 1 0-8Z"></path>
</svg>
</template>
<template id="trash-icon">
<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 d="M11 1.75V3h2.25a.75.75 0 0 1 0 1.5H2.75a.75.75 0 0 1 0-1.5H5V1.75C5 .784 5.784 0 6.75 0h2.5C10.216 0 11 .784 11 1.75ZM4.496 6.675l.66 6.6a.25.25 0 0 0 .249.225h5.19a.25.25 0 0 0 .249-.225l.66-6.6a.75.75 0 0 1 1.492.149l-.66 6.6A1.748 1.748 0 0 1 10.595 15h-5.19a1.75 1.75 0 0 1-1.741-1.575l-.66-6.6a.75.75 0 1 1 1.492-.15ZM6.5 1.75V3h3V1.75a.25.25 0 0 0-.25-.25h-2.5a.25.25 0 0 0-.25.25Z"></path>
</svg>
</template>
<template id="team-icon">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-people">
<path d="M2 5.5a3.5 3.5 0 1 1 5.898 2.549 5.508 5.508 0 0 1 3.034 4.084.75.75 0 1 1-1.482.235 4 4 0 0 0-7.9 0 .75.75 0 0 1-1.482-.236A5.507 5.507 0 0 1 3.102 8.05 3.493 3.493 0 0 1 2 5.5ZM11 4a3.001 3.001 0 0 1 2.22 5.018 5.01 5.01 0 0 1 2.56 3.012.749.749 0 0 1-.885.954.752.752 0 0 1-.549-.514 3.507 3.507 0 0 0-2.522-2.372.75.75 0 0 1-.574-.73v-.352a.75.75 0 0 1 .416-.672A1.5 1.5 0 0 0 11 5.5.75.75 0 0 1 11 4Zm-5.5-.5a2 2 0 1 0-.001 3.999A2 2 0 0 0 5.5 3.5Z"></path>
</svg>
</template>
<template id="project-icon">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-project">
<path d="M1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25V1.75C0 .784.784 0 1.75 0ZM1.5 1.75v12.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25ZM11.75 3a.75.75 0 0 1 .75.75v7.5a.75.75 0 0 1-1.5 0v-7.5a.75.75 0 0 1 .75-.75Zm-8.25.75a.75.75 0 0 1 1.5 0v5.5a.75.75 0 0 1-1.5 0ZM8 3a.75.75 0 0 1 .75.75v3.5a.75.75 0 0 1-1.5 0v-3.5A.75.75 0 0 1 8 3Z"></path>
</svg>
</template>
<template id="pencil-icon">
<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 d="M11.013 1.427a1.75 1.75 0 0 1 2.474 0l1.086 1.086a1.75 1.75 0 0 1 0 2.474l-8.61 8.61c-.21.21-.47.364-.756.445l-3.251.93a.75.75 0 0 1-.927-.928l.929-3.25c.081-.286.235-.547.445-.758l8.61-8.61Zm.176 4.823L9.75 4.81l-6.286 6.287a.253.253 0 0 0-.064.108l-.558 1.953 1.953-.558a.253.253 0 0 0 .108-.064Zm1.238-3.763a.25.25 0 0 0-.354 0L10.811 3.75l1.439 1.44 1.263-1.263a.25.25 0 0 0 0-.354Z"></path>
</svg>
</template>
<template id="copilot-icon">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copilot">
<path d="M7.998 15.035c-4.562 0-7.873-2.914-7.998-3.749V9.338c.085-.628.677-1.686 1.588-2.065.013-.07.024-.143.036-.218.029-.183.06-.384.126-.612-.201-.508-.254-1.084-.254-1.656 0-.87.128-1.769.693-2.484.579-.733 1.494-1.124 2.724-1.261 1.206-.134 2.262.034 2.944.765.05.053.096.108.139.165.044-.057.094-.112.143-.165.682-.731 1.738-.899 2.944-.765 1.23.137 2.145.528 2.724 1.261.566.715.693 1.614.693 2.484 0 .572-.053 1.148-.254 1.656.066.228.098.429.126.612.012.076.024.148.037.218.924.385 1.522 1.471 1.591 2.095v1.872c0 .766-3.351 3.795-8.002 3.795Zm0-1.485c2.28 0 4.584-1.11 5.002-1.433V7.862l-.023-.116c-.49.21-1.075.291-1.727.291-1.146 0-2.059-.327-2.71-.991A3.222 3.222 0 0 1 8 6.303a3.24 3.24 0 0 1-.544.743c-.65.664-1.563.991-2.71.991-.652 0-1.236-.081-1.727-.291l-.023.116v4.255c.419.323 2.722 1.433 5.002 1.433ZM6.762 2.83c-.193-.206-.637-.413-1.682-.297-1.019.113-1.479.404-1.713.7-.247.312-.369.789-.369 1.554 0 .793.129 1.171.308 1.371.162.181.519.379 1.442.379.853 0 1.339-.235 1.638-.54.315-.322.527-.827.617-1.553.117-.935-.037-1.395-.241-1.614Zm4.155-.297c-1.044-.116-1.488.091-1.681.297-.204.219-.359.679-.242 1.614.091.726.303 1.231.618 1.553.299.305.784.54 1.638.54.922 0 1.28-.198 1.442-.379.179-.2.308-.578.308-1.371 0-.765-.123-1.242-.37-1.554-.233-.296-.693-.587-1.713-.7Z"></path><path d="M6.25 9.037a.75.75 0 0 1 .75.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 .75-.75Zm4.25.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 1.5 0Z"></path>
</svg>
</template>
<template id="copilot-error-icon">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copilot-error">
<path d="M16 11.24c0 .112-.072.274-.21.467L13 9.688V7.862l-.023-.116c-.49.21-1.075.291-1.727.291-.198 0-.388-.009-.571-.029L6.833 5.226a4.01 4.01 0 0 0 .17-.782c.117-.935-.037-1.395-.241-1.614-.193-.206-.637-.413-1.682-.297-.683.076-1.115.231-1.395.415l-1.257-.91c.579-.564 1.413-.877 2.485-.996 1.206-.134 2.262.034 2.944.765.05.053.096.108.139.165.044-.057.094-.112.143-.165.682-.731 1.738-.899 2.944-.765 1.23.137 2.145.528 2.724 1.261.566.715.693 1.614.693 2.484 0 .572-.053 1.148-.254 1.656.066.228.098.429.126.612.012.076.024.148.037.218.924.385 1.522 1.471 1.591 2.095Zm-5.083-8.707c-1.044-.116-1.488.091-1.681.297-.204.219-.359.679-.242 1.614.091.726.303 1.231.618 1.553.299.305.784.54 1.638.54.922 0 1.28-.198 1.442-.379.179-.2.308-.578.308-1.371 0-.765-.123-1.242-.37-1.554-.233-.296-.693-.587-1.713-.7Zm2.511 11.074c-1.393.776-3.272 1.428-5.43 1.428-4.562 0-7.873-2.914-7.998-3.749V9.338c.085-.628.677-1.686 1.588-2.065.013-.07.024-.143.036-.218.029-.183.06-.384.126-.612-.18-.455-.241-.963-.252-1.475L.31 4.107A.747.747 0 0 1 0 3.509V3.49a.748.748 0 0 1 .625-.73c.156-.026.306.047.435.139l14.667 10.578a.592.592 0 0 1 .227.264.752.752 0 0 1 .046.249v.022a.75.75 0 0 1-1.19.596Zm-1.367-.991L5.635 7.964a5.128 5.128 0 0 1-.889.073c-.652 0-1.236-.081-1.727-.291l-.023.116v4.255c.419.323 2.722 1.433 5.002 1.433 1.539 0 3.089-.505 4.063-.934Z"></path>
</svg>
</template>
<template id="workflow-icon">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-workflow">
<path d="M0 1.75C0 .784.784 0 1.75 0h3.5C6.216 0 7 .784 7 1.75v3.5A1.75 1.75 0 0 1 5.25 7H4v4a1 1 0 0 0 1 1h4v-1.25C9 9.784 9.784 9 10.75 9h3.5c.966 0 1.75.784 1.75 1.75v3.5A1.75 1.75 0 0 1 14.25 16h-3.5A1.75 1.75 0 0 1 9 14.25v-.75H5A2.5 2.5 0 0 1 2.5 11V7h-.75A1.75 1.75 0 0 1 0 5.25Zm1.75-.25a.25.25 0 0 0-.25.25v3.5c0 .138.112.25.25.25h3.5a.25.25 0 0 0 .25-.25v-3.5a.25.25 0 0 0-.25-.25Zm9 9a.25.25 0 0 0-.25.25v3.5c0 .138.112.25.25.25h3.5a.25.25 0 0 0 .25-.25v-3.5a.25.25 0 0 0-.25-.25Z"></path>
</svg>
</template>
<template id="book-icon">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-book">
<path d="M0 1.75A.75.75 0 0 1 .75 1h4.253c1.227 0 2.317.59 3 1.501A3.743 3.743 0 0 1 11.006 1h4.245a.75.75 0 0 1 .75.75v10.5a.75.75 0 0 1-.75.75h-4.507a2.25 2.25 0 0 0-1.591.659l-.622.621a.75.75 0 0 1-1.06 0l-.622-.621A2.25 2.25 0 0 0 5.258 13H.75a.75.75 0 0 1-.75-.75Zm7.251 10.324.004-5.073-.002-2.253A2.25 2.25 0 0 0 5.003 2.5H1.5v9h3.757a3.75 3.75 0 0 1 1.994.574ZM8.755 4.75l-.004 7.322a3.752 3.752 0 0 1 1.992-.572H14.5v-9h-3.495a2.25 2.25 0 0 0-2.25 2.25Z"></path>
</svg>
</template>
<template id="code-review-icon">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-code-review">
<path d="M1.75 1h12.5c.966 0 1.75.784 1.75 1.75v8.5A1.75 1.75 0 0 1 14.25 13H8.061l-2.574 2.573A1.458 1.458 0 0 1 3 14.543V13H1.75A1.75 1.75 0 0 1 0 11.25v-8.5C0 1.784.784 1 1.75 1ZM1.5 2.75v8.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h6.5a.25.25 0 0 0 .25-.25v-8.5a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25Zm5.28 1.72a.75.75 0 0 1 0 1.06L5.31 7l1.47 1.47a.751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018l-2-2a.75.75 0 0 1 0-1.06l2-2a.75.75 0 0 1 1.06 0Zm2.44 0a.75.75 0 0 1 1.06 0l2 2a.75.75 0 0 1 0 1.06l-2 2a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L10.69 7 9.22 5.53a.75.75 0 0 1 0-1.06Z"></path>
</svg>
</template>
<template id="codespaces-icon">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-codespaces">
<path d="M0 11.25c0-.966.784-1.75 1.75-1.75h12.5c.966 0 1.75.784 1.75 1.75v3A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25Zm2-9.5C2 .784 2.784 0 3.75 0h8.5C13.216 0 14 .784 14 1.75v5a1.75 1.75 0 0 1-1.75 1.75h-8.5A1.75 1.75 0 0 1 2 6.75Zm1.75-.25a.25.25 0 0 0-.25.25v5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-5a.25.25 0 0 0-.25-.25Zm-2 9.5a.25.25 0 0 0-.25.25v3c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-3a.25.25 0 0 0-.25-.25Z"></path><path d="M7 12.75a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1-.75-.75Zm-4 0a.75.75 0 0 1 .75-.75h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1-.75-.75Z"></path>
</svg>
</template>
<template id="comment-icon">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-comment">
<path d="M1 2.75C1 1.784 1.784 1 2.75 1h10.5c.966 0 1.75.784 1.75 1.75v7.5A1.75 1.75 0 0 1 13.25 12H9.06l-2.573 2.573A1.458 1.458 0 0 1 4 13.543V12H2.75A1.75 1.75 0 0 1 1 10.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h4.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path>
</svg>
</template>
<template id="comment-discussion-icon">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-comment-discussion">
<path d="M1.75 1h8.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 10.25 10H7.061l-2.574 2.573A1.458 1.458 0 0 1 2 11.543V10h-.25A1.75 1.75 0 0 1 0 8.25v-5.5C0 1.784.784 1 1.75 1ZM1.5 2.75v5.5c0 .138.112.25.25.25h1a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h3.5a.25.25 0 0 0 .25-.25v-5.5a.25.25 0 0 0-.25-.25h-8.5a.25.25 0 0 0-.25.25Zm13 2a.25.25 0 0 0-.25-.25h-.5a.75.75 0 0 1 0-1.5h.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 14.25 12H14v1.543a1.458 1.458 0 0 1-2.487 1.03L9.22 12.28a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l2.22 2.22v-2.19a.75.75 0 0 1 .75-.75h1a.25.25 0 0 0 .25-.25Z"></path>
</svg>
</template>
<template id="organization-icon">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-organization">
<path d="M1.75 16A1.75 1.75 0 0 1 0 14.25V1.75C0 .784.784 0 1.75 0h8.5C11.216 0 12 .784 12 1.75v12.5c0 .085-.006.168-.018.25h2.268a.25.25 0 0 0 .25-.25V8.285a.25.25 0 0 0-.111-.208l-1.055-.703a.749.749 0 1 1 .832-1.248l1.055.703c.487.325.779.871.779 1.456v5.965A1.75 1.75 0 0 1 14.25 16h-3.5a.766.766 0 0 1-.197-.026c-.099.017-.2.026-.303.026h-3a.75.75 0 0 1-.75-.75V14h-1v1.25a.75.75 0 0 1-.75.75Zm-.25-1.75c0 .138.112.25.25.25H4v-1.25a.75.75 0 0 1 .75-.75h2.5a.75.75 0 0 1 .75.75v1.25h2.25a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25h-8.5a.25.25 0 0 0-.25.25ZM3.75 6h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1 0-1.5ZM3 3.75A.75.75 0 0 1 3.75 3h.5a.75.75 0 0 1 0 1.5h-.5A.75.75 0 0 1 3 3.75Zm4 3A.75.75 0 0 1 7.75 6h.5a.75.75 0 0 1 0 1.5h-.5A.75.75 0 0 1 7 6.75ZM7.75 3h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1 0-1.5ZM3 9.75A.75.75 0 0 1 3.75 9h.5a.75.75 0 0 1 0 1.5h-.5A.75.75 0 0 1 3 9.75ZM7.75 9h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1 0-1.5Z"></path>
</svg>
</template>
<template id="rocket-icon">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-rocket">
<path d="M14.064 0h.186C15.216 0 16 .784 16 1.75v.186a8.752 8.752 0 0 1-2.564 6.186l-.458.459c-.314.314-.641.616-.979.904v3.207c0 .608-.315 1.172-.833 1.49l-2.774 1.707a.749.749 0 0 1-1.11-.418l-.954-3.102a1.214 1.214 0 0 1-.145-.125L3.754 9.816a1.218 1.218 0 0 1-.124-.145L.528 8.717a.749.749 0 0 1-.418-1.11l1.71-2.774A1.748 1.748 0 0 1 3.31 4h3.204c.288-.338.59-.665.904-.979l.459-.458A8.749 8.749 0 0 1 14.064 0ZM8.938 3.623h-.002l-.458.458c-.76.76-1.437 1.598-2.02 2.5l-1.5 2.317 2.143 2.143 2.317-1.5c.902-.583 1.74-1.26 2.499-2.02l.459-.458a7.25 7.25 0 0 0 2.123-5.127V1.75a.25.25 0 0 0-.25-.25h-.186a7.249 7.249 0 0 0-5.125 2.123ZM3.56 14.56c-.732.732-2.334 1.045-3.005 1.148a.234.234 0 0 1-.201-.064.234.234 0 0 1-.064-.201c.103-.671.416-2.273 1.15-3.003a1.502 1.502 0 1 1 2.12 2.12Zm6.94-3.935c-.088.06-.177.118-.266.175l-2.35 1.521.548 1.783 1.949-1.2a.25.25 0 0 0 .119-.213ZM3.678 8.116 5.2 5.766c.058-.09.117-.178.176-.266H3.309a.25.25 0 0 0-.213.119l-1.2 1.95ZM12 5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</template>
<template id="shield-check-icon">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-shield-check">
<path d="m8.533.133 5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-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 0 1 1.217-1.667l5.25-1.68a1.748 1.748 0 0 1 1.066 0Zm-.61 1.429.001.001-5.25 1.68a.251.251 0 0 0-.174.237V7c0 1.36.275 2.666 1.057 3.859.784 1.194 2.121 2.342 4.366 3.298a.196.196 0 0 0 .154 0c2.245-.957 3.582-2.103 4.366-3.297C13.225 9.666 13.5 8.358 13.5 7V3.48a.25.25 0 0 0-.174-.238l-5.25-1.68a.25.25 0 0 0-.153 0ZM11.28 6.28l-3.5 3.5a.75.75 0 0 1-1.06 0l-1.5-1.5a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l.97.97 2.97-2.97a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path>
</svg>
</template>
<template id="heart-icon">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-heart">
<path d="m8 14.25.345.666a.75.75 0 0 1-.69 0l-.008-.004-.018-.01a7.152 7.152 0 0 1-.31-.17 22.055 22.055 0 0 1-3.434-2.414C2.045 10.731 0 8.35 0 5.5 0 2.836 2.086 1 4.25 1 5.797 1 7.153 1.802 8 3.02 8.847 1.802 10.203 1 11.75 1 13.914 1 16 2.836 16 5.5c0 2.85-2.045 5.231-3.885 6.818a22.066 22.066 0 0 1-3.744 2.584l-.018.01-.006.003h-.002ZM4.25 2.5c-1.336 0-2.75 1.164-2.75 3 0 2.15 1.58 4.144 3.365 5.682A20.58 20.58 0 0 0 8 13.393a20.58 20.58 0 0 0 3.135-2.211C12.92 9.644 14.5 7.65 14.5 5.5c0-1.836-1.414-3-2.75-3-1.373 0-2.609.986-3.029 2.456a.749.749 0 0 1-1.442 0C6.859 3.486 5.623 2.5 4.25 2.5Z"></path>
</svg>
</template>
<template id="server-icon">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-server">
<path d="M1.75 1h12.5c.966 0 1.75.784 1.75 1.75v4c0 .372-.116.717-.314 1 .198.283.314.628.314 1v4a1.75 1.75 0 0 1-1.75 1.75H1.75A1.75 1.75 0 0 1 0 12.75v-4c0-.358.109-.707.314-1a1.739 1.739 0 0 1-.314-1v-4C0 1.784.784 1 1.75 1ZM1.5 2.75v4c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-4a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25Zm.25 5.75a.25.25 0 0 0-.25.25v4c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-4a.25.25 0 0 0-.25-.25ZM7 4.75A.75.75 0 0 1 7.75 4h4.5a.75.75 0 0 1 0 1.5h-4.5A.75.75 0 0 1 7 4.75ZM7.75 10h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1 0-1.5ZM3 4.75A.75.75 0 0 1 3.75 4h.5a.75.75 0 0 1 0 1.5h-.5A.75.75 0 0 1 3 4.75ZM3.75 10h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1 0-1.5Z"></path>
</svg>
</template>
<template id="globe-icon">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-globe">
<path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM5.78 8.75a9.64 9.64 0 0 0 1.363 4.177c.255.426.542.832.857 1.215.245-.296.551-.705.857-1.215A9.64 9.64 0 0 0 10.22 8.75Zm4.44-1.5a9.64 9.64 0 0 0-1.363-4.177c-.307-.51-.612-.919-.857-1.215a9.927 9.927 0 0 0-.857 1.215A9.64 9.64 0 0 0 5.78 7.25Zm-5.944 1.5H1.543a6.507 6.507 0 0 0 4.666 5.5c-.123-.181-.24-.365-.352-.552-.715-1.192-1.437-2.874-1.581-4.948Zm-2.733-1.5h2.733c.144-2.074.866-3.756 1.58-4.948.12-.197.237-.381.353-.552a6.507 6.507 0 0 0-4.666 5.5Zm10.181 1.5c-.144 2.074-.866 3.756-1.58 4.948-.12.197-.237.381-.353.552a6.507 6.507 0 0 0 4.666-5.5Zm2.733-1.5a6.507 6.507 0 0 0-4.666-5.5c.123.181.24.365.353.552.714 1.192 1.436 2.874 1.58 4.948Z"></path>
</svg>
</template>
<template id="issue-opened-icon">
<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">
<path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"></path>
</svg>
</template>
<template id="device-mobile-icon">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-device-mobile">
<path d="M3.75 0h8.5C13.216 0 14 .784 14 1.75v12.5A1.75 1.75 0 0 1 12.25 16h-8.5A1.75 1.75 0 0 1 2 14.25V1.75C2 .784 2.784 0 3.75 0ZM3.5 1.75v12.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25h-8.5a.25.25 0 0 0-.25.25ZM8 13a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"></path>
</svg>
</template>
<template id="package-icon">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-package">
<path d="m8.878.392 5.25 3.045c.54.314.872.89.872 1.514v6.098a1.75 1.75 0 0 1-.872 1.514l-5.25 3.045a1.75 1.75 0 0 1-1.756 0l-5.25-3.045A1.75 1.75 0 0 1 1 11.049V4.951c0-.624.332-1.201.872-1.514L7.122.392a1.75 1.75 0 0 1 1.756 0ZM7.875 1.69l-4.63 2.685L8 7.133l4.755-2.758-4.63-2.685a.248.248 0 0 0-.25 0ZM2.5 5.677v5.372c0 .09.047.171.125.216l4.625 2.683V8.432Zm6.25 8.271 4.625-2.683a.25.25 0 0 0 .125-.216V5.677L8.75 8.432Z"></path>
</svg>
</template>
<template id="credit-card-icon">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-credit-card">
<path d="M10.75 9a.75.75 0 0 0 0 1.5h1.5a.75.75 0 0 0 0-1.5h-1.5Z"></path><path d="M0 3.75C0 2.784.784 2 1.75 2h12.5c.966 0 1.75.784 1.75 1.75v8.5A1.75 1.75 0 0 1 14.25 14H1.75A1.75 1.75 0 0 1 0 12.25ZM14.5 6.5h-13v5.75c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25Zm0-2.75a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25V5h13Z"></path>
</svg>
</template>
<template id="play-icon">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-play">
<path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm4.879-2.773 4.264 2.559a.25.25 0 0 1 0 .428l-4.264 2.559A.25.25 0 0 1 6 10.559V5.442a.25.25 0 0 1 .379-.215Z"></path>
</svg>
</template>
<template id="gift-icon">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-gift">
<path d="M2 2.75A2.75 2.75 0 0 1 4.75 0c.983 0 1.873.42 2.57 1.232.268.318.497.668.68 1.042.183-.375.411-.725.68-1.044C9.376.42 10.266 0 11.25 0a2.75 2.75 0 0 1 2.45 4h.55c.966 0 1.75.784 1.75 1.75v2c0 .698-.409 1.301-1 1.582v4.918A1.75 1.75 0 0 1 13.25 16H2.75A1.75 1.75 0 0 1 1 14.25V9.332C.409 9.05 0 8.448 0 7.75v-2C0 4.784.784 4 1.75 4h.55c-.192-.375-.3-.8-.3-1.25ZM7.25 9.5H2.5v4.75c0 .138.112.25.25.25h4.5Zm1.5 0v5h4.5a.25.25 0 0 0 .25-.25V9.5Zm0-4V8h5.5a.25.25 0 0 0 .25-.25v-2a.25.25 0 0 0-.25-.25Zm-7 0a.25.25 0 0 0-.25.25v2c0 .138.112.25.25.25h5.5V5.5h-5.5Zm3-4a1.25 1.25 0 0 0 0 2.5h2.309c-.233-.818-.542-1.401-.878-1.793-.43-.502-.915-.707-1.431-.707ZM8.941 4h2.309a1.25 1.25 0 0 0 0-2.5c-.516 0-1 .205-1.43.707-.337.392-.646.975-.879 1.793Z"></path>
</svg>
</template>
<template id="code-square-icon">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-code-square">
<path d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25Zm7.47 3.97a.75.75 0 0 1 1.06 0l2 2a.75.75 0 0 1 0 1.06l-2 2a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L10.69 8 9.22 6.53a.75.75 0 0 1 0-1.06ZM6.78 6.53 5.31 8l1.47 1.47a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215l-2-2a.75.75 0 0 1 0-1.06l2-2a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path>
</svg>
</template>
<template id="device-desktop-icon">
<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 d="M14.25 1c.966 0 1.75.784 1.75 1.75v7.5A1.75 1.75 0 0 1 14.25 12h-3.727c.099 1.041.52 1.872 1.292 2.757A.752.752 0 0 1 11.25 16h-6.5a.75.75 0 0 1-.565-1.243c.772-.885 1.192-1.716 1.292-2.757H1.75A1.75 1.75 0 0 1 0 10.25v-7.5C0 1.784.784 1 1.75 1ZM1.75 2.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25ZM9.018 12H6.982a5.72 5.72 0 0 1-.765 2.5h3.566a5.72 5.72 0 0 1-.765-2.5Z"></path>
</svg>
</template>
<div class="position-relative">
<ul
role="listbox"
class="ActionListWrap QueryBuilder-ListWrap"
aria-label="Suggestions"
data-action="
combobox-commit:query-builder#comboboxCommit
mousedown:query-builder#resultsMousedown
"
data-target="query-builder.resultsList"
data-persist-list=false
id="query-builder-test-results"
tabindex="-1"
></ul>
</div>
<div class="FormControl-inlineValidation" id="validation-14e01f62-0c3e-4de6-92cb-a60e492ea132" hidden="hidden">
<span class="FormControl-inlineValidation--visual">
<svg aria-hidden="true" height="12" viewBox="0 0 12 12" version="1.1" width="12" data-view-component="true" class="octicon octicon-alert-fill">
<path d="M4.855.708c.5-.896 1.79-.896 2.29 0l4.675 8.351a1.312 1.312 0 0 1-1.146 1.954H1.33A1.313 1.313 0 0 1 .183 9.058ZM7 7V3H5v4Zm-1 3a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z"></path>
</svg>
</span>
<span></span>
</div> </div>
<div data-target="query-builder.screenReaderFeedback" aria-live="polite" aria-atomic="true" class="sr-only"></div>
</query-builder></form>
<div class="d-flex flex-row color-fg-muted px-3 text-small color-bg-default search-feedback-prompt">
<a target="_blank" href="https://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax" data-view-component="true" class="Link color-fg-accent text-normal ml-2">Search syntax tips</a> <div class="d-flex flex-1"></div>
</div>
</div>
</div>
</div>
</modal-dialog></div>
</div>
<div data-action="click:qbsearch-input#retract" class="dark-backdrop position-fixed" hidden data-target="qbsearch-input.darkBackdrop"></div>
<div class="color-fg-default">
<dialog-helper>
<dialog data-target="qbsearch-input.feedbackDialog" data-action="close:qbsearch-input#handleDialogClose cancel:qbsearch-input#handleDialogClose" id="feedback-dialog" aria-modal="true" aria-labelledby="feedback-dialog-title" aria-describedby="feedback-dialog-description" data-view-component="true" class="Overlay Overlay-whenNarrow Overlay--size-medium Overlay--motion-scaleFade Overlay--disableScroll">
<div data-view-component="true" class="Overlay-header">
<div class="Overlay-headerContentWrap">
<div class="Overlay-titleWrap">
<h1 class="Overlay-title " id="feedback-dialog-title">
Provide feedback
</h1>
</div>
<div class="Overlay-actionWrap">
<button data-close-dialog-id="feedback-dialog" aria-label="Close" aria-label="Close" type="button" data-view-component="true" class="close-button Overlay-closeButton"><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 d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg></button>
</div>
</div>
</div>
<scrollable-region data-labelled-by="feedback-dialog-title">
<div data-view-component="true" class="Overlay-body"> <!-- '"` --><!-- </textarea></xmp> --></option></form><form id="code-search-feedback-form" data-turbo="false" action="/search/feedback" accept-charset="UTF-8" method="post"><input type="hidden" name="authenticity_token" value="2qeT7m6wjvKcwsOASFdF_atxwPphK7MV-W6ON4TMzFwV6GjOx_uqvp1byLjVGDWpFsUuasPrSjRoZj2R1HdgoA" />
<p>We read every piece of feedback, and take your input very seriously.</p>
<textarea name="feedback" class="form-control width-full mb-2" style="height: 120px" id="feedback"></textarea>
<input name="include_email" id="include_email" aria-label="Include my email address so I can be contacted" class="form-control mr-2" type="checkbox">
<label for="include_email" style="font-weight: normal">Include my email address so I can be contacted</label>
</form></div>
</scrollable-region>
<div data-view-component="true" class="Overlay-footer Overlay-footer--alignEnd"> <button data-close-dialog-id="feedback-dialog" type="button" data-view-component="true" class="btn"> Cancel
</button>
<button form="code-search-feedback-form" data-action="click:qbsearch-input#submitFeedback" type="submit" data-view-component="true" class="btn-primary btn"> Submit feedback
</button>
</div>
</dialog></dialog-helper>
<custom-scopes data-target="qbsearch-input.customScopesManager">
<dialog-helper>
<dialog data-target="custom-scopes.customScopesModalDialog" data-action="close:qbsearch-input#handleDialogClose cancel:qbsearch-input#handleDialogClose" id="custom-scopes-dialog" aria-modal="true" aria-labelledby="custom-scopes-dialog-title" aria-describedby="custom-scopes-dialog-description" data-view-component="true" class="Overlay Overlay-whenNarrow Overlay--size-medium Overlay--motion-scaleFade Overlay--disableScroll">
<div data-view-component="true" class="Overlay-header Overlay-header--divided">
<div class="Overlay-headerContentWrap">
<div class="Overlay-titleWrap">
<h1 class="Overlay-title " id="custom-scopes-dialog-title">
Saved searches
</h1>
<h2 id="custom-scopes-dialog-description" class="Overlay-description">Use saved searches to filter your results more quickly</h2>
</div>
<div class="Overlay-actionWrap">
<button data-close-dialog-id="custom-scopes-dialog" aria-label="Close" aria-label="Close" type="button" data-view-component="true" class="close-button Overlay-closeButton"><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 d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg></button>
</div>
</div>
</div>
<scrollable-region data-labelled-by="custom-scopes-dialog-title">
<div data-view-component="true" class="Overlay-body"> <div data-target="custom-scopes.customScopesModalDialogFlash"></div>
<div hidden class="create-custom-scope-form" data-target="custom-scopes.createCustomScopeForm">
<!-- '"` --><!-- </textarea></xmp> --></option></form><form id="custom-scopes-dialog-form" data-turbo="false" action="/search/custom_scopes" accept-charset="UTF-8" method="post"><input type="hidden" name="authenticity_token" value="qgiYjcVenjN8M1vqjYxNjGflwpwSlSXhgwfRIz8slA879pHYG44EFuVQyrXxlh4KNNV2IUIAHyTZbrwIAKrU-Q" />
<div data-target="custom-scopes.customScopesModalDialogFlash"></div>
<input type="hidden" id="custom_scope_id" name="custom_scope_id" data-target="custom-scopes.customScopesIdField">
<div class="form-group">
<label for="custom_scope_name">Name</label>
<auto-check src="/search/custom_scopes/check_name" required>
<input
type="text"
name="custom_scope_name"
id="custom_scope_name"
data-target="custom-scopes.customScopesNameField"
class="form-control"
autocomplete="off"
placeholder="github-ruby"
required
maxlength="50">
<input type="hidden" value="jIQQkOd9C9bXlJHGXcXtdi8fCHqR_gXOs2nYtq3S05DqY7zNPDSi8VPeI62mizWRulPxtEghm84Fup-KFVP3PA" data-csrf="true" />
</auto-check>
</div>
<div class="form-group">
<label for="custom_scope_query">Query</label>
<input
type="text"
name="custom_scope_query"
id="custom_scope_query"
data-target="custom-scopes.customScopesQueryField"
class="form-control"
autocomplete="off"
placeholder="(repo:mona/a OR repo:mona/b) AND lang:python"
required
maxlength="500">
</div>
<p class="text-small color-fg-muted">
To see all available qualifiers, see our <a class="Link--inTextBlock" href="https://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax">documentation</a>.
</p>
</form> </div>
<div data-target="custom-scopes.manageCustomScopesForm">
<div data-target="custom-scopes.list"></div>
</div>
</div>
</scrollable-region>
<div data-view-component="true" class="Overlay-footer Overlay-footer--alignEnd Overlay-footer--divided"> <button data-action="click:custom-scopes#customScopesCancel" type="button" data-view-component="true" class="btn"> Cancel
</button>
<button form="custom-scopes-dialog-form" data-action="click:custom-scopes#customScopesSubmit" data-target="custom-scopes.customScopesSubmitButton" type="submit" data-view-component="true" class="btn-primary btn"> Create saved search
</button>
</div>
</dialog></dialog-helper>
</custom-scopes>
</div>
</qbsearch-input>
<div class="position-relative HeaderMenu-link-wrap d-lg-inline-block">
<a
href="/login?return_to=https%3A%2F%2Fgithub.com%2Fwashingtonpost%2Fwpds-ui-kit%2Fraw%2Fv1.23.1%2Fui%2Fpopover%2Fsrc%2Fplay.stories.tsx%2F"
class="HeaderMenu-link HeaderMenu-link--sign-in HeaderMenu-button flex-shrink-0 no-underline d-none d-lg-inline-flex border border-lg-0 rounded px-2 py-1"
style="margin-left: 12px;"
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/washingtonpost/wpds-ui-kit/raw/v1.23.1/ui/popover/src/play.stories.tsx&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="4faa9d0c8ca81fb384f58154f046db4ac8f1e750b847fa8f0b468be87bb93502"
data-analytics-event="{&quot;category&quot;:&quot;Marketing nav&quot;,&quot;action&quot;:&quot;click to go to homepage&quot;,&quot;label&quot;:&quot;ref_page:Marketing;ref_cta:Sign in;ref_loc:Header&quot;}"
>
Sign in
</a>
<div style="right: -30%; background-color: transparent; border: none" data-view-component="true" class="auth-form-body Popover position-absolute d-none d-sm-none d-md-none d-lg-block">
<div style="width: 300px" data-view-component="true" class="Popover-message Box Popover-message--top-right color-fg-default p-4 mt-2 mx-auto text-left">
<h4 data-view-component="true" class="color-fg-default mb-2"> Sign in to GitHub
</h4>
<!-- '"` --><!-- </textarea></xmp> --></option></form><form data-turbo="false" action="/session" accept-charset="UTF-8" method="post"><input type="hidden" name="authenticity_token" value="-kRTE-TX3GzfNy7KP8iHNDKKyMWBv762W34pNnQ7MXqXdIlGFEzkTu2gG8cI7WiCMJxGJxXu9UHQ_AN8GXEAQA" /> <input type="hidden" name="add_account" id="add_account" autocomplete="off" class="form-control" />
<label for="login_field">
Username or email address
</label>
<input type="text" name="login" id="login_field" class="form-control input-block js-login-field" autocapitalize="off" autocorrect="off" autocomplete="username" autofocus="autofocus" required="required" />
<div class="position-relative">
<label for="password">
Password
</label>
<input type="password" name="password" id="password" class="form-control form-control input-block js-password-field" autocomplete="current-password" required="required" />
<a class="label-link position-absolute top-0 right-0" id="forgot-password" href="/password_reset">Forgot password?</a>
<input type="hidden" name="webauthn-conditional" value="undefined">
<input type="hidden" class="js-support" name="javascript-support" value="unknown">
<input type="hidden" class="js-webauthn-support" name="webauthn-support" value="unknown">
<input type="hidden" class="js-webauthn-iuvpaa-support" name="webauthn-iuvpaa-support" value="unknown">
<input type="hidden" name="return_to" id="return_to" value="https://github.com/washingtonpost/wpds-ui-kit/raw/v1.23.1/ui/popover/src/play.stories.tsx/" autocomplete="off" class="form-control" />
<input type="hidden" name="allow_signup" id="allow_signup" autocomplete="off" class="form-control" />
<input type="hidden" name="client_id" id="client_id" autocomplete="off" class="form-control" />
<input type="hidden" name="integration" id="integration" autocomplete="off" class="form-control" />
<input type="text" name="required_field_d582" hidden="hidden" class="form-control" /><input type="hidden" name="timestamp" value="1768436295420" autocomplete="off" class="form-control" /><input type="hidden" name="timestamp_secret" value="005538551ec552ecf85c0f4dd3d0b00bf7482201b70843b3633bb57be00188da" autocomplete="off" class="form-control" />
<input type="submit" name="commit" value="Sign in" class="btn btn-primary btn-block js-sign-in-button" data-disable-with="Signing in…" data-signin-label="Sign in" data-sso-label="Sign in with your identity provider" development="false" disable-emu-sso="false" />
</div>
</form> <webauthn-status class="js-webauthn-login-emu-control">
<div data-target="webauthn-status.partial" class="d-flex flex-justify-between flex-column mt-3 mb-0" hidden>
<a href="/login?return_to=https%3A%2F%2Fgithub.com%2Fwashingtonpost%2Fwpds-ui-kit%2Fraw%2Fv1.23.1%2Fui%2Fpopover%2Fsrc%2Fplay.stories.tsx%2F" data-analytics-event="{&quot;category&quot;:&quot;passkey_404_login&quot;,&quot;action&quot;:&quot;clicked&quot;,&quot;label&quot;:null}" data-view-component="true" class="Button--link Button--medium Button"> <span class="Button-content">
<span class="Button-label">or continue with other methods</span>
</span>
</a>
</div>
</webauthn-status>
</div></div> </div>
<a href="/signup?ref_cta=Sign+up&amp;ref_loc=header+logged+out&amp;ref_page=%2Fwashingtonpost%2Fwpds-ui-kit%2Fraw%2Fv1.23.1%2Fui%2Fpopover%2Fsrc%2Fplay.stories.tsx&amp;source=header"
class="HeaderMenu-link HeaderMenu-link--sign-up HeaderMenu-button flex-shrink-0 d-flex d-lg-inline-flex 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/washingtonpost/wpds-ui-kit/raw/v1.23.1/ui/popover/src/play.stories.tsx&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="4faa9d0c8ca81fb384f58154f046db4ac8f1e750b847fa8f0b468be87bb93502"
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:/washingtonpost/wpds-ui-kit/raw/v1.23.1/ui/popover/src/play.stories.tsx;ref_cta:Sign up;ref_loc:header logged out&quot;}"
>
Sign up
</a>
<div class="AppHeader-appearanceSettings">
<react-partial-anchor>
<button data-target="react-partial-anchor.anchor" id="icon-button-5df64c22-d2f9-42f1-afdd-6698bd2c224d" aria-labelledby="tooltip-d3df88ee-fcc3-4f1d-8d84-e3ed68b3bc51" type="button" disabled="disabled" data-view-component="true" class="Button Button--iconOnly Button--invisible Button--medium AppHeader-button HeaderMenu-link border cursor-wait"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-sliders Button-visual">
<path d="M15 2.75a.75.75 0 0 1-.75.75h-4a.75.75 0 0 1 0-1.5h4a.75.75 0 0 1 .75.75Zm-8.5.75v1.25a.75.75 0 0 0 1.5 0v-4a.75.75 0 0 0-1.5 0V2H1.75a.75.75 0 0 0 0 1.5H6.5Zm1.25 5.25a.75.75 0 0 0 0-1.5h-6a.75.75 0 0 0 0 1.5h6ZM15 8a.75.75 0 0 1-.75.75H11.5V10a.75.75 0 1 1-1.5 0V6a.75.75 0 0 1 1.5 0v1.25h2.75A.75.75 0 0 1 15 8Zm-9 5.25v-2a.75.75 0 0 0-1.5 0v1.25H1.75a.75.75 0 0 0 0 1.5H4.5v1.25a.75.75 0 0 0 1.5 0v-2Zm9 0a.75.75 0 0 1-.75.75h-6a.75.75 0 0 1 0-1.5h6a.75.75 0 0 1 .75.75Z"></path>
</svg>
</button><tool-tip id="tooltip-d3df88ee-fcc3-4f1d-8d84-e3ed68b3bc51" for="icon-button-5df64c22-d2f9-42f1-afdd-6698bd2c224d" popover="manual" data-direction="s" data-type="label" data-view-component="true" class="sr-only position-absolute">Appearance settings</tool-tip>
<template data-target="react-partial-anchor.template">
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react.ba8e7c6202eb5114c3af.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/appearance-settings.753d458774a2f782559b.module.css" />
<react-partial
partial-name="appearance-settings"
data-ssr="false"
data-attempted-ssr="false"
data-react-profiling="true"
>
<script type="application/json" data-target="react-partial.embeddedData">{"props":{}}</script>
<div data-target="react-partial.reactRoot"></div>
</react-partial>
</template>
</react-partial-anchor>
</div>
<button type="button" class="sr-only js-header-menu-focus-trap d-block d-lg-none">Resetting focus</button>
</div>
</div>
</div>
</div>
</header>
<div hidden="hidden" data-view-component="true" class="js-stale-session-flash stale-session-flash flash flash-warn flash-full">
<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 d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
<span class="js-stale-session-flash-signed-in" hidden>You signed in with another tab or window. <a class="Link--inTextBlock" 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 class="Link--inTextBlock" href="">Reload</a> to refresh your session.</span>
<span class="js-stale-session-flash-switched" hidden>You switched accounts on another tab or window. <a class="Link--inTextBlock" href="">Reload</a> to refresh your session.</span>
<button id="icon-button-f6874361-f02c-40c5-9fff-81d9887b13ec" aria-labelledby="tooltip-a7b7eb52-28c3-4570-a456-1929d8917578" type="button" data-view-component="true" class="Button Button--iconOnly Button--invisible Button--medium flash-close js-flash-close"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x Button-visual">
<path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg>
</button><tool-tip id="tooltip-a7b7eb52-28c3-4570-a456-1929d8917578" for="icon-button-f6874361-f02c-40c5-9fff-81d9887b13ec" popover="manual" data-direction="s" data-type="label" data-view-component="true" class="sr-only position-absolute">Dismiss alert</tool-tip>
</div>
</div>
<div id="start-of-content" class="show-on-focus"></div>
<div id="js-flash-container" class="flash-container" data-turbo-replace>
<template class="js-flash-template">
<div class="flash flash-full {{ className }}">
<div >
<button autofocus 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 d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg>
</button>
<div aria-atomic="true" role="alert" class="js-flash-alert">
<div>{{ message }}</div>
</div>
</div>
</div>
</template>
</div>
<div
class="application-main d-flex flex-auto flex-column"
data-commit-hovercards-enabled
data-discussion-hovercards-enabled
data-issue-and-pr-hovercards-enabled
data-project-hovercards-enabled
>
<main class="font-mktg " >
<div class="position-relative" style="z-index: 0; transition: all 0.25s ease-in">
<div class="position-absolute overflow-hidden width-full top-0 left-0" style="height: 370px" data-hpc>
<img alt="" class="position-absolute" height="415" width="940" style="top: -20px; left: -20px; z-index: 1; width: 110%; height: 425px"
src="data:image/jpeg;base64,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">
</div>
<div class="position-relative d-block my-0 mx-auto overflow-hidden" style="width: 940px; height: 370px; clear: both">
<img alt="404 &ldquo;This is not the web page you are looking for&rdquo;" class="position-absolute" height="249" width="271" style="z-index: 10; left: 72px; top: 72px"
src="data:image/png;base64,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">
<img alt="" class="position-absolute" height="230" width="188" style="top: 94px; left: 356px; z-index: 9;"
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALwAAADmCAMAAABYgh8IAAAAA3NCSVQICAjb4U/gAAABgFBMVEX///9SOCxSOjH/wp8AAAD+wJ4ICAhWPjL/7tDMQjj////66834vZuZmZmVcl+bdmN7KCIxIRr39/dUQjpRS0nFQjhKMihptaVQRUEzJyAyIx46KSF8LSdAKyJSOCxUQjqcincQEBBSOjFSOjHzp4tSOCz/xqZSOjFkTEBUQjpSOjG7qJP/+PQpHhpSOjFSOjH87+jz4cRqUURDMSlTSURQRUFUQjr/1r//0bAaEg9UQjqHZFL/59nOTENTSURSOCyNfGojGhddV0wpKSnGl3yWlJKUh3d4YlM5OTkQEBDez7fLvKWdj4hzW0xIQj/05+bbp4nWZlZTSURTSURSOjFSOjHo17yMgn5+bFwZLSlWPjL358v/4sL5w6XWxKyJcmF3VkYhFxIzMzP86MynnIi1jHRXmYwhISEYGBhSOCwICAj50rvehn+SblqRMClWPjIICAgAAACLZWJAa2I2XVRRS0kQEBBUQjpLOC/xt5blqqWvhnBNh3spRD4ICAhWPjKmNNozAAAAgHRSTlMA////////////////////////RBH///8i///////uZv//d4j/3f+q/1WZ////Zrv/////IjN3////M////zPM//8RM/////8RiP////8R////EUTM7v////+7/////////yL/////RGa73f////+q7u7///8id5mq//////+q7kFCNkwAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAcdEVYdFNvZnR3YXJlAEFkb2JlIEZpcmV3b3JrcyBDUzQGstOgAAAgAElEQVR4nMVdh0PUyBo32U2C7gLC0vvCozcBQREbFlTUs/feFfXOe/q84on/+pv2lZkkm6x3nCNuSzL5zTe/r8zMl2TXrsTSNrny2/z8+PBgZX/yDv9e6Tp6rXKongMGPV0i+TI+eXWngGWUrsmpGxrGt2u5DxrxfIPel3++d2ywbQcxJpa2ym8DHit5hV9B6JGvP/q+P145saNgrdJWmcKeV/LzvBs5xXfds4togUDvfRv5l/hf+c3Xvc763/NWch3b5bFjtOhNB3jjR3cY965dhzTN7aJ0L5fo57CxrPHw4Vh+zfke5ILnvoNZ/+BH3mSeGqboCHV8RE2R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">
<img alt="" class="position-absolute" height="156" width="440" style="top: 150px; left: 432px; z-index: 8;"
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAbgAAACcCAMAAAA6Xk4VAAAAA3NCSVQICAjb4U/gAAADAFBMVEX///9NmcCTfmuUe2OQd2KMdWGGcFqEbVqEa1JNmcCbhGucf2ibhGucf2iUe2NHhaiQd2KfinFJm8ajhWubhGucf2iDeW2Qd2KBdmuMclqKbllzYExJm8ajhWubhGucf2iMclqKbllJnctEnMubhGucf2icfWKQd2JChaxJnctEnMujhWubhGuegWWcf2iQd2KjhWubhGuegWWcf2iUe2OMclqKbllIodGjhWubhGuegWWUe2OMclpEpNdBoNOnimujhWuegWWUe2M8iriMclpsWkhDp92ljXOnimujhWulhGSegWWcfWKUe2M4i76VeF2Uc1mMclqOb1NCq+FDp92tjXCnimujhWulhGQyi8WMclpPrdxLrN1Cq+FAquM9quM/qOOvkG87peCtjXCtjGunimuqh2o2n9ujhWurhGSlhGQ2ltKcfWIvktAvjs0yi8Uqi8sticWUc1mTcVRpUkJkUUFardVTrdhPqNSvkG+yj3CtjGutiWenimuqh2qrhGSegWWcfWIyi8UxiL+Uc1m9poq9pIa1nYJgrdNirNBardVqqsezmn2wmX5aqtCVnZWtlXq0k3NapMxTps+sk3a0kW6yj3CvkG+zjmymkXZTositjGuljXNSncOtiWdQm7+nimuqh2qfinFNmcCrhGSchnOjhWtQlrx5jpGlhGSbhGuUhHWegWWmfmGcf2iMgniVgW2ifF2cfWKTfmtIjrVCjLSceluUe2ODfnhAiLeVeF2PemR6enqQd2I7h7qZdFlChayUc1mMdWE6hbZ0eXw6g6+TcVSMclqOb1M6gKaGcFpqdX2KblmMa1OEbVphc4GEa1JecX+EaE4yeaKDZk98aFSDZEwxdJ5RbYF5ZFJ7YkswcJZ1YU9DaoN5XklzYEwubJN0XEkpapM5ZYFzWUNsWkhrV0MzYX8tX35pUkJoUj5kUUEpXH1jTzxgTj9hTDpbSjpRQjZSQjNMPzNLPDFHOS1CODBENyxANCs9NC86MCo3LSgwKSktJycvJyUrJCR/7i4wAAABAHRSTlMAEREREREREREiIiIzMzMzM0REREREREREREREVVVVVVVVZmZmZmZmZnd3d3d3d3eIiIiIiIiImZmZmZmZqqqqqqqqqqqqu7u7u7u7u7u7u7u7u8zMzMzMzMzM3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7u7u7u7u7u7u7u7u7u7u////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////WBVVlgAAAAlwSFlzAAALEgAACxIB0t1+/AAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNAay06AAACAASURBVHic7Z0LYFtl2ce7DS8MxsdgE0VwoOxTUWFsMHCICKKuXJSbOoG0xSGKjG0OAbmo3NwYKDbYnKWkBjsGmtoOEyXIGNRUvrVOOktpCy2jI5hmTbuypDljY03p97z39z3nJM2lJIPmaZqce855f+f/XN5zkpSUHBB20OzZcxacsuCURaWlpYtgYPbsaYXepaKlsumfWHBO6Q9+5LKyH5R+fkah969oZptx0jnf/YUlMcl+fsHcQu9n0bhNnbOg9Ae14zEjtsFz57kfKPQOFw10tmB8mQmr9SC788wiuoLa1LnnZAANDGPzBNpfWHV4ofd98tqMLy7JCBrj9kI0FtP1gYWF3v9JaVPnlv48U2rUTwZjcV2P6/Ho8YU+iMlns865PXNqLpcbc9P1WDyO4A1/vNDHMcns89ZF2viGuLWD2PS9+/fpMdBcoY9kUtmcLFykAOcHXvrIWCIxsgcGvlbog5lEdkrW2LDgQroO3MbGRscSe8BZFvpoJo/NzZ4binB+SEv2AbWxxNjY28CwKLk82fTMqjbFUErZAwEOmCFLjAG43YU+oMlipdlzQ56yfliPv4X8JLb9QK6YWObFDsuBGwLXoseGEwkc4ZC7LPrKfNlXcuCGQtx2Pb4HgCVGsbsc3avrNxX6kCaH3ZEjuKGYvo85SnjZH48VS7l82Cdy4IZzk1h8+O3RUUINnOXIcFz/cKEPajLYolzAbYBiIK7H9icgn0wkcIwbgRq8mJ3kwc7PBRy6mhOP6YgbqQbAYvF4MTvJg2XbR8nAtUH5jZJKym5sbE8xrcyLZd9LScC1AzhwkaOjOMSNjo3u0eM/LfRBTQbLodsEg+vS43Ge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">
<img alt="" class="position-absolute" height="49" width="166" style=" top: 297px; left: 371px; z-index: 7;"
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKYAAAAxCAYAAABQ69KMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAHXRJREFUeNqEXW/Ebld2X2u/rxBCCCEk7kjdunVJ3XHHMBVCKoRUxjC0OqaUofphVNMvjaE1NbSG9ktDCaH6IRKlY9IZMzoavVq9xFyuiUYuISbmaoiGEC7h2avrnL33Wr+19j5vbjx5z/Occ/bZZ++115/f+rP5h6/8KRUSov2j/2cmkUIsQsxVf2X9z8/p//Zjpqr/Ff1vu6bYNVs72/ft63b9dn78fvxPr4f22tUMbbYnCv5f+5H7V7Xfhavdsb8Hz+1t/dPXg2s59E/78bj24yHozwP6uWLtTn1rzxpNcW8F297HpN3zkd77wRjPbZy1vVt8wfj4e7RxEmJruZ3n8J77HLHsfaz7Pds8nGjd/7L3jtMc5fFqv0j/f+l3nvb29+u2Bqr3o9JZeCb+83PFxinT2TkSpQ0CiT0AL2bBAadO0P12FnhAhQnyiWFcAPtgSyfGUyCqcRwHUGwi9uP+PKSpQJTc+0F0TS+6T9u51k9d1d/v19MPax8u9Ql8RK95dPRzvFeBd6W0RGLfYEJgMdjQwKQjAW5EuWjvM23j7f4u97SP72x91H7d0XY+1d/u6nUf6t/39fPxePa4vxGJz0Ve6IPI23zUNp87w5HDd2yLWPyerW9jzMcYdRoYRLe/G8cWfQyq0wmctbnXs+dErbH2UrW9mFBqdLxre7Hx4rSv1NiB8EL7X+7DUoG4qROW2KpqE9GuLX3gCNoaK3PiopWvabuXdYA2jnZJf7usnwdZ6lX9fn/mLsilkYBspLd+CRKKDtNGvAcT18bA7y+hzcFdauj3ipvA+fu0jev2O9cnURLxxNHkjrb3qR7f1q58ov28oz/e1o/+5U9ojJ10RrqNbSfOIRHau5XAdHDhsfWx2oJq0rOzC+600NsS5hXfP3jfQbBj/Nrx+WDJBA/fxbmtKGgWuAFyOOnk59du955s+ga3bNwYWXgTqU4gPkAM5/XLA53wtgm73MXqZT11dbxIHADxQTcFIIvfg0kQiSKxCPxWYLWLccpGaFn8cTs/1Ixt8XdOg20MFSAuEpQ0oD5xXRHylT5/18dP/u71o41A9Vi5Lr3diJXe0+l9f4hjJwzvU1aJdsnWJZxJCKk2rkVAfPMJORn0B+cJVSdJdNO+n89CarBYgcFtEyzsehHDgwdhj4kb322F2co7WVeNa3AQ0PfrPV/exK0eX9PjK3r6ih4/whQHPagZ/bm167Zb30oifO73chKp2F7kp9XGb3AHTmJxfPf3dXHHSUXa3l3qggjLzI2jxGmiefSBgmKD11WzD4DRPNw/T0Z9VT7Te97WFt7ZOO6mJugzbqqOeHdrtpg+K/ZpDIATIVGwIUzn7GM++l+M6JFIV5zZ7ZXzqGQ3pTnoK5n9CiWi4DDZqGyjiiBGNGEyL+sTv6J/v6wD9qQ++5qLx5om2XUmVxEqiN9BTDh4tdN9VxFoVhGODK0qTUS5qGPj5iUYIDLxuaUB03Ve15TXKkIkINBNRSYVYTAQBr39yOAA1aCpCyTXuwTy9lnuams39bFv6Xve1Pl7S9v+jKyfMi0cNLSkc9rKpS8blIDIEGQyToPOKMAxZYilxMZdoQc2TrXT91Cu2YwYXA1utZlBdEkH9Fk9fkZPP9VWsyRr1pV3Rs6Kkz4WkJRm+UsWy2TiPC4wDhM58ADTs6Vzp+1dVCS5uOuLduduTWSZASazJjWrNTUYOn3JWL99ol19GhyHko4tNs6nRMA1EOWRJAgLRSZx+qg+4+v69+vO2eoN/fOm0sANpYsbUQLunAbEv4t873vijDImWpbqy+jTeeYYwwgx8QAK6XiFQbwFpgGNm43b7Fac8P369Gf1l2e1vY0YH0c9w59RTBMMnKy/7DTQXao1Ec1GDhW4yNCNBiG1SRMYqAEZDU58MopiUEVsgLvRQGixy7zqMxdGLumwi4tAvH8seJ4seDZuPxlNXCedlG3RNChoydlFApd3hsRJRO8M5KmOkmxGlhKn/Ex/+4FO+AfURfxY8gWMKzGpBu+UFhwlzIXHmPzrK3+yd2qILVxJjlNy4pTFROPi34P6UWLk39Vrnm1644G4Cvjn6Bxa/Ahr9IE3LFWgT7Q0HPA5JFG3C/AUcOW9fcPjuC+yutAB4xJziKtMXHmFsV6MV9LnYoGZI08GE0fi2/u1UB2iYRLRzBkWi1q4qiK3lPm8oXTwekcBJgOn0ZMbwf4+bKpjXjiNUXQuWRAKoGIcx14SMSeuJlY6pd+nLWwi4Ef6+T/9vKbNf22DazgJNwHwYXC3apNZAxY3rq27yCYwACStOJ6mq4lbJ6IsNhyeiqgEiRPlgK4yiD70JFQTSodfRhvtWhufgNGKLW6XHEIO4fjknMK7be8ki3fFMR1QDSIJNtYSNeHmAKEgDbu1B6qFJEeIYxr6jOtKN9/Vo3f1vd7VG/9Cf34kM5FqRtApMLZBR7zA0cv8ohwUJk4QysZBdqu8NXhVz/+tHv1Kifif9crntINnbTUUIA6fRoRvULxlCL0NDoD1ImCE0MQp86SxiaWIz41n7lIC+kEJq6Pk5XDCOZu9PeBwaP0d+pPrkNt9u6rBZKJ8qAZu4fOEOGCfd+B6YZAy9tiA7QISKHMlNKikj4Vr4FG1QIZSk43C4IXbIbzv6jv9r575kfb3eW3/jAGrdpYyoxB5HkrmZkIIi5TJEus6n4pq+k/99X/02wt6x8PjJZuHoBHG1qHokcAn+cv7ZJBN/JjYedVKGOBhiOwvL5zwXJm4qkFaE+GUlYUAepujCS5R6mT4BBCcx+KS7g0Z+J5M+mGFsV4B0yiumxJ11t+JE9ccALgEaBy5Z/KhdclYgmwbiw7Rh/HetS9SJgFdv0uZsv/ynH7/oR78Sj9/3tU7wGQ5oRVOeUNnLdEt5P5QF3Ft0HqnvqbHP9fjn2zYWNPdsp4ny5cb/ndJBOCck4NP10QS1bCWMqENQhFyfQWJDPvWxGiyAhPWlrkuT+4DWLjMafI4Ep5IIP72Gx9oirIU1cihKSyj08QNwwIWwJ+h3wPOi+OLcB9P3j0jRlucCw/YWEQ16Pcq1uWv9Vm/1OPv6eehRrhAH4KSR0xNKpJWU2Si3JwfVJ/SSfqF/vAvOiDX0deZDQoTKv3lxoANKCqMnRTUjpKokAjVLCZTEBFAX7DM4mJX8rkmJZt2ztImiQ3tdIJwWH/lZhsLzRfbyiXH0X0LhCoTsHQC7A+dFyUs3ov/Ra9dvsdUDUlcFqQWwzg57lwnr9m8aKLHxxejPKjH39E2f6nH39Er7gsL34zGjhJvhqIEnU1scAfF6/E/6d//0FNP4EAzGBhoUNiAcyOo3RvBbCKDGNqY3IkUjBaii9x1KSAC3GeTiAXgOd7TJ0j68hE2vzHCTnsblZdGC+K1JholCMX2Tot3jRYuEmoFRkEA+ZAbFYixjjNSlj5pzoiCSICJogRxl3Sc31ndCR4vKRculq6/PqDtfk9b/oUePy1JvRoLYDfGSwexax8c+LfBPe/qTd/M+FzuGBIUupd4QBaSFW+hgYJm4nbCiBw0DopcsFJlNmjM2i0L7h6NFupgtXRdaFjRPHSfrMQLHRgtEtQN7iLS9NOuc5txVhPKwAJPKROURlTDmKAqEz1MURkqaQ55IYVEOATYBDdtJnsI94vBiV2C2YITpKErevzv+tmY3v0UEJ7uVh3cxF1vdKYvvFnar21Kq+DDF9YwAsBZD+RueXLQg6JxseuI3YIXC+HqA8Rsv8+DUvpE82Qhr1ZwsUCFDp+wTP4aBMQHsF+4ggZZzc+PQRzRuMCFKoELDiPBiFPExsh1Vu6OLQF/9CkYH0gowbgUn1gGCGi2ASCUcAoVFAt+Gf1qc7BGUff5Yj58xvCmYUgkQIjf1N/+W48eRzRkN5xxYBv10r9px17wlV2J+ZhFIxeMkzNHxGTPicESYMEPg2rXyYSDch5xQA/OCMHC4/ksUx8HsaTVC9wIpYZAgG/kQua1YUrhYtFnfYQDcuJ2PJCMjmy43dG5tkmjOoEtQTXhGgKoaXG1v3OZdV3hpVcpEP0CvWChSZ+PqgMBE4mSucXJ8s83Yxqx8QIiYlOEXttk/+QPhVW+DMtaKNFECwuZ6xzymzidrWIGkIoBlC/iLrdkySHRsOFzEDCwIPIBJrdraDKcgovTruPJ6l6pDoMb+jvWJZF4DOrQyYff2IF2N8bEPHRHvMI5epbXkoJxOCExcsh+2tyJhSNGw0oORT5io43DC3ju+uyxPLQ5Z/T4iTFHZaxI/fHv9bLn+cCrwlQPQBsBOKlMCrJHHNEUsCCTSB1GU0nGGE2ruhktZck53JMihvU1YDt6oXYxzTXERNbgaSmgj0YYSYKTgBe+bbdqkYOhfj5Ep0NqjRgN+J68P+BgEFnAbY4LB8eAyIyLdkJDo2sgDLPTpSYm4otfmA7uoaBbBjxUVlKXH9RzP2kQEzUcUz/P6RP+eOVnJgh0FSqTDjHyeob+VQh0ruFeWoSJxZUKxF+5p1ycAVH0/BWJoWPMx6kPA6pyNaMupNXczvDICEROFQg8yJjvalFQ8j2vIK9hHaNHrHBEAnzcxNJPUAJ4ny52QqwJBr17Yvp+kAy8Fu3oKg7pIZxw4JwHZoE5dUJGuvR9VD/fN6VHT35/tnjjimw6k4tf4zIQp4cuyMBZhh+OUGcSEDmQV9QnB1MuBnRRuIZBmMQicDac9HVUTYZWSvCETO67AB9FXQt1NgbDDY2f4HOnMi3Qi4I0CCJ3MESR86IL3J4Xi6aAa7mE9BFKILxQDEyOTouYRsIH4XV1wmORuMu0cPpY/L7O41XV2MqT2wGKpzHBWdQUiBUc1liMpu6+ZCabnLEinIAl5I6ESagdGskrdQFdDNbn8EZMCEO1oYKoqQCGS1c9gh+YKWW6lBD0IBBwEqLIJeKrA8vMqRYXGZEVUYbRtoxYzAODJxhoh7azqUct2asapmw5SUAwjkJIQDWyKxM9VYN7en8avSxBeHTCTIAVn+l0vrCJ8qdXWXaSpAAnrjjEU+B6TJYhxws9CO+vpoVh3ktvR2gKt0VIA1MJPDyOAmfx1GGG3J+smNd+LobHoY+cekzqyv3aHAgYreTIxD5pwiZyObgPI9eQvpCHYWcKVRtEijH5C6s4hL3NVoB53pLUARHqgS0shqG6JOCsABizwEg0RB3cGD0dLEheqmKtX/TU1tKjCIwO60+ozPpIWpUleon66j4DhsYgtkoYxIHwx2iWNUAdXXuYoTi/87DGMTrblXa0kN2TU2n2G8/IhEwii1N8I8I6Iy9/wz1k4aUJrtQRrZWMlPY7T/7sHJzhzEImRwctJF5WKRAZQIeI47pue7QFVwIN7M8UXiIUY4FmaIohumpysrBc2s7cc5Y6/LXVQN05Vq5OCrGsuFvtVqZdXxeDEXUyg0kAoEaYJHsYOBCL666mizGHELhchIBTTGVW8mnSq0pSXWTponNssi0QxGiDFc6cgiBm3TJPdkxym8PHPDGQJySEJnEMDCYk9on5rEOoYsdnBxwmNiqnEEuaxyTgoUzBeK20ylOSe1tLd7IoDH5YBENZDvygMhFd00FpAZPUoEsZpzQ/tQRvhUfRtG+r5K3heXAiLSmnBaahpXwAB59z1V13qokb1gVxHJstwcuTC0t01QD1+Gig0NKzFSe/TAsi6+DZykZGgFFgqIeiRPO5lRCmVzCoOzseEoQ1heQFF2mO+dzPvb25JN/Qzykmt8ME15kb2oukUPoQgT6tRNDkWA70TdTlZGEg1PBsEykSLdARMLtaZF5lRA6MEI+0ljkMd9buJGO3nALDZOmFGf6raaFBqsHIaXK0Ik+kWKT8ygtEyUAJ+fEiIfGNl8lhtDSy8lgMHNtD6WT2NMEiY6HlIoPF+4PNJXlXr3zVNbwOJXDPAl6AwzkkXkJuJC/1DPfEsLndDBLqf9t1EfQOE8wcn820dvElH3WemByUa8o/WO8eh8lmqXKo8tNUlZGUhzGFAb7JgbGmckRuvPL5Z1GOoHks5VOX6kAMpcsqB0/oh0iZkYK9ryXEIOQI1aH+DacH6rliKED18etpM4UqRFCYdLmrn38oHYp4Ubv1iQWhcg0BnEexKAN0j0aDxzfmgShc3Z2XCB4j2d1rQwGfNHEm4HOWNVSyAsDHREwBIUygV1MgMFMRhGIFDsIQPjm2MBN3ZlyIUmBixXTEI+w1BzrEsRCQJiVx7bUbNCarpcJcRlSnGMFaZKnKYFkut9alG3+zY4IxdkGCd/Ev9eheaZ4O3qj097SVUyDGXvSqBpeYE+xYKSs9YhZ94mVSwCs0IohQRCDc4AOW6xwNmCbpUQEvjFYrogZzwO/s98XgVWIJETsIi+Azs9VqYWsyA8qlQzh4PcJ2GN2zcuLlsXBpUqkZ18Uj1i/whR9BTdyDqBm8eRTE8ME94pmtAzpcMbQJdGd+Xb+90iLYO3alF/9Ub/lWcPj3qOscsznnupSlAn+RRwND9zOXyGB4nhjUq3LM5spqxXSNldXqPv2kkwparZOC7glt4oBS45I0caa14ZiirLrox5yi4OSQFA3KvDDYohTIkNFcX2kVkFig7zEqjJdFC2nCTEM/JYYFooQAx8VPdZz+wCrujUiePmH/qE19Vf9+GnOTeeHSuwjgPZqEE6STZtFCEEfIMDweeo9prrQIWi1JH8v6GhpykoyioQth1mBJ5QTX7+eE6PBVjVFIh8ZW9qHPsY3ZSPG+Y9aoWDZpxEhdJYoitACawlNYnxzGbHqkfYlxlRNK4uZdCXCRqxuEMZsv611Kd+WzYUS766FPut72hn75on674w+WoAMugwFC/UOZ/KUClTcqFGwK4DHXUJ3Dc5M78UsSK6k3Pmld701cCgu1ogvWjKKerFYWabqrXHK0HZDAxlW5XudMlF5ORVKOe3ZhVsxQDMaOeP9qArLF1ZTot5YJbVgFIs9Sqpqw84UvSV0beV11GdmUDOeNEP9o++w1ktBjNPSBWASG3tOLv6S3v0TJ9I+FBGTh+3QOJL3y14wXQjGDrmNlQwX96Ty5sOTAkvT40V3tEOfEwfIFx5KH30XcrqAFynWpToQUZJbkaz4OpvWyM0JEcwXPKZ4SKjeX7M5EzxkuPOR0PZwuRMiHynV1CfOEcLpR+kWcI+fwP5RyGVxfLM7b2t5v6a8v10XYXMHqbgUSkbTprU7Ntzfuqd9vodUYSa1M9X1GOL13PoLDJVQlPpmSvXRBGtjMk/hFvC4bLzFCfoZNRrDsWr9lIoQ4unXqizJXzShLw61CqFeMbcVwPAruzmEUoLHi+eq+QKZCY0txmrxZlSFSPpZlzFY/LWJMTSXpXi0vWsYHkmsF+vMnek7pir+o7d1a6/Bm1AKYXDnUCtK/t/X7l7TNb+nx+wLpoaEKcciBcUA2exMQ3kBrPIrDXgZwCbtwCMnyGMW1qVUPMgfDX8lGUFm6KEsotlWWVTMQZLaA3ZIJMVu1fKHljF6tYkhGOYwpCB4wzCEfqSjB1Zg5eVmYNrwKT4N40QouzEIHNaXu6T0qgek39NxLWQUQkBS9dI2A/iaAL6bKuKJmPMuv6zXf0M/bFvLGvPRyILuvIdKcJn1qPw+F5UU8GWzlJ0Y4BWMCV5mchnJIWaaYDghrCq5gBi7O4KU6CwMvHHVr9K6Yw0DmwNtRyGpO9qcLC1mN9OoSUhxmw2ykfXDwZJVkzCRJMTJEVyFqVJY6PXr5Sk+2qzEAaKsb/3d6/AXaJbB8uEJgQvSViFc3yBAQB9+ppTicdLBf1cZ+U899Vf/+eH6L2ZtQFpl4pu+MQgQIsbDQsp5RTiPgdaKV764AQsbyzTml7p5AxwWPSu9CtTqgJ7h+RilWNZAy1wh4pcXLyTIdZW1g1oVXKG26cIjjSlAFeBUtNRXlLYeespnT+rP6mLyv7byov39Bf/sznfCP1u9XQrEyY1orR/t4ZXcN8ir66A1t6Hf081hD6+muTBYjQTBqLKs3ezMqAnBzQDCUd2GoELeK2cQkq1xzUro17cSApf9QJ0ZHZYW6P2WxINZRQvm3kirmoTPiKG51RaSxekqNKQ1QojHjuBGyO9J7EQiVCfDHRR1dj3s797T9V/XdfluPf00/f6N3fjxqj1YpM3KBBhIjB2ZZxAlCSWvGUoF5vZpv86+0k4/pGGuH+KW+3UcopJrxubqo8lZT9d0wgTyXvA6QToriWa9q18Hcul2BxPUg+1NS6USadMfMHZF7E0R3YxprsfFx///KETBlaY6YRqEAue26nvDk0o3v8nkIh1icaJgLJijFMyAf+rGe+0P9+5jOyTf075u5fM8usYqAPl3AzoB0mD4m54MIRhKWKfpcl3F+Vsx11B3CgWR6Ux/0ph5/W+/5il73PO0VPbZKwgRh2VHMFDCO5nA1YPljhWGmXxY/HRvM+iZPVdOIiMr0naCQ/UUuvJJKU08uzeHOkzUMhvgp5pKvtm0ZkgaT1oSyTQBzZQVpS0AniNYbKeS8n2yxLzZS+FTb3KoKv6qf7e8nIT5XeL5H1s6WqULyKHWN+TpWo1c41Vx3w8YJeM0pwFK9qd9u6nNe1C+Ps+x115/RyXpaZ+yhodvZ9huhAoWXreZFTXezBmUOgsVwLyxStdpVLRe4ctBJltao9VNiBQ6/Mu4gx1IDr5twXyjYgruboajEeut8YCkjV15VRHEVC7BXce5qxb4gh6ukKnl66ob+dkPn7Ibe9+aq2nILWRS3IWRd0tu3A6FUjtUjts6DNcRQ49IaknksWLoq40n9Y4ejOLhm1Gww08v6rJf7ith2S3hGr922TvmK3vxIqEBBEV+M9Snr5xS+d104hrChjhlLZ6PICvvvbKKnFvBI+SP2ySqu8iQXW4JXYp15SjlAjZgL1EIXdznykdSoqX67E0TccQ25OhYfqyGvP+0+8pmO8Vs6xspc6L+UUDbR/KnHXA7O7fhC1qstS7X3kRc0ZdxevGr18ISdD0gjuskqbKx0mv3kkN8tYDxUi4qGPQ/Z3WLg+bmlE3DLV5tc0mep6D/thMptq4/7UPFueSVt0RSKosp356IAbsft6vJODnIoOn0Hj7PA0UMEe1A5eBKV+fuqTjovAk2CGJ5C6WTJgYK6Ilj2WnyjqL2mal0Q7n79e3q8gd0bId7UuXmrQBQY5ugzBK8YkSUJGne1OMrhgvHmWV04R9+zVTwb7LvUxXYhfdVImXxtBSxstNBtZUIN8I3biAXRygc6MR9op14HTrhtNDp2QXtCj6/qs7bjh91TBQVH5SxZn6nimfRnhnxpDs4BOtjhYS7dSostWlLwhKEBdQraiHnrtNDt3B/dJGL00dewD2eFEgslbD5LM6x1SwntjrawEeK2S9qdfas/aqtvqD1jbnLtSlPnsJAYxwV2vGclhY1agw48kmlANThf56+wBQvPK3+OZFltJIS+btvL0KJtyHQROhjs5mXaNvLkn7XB5hF8sJUSUQLla7T/pSvKTS9z29LvALjtJZiFpvykuBlV3GkhKuZ1Odi4zSDRvL9O3K2CPR9feHLxVtTtko8Atygpy6BkGjtDfKxtvKfXbftJvrNxQz3eCPC9DB0JGEACW/exZHdIXUihbn1U3mNHim2oRYEIc9l0NP7yBqwF1Irzw4CMvLvsAl6wjjJuRrrewJMBErGkNYsckuCUm2OiCbaf3ixAeYv23bso43TXu9i6ohdvWzlf2jms0EO6KB7XCdiq2V0N26eERSUhcJjJ9wMaBWFXbkOckChqxSY9MACJADcsxknfg/592KG5LSTxjj70pL/f7rz0Hb3/HvcdeSURBG7klbfIs1pRY8FUV4tWUfkhEknE3JzZtRvF9wzm07SVChNuyHqeO37EAacBA0KksBHdabEpEy0gE4aa7LKMHMqbKg0D63hHXbrVjahbBOgCc3af7e+5bRN91tUDIGLTqR7Q4ytjb0V/J74eYwli5t+80ZLhfh/obx9RTIf9WLv4PqgkW8du9zbe0fP39J6d2OI23dy2Zk5qC6cM0zGcdez01t8t68EehUS2t6W5ZIVgN7YK0U4npeEzYyfHaE1Uk2yBjBjYNO9jD8//F2AADp/9/kGB8WMAAAAASUVORK5CYII=">
<img alt="" class="position-absolute" height="75" width="430" style="top: 263px; left: 442px; z-index: 6;"
src="data:image/png;base64,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">
<img alt="" class="position-absolute" height="123" width="304" style="top: 73px; left: 467px; z-index: 5;"
src="data:image/png;base64,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">
<img alt="" class="position-absolute" height="50" width="116" style="top: 113px; left: 762px; z-index: 4;"
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHQAAAAyCAMAAAC6RQ9kAAAAA3NCSVQICAjb4U/gAAABgFBMVEX////kyZm1pIDexpr73qqnmnallnGnmnn33aqjlXn12anszpi7p4PUvZPu1aXPuo6tm3zr0aLfxZbNt4xxbWOUim6yn3l7c2NsaF2+rIStm3yom4C2o3v22KSznW+rnIGejGuqlm3ZxJZxbWN0bFvUvZPv0JvnzZ2MfmPArYq7p4PXvo7Qu5LFsoq+rIRsaWDx057ErYKznXCsmnKFe2qom4CPgWSMhG3Qu5Kck3OllnGjlXl7c2NzcGeJf217c2OJf23FsoqUim6+rISck3PArYp/eWl/eGWfknrGsIzArYrGsIyck3PNt4zXvo67p4Pr0aLQu5K7p4Omk2zfxZbZxJbErYL12anu1aWwm2753KfmzaHny5aMg3N/eWmfknqajnmUiXSMhG2Mg3OrnIGjlXmUim6UiXSMhG2EeGN/eGW1pICajHOFe2rGsIy7p4OVhme+rIStm3ynmnmejGuUim6VhmfUvZPQu5LNt4zexprPuo7GsIy7p4Oyn3mmk2w+/MV0AAAAgHRSTlMA////////////////////RP///yJ3/yIR7v9E////RHe7/xEiu///RHfu/////xH/////IjNEVaqqzMwRESIzVXeIu8zdIiIzZmZ3d4iZqru7u7vM3d3u7u7///8RESIiIiIiMzMzMzMzM0RERFVVVWZmZmZmZnd3d4iIiIiIiOmar1cAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAcdEVYdFNvZnR3YXJlAEFkb2JlIEZpcmV3b3JrcyBDUzQGstOgAAAFzUlEQVRYheWXh3saRxDFvSzHHQsczUEKCFVkiINKFEW25RZFcVwjJFvNTu+99+p/PfNmCwfcxYosf8n3ZcB3gjvv797sm9nl1KlHxNyjbngCMf7U/wU6929Al/5L6X3nq43f5ud/uf3ZpScARXp/GB/68q1fD4IHYXP5TC73em731psnDYXS9dMDX729nVZBmkIpVc4hXr188tCLA9CfAiIqftM/1WwTda90otC5IeilbahkoYAG9Ocyiz1J6JDSNw41Kg0wvRTOTVC3HgvzwcbG7ZJrfoNKLx8qTms6IBxT+cPyY1JvHqgmxrhlPpPSq54rm21WyFyXZDzGGVC/OSby8jYP1KRBdq9Y6Dnvgrn8cwACZRc+4rklU8FXIZv4xvGg20qLeEDUPS576kjnfAN9D5cUpxZYfeJsa6m7x2J+CSIkBCFV/ZaFWqVbSrtI6dwq7SjODc9q7liFc2Dmyzw6EtxP71IjDKkdNFUzRDT5tkDBUUobOLd3VND46urqjQZi6mYYlsvl18oIQbE3T1ERUkiEwEngjIOsdrvdgrQx+yzHt6c5xuil3wlbgBJGEGY0Gk84hP4k+idh+PxnPnWkGIuH2tG0AIvQWAsXRqFRiy+OxkyE2oGlyd+wPP1IfeE6wSeh9B/nmKB5sZjJZjNeDGuh6lPUk6BTFiVdIqWFWqR0avsZZ2g1m6FXDLRYoQuZzEQSVESsaU/mi7JyEepTwE0+VRBaaYFGzmYnYqCyhku11PUE9zrvGJ3WREKG6HFK2TVFVyadU1QrZwGVkENDx0AXAa0nKG1EjCP7J6GhKtrfbc8LSKnQ0BryW4+DVmm2s36yewct5GZXitB2HTR2dEDu8RGoWMTQMU4qigIm1fu7khGuTI179JGgQdgut8t4604VmPQyVEp2UiYOWskiUq8kuFdGKlVEfCpIaaAqvud7nufjQEdu9TCSTm8BRopxUlGIOl3K1BJLpl9+ItJ96HOZUlohlIei8/lsoNLMqcwgRieVoHlUUz1Jqe0xwprWaQ9p/maZCJUsNTBGkk9zekUd/vVjoLKKx/ET5nTAvJFlRDA0XdEwpBYH3hxFoIsYetRJRYnM05Vk90a7jssul0w6PWs1cnY9Lhq4l6GCe1J21EmktMKN49MEaH9FkW4N0U8CaMVmVx8HoHQXehLa3YhS1DDFF/Fz6tqsNGDhHMVQdq5v0F6gTMmY9FbYSSM9qYglAdAXE+bUrcvWSq4Xc3p1Xi03MEp5TnFXHe1hxL7kXrmAJLyUlN74zoD0kqxZrdTTZcolo1Jdo1Swk2JWNygt4HFeToQKl1jhVlL8UQ44vWwi0yK4H0bcK6qZOCeRUvQkkjr8M9Ok15VLZLXWSTbu1Rq1XOx3AzunuJF70oiTihisjiXoagK0vzFxD6C1a/faKuUU87LjoLg51kmYU3EWUmOdVLIrdv9g9i5Up0rXqe/Anu1ITinpyY42wiJG7QEa66TSYOeLFKwQ5XSkI+l5xZIe9N1Lt+f1GjYYVYxyHnMa66RGZF9m59WuqrTKaCMZmb5Lr1OKHouxR5XSZh3GjnXSFEtsi3a7uLCwsNi1WnkRV1hlTHK1YGxbVBTKq/WIk4qcrIvwWJyTplgdpqrKeYn2f1ZqSlRn1+efiYBeM0YSet835KQip60HaJyTuGQkVkkNjW7RsHOoGBsZrdit8Mbsmq5TGe+kIruil9STSvwf006pbUnOSEaibQ7YKFml2m55bB6GnFTkx95BocY5SdcpulvV2s71ClunFurbOe0KuW96r+mx2WEoHmcWNZOdmZ5e61xvRaFLq+/Sr8TzFH/82bt7t/cMx+87O/Qzcffw8HBPNyTdgP2+e/eNUikK3O5qE4iaifxziOrziJWVyZVJxPrMw+mvO5+0YjtjUlz56MOPX6B4//NSo/HdnTvf9zY3N3u9/fX19Xv37k9i6JXJ+zMcF6Y5fux01tY6a51WqzXWcrS/AGShj5noGrZMAAAAAElFTkSuQmCC">
</div>
</div>
<div class="container-lg mt-5 px-3">
<!-- '"` --><!-- </textarea></xmp> --></option></form><form role="search" data-turbo="false" action="/search" accept-charset="UTF-8" method="get">
<label for="not-found-search" class="d-block text-normal color-fg-muted mb-1 f4">Find code, projects, and people on GitHub:</label>
<div class="d-flex flex-items-center">
<input type="text" name="q" id="not-found-search" class="flex-auto input-lg form-control mr-2">
<button type="submit" data-view-component="true" class="btn"> Search
</button>
</div>
</form>
<div class="mt-5 color-fg-muted text-center">
<a href="https://support.github.com?tags=dotcom-404" class="Link--secondary">Contact Support</a> &mdash;
<a href="https://githubstatus.com" class="Link--secondary">GitHub Status</a> &mdash;
<a href="https://twitter.com/githubstatus" class="Link--secondary">@githubstatus</a>
</div>
</div>
</main>
</div>
<footer role="contentinfo" class="footer pt-6 position-relative" data-analytics-visible="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;visible&quot;,&quot;label&quot;:&quot;text: Marketing footer&quot;}" >
<h2 class="sr-only">Site-wide Links</h2>
<div class="container-xl p-responsive">
<div class="d-flex flex-wrap py-5 mb-5">
<section class="col-12 col-lg-4 mb-5 pr-lg-4">
<a href="/" data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to home&quot;,&quot;label&quot;:&quot;text:home&quot;}" class="color-fg-default d-inline-block" aria-label="Go to GitHub homepage">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 367.4 90" class="footer-logo-mktg d-block" height="30"><g fill="currentColor"><path d="m46.1 0c-25.5 0-46.1 20.6-46.1 46.1 0 20.4 13.2 37.7 31.5 43.8 2.3.4 3.2-1 3.2-2.2 0-1.1-.1-4.7-.1-8.6-11.6 2.1-14.6-2.8-15.5-5.4-.5-1.3-2.8-5.4-4.7-6.5-1.6-.9-3.9-3-.1-3.1 3.6-.1 6.2 3.3 7.1 4.7 4.2 7 10.8 5 13.4 3.8.4-3 1.6-5 2.9-6.2-10.3-1.2-21-5.1-21-22.8 0-5 1.8-9.2 4.7-12.4-.5-1.2-2.1-5.9.5-12.2 0 0 3.9-1.2 12.7 4.7 3.7-1 7.6-1.6 11.5-1.6s7.8.5 11.5 1.6c8.8-6 12.7-4.7 12.7-4.7 2.5 6.3.9 11.1.5 12.2 2.9 3.2 4.7 7.3 4.7 12.4 0 17.7-10.8 21.6-21.1 22.8 1.7 1.4 3.1 4.2 3.1 8.5 0 6.2-.1 11.1-.1 12.7 0 1.2.9 2.7 3.2 2.2 18.2-6.1 31.4-23.4 31.4-43.8.3-25.4-20.4-46-45.9-46z"></path><path d="m221.6 67.1h-.1zm0 0c-.5 0-1.8.3-3.2.3-4.4 0-5.9-2-5.9-4.6v-17.5h8.9c.5 0 .9-.4.9-1.1v-9.5c0-.5-.4-.9-.9-.9h-8.9v-11.7c0-.4-.3-.7-.8-.7h-12c-.5 0-.8.3-.8.7v12.1s-6.1 1.5-6.5 1.6-.7.5-.7.9v7.6c0 .6.4 1.1.9 1.1h6.2v18.3c0 13.6 9.5 15 16 15 3 0 6.5-.9 7.1-1.2.3-.1.5-.5.5-.9v-8.4c.1-.6-.3-1-.8-1.1zm132.2-12.2c0-10.1-4.1-11.4-8.4-11-3.3.2-6 1.9-6 1.9v19.6s2.7 1.9 6.8 2c5.8.2 7.6-1.9 7.6-12.5zm13.6-.9c0 19.1-6.2 24.6-17 24.6-9.1 0-14.1-4.6-14.1-4.6s-.2 2.6-.5 2.9c-.2.3-.4.4-.8.4h-8.3c-.6 0-1.1-.4-1.1-.9l.1-62c0-.5.4-.9.9-.9h11.9c.5 0 .9.4.9.9l-.1 20.9s4.6-3 11.3-3h.1c6.8-0 16.7 2.5 16.7 21.7zm-48.7-20.2h-11.7c-.6 0-.9.4-.9 1.1v30.3s-3.1 2.2-7.3 2.2-5.4-1.9-5.4-6.1v-26.5c0-.5-.4-.9-.9-.9h-11.9c-.5 0-.9.4-.9.9v28.5c0 12.3 6.9 15.3 16.3 15.3 7.8 0 14.1-4.3 14.1-4.3s.3 2.2.4 2.5.5.5.9.5h7.5c.6 0 .9-.4.9-.9l.1-41.7c-.1-.4-.6-.9-1.2-.9zm-132.2 0h-11.9c-.5 0-.9.5-.9 1.1v40.9c0 1.1.7 1.5 1.7 1.5h10.7c1.1 0 1.4-.5 1.4-1.5v-41.1c0-.5-.5-.9-1-.9zm-5.8-18.9c-4.3 0-7.7 3.4-7.7 7.7s3.4 7.7 7.7 7.7c4.2 0 7.6-3.4 7.6-7.7s-3.4-7.7-7.6-7.7zm92-1.4h-11.8c-.5 0-.9.4-.9.9v22.8h-18.5v-22.7c0-.5-.4-.9-.9-.9h-11.9c-.5 0-.9.4-.9.9v62c0 .5.5.9.9.9h11.9c.5 0 .9-.4.9-.9v-26.6h18.5l-.1 26.5c0 .5.4.9.9.9h11.9c.5 0 .9-.4.9-.9v-62c0-.4-.4-.9-.9-.9zm-105.3 27.5v32c0 .2-.1.6-.3.7 0 0-7 5-18.5 5-13.9 0-30.3-4.4-30.3-33 0-28.7 14.4-34.6 28.4-34.5 12.2 0 17.1 2.7 17.8 3.2.2.3.3.5.3.8l-2.3 9.9c0 .5-.5 1.1-1.1.9-2-.6-5-1.8-12.1-1.8-8.2 0-17 2.3-17 20.8s8.4 20.6 14.4 20.6c5.1 0 7-.6 7-.6v-12.8h-8.2c-.6 0-1.1-.4-1.1-.9v-10.3c0-.5.4-.9 1.1-.9h20.9c.6-.1 1 .4 1 .9z"></path></g></svg>
</a>
<h3 class="h5 mt-4 mb-0" id="subscribe-to-newsletter">Subscribe to our developer newsletter</h3>
<p class="f5 color-fg-muted mb-3">Get tips, technical guides, and best practices. Twice a month.</p>
<a class="btn-mktg mb-4 btn-muted-mktg" data-analytics-event="{&quot;category&quot;:&quot;Subscribe&quot;,&quot;action&quot;:&quot;click to Subscribe&quot;,&quot;label&quot;:&quot;ref_cta:Subscribe;&quot;}" href="https://github.com/newsletter">
Subscribe
</a>
</section>
<nav class="col-6 col-sm-3 col-lg-2 mb-6 mb-md-2 pr-3 pr-lg-0 pl-lg-4" aria-labelledby="footer-title-product">
<h3 class="h5 mb-3 text-mono color-fg-muted text-normal" id="footer-title-product">
Platform
</h3>
<ul class="list-style-none color-fg-muted f5">
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;features&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;features_link_platform_footer&quot;}" href="/features">Features</a>
</li>
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;enterprise&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;enterprise_link_platform_footer&quot;}" href="/enterprise">Enterprise</a>
</li>
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;copilot&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;copilot_link_platform_footer&quot;}" href="/features/copilot">Copilot</a>
</li>
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;ai&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;ai_link_platform_footer&quot;}" href="/features/ai">AI</a>
</li>
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;security&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;security_link_platform_footer&quot;}" href="/security">Security</a>
</li>
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;pricing&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;pricing_link_platform_footer&quot;}" href="/pricing">Pricing</a>
</li>
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;team&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;team_link_platform_footer&quot;}" href="/team">Team</a>
</li>
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;resources&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;resources_link_platform_footer&quot;}" href="https://resources.github.com">Resources</a>
</li>
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;roadmap&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;roadmap_link_platform_footer&quot;}" href="https://github.com/github/roadmap">Roadmap</a>
</li>
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;compare&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;compare_link_platform_footer&quot;}" href="https://resources.github.com/devops/tools/compare">Compare GitHub</a>
</li>
</ul>
</nav>
<nav class="col-6 col-sm-3 col-lg-2 mb-6 mb-md-2 pr-3 pr-md-0 pl-md-4" aria-labelledby="footer-title-platform">
<h3 class="h5 mb-3 text-mono color-fg-muted text-normal" id="footer-title-platform">
Ecosystem
</h3>
<ul class="list-style-none f5">
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;dev-api&quot;,&quot;context&quot;:&quot;ecosystem&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;dev-api_link_ecosystem_footer&quot;}" href="https://docs.github.com/get-started/exploring-integrations/about-building-integrations">Developer API</a>
</li>
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;partners&quot;,&quot;context&quot;:&quot;ecosystem&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;partners_link_ecosystem_footer&quot;}" href="https://partner.github.com">Partners</a>
</li>
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;edu&quot;,&quot;context&quot;:&quot;ecosystem&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;edu_link_ecosystem_footer&quot;}" href="https://github.com/edu">Education</a>
</li>
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;cli&quot;,&quot;context&quot;:&quot;ecosystem&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;cli_link_ecosystem_footer&quot;}" href="https://cli.github.com">GitHub CLI</a>
</li>
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;desktop&quot;,&quot;context&quot;:&quot;ecosystem&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;desktop_link_ecosystem_footer&quot;}" href="https://desktop.github.com">GitHub Desktop</a>
</li>
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;mobile&quot;,&quot;context&quot;:&quot;ecosystem&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;mobile_link_ecosystem_footer&quot;}" href="https://github.com/mobile">GitHub Mobile</a>
</li>
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;marketplace&quot;,&quot;context&quot;:&quot;ecosystem&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;marketplace_link_ecosystem_footer&quot;}" href="https://github.com/marketplace">GitHub Marketplace</a>
</li>
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;mcp_registry&quot;,&quot;context&quot;:&quot;ecosystem&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;mcp_registry_link_ecosystem_footer&quot;}" href="https://github.com/mcp">MCP Registry</a>
</li>
</ul>
</nav>
<nav class="col-6 col-sm-3 col-lg-2 mb-6 mb-md-2 pr-3 pr-md-0 pl-md-4" aria-labelledby="footer-title-support">
<h3 class="h5 mb-3 text-mono color-fg-muted text-normal" id="footer-title-support">
Support
</h3>
<ul class="list-style-none f5">
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;docs&quot;,&quot;context&quot;:&quot;support&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;docs_link_support_footer&quot;}" href="https://docs.github.com">Docs</a>
</li>
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;community&quot;,&quot;context&quot;:&quot;support&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;community_link_support_footer&quot;}" href="https://github.community">Community Forum</a>
</li>
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;services&quot;,&quot;context&quot;:&quot;support&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;services_link_support_footer&quot;}" href="https://services.github.com">Professional Services</a>
</li>
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;premium_support&quot;,&quot;context&quot;:&quot;support&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;premium_support_link_support_footer&quot;}" href="/enterprise/premium-support">Premium Support</a>
</li>
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;skills&quot;,&quot;context&quot;:&quot;support&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;skills_link_support_footer&quot;}" href="https://skills.github.com">Skills</a>
</li>
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;status&quot;,&quot;context&quot;:&quot;support&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;status_link_support_footer&quot;}" href="https://www.githubstatus.com">Status</a>
</li>
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;contact_github&quot;,&quot;context&quot;:&quot;support&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;contact_github_link_support_footer&quot;}" href="https://support.github.com?tags=dotcom-footer">Contact GitHub</a>
</li>
</ul>
</nav>
<nav class="col-6 col-sm-3 col-lg-2 mb-6 mb-md-2 pr-3 pr-md-0 pl-md-4" aria-labelledby="footer-title-company">
<h3 class="h5 mb-3 text-mono color-fg-muted text-normal" id="footer-title-company">
Company
</h3>
<ul class="list-style-none f5">
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;about&quot;,&quot;context&quot;:&quot;company&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;about_link_company_footer&quot;}" href="https://github.com/about">About</a>
</li>
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;why_github&quot;,&quot;context&quot;:&quot;company&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;why_github_link_company_footer&quot;}" href="https://github.com/why-github">Why GitHub</a>
</li>
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;customer_stories&quot;,&quot;context&quot;:&quot;company&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;customer_stories_link_company_footer&quot;}" href="/customer-stories?type=enterprise">Customer stories</a>
</li>
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;blog&quot;,&quot;context&quot;:&quot;company&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;blog_link_company_footer&quot;}" href="https://github.blog">Blog</a>
</li>
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;readme&quot;,&quot;context&quot;:&quot;company&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;readme_link_company_footer&quot;}" href="/readme">The ReadME Project</a>
</li>
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;careers&quot;,&quot;context&quot;:&quot;company&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;careers_link_company_footer&quot;}" href="https://github.careers">Careers</a>
</li>
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;newsroom&quot;,&quot;context&quot;:&quot;company&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;newsroom_link_company_footer&quot;}" href="/newsroom">Newsroom</a>
</li>
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;inclusion&quot;,&quot;context&quot;:&quot;company&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;inclusion_link_company_footer&quot;}" href="/about/diversity">Inclusion</a>
</li>
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;social_impact&quot;,&quot;context&quot;:&quot;company&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;social_impact_link_company_footer&quot;}" href="https://socialimpact.github.com">Social Impact</a>
</li>
<li class="lh-condensed mb-3">
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;shop&quot;,&quot;context&quot;:&quot;company&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;shop_link_company_footer&quot;}" href="https://shop.github.com">Shop</a>
</li>
</ul>
</nav>
</div>
</div>
<div class="color-bg-subtle">
<div class="container-xl p-responsive f6 py-4 d-md-flex flex-justify-between flex-items-center gap-3">
<nav aria-label="Legal and Resource Links">
<ul class="list-style-none d-flex flex-wrap color-fg-muted gapx-3">
<li>
&copy; <time datetime="2026">2026</time> GitHub, Inc.
</li>
<li>
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;terms&quot;,&quot;context&quot;:&quot;subfooter&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;terms_link_subfooter_footer&quot;}" href="https://docs.github.com/site-policy/github-terms/github-terms-of-service">Terms</a>
</li>
<li>
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;privacy&quot;,&quot;context&quot;:&quot;subfooter&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;privacy_link_subfooter_footer&quot;}" href="https://docs.github.com/site-policy/privacy-policies/github-privacy-statement">Privacy</a>
<a href="https://github.com/github/site-policy/pull/582" class="Link--secondary">(Updated 02/2024)<time datetime="2024-02" class="sr-only">02/2024</time></a>
</li>
<li>
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;sitemap&quot;,&quot;context&quot;:&quot;subfooter&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;sitemap_link_subfooter_footer&quot;}" href="/sitemap">Sitemap</a>
</li>
<li>
<a class="Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;what_is_git&quot;,&quot;context&quot;:&quot;subfooter&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;what_is_git_link_subfooter_footer&quot;}" href="/git-guides">What is Git?</a>
</li>
<li >
<cookie-consent-link>
<button
type="button"
class="Link--secondary underline-on-hover border-0 p-0 color-bg-transparent"
data-action="click:cookie-consent-link#showConsentManagement"
data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;cookies&quot;,&quot;context&quot;:&quot;subfooter&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;cookies_link_subfooter_footer&quot;}"
>
Manage cookies
</button>
</cookie-consent-link>
</li>
<li>
<cookie-consent-link>
<button
type="button"
class="Link--secondary underline-on-hover border-0 p-0 color-bg-transparent text-left"
data-action="click:cookie-consent-link#showConsentManagement"
data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;dont_share_info&quot;,&quot;context&quot;:&quot;subfooter&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;dont_share_info_link_subfooter_footer&quot;}"
>
Do not share my personal information
</button>
</cookie-consent-link>
</li>
</ul>
</nav>
<nav aria-label="GitHub&#39;s Social Media Links" class="footer-social mt-3 mt-md-0 d-flex gapx-6 gapy-1 flex-wrap flex-items-center flex-lg-justify-end">
<ul class="list-style-none d-flex flex-items-center lh-condensed-ultra gap-3">
<li>
<a href="https://www.linkedin.com/company/github" class="footer-social-icon d-block Link--outlineOffset" data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to Linkedin&quot;,&quot;label&quot;:&quot;text:linkedin&quot;}">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 19 18" aria-hidden="true" class="d-block" width="19" height="18"><path d="M3.94 2A2 2 0 1 1 2 0a2 2 0 0 1 1.94 2zM4 5.48H0V18h4zm6.32 0H6.34V18h3.94v-6.57c0-3.66 4.77-4 4.77 0V18H19v-7.93c0-6.17-7.06-5.94-8.72-2.91z" fill="currentColor"></path></svg>
<span class="sr-only">GitHub on LinkedIn</span>
</a>
</li>
<li>
<a href="https://www.instagram.com/github" class="footer-social-icon d-block Link--outlineOffset" data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to Instagram&quot;,&quot;label&quot;:&quot;text:instagram&quot;}">
<svg xmlns="http://www.w3.org/2000/svg" role="img" viewBox="0 0 24 24" aria-hidden="true" class="d-block" width="18" height="18"><title>Instagram</title><path d="M12 0C8.74 0 8.333.015 7.053.072 5.775.132 4.905.333 4.14.63c-.789.306-1.459.717-2.126 1.384S.935 3.35.63 4.14C.333 4.905.131 5.775.072 7.053.012 8.333 0 8.74 0 12s.015 3.667.072 4.947c.06 1.277.261 2.148.558 2.913.306.788.717 1.459 1.384 2.126.667.666 1.336 1.079 2.126 1.384.766.296 1.636.499 2.913.558C8.333 23.988 8.74 24 12 24s3.667-.015 4.947-.072c1.277-.06 2.148-.262 2.913-.558.788-.306 1.459-.718 2.126-1.384.666-.667 1.079-1.335 1.384-2.126.296-.765.499-1.636.558-2.913.06-1.28.072-1.687.072-4.947s-.015-3.667-.072-4.947c-.06-1.277-.262-2.149-.558-2.913-.306-.789-.718-1.459-1.384-2.126C21.319 1.347 20.651.935 19.86.63c-.765-.297-1.636-.499-2.913-.558C15.667.012 15.26 0 12 0zm0 2.16c3.203 0 3.585.016 4.85.071 1.17.055 1.805.249 2.227.415.562.217.96.477 1.382.896.419.42.679.819.896 1.381.164.422.36 1.057.413 2.227.057 1.266.07 1.646.07 4.85s-.015 3.585-.074 4.85c-.061 1.17-.256 1.805-.421 2.227-.224.562-.479.96-.899 1.382-.419.419-.824.679-1.38.896-.42.164-1.065.36-2.235.413-1.274.057-1.649.07-4.859.07-3.211 0-3.586-.015-4.859-.074-1.171-.061-1.816-.256-2.236-.421-.569-.224-.96-.479-1.379-.899-.421-.419-.69-.824-.9-1.38-.165-.42-.359-1.065-.42-2.235-.045-1.26-.061-1.649-.061-4.844 0-3.196.016-3.586.061-4.861.061-1.17.255-1.814.42-2.234.21-.57.479-.96.9-1.381.419-.419.81-.689 1.379-.898.42-.166 1.051-.361 2.221-.421 1.275-.045 1.65-.06 4.859-.06l.045.03zm0 3.678c-3.405 0-6.162 2.76-6.162 6.162 0 3.405 2.76 6.162 6.162 6.162 3.405 0 6.162-2.76 6.162-6.162 0-3.405-2.76-6.162-6.162-6.162zM12 16c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4zm7.846-10.405c0 .795-.646 1.44-1.44 1.44-.795 0-1.44-.646-1.44-1.44 0-.794.646-1.439 1.44-1.439.793-.001 1.44.645 1.44 1.439z" fill="currentColor"></path></svg>
<span class="sr-only">GitHub on Instagram</span>
</a>
</li>
<li>
<a href="https://www.youtube.com/github" class="footer-social-icon d-block Link--outlineOffset" data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to YouTube&quot;,&quot;label&quot;:&quot;text:youtube&quot;}">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 19.17 13.6" aria-hidden="true" class="d-block" width="23" height="16"><path d="M18.77 2.13A2.4 2.4 0 0 0 17.09.42C15.59 0 9.58 0 9.58 0a57.55 57.55 0 0 0-7.5.4A2.49 2.49 0 0 0 .39 2.13 26.27 26.27 0 0 0 0 6.8a26.15 26.15 0 0 0 .39 4.67 2.43 2.43 0 0 0 1.69 1.71c1.52.42 7.5.42 7.5.42a57.69 57.69 0 0 0 7.51-.4 2.4 2.4 0 0 0 1.68-1.71 25.63 25.63 0 0 0 .4-4.67 24 24 0 0 0-.4-4.69zM7.67 9.71V3.89l5 2.91z" fill="currentColor"></path></svg>
<span class="sr-only">GitHub on YouTube</span>
</a>
</li>
<li>
<a href="https://x.com/github" class="footer-social-icon d-block Link--outlineOffset" data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to X&quot;,&quot;label&quot;:&quot;text:x&quot;}">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 1227" fill="currentColor" aria-hidden="true" class="d-block" width="16" height="16"><path d="M714.163 519.284 1160.89 0h-105.86L667.137 450.887 357.328 0H0l468.492 681.821L0 1226.37h105.866l409.625-476.152 327.181 476.152H1200L714.137 519.284h.026ZM569.165 687.828l-47.468-67.894-377.686-540.24h162.604l304.797 435.991 47.468 67.894 396.2 566.721H892.476L569.165 687.854v-.026Z"></path></svg>
<span class="sr-only">GitHub on X</span>
</a>
</li>
<li>
<a href="https://www.tiktok.com/@github" class="footer-social-icon d-block Link--outlineOffset" data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to tiktok&quot;,&quot;label&quot;:&quot;text:tiktok&quot;}">
<svg xmlns="http://www.w3.org/2000/svg" role="img" viewBox="0 0 24 24" aria-hidden="true" class="d-block" width="18" height="18"><title>TikTok</title><path d="M12.525.02c1.31-.02 2.61-.01 3.91-.02.08 1.53.63 3.09 1.75 4.17 1.12 1.11 2.7 1.62 4.24 1.79v4.03c-1.44-.05-2.89-.35-4.2-.97-.57-.26-1.1-.59-1.62-.93-.01 2.92.01 5.84-.02 8.75-.08 1.4-.54 2.79-1.35 3.94-1.31 1.92-3.58 3.17-5.91 3.21-1.43.08-2.86-.31-4.08-1.03-2.02-1.19-3.44-3.37-3.65-5.71-.02-.5-.03-1-.01-1.49.18-1.9 1.12-3.72 2.58-4.96 1.66-1.44 3.98-2.13 6.15-1.72.02 1.48-.04 2.96-.04 4.44-.99-.32-2.15-.23-3.02.37-.63.41-1.11 1.04-1.36 1.75-.21.51-.15 1.07-.14 1.61.24 1.64 1.82 3.02 3.5 2.87 1.12-.01 2.19-.66 2.77-1.61.19-.33.4-.67.41-1.06.1-1.79.06-3.57.07-5.36.01-4.03-.01-8.05.02-12.07z" fill="currentColor"></path></svg>
<span class="sr-only">GitHub on TikTok</span>
</a>
</li>
<li>
<a href="https://www.twitch.tv/github" class="footer-social-icon d-block Link--outlineOffset" data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to Twitch&quot;,&quot;label&quot;:&quot;text:twitch&quot;}">
<svg xmlns="http://www.w3.org/2000/svg" role="img" viewBox="0 0 24 24" aria-hidden="true" class="d-block" width="18" height="18"><title>Twitch</title><path d="M11.571 4.714h1.715v5.143H11.57zm4.715 0H18v5.143h-1.714zM6 0L1.714 4.286v15.428h5.143V24l4.286-4.286h3.428L22.286 12V0zm14.571 11.143l-3.428 3.428h-3.429l-3 3v-3H6.857V1.714h13.714Z" fill="currentColor"></path></svg>
<span class="sr-only">GitHub on Twitch</span>
</a>
</li>
<li>
<a href="https://github.com/github" class="footer-social-icon d-block Link--outlineOffset" data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to github&#39;s org&quot;,&quot;label&quot;:&quot;text:github&quot;}">
<svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 0 16 16" width="20" aria-hidden="true" class="d-block"><path fill="currentColor" 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>
<span class="sr-only">GitHub’s organization on GitHub</span>
</a>
</li>
</ul>
<locale-selector>
<experimental-action-menu data-anchor-align="start" data-anchor-side="outside-bottom" data-view-component="true" class="footer-social-icon">
<button role="button" aria-haspopup="true" aria-controls="locale-selector-list" aria-expanded="false" id="locale-selector-text" aria-label="English - Select language" type="button" data-view-component="true" class="d-flex flex-items-center border-0 color-bg-transparent p-0 locale-trigger Button--secondary Button--medium Button"> <span class="Button-content">
<span class="Button-label"><span class="locale-selector-trigger">
<svg height="16" aria-hidden="true" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-globe mr-1 color-fg-muted locale-icon">
<path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM5.78 8.75a9.64 9.64 0 0 0 1.363 4.177c.255.426.542.832.857 1.215.245-.296.551-.705.857-1.215A9.64 9.64 0 0 0 10.22 8.75Zm4.44-1.5a9.64 9.64 0 0 0-1.363-4.177c-.307-.51-.612-.919-.857-1.215a9.927 9.927 0 0 0-.857 1.215A9.64 9.64 0 0 0 5.78 7.25Zm-5.944 1.5H1.543a6.507 6.507 0 0 0 4.666 5.5c-.123-.181-.24-.365-.352-.552-.715-1.192-1.437-2.874-1.581-4.948Zm-2.733-1.5h2.733c.144-2.074.866-3.756 1.58-4.948.12-.197.237-.381.353-.552a6.507 6.507 0 0 0-4.666 5.5Zm10.181 1.5c-.144 2.074-.866 3.756-1.58 4.948-.12.197-.237.381-.353.552a6.507 6.507 0 0 0 4.666-5.5Zm2.733-1.5a6.507 6.507 0 0 0-4.666-5.5c.123.181.24.365.353.552.714 1.192 1.436 2.874 1.58 4.948Z"></path>
</svg>
<span class="color-fg-muted Link--secondary f6">English</span>
<svg height="16" aria-hidden="true" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-chevron-down ml-1 color-fg-muted locale-icon">
<path d="M12.78 5.22a.749.749 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.06 0L3.22 6.28a.749.749 0 1 1 1.06-1.06L8 8.939l3.72-3.719a.749.749 0 0 1 1.06 0Z"></path>
</svg>
</span></span>
</span>
</button>
<div class="Overlay-backdrop--anchor" data-menu-overlay>
<div class="Overlay Overlay-whenNarrow Overlay--height-auto Overlay--width-auto" hidden>
<div class="Overlay-body Overlay-body--paddingNone">
<ul class="ActionList" id="locale-selector-list" role="menu" aria-labelledby="locale-selector-text">
<li role="none" data-view-component="true" class="ActionList-item">
<a href="" selected="selected" style="white-space: normal;" data-action="click:locale-selector#handleSelectLocale" data-locale="en-us" role="menuitem" tabindex="-1" data-view-component="true" class="footer-social-locale ActionList-content">
<span class="ActionList-item-label">
<div style="width: 16px; display: inline-block; text-align: center; margin-right: 8px; flex-shrink: 0;">
<svg height="16" aria-hidden="true" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check">
<path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path>
</svg>
</div>
<span>English</span>
</span>
</a></li>
<li role="none" data-view-component="true" class="ActionList-item">
<a href="" style="white-space: normal;" data-action="click:locale-selector#handleSelectLocale" data-locale="pt-br" role="menuitem" tabindex="-1" data-view-component="true" class="footer-social-locale ActionList-content">
<span class="ActionList-item-label">
<div style="width: 16px; display: inline-block; text-align: center; margin-right: 8px; flex-shrink: 0;">
</div>
<span>Português (Brasil)</span>
</span>
</a></li>
<li role="none" data-view-component="true" class="ActionList-item">
<a href="" style="white-space: normal;" data-action="click:locale-selector#handleSelectLocale" data-locale="es-419" role="menuitem" tabindex="-1" data-view-component="true" class="footer-social-locale ActionList-content">
<span class="ActionList-item-label">
<div style="width: 16px; display: inline-block; text-align: center; margin-right: 8px; flex-shrink: 0;">
</div>
<span>Español (América Latina)</span>
</span>
</a></li>
<li role="none" data-view-component="true" class="ActionList-item">
<a href="" style="white-space: normal;" data-action="click:locale-selector#handleSelectLocale" data-locale="ja" role="menuitem" tabindex="-1" data-view-component="true" class="footer-social-locale ActionList-content">
<span class="ActionList-item-label">
<div style="width: 16px; display: inline-block; text-align: center; margin-right: 8px; flex-shrink: 0;">
</div>
<span>日本語</span>
</span>
</a></li>
<li role="none" data-view-component="true" class="ActionList-item">
<a href="" style="white-space: normal;" data-action="click:locale-selector#handleSelectLocale" data-locale="ko-kr" role="menuitem" tabindex="-1" data-view-component="true" class="footer-social-locale ActionList-content">
<span class="ActionList-item-label">
<div style="width: 16px; display: inline-block; text-align: center; margin-right: 8px; flex-shrink: 0;">
</div>
<span>한국어</span>
</span>
</a></li>
</ul>
</div>
</div>
</div>
</experimental-action-menu> </locale-selector>
</nav>
</div>
</div>
</footer>
<ghcc-consent id="ghcc" class="position-fixed bottom-0 left-0" style="z-index: 999999"
data-locale="en"
data-initial-cookie-consent-allowed=""
data-cookie-consent-required="false"
></ghcc-consent>
<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 d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></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 d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg>
</button>
You can’t perform that action at this time.
</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 d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-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;">
<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" 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 d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></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 d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path>
</svg>
</clipboard-copy>
</div>
</template>
<template id="snippet-clipboard-copy-button-unpositioned">
<div class="zeroclipboard-container">
<clipboard-copy aria-label="Copy" class="ClipboardButton btn btn-invisible js-clipboard-copy m-2 p-0 d-flex flex-justify-center flex-items-center" 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">
<path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></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">
<path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path>
</svg>
</clipboard-copy>
</div>
</template>
</div>
<div id="js-global-screen-reader-notice" class="sr-only mt-n1" aria-live="polite" aria-atomic="true" ></div>
<div id="js-global-screen-reader-notice-assertive" class="sr-only mt-n1" aria-live="assertive" aria-atomic="true"></div>
</body>
</html>
# Copyright 2023 Google Inc. All Rights Reserved.
#
# Distributed under MIT license.
# See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
# Workflow for building the release binaries.
name: Release build / deploy
on:
push:
branches:
- master
- v*.*.*
release:
types: [ published ]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
windows_build:
name: Windows Build (vcpkg / ${{ matrix.triplet }})
runs-on: [windows-2022]
strategy:
fail-fast: false
matrix:
include:
- triplet: x86-windows-dynamic
arch: '-A Win32'
build_shared_libs: 'ON'
- triplet: x64-windows-dynamic
arch: '-A x64'
build_shared_libs: 'ON'
- triplet: x86-windows-static
arch: '-A Win32'
build_shared_libs: 'OFF'
- triplet: x64-windows-static
arch: '-A x64'
build_shared_libs: 'OFF'
env:
VCPKG_VERSION: '2022.11.14'
VCPKG_ROOT: vcpkg
VCPKG_DISABLE_METRICS: 1
steps:
- name: Checkout the source
uses: actions/checkout@v3
with:
submodules: false
fetch-depth: 1
- uses: actions/cache@v3
id: cache-vcpkg
with:
path: vcpkg
key: release-${{ runner.os }}-vcpkg-${{ env.VCPKG_VERSION }}-${{ matrix.triplet }}
- name: Download vcpkg
if: steps.cache-vcpkg.outputs.cache-hit != 'true'
# wget doesn't seem to work under bash.
shell: 'powershell'
run: |
C:\msys64\usr\bin\wget.exe -nv `
https://github.com/microsoft/vcpkg/archive/refs/tags/${{ env.VCPKG_VERSION }}.zip `
-O vcpkg.zip
- name: Bootstrap vcpkg
if: steps.cache-vcpkg.outputs.cache-hit != 'true'
shell: 'bash'
run: |
set -x
unzip -q vcpkg.zip
rm -rf ${VCPKG_ROOT}
mv vcpkg-${VCPKG_VERSION} ${VCPKG_ROOT}
${VCPKG_ROOT}/bootstrap-vcpkg.sh
- name: Configure
shell: 'bash'
run: |
set -x
mkdir out
cmake -Bout -H. ${{ matrix.arch }} \
-DBUILD_TESTING=OFF \
-DBUILD_SHARED_LIBS=${{ matrix.build_shared_libs }} \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=`pwd`/prefix \
-DCMAKE_TOOLCHAIN_FILE=${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake \
-DVCPKG_TARGET_TRIPLET=${{ matrix.triplet }} \
#
- name: Build
shell: 'bash'
run: |
set -x
cmake --build out --config Release
- name: Install
shell: 'bash'
run: |
set -x
cmake --build out --config Release --target install
cp LICENSE prefix/bin/LICENSE.brotli
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: brotli-${{matrix.triplet}}
path: |
prefix/bin/*
- name: Package release zip
if: github.event_name == 'release'
shell: 'powershell'
run: |
Compress-Archive -Path prefix\bin\* `
-DestinationPath brotli-${{matrix.triplet}}.zip
- name: Upload binaries to release
if: github.event_name == 'release'
uses: AButler/[email protected]
with:
files: brotli-${{matrix.triplet}}.zip
repo-token: ${{ secrets.GITHUB_TOKEN }}
Early on in my programming journey, syntax highlighting aided my understanding the coding. However, as I gained more experience, I found myself relying less on it. Eventually, I realized that the abundance of colors was very straining on my eyes and made it difficult to focus and concentrate.
Moondust is crafted to reduce eye strain, allowing to focus on code. It challenges the conventional approach of highlighting keywords and typical structures. Instead of drawing excessive attention to them, this theme brings business logic to the forefront.
For a more in-depth discussion on the issues associated with the conventional approach to syntax highlighting, recommend reading the articles A case against syntax highlighting and Syntax highlighting is a waste of an information channel.
Moondust is tailored for each syntax individually. At present, it supports CSS, Dockerfile, fish, Go, Go Module, Go Sum, HTML, INI, JavaScript, JSON, JSON with Comments, JSON Lines, JSX, Makefile, Python, Ruby, Rust, Shell Script, SQL, Swift, TOML, TypeScript, TSX, and YAML.
In the initial phase, Moondust was primarily a modification of the GitHub Theme. I owe a great deal of gratitude to the Primer team for their work.
A special shout-out goes to the entire community that focuses on creating minimalistic, two-color, monochrome themes, particularly Monochrome. It was a delight for me to delve into your work, and it is heartening to realize that our aesthetic preferences align closely.